From 1a0d9099e669cf7540a6df375b0fa48b1cca8adf Mon Sep 17 00:00:00 2001 From: Benoit Lubek Date: Fri, 13 Oct 2023 18:16:55 +0200 Subject: [PATCH] [IJ plugin] Telemetry: networking (#5285) --- .../ijplugin/codegen/ApolloCodegenService.kt | 18 +- .../gradle/GradleToolingModelService.kt | 22 +- .../project/ApolloProjectManagerListener.kt | 4 +- .../v3tov4/ApolloV3ToV4MigrationProcessor.kt | 2 +- .../ijplugin/settings/AppSettingsListener.kt | 12 + .../settings/AppSettingsStateService.kt | 64 + .../settings/ProjectSettingsListener.kt | 12 + ...gsService.kt => ProjectSettingsService.kt} | 50 +- .../ijplugin/settings/SettingsComponent.kt | 13 +- .../ijplugin/settings/SettingsConfigurable.kt | 24 +- .../ijplugin/settings/SettingsListener.kt | 12 - .../fieldinsights/FieldInsightsService.kt | 26 +- .../RefreshFieldInsightsAction.kt | 4 +- .../ijplugin/telemetry/Dependency.kt | 25 +- .../ijplugin/telemetry/TelemetryNetworking.kt | 30 + .../ijplugin/telemetry/TelemetryService.kt | 64 +- .../ijplugin/telemetry/TelemetrySession.kt | 16 +- .../com/apollographql/ijplugin/util/Apollo.kt | 10 +- .../ijplugin/util/MavenCoordinates.kt | 28 + .../inspection/Apollo4Available.gradle.kts | 8 +- ...ciesInLibsVersionsToml_after.versions.toml | 12 +- ...dlePluginInBuildGradleKts_after.gradle.kts | 16 +- libraries/apollo-tooling/build.gradle.kts | 1 + .../platform-api/internal/operations.graphql | 6 +- .../platform-api/internal/schema.graphqls | 9710 +++++++++++++---- .../apollo3/tooling/FieldInsights.kt | 3 +- .../apollo3/tooling/InternalPlatformApi.kt | 6 +- .../apollo3/tooling/RegisterOperations.kt | 2 +- .../apollo3/tooling/Telemetry.kt | 74 + .../apollo3/tooling/TimestampAdapter.kt | 18 + 30 files changed, 7703 insertions(+), 2589 deletions(-) create mode 100644 intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/AppSettingsListener.kt create mode 100644 intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/AppSettingsStateService.kt create mode 100644 intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/ProjectSettingsListener.kt rename intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/{SettingsService.kt => ProjectSettingsService.kt} (75%) delete mode 100644 intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsListener.kt create mode 100644 intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/TelemetryNetworking.kt create mode 100644 intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/util/MavenCoordinates.kt create mode 100644 libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/Telemetry.kt create mode 100644 libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/TimestampAdapter.kt diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/codegen/ApolloCodegenService.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/codegen/ApolloCodegenService.kt index 49c0b829ad2..2e84fa82f9e 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/codegen/ApolloCodegenService.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/codegen/ApolloCodegenService.kt @@ -8,9 +8,9 @@ import com.apollographql.ijplugin.gradle.getGradleRootPath import com.apollographql.ijplugin.project.ApolloProjectListener import com.apollographql.ijplugin.project.ApolloProjectService import com.apollographql.ijplugin.project.apolloProjectService -import com.apollographql.ijplugin.settings.SettingsListener -import com.apollographql.ijplugin.settings.SettingsState -import com.apollographql.ijplugin.settings.settingsState +import com.apollographql.ijplugin.settings.ProjectSettingsListener +import com.apollographql.ijplugin.settings.ProjectSettingsState +import com.apollographql.ijplugin.settings.projectSettingsState import com.apollographql.ijplugin.util.apolloGeneratedSourcesRoots import com.apollographql.ijplugin.util.dispose import com.apollographql.ijplugin.util.isNotDisposed @@ -62,7 +62,7 @@ class ApolloCodegenService( logd("project=${project.name}") startOrStopCodegenObservers() startObserveApolloProject() - startObservingSettings() + startObserveSettings() } private fun startObserveApolloProject() { @@ -75,17 +75,17 @@ class ApolloCodegenService( }) } - private fun startObservingSettings() { + private fun startObserveSettings() { logd() - project.messageBus.connect(this).subscribe(SettingsListener.TOPIC, object : SettingsListener { - override fun settingsChanged(settingsState: SettingsState) { - logd("settingsState=$settingsState") + project.messageBus.connect(this).subscribe(ProjectSettingsListener.TOPIC, object : ProjectSettingsListener { + override fun settingsChanged(projectSettingsState: ProjectSettingsState) { + logd("projectSettingsState=$projectSettingsState") startOrStopCodegenObservers() } }) } - private fun shouldTriggerCodegenAutomatically() = project.apolloProjectService.apolloVersion.isAtLeastV3 && project.settingsState.automaticCodegenTriggering + private fun shouldTriggerCodegenAutomatically() = project.apolloProjectService.apolloVersion.isAtLeastV3 && project.projectSettingsState.automaticCodegenTriggering private fun startOrStopCodegenObservers() { if (shouldTriggerCodegenAutomatically()) { diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/gradle/GradleToolingModelService.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/gradle/GradleToolingModelService.kt index 9afd11726f0..d3fe8e4a341 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/gradle/GradleToolingModelService.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/gradle/GradleToolingModelService.kt @@ -5,9 +5,9 @@ import com.apollographql.ijplugin.ApolloBundle import com.apollographql.ijplugin.project.ApolloProjectListener import com.apollographql.ijplugin.project.ApolloProjectService import com.apollographql.ijplugin.project.apolloProjectService -import com.apollographql.ijplugin.settings.SettingsListener -import com.apollographql.ijplugin.settings.SettingsState -import com.apollographql.ijplugin.settings.settingsState +import com.apollographql.ijplugin.settings.ProjectSettingsListener +import com.apollographql.ijplugin.settings.ProjectSettingsState +import com.apollographql.ijplugin.settings.projectSettingsState import com.apollographql.ijplugin.telemetry.telemetryService import com.apollographql.ijplugin.util.dispose import com.apollographql.ijplugin.util.isNotDisposed @@ -53,7 +53,7 @@ class GradleToolingModelService( startObserveApolloProject() startOrStopObserveGradleHasSynced() startOrAbortFetchToolingModels() - startObservingSettings() + startObserveSettings() } private fun startObserveApolloProject() { @@ -68,7 +68,7 @@ class GradleToolingModelService( } private fun shouldFetchToolingModels() = project.apolloProjectService.apolloVersion.isAtLeastV4 && - project.settingsState.contributeConfigurationToGraphqlPlugin + project.projectSettingsState.contributeConfigurationToGraphqlPlugin private fun startOrStopObserveGradleHasSynced() { logd() @@ -101,14 +101,14 @@ class GradleToolingModelService( gradleHasSyncedDisposable = null } - private fun startObservingSettings() { + private fun startObserveSettings() { logd() - project.messageBus.connect(this).subscribe(SettingsListener.TOPIC, object : SettingsListener { - private var contributeConfigurationToGraphqlPlugin: Boolean = project.settingsState.contributeConfigurationToGraphqlPlugin + project.messageBus.connect(this).subscribe(ProjectSettingsListener.TOPIC, object : ProjectSettingsListener { + private var contributeConfigurationToGraphqlPlugin: Boolean = project.projectSettingsState.contributeConfigurationToGraphqlPlugin - override fun settingsChanged(settingsState: SettingsState) { - val contributeConfigurationToGraphqlPluginChanged = contributeConfigurationToGraphqlPlugin != settingsState.contributeConfigurationToGraphqlPlugin - contributeConfigurationToGraphqlPlugin = settingsState.contributeConfigurationToGraphqlPlugin + override fun settingsChanged(projectSettingsState: ProjectSettingsState) { + val contributeConfigurationToGraphqlPluginChanged = contributeConfigurationToGraphqlPlugin != projectSettingsState.contributeConfigurationToGraphqlPlugin + contributeConfigurationToGraphqlPlugin = projectSettingsState.contributeConfigurationToGraphqlPlugin logd("contributeConfigurationToGraphqlPluginChanged=$contributeConfigurationToGraphqlPluginChanged") if (contributeConfigurationToGraphqlPluginChanged) { startOrAbortFetchToolingModels() diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/project/ApolloProjectManagerListener.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/project/ApolloProjectManagerListener.kt index b5ef9e660a6..8631bb6b161 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/project/ApolloProjectManagerListener.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/project/ApolloProjectManagerListener.kt @@ -3,7 +3,7 @@ package com.apollographql.ijplugin.project import com.apollographql.ijplugin.codegen.ApolloCodegenService import com.apollographql.ijplugin.gradle.GradleToolingModelService import com.apollographql.ijplugin.graphql.GraphQLConfigService -import com.apollographql.ijplugin.settings.SettingsService +import com.apollographql.ijplugin.settings.ProjectSettingsService import com.apollographql.ijplugin.studio.fieldinsights.FieldInsightsService import com.apollographql.ijplugin.studio.sandbox.SandboxService import com.apollographql.ijplugin.telemetry.TelemetryService @@ -23,7 +23,7 @@ internal class ApolloProjectManagerListener : ProjectManagerListener { logd("apolloVersion=" + project.apolloProjectService.apolloVersion) project.service() project.service() - project.service() + project.service() project.service() project.service() project.service() diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/refactoring/migration/v3tov4/ApolloV3ToV4MigrationProcessor.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/refactoring/migration/v3tov4/ApolloV3ToV4MigrationProcessor.kt index a4ff0e5468d..d4461ce0c38 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/refactoring/migration/v3tov4/ApolloV3ToV4MigrationProcessor.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/refactoring/migration/v3tov4/ApolloV3ToV4MigrationProcessor.kt @@ -24,7 +24,7 @@ import com.apollographql.ijplugin.refactoring.migration.v3tov4.item.UpdateMultiM import com.apollographql.ijplugin.refactoring.migration.v3tov4.item.UpdateWebSocketReconnectWhen import com.intellij.openapi.project.Project -private const val apollo4LatestVersion = "4.0.0-alpha.3" +private const val apollo4LatestVersion = "4.0.0-beta.1" /** * Migrations of Apollo Kotlin v3 to v4. diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/AppSettingsListener.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/AppSettingsListener.kt new file mode 100644 index 00000000000..bc6d5546f53 --- /dev/null +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/AppSettingsListener.kt @@ -0,0 +1,12 @@ +package com.apollographql.ijplugin.settings + +import com.intellij.util.messages.Topic + +interface AppSettingsListener { + companion object { + @Topic.ProjectLevel + val TOPIC: Topic = Topic.create("Apollo GraphQL app settings", AppSettingsListener::class.java) + } + + fun settingsChanged(appSettingsState: AppSettingsState) +} diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/AppSettingsStateService.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/AppSettingsStateService.kt new file mode 100644 index 00000000000..1a9aab67915 --- /dev/null +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/AppSettingsStateService.kt @@ -0,0 +1,64 @@ +package com.apollographql.ijplugin.settings + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.components.PersistentStateComponent +import com.intellij.openapi.components.Service +import com.intellij.openapi.components.State +import com.intellij.openapi.components.Storage +import com.intellij.openapi.components.service +import com.intellij.util.xmlb.XmlSerializerUtil + +/** + * Application level settings. + */ +@Service(Service.Level.APP) +@State( + name = "com.apollographql.ijplugin.settings.AppSettingsState", + storages = [Storage("apollo.xml")] +) +class AppSettingsStateService : PersistentStateComponent, AppSettingsState { + private val _state = AppSettingsStateImpl() + + override fun getState(): AppSettingsStateImpl { + return _state + } + + override fun loadState(state: AppSettingsStateImpl) { + XmlSerializerUtil.copyBean(state, this._state) + notifySettingsChanged() + } + + override var hasShownTelemetryOptOutDialog: Boolean + get() = _state.hasShownTelemetryOptOutDialog + set(value) { + _state.hasShownTelemetryOptOutDialog = value + notifySettingsChanged() + } + + override var telemetryEnabled: Boolean + get() = _state.telemetryEnabled + set(value) { + _state.telemetryEnabled = value + notifySettingsChanged() + } + + private var lastNotifiedState: AppSettingsState? = null + private fun notifySettingsChanged() { + if (lastNotifiedState != _state) { + lastNotifiedState = _state.copy() + ApplicationManager.getApplication().messageBus.syncPublisher(AppSettingsListener.TOPIC).settingsChanged(_state) + } + } +} + +interface AppSettingsState { + var hasShownTelemetryOptOutDialog: Boolean + var telemetryEnabled: Boolean +} + +data class AppSettingsStateImpl( + override var hasShownTelemetryOptOutDialog: Boolean = false, + override var telemetryEnabled: Boolean = true, +) : AppSettingsState + +val appSettingsState get(): AppSettingsState = service() diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/ProjectSettingsListener.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/ProjectSettingsListener.kt new file mode 100644 index 00000000000..1d0c41f559a --- /dev/null +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/ProjectSettingsListener.kt @@ -0,0 +1,12 @@ +package com.apollographql.ijplugin.settings + +import com.intellij.util.messages.Topic + +interface ProjectSettingsListener { + companion object { + @Topic.ProjectLevel + val TOPIC: Topic = Topic.create("Apollo GraphQL project settings", ProjectSettingsListener::class.java) + } + + fun settingsChanged(projectSettingsState: ProjectSettingsState) +} diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsService.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/ProjectSettingsService.kt similarity index 75% rename from intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsService.kt rename to intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/ProjectSettingsService.kt index 57718e7e9dd..3fb64a39e9b 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsService.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/ProjectSettingsService.kt @@ -9,6 +9,7 @@ import com.intellij.openapi.components.PersistentStateComponent import com.intellij.openapi.components.Service import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage +import com.intellij.openapi.components.StoragePathMacros import com.intellij.openapi.components.service import com.intellij.openapi.project.Project import com.intellij.util.xmlb.XmlSerializerUtil @@ -16,19 +17,23 @@ import com.intellij.util.xmlb.annotations.Attribute import com.intellij.util.xmlb.annotations.Transient import java.util.UUID +/** + * Project level settings. + * These settings are not meant to be shared with the team, which is why they are stored in workspace.xml, typically ignored by VCS. + */ @Service(Service.Level.PROJECT) @State( - name = "com.apollographql.ijplugin.settings.SettingsState", - storages = [Storage("apollo.xml")] + name = "com.apollographql.ijplugin.settings.ProjectSettingsState", + storages = [Storage(StoragePathMacros.WORKSPACE_FILE)] ) -class SettingsService(private val project: Project) : PersistentStateComponent, SettingsState { - private val _state = SettingsStateImpl() +class ProjectSettingsService(private val project: Project) : PersistentStateComponent, ProjectSettingsState { + private val _state = ProjectSettingsStateImpl() - override fun getState(): SettingsStateImpl { + override fun getState(): ProjectSettingsStateImpl { return _state } - override fun loadState(state: SettingsStateImpl) { + override fun loadState(state: ProjectSettingsStateImpl) { XmlSerializerUtil.copyBean(state, this._state) notifySettingsChanged() } @@ -66,24 +71,11 @@ class SettingsService(private val project: Project) : PersistentStateComponent var telemetryInstanceId: String - var telemetryEnabled: Boolean - var hasShownTelemetryOptOutDialog: Boolean } data class ApolloKotlinServiceConfiguration( @@ -137,15 +127,13 @@ data class ApolloKotlinServiceConfiguration( } } -data class SettingsStateImpl( +data class ProjectSettingsStateImpl( override var automaticCodegenTriggering: Boolean = true, override var hasEnabledGraphQLPluginApolloKotlinSupport: Boolean = false, override var contributeConfigurationToGraphqlPlugin: Boolean = true, override var apolloKotlinServiceConfigurations: List = emptyList(), override var telemetryInstanceId: String = "", - override var telemetryEnabled: Boolean = true, - override var hasShownTelemetryOptOutDialog: Boolean = false, -) : SettingsState +) : ProjectSettingsState -val Project.settingsState get(): SettingsState = service() +val Project.projectSettingsState get(): ProjectSettingsState = service() diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsComponent.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsComponent.kt index 1dd9eb97f9e..b54c7877ee8 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsComponent.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsComponent.kt @@ -3,7 +3,6 @@ package com.apollographql.ijplugin.settings import com.apollographql.ijplugin.ApolloBundle import com.apollographql.ijplugin.project.apolloProjectService import com.apollographql.ijplugin.settings.studio.ApiKeyDialog -import com.apollographql.ijplugin.telemetry.TELEMETRY_ENABLED import com.intellij.openapi.observable.properties.PropertyGraph import com.intellij.openapi.project.Project import com.intellij.ui.AddEditRemovePanel @@ -24,7 +23,7 @@ class SettingsComponent(private val project: Project) { var automaticCodegenTriggering: Boolean by automaticCodegenTriggeringProperty var contributeConfigurationToGraphqlPlugin: Boolean by contributeConfigurationToGraphqlPluginProperty var apolloKotlinServiceConfigurations: List - get() = addEditRemovePanel?.data?.toList()?: emptyList() + get() = addEditRemovePanel?.data?.toList() ?: emptyList() set(value) { addEditRemovePanel?.data = value.toMutableList() } @@ -101,12 +100,10 @@ class SettingsComponent(private val project: Project) { } } } - if (TELEMETRY_ENABLED) { - row { - checkBox(ApolloBundle.message("settings.telemetry.telemetryEnabled.text")) - .comment(ApolloBundle.message("settings.telemetry.telemetryEnabled.comment")) - .bindSelected(telemetryEnabledProperty) - } + row { + checkBox(ApolloBundle.message("settings.telemetry.telemetryEnabled.text")) + .comment(ApolloBundle.message("settings.telemetry.telemetryEnabled.comment")) + .bindSelected(telemetryEnabledProperty) } } diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsConfigurable.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsConfigurable.kt index 3c3ef0fe4d5..90a126e73b8 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsConfigurable.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsConfigurable.kt @@ -16,24 +16,24 @@ class SettingsConfigurable(private val project: Project) : Configurable { } override fun isModified(): Boolean { - return settingsComponent!!.automaticCodegenTriggering != project.settingsState.automaticCodegenTriggering || - settingsComponent!!.contributeConfigurationToGraphqlPlugin != project.settingsState.contributeConfigurationToGraphqlPlugin || - settingsComponent!!.apolloKotlinServiceConfigurations != project.settingsState.apolloKotlinServiceConfigurations || - settingsComponent!!.telemetryEnabled != project.settingsState.telemetryEnabled + return settingsComponent!!.automaticCodegenTriggering != project.projectSettingsState.automaticCodegenTriggering || + settingsComponent!!.contributeConfigurationToGraphqlPlugin != project.projectSettingsState.contributeConfigurationToGraphqlPlugin || + settingsComponent!!.apolloKotlinServiceConfigurations != project.projectSettingsState.apolloKotlinServiceConfigurations || + settingsComponent!!.telemetryEnabled != appSettingsState.telemetryEnabled } override fun apply() { - project.settingsState.automaticCodegenTriggering = settingsComponent!!.automaticCodegenTriggering - project.settingsState.contributeConfigurationToGraphqlPlugin = settingsComponent!!.contributeConfigurationToGraphqlPlugin - project.settingsState.apolloKotlinServiceConfigurations = settingsComponent!!.apolloKotlinServiceConfigurations - project.settingsState.telemetryEnabled = settingsComponent!!.telemetryEnabled + project.projectSettingsState.automaticCodegenTriggering = settingsComponent!!.automaticCodegenTriggering + project.projectSettingsState.contributeConfigurationToGraphqlPlugin = settingsComponent!!.contributeConfigurationToGraphqlPlugin + project.projectSettingsState.apolloKotlinServiceConfigurations = settingsComponent!!.apolloKotlinServiceConfigurations + appSettingsState.telemetryEnabled = settingsComponent!!.telemetryEnabled } override fun reset() { - settingsComponent!!.automaticCodegenTriggering = project.settingsState.automaticCodegenTriggering - settingsComponent!!.contributeConfigurationToGraphqlPlugin = project.settingsState.contributeConfigurationToGraphqlPlugin - settingsComponent!!.apolloKotlinServiceConfigurations = project.settingsState.apolloKotlinServiceConfigurations - settingsComponent!!.telemetryEnabled = project.settingsState.telemetryEnabled + settingsComponent!!.automaticCodegenTriggering = project.projectSettingsState.automaticCodegenTriggering + settingsComponent!!.contributeConfigurationToGraphqlPlugin = project.projectSettingsState.contributeConfigurationToGraphqlPlugin + settingsComponent!!.apolloKotlinServiceConfigurations = project.projectSettingsState.apolloKotlinServiceConfigurations + settingsComponent!!.telemetryEnabled = appSettingsState.telemetryEnabled } override fun getPreferredFocusedComponent() = settingsComponent!!.preferredFocusedComponent diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsListener.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsListener.kt deleted file mode 100644 index a7102c16655..00000000000 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/settings/SettingsListener.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.apollographql.ijplugin.settings - -import com.intellij.util.messages.Topic - -interface SettingsListener { - companion object { - @Topic.ProjectLevel - val TOPIC: Topic = Topic.create("Apollo GraphQL Settings", SettingsListener::class.java) - } - - fun settingsChanged(settingsState: SettingsState) -} diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/studio/fieldinsights/FieldInsightsService.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/studio/fieldinsights/FieldInsightsService.kt index f3d2db748c9..b074716e515 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/studio/fieldinsights/FieldInsightsService.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/studio/fieldinsights/FieldInsightsService.kt @@ -6,9 +6,9 @@ import com.apollographql.ijplugin.gradle.ApolloKotlinService import com.apollographql.ijplugin.gradle.ApolloKotlinServiceListener import com.apollographql.ijplugin.gradle.GradleToolingModelService import com.apollographql.ijplugin.settings.ApolloKotlinServiceConfiguration -import com.apollographql.ijplugin.settings.SettingsListener -import com.apollographql.ijplugin.settings.SettingsState -import com.apollographql.ijplugin.settings.settingsState +import com.apollographql.ijplugin.settings.ProjectSettingsListener +import com.apollographql.ijplugin.settings.ProjectSettingsState +import com.apollographql.ijplugin.settings.projectSettingsState import com.apollographql.ijplugin.util.logd import com.apollographql.ijplugin.util.logw import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer @@ -47,17 +47,17 @@ class FieldInsightsServiceImpl(private val project: Project) : FieldInsightsServ init { logd("project=${project.name}") - startObservingSettings() - startObservingApolloKotlinServices() + startObserveSettings() + startObserveApolloKotlinServices() } - private fun startObservingSettings() { + private fun startObserveSettings() { logd() - project.messageBus.connect(this).subscribe(SettingsListener.TOPIC, object : SettingsListener { - var apolloKotlinServiceConfigurations: List = project.settingsState.apolloKotlinServiceConfigurations - override fun settingsChanged(settingsState: SettingsState) { - val apolloKotlinServiceConfigurationsChanged = apolloKotlinServiceConfigurations != settingsState.apolloKotlinServiceConfigurations - apolloKotlinServiceConfigurations = settingsState.apolloKotlinServiceConfigurations + project.messageBus.connect(this).subscribe(ProjectSettingsListener.TOPIC, object : ProjectSettingsListener { + var apolloKotlinServiceConfigurations: List = project.projectSettingsState.apolloKotlinServiceConfigurations + override fun settingsChanged(projectSettingsState: ProjectSettingsState) { + val apolloKotlinServiceConfigurationsChanged = apolloKotlinServiceConfigurations != projectSettingsState.apolloKotlinServiceConfigurations + apolloKotlinServiceConfigurations = projectSettingsState.apolloKotlinServiceConfigurations logd("apolloKotlinServiceConfigurationsChanged=$apolloKotlinServiceConfigurationsChanged") if (apolloKotlinServiceConfigurationsChanged) { scheduleFetchLatencies() @@ -66,7 +66,7 @@ class FieldInsightsServiceImpl(private val project: Project) : FieldInsightsServ }) } - private fun startObservingApolloKotlinServices() { + private fun startObserveApolloKotlinServices() { project.messageBus.connect(this).subscribe(ApolloKotlinServiceListener.TOPIC, object : ApolloKotlinServiceListener { override fun apolloKotlinServicesAvailable() { logd() @@ -84,7 +84,7 @@ class FieldInsightsServiceImpl(private val project: Project) : FieldInsightsServ logd() val apolloKotlinServices = GradleToolingModelService.getApolloKotlinServices(project) val apolloKotlinServicesWithConfigurations: Map = apolloKotlinServices.associateWith { service -> - project.settingsState.apolloKotlinServiceConfigurations.firstOrNull { configuration -> + project.projectSettingsState.apolloKotlinServiceConfigurations.firstOrNull { configuration -> service.id == configuration.apolloKotlinServiceId } }.filterValues { it != null }.mapValues { it.value!! } diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/studio/fieldinsights/RefreshFieldInsightsAction.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/studio/fieldinsights/RefreshFieldInsightsAction.kt index dd6800e8953..0dd29be0339 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/studio/fieldinsights/RefreshFieldInsightsAction.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/studio/fieldinsights/RefreshFieldInsightsAction.kt @@ -3,7 +3,7 @@ package com.apollographql.ijplugin.studio.fieldinsights import com.apollographql.ijplugin.ApolloBundle import com.apollographql.ijplugin.project.apolloProjectService import com.apollographql.ijplugin.settings.SettingsConfigurable -import com.apollographql.ijplugin.settings.settingsState +import com.apollographql.ijplugin.settings.projectSettingsState import com.apollographql.ijplugin.util.logd import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnAction @@ -16,7 +16,7 @@ class RefreshFieldInsightsAction : AnAction() { logd() val project = e.project ?: return - if (project.settingsState.apolloKotlinServiceConfigurations.isEmpty()) { + if (project.projectSettingsState.apolloKotlinServiceConfigurations.isEmpty()) { val okCancelResult = Messages.showOkCancelDialog( e.project, ApolloBundle.message("action.RefreshFieldInsightsAction.mustConfigureDialog.message"), diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/Dependency.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/Dependency.kt index fc41381d773..15210b04d1e 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/Dependency.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/Dependency.kt @@ -1,31 +1,12 @@ package com.apollographql.ijplugin.telemetry -import com.intellij.openapi.components.service -import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.ProjectRootManager +import com.apollographql.ijplugin.util.MavenCoordinates -data class Dependency( - val group: String, - val artifact: String, - val version: String, -) - -fun Project.getProjectDependencies(): Set { - val dependencies = mutableSetOf() - service().orderEntries().librariesOnly().forEachLibrary { library -> - val components = library.name?.substringAfter(" ")?.split(":") ?: return@forEachLibrary true - if (components.size < 3) return@forEachLibrary true - dependencies.add(Dependency(components[0], components[1], components[2].substringBeforeLast("@"))) - true - } - return dependencies -} - -fun Dependency.toTelemetryProperty(): TelemetryProperty? = when { +fun MavenCoordinates.toTelemetryProperty(): TelemetryProperty? = when { group == "com.apollographql.apollo" || group == "com.apollographql.apollo3" -> TelemetryProperty.Dependency(group, artifact, version) group == "org.jetbrains.kotlin" && artifact == "kotlin-stdlib" -> TelemetryProperty.KotlinVersion(version) group == "androidx.compose.runtime" && artifact == "runtime" -> TelemetryProperty.ComposeVersion(version) else -> null } -fun Set.toTelemetryProperties(): Set = mapNotNull { it.toTelemetryProperty() }.toSet() +fun Set.toTelemetryProperties(): Set = mapNotNull { it.toTelemetryProperty() }.toSet() diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/TelemetryNetworking.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/TelemetryNetworking.kt new file mode 100644 index 00000000000..dff725d94d1 --- /dev/null +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/TelemetryNetworking.kt @@ -0,0 +1,30 @@ +package com.apollographql.ijplugin.telemetry + +import com.apollographql.apollo3.annotations.ApolloInternal +import com.apollographql.apollo3.tooling.Telemetry +import org.jetbrains.kotlin.idea.util.application.isApplicationInternalMode + +private const val STAGING_INTERNAL_PLATFORM_API_URL = "https://graphql-staging.api.apollographql.com/api/graphql" + +@OptIn(ApolloInternal::class) +suspend fun executeTelemetryNetworkCall(telemetrySession: TelemetrySession) { + Telemetry.trackApolloKotlinUsage( + serverUrl = if (isApplicationInternalMode()) STAGING_INTERNAL_PLATFORM_API_URL else null, + instanceId = telemetrySession.instanceId, + properties = telemetrySession.properties.map { it.toToolingTelemetryProperty() }, + events = telemetrySession.events.map { it.toTelemetryEvent() }, + ).getOrThrow() +} + +@OptIn(ApolloInternal::class) +private fun TelemetryProperty.toToolingTelemetryProperty() = Telemetry.TelemetryProperty( + type = type, + payload = parameters, +) + +@OptIn(ApolloInternal::class) +private fun TelemetryEvent.toTelemetryEvent() = Telemetry.TelemetryEvent( + type = type, + date = date, + payload = parameters, +) diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/TelemetryService.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/TelemetryService.kt index 33fb6d0bf1b..8c02f38d352 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/TelemetryService.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/telemetry/TelemetryService.kt @@ -3,9 +3,10 @@ package com.apollographql.ijplugin.telemetry import com.apollographql.apollo3.gradle.api.ApolloGradleToolingModel import com.apollographql.ijplugin.ApolloBundle import com.apollographql.ijplugin.icons.ApolloIcons -import com.apollographql.ijplugin.settings.SettingsListener -import com.apollographql.ijplugin.settings.SettingsState -import com.apollographql.ijplugin.settings.settingsState +import com.apollographql.ijplugin.settings.AppSettingsListener +import com.apollographql.ijplugin.settings.AppSettingsState +import com.apollographql.ijplugin.settings.appSettingsState +import com.apollographql.ijplugin.settings.projectSettingsState import com.apollographql.ijplugin.studio.fieldinsights.ApolloFieldInsightsInspection import com.apollographql.ijplugin.telemetry.TelemetryProperty.AndroidCompileSdk import com.apollographql.ijplugin.telemetry.TelemetryProperty.AndroidGradlePluginVersion @@ -48,9 +49,11 @@ import com.apollographql.ijplugin.telemetry.TelemetryProperty.ApolloWarnOnDeprec import com.apollographql.ijplugin.telemetry.TelemetryProperty.GradleModuleCount import com.apollographql.ijplugin.telemetry.TelemetryProperty.GradleVersion import com.apollographql.ijplugin.telemetry.TelemetryProperty.IdeVersion +import com.apollographql.ijplugin.util.MavenCoordinates import com.apollographql.ijplugin.util.NOTIFICATION_GROUP_ID_TELEMETRY import com.apollographql.ijplugin.util.cast import com.apollographql.ijplugin.util.createNotification +import com.apollographql.ijplugin.util.getLibraryMavenCoordinates import com.apollographql.ijplugin.util.logd import com.apollographql.ijplugin.util.logw import com.intellij.ProjectTopics @@ -59,6 +62,7 @@ import com.intellij.ide.plugins.PluginManagerCore import com.intellij.notification.NotificationAction import com.intellij.notification.NotificationType import com.intellij.openapi.Disposable +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationNamesInfo import com.intellij.openapi.application.ex.ApplicationInfoEx import com.intellij.openapi.components.Service @@ -68,6 +72,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModuleRootEvent import com.intellij.openapi.roots.ModuleRootListener import com.intellij.profile.codeInspection.ProjectInspectionProfileManager +import kotlinx.coroutines.runBlocking import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.ScheduledFuture @@ -76,14 +81,8 @@ import java.util.concurrent.TimeUnit private const val DATA_PRIVACY_URL = "https://www.apollographql.com/docs/graphos/data-privacy/" -/** - * TODO remove this - */ -const val TELEMETRY_ENABLED = false - private const val SEND_PERIOD_MINUTES = 30L - @Service(Service.Level.PROJECT) class TelemetryService( private val project: Project, @@ -95,7 +94,7 @@ class TelemetryService( private val telemetryEventList: TelemetryEventList = TelemetryEventList() - private var projectLibraries: Set = emptySet() + private var projectLibraries: Set = emptySet() private val executor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor() private var sendTelemetryFuture: ScheduledFuture<*>? = null @@ -123,16 +122,16 @@ class TelemetryService( private fun onLibrariesChanged() { logd() - projectLibraries = project.getProjectDependencies() + projectLibraries = project.getLibraryMavenCoordinates() } private fun startObserveSettings() { logd() - project.messageBus.connect(this).subscribe(SettingsListener.TOPIC, object : SettingsListener { - var telemetryEnabled = project.settingsState.telemetryEnabled - override fun settingsChanged(settingsState: SettingsState) { - val telemetryEnabledChanged = telemetryEnabled != settingsState.telemetryEnabled - telemetryEnabled = settingsState.telemetryEnabled + ApplicationManager.getApplication().messageBus.connect(this).subscribe(AppSettingsListener.TOPIC, object : AppSettingsListener { + var telemetryEnabled = appSettingsState.telemetryEnabled + override fun settingsChanged(appSettingsState: AppSettingsState) { + val telemetryEnabledChanged = telemetryEnabled != appSettingsState.telemetryEnabled + telemetryEnabled = appSettingsState.telemetryEnabled logd("telemetryEnabledChanged=$telemetryEnabledChanged") if (telemetryEnabledChanged) { scheduleSendTelemetry() @@ -142,7 +141,7 @@ class TelemetryService( } fun logEvent(telemetryEvent: TelemetryEvent) { - if (!project.settingsState.telemetryEnabled) return + if (!appSettingsState.telemetryEnabled) return logd("telemetryEvent=$telemetryEvent") telemetryEventList.addEvent(telemetryEvent) } @@ -156,7 +155,7 @@ class TelemetryService( addAll(getIdeTelemetryProperties()) } return TelemetrySession( - instanceId = project.settingsState.telemetryInstanceId, + instanceId = project.projectSettingsState.telemetryInstanceId, properties = properties, events = telemetryEventList.events, ) @@ -170,18 +169,18 @@ class TelemetryService( add(IdeVersion(appName)) System.getProperties().getProperty("os.name")?.let { add(TelemetryProperty.IdeOS(it)) } PluginManagerCore.getPlugin(PluginId.getId("com.apollographql.ijplugin"))?.version?.let { add(ApolloIjPluginVersion(it)) } - add(ApolloIjPluginAutomaticCodegenTriggering(project.settingsState.automaticCodegenTriggering)) - add(ApolloIjPluginContributeConfigurationToGraphqlPlugin(project.settingsState.contributeConfigurationToGraphqlPlugin)) - add(ApolloIjPluginHasConfiguredGraphOsApiKeys(project.settingsState.apolloKotlinServiceConfigurations.isNotEmpty())) + add(ApolloIjPluginAutomaticCodegenTriggering(project.projectSettingsState.automaticCodegenTriggering)) + add(ApolloIjPluginContributeConfigurationToGraphqlPlugin(project.projectSettingsState.contributeConfigurationToGraphqlPlugin)) + add(ApolloIjPluginHasConfiguredGraphOsApiKeys(project.projectSettingsState.apolloKotlinServiceConfigurations.isNotEmpty())) ProjectInspectionProfileManager.getInstance(project).currentProfile.getInspectionTool("ApolloFieldInsights", project)?.tool?.cast()?.let { add(ApolloIjPluginHighLatencyFieldThreshold(it.thresholdMs)) } } private fun scheduleSendTelemetry() { - logd("telemetryEnabled=${project.settingsState.telemetryEnabled}") + logd("telemetryEnabled=${appSettingsState.telemetryEnabled}") sendTelemetryFuture?.cancel(true) - if (!project.settingsState.telemetryEnabled) return + if (!appSettingsState.telemetryEnabled) return sendTelemetryFuture = executor.scheduleAtFixedRate(::sendTelemetry, SEND_PERIOD_MINUTES, SEND_PERIOD_MINUTES, TimeUnit.MINUTES) } @@ -194,7 +193,7 @@ class TelemetryService( return } try { - doSendTelemetry(telemetrySession) + runBlocking { executeTelemetryNetworkCall(telemetrySession) } lastSentProperties = telemetrySession.properties telemetryEventList.clear() } catch (e: Exception) { @@ -202,25 +201,16 @@ class TelemetryService( } } - private fun doSendTelemetry(telemetrySession: TelemetrySession) { - logd() - // TODO Send to the network - telemetrySession.properties.forEach { logd(it) } - logd("---") - telemetrySession.events.forEach { logd(it) } - } - private fun maybeShowTelemetryOptOutDialog() { - if (!TELEMETRY_ENABLED) return - if (project.settingsState.hasShownTelemetryOptOutDialog) return - project.settingsState.hasShownTelemetryOptOutDialog = true + if (appSettingsState.hasShownTelemetryOptOutDialog) return + appSettingsState.hasShownTelemetryOptOutDialog = true createNotification( notificationGroupId = NOTIFICATION_GROUP_ID_TELEMETRY, title = ApolloBundle.message("telemetry.optOutDialog.title"), content = ApolloBundle.message("telemetry.optOutDialog.content"), type = NotificationType.INFORMATION, NotificationAction.create(ApolloBundle.message("telemetry.optOutDialog.optOut")) { _, notification -> - project.settingsState.telemetryEnabled = false + appSettingsState.telemetryEnabled = false notification.expire() }, NotificationAction.create(ApolloBundle.message("telemetry.optOutDialog.learnMore")) { _, _ -> @@ -281,7 +271,7 @@ private fun ApolloGradleToolingModel.toTelemetryProperties(): Set, List. + * Keeping the parameters flat helps with the analysis of the data. + */ val parameters: Any?, ) { @@ -30,13 +35,13 @@ sealed class TelemetryProperty( } /** - * Gradle dependencies used by the project. + * Apollo Kotlin Gradle dependency used by the project. */ class Dependency( group: String, artifact: String, version: String, - ) : TelemetryProperty("dependency_$group:$artifact", mapOf("version" to version)) + ) : TelemetryProperty("dependency_$group:$artifact", version) /** * Version of Kotlin (per kotlin-stdlib). @@ -196,7 +201,7 @@ sealed class TelemetryProperty( /** * Other Apollo Kotlin Gradle plugin options that are used for which we don't care about the value. */ - class ApolloUsedOptions(otherOptions: Set) : TelemetryProperty("ak_used_options", otherOptions) + class ApolloUsedOptions(otherOptions: List) : TelemetryProperty("ak_used_options", otherOptions) /** * Value of the Apollo Kotlin option `generateSourcesDuringGradleSync` if set. @@ -261,6 +266,11 @@ sealed class TelemetryProperty( sealed class TelemetryEvent( val type: String, + + /** + * Allowed types: primitives, Map, List. + * Keeping the parameters flat helps with the analysis of the data. + */ val parameters: Any?, ) { val date: Instant = Instant.now() diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/util/Apollo.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/util/Apollo.kt index 6baf11c6f38..e9cba64e8d9 100644 --- a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/util/Apollo.kt +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/util/Apollo.kt @@ -11,10 +11,8 @@ import com.intellij.openapi.vfs.VirtualFile fun Project.getApolloVersion(): ApolloVersion { var foundVersion = ApolloVersion.NONE service().orderEntries().librariesOnly().forEachLibrary { library -> - val components = library.name?.substringAfter(" ")?.split(":") ?: return@forEachLibrary true - if (components.size < 3) return@forEachLibrary true - val (group, _, version) = components - when (group) { + val mavenCoordinates = library.toMavenCoordinates() ?: return@forEachLibrary true + when (mavenCoordinates.group) { "com.apollographql.apollo" -> { foundVersion = ApolloVersion.V2 false @@ -22,12 +20,12 @@ fun Project.getApolloVersion(): ApolloVersion { "com.apollographql.apollo3" -> { when { - version.startsWith("3.") -> { + mavenCoordinates.version.startsWith("3.") -> { foundVersion = ApolloVersion.V3 false } - version.startsWith("4.") -> { + mavenCoordinates.version.startsWith("4.") -> { foundVersion = ApolloVersion.V4 false } diff --git a/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/util/MavenCoordinates.kt b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/util/MavenCoordinates.kt new file mode 100644 index 00000000000..47f8330022c --- /dev/null +++ b/intellij-plugin/src/main/kotlin/com/apollographql/ijplugin/util/MavenCoordinates.kt @@ -0,0 +1,28 @@ +package com.apollographql.ijplugin.util + +import com.intellij.openapi.components.service +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ProjectRootManager +import com.intellij.openapi.roots.libraries.Library + +data class MavenCoordinates( + val group: String, + val artifact: String, + val version: String, +) + +fun Library.toMavenCoordinates(): MavenCoordinates? { + val components = name?.substringAfter(" ")?.split(":") ?: return null + if (components.size < 3) return null + val version = (if (components.size == 3) components[2] else components[3]).substringBeforeLast("@") + return MavenCoordinates(components[0], components[1], version) +} + +fun Project.getLibraryMavenCoordinates(): Set { + val dependencies = mutableSetOf() + service().orderEntries().librariesOnly().forEachLibrary { library -> + library.toMavenCoordinates()?.let { dependencies.add(it) } + true + } + return dependencies +} diff --git a/intellij-plugin/src/test/testData/inspection/Apollo4Available.gradle.kts b/intellij-plugin/src/test/testData/inspection/Apollo4Available.gradle.kts index 1f4e96caf81..53ef9382a64 100644 --- a/intellij-plugin/src/test/testData/inspection/Apollo4Available.gradle.kts +++ b/intellij-plugin/src/test/testData/inspection/Apollo4Available.gradle.kts @@ -2,12 +2,12 @@ plugins { kotlin("jvm") version "1.8.10" val myVar = "" - id("com.apollographql.apollo3") version "4.0.0-alpha.3" + id("com.apollographql.apollo3") version "4.0.0-beta.1" id("com.apollographql.apollo3") version "3.8.2" // should report id("com.apollographql.apollo3") version myVar id("com.apollographql.apollo3") version "3${"8.2"}" - id("com.apollographql.apollo3").version("4.0.0-alpha.3") + id("com.apollographql.apollo3").version("4.0.0-beta.1") id("com.apollographql.apollo3").version("3.8.2") // should report id("com.apollographql.apollo3").version(myVar) id("com.apollographql.apollo3").version("3${"8.2"}") @@ -20,14 +20,14 @@ plugins { dependencies { val myVar = "" implementation("com.apollographql.apollo3", "apollo-runtime") - implementation("com.apollographql.apollo3", "apollo-runtime", "4.0.0-alpha.3") + implementation("com.apollographql.apollo3", "apollo-runtime", "4.0.0-beta.1") implementation("com.apollographql.apollo3", "apollo-runtime", "3.8.2") // should report implementation("com.apollographql.apollo3", "apollo-runtime", myVar) implementation("com.apollographql.apollo3", "apollo-runtime", "3${"8.2"}") implementation("some.other.group", "some.artifact", "3.8.2") implementation("com.apollographql.apollo3:apollo-runtime") - implementation("com.apollographql.apollo3:apollo-runtime:4.0.0-alpha.3") + implementation("com.apollographql.apollo3:apollo-runtime:4.0.0-beta.1") implementation("com.apollographql.apollo3:apollo-runtime:3.8.2") // should report implementation("com.apollographql.apollo3:apollo-runtime:${myVar}") implementation("com.apollographql.apollo3:apollo-runtime:3${"8.2"}") diff --git a/intellij-plugin/src/test/testData/migration/v3-to-v4/updateGradleDependenciesInLibsVersionsToml_after.versions.toml b/intellij-plugin/src/test/testData/migration/v3-to-v4/updateGradleDependenciesInLibsVersionsToml_after.versions.toml index 8e37377f10c..58fcd39dba0 100644 --- a/intellij-plugin/src/test/testData/migration/v3-to-v4/updateGradleDependenciesInLibsVersionsToml_after.versions.toml +++ b/intellij-plugin/src/test/testData/migration/v3-to-v4/updateGradleDependenciesInLibsVersionsToml_after.versions.toml @@ -1,17 +1,17 @@ [versions] # gradlePlugin versions androidBuildTools = "7.2.1" -apollo = "4.0.0-alpha.3" +apollo = "4.0.0-beta.1" [libraries] accompanist-insets = { module = "com.google.accompanist:accompanist-insets", version.ref = "accompanist" } -apollo-runtime-short = "com.apollographql.apollo3:apollo-runtime:4.0.0-alpha.3" -apollo-runtime-medium-version = { module = "com.apollographql.apollo3:apollo-runtime", version = "4.0.0-alpha.3" } +apollo-runtime-short = "com.apollographql.apollo3:apollo-runtime:4.0.0-beta.1" +apollo-runtime-medium-version = { module = "com.apollographql.apollo3:apollo-runtime", version = "4.0.0-beta.1" } apollo-runtime-medium-ref = { module = "com.apollographql.apollo3:apollo-runtime", version.ref = "apollo" } -apollo-runtime-long-version = { group = "com.apollographql.apollo3", name = "apollo-runtime", version = "4.0.0-alpha.3" } +apollo-runtime-long-version = { group = "com.apollographql.apollo3", name = "apollo-runtime", version = "4.0.0-beta.1" } apollo-runtime-long-ref = { group = "com.apollographql.apollo3", name = "apollo-runtime", version.ref = "apollo" } [plugins] -apollo-shortNotation = "com.apollographql.apollo3:4.0.0-alpha.3" +apollo-shortNotation = "com.apollographql.apollo3:4.0.0-beta.1" apollo-longNotation = { id = "com.apollographql.apollo3", version.ref = "apollo" } -apollo-referenceNotation = { id = "com.apollographql.apollo3", version = "4.0.0-alpha.3" } +apollo-referenceNotation = { id = "com.apollographql.apollo3", version = "4.0.0-beta.1" } diff --git a/intellij-plugin/src/test/testData/migration/v3-to-v4/upgradeGradlePluginInBuildGradleKts_after.gradle.kts b/intellij-plugin/src/test/testData/migration/v3-to-v4/upgradeGradlePluginInBuildGradleKts_after.gradle.kts index bd95c721add..e3f7e9e00ba 100644 --- a/intellij-plugin/src/test/testData/migration/v3-to-v4/upgradeGradlePluginInBuildGradleKts_after.gradle.kts +++ b/intellij-plugin/src/test/testData/migration/v3-to-v4/upgradeGradlePluginInBuildGradleKts_after.gradle.kts @@ -2,16 +2,16 @@ plugins { java kotlin("jvm") version "1.6.10" id("com.apollographql.apollo3") - id("com.apollographql.apollo3") version "4.0.0-alpha.3" - id("com.apollographql.apollo3") version "4.0.0-alpha.3" apply false - // TODO: Update version to 4.0.0-alpha.3 + id("com.apollographql.apollo3") version "4.0.0-beta.1" + id("com.apollographql.apollo3") version "4.0.0-beta.1" apply false + // TODO: Update version to 4.0.0-beta.1 id("com.apollographql.apollo3") version someClass.someConstant - // TODO: Update version to 4.0.0-alpha.3 + // TODO: Update version to 4.0.0-beta.1 id("com.apollographql.apollo3") version "${someClass.someConstant}" - id("com.apollographql.apollo3") version "4.0.0-alpha.3" - id("com.apollographql.apollo3") version "4.0.0-alpha.3" apply false - // TODO: Update version to 4.0.0-alpha.3 + id("com.apollographql.apollo3") version "4.0.0-beta.1" + id("com.apollographql.apollo3") version "4.0.0-beta.1" apply false + // TODO: Update version to 4.0.0-beta.1 id("com.apollographql.apollo3") version someClass.someConstant - // TODO: Update version to 4.0.0-alpha.3 + // TODO: Update version to 4.0.0-beta.1 id("com.apollographql.apollo3") version "${someClass.someConstant}" } diff --git a/libraries/apollo-tooling/build.gradle.kts b/libraries/apollo-tooling/build.gradle.kts index 0c811a92f3c..22abf66b6d1 100644 --- a/libraries/apollo-tooling/build.gradle.kts +++ b/libraries/apollo-tooling/build.gradle.kts @@ -71,6 +71,7 @@ apollo { endpointUrl.set("https://graphql.api.apollographql.com/api/graphql") schemaFile.set(file("src/main/graphql/platform-api/internal/schema.graphqls")) } + mapScalar("Timestamp", "java.time.Instant", "com.apollographql.apollo3.tooling.TimestampAdapter") } } diff --git a/libraries/apollo-tooling/src/main/graphql/platform-api/internal/operations.graphql b/libraries/apollo-tooling/src/main/graphql/platform-api/internal/operations.graphql index 061a8441e49..ffc31a5e61c 100644 --- a/libraries/apollo-tooling/src/main/graphql/platform-api/internal/operations.graphql +++ b/libraries/apollo-tooling/src/main/graphql/platform-api/internal/operations.graphql @@ -3,7 +3,7 @@ mutation RegisterOperations( $clientIdentity: RegisteredClientIdentityInput! $operations: [RegisteredOperationInput!]! $manifestVersion: Int! - $graphVariant: String + $graphVariant: String! ) { service(id: $id) { registerOperationsWithResponse( @@ -43,3 +43,7 @@ query FieldLatencies($serviceId: ID!, $fromTimestamp: Timestamp!, $percentile: F } } } + +mutation TrackApolloKotlinUsage($instanceId: ID!, $properties: [ApolloKotlinUsagePropertyInput!]!, $events: [ApolloKotlinUsageEventInput!]!) { + trackApolloKotlinUsage(instanceId: $instanceId, properties: $properties, events: $events) +} diff --git a/libraries/apollo-tooling/src/main/graphql/platform-api/internal/schema.graphqls b/libraries/apollo-tooling/src/main/graphql/platform-api/internal/schema.graphqls index ec20a2ab3bc..aa4c2c2b395 100644 --- a/libraries/apollo-tooling/src/main/graphql/platform-api/internal/schema.graphqls +++ b/libraries/apollo-tooling/src/main/graphql/platform-api/internal/schema.graphqls @@ -4,39 +4,24 @@ An organization in Apollo Studio. Can have multiple members and graphs. type Account { billingInfo: BillingInfo - billingInfoV2: BillingInfoV2 @deprecated(reason: "Use `billingInfo`.") - billingInsights(from: Date!, limit: Int, to: Date, windowSize: BillingUsageStatsWindowSize): BillingInsights! currentBillingMonth: BillingMonth currentPlan: BillingPlan! - currentPlanV2: BillingPlanV2! @deprecated(reason: "Use `currentPlan`.") - currentSubscription: BillingSubscription - currentSubscriptionV2: BillingSubscriptionV2 @deprecated(reason: "Use `currentSubscription`.") - eligibleForUsageBasedPlan: Boolean! expiredTrialDismissedAt: Timestamp expiredTrialSubscription: BillingSubscription - expiredTrialSubscriptionV2: BillingSubscriptionV2 @deprecated(reason: "Use `expiredTrialSubscription`.") - hasBeenOnTrial: Boolean! - hasBeenOnTrialV2: Boolean! @deprecated(reason: "Use `hasBeenOnTrial`.") - hasBillingInfo: Boolean - """ - Globally unique identifier, which isn't guaranteed stable (can be changed by administrators). - """ - id: ID! - """ Internal immutable identifier for the account. Only visible to Apollo admins (because it really shouldn't be used in normal client apps). @@ -45,10 +30,14 @@ type Account { invoices: [Invoice!]! + isLocked: Boolean + isOnExpiredTrial: Boolean! isOnTrial: Boolean! + lockDetails: AccountLockDetails + """ Fetches usage based pricing operations counts for the calling user. If a particular window is not specified, totals for the user's current billing period are returned. (Will error if the user is not currently on a usage @@ -62,7 +51,51 @@ type Account { subscriptions: [BillingSubscription!]! - subscriptionsV2: [BillingSubscriptionV2!]! @deprecated(reason: "Use `subscriptions`.") + survey(id: String!): Survey + + """ + Fetch a CloudOnboarding associated with this account + """ + cloudOnboarding(graphRef: String!): CloudOnboarding + + """ + List the private subgraphs associated with your Apollo account + """ + privateSubgraphs(cloudProvider: CloudProvider!): [PrivateSubgraph!]! + + companyUrl: String + + """ + Globally unique identifier, which isn't guaranteed stable (can be changed by administrators). + """ + id: ID! + + invitations(includeAccepted: Boolean! = false): [AccountInvitation!] + + """ + Name of the organization, which can change over time and isn't unique. + """ + name: String! + + roles: AccountRoles + + """ + How many seats would be included in your next bill, as best estimated today + """ + seatCountForNextBill: Int + + seats: Seats + + """ + If non-null, this organization tracks its members through an upstream, eg PingOne; + invitations are not possible on SSO-synchronized account. + """ + sso: OrganizationSSO + + """ + A list of reusable invitations for the organization. + """ + staticInvitations: [OrganizationInviteLink!] auditLogExports: [AuditLogExport!] @@ -90,7 +123,10 @@ type Account { billingContactEmail: String - companyUrl: String + """ + The time at which the account was created + """ + createdAt: Timestamp graphIDAvailable(id: ID!): Boolean! @@ -104,28 +140,12 @@ type Account { """ graphsConnection("Return the elements in the list that come after the specified cursor." after: String, "Return the elements in the list that come before the specified cursor." before: String, "Filtering options for graphs returned from the connection. Defaults to returning all graphs." filterBy: GraphFilter, "Return the first n elements from the list." first: Int, "Return the last n elements from the list." last: Int): AccountGraphConnection - invitations(includeAccepted: Boolean! = false): [AccountInvitation!] - memberships: [AccountMembership!] - """ - Name of the organization, which can change over time and isn't unique. - """ - name: String! - - provisionedAt: Timestamp + provisionedAt: Timestamp @deprecated(reason: "use Account.createdAt instead") requests(from: Timestamp!, to: Timestamp!): Long - roles: AccountRoles - - """ - How many seats would be included in your next bill, as best estimated today - """ - seatCountForNextBill: Int - - seats: Seats - secondaryIDs: [ID!]! """ @@ -133,18 +153,7 @@ type Account { """ services(includeDeleted: Boolean): [Service!]! @deprecated(reason: "Use graphs field instead") - """ - If non-null, this organization tracks its members through an upstream, eg PingOne; - invitations are not possible on SSO-synchronized account. - """ - sso: OrganizationSSO - - state: AccountState - - """ - A list of reusable invitations for the organization. - """ - staticInvitations: [OrganizationInviteLink!] + state: AccountState @deprecated(reason: "no longer relevant; it's only ever populated for enterprise accounts") stats(from: Timestamp!, "Granularity of buckets. Defaults to the entire range (aggregate all data into a single durationBucket) when null." resolution: Resolution, "Defaults to the current time when null." to: Timestamp): AccountStatsWindow! @deprecated(reason: "use Account.statsWindow instead") @@ -163,7 +172,7 @@ type Account { """ All Variants within the Graphs belonging to this organization. Can be limited to those favorited by the current user. """ - variants("Filtering options for graph variants returned from the connection. Defaults to returning all graph variants." filterBy: GraphVariantFilter = ALL): AccountGraphVariantConnection + variants("Filtering options for graph variants returned from the connection. Defaults to returning all graph variants." filterBy: GraphVariantFilter = ALL): AccountGraphVariantConnection @deprecated(reason: "use Service.variants instead") """ Returns a different registry related stats pertaining to this account. @@ -173,26 +182,6 @@ type Account { vitallyTraits: AccountCustomerTraits } -""" -The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1. -""" -scalar Int - -""" -The `Boolean` scalar type represents `true` or `false`. -""" -scalar Boolean - -""" -The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID. -""" -scalar ID - -""" -The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text. -""" -scalar String - """ Columns of AccountBillingUsageStats. """ @@ -205,6 +194,10 @@ enum AccountBillingUsageStatsColumn { OPERATION_COUNT_PROVIDED_EXPLICITLY + OPERATION_SUBTYPE + + OPERATION_TYPE + SCHEMA_TAG SERVICE_ID @@ -219,6 +212,10 @@ type AccountBillingUsageStatsDimensions { operationCountProvidedExplicitly: String + operationSubtype: String + + operationType: String + schemaTag: String serviceId: ID @@ -249,6 +246,16 @@ input AccountBillingUsageStatsFilter { """ operationCountProvidedExplicitly: String + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [AccountBillingUsageStatsFilter!] """ @@ -281,6 +288,16 @@ input AccountBillingUsageStatsFilterIn { """ operationCountProvidedExplicitly: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose schemaTag dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -990,6 +1007,10 @@ enum AccountFieldUsageColumn { FIELD_NAME + OPERATION_SUBTYPE + + OPERATION_TYPE + PARENT_TYPE QUERY_ID @@ -1014,6 +1035,10 @@ type AccountFieldUsageDimensions { fieldName: String + operationSubtype: String + + operationType: String + parentType: String queryId: ID @@ -1052,6 +1077,16 @@ input AccountFieldUsageFilter { not: AccountFieldUsageFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [AccountFieldUsageFilter!] """ @@ -1104,6 +1139,16 @@ input AccountFieldUsageFilterIn { """ fieldName: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose parentType dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -1201,6 +1246,138 @@ type AccountGraphEdge { node: Service } +""" +Columns of AccountGraphosCloudMetrics. +""" +enum AccountGraphosCloudMetricsColumn { + AGENT_VERSION + + RESPONSE_SIZE + + RESPONSE_SIZE_THROTTLED + + ROUTER_ID + + ROUTER_OPERATIONS + + ROUTER_OPERATIONS_THROTTLED + + SCHEMA_TAG + + SERVICE_ID + + SUBGRAPH_FETCHES + + SUBGRAPH_FETCHES_THROTTLED + + TIMESTAMP +} + +type AccountGraphosCloudMetricsDimensions { + agentVersion: String + + routerId: String + + schemaTag: String + + serviceId: ID +} + +""" +Filter for data in AccountGraphosCloudMetrics. Fields with dimension names represent equality checks. All fields are implicitly ANDed together. +""" +input AccountGraphosCloudMetricsFilter { + """ + Selects rows whose agentVersion dimension equals the given value if not null. To query for the null value, use {in: {agentVersion: [null]}} instead. + """ + agentVersion: String + + and: [AccountGraphosCloudMetricsFilter!] + + in: AccountGraphosCloudMetricsFilterIn + + not: AccountGraphosCloudMetricsFilter + + or: [AccountGraphosCloudMetricsFilter!] + + """ + Selects rows whose routerId dimension equals the given value if not null. To query for the null value, use {in: {routerId: [null]}} instead. + """ + routerId: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID +} + +""" +Filter for data in AccountGraphosCloudMetrics. Fields match if the corresponding dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input AccountGraphosCloudMetricsFilterIn { + """ + Selects rows whose agentVersion dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + agentVersion: [String] + + """ + Selects rows whose routerId dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + routerId: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + serviceId: [ID] +} + +type AccountGraphosCloudMetricsMetrics { + responseSize: Long! + + responseSizeThrottled: Long! + + routerOperations: Long! + + routerOperationsThrottled: Long! + + subgraphFetches: Long! + + subgraphFetchesThrottled: Long! +} + +input AccountGraphosCloudMetricsOrderBySpec { + column: AccountGraphosCloudMetricsColumn! + + direction: Ordering! +} + +type AccountGraphosCloudMetricsRecord { + """ + Dimensions of AccountGraphosCloudMetrics that can be grouped by. + """ + groupBy: AccountGraphosCloudMetricsDimensions! + + """ + Metrics of AccountGraphosCloudMetrics that can be aggregated over. + """ + metrics: AccountGraphosCloudMetricsMetrics! + + """ + Starting segment timestamp. + """ + timestamp: Timestamp! +} + """ A list of all variants from all graphs attached to the account. """ @@ -1272,6 +1449,22 @@ type AccountInvitation { role: UserPermission! } +type AccountLockDetails { + actor: String + + reason: String + + timestamp: Timestamp + + type: AccountLockType +} + +enum AccountLockType { + AUTOMATED_TRIAL_END + + MANUAL +} + type AccountMembership { account: Account! @@ -1294,16 +1487,16 @@ type AccountMutation { """ cancelSubscriptions: Account + currentSubscription: BillingSubscriptionMutation + """ - Changes an annual team subscription to a monthly team subscription when the current period expires. + If the org is on an enterprise trial, set the end date to a new value. """ - convertAnnualTeamSubscriptionToMonthlyAtNextPeriod: Account + extendTrial: Account """ - Acknowledge that a trial has expired and return to community + Get reference to the account ID """ - dismissExpiredTrial: Account - internalID: String """ @@ -1327,11 +1520,6 @@ type AccountMutation { """ setPlan(id: ID!): Void - """ - Start a new team subscription with the given billing period. - """ - startTeamSubscription(billingPeriod: BillingPeriod!): Account - """ Apollo admins only: Terminate the ongoing subscription in the account as soon as possible, without refunds. """ @@ -1343,21 +1531,27 @@ type AccountMutation { """ terminateSubscriptions: Account - auditExport(id: String!): AuditLogExportMutation - - createGraph(graphType: GraphType!, hiddenFromUninvitedNonAdmin: Boolean!, id: ID!, title: String!, variantCreationConfig: VariantCreationConfig): GraphCreationResult! + """ + Update the billing address for a Recurly token + """ + updateBillingAddress(billingAddress: BillingAddressInput!): Account - createStaticInvitation(role: UserPermission!): OrganizationInviteLink + """ + Update the billing information from a Recurly token + """ + updateBillingInfo(token: String!): Void """ - Delete the account's avatar. Requires Account.canUpdateAvatar to be true. + Create a CloudOnboarding for this account """ - deleteAvatar: AvatarDeleteError + createCloudOnboarding(input: CloudOnboardingInput!): CreateOnboardingResult! """ - Hard delete an account and all associated services + Mutations for interacting with an Apollo account's private subgraphs on GraphOS """ - hardDelete: Void + privateSubgraph: PrivateSubgraphMutation! + + createStaticInvitation(role: UserPermission!): OrganizationInviteLink """ Send an invitation to join the account by E-mail @@ -1365,60 +1559,74 @@ type AccountMutation { invite(email: String!, role: UserPermission): AccountInvitation """ - Delete an invitation + Send a new E-mail for an existing invitation """ - removeInvitation(id: ID): Void + resendInvitation(id: ID): AccountInvitation + + revokeStaticInvitation(token: String!): OrganizationInviteLink + + updateCompanyUrl(companyUrl: String): Account """ - Remove a member of the account + Update the account ID """ - removeMember(id: ID!): Account + updateID(id: ID!): Account """ - Trigger a request for an audit export + Update the company name """ - requestAuditExport(actors: [ActorInput!], from: Timestamp!, graphIds: [String!], to: Timestamp!): Account + updateName(name: String!): Void + + auditExport(id: String!): AuditLogExportMutation + + createGraph(graphType: GraphType!, hiddenFromUninvitedNonAdmin: Boolean!, id: ID!, title: String!, variantCreationConfig: VariantCreationConfig): GraphCreationResult! """ - Send a new E-mail for an existing invitation + Delete the account's avatar. Requires Account.canUpdateAvatar to be true. """ - resendInvitation(id: ID): AccountInvitation - - revokeStaticInvitation(token: String!): OrganizationInviteLink + deleteAvatar: AvatarDeleteError """ - This is called by the form shown to users after they cancel their team subscription. + Hard delete an account and all associated services """ - submitTeamCancellationFeedback(feedback: String!): Void + hardDelete: Void - trackTermsAccepted(at: Timestamp!): Void + """ + Lock an account, which limits the functionality available with regard to its graphs. + """ + lock(reason: String, type: AccountLockType): Account """ - Update the billing address for a Recurly token + Delete an invitation """ - updateBillingAddress(billingAddress: BillingAddressInput!): Account + removeInvitation(id: ID): Void """ - Update the billing information from a Recurly token + Remove a member of the account """ - updateBillingInfo(token: String!): Void + removeMember(id: ID!): Account - updateCompanyUrl(companyUrl: String): Account + """ + Trigger a request for an audit export + """ + requestAuditExport(actors: [ActorInput!], from: Timestamp!, graphIds: [String!], to: Timestamp!): Account """ - Set the E-mail address of the account, used notably for billing + This is called by the form shown to users after they cancel their team subscription. """ - updateEmail(email: String!): Void + submitTeamCancellationFeedback(feedback: String!): Void + + trackTermsAccepted(at: Timestamp!): Void """ - Update the account ID + Unlock a locked account. """ - updateID(id: ID!): Account + unlock: Account """ - Update the company name + Set the E-mail address of the account, used notably for billing """ - updateName(name: String!): Void + updateEmail(email: String!): Void """ Apollo admins only: enable or disable an account for PingOne SSO login @@ -1446,6 +1654,10 @@ enum AccountOperationCheckStatsColumn { CLIENT_VERSION + OPERATION_SUBTYPE + + OPERATION_TYPE + QUERY_ID QUERY_NAME @@ -1464,6 +1676,10 @@ type AccountOperationCheckStatsDimensions { clientVersion: String + operationSubtype: String + + operationType: String + queryId: ID queryName: String @@ -1493,6 +1709,16 @@ input AccountOperationCheckStatsFilter { not: AccountOperationCheckStatsFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [AccountOperationCheckStatsFilter!] """ @@ -1530,6 +1756,16 @@ input AccountOperationCheckStatsFilterIn { """ clientVersion: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -1628,6 +1864,10 @@ enum AccountQueryStatsColumn { FROM_ENGINEPROXY + OPERATION_SUBTYPE + + OPERATION_TYPE + QUERY_ID QUERY_NAME @@ -1656,12 +1896,18 @@ type AccountQueryStatsDimensions { fromEngineproxy: String + operationSubtype: String + + operationType: String + queryId: ID queryName: String querySignature: String + querySignatureLength: Int + schemaHash: String schemaTag: String @@ -1694,6 +1940,16 @@ input AccountQueryStatsFilter { not: AccountQueryStatsFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [AccountQueryStatsFilter!] """ @@ -1741,6 +1997,16 @@ input AccountQueryStatsFilterIn { """ fromEngineproxy: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -1815,14 +2081,10 @@ type AccountQueryStatsRecord { type AccountRoles { canAudit: Boolean! - canCreateDevGraph: Boolean! @deprecated(reason: "No longer supported") - canCreateService: Boolean! canDelete: Boolean! - canDownloadInvoice: Boolean! @deprecated(reason: "Use canQueryBillingInfo instead") - canManageMembers: Boolean! canQuery: Boolean! @@ -1831,8 +2093,6 @@ type AccountRoles { canQueryBillingInfo: Boolean! - canQueryInvoices: Boolean! @deprecated(reason: "Use canQueryBillingInfo instead") - canQueryMembers: Boolean! canQueryStats: Boolean! @@ -1874,6 +2134,8 @@ type AccountStatsWindow { fieldUsage("Filter to select what rows to return." filter: AccountFieldUsageFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order AccountFieldUsage by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [AccountFieldUsageOrderBySpec!]): [AccountFieldUsageRecord!]! + graphosCloudMetrics("Filter to select what rows to return." filter: AccountGraphosCloudMetricsFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order AccountGraphosCloudMetrics by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [AccountGraphosCloudMetricsOrderBySpec!]): [AccountGraphosCloudMetricsRecord!]! + operationCheckStats("Filter to select what rows to return." filter: AccountOperationCheckStatsFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order AccountOperationCheckStats by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [AccountOperationCheckStatsOrderBySpec!]): [AccountOperationCheckStatsRecord!]! queryStats("Filter to select what rows to return." filter: AccountQueryStatsFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order AccountQueryStats by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [AccountQueryStatsOrderBySpec!]): [AccountQueryStatsRecord!]! @@ -2139,7 +2401,9 @@ enum AccountTraceRefsColumn { DURATION_BUCKET - DURATION_NS + OPERATION_SUBTYPE + + OPERATION_TYPE QUERY_ID @@ -2153,9 +2417,9 @@ enum AccountTraceRefsColumn { TIMESTAMP - TRACE_ID + TRACE_COUNT - TRACE_SIZE_BYTES + TRACE_ID } type AccountTraceRefsDimensions { @@ -2165,6 +2429,12 @@ type AccountTraceRefsDimensions { durationBucket: Int + generatedTraceId: String + + operationSubtype: String + + operationType: String + queryId: ID queryName: String @@ -2205,6 +2475,16 @@ input AccountTraceRefsFilter { not: AccountTraceRefsFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [AccountTraceRefsFilter!] """ @@ -2257,6 +2537,16 @@ input AccountTraceRefsFilterIn { """ durationBucket: [Int] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -2289,9 +2579,7 @@ input AccountTraceRefsFilterIn { } type AccountTraceRefsMetrics { - durationNs: Long! - - traceSizeBytes: Long! + traceCount: Long! } input AccountTraceRefsOrderBySpec { @@ -2353,6 +2641,23 @@ enum ActorType { USER } +""" +parentCommentId is only present for replies. schemaCoordinate & subgraph are only present for initial change comments. If all are absent, this is a general parent comment on the proposal. +""" +input AddCommentInput { + message: String! + + parentCommentId: String + + revisionId: String! + + schemaCoordinate: String + + schemaScope: String +} + +union AddCommentResult = NotFoundError|ParentChangeProposalComment|ParentGeneralProposalComment|ReplyChangeProposalComment|ReplyGeneralProposalComment|ValidationError + union AddOperationCollectionEntriesResult = AddOperationCollectionEntriesSuccess|PermissionError|ValidationError type AddOperationCollectionEntriesSuccess { @@ -2473,6 +2778,41 @@ type ApiKeyProvision { created: Boolean! } +""" +A generic event for the `trackApolloKotlinUsage` mutation +""" +input ApolloKotlinUsageEventInput { + """ + When the event occurred + """ + date: Timestamp! + + """ + Optional parameters attached to the event + """ + payload: Object + + """ + Type of event + """ + type: ID! +} + +""" +A generic property for the `trackApolloKotlinUsage` mutation +""" +input ApolloKotlinUsagePropertyInput { + """ + Optional parameters attached to the property + """ + payload: Object + + """ + Type of property + """ + type: ID! +} + enum AuditAction { BroadcastMessage @@ -2607,6 +2947,61 @@ enum AvatarUploadErrorCode { union AvatarUploadResult = AvatarUploadError|MediaUploadInfo +""" +AWS-specific information for a Shard +""" +type AwsShard { + """ + AWS Account ID where the Shard is hosted + """ + accountId: String! + + """ + ARN of the ECS Cluster + """ + ecsClusterArn: String! + + """ + DNS endpoint for the load balancer + """ + endpoint: String! + + """ + ARN of the IAM role to perform provisioning operations on this shard + """ + iamRoleArn: String! + + """ + ARN of the load balancer + """ + loadbalancerArn: String! + + """ + ARN of the load balancer listener + """ + loadbalancerListenerArn: String! + + """ + ID of the security group for the load balancer + """ + loadbalancerSecurityGroupId: String! + + """ + ARN of the IAM permissions boundaries for IAM roles provisioned in this shard + """ + permissionsBoundaryArn: String! + + """ + IDs of the subnets + """ + subnetIds: [String!]! + + """ + ID of the VPC + """ + vpcId: String! +} + scalar BigInt type BillableMetricStats { @@ -2630,7 +3025,7 @@ type BillingAddress { } """ -Billing address inpnut +Billing address input """ input BillingAddressInput { address1: String! @@ -2653,32 +3048,35 @@ type BillingAdminQuery { currentPlanFromGrpc(internalAccountId: ID!): GQLBillingPlanFromGrpc } -type BillingInfo { - address: BillingAddress! - - cardType: String - - firstName: String - - lastFour: Int +type BillingCapability { + defaultValue: Boolean! - lastName: String + intendedUse: String! - month: Int + label: String! +} - name: String +""" +Billing capability input +""" +input BillingCapabilityInput { + defaultValue: Boolean! - vatNumber: String + intendedUse: String! - year: Int + label: String! } -type BillingInfoV2 { +type BillingInfo { address: BillingAddress! cardType: String - lastFour: String + firstName: String + + lastFour: Int + + lastName: String month: Int @@ -2701,6 +3099,25 @@ type BillingInsightsUsage { totalOperationCount: Long! } +type BillingLimit { + defaultValue: Long! + + intendedUse: String! + + label: String! +} + +""" +Billing limit input +""" +input BillingLimitInput { + defaultValue: Long! + + intendedUse: String! + + label: String! +} + enum BillingModel { REQUEST_BASED @@ -2716,6 +3133,11 @@ type BillingMonth { } type BillingMutation { + """ + Temporary utility mutation to convert annual team plan orgs to monthly team plans + """ + convertAnnualTeamOrgToMonthly(internalAccountId: ID!): Void + createSetupIntent(internalAccountId: ID!): SetupIntentResult endPaidUsageBasedPlan(internalAccountId: ID!): EndUsageBasedPlanResult @@ -2744,6 +3166,16 @@ enum BillingPeriod { type BillingPlan { addons: [BillingPlanAddon!]! + """ + Retrieve all capabilities for the plan + """ + allCapabilities: [BillingPlanCapability!]! + + """ + Retrieve a list of all effective capability limits for this plan + """ + allLimits: [BillingPlanLimit!]! + billingModel: BillingModel! billingPeriod: BillingPeriod @@ -2760,10 +3192,20 @@ type BillingPlan { description: String + """ + Retrieve the limit applied to this plan for a capability + """ + effectiveLimit(label: String!): Long + errors: Boolean! federation: Boolean! + """ + Check whether a capability is enabled for the plan + """ + hasCapability(label: String!): Boolean + id: ID! isTrial: Boolean! @@ -2777,7 +3219,7 @@ type BillingPlan { maxRangeInDays: Int """ - The maximum number of days that checks stats will be stored. + The maximum number of days that checks stats will be stored """ maxRangeInDaysForChecks: Int @@ -2791,6 +3233,8 @@ type BillingPlan { operationRegistry: Boolean! + persistedQueries: Boolean! + """ The price of every seat """ @@ -2825,10 +3269,13 @@ type BillingPlanAddon { pricePerUnitInUsdCents: Int! } -type BillingPlanAddonV2 { - id: ID! +""" +Billing plan addon input +""" +input BillingPlanAddonInput { + code: String - pricePerUnitInUsdCents: Int! + usdCentsPrice: Int } type BillingPlanCapabilities { @@ -2860,6 +3307,8 @@ type BillingPlanCapabilities { operationRegistry: Boolean! + persistedQueries: Boolean! + ranges: [String!]! schemaValidation: Boolean! @@ -2871,168 +3320,168 @@ type BillingPlanCapabilities { webhooks: Boolean! } -enum BillingPlanKind { - COMMUNITY +type BillingPlanCapability { + label: String! - ENTERPRISE_INTERNAL + plan: BillingPlan! - ENTERPRISE_PAID + value: Boolean! +} - ENTERPRISE_PILOT +""" +Billing plan input +""" +input BillingPlanInput { + addons: [BillingPlanAddonInput!]! - ENTERPRISE_TRIAL + billingModel: BillingModel! - ONE_FREE + billingPeriod: BillingPeriod! - ONE_PAID + clientVersions: Boolean - SERVERLESS + clients: Boolean - SERVERLESS_FREE + contracts: Boolean - SERVERLESS_PAID + datadog: Boolean - STARTER + description: String! - TEAM_PAID + errors: Boolean - TEAM_TRIAL + federation: Boolean - UNKNOWN -} + id: ID! -enum BillingPlanKindV2 { - COMMUNITY - - ENTERPRISE_INTERNAL - - ENTERPRISE_PAID + kind: BillingPlanKind! - ENTERPRISE_PILOT + launches: Boolean - ENTERPRISE_TRIAL + maxAuditInDays: Int - ONE_FREE + maxRangeInDays: Int - ONE_PAID + maxRangeInDaysForChecks: Int - SERVERLESS + maxRequestsPerMonth: Long - SERVERLESS_FREE + metrics: Boolean - SERVERLESS_PAID + name: String! - STARTER + notifications: Boolean - TEAM_PAID + operationRegistry: Boolean - TEAM_TRIAL + persistedQueries: Boolean - UNKNOWN -} + pricePerSeatInUsdCents: Int -enum BillingPlanTier { - COMMUNITY + pricePerUnitInUsdCents: Int - ENTERPRISE + public: Boolean! - ONE + schemaValidation: Boolean - TEAM + traces: Boolean - UNKNOWN + userRoles: Boolean - USAGE_BASED + webhooks: Boolean } -enum BillingPlanTierV2 { +enum BillingPlanKind { COMMUNITY - ENTERPRISE - - ONE - - TEAM - - UNKNOWN - - USAGE_BASED -} + DEDICATED -type BillingPlanV2 { - addons: [BillingPlanAddonV2!]! + ENTERPRISE_INTERNAL - billingModel: BillingModel! + ENTERPRISE_PAID - billingPeriod: BillingPeriod + ENTERPRISE_PILOT - clientVersions: Boolean! + ENTERPRISE_TRIAL - clients: Boolean! + ONE_FREE - contracts: Boolean! + ONE_PAID - datadog: Boolean! + SERVERLESS - description: String + SERVERLESS_FREE - errors: Boolean! + SERVERLESS_PAID - federation: Boolean! + STARTER - id: ID! + TEAM_PAID - isTrial: Boolean! + TEAM_TRIAL - kind: BillingPlanKindV2! + UNKNOWN +} - launches: Boolean! +type BillingPlanLimit { + label: String! - maxAuditInDays: Int! + plan: BillingPlan! - maxRangeInDays: Int + value: Long! +} +type BillingPlanMutation { """ - The maximum number of days that checks stats will be stored. + Archive this billing plan """ - maxRangeInDaysForChecks: Int - - maxRequestsPerMonth: Long + archive: Void - metrics: Boolean! + """ + Remove the specified capability from this plan + """ + clearCapability(label: String!): Void - name: String! + """ + Remove the specified limit from this plan + """ + clearLimit(label: String!): Void - notifications: Boolean! + id: ID! - operationRegistry: Boolean! + """ + Reset the specified capability on this plan to the global default value for the capability + """ + resetCapability(label: String!): BillingPlanCapability """ - The price of every seat + Reset the specified limit on this plan to the global default value for the limit """ - pricePerSeatInUsdCents: Int + resetLimit(label: String!): BillingPlanLimit """ - The price of subscribing to this plan with a quantity of 1 (currently always the case) + Sets the specified capability on this plan to the provided value """ - pricePerUnitInUsdCents: Int! + setCapability(label: String!, value: Boolean!): BillingPlanCapability """ - Whether the plan is accessible by all users in QueryRoot.allPlans, QueryRoot.plan, or AccountMutation.setPlan + Sets the specified limit on this plan to the provided value """ - public: Boolean! + setLimit(label: String!, value: Long!): BillingPlanLimit +} - ranges: [String!]! +enum BillingPlanTier { + COMMUNITY - schemaValidation: Boolean! + ENTERPRISE - tier: BillingPlanTierV2! + ONE - traces: Boolean! + TEAM - userRoles: Boolean! + UNKNOWN - webhooks: Boolean! + USAGE_BASED } type BillingSubscription { @@ -3040,6 +3489,16 @@ type BillingSubscription { addons: [BillingSubscriptionAddon!]! + """ + Retrieve all capabilities for this subscription + """ + allCapabilities: [SubscriptionCapability!]! + + """ + Retrieve a list of all effective capability limits for this subscription + """ + allLimits: [SubscriptionLimit!]! + autoRenew: Boolean! canceledAt: Timestamp @@ -3053,6 +3512,11 @@ type BillingSubscription { currentPeriodStartedAt: Timestamp! + """ + Retrieve the limit applied to this subscription for a capability + """ + effectiveLimit(label: String!): Long + expiresAt: Timestamp """ @@ -3060,6 +3524,11 @@ type BillingSubscription { """ graceTimeForNextRenewal: Timestamp + """ + Check whether a capability is enabled for the subscription + """ + hasCapability(label: String!): Boolean + maxSelfHostedRequestsPerMonth: Int maxServerlessRequestsPerMonth: Int @@ -3102,71 +3571,34 @@ type BillingSubscriptionAddon { quantity: Int! } -type BillingSubscriptionAddonV2 { - id: ID! - - pricePerUnitInUsdCents: Int! - - quantity: Int! -} - -type BillingSubscriptionV2 { - activatedAt: Timestamp! - - addons: [BillingSubscriptionAddonV2!]! - - autoRenew: Boolean! - - canceledAt: Timestamp - - """ - Draft invoice for this subscription - """ - currentDraftInvoice: DraftInvoice - - currentPeriodEndsAt: Timestamp! - - currentPeriodStartedAt: Timestamp! - - expiresAt: Timestamp - +type BillingSubscriptionMutation { """ - Renewal grace time for updating seat count + Remove the specified capability override for this subscription """ - graceTimeForNextRenewal: Timestamp - - maxSelfHostedRequestsPerMonth: Int - - maxServerlessRequestsPerMonth: Int - - plan: BillingPlanV2! + clearCapability(label: String!): Void """ - The price of every seat + Remove the specified limit override for this subscription """ - pricePerSeatInUsdCents: Int + clearLimit(label: String!): Void """ - The price of every unit in the subscription (hence multiplied by quantity to get to the basePriceInUsdCents) + Sets the capability override on this subscription to the provided value """ - pricePerUnitInUsdCents: Int! - - quantity: Int! + setCapability(label: String!, value: Boolean!): SubscriptionCapability """ - Total price of the subscription when it next renews, including add-ons (such as seats) + Sets the limit override on this subscription to the provided value """ - renewalTotalPriceInUsdCents: Long! + setLimit(label: String!, value: Long!): SubscriptionLimit - state: SubscriptionStateV2! + uuid: ID! +} - """ - When this subscription's trial period expires (if it is a trial). Not the same as the - subscription's Recurly expiration). - """ - trialExpiresAt: Timestamp +type BillingTier { + tier: BillingPlanTier! - uuid: ID! + searchAccounts(search: String): [Account!]! } """ @@ -3183,6 +3615,10 @@ enum BillingUsageStatsColumn { OPERATION_COUNT_PROVIDED_EXPLICITLY + OPERATION_SUBTYPE + + OPERATION_TYPE + SCHEMA_TAG SERVICE_ID @@ -3199,6 +3635,10 @@ type BillingUsageStatsDimensions { operationCountProvidedExplicitly: String + operationSubtype: String + + operationType: String + schemaTag: String serviceId: ID @@ -3234,6 +3674,16 @@ input BillingUsageStatsFilter { """ operationCountProvidedExplicitly: String + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [BillingUsageStatsFilter!] """ @@ -3271,6 +3721,16 @@ input BillingUsageStatsFilterIn { """ operationCountProvidedExplicitly: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose schemaTag dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -3339,18 +3799,6 @@ type Build { result: BuildResult } -interface BuildCheckError { - """ - The step at which the build failed. - """ - failedStep: String - - """ - A human-readable message describing the error. - """ - message: String! -} - interface BuildCheckFailed implements BuildCheckResult { buildInputs: BuildInputs! @@ -3359,7 +3807,7 @@ interface BuildCheckFailed implements BuildCheckResult { """ A list of errors generated by this build. """ - errors: [BuildCheckError!]! + errors: [BuildError!]! id: ID! @@ -3436,9 +3884,15 @@ interface BuildCheckTask implements CheckWorkflowTask { workflow: CheckWorkflow! } +""" +The configuration for building a composition graph variant +""" type BuildConfig { buildPipelineTrack: BuildPipelineTrack! + """ + Show all uses of @tag directives to consumers in Schema Reference and Explorer + """ tagInApiSchema: Boolean! } @@ -3470,6 +3924,8 @@ A single error that occurred during the failed execution of a build. type BuildError { code: String + failedStep: String + locations: [SourceLocation!]! message: String! @@ -3501,6 +3957,42 @@ enum BuildPipelineTrack { FED_2_3 FED_2_4 + + FED_2_5 +} + +enum BuildPipelineTrackBadge { + DEPRECATED + + EXPERIMENTAL + + LATEST + + UNSUPPORTED +} + +type BuildPipelineTrackDetails { + badge: BuildPipelineTrackBadge + + buildPipelineTrack: BuildPipelineTrack! + + """ + currently running version of composition for this track, includes patch updates + """ + compositionVersion: String! + + deprecatedAt: Timestamp + + displayName: String! + + minimumGatewayVersion: String + + """ + Minimum supported router and gateway versions. Min router version can be null since fed 1 doesn't have router support. + """ + minimumRouterVersion: String + + notSupportedAt: Timestamp } union BuildResult = BuildFailure|BuildSuccess @@ -3531,6 +4023,14 @@ enum CacheScope { UNRECOGNIZED } +type CannotDeleteLinkedPersistedQueryListError implements Error { + message: String! +} + +type CannotModifyOperationBodyError implements Error { + message: String! +} + """ A single change that was made to a definition in a schema. """ @@ -3831,6 +4331,38 @@ type ChangeOnOperation { impact: String } +interface ChangeProposalComment implements ProposalComment { + createdAt: Timestamp! + + """ + null if the user is deleted + """ + createdBy: Identity + + id: ID! + + message: String! + + """ + true if the schemaCoordinate this comment is on doesn't exist in the diff between the most recent revision & the base sdl + """ + outdated: Boolean! + + schemaCoordinate: String! + + """ + '#@!api!@#' for api schema, '#@!supergraph!@#' for supergraph schema, subgraph otherwise + """ + schemaScope: String! + + status: CommentStatus! + + """ + null if never updated + """ + updatedAt: Timestamp +} + enum ChangeSeverity { FAILURE @@ -3927,6 +4459,11 @@ type CheckConfiguration { """ includedVariants: [String!]! + """ + Whether to run Linting during schema checks. + """ + enableLintChecks: Boolean! + """ Time when check configuration was created """ @@ -3964,15 +4501,15 @@ type CheckConfiguration { Default configuration to include operations on the base variant. """ includeBaseVariant: Boolean! + + """ + How submitted build input diffs are handled when they match (or don't) a Proposal + """ + proposalChangeMismatchSeverity: ProposalChangeMismatchSeverity! } """ -The `Float` scalar type represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point). -""" -scalar Float - -""" -Filter options available when listing checks. +Filter options available when listing checks. """ input CheckFilterInput { authors: [String!] @@ -3984,6 +4521,10 @@ input CheckFilterInput { status: CheckFilterInputStatusOption variants: [String!] + + ids: [String!] + + includeProposalChecks: Boolean = false } """ @@ -3993,9 +4534,9 @@ This should always match CheckWorkflowStatus enum CheckFilterInputStatusOption { FAILED - PENDING - PASSED + + PENDING } """ @@ -4061,6 +4602,11 @@ input CheckSchemaAsyncInput { """ introspectionEndpoint: String + """ + If `true`, the check was initiated automatically by a Proposal update. + """ + isProposal: Boolean + """ If `true`, the check was initiated by Apollo Sandbox. """ @@ -4094,7 +4640,45 @@ type CheckSchemaResult { workflow: CheckWorkflow } +type CheckStepCompleted { + id: ID! + + status: CheckStepStatus! +} + +type CheckStepFailed { + message: String! +} + +input CheckStepInput { + graphID: String! + + graphVariant: String! + + taskID: ID! + + workflowID: ID! +} + +union CheckStepResult = CheckStepCompleted|CheckStepFailed|ValidationError + +enum CheckStepStatus { + FAILURE + + SUCCESS +} + type CheckWorkflow { + """ + The schema provided as the base to check against. + """ + baseSchemaHash: String + + """ + The base subgraphs provided as the base to check against. + """ + baseSubgraphs: [Subgraph!] + """ The variant provided as a base to check against. Only the differences from the base schema will be tested in operations checks. @@ -4133,6 +4717,16 @@ type CheckWorkflow { """ operationsTask: OperationsCheckTask + """ + The proposed schema being checked by this check workflow. + """ + proposedSchemaHash: String + + """ + The proposed subgraphs for this check workflow. + """ + proposedSubgraphs: [Subgraph!] + """ If this check was created by rerunning, the original check workflow that was rerun. """ @@ -4185,6 +4779,11 @@ type CheckWorkflow { """ isSandboxCheck: Boolean! + """ + Only true if the check was triggered from a proposal update. + """ + isProposalCheck: Boolean! + """ If this check is triggered for an sdl fetched using introspection, this is the endpoint where that schema was being served. """ @@ -4304,7 +4903,20 @@ type ClientInfoFilterOutput { version: String } +""" +Cloud queries +""" type Cloud { + """ + Return all RouterConfigVersions + """ + configVersions(first: Int, offset: Int): [RouterConfigVersion!]! + + """ + Return a given RouterConfigVersion + """ + configVersion(name: String!): RouterConfigVersion + """ The regions where a cloud router can be deployed """ @@ -4331,47 +4943,213 @@ type Cloud { Return the Cloud Router associated with the provided id """ router(id: ID!): Router + + """ + Return the Shard associated with the provided id + """ + shard(id: ID!): Shard + + """ + Return all Shards + """ + shards(provider: CloudProvider, first: Int, offset: Int): [Shard!]! } +""" +Invalid input error +""" type CloudInvalidInputError { + """ + Argument related to the error + """ argument: String! + """ + Location of the error + """ location: String + """ + Reason for the error + """ reason: String! } +""" +Cloud mutations +""" type CloudMutation { + """ + Create a new RouterConfigVersion + """ + createConfigVersion(input: RouterConfigVersionInput!): RouterVersionConfigResult! + + """ + Update a RouterConfigVersion + """ + updateConfigVersion(input: RouterConfigVersionInput!): RouterVersionConfigResult! + + """ + Create a new Shard + """ + createShard(input: CreateShardInput!): ShardResult! + + """ + Update an existing Shard + """ + updateShard(input: UpdateShardInput!): ShardResult! + order(orderId: String!): OrderMutation + """ + Create a new router version + """ createVersion(version: RouterVersionCreateInput!): CreateRouterVersionResult! + """ + Update an existing router version + """ updateVersion(version: RouterVersionUpdateInput!): UpdateRouterVersionResult! - deleteVersion(version: RouterVersionDeleteInput!): DeleteRouterVersionResult! - + """ + Fetch a Cloud Router for mutations + """ router(id: ID!): RouterMutation + """ + Create a new Cloud Router + """ createRouter(id: ID!, input: CreateRouterInput!): CreateRouterResult! + """ + Destroy an existing Cloud Router + """ destroyRouter(id: ID!): DestroyRouterResult! + """ + Update an existing Cloud Router + """ updateRouter(id: ID!, input: UpdateRouterInput!): UpdateRouterResult! } +""" +Cloud onboarding information +""" +type CloudOnboarding { + """ + Graph variant reference for Cloud Onboarding + """ + graphRef: String! + + """ + Cloud provider for Cloud Onboarding + """ + provider: CloudProvider! + + """ + Tier for Cloud Onboarding + """ + tier: CloudTier! + + """ + Region for Cloud Onboarding + """ + region: RegionDescription! +} + +""" +Input to create a new Cloud Onboarding +""" +input CloudOnboardingInput { + """ + graph variant name for the onboarding + """ + graphRef: String! + + """ + The cloud provider + """ + provider: CloudProvider! + + """ + Tier for the Cloud Onboarding + """ + tier: CloudTier! + + """ + Region for the Cloud Onboarding + """ + region: String! +} + """ List of supported cloud providers """ enum CloudProvider { + """ + Amazon Web Services + """ + AWS + + """ + Fly.io + """ FLY } +""" +Cloud Router tiers +""" +enum CloudTier { + """ + Serverless tier + """ + SERVERLESS + + """ + Dedicated tier + """ + DEDICATED + + """ + Enterprise Cloud tier + """ + ENTERPRISE +} + union CloudValidationResult = CloudValidationSuccess|InvalidInputErrors|InternalServerError +""" +Config validation success +""" type CloudValidationSuccess { message: String! } +input CommentFilter { + schemaScope: String + + status: [CommentStatus!] + + type: [CommentType!]! +} + +enum CommentStatus { + DELETED + + OPEN + + RESOLVED +} + +enum CommentType { + CHANGE + + GENERAL + + REVIEW +} + interface CommunicationChannel { id: ID! @@ -4535,6 +5313,8 @@ type CompositionAndRemoveResult { List of subgraphs that are included in this composition. """ subgraphConfigs: [SubgraphConfig!]! + + createdAt: Timestamp! } """ @@ -4562,14 +5342,24 @@ type CompositionAndUpsertResult { wasCreated: Boolean! """ - ID that points to the results of composition. + Whether an implementingService was updated as part of this mutation """ - graphCompositionID: String! + wasUpdated: Boolean! """ - Whether an implementingService was updated as part of this mutation + All subgraphs that were created from this mutation """ - wasUpdated: Boolean! + subgraphsCreated: [String!]! + + """ + All subgraphs that were updated from this mutation + """ + subgraphsUpdated: [String!]! + + """ + ID that points to the results of composition. + """ + graphCompositionID: String! """ List of subgraphs that are included in this composition. @@ -4585,6 +5375,8 @@ type CompositionAndUpsertResult { Human-readable text describing the launch result of the subgraph publish. """ launchCliCopy: String + + createdAt: Timestamp! } type CompositionBuildCheckFailed implements BuildCheckFailed & BuildCheckResult & CompositionBuildCheckResult { @@ -4594,7 +5386,7 @@ type CompositionBuildCheckFailed implements BuildCheckFailed & BuildCheckResult compositionPackageVersion: String - errors: [CompositionBuildError!]! + errors: [BuildError!]! id: ID! @@ -4636,26 +5428,6 @@ interface CompositionBuildCheckResult implements BuildCheckResult { workflowTask: CompositionCheckTask! } -type CompositionBuildError implements BuildCheckError { - """ - A machine-readable error code. See https://www.apollographql.com/docs/federation/errors/ for a - list of existing composition error codes. - """ - code: String - - """ - The step at which composition failed. - """ - failedStep: String - - """ - Source locations related to the error. - """ - locations: [SourceLocation!] - - message: String! -} - type CompositionBuildInput { subgraphs: [Subgraph!]! @@ -4756,6 +5528,13 @@ type CompositionPublishResult implements CompositionResult { """ graphCompositionID: ID! + graphID: ID! + + """ + Null if CompositionPublishResult was not on a Proposal Variant + """ + proposalRevision: ProposalRevision + """ The generated composition config, or null if any errors occurred. """ @@ -4781,13 +5560,13 @@ type CompositionPublishResult implements CompositionResult { """ subgraphConfigs: [SubgraphConfig!]! - webhookNotificationBody: String - """ Cloud router configuration associated with this build event. It will be non-null for any cloud-router variant, and null for any not cloudy variant/graph """ routerConfig: String + + createdAt: Timestamp! } """ @@ -4819,6 +5598,8 @@ interface CompositionResult { It will be non-null for any cloud-router variant, and null for any not cloudy variant/graph """ routerConfig: String + + createdAt: Timestamp! } type CompositionStatusSubscription implements ChannelSubscription { @@ -4896,6 +5677,8 @@ type CompositionValidationResult implements CompositionResult { It will be non-null for any cloud-router variant, and null for any not cloudy variant/graph """ routerConfig: String + + createdAt: Timestamp! } input ContractConfigInput { @@ -4970,24 +5753,6 @@ enum ContractVariantFailedStep { VERSION_CHECK } -type ContractVariantPreviewErrors { - errorMessages: [String!]! - - failedStep: ContractVariantFailedStep! -} - -union ContractVariantPreviewResult = ContractVariantPreviewErrors|ContractVariantPreviewSuccess - -type ContractVariantPreviewSuccess { - baseApiSchema: String! - - baseCoreSchema: String! - - contractApiSchema: String! - - contractCoreSchema: String! -} - type ContractVariantUpsertErrors { """ A list of all errors that occurred when attempting to create or update a contract variant. @@ -5014,6 +5779,14 @@ type ContractVariantUpsertSuccess { launchUrl: String } +type Coordinate { + byteOffset: Int! + + column: Int! + + line: Int! +} + """ Contains the supergraph and API schemas generated by composition. """ @@ -5040,44 +5813,159 @@ type CoreSchema { typeCount: Int! } -union CreateOperationCollectionResult = OperationCollection|PermissionError|ValidationError +""" +Input to create a new AWS shard +""" +input CreateAwsShardInput { + region: String! -input CreateRouterInput { - """ - The cloud provider - """ - provider: CloudProvider! + endpoint: String! - """ - Subset of the region codes aligned to the result of Query.regions - This is currently not an enum to support future scenarios where - various cloud providers could have different regions where - they are available - """ - region: Region! + accountId: String! - routerUrl: String + iamRoleArn: String! - routerVersion: String + loadbalancerArn: String! - routerConfig: String + loadbalancerSecurityGroupId: String! - graphCompositionId: String -} + loadbalancerListenerArn: String! -union CreateRouterResult = CreateRouterSuccess|InvalidInputErrors|InternalServerError + ecsClusterArn: String! -""" -Success branch of a createRouter mutation. -id of the order can be polled -via Query.cloud().order(id: ID!) to check-in on the progress -of the underlying operation -""" -type CreateRouterSuccess { - order: Order! -} + vpcId: String! -union CreateRouterVersionResult = RouterVersion|CloudInvalidInputError|InternalServerError + subnetIds: [String!]! + + permissionsBoundaryArn: String! +} + +""" +Input to create a new Fly shard +""" +input CreateFlyShardInput { + region: String! + + organizationId: String! + + endpoint: String! + + etcdEndpoints: [String!]! +} + +union CreateOnboardingResult = CreateOnboardingSuccess|InvalidInputErrors|InternalServerError + +""" +Success creating a CloudOnboarding +""" +type CreateOnboardingSuccess { + onboarding: CloudOnboarding! +} + +union CreateOperationCollectionResult = OperationCollection|PermissionError|ValidationError + +type CreatePersistedQueryListResult { + persistedQueryList: PersistedQueryList! +} + +union CreatePersistedQueryListResultOrError = CreatePersistedQueryListResult|PermissionError + +""" +An error that occurs when creating a proposal fails. +""" +type CreateProposalError implements Error { + """ + The error's details. + """ + message: String! +} + +input CreateProposalInput { + description: String + + displayName: String! + + sourceVariantName: String! +} + +union CreateProposalResult = CreateProposalError|GraphVariant|PermissionError|ValidationError + +""" +Input to create a new Cloud Router +""" +input CreateRouterInput { + """ + URL for the Cloud Router + """ + routerUrl: String + + """ + Router version for the Cloud Router + """ + routerVersion: String + + """ + Configuration for the Cloud Router + """ + routerConfig: String + + """ + Graph composition ID, also known as launch ID + """ + graphCompositionId: String + + """ + Number of GCUs allocated for the Cloud Router + + This is ignored for serverless Cloud Routers + """ + gcus: Int + + """ + Unique identifier for ordering orders + """ + orderingId: String! +} + +union CreateRouterResult = CreateRouterSuccess|InvalidInputErrors|InternalServerError + +""" +Success branch of a createRouter mutation + +id of the order can be polled +via Query.cloud().order(id: ID!) to check-in on the progress +of the underlying operation +""" +type CreateRouterSuccess { + order: Order! +} + +union CreateRouterVersionResult = RouterVersion|CloudInvalidInputError|InternalServerError + +""" +Input to create a new Shard +""" +input CreateShardInput { + shardId: String! + + gcuCapacity: Int + + gcuUsage: Int + + routerCapacity: Int + + routerUsage: Int + + provider: CloudProvider! + + tier: CloudTier! + + status: ShardStatus + + aws: CreateAwsShardInput + + fly: CreateFlyShardInput +} type CronExecution { completedAt: Timestamp @@ -5177,6 +6065,18 @@ The input/output is a string in RFC3339 format. """ scalar DateTime +input DeleteCommentInput { + id: String! +} + +union DeleteCommentResult = DeleteCommentSuccess|NotFoundError|PermissionError|ValidationError + +type DeleteCommentSuccess { + comment: DeleteCommentSuccessResult +} + +union DeleteCommentSuccessResult = ParentChangeProposalComment|ParentGeneralProposalComment + union DeleteOperationCollectionResult = DeleteOperationCollectionSuccess|PermissionError type DeleteOperationCollectionSuccess { @@ -5185,7 +6085,21 @@ type DeleteOperationCollectionSuccess { variants: [GraphVariant!]! } -union DeleteRouterVersionResult = RouterVersion|CloudInvalidInputError|InternalServerError +type DeletePersistedQueryListResult { + graph: Service! +} + +union DeletePersistedQueryListResultOrError = CannotDeleteLinkedPersistedQueryListError|DeletePersistedQueryListResult|PermissionError + +input DeleteProposalSubgraphInput { + previousLaunchId: ID + + subgraphName: String! + + summary: String! +} + +union DeleteProposalSubgraphResult = PermissionError|Proposal|ValidationError """ The result of attempting to delete a graph variant. @@ -5205,6 +6119,9 @@ enum DeletionTargetType { union DestroyRouterResult = DestroyRouterSuccess|InvalidInputErrors|InternalServerError +""" +Success branch of a destroyRouter mutation +""" type DestroyRouterSuccess { """ Order for the destroyRouter mutation @@ -5220,14 +6137,14 @@ Support for a single directive on a graph variant """ type DirectiveSupportStatus { """ - name of the directive + whether the directive is supported on the current graph variant """ - name: String! + enabled: Boolean! """ - whether the directive is supported on the current graph variant + name of the directive """ - enabled: Boolean! + name: String! } """ @@ -5557,6 +6474,14 @@ type EdgeServerInfosRecord { timestamp: Timestamp! } +input EditCommentInput { + id: String! + + message: String! +} + +union EditCommentResult = NotFoundError|ParentChangeProposalComment|ParentGeneralProposalComment|PermissionError|ReplyChangeProposalComment|ReplyGeneralProposalComment|ValidationError + enum EmailCategory { EDUCATIONAL } @@ -5591,6 +6516,9 @@ type Entity { subgraphKeys: [SubgraphKeyMap!] } +""" +GraphQL Error +""" interface Error { message: String! } @@ -5870,6 +6798,11 @@ type FederatedImplementingService { """ createdAt: Timestamp! + """ + The timestamp when the subgraph was deleted. Null if it wasn't deleted. + """ + deletedAt: Timestamp + """ The timestamp when the subgraph was most recently updated. """ @@ -6068,6 +7001,124 @@ type FieldInsights { lastSeen: Timestamp } +input FieldInsightsListFilterInInput { + clientName: [String] + + clientVersion: [String] +} + +input FieldInsightsListFilterInput { + clientName: String + + clientVersion: String + + in: FieldInsightsListFilterInInput + + isDeprecated: Boolean + + isUnused: Boolean + + or: [FieldInsightsListFilterInput!] + + """ + Filters on partial string matches of Parent Type and Field Name + """ + search: String +} + +type FieldInsightsListItem { + description: String + + errorCount: Long! + + errorCountPerMin: Float! + + errorPercentage: Float! + + estimatedExecutionCount: Long! + + executionCount: Long! + + fieldName: String! + + isDeprecated: Boolean! + + isUnused: Boolean! + + p50LatencyMs: Float! + + p90LatencyMs: Float! + + p95LatencyMs: Float! + + p99LatencyMs: Float! + + parentType: String! + + referencingOperationCount: Long! + + referencingOperationCountPerMin: Float! + + totalLatencyHistogram: DurationHistogram! @deprecated(reason: "Use p50LatencyMs, p90LatencyMs, p95LatencyMs, or p99LatencyMs instead") +} + +enum FieldInsightsListOrderByColumn { + ERROR_COUNT + + ERROR_COUNT_PER_MIN + + ERROR_PERCENTAGE + + ESTIMATED_EXECUTION_COUNT + + EXECUTION_COUNT + + PARENT_TYPE_AND_FIELD_NAME + + REFERENCING_OPERATION_COUNT + + REFERENCING_OPERATION_COUNT_PER_MIN + + SERVICE_TIME_P50 + + SERVICE_TIME_P90 + + SERVICE_TIME_P95 + + SERVICE_TIME_P99 +} + +input FieldInsightsListOrderByInput { + column: FieldInsightsListOrderByColumn! + + direction: Ordering! +} + +""" +Information about pagination in a connection. +""" +type FieldInsightsListPageInfo { + """ + When paginating forwards, the cursor to continue. + """ + endCursor: String + + """ + Not implemented. Always returns true + """ + hasNextPage: Boolean! + + """ + Not implemented. Always returns true + """ + hasPreviousPage: Boolean! + + """ + When paginating backwards, the cursor to continue. + """ + startCursor: String +} + """ Columns of FieldLatencies. """ @@ -6196,6 +7247,11 @@ type FieldLatenciesRecord { timestamp: Timestamp! } +""" +Federation type representing set of fields +""" +scalar FieldSet + """ Columns of FieldUsage. """ @@ -6210,6 +7266,10 @@ enum FieldUsageColumn { FIELD_NAME + OPERATION_SUBTYPE + + OPERATION_TYPE + PARENT_TYPE QUERY_ID @@ -6234,6 +7294,10 @@ type FieldUsageDimensions { fieldName: String + operationSubtype: String + + operationType: String + parentType: String queryId: ID @@ -6272,6 +7336,16 @@ input FieldUsageFilter { not: FieldUsageFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [FieldUsageFilter!] """ @@ -6324,6 +7398,16 @@ input FieldUsageFilterIn { """ fieldName: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose parentType dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -6391,7 +7475,7 @@ type FilterBuildCheckFailed implements BuildCheckFailed & BuildCheckResult & Fil buildPipelineTrack: BuildPipelineTrack! - errors: [FilterBuildError!]! + errors: [BuildError!]! id: ID! @@ -6426,16 +7510,6 @@ interface FilterBuildCheckResult implements BuildCheckResult { workflowTask: FilterCheckTask! } -type FilterBuildError implements BuildCheckError { - """ - The step at which filtering failed. See https://www.apollographql.com/docs/studio/contracts/#contract-errors - for a list of existing steps. - """ - failedStep: String! - - message: String! -} - """ Inputs provided to the build for a contract variant, which filters types and fields from a source variant's schema. """ @@ -6559,3133 +7633,5700 @@ input FilterConfigInput { include: [String!]! } -type FlyClientError { - message: String! -} +""" +Experimental, this will likely be replaced by a nested diff. +""" +type FlatDiff { + diff: [FlatDiffItem!]! -type FlyForceRollingUpdateError { - error: FlyForceRollingUpdateErrorValue! + id: ID! + + summary: FlatDiffSummary! } -union FlyForceRollingUpdateErrorValue = FlyClientError|InvalidRequest +type FlatDiffAddArgument implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! -union FlyForceRollingUpdateResult = FlyForceRollingUpdateSuccess|FlyForceRollingUpdateError + type: FlatDiffType! -type FlyForceRollingUpdateSuccess { - updated: Boolean! + value: String! } -type FlyRouterMutation { - forceRollingUpdate: FlyForceRollingUpdateResult! +type FlatDiffAddDirective implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! + + type: FlatDiffType! } -type GitContext { - remoteUrl: String +type FlatDiffAddDirectiveUsage implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! - remoteHost: GitRemoteHost + type: FlatDiffType! - commit: ID + value: String! +} - commitUrl: String +type FlatDiffAddEnum implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - committer: String + type: FlatDiffType! +} - message: String +type FlatDiffAddEnumValue implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - branch: String + type: FlatDiffType! } -""" -Input type to provide when specifying the Git context for a run of schema checks. -""" -input GitContextInput { - """ - The Git repository branch used in the check. - """ - branch: String +type FlatDiffAddField implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! - """ - The ID of the Git commit used in the check. - """ - commit: ID + type: FlatDiffType! - """ - The username of the user who created the Git commit used in the check. - """ - committer: String + value: String! +} - """ - The commit message of the Git commit used in the check. - """ - message: String +type FlatDiffAddImplementation implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! - """ - The Git repository's remote URL. - """ - remoteUrl: String + type: FlatDiffType! + + value: String! } -enum GitRemoteHost { - BITBUCKET +type FlatDiffAddInput implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - GITHUB + type: FlatDiffType! +} - GITLAB +type FlatDiffAddInterface implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! + + type: FlatDiffType! } -type GQLBillingPlanFromGrpc { - dbPlan: BillingPlanV2 +type FlatDiffAddObject implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - matchesDbPlan: Boolean + type: FlatDiffType! +} - rawProtoJson: String +type FlatDiffAddScalar implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! + + type: FlatDiffType! } -""" -Represents a graph API key, which has permissions scoped to a -user role for a single Apollo graph. -""" -type GraphApiKey implements ApiKey { - """ - The timestamp when the API key was created. - """ - createdAt: Timestamp! +type FlatDiffAddSchemaDefinition implements FlatDiffItem { + type: FlatDiffType! +} - """ - Details of the user or graph that created the API key. - """ - createdBy: Identity +type FlatDiffAddSchemaDirectiveUsage implements FlatDiffItem & FlatDiffItemValue { + type: FlatDiffType! - """ - The API key's ID. - """ - id: ID! + value: String! +} - """ - The API key's name, for distinguishing it from other keys. - """ - keyName: String +type FlatDiffAddSchemaRootOperation implements FlatDiffItem & FlatDiffItemRootType & FlatDiffItemValue { + rootType: String! - """ - The permission level assigned to the API key upon creation. - """ - role: UserPermission! + type: FlatDiffType! - """ - The value of the API key. **This is a secret credential!** - """ - token: String! + value: String! } -type GraphCapabilities { - """ - False if this graph is a cloud supergraph. - """ - canPublishMonograph: Boolean! - - """ - Currently, graph URL is not updatable for cloud supergraphs. - """ - canUpdateURL: Boolean! +type FlatDiffAddUnion implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - """ - Minimum Federation Version track required for all variants of this graph. - """ - minimumBuildPipelineTrack: BuildPipelineTrack! + type: FlatDiffType! } -""" -The timing details for the build step of a launch. -""" -type GraphCreationError { - message: String! +type FlatDiffAddUnionMember implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! + + type: FlatDiffType! + + value: String! } -union GraphCreationResult = GraphCreationError|Service +type FlatDiffAddValidLocation implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! -""" -Filtering options for graph connections. -""" -input GraphFilter { - """ - Only include graphs in a certain state. - """ - state: GraphState + type: FlatDiffType! - """ - Only include graphs of certain types. - """ - type: [GraphType!] + value: String! } -union GraphImplementors = NonFederatedImplementingService|FederatedImplementingServices +type FlatDiffChangeArgumentDefault implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemNullableValue { + coordinate: String! -""" -A GraphQL document, such as the definition of an operation or schema. -""" -scalar GraphQLDocument + type: FlatDiffType! -""" -Various states a graph can be in. -""" -enum GraphState { - """ - The graph has not been configured with any variants. - """ - CONFIGURED + value: String +} - """ - The graph has not been configured with any variants. - """ - NOT_CONFIGURED +type FlatDiffChangeDescription implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemNullableValue { + coordinate: String! + + type: FlatDiffType! + + value: String } -enum GraphType { - CLASSIC +type FlatDiffChangeDirectiveRepeatable implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - CLOUD_SUPERGRAPH + type: FlatDiffType! - SELF_HOSTED_SUPERGRAPH + value: Boolean! } -""" -A graph variant -""" -type GraphVariant { - """ - The variant's global identifier in the form `graphID@variant`. - """ - id: ID! +type FlatDiffChangeInputFieldDefault implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemNullableValue { + coordinate: String! - router: Router + type: FlatDiffType! - validateRouter(config: RouterConfigInput!): CloudValidationResult! + value: String +} - checkConfiguration: VariantCheckConfiguration! +type FlatDiffChangeSchemaDescription implements FlatDiffItem & FlatDiffItemNullableValue { + type: FlatDiffType! - """ - Compose and filter preview contract schema built from this source variant. - """ - composeAndFilterPreview("The filter configuration of a hypothetical contract variant on this variant. Null indicates that filtering should be skipped\/not run, in which case ComposeAndFilterPreviewSuccess.filterResults will be null." filterConfig: FilterConfigInput, "Any hypothetical changes desired for the subgraphs of this variant. Null is the same as the empty list." subgraphChanges: [ComposeAndFilterPreviewSubgraphChange!]): ComposeAndFilterPreviewResult + value: String +} - """ - The filter configuration used to build a contract schema. The configuration consists of lists of tags for schema elements to include or exclude in the resulting schema. - """ - contractFilterConfig: FilterConfig +interface FlatDiffItem { + type: FlatDiffType! +} - """ - A human-readable description of the filter configuration of this contract variant, or null if this isn't a contract - variant. - """ - contractFilterConfigDescription: String +interface FlatDiffItemCoordinate implements FlatDiffItem { + coordinate: String! - """ - Preview a Contract schema built from this source variant. - """ - contractPreview(filters: FilterConfigInput!): ContractPreview! + type: FlatDiffType! +} - derivedVariantCount: Int! +interface FlatDiffItemNullableValue implements FlatDiffItem { + type: FlatDiffType! - """ - Returns the list of variants derived from this variant. This currently includes contracts only. - """ - derivedVariants: [GraphVariant!] + value: String +} - """ - Returns details about a field in the schema. Unless an error occurs, we will currently always return a non-null - response here, with the timestamps set to null if there is no usage of the field or if field doesn't exist in the - schema. However we are keeping the return type as nullable in case we want to update this later in a - backwards-compatible way to make null mean that the field doesn't exist in the schema at all. - """ - fieldInsights(fieldName: String!, parentType: String!): FieldInsights +interface FlatDiffItemRootType implements FlatDiffItem { + rootType: String! - """ - The graph that this variant belongs to. - """ - graph: Service! + type: FlatDiffType! +} - """ - Graph ID of the variant. Prefer using graph { id } when feasible. - """ - graphId: String! +interface FlatDiffItemValue implements FlatDiffItem { + type: FlatDiffType! - """ - Represents whether this variant has a supergraph schema. Note that this can only be true for variants with build steps - (running e.g. federation composition or contracts filtering). This will be false for a variant with a build step if it - has never successfully published. - """ - hasSupergraphSchema: Boolean! + value: String! +} - internalVariantUUID: String! +type FlatDiffRemoveArgument implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! - """ - Represents whether this variant is a Contract. - """ - isContract: Boolean + type: FlatDiffType! - """ - Is this variant one of the current user's favorite variants? - """ - isFavoriteOfCurrentUser: Boolean! + value: String! +} - isPublic: Boolean! +type FlatDiffRemoveDirective implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - """ - Represents whether this variant should be listed in the public variants directory. This can only be true if the variant is also public. - """ - isPubliclyListed: Boolean! + type: FlatDiffType! +} - """ - Represents whether Apollo has verified the authenticity of this public variant. This can only be true if the variant is also public. - """ - isVerified: Boolean! +type FlatDiffRemoveDirectiveUsage implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! - """ - Latest approved launch for the variant, and what is served through Uplink. - """ - latestApprovedLaunch: Launch + type: FlatDiffType! - """ - Latest launch for the variant, whether successful or not. - """ - latestLaunch: Launch + value: String! +} - launch(id: ID!): Launch +type FlatDiffRemoveEnum implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - launchHistory(limit: Int! = 100): [Launch!]! + type: FlatDiffType! +} - links: [LinkInfo!] +type FlatDiffRemoveEnumValue implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - """ - The variant's name (e.g., `staging`). - """ - name: String! + type: FlatDiffType! +} - """ - The merged/computed/effective check configuration for the operations check task. - """ - operationsCheckConfiguration(overrides: OperationsCheckConfigurationOverridesInput): OperationsCheckConfiguration +type FlatDiffRemoveField implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! - """ - Which permissions the current user has for interacting with this variant - """ - permissions: GraphVariantPermissions! + type: FlatDiffType! - readme: Readme! + value: String! +} - """ - The total number of requests for this variant in the last 24 hours - """ - requestsInLastDay: Long - - """ - The variant this variant is derived from. This property currently only exists on contract variants. - """ - sourceVariant: GraphVariant +type FlatDiffRemoveImplementation implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! - """ - The last instant that usage information (e.g. operation stat, client stats) was reported for this variant - """ - usageLastReportedAt: Timestamp + type: FlatDiffType! - """ - A list of the saved [operation collections](https://www.apollographql.com/docs/studio/explorer/operation-collections/) associated with this variant. - """ - operationCollections: [OperationCollection!]! + value: String! +} - """ - A list of the saved [operation collections](https://www.apollographql.com/docs/studio/explorer/operation-collections/) associated with this variant, paged. - """ - operationCollectionsConnection(after: String, before: String, first: Int, last: Int): GraphVariantOperationCollectionConnection +type FlatDiffRemoveInput implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - """ - The URL of the variant's GraphQL endpoint for query and mutation operations. For subscription operations, use `subscriptionUrl`. - """ - url: String + type: FlatDiffType! +} - """ - If the graphql endpoint is set up to accept cookies. - """ - sendCookies: Boolean +type FlatDiffRemoveInterface implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - """ - The URL of the variant's GraphQL endpoint for subscription operations. - """ - subscriptionUrl: String + type: FlatDiffType! +} - """ - Explorer setting for preflight script to run before the actual GraphQL operations is run. - """ - preflightScript: String +type FlatDiffRemoveObject implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - """ - Explorer setting for shared headers for a graph - """ - sharedHeaders: String + type: FlatDiffType! +} - """ - As new schema tags keep getting published, activeSchemaPublish refers to the latest. - """ - activeSchemaPublish: SchemaTag +type FlatDiffRemoveScalar implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - """ - The details of the variant's most recent publication. - """ - latestPublication: SchemaTag + type: FlatDiffType! +} - """ - If the variant is protected - """ - isProtected: Boolean! +type FlatDiffRemoveSchemaDefinition implements FlatDiffItem { + type: FlatDiffType! +} - """ - Generate a federated operation plan for a given operation - """ - plan(document: GraphQLDocument!, operationName: String): QueryPlan +type FlatDiffRemoveSchemaDirectiveUsage implements FlatDiffItem & FlatDiffItemValue { + type: FlatDiffType! - """ - If the variant has managed subgraphs. - """ - isFederated: Boolean @deprecated(reason: "Replaced by hasManagedSubgraphs") + value: String! +} - """ - If the variant has managed subgraphs. - """ - hasManagedSubgraphs: Boolean +type FlatDiffRemoveSchemaRootOperation implements FlatDiffItem & FlatDiffItemRootType { + rootType: String! - """ - A list of the subgraphs included in this variant. This value is null for non-federated variants. Set `includeDeleted` to `true` to include deleted subgraphs. - """ - subgraphs(includeDeleted: Boolean! = false): [FederatedImplementingService!] + type: FlatDiffType! +} - """ - A list of the entities across all subgraphs, exposed to consumers & up. This value is null for non-federated variants. - """ - entities: EntitiesResponseOrError +type FlatDiffRemoveUnion implements FlatDiffItem & FlatDiffItemCoordinate { + coordinate: String! - """ - Returns the details of the subgraph with the provided `name`, or null if this variant doesn't include a subgraph with that name. - """ - subgraph(name: ID!): FederatedImplementingService + type: FlatDiffType! +} - """ - A list of supported directives - """ - supportedDirectives: [DirectiveSupportStatus!] +type FlatDiffRemoveUnionMember implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! - """ - The version of composition currently in use, if applicable - """ - compositionVersion: String + type: FlatDiffType! - """ - Registry stats for this particular graph variant - """ - registryStatsWindow(from: Timestamp!, resolution: Resolution, to: Timestamp): RegistryStatsWindow + value: String! +} - """ - If this is true tag directives in the core schema will also appear in the - api schema - """ - passTagDirectiveToApiSchema: Boolean! @deprecated(reason: "Use buildConfig.tagInApiSchema") +type FlatDiffRemoveValidLocation implements FlatDiffItem & FlatDiffItemCoordinate & FlatDiffItemValue { + coordinate: String! - buildConfig: BuildConfig! + type: FlatDiffType! - routerConfig: String + value: String! } -""" -Ways to filter graph variants. -""" -enum GraphVariantFilter { - """ - All Variants - """ - ALL +union FlatDiffResult = FlatDiff|NotFoundError|SchemaValidationError - """ - Variants favorited by the current user - """ - FAVORITES -} +type FlatDiffSummary { + directive: FlatDiffTypeSummary! -union GraphVariantLookup = GraphVariant|InvalidRefFormat + enum: FlatDiffTypeSummary! -""" -Modifies a variant of a graph, also called a schema tag in parts of our product. -""" -type GraphVariantMutation { - """ - Global identifier for the graph variant, in the form `graph@variant`. - """ - id: ID! + input: FlatDiffTypeSummary! - """ - Gets the router attached to a graph variant - """ - router: RouterMutation + interface: FlatDiffTypeSummary! - createRouter(input: CreateRouterInput!): CreateRouterResult! + object: FlatDiffTypeSummary! - destroyRouter: DestroyRouterResult! + scalar: FlatDiffTypeSummary! - updateRouter(input: UpdateRouterInput!): UpdateRouterResult! + schema: FlatDiffTypeSummary! - addLinkToVariant(title: String, type: LinkInfoType!, url: String!): GraphVariant! + union: FlatDiffTypeSummary! +} - """ - Graph ID of the variant - """ - graphId: String! +enum FlatDiffType { + ADD_ARGUMENT - """ - Name of the variant, like `variant`. - """ - name: String! + ADD_DIRECTIVE - relaunch: RelaunchResult! + ADD_DIRECTIVE_USAGE - removeLinkFromVariant(linkInfoId: ID!): GraphVariant! + ADD_ENUM - setIsFavoriteOfCurrentUser(favorite: Boolean!): GraphVariant! + ADD_ENUM_VALUE - """ - _Asynchronously_ kicks off operation checks for a proposed non-federated - schema change against its associated graph. + ADD_FIELD - Returns a `CheckRequestSuccess` object with a workflow ID that you can use - to check status, or an error object if the checks workflow failed to start. - """ - submitCheckSchemaAsync(input: CheckSchemaAsyncInput!): CheckRequestResult! + ADD_IMPLEMENTATION - """ - Submit a request for a Filter Schema Check and receive a result with a workflow ID that can be used to check status, or an error message that explains what went wrong. - """ - submitFilterCheckAsync(input: FilterCheckAsyncInput!): CheckRequestResult! + ADD_INPUT - """ - _Asynchronously_ kicks off composition and operation checks for a proposed subgraph schema change against its associated supergraph. + ADD_INTERFACE - Returns a `CheckRequestSuccess` object with a workflow ID that you can use - to check status, or an error object if the checks workflow failed to start. - """ - submitSubgraphCheckAsync(input: SubgraphCheckAsyncInput!): CheckRequestResult! + ADD_OBJECT - updateCheckConfigurationDownstreamVariants("During downstream checks, this variant's check workflow will wait for all downstream check\nworkflows for variants to complete, and if any of them fail, then\nthis variant's check workflow will fail. If this argument is null, the value is unchanged." blockingDownstreamVariants: [String!]): VariantCheckConfiguration! + ADD_SCALAR - updateCheckConfigurationEnableOperationsCheck(enabled: Boolean!): VariantCheckConfiguration + ADD_SCHEMA_DEFINITION - updateCheckConfigurationExcludedClients("When this argument is true, indicates that graph-level configuration is appended to the\nvariant-level configuration." appendGraphSettings: Boolean!, "During operation checks, ignore clients matching any of the filters. If this\nargument is null, the value is unchanged." excludedClients: [ClientFilterInput!]): VariantCheckConfiguration! + ADD_SCHEMA_DIRECTIVE_USAGE - updateCheckConfigurationExcludedOperations("When this argument is true, indicates that graph-level configuration is appended to the\nvariant-level configuration." appendGraphSettings: Boolean!, "During operation checks, ignore operations matching any of the \nfilters. If this argument is null, the value is unchanged." excludedOperationNames: [OperationNameFilterInput!], "During operation checks, ignore operations matching any of the filters. If\nthis argument is null, the value is unchanged." excludedOperations: [OperationInfoFilterInput!]): VariantCheckConfiguration! + ADD_SCHEMA_ROOT_OPERATION - updateCheckConfigurationIncludedVariants("During operation checks, fetch operations from the metrics data for \nvariants. If the useGraphSettings argument is true, this argument is ignored. If the\nuseGraphSettings argument is false and this argument is null, the value is unchanged (if\nuseGraphSettings was previously true, the default of a list containing just this variant is\nused instead)." includedVariants: [String!], "When this argument is true, indicates that graph-level configuration is used for this variant\nsetting." useGraphSettings: Boolean!): VariantCheckConfiguration! + ADD_UNION - updateCheckConfigurationTimeRange("During operation checks, ignore operations that executed less than \ntimes in the time range. If the useGraphSettings argument is true, this argument is ignored. If\nthe useGraphSettings argument is false and this argument is null, the value is unchanged (if\nuseGraphSettings was previously true, the default of 1 is used instead)." operationCountThreshold: Int, "Duration operation checks, ignore operations that constituted less than\n% of the operations in the time range. Expected values are\nbetween 0% and 5%. If the useGraphSettings argument is true, this argument is ignored. If the\nuseGraphSettings argument is false and this argument is null, the value is unchanged (if\nuseGraphSettings was previously true, the default of 0% is used instead)." operationCountThresholdPercentage: Float, "During operation checks, fetch operations from the last seconds. If the\nuseGraphSettings argument is true, this argument is ignored. If the useGraphSettings argument\nis false and this argument is null, the value is unchanged (if useGraphSettings was previously\ntrue, the default of 7 days is used instead)." timeRangeSeconds: Long, "When this argument is true, indicates that graph-level configuration is used for this variant\nsetting." useGraphSettings: Boolean!): VariantCheckConfiguration! + ADD_UNION_MEMBER - updateVariantIsPublic(isPublic: Boolean!): GraphVariant + ADD_VALID_LOCATION - updateVariantIsPubliclyListed(isPubliclyListed: Boolean!): GraphVariant + CHANGE_ARGUMENT_DEFAULT - updateVariantIsVerified(isVerified: Boolean!): GraphVariant + CHANGE_DESCRIPTION - """ - Updates the [README](https://www.apollographql.com/docs/studio/org/graphs/#the-readme-page) of this variant. - """ - updateVariantReadme("The full new text of the README, as a Markdown-formatted string." readme: String!): GraphVariant + CHANGE_INPUT_FIELD_DEFAULT - internalVariantUUID: String! + CHANGE_REPEATABLE - service: Service + CHANGE_SCHEMA_DESCRIPTION - updateURL(url: String): GraphVariant + REMOVE_ARGUMENT - updateSubscriptionURL(subscriptionUrl: String): GraphVariant + REMOVE_DIRECTIVE - updateSendCookies(sendCookies: Boolean!): GraphVariant + REMOVE_DIRECTIVE_USAGE - updateIsProtected(isProtected: Boolean!): GraphVariant + REMOVE_ENUM - updatePreflightScript(preflightScript: String): GraphVariant + REMOVE_ENUM_VALUE - updateSharedHeaders(sharedHeaders: String): GraphVariant + REMOVE_FIELD - """ - Delete the variant. - """ - delete: DeleteSchemaTagResult! + REMOVE_IMPLEMENTATION - passTagDirectiveToApiSchema(enable: Boolean!): GraphVariant + REMOVE_INPUT - buildConfig(version: BuildPipelineTrack!, tagInApiSchema: Boolean! = false): GraphVariant + REMOVE_INTERFACE - """ - Runs composition on a graph variant with existing subgraphs and then publishes if successful. - """ - recomposeAndPublish(forcePublish: Boolean! = true): GraphVariant + REMOVE_OBJECT - upsertRouterConfig(configuration: String!): UpsertRouterResult + REMOVE_SCALAR + + REMOVE_SCHEMA_DEFINITION + + REMOVE_SCHEMA_DIRECTIVE_USAGE + + REMOVE_SCHEMA_ROOT_OPERATION + + REMOVE_UNION + + REMOVE_UNION_MEMBER + + REMOVE_VALID_LOCATION } -type GraphVariantOperationCollectionConnection { - """ - A list of edges from the graph variant to its operation collections. - """ - edges: [GraphVariantOperationCollectionEdge!] +type FlatDiffTypeSummary { + add: Int! - """ - A list of operation collections attached to a graph variant. - """ - nodes: [OperationCollection!] + change: Int! - """ - Information to aid in pagination. - """ - pageInfo: PageInfo! + remove: Int! - totalCount: Int! + typeCount: Int! } """ -An edge between a graph variant and an operation collection. +Error connecting to Fly """ -type GraphVariantOperationCollectionEdge { +type FlyClientError { """ - A cursor for use in pagination. + Error message """ - cursor: String! + message: String! +} +""" +Error triggering a rolling update +""" +type FlyForceRollingUpdateError { """ - An operation collection attached to a graph variant. + Concrete error for the flyForceRollingUpdate mutation """ - node: OperationCollection + error: FlyForceRollingUpdateErrorValue! } +union FlyForceRollingUpdateErrorValue = FlyClientError|InvalidRequest + +union FlyForceRollingUpdateResult = FlyForceRollingUpdateSuccess|FlyForceRollingUpdateError + """ -Individual permissions for the current user when interacting with a particular Studio graph variant. +Success triggering a rolling update """ -type GraphVariantPermissions { +type FlyForceRollingUpdateSuccess { """ - Whether the currently authenticated user is permitted to manage/update this variant's build configuration (e.g., build pipeline version). + Whether the app was updated """ - canManageBuildConfig: Boolean! + updated: Boolean! +} +type FlyRouterMutation { """ - Whether the currently authenticated user is permitted to manage/update cloud routers + Force a rolling update """ - canManageCloudRouter: Boolean! + forceRollingUpdate: FlyForceRollingUpdateResult! +} +""" +Fly-specific information for a Shard +""" +type FlyShard { """ - Whether the currently authenticated user is permitted to update variant-level settings for the Apollo Studio Explorer. + DNS endpoint for the orchestrator """ - canManageExplorerSettings: Boolean! + endpoint: String! """ - Whether the currently authenticated user is permitted to publish schemas to this variant. + Fly organization ID """ - canPushSchemas: Boolean! + organizationId: String! """ - Whether the currently authenticated user is permitted to view this variant's build configuration details (e.g., build pipeline version). + Endpoints of the Etcd cluster """ - canQueryBuildConfig: Boolean! + etcdEndpoints: [String!]! +} - """ - Whether the currently authenticated user is permitted to view details regarding cloud routers - """ - canQueryCloudRouter: Boolean! +interface GeneralProposalComment implements ProposalComment { + createdAt: Timestamp! """ - Whether the currently authenticated user is permitted to view cloud router logs + null if the user is deleted """ - canQueryCloudRouterLogs: Boolean! + createdBy: Identity - """ - Whether the currently authenticated user is permitted to download schemas associated to this variant. - """ - canQuerySchemas: Boolean! + id: ID! - canUpdateVariantLinkInfo: Boolean! + message: String! + + status: CommentStatus! """ - Whether the currently authenticated user is permitted to update the README for this variant. + null if never updated """ - canUpdateVariantReadme: Boolean! + updatedAt: Timestamp +} - variantId: ID! +type GitContext { + remoteUrl: String - canCreateCollectionInVariant: Boolean! + remoteHost: GitRemoteHost - canShareCollectionInVariant: Boolean! -} + commit: ID -input HistoricQueryParameters { - from: String = "-86400" + commitUrl: String - to: String = "0" + committer: String - """ - Minimum number of requests within the window for a query to be considered. - """ - queryCountThreshold: Int = 1 + message: String + branch: String +} + +""" +This is stored with a schema when it is uploaded +""" +input GitContextInput { """ - Number of requests within the window for a query to be considered, relative to - total request count. Expected values are between 0 and 0.05 (minimum 5% of total - request volume) + The Git repository branch used in the check. """ - queryCountThresholdPercentage: Float = 0 + branch: String """ - A list of operation IDs to filter out during validation. + The ID of the Git commit used in the check. """ - ignoredOperations: [ID!] = null + commit: ID """ - A list of clients to filter out during validation. + The username of the user who created the Git commit used in the check. """ - excludedClients: [ClientInfoFilter!] = null + committer: String """ - A list of operation names to filter out during validation. + The commit message of the Git commit used in the check. """ - excludedOperationNames: [OperationNameFilterInput!] = null + message: String """ - A list of variants to include in the validation. If no variants are provided - then this defaults to the "current" variant along with the base variant. The - base variant indicates the schema that generates diff and marks the metrics that - are checked for broken queries. We union this base variant with the untagged values('', - same as null inside of `in`, and 'current') in this metrics fetch. This strategy - supports users who have not tagged their metrics or schema. + The Git repository's remote URL. """ - includedVariants: [String!] = null + remoteUrl: String +} + +enum GitRemoteHost { + BITBUCKET + + GITHUB + + GITLAB +} + +type GQLBillingPlanFromGrpc { + dbPlan: BillingPlan + + matchesDbPlan: Boolean + + rawProtoJson: String } """ -Input type to provide when specifying configuration details for schema checks. +Represents a graph API key, which has permissions scoped to a +user role for a single Apollo graph. """ -input HistoricQueryParametersInput { +type GraphApiKey implements ApiKey { """ - Clients to be excluded from check. + The timestamp when the API key was created. """ - excludedClients: [ClientInfoFilter!] + createdAt: Timestamp! """ - Operations to be ignored in this schema check, specified by operation name. + Details of the user or graph that created the API key. """ - excludedOperationNames: [OperationNameFilterInput!] + createdBy: Identity """ - Start time for operations to be checked against. Specified as either a) an ISO formatted date/time string or b) a negative number of seconds relative to the time the check request was submitted. + The API key's ID. """ - from: String + id: ID! """ - Operations to be ignored in this schema check, specified by ID. + The API key's name, for distinguishing it from other keys. """ - ignoredOperations: [ID!] + keyName: String """ - Graph variants to be included in check. + The permission level assigned to the API key upon creation. """ - includedVariants: [String!] + role: UserPermission! """ - Maximum number of queries to be checked against the change. + The value of the API key. **This is a secret credential!** """ - queryCountThreshold: Int + token: String! +} +type GraphCapabilities { """ - Only fail check if this percentage of operations would be negatively impacted. + False if this graph is a cloud supergraph. """ - queryCountThresholdPercentage: Float + canPublishMonograph: Boolean! """ - End time for operations to be checked against. Specified as either a) an ISO formatted date/time string or b) a negative number of seconds relative to the time the check request was submitted. + Currently, graph URL is not updatable for cloud supergraphs. """ - to: String -} - -enum HTTPMethod { - CONNECT + canUpdateURL: Boolean! - DELETE + """ + Minimum Federation Version track required for all variants of this graph. + """ + minimumBuildPipelineTrack: BuildPipelineTrack! +} - GET +""" +The timing details for the build step of a launch. +""" +type GraphCreationError { + message: String! +} - HEAD +union GraphCreationResult = GraphCreationError|Service - OPTIONS +""" +Filtering options for graph connections. +""" +input GraphFilter { + """ + Only include graphs in a certain state. + """ + state: GraphState - PATCH + """ + Only include graphs of certain types. + """ + type: [GraphType!] +} - POST +union GraphImplementors = NonFederatedImplementingService|FederatedImplementingServices - PUT +""" +The linter configuration for this graph. +""" +type GraphLinterConfiguration { + """ + The set of @tag names allowed in the schema. + """ + allowedTagNames: [String!]! - TRACE + """ + Whether to ignore @deprecated elements from linting violations. + """ + ignoreDeprecated: Boolean! - UNKNOWN + """ + Whether to ignore @inaccessible elements from linting violations. + """ + ignoreInaccessible: Boolean! - UNRECOGNIZED + """ + The set of lint rules configured for this graph. + """ + rules: [LinterRuleLevelConfiguration!]! } """ -An identity (such as a `User` or `Graph`) in Apollo Studio. See implementing types for details. +The changes to the linter configuration for this graph. """ -interface Identity { +input GraphLinterConfigurationChangesInput { """ - Returns a representation of the identity as an `Actor` type. + A set of allowed @tag names to be added to the linting configuration for this graph or null if no changes should be made. """ - asActor: Actor! + allowedTagNameAdditions: [String!] """ - The identity's identifier, which is unique among objects of its type. + A set of @tag names to be removed from the allowed @tag list for this graphs linting configuration or null if no changes should be made. """ - id: ID! + allowedTagNameRemovals: [String!] """ - The identity's human-readable name. + Change whether @deprecated elements should be linted or null if no changes should be made. """ - name: String! + ignoreDeprecated: Boolean + + """ + Change whether @inaccessible elements should be linted or null if no changes should be made. + """ + ignoreInaccessible: Boolean + + """ + A set of rule changes or null if no changes should be made. + """ + rules: [LinterRuleLevelConfigurationChangesInput!] } """ -An actor's identity and info about the client they used to perform the action +Columns of GraphosCloudMetrics. """ -type IdentityAndClientInfo { +enum GraphosCloudMetricsColumn { + ACCOUNT_ID + + AGENT_VERSION + + RESPONSE_SIZE + + RESPONSE_SIZE_THROTTLED + + ROUTER_ID + + ROUTER_OPERATIONS + + ROUTER_OPERATIONS_THROTTLED + + SCHEMA_TAG + + SERVICE_ID + + SUBGRAPH_FETCHES + + SUBGRAPH_FETCHES_THROTTLED + + TIMESTAMP +} + +type GraphosCloudMetricsDimensions { + accountId: ID + + agentVersion: String + + routerId: String + + schemaTag: String + + serviceId: ID +} + +""" +Filter for data in GraphosCloudMetrics. Fields with dimension names represent equality checks. All fields are implicitly ANDed together. +""" +input GraphosCloudMetricsFilter { """ - Identity info about the actor + Selects rows whose accountId dimension equals the given value if not null. To query for the null value, use {in: {accountId: [null]}} instead. """ - identity: Identity + accountId: ID """ - Client name provided when the actor performed the action + Selects rows whose agentVersion dimension equals the given value if not null. To query for the null value, use {in: {agentVersion: [null]}} instead. """ - clientName: String + agentVersion: String + + and: [GraphosCloudMetricsFilter!] + + in: GraphosCloudMetricsFilterIn + + not: GraphosCloudMetricsFilter + + or: [GraphosCloudMetricsFilter!] """ - Client version provided when the actor performed the action + Selects rows whose routerId dimension equals the given value if not null. To query for the null value, use {in: {routerId: [null]}} instead. """ - clientVersion: String -} + routerId: String -union IdentityMutation = ServiceMutation|UserMutation + """ + Selects rows whose schemaTag dimension equals the given value if not null. To query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String -type IgnoreOperationsInChecksResult { - graph: Service! + """ + Selects rows whose serviceId dimension equals the given value if not null. To query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID } """ -The location of the implementing service config file in storage +Filter for data in GraphosCloudMetrics. Fields match if the corresponding dimension's value is in the given list. All fields are implicitly ANDed together. """ -type ImplementingServiceLocation { +input GraphosCloudMetricsFilterIn { """ - The name of the implementing service + Selects rows whose accountId dimension is in the given list. A null value in the list means a row with null for that dimension. """ - name: String! + accountId: [ID] """ - The path in storage to access the implementing service config file + Selects rows whose agentVersion dimension is in the given list. A null value in the list means a row with null for that dimension. """ - path: String! -} + agentVersion: [String] -type InternalAdminUser { - role: InternalMdgAdminRole! + """ + Selects rows whose routerId dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + routerId: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + serviceId: [ID] +} + +type GraphosCloudMetricsMetrics { + responseSize: Long! + + responseSizeThrottled: Long! + + routerOperations: Long! + + routerOperationsThrottled: Long! + + subgraphFetches: Long! + + subgraphFetchesThrottled: Long! +} + +input GraphosCloudMetricsOrderBySpec { + column: GraphosCloudMetricsColumn! + + direction: Ordering! +} + +type GraphosCloudMetricsRecord { + """ + Dimensions of GraphosCloudMetrics that can be grouped by. + """ + groupBy: GraphosCloudMetricsDimensions! + + """ + Metrics of GraphosCloudMetrics that can be aggregated over. + """ + metrics: GraphosCloudMetricsMetrics! + + """ + Starting segment timestamp. + """ + timestamp: Timestamp! +} + +type GraphQLDoc { + graph: Service! + + hash: ID! + + source: GraphQLDocument! +} + +""" +A GraphQL document, such as the definition of an operation or schema. +""" +scalar GraphQLDocument + +""" +Various states a graph can be in. +""" +enum GraphState { + """ + The graph has not been configured with any variants. + """ + CONFIGURED + + """ + The graph has not been configured with any variants. + """ + NOT_CONFIGURED +} + +enum GraphType { + CLASSIC + + CLOUD_SUPERGRAPH + + SELF_HOSTED_SUPERGRAPH +} + +""" +A graph variant +""" +type GraphVariant { + """ + The variant's global identifier in the form `graphID@variant`. + """ + id: ID! + + """ + Router associated with this graph variant + """ + router: Router + + """ + Validate router configuration for this graph variant + """ + validateRouter(config: RouterConfigInput!): CloudValidationResult! + + """ + Graph ID of the variant. Prefer using graph { id } when feasible. + """ + graphId: String! + + """ + The variant's name (e.g., `staging`). + """ + name: String! + + """ + The list of BuildPipelineTracks and their associated details that this variant is allowed to set in their build configuration. + """ + allowedTracks: [BuildPipelineTrackDetails!]! + + """ + If this variant doesn't conduct a build (monograph) then this field will be null + For contract variants the build config is set based on the upstream composition variant. + """ + buildConfig: BuildConfig + + """ + The time the variant's federation version and/or the supported directives was last updated + """ + buildConfigUpdatedAt: Timestamp + + checkConfiguration: VariantCheckConfiguration! + + """ + Compose and filter preview contract schema built from this source variant. + """ + composeAndFilterPreview("The filter configuration of a hypothetical contract variant on this variant. Null indicates that filtering should be skipped\/not run, in which case ComposeAndFilterPreviewSuccess.filterResults will be null." filterConfig: FilterConfigInput, "Any hypothetical changes desired for the subgraphs of this variant. Null is the same as the empty list." subgraphChanges: [ComposeAndFilterPreviewSubgraphChange!]): ComposeAndFilterPreviewResult + + """ + Federation version this variant uses + """ + compositionVersion: String + + """ + The filter configuration used to build a contract schema. The configuration consists of lists of tags for schema elements to include or exclude in the resulting schema. + """ + contractFilterConfig: FilterConfig + + """ + A human-readable description of the filter configuration of this contract variant, or null if this isn't a contract + variant. + """ + contractFilterConfigDescription: String + + """ + Preview a Contract schema built from this source variant. + """ + contractPreview(filters: FilterConfigInput!): ContractPreview! + + """ + Time the variant was created + """ + createdAt: Timestamp! + + derivedVariantCount: Int! + + """ + Returns the list of variants derived from this variant. This currently includes contracts only. + """ + derivedVariants: [GraphVariant!] + + """ + Returns details about a field in the schema. Unless an error occurs, we will currently always return a non-null + response here, with the timestamps set to null if there is no usage of the field or if field doesn't exist in the + schema. However we are keeping the return type as nullable in case we want to update this later in a + backwards-compatible way to make null mean that the field doesn't exist in the schema at all. + """ + fieldInsights(fieldName: String!, parentType: String!): FieldInsights + + """ + Returns a paginated list of field insights list items, including all fields from the active schema for this variant. + """ + fieldInsightsList(after: String, before: String, filter: FieldInsightsListFilterInput, first: Int, from: Timestamp!, last: Int, orderBy: FieldInsightsListOrderByInput, to: Timestamp!): GraphVariantFieldInsightsListItemConnection! + + """ + The graph that this variant belongs to. + """ + graph: Service! + + """ + Represents whether this variant has a supergraph schema. Note that this can only be true for variants with build steps + (running e.g. federation composition or contracts filtering). This will be false for a variant with a build step if it + has never successfully published. + """ + hasSupergraphSchema: Boolean! + + internalVariantUUID: String! + + """ + Represents whether this variant is a Contract. + """ + isContract: Boolean + + """ + Is this variant one of the current user's favorite variants? + """ + isFavoriteOfCurrentUser: Boolean! + + """ + Represents whether this variant is a Proposal. + """ + isProposal: Boolean + + isPublic: Boolean! + + """ + Represents whether this variant should be listed in the public variants directory. This can only be true if the variant is also public. + """ + isPubliclyListed: Boolean! + + """ + Represents whether Apollo has verified the authenticity of this public variant. This can only be true if the variant is also public. + """ + isVerified: Boolean! + + """ + Latest approved launch for the variant, and what is served through Uplink. + """ + latestApprovedLaunch: Launch + + """ + Latest launch for the variant, whether successful or not. + """ + latestLaunch: Launch + + launch(id: ID!): Launch + + """ + A list of launches ordered by date, asc or desc depending on orderBy. The maximum limit is 100. + """ + launchHistory(limit: Int! = 100, offset: Int! = 0, orderBy: LaunchHistoryOrder! = CREATED_DESC): [Launch!] + + """ + Count of total launch history + """ + launchHistoryLength: Long + + links: [LinkInfo!] + + """ + Returns a paginated list of operation insights list items. + """ + operationInsightsList(after: String, before: String, filter: OperationInsightsListFilterInput, first: Int, from: Timestamp!, last: Int, orderBy: OperationInsightsListOrderByInput, to: Timestamp!): GraphVariantOperationInsightsListItemConnection! + + """ + The merged/computed/effective check configuration for the operations check task. + """ + operationsCheckConfiguration(overrides: OperationsCheckConfigurationOverridesInput): OperationsCheckConfiguration + + """ + Which permissions the current user has for interacting with this variant + """ + permissions: GraphVariantPermissions! + + readme: Readme! + + """ + The total number of requests for this variant in the last 24 hours + """ + requestsInLastDay: Long + + """ + The variant this variant is derived from. This property currently only exists on contract variants. + """ + sourceVariant: GraphVariant + + """ + A list of supported directives + """ + supportedDirectives: [DirectiveSupportStatus!] + + """ + The last instant that usage information (e.g. operation stat, client stats) was reported for this variant + """ + usageLastReportedAt: Timestamp + + """ + A list of the saved [operation collections](https://www.apollographql.com/docs/studio/explorer/operation-collections/) associated with this variant. + """ + operationCollections: [OperationCollection!]! + + """ + A list of the saved [operation collections](https://www.apollographql.com/docs/studio/explorer/operation-collections/) associated with this variant, paged. + """ + operationCollectionsConnection(after: String, before: String, first: Int, last: Int): GraphVariantOperationCollectionConnection + + """ + The Persisted Query List linked to this variant, if any. + """ + persistedQueryList: PersistedQueryList + + proposal: Proposal + + """ + The URL of the variant's GraphQL endpoint for query and mutation operations. For subscription operations, use `subscriptionUrl`. + """ + url: String + + """ + If the graphql endpoint is set up to accept cookies. + """ + sendCookies: Boolean + + """ + The URL of the variant's GraphQL endpoint for subscription operations. + """ + subscriptionUrl: String + + """ + Explorer setting for preflight script to run before the actual GraphQL operations is run. + """ + preflightScript: String + + """ + Explorer setting for shared headers for a graph + """ + sharedHeaders: String + + """ + As new schema tags keep getting published, activeSchemaPublish refers to the latest. + """ + activeSchemaPublish: SchemaTag + + """ + The details of the variant's most recent publication. + """ + latestPublication: SchemaTag + + """ + If the variant is protected + """ + isProtected: Boolean! + + """ + Generate a federated operation plan for a given operation + """ + plan(document: GraphQLDocument!, operationName: String): QueryPlan + + """ + If the variant has managed subgraphs. + """ + isFederated: Boolean @deprecated(reason: "Replaced by hasManagedSubgraphs") + + """ + If the variant has managed subgraphs. + """ + hasManagedSubgraphs: Boolean + + """ + A list of the subgraphs included in this variant. This value is null for non-federated variants. Set `includeDeleted` to `true` to include deleted subgraphs. + """ + subgraphs(includeDeleted: Boolean! = false): [FederatedImplementingService!] + + """ + A list of the subgraphs that have been published to since the variant was created. + Does not include subgraphs that were created & deleted since the variant was created. + """ + updatedSubgraphs: [FederatedImplementingService!] + + """ + A list of the entities across all subgraphs, exposed to consumers & up. This value is null for non-federated variants. + """ + entities: EntitiesResponseOrError + + """ + Returns the details of the subgraph with the provided `name`, or null if this variant doesn't include a subgraph with that name. + """ + subgraph(name: ID!): FederatedImplementingService + + """ + Registry stats for this particular graph variant + """ + registryStatsWindow(from: Timestamp!, resolution: Resolution, to: Timestamp): RegistryStatsWindow + + routerConfig: String +} + +type GraphVariantFieldInsightsListItemConnection { + """ + A list of edges from the graph variant to its field insights list items. + """ + edges: [GraphVariantFieldInsightsListItemEdge!] + + """ + A list of field insights list items that belong to a graph variant. + """ + nodes: [FieldInsightsListItem!] + + """ + Information to aid in pagination. + """ + pageInfo: FieldInsightsListPageInfo! + + """ + The total number of field insights list items connected to the graph variant + """ + totalCount: Int! +} + +""" +An edge between a graph variant and a field insights list item. +""" +type GraphVariantFieldInsightsListItemEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + A field insights list item attached to the graph variant. + """ + node: FieldInsightsListItem +} + +""" +Ways to filter graph variants. +""" +enum GraphVariantFilter { + """ + All Variants + """ + ALL + + """ + Variants favorited by the current user + """ + FAVORITES +} + +union GraphVariantLookup = GraphVariant|InvalidRefFormat + +""" +Modifies a variant of a graph, also called a schema tag in parts of our product. +""" +type GraphVariantMutation { + """ + Global identifier for the graph variant, in the form `graph@variant`. + """ + id: ID! + + """ + Gets the router attached to a graph variant + """ + router: RouterMutation + + createRouter(input: CreateRouterInput!): CreateRouterResult! + + destroyRouter: DestroyRouterResult! + + updateRouter(input: UpdateRouterInput!): UpdateRouterResult! + + addLinkToVariant(title: String, type: LinkInfoType!, url: String!): GraphVariant! + + buildConfig(tagInApiSchema: Boolean! = false, version: BuildPipelineTrack!): GraphVariant + + """ + Graph ID of the variant + """ + graphId: String! + + """ + Name of the variant, like `variant`. + """ + name: String! + + relaunch: RelaunchResult! + + removeLinkFromVariant(linkInfoId: ID!): GraphVariant! + + service: Service! + + setIsFavoriteOfCurrentUser(favorite: Boolean!): GraphVariant! + + """ + _Asynchronously_ kicks off operation checks for a proposed non-federated + schema change against its associated graph. + + Returns a `CheckRequestSuccess` object with a workflow ID that you can use + to check status, or an error object if the checks workflow failed to start. + """ + submitCheckSchemaAsync(input: CheckSchemaAsyncInput!): CheckRequestResult! + + """ + Submit a request for a Filter Schema Check and receive a result with a workflow ID that can be used to check status, or an error message that explains what went wrong. + """ + submitFilterCheckAsync(input: FilterCheckAsyncInput!): CheckRequestResult! + + """ + _Asynchronously_ kicks off composition and operation checks for a proposed subgraph schema change against its associated supergraph. + + Returns a `CheckRequestSuccess` object with a workflow ID that you can use + to check status, or an error object if the checks workflow failed to start. + """ + submitSubgraphCheckAsync(input: SubgraphCheckAsyncInput!): CheckRequestResult! + + updateCheckConfigurationDownstreamVariants("During downstream checks, this variant's check workflow will wait for all downstream check\nworkflows for variants to complete, and if any of them fail, then\nthis variant's check workflow will fail. If this argument is null, the value is unchanged." blockingDownstreamVariants: [String!]): VariantCheckConfiguration! + + updateCheckConfigurationEnableOperationsCheck(enabled: Boolean!): VariantCheckConfiguration + + updateCheckConfigurationExcludedClients("When this argument is true, indicates that graph-level configuration is appended to the\nvariant-level configuration." appendGraphSettings: Boolean!, "During operation checks, ignore clients matching any of the filters. If this\nargument is null, the value is unchanged." excludedClients: [ClientFilterInput!]): VariantCheckConfiguration! + + updateCheckConfigurationExcludedOperations("When this argument is true, indicates that graph-level configuration is appended to the\nvariant-level configuration." appendGraphSettings: Boolean!, "During operation checks, ignore operations matching any of the \nfilters. If this argument is null, the value is unchanged." excludedOperationNames: [OperationNameFilterInput!], "During operation checks, ignore operations matching any of the filters. If\nthis argument is null, the value is unchanged." excludedOperations: [OperationInfoFilterInput!]): VariantCheckConfiguration! + + updateCheckConfigurationIncludedVariants("During operation checks, fetch operations from the metrics data for \nvariants. If the useGraphSettings argument is true, this argument is ignored. If the\nuseGraphSettings argument is false and this argument is null, the value is unchanged (if\nuseGraphSettings was previously true, the default of a list containing just this variant is\nused instead)." includedVariants: [String!], "When this argument is true, indicates that graph-level configuration is used for this variant\nsetting." useGraphSettings: Boolean!): VariantCheckConfiguration! + + updateCheckConfigurationTimeRange("During operation checks, ignore operations that executed less than \ntimes in the time range. If the useGraphSettings argument is true, this argument is ignored. If\nthe useGraphSettings argument is false and this argument is null, the value is unchanged (if\nuseGraphSettings was previously true, the default of 1 is used instead)." operationCountThreshold: Int, "Duration operation checks, ignore operations that constituted less than\n% of the operations in the time range. Expected values are\nbetween 0% and 5%. If the useGraphSettings argument is true, this argument is ignored. If the\nuseGraphSettings argument is false and this argument is null, the value is unchanged (if\nuseGraphSettings was previously true, the default of 0% is used instead)." operationCountThresholdPercentage: Float, "During operation checks, fetch operations from the last seconds. If the\nuseGraphSettings argument is true, this argument is ignored. If the useGraphSettings argument\nis false and this argument is null, the value is unchanged (if useGraphSettings was previously\ntrue, the default of 7 days is used instead)." timeRangeSeconds: Long, "When this argument is true, indicates that graph-level configuration is used for this variant\nsetting." useGraphSettings: Boolean!): VariantCheckConfiguration! + + updateVariantIsPublic(isPublic: Boolean!): GraphVariant + + updateVariantIsPubliclyListed(isPubliclyListed: Boolean!): GraphVariant + + updateVariantIsVerified(isVerified: Boolean!): GraphVariant + + """ + Updates the [README](https://www.apollographql.com/docs/studio/org/graphs/#the-readme-page) of this variant. + """ + updateVariantReadme("The full new text of the README, as a Markdown-formatted string." readme: String!): GraphVariant + + runLintCheck(input: RunLintCheckInput!): CheckStepResult! + + linkPersistedQueryList(persistedQueryListId: ID!): LinkPersistedQueryListResultOrError! + + unlinkPersistedQueryList: UnlinkPersistedQueryListResultOrError! + + """ + Mutation called by CheckCoordinator to find associated proposals to the schema diffs in a check workflow + """ + runProposalsCheck(input: RunProposalsCheckInput!): CheckStepResult! + + internalVariantUUID: String! + + updateURL(url: String): GraphVariant + + updateSubscriptionURL(subscriptionUrl: String): GraphVariant + + updateSendCookies(sendCookies: Boolean!): GraphVariant + + updateIsProtected(isProtected: Boolean!): GraphVariant + + updatePreflightScript(preflightScript: String): GraphVariant + + updateSharedHeaders(sharedHeaders: String): GraphVariant + + """ + Delete the variant. + """ + delete: DeleteSchemaTagResult! + + upsertRouterConfig(configuration: String!): UpsertRouterResult +} + +type GraphVariantOperationCollectionConnection { + """ + A list of edges from the graph variant to its operation collections. + """ + edges: [GraphVariantOperationCollectionEdge!] + + """ + A list of operation collections attached to a graph variant. + """ + nodes: [OperationCollection!] + + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + + totalCount: Int! +} + +""" +An edge between a graph variant and an operation collection. +""" +type GraphVariantOperationCollectionEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + An operation collection attached to a graph variant. + """ + node: OperationCollection +} + +type GraphVariantOperationInsightsListItemConnection { + """ + A list of edges from the graph variant to its operation insights list items. + """ + edges: [GraphVariantOperationInsightsListItemEdge!] + + """ + A list of operation insights list items that belong to a graph variant. + """ + nodes: [OperationInsightsListItem!] + + """ + Information to aid in pagination. + """ + pageInfo: OperationInsightsListPageInfo! + + """ + The total number of operation insights list items connected to the graph variant. + """ + totalCount: Int! +} + +type GraphVariantOperationInsightsListItemEdge { + """ + A cursor for use in pagination. + """ + cursor: String! + + """ + A operation insights list items attached to the graph variant. + """ + node: OperationInsightsListItem +} + +""" +Individual permissions for the current user when interacting with a particular Studio graph variant. +""" +type GraphVariantPermissions { + """ + Whether the currently authenticated user is permitted to manage/update this variant's build configuration (e.g., build pipeline version). + """ + canManageBuildConfig: Boolean! + + """ + Whether the currently authenticated user is permitted to manage/update cloud routers + """ + canManageCloudRouter: Boolean! + + """ + Whether the currently authenticated user is permitted to update variant-level settings for the Apollo Studio Explorer. + """ + canManageExplorerSettings: Boolean! + + """ + Whether the currently authenticated user is permitted to publish schemas to this variant. + """ + canPushSchemas: Boolean! + + """ + Whether the currently authenticated user can read any information about this variant. + """ + canQuery: Boolean! + + """ + Whether the currently authenticated user is permitted to view this variant's build configuration details (e.g., build pipeline version). + """ + canQueryBuildConfig: Boolean! + + """ + Whether the currently authenticated user is permitted to view details regarding cloud routers + """ + canQueryCloudRouter: Boolean! + + """ + Whether the currently authenticated user is permitted to view cloud router logs + """ + canQueryCloudRouterLogs: Boolean! + + """ + Whether the currently authenticated user is permitted to view launch history + """ + canQueryLaunches: Boolean! + + """ + Whether the currently authenticated user is permitted to download schemas associated to this variant. + """ + canQuerySchemas: Boolean! + + canUpdateVariantLinkInfo: Boolean! + + """ + Whether the currently authenticated user is permitted to update the README for this variant. + """ + canUpdateVariantReadme: Boolean! + + variantId: ID! + + canCreateCollectionInVariant: Boolean! + + canShareCollectionInVariant: Boolean! +} + +input HistoricQueryParameters { + from: String = "-86400" + + to: String = "0" + + """ + Minimum number of requests within the window for a query to be considered. + """ + queryCountThreshold: Int = 1 + + """ + Number of requests within the window for a query to be considered, relative to + total request count. Expected values are between 0 and 0.05 (minimum 5% of total + request volume) + """ + queryCountThresholdPercentage: Float = 0 + + """ + A list of operation IDs to filter out during validation. + """ + ignoredOperations: [ID!] = null + + """ + A list of clients to filter out during validation. + """ + excludedClients: [ClientInfoFilter!] = null + + """ + A list of operation names to filter out during validation. + """ + excludedOperationNames: [OperationNameFilterInput!] = null + + """ + A list of variants to include in the validation. If no variants are provided + then this defaults to the "current" variant along with the base variant. The + base variant indicates the schema that generates diff and marks the metrics that + are checked for broken queries. We union this base variant with the untagged values('', + same as null inside of `in`, and 'current') in this metrics fetch. This strategy + supports users who have not tagged their metrics or schema. + """ + includedVariants: [String!] = null +} + +""" +Input type to provide when specifying configuration details for schema checks. +""" +input HistoricQueryParametersInput { + """ + Clients to be excluded from check. + """ + excludedClients: [ClientInfoFilter!] + + """ + Operations to be ignored in this schema check, specified by operation name. + """ + excludedOperationNames: [OperationNameFilterInput!] + + """ + Start time for operations to be checked against. Specified as either a) an ISO formatted date/time string or b) a negative number of seconds relative to the time the check request was submitted. + """ + from: String + + """ + Operations to be ignored in this schema check, specified by ID. + """ + ignoredOperations: [ID!] + + """ + Graph variants to be included in check. + """ + includedVariants: [String!] + + """ + Maximum number of queries to be checked against the change. + """ + queryCountThreshold: Int + + """ + Only fail check if this percentage of operations would be negatively impacted. + """ + queryCountThresholdPercentage: Float + + """ + End time for operations to be checked against. Specified as either a) an ISO formatted date/time string or b) a negative number of seconds relative to the time the check request was submitted. + """ + to: String +} + +enum HTTPMethod { + CONNECT + + DELETE + + GET + + HEAD + + OPTIONS + + PATCH + + POST + + PUT + + TRACE + + UNKNOWN + + UNRECOGNIZED +} + +""" +An identity (such as a `User` or `Graph`) in Apollo Studio. See implementing types for details. +""" +interface Identity { + """ + Returns a representation of the identity as an `Actor` type. + """ + asActor: Actor! + + """ + The identity's identifier, which is unique among objects of its type. + """ + id: ID! + + """ + The identity's human-readable name. + """ + name: String! +} + +""" +An actor's identity and info about the client they used to perform the action +""" +type IdentityAndClientInfo { + """ + Identity info about the actor + """ + identity: Identity + + """ + Client name provided when the actor performed the action + """ + clientName: String + + """ + Client version provided when the actor performed the action + """ + clientVersion: String +} + +union IdentityMutation = ServiceMutation|UserMutation + +type IgnoredRule { + ignoredRule: LintRule! + + schemaCoordinate: String! + + subgraphName: String +} + +input IgnoredRuleInput { + ignoredRule: LintRule! + + schemaCoordinate: String! + + subgraphName: String +} + +type IgnoreOperationsInChecksResult { + graph: Service! +} + +""" +The location of the implementing service config file in storage +""" +type ImplementingServiceLocation { + """ + The name of the implementing service + """ + name: String! + + """ + The path in storage to access the implementing service config file + """ + path: String! +} + +type InternalAdminUser { + role: InternalMdgAdminRole! userID: String! } -type InternalIdentity implements Identity { - accounts: [Account!]! +type InternalIdentity implements Identity { + asActor: Actor! + + email: String + + id: ID! + + name: String! + + accounts: [Account!]! +} + +enum InternalMdgAdminRole { + INTERNAL_MDG_READ_ONLY + + INTERNAL_MDG_SALES + + INTERNAL_MDG_SUPER_ADMIN + + INTERNAL_MDG_SUPPORT +} + +""" +Generic server error. This should only ever return 'internal server error' as a message +""" +type InternalServerError implements Error { + """ + Message related to the internal error + """ + message: String! +} + +type IntrospectionDirective { + name: String! + + description: String + + locations: [IntrospectionDirectiveLocation!]! + + args: [IntrospectionInputValue!]! +} + +input IntrospectionDirectiveInput { + name: String! + + description: String + + locations: [IntrospectionDirectiveLocation!]! + + args: [IntrospectionInputValueInput!]! + + isRepeatable: Boolean +} + +""" +__DirectiveLocation introspection type +""" +enum IntrospectionDirectiveLocation { + """ + Location adjacent to a query operation. + """ + QUERY + + """ + Location adjacent to a mutation operation. + """ + MUTATION + + """ + Location adjacent to a subscription operation. + """ + SUBSCRIPTION + + """ + Location adjacent to a field. + """ + FIELD + + """ + Location adjacent to a fragment definition. + """ + FRAGMENT_DEFINITION + + """ + Location adjacent to a fragment spread. + """ + FRAGMENT_SPREAD + + """ + Location adjacent to an inline fragment. + """ + INLINE_FRAGMENT + + """ + Location adjacent to a variable definition. + """ + VARIABLE_DEFINITION + + """ + Location adjacent to a schema definition. + """ + SCHEMA + + """ + Location adjacent to a scalar definition. + """ + SCALAR + + """ + Location adjacent to an object type definition. + """ + OBJECT + + """ + Location adjacent to a field definition. + """ + FIELD_DEFINITION + + """ + Location adjacent to an argument definition. + """ + ARGUMENT_DEFINITION + + """ + Location adjacent to an interface definition. + """ + INTERFACE + + """ + Location adjacent to a union definition. + """ + UNION + + """ + Location adjacent to an enum definition. + """ + ENUM + + """ + Location adjacent to an enum value definition. + """ + ENUM_VALUE + + """ + Location adjacent to an input object type definition. + """ + INPUT_OBJECT + + """ + Location adjacent to an input object field definition. + """ + INPUT_FIELD_DEFINITION +} + +""" +Values associated with introspection result for an enum value +""" +type IntrospectionEnumValue { + name: String! + + description: String + + isDeprecated: Boolean! + + depreactionReason: String @deprecated(reason: "Use deprecationReason instead") + + deprecationReason: String +} + +""" +__EnumValue introspection type +""" +input IntrospectionEnumValueInput { + name: String! + + description: String + + isDeprecated: Boolean! + + deprecationReason: String +} + +""" +Values associated with introspection result for field +""" +type IntrospectionField { + name: String! + + description: String + + args: [IntrospectionInputValue!]! + + type: IntrospectionType! + + isDeprecated: Boolean! + + deprecationReason: String +} + +""" +__Field introspection type +""" +input IntrospectionFieldInput { + name: String! + + description: String + + args: [IntrospectionInputValueInput!]! + + type: IntrospectionTypeInput! + + isDeprecated: Boolean! + + deprecationReason: String +} + +""" +Values associated with introspection result for an input field +""" +type IntrospectionInputValue { + name: String! + + description: String + + type: IntrospectionType! + + defaultValue: String +} + +""" +__Value introspection type +""" +input IntrospectionInputValueInput { + name: String! + + description: String + + type: IntrospectionTypeInput! + + defaultValue: String + + isDeprecated: Boolean + + deprecationReason: String +} + +type IntrospectionSchema { + types(filter: TypeFilterConfig = { + includeAbstractTypes: true + includeBuiltInTypes: true + includeIntrospectionTypes: true + } + ): [IntrospectionType!]! + + queryType: IntrospectionType! + + mutationType: IntrospectionType + + subscriptionType: IntrospectionType + + directives: [IntrospectionDirective!]! +} + +""" +__Schema introspection type +""" +input IntrospectionSchemaInput { + types: [IntrospectionTypeInput!] + + queryType: IntrospectionTypeRefInput! + + mutationType: IntrospectionTypeRefInput + + subscriptionType: IntrospectionTypeRefInput + + directives: [IntrospectionDirectiveInput!]! + + description: String +} + +""" +Object containing all possible values for an introspectionType +""" +type IntrospectionType { + kind: IntrospectionTypeKind + + name: String + + """ + printed representation of type, including nested nullability and list ofTypes + """ + printed: String! + + """ + the base kind of the type this references, ignoring lists and nullability + """ + baseKind: IntrospectionTypeKind + + description: String + + fields: [IntrospectionField!] + + interfaces: [IntrospectionType!] + + possibleTypes: [IntrospectionType!] + + enumValues(includeDeprecated: Boolean = false): [IntrospectionEnumValue!] + + inputFields: [IntrospectionInputValue!] + + ofType: IntrospectionType +} + +""" +__Type introspection type +""" +input IntrospectionTypeInput { + kind: IntrospectionTypeKind! + + name: String + + description: String + + specifiedByUrl: String + + fields: [IntrospectionFieldInput!] + + interfaces: [IntrospectionTypeInput!] + + possibleTypes: [IntrospectionTypeInput!] + + enumValues: [IntrospectionEnumValueInput!] + + inputFields: [IntrospectionInputValueInput!] + + ofType: IntrospectionTypeInput +} + +enum IntrospectionTypeKind { + """ + Indicates this type is a scalar. + """ + SCALAR + + """ + Indicates this type is an object. 'fields' and 'interfaces' are valid fields. + """ + OBJECT + + """ + Indicates this type is an interface. 'fields' and 'possibleTypes' are valid + fields + """ + INTERFACE + + """ + Indicates this type is a union. 'possibleTypes' is a valid field. + """ + UNION + + """ + Indicates this type is an enum. 'enumValues' is a valid field. + """ + ENUM + + """ + Indicates this type is an input object. 'inputFields' is a valid field. + """ + INPUT_OBJECT + + """ + Indicates this type is a list. 'ofType' is a valid field. + """ + LIST + + """ + Indicates this type is a non-null. 'ofType' is a valid field. + """ + NON_NULL +} + +""" +Shallow __Type introspection type +""" +input IntrospectionTypeRefInput { + name: String! + + kind: String +} + +""" +An error caused by providing invalid input for a task, such as schema checks. +""" +type InvalidInputError { + """ + The error message. + """ + message: String! +} + +""" +Generic input error +""" +type InvalidInputErrors implements Error { + errors: [CloudInvalidInputError!]! + + message: String! +} + +type InvalidOperation { + signature: ID! + + errors: [OperationValidationError!] +} + +""" +This object is returned when a request to fetch a Studio graph variant provides an invalid graph ref. +""" +type InvalidRefFormat implements Error { + message: String! +} + +""" +Invalid request +""" +type InvalidRequest { + """ + Error message + """ + message: String! +} + +type InvalidTarget implements Error { + message: String! +} + +type Invoice { + closedAt: Timestamp + + collectionMethod: String + + createdAt: Timestamp! + + id: ID! + + invoiceNumber: Int! + + invoiceNumberV2: String! + + state: InvoiceState! + + totalInCents: Int! + + updatedAt: Timestamp! + + uuid: ID! +} + +type InvoiceLineItem { + """ + Line items may be grouped to help the customer better understand their charges + """ + groupKey: String + + """ + Line items may be grouped to help the customer better understand their charges + """ + groupValue: String + + name: String! + + """ + The quantity of 'things' in this line item. (e.g. number of operations, seats, etc). + May be null for flat charges. + """ + quantity: Int + + """ + The amount this line item costs. + """ + totalInCents: Int! +} + +enum InvoiceState { + COLLECTED + + FAILED + + OPEN + + PAST_DUE + + UNKNOWN + + VOID +} + +scalar JSON + +""" +A scalar that can represent any JSON Object value. +""" +scalar JSONObject + +""" +Represents the complete process of making a set of updates to a deployed graph variant. +""" +type Launch { + """ + The unique identifier for this launch. + """ + id: ID! + + """ + The ID of the launch's associated graph. + """ + graphId: String! + + """ + The name of the launch's associated variant. + """ + graphVariant: String! + + """ + Cloud Router order for this launch ID + """ + order: OrderOrError! + + orders: [Order!]! + + """ + The timestamp when the launch was approved. + """ + approvedAt: Timestamp + + """ + The associated build for this launch (a build includes schema composition and contract filtering). This value is null until the build is initiated. + """ + build: Build + + """ + The inputs provided to this launch's associated build, including subgraph schemas and contract filters. + """ + buildInput: BuildInput! + + """ + The timestamp when the launch completed. This value is null until the launch completes. + """ + completedAt: Timestamp + + """ + The timestamp when the launch was initiated. + """ + createdAt: Timestamp! + + """ + Contract launches that were triggered by this launch. + """ + downstreamLaunches: [Launch!]! + + isAvailable: Boolean + + """ + Whether the launch completed. + """ + isCompleted: Boolean + + """ + Whether the result of the launch has been published to the associated graph and variant. This is always false for a failed launch. + """ + isPublished: Boolean + + isTarget: Boolean + + """ + The most recent launch sequence step that has started but not necessarily completed. + """ + latestSequenceStep: LaunchSequenceStep + + """ + The launch right before this one. Null if this is the first on this variant. + """ + previousLaunch: Launch + + """ + A specific publication of a graph variant pertaining to this launch. + """ + publication: SchemaTag + + """ + A list of results from the completed launch. The items included in this list vary depending on whether the launch succeeded, failed, or was superseded. + """ + results: [LaunchResult!]! + + """ + Cloud router configuration associated with this build event. It will be non-null for any cloud-router variant, and null for any not cloudy variant/graph. + """ + routerConfig: String + + schemaTag: SchemaTag + + """ + A list of all serial steps in the launch sequence. This list can change as the launch progresses. For example, a `LaunchCompletedStep` is appended after a launch completes. + """ + sequence: [LaunchSequenceStep!]! + + """ + A shortened version of `Launch.id` that includes only the first 8 characters. + """ + shortenedID: String! + + """ + The launch's status. If a launch is superseded, its status remains `LAUNCH_INITIATED`. To check for a superseded launch, use `supersededAt`. + """ + status: LaunchStatus! + + """ + A list of subgraph changes that are included in this launch. + """ + subgraphChanges: [SubgraphChange!] + + """ + The timestamp when this launch was superseded by another launch. If an active launch is superseded, it terminates. + """ + supersededAt: Timestamp + + """ + The launch that superseded this launch, if any. If an active launch is superseded, it terminates. + """ + supersededBy: Launch + + """ + The source variant launch that caused this launch to be initiated. This value is present only for contract variant launches. Otherwise, it's null. + """ + upstreamLaunch: Launch + + proposalRevision: ProposalRevision +} + +enum LaunchHistoryOrder { + CREATED_ASC + + CREATED_DESC +} + +union LaunchResult = ChangelogLaunchResult + +""" +The timing details for the build step of a launch. +""" +type LaunchSequenceBuildStep { + """ + The timestamp when the step completed. + """ + completedAt: Timestamp + + """ + The timestamp when the step started. + """ + startedAt: Timestamp +} + +""" +The timing details for the completion step of a launch. +""" +type LaunchSequenceCompletedStep { + """ + The timestamp when the step (and therefore the launch) completed. + """ + completedAt: Timestamp +} + +""" +The timing details for the initiation step of a launch. +""" +type LaunchSequenceInitiatedStep { + """ + The timestamp when the step (and therefore the launch) started. + """ + startedAt: Timestamp +} + +""" +The timing details for the publish step of a launch. +""" +type LaunchSequencePublishStep { + """ + The timestamp when the step completed. + """ + completedAt: Timestamp + + """ + The timestamp when the step started. + """ + startedAt: Timestamp +} + +union LaunchSequenceStep = LaunchSequenceBuildStep|LaunchSequenceCompletedStep|LaunchSequenceInitiatedStep|LaunchSequencePublishStep|LaunchSequenceSupersededStep + +""" +The timing details for the superseded step of a launch. This step occurs only if the launch is superseded by another launch. +""" +type LaunchSequenceSupersededStep { + """ + The timestamp when the step completed, thereby ending the execution of this launch in favor of the superseding launch. + """ + completedAt: Timestamp +} + +enum LaunchStatus { + LAUNCH_COMPLETED + + LAUNCH_FAILED + + LAUNCH_INITIATED +} + +type LinkInfo { + createdAt: Timestamp! + + id: ID! + + title: String + + type: LinkInfoType! + + url: String! +} + +enum LinkInfoType { + DEVELOPER_PORTAL + + OTHER + + REPOSITORY +} + +type LinkPersistedQueryListResult { + graphVariant: GraphVariant! + + persistedQueryList: PersistedQueryList! +} + +union LinkPersistedQueryListResultOrError = LinkPersistedQueryListResult|ListNotFoundError|PermissionError|VariantAlreadyLinkedError + +type LintCheckTask implements CheckWorkflowTask { + completedAt: Timestamp + + createdAt: Timestamp! + + graphID: ID! + + id: ID! + + status: CheckWorkflowTaskStatus! + + targetURL: String + + workflow: CheckWorkflow! + + result: LintResult +} + +""" +A single rule violation. +""" +type LintDiagnostic { + """ + The category used for grouping similar rules. + """ + category: LinterRuleCategory! + + """ + The schema coordinate of this diagnostic. + """ + coordinate: String! + + """ + The graph's configured level for the rule. + """ + level: LintDiagnosticLevel! + + """ + The message describing the rule violation. + """ + message: String! + + """ + The lint rule being violated. + """ + rule: LintRule! + + """ + The human readable position in the file of the rule violation. + """ + sourceLocations: [Location!]! +} + +""" +The severity level of an lint result. +""" +enum LintDiagnosticLevel { + ERROR + + IGNORED + + WARNING +} + +input LinterIgnoredRuleChangesInput { + ruleViolationsToEnable: [IgnoredRuleInput!]! + + ruleViolationsToIgnore: [IgnoredRuleInput!]! +} + +""" +The category used for grouping similar rules. +""" +enum LinterRuleCategory { + """ + These rules are generated during composition. + """ + COMPOSITION + + """ + These rules enforce naming conventions. + """ + NAMING + + """ + These rules define conventions for the entire schema and directive usage outside of composition. + """ + OTHER +} + +type LinterRuleLevelConfiguration { + """ + Illustrative code showcasing the potential violation of this rule. + """ + badExampleCode: String + + """ + The category used for grouping similar rules. + """ + category: LinterRuleCategory! + + """ + A human readable description of the rule. + """ + description: String! + + """ + Illustrative code showcasing the fix for the potential violation of this rule. + """ + goodExampleCode: String + + """ + The configured level for the rule. + """ + level: LintDiagnosticLevel! + + """ + The name for this lint rule. + """ + rule: LintRule! +} + +input LinterRuleLevelConfigurationChangesInput { + level: LintDiagnosticLevel! + + rule: LintRule! +} + +""" +The result of linting a schema. +""" +type LintResult { + """ + The set of lint rule violations found in the schema. + """ + diagnostics: [LintDiagnostic!]! + + """ + Stats generated from the resulting diagnostics. + """ + stats: LintStats! +} + +enum LintRule { + ALL_ELEMENTS_REQUIRE_DESCRIPTION + + CONTACT_DIRECTIVE_MISSING + + DEFINED_TYPES_ARE_UNUSED + + DEPRECATED_DIRECTIVE_MISSING_REASON + + DIRECTIVE_COMPOSITION + + DIRECTIVE_NAMES_SHOULD_BE_CAMEL_CASE + + DOES_NOT_PARSE + + ENUM_PREFIX + + ENUM_SUFFIX + + ENUM_USED_AS_INPUT_WITHOUT_SUFFIX + + ENUM_USED_AS_OUTPUT_DESPITE_SUFFIX + + ENUM_VALUES_SHOULD_BE_SCREAMING_SNAKE_CASE + + FIELD_NAMES_SHOULD_BE_CAMEL_CASE + + FROM_SUBGRAPH_DOES_NOT_EXIST + + INCONSISTENT_ARGUMENT_PRESENCE + + INCONSISTENT_BUT_COMPATIBLE_ARGUMENT_TYPE + + INCONSISTENT_BUT_COMPATIBLE_FIELD_TYPE + + INCONSISTENT_DEFAULT_VALUE_PRESENCE + + INCONSISTENT_DESCRIPTION + + INCONSISTENT_ENTITY + + INCONSISTENT_ENUM_VALUE_FOR_INPUT_ENUM + + INCONSISTENT_ENUM_VALUE_FOR_OUTPUT_ENUM + + INCONSISTENT_EXECUTABLE_DIRECTIVE_LOCATIONS + + INCONSISTENT_EXECUTABLE_DIRECTIVE_PRESENCE + + INCONSISTENT_EXECUTABLE_DIRECTIVE_REPEATABLE + + INCONSISTENT_INPUT_OBJECT_FIELD + + INCONSISTENT_INTERFACE_VALUE_TYPE_FIELD + + INCONSISTENT_NON_REPEATABLE_DIRECTIVE_ARGUMENTS + + INCONSISTENT_OBJECT_VALUE_TYPE_FIELD + + INCONSISTENT_RUNTIME_TYPES_FOR_SHAREABLE_RETURN + + INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_LOCATIONS + + INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_REPEATABLE + + INCONSISTENT_UNION_MEMBER + + INPUT_ARGUMENT_NAMES_SHOULD_BE_CAMEL_CASE + + INPUT_TYPE_SUFFIX + + INTERFACE_PREFIX + + INTERFACE_SUFFIX + + MERGED_NON_REPEATABLE_DIRECTIVE_ARGUMENTS + + NO_EXECUTABLE_DIRECTIVE_INTERSECTION + + OBJECT_PREFIX + + OBJECT_SUFFIX + + OVERRIDDEN_FIELD_CAN_BE_REMOVED + + OVERRIDE_DIRECTIVE_CAN_BE_REMOVED + + QUERY_DOCUMENT_DECLARATION + + RESTY_FIELD_NAMES + + TAG_DIRECTIVE_USES_UNKNOWN_NAME + + TYPE_NAMES_SHOULD_BE_PASCAL_CASE + + TYPE_PREFIX + + TYPE_SUFFIX + + UNUSED_ENUM_TYPE +} + +""" +Stats generated from linting a schema against the graph's linter configuration. +""" +type LintStats { + """ + Total number of lint errors. + """ + errorsCount: Int! + + """ + Total number of lint rules ignored. + """ + ignoredCount: Int! + + """ + Total number of lint rules violated. + """ + totalCount: Int! + + """ + Total number of lint warnings. + """ + warningsCount: Int! +} + +type ListNotFoundError implements Error { + listId: ID! + + message: String! +} + +type Location { + end: Coordinate + + start: Coordinate + + subgraphName: String +} + +""" +Level of the log entry +""" +enum LogLevel { + """ + Debug log entry + """ + DEBUG + + """ + Informational log entry + """ + INFO + + """ + Warning log entry + """ + WARN + + """ + Error log entry + """ + ERROR +} + +""" +Order log message +""" +type LogMessage { + """ + Timestamp in UTC + """ + timestamp: DateTime! + + """ + Log message contents + """ + message: String! + + """ + Log level + """ + level: LogLevel! +} + +""" +Long type +""" +scalar Long + +type MarkChangesForOperationAsSafeResult { + success: Boolean! + + message: String! + + """ + Nice to have for the frontend since the Apollo cache is already watching for AffectedQuery to update. + This might return null if no behavior changes were found for the affected operation ID. + This is a weird situation that should never happen. + """ + affectedOperation: AffectedQuery +} + +type MediaUploadInfo { + csrfToken: String! + + maxContentLength: Int! + + url: String! +} + +type Message { + auditLog: [AuditLog!]! + + channels: [SlackCommunicationChannel!]! + + confirmations: [MessageConfirmation]! + + content: MessageContent! + + createdAt: Timestamp! + + id: ID! + + modifiedAt: Timestamp! + + state: State! + + user: RequesterUser! +} + +type MessageConfirmation { + channel: SlackCommunicationChannel + + createdAt: Timestamp! + + id: ID! + + modifiedAt: Timestamp! + + slackMessage: SlackMessageMeta! + + state: SlackPublishState! +} + +type MessageContent { + body: String! + + buttonText: String + + buttonURL: String + + header: String! +} + +input MessageInput { + body_text: String! + + button_text: String + + button_url: String + + channel_id: [ID!]! + + header_text: String! +} + +union MessageMutationResult = CustomerSupportSlackError|Message + +type MetricStatWindow { + timestamp: Timestamp! + + value: Long! + + windowSize: BillingUsageStatsWindowSize! +} + +union MoveOperationCollectionEntryResult = InvalidTarget|MoveOperationCollectionEntrySuccess|PermissionError + +type MoveOperationCollectionEntrySuccess { + operation: OperationCollectionEntry! + + originCollection: OperationCollection! + + targetCollection: OperationCollection! +} + +""" +GraphQL mutations +""" +type Mutation { + billing: BillingMutation + + """ + Define a new billing plan + """ + newBillingPlan(plan: BillingPlanInput!): BillingPlan + + """ + Define a new boolean capability to be applied to billing plans and subscriptions + """ + newCapability(capability: BillingCapabilityInput!): BillingCapability + + """ + Define a new numeric limit to be applied to billing plans and subscriptions + """ + newLimit(limit: BillingLimitInput!): BillingLimit + + plan(id: ID!): BillingPlanMutation + + updateSurvey(internalAccountId: String!, surveyId: String!, surveyState: [SurveyQuestionInput!]!): Survey! + + """ + Cloud mutations + """ + cloud: CloudMutation! + + account(id: ID!): AccountMutation + + me: IdentityMutation + + signUp(email: String!, fullName: String!, password: String!, referrer: String, trackingGoogleClientId: String, trackingMarketoClientId: String, userSegment: UserSegment, utmCampaign: String, utmMedium: String, utmSource: String): User + + """ + Finalize a password reset with a token included in the E-mail link, + returns the corresponding login email when successful + """ + finalizePasswordReset(newPassword: String!, resetToken: String!): String + + """ + Provides access to mutation fields for modifying a Studio graph with the provided ID. + """ + graph(id: ID!): ServiceMutation + + """ + Join an account with a token + """ + joinAccount(accountId: ID!, joinToken: String!): Account + + newAccount(companyUrl: String, id: ID!, organizationName: String, planId: String): Account + + newService(accountId: ID!, description: String, hiddenFromUninvitedNonAdminAccountMembers: Boolean! = false, id: ID!, isDev: Boolean = false @deprecated(reason: "No longer supported"), name: String, onboardingArchitecture: OnboardingArchitecture, title: String): Service + + """ + Report a running GraphQL server's schema. + """ + reportSchema("Only sent if previously requested i.e. received ReportSchemaResult with withCoreSchema = true. This is a GraphQL schema document as a string. Note that for a GraphQL server with a core schema, this should be the core schema, not the API schema." coreSchema: String, "Information about server and its schema." report: SchemaReport!): ReportSchemaResult + + """ + Ask for a user's password to be reset by E-mail + """ + resetPassword(email: String!): Void + + resolveAllInternalCronExecutions(group: String, name: String): Void + + resolveInternalCronExecution(id: ID!): CronExecution + + service(id: ID!): ServiceMutation + + """ + Set the subscriptions for a given email + """ + setSubscriptions(email: String!, subscriptions: [EmailCategory!]!, token: String!): EmailPreferences + + """ + Set the studio settings for the current user + """ + setUserSettings(newSettings: UserSettingsInput): UserSettings + + """ + This is called by the form shown to users after they delete their user or organization account. + """ + submitPostDeletionFeedback(feedback: String!, targetIdentifier: ID!, targetType: DeletionTargetType!): Void + + """ + Mutation for basic engagement tracking in studio + """ + track(event: EventEnum!, graphID: String!, graphVariant: String! = "current"): Void + + """ + Apollo Kotlin usage tracking. + """ + trackApolloKotlinUsage("Events to log" events: [ApolloKotlinUsageEventInput!]!, "A random ID that is generated on first initialization of the Apollo Kotlin IJ\/AS plugin on a given project" instanceId: ID!, "Properties to log" properties: [ApolloKotlinUsagePropertyInput!]!): Void + + """ + Router usage tracking. Reserved to https://router.apollo.dev/telemetry (https://github.com/apollographql/orbiter). + """ + trackRouterUsage("If we think the router is being run on continuous integration then this will be populated" ci: String, "The OS that the router is running on" os: String!, "A random ID that is generated on first startup of the Router. It is not persistent between restarts of the Router, but will be persistent for hot reloads" sessionId: ID!, "A list of key count pairs that represents the a path into the config\/arguments and the number of times that it occurred" usage: [RouterUsageInput!]!, "The version of the Router" version: String!): Void + + """ + Rover session tracking. Reserved to https://rover.apollo.dev/telemetry (https://github.com/apollographql/orbiter). + """ + trackRoverSession(anonymousId: ID!, arguments: [RoverArgumentInput!]!, ci: String, command: String!, cwdHash: SHA256!, os: String!, remoteUrlHash: SHA256, sessionId: ID!, version: String!): Void + + """ + Unsubscribe a given email from all emails + """ + unsubscribeFromAll(email: String!, token: String!): EmailPreferences + + """ + Provides access to mutation fields for modifying an Apollo user with the + provided ID. + """ + user(id: ID!): UserMutation + + """ + Push a lead to Marketo by program ID + """ + pushMarketoLead("Marketo program ID" programId: ID!, "Marketo program status" programStatus: String, "Marketo lead source" source: String, input: PushMarketoLeadInput!): Boolean! + + transferOdysseyProgress(from: ID!, to: ID!): Boolean! + + """ + Creates an [operation collection](https://www.apollographql.com/docs/studio/explorer/operation-collections/) for a given variant, or creates a [sandbox collection](https://www.apollographql.com/docs/studio/explorer/operation-collections/#sandbox-collections) without an associated variant. + """ + createOperationCollection("The collection's description." description: String, "Whether the collection is a [sandbox collection](https:\/\/www.apollographql.com\/docs\/studio\/explorer\/operation-collections\/#sandbox-collections)." isSandbox: Boolean!, "Whether the collection is shared across its associated organization." isShared: Boolean!, "The minimum role a user needs to edit this collection. Valid values: null, CONSUMER, OBSERVER, DOCUMENTER, CONTRIBUTOR, GRAPH_ADMIN. This value is ignored if `isShared` is `false`. The default value is `GRAPH_ADMIN`." minEditRole: UserPermission, "The collection's name." name: String!, "The [graph ref](https:\/\/www.apollographql.com\/docs\/rover\/conventions\/#graph-refs) of the graph variants to associate the collection with." variantRefs: [ID!]): CreateOperationCollectionResult! + + operationCollection(id: ID!): OperationCollectionMutation + + proposal(id: ID!): ProposalMutationResult! + + proposalByVariantRef(variantRef: ID!): ProposalMutationResult! + + approveMessage(messageId: ID!, state: State!): MessageMutationResult! + + createMessage(message: MessageInput!): MessageMutationResult! + + editMessage(messageId: ID!, messageUpdates: MessageInput!): MessageMutationResult! + + publishSlackMessage(messageId: ID!): MessageMutationResult! + + publishSlackTest(messageId: ID!): MessageMutationResult! + + recallMessage(slackChannelId: ID!, slackMessageId: ID!): MessageMutationResult! +} + +""" +ISO 8601 combined date and time without timezone. + +# Examples + +* `2015-07-01T08:59:60.123`, +""" +scalar NaiveDateTime + +type NamedIntrospectionArg { + name: String + + description: String +} + +type NamedIntrospectionArgNoDescription { + name: String +} + +""" +The shared fields for a named introspection type. Currently this is returned for the +top level value affected by a change. In the future, we may update this +type to be an interface, which is extended by the more specific types: +scalar, object, input object, union, interface, and enum + +For an in-depth look at where these types come from, see: +https://github.com/DefinitelyTyped/DefinitelyTyped/blob/659eb50d3/types/graphql/utilities/introspectionQuery.d.ts#L31-L37 +""" +type NamedIntrospectionType { + kind: IntrospectionTypeKind + + name: String + + description: String +} + +type NamedIntrospectionTypeNoDescription { + name: String +} + +""" +Introspection values that can be children of other types for changes, such +as input fields, objects in interfaces, enum values. In the future, this +value could become an interface to allow fields specific to the types +returned. +""" +type NamedIntrospectionValue { + name: String + + description: String + + printedType: String +} + +type NamedIntrospectionValueNoDescription { + name: String + + printedType: String +} + +""" +A non-federated service for a monolithic graph. +""" +type NonFederatedImplementingService { + """ + Timestamp of when this implementing service was created. + """ + createdAt: Timestamp! + + """ + Identifies which graph this non-implementing service belongs to. + Formerly known as "service_id". + """ + graphID: String! + + """ + Specifies which variant of a graph this implementing service belongs to". + Formerly known as "tag". + """ + graphVariant: String! +} + +""" +An error that occurs when a requested object is not found. +""" +type NotFoundError implements Error { + """ + The error message. + """ + message: String! +} + +""" +An arbitrary JSON object. +""" +scalar Object + +type OdysseyAttempt { + id: ID! + + testId: String! + + startedAt: Timestamp! + + completedAt: Timestamp + + responses: [OdysseyResponse!]! + + pass: Boolean +} + +type OdysseyCertification { + id: ID! + + certificationId: String! + + earnedAt: Timestamp! + + owner: OdysseyCertificationOwner + + source: String +} + +type OdysseyCertificationOwner { + id: ID! + + fullName: String! +} + +type OdysseyCourse { + id: ID! + + enrolledAt: Timestamp + + completedAt: Timestamp +} + +input OdysseyCourseInput { + courseId: String! + + completedAt: Timestamp + + isBeta: Boolean +} + +type OdysseyResponse { + id: ID! + + questionId: String! + + values: [OdysseyValue!]! + + correct: Boolean +} + +input OdysseyResponseCorrectnessInput { + id: ID! + + correct: Boolean! +} + +input OdysseyResponseInput { + attemptId: ID! + + questionId: String! + + correct: Boolean + + values: [String!]! +} + +type OdysseyTask { + id: ID! + + value: String + + completedAt: Timestamp +} + +input OdysseyTaskInput { + taskId: String! + + value: String + + completedAt: Timestamp +} + +type OdysseyValue { + id: ID! + + value: String! +} + +enum OnboardingArchitecture { + MONOLITH + + SUPERGRAPH +} + +type Operation { + id: ID! + + name: String - asActor: Actor! + signature: String - email: String + truncated: Boolean! +} +type OperationAcceptedChange { id: ID! - name: String! -} + graphID: ID! -enum InternalMdgAdminRole { - INTERNAL_MDG_READ_ONLY + checkID: ID! - INTERNAL_MDG_SALES + operationID: String! - INTERNAL_MDG_SUPER_ADMIN + change: StoredApprovedChange! - INTERNAL_MDG_SUPPORT + acceptedAt: Timestamp! + + acceptedBy: Identity } """ -Generic server error. This should only ever return 'internal server error' as a message +Columns of OperationCheckStats. """ -type InternalServerError implements Error { - message: String! -} +enum OperationCheckStatsColumn { + CACHED_REQUESTS_COUNT -type IntrospectionDirective { - name: String! + CLIENT_NAME - description: String + CLIENT_VERSION - locations: [IntrospectionDirectiveLocation!]! + OPERATION_SUBTYPE - args: [IntrospectionInputValue!]! + OPERATION_TYPE + + QUERY_ID + + QUERY_NAME + + SCHEMA_TAG + + SERVICE_ID + + TIMESTAMP + + UNCACHED_REQUESTS_COUNT } -input IntrospectionDirectiveInput { - name: String! +type OperationCheckStatsDimensions { + clientName: String - description: String + clientVersion: String - locations: [IntrospectionDirectiveLocation!]! + operationSubtype: String - args: [IntrospectionInputValueInput!]! + operationType: String - isRepeatable: Boolean + queryId: ID + + queryName: String + + schemaTag: String + + serviceId: ID } """ -__DirectiveLocation introspection type +Filter for data in OperationCheckStats. Fields with dimension names represent equality checks. All fields are implicitly ANDed together. """ -enum IntrospectionDirectiveLocation { - """ - Location adjacent to a query operation. - """ - QUERY +input OperationCheckStatsFilter { + and: [OperationCheckStatsFilter!] """ - Location adjacent to a mutation operation. + Selects rows whose clientName dimension equals the given value if not null. To query for the null value, use {in: {clientName: [null]}} instead. """ - MUTATION + clientName: String """ - Location adjacent to a subscription operation. + Selects rows whose clientVersion dimension equals the given value if not null. To query for the null value, use {in: {clientVersion: [null]}} instead. """ - SUBSCRIPTION + clientVersion: String - """ - Location adjacent to a field. - """ - FIELD + in: OperationCheckStatsFilterIn - """ - Location adjacent to a fragment definition. - """ - FRAGMENT_DEFINITION + not: OperationCheckStatsFilter """ - Location adjacent to a fragment spread. + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. """ - FRAGMENT_SPREAD + operationSubtype: String """ - Location adjacent to an inline fragment. + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. """ - INLINE_FRAGMENT + operationType: String + + or: [OperationCheckStatsFilter!] """ - Location adjacent to a variable definition. + Selects rows whose queryId dimension equals the given value if not null. To query for the null value, use {in: {queryId: [null]}} instead. """ - VARIABLE_DEFINITION + queryId: ID """ - Location adjacent to a schema definition. + Selects rows whose queryName dimension equals the given value if not null. To query for the null value, use {in: {queryName: [null]}} instead. """ - SCHEMA + queryName: String """ - Location adjacent to a scalar definition. + Selects rows whose schemaTag dimension equals the given value if not null. To query for the null value, use {in: {schemaTag: [null]}} instead. """ - SCALAR + schemaTag: String """ - Location adjacent to an object type definition. + Selects rows whose serviceId dimension equals the given value if not null. To query for the null value, use {in: {serviceId: [null]}} instead. """ - OBJECT + serviceId: ID +} +""" +Filter for data in OperationCheckStats. Fields match if the corresponding dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input OperationCheckStatsFilterIn { """ - Location adjacent to a field definition. + Selects rows whose clientName dimension is in the given list. A null value in the list means a row with null for that dimension. """ - FIELD_DEFINITION + clientName: [String] """ - Location adjacent to an argument definition. + Selects rows whose clientVersion dimension is in the given list. A null value in the list means a row with null for that dimension. """ - ARGUMENT_DEFINITION + clientVersion: [String] """ - Location adjacent to an interface definition. + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. """ - INTERFACE + operationSubtype: [String] """ - Location adjacent to a union definition. + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. """ - UNION + operationType: [String] """ - Location adjacent to an enum definition. + Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. """ - ENUM + queryId: [ID] """ - Location adjacent to an enum value definition. + Selects rows whose queryName dimension is in the given list. A null value in the list means a row with null for that dimension. """ - ENUM_VALUE + queryName: [String] """ - Location adjacent to an input object type definition. + Selects rows whose schemaTag dimension is in the given list. A null value in the list means a row with null for that dimension. """ - INPUT_OBJECT + schemaTag: [String] """ - Location adjacent to an input object field definition. + Selects rows whose serviceId dimension is in the given list. A null value in the list means a row with null for that dimension. """ - INPUT_FIELD_DEFINITION + serviceId: [ID] } -""" -Values associated with introspection result for an enum value -""" -type IntrospectionEnumValue { - name: String! - - description: String +type OperationCheckStatsMetrics { + cachedRequestsCount: Long! - isDeprecated: Boolean! + uncachedRequestsCount: Long! +} - depreactionReason: String @deprecated(reason: "Use deprecationReason instead") +input OperationCheckStatsOrderBySpec { + column: OperationCheckStatsColumn! - deprecationReason: String + direction: Ordering! } -""" -__EnumValue introspection type -""" -input IntrospectionEnumValueInput { - name: String! - - description: String +type OperationCheckStatsRecord { + """ + Dimensions of OperationCheckStats that can be grouped by. + """ + groupBy: OperationCheckStatsDimensions! - isDeprecated: Boolean! + """ + Metrics of OperationCheckStats that can be aggregated over. + """ + metrics: OperationCheckStatsMetrics! - deprecationReason: String + """ + Starting segment timestamp. + """ + timestamp: Timestamp! } """ -Values associated with introspection result for field +A list of saved GraphQL operations. """ -type IntrospectionField { - name: String! - - description: String - - args: [IntrospectionInputValue!]! +type OperationCollection { + """ + The timestamp when the collection was created. + """ + createdAt: Timestamp! - type: IntrospectionType! + """ + The user or other entity that created the collection. + """ + createdBy: Identity - isDeprecated: Boolean! + """ + The collection's description. A `null` description was never set, and empty string description was set to be empty string by a user, or other entity. + """ + description: String - deprecationReason: String -} + """ + If a user has any of these roles, they will be able to edit this + collection. + """ + editRoles: [UserPermission!] @deprecated(reason: "deprecated in favour of minEditRole") -""" -__Field introspection type -""" -input IntrospectionFieldInput { - name: String! + id: ID! - description: String + """ + Whether the current user has marked the collection as a favorite. + """ + isFavorite: Boolean! - args: [IntrospectionInputValueInput!]! + """ + Whether the collection is a [sandbox collection](https://www.apollographql.com/docs/studio/explorer/operation-collections/#sandbox-collections). + """ + isSandbox: Boolean! - type: IntrospectionTypeInput! + """ + Whether the collection is shared across its associated organization. + """ + isShared: Boolean! - isDeprecated: Boolean! + """ + The timestamp when the collection was most recently updated. + """ + lastUpdatedAt: Timestamp! - deprecationReason: String -} + """ + The user or other entity that most recently updated the collection. + """ + lastUpdatedBy: Identity -""" -Values associated with introspection result for an input field -""" -type IntrospectionInputValue { + """ + The minimum role a user needs to edit this collection. Valid values: null, CONSUMER, OBSERVER, DOCUMENTER, CONTRIBUTOR, GRAPH_ADMIN. This value is always `null` if `isShared` is `false`. If `null` when `isShared` is `true`, the minimum role is `GRAPH_ADMIN`. + """ + minEditRole: UserPermission + + """ + The collection's name. + """ name: String! - description: String + """ + Returns the operation in the collection with the specified ID, if any. + """ + operation(id: ID!): OperationCollectionEntryResult - type: IntrospectionType! + """ + A list of the GraphQL operations that belong to the collection. + """ + operations: [OperationCollectionEntry!]! - defaultValue: String + """ + The permissions that the current user has for the collection. + """ + permissions: OperationCollectionPermissions! + + variants: [GraphVariant!]! } """ -__Value introspection type +A saved operation entry within an Operation Collection. """ -input IntrospectionInputValueInput { - name: String! - - description: String - - type: IntrospectionTypeInput! +type OperationCollectionEntry { + collection: OperationCollection! - defaultValue: String + """ + The timestamp when the entry was created. + """ + createdAt: Timestamp! - isDeprecated: Boolean + """ + The user or other entity that created the entry. + """ + createdBy: Identity - deprecationReason: String -} + """ + Details of the entry's associated operation, such as its `body` and `variables`. + """ + currentOperationRevision: OperationCollectionEntryState! -type IntrospectionSchema { - types(filter: TypeFilterConfig = { - includeAbstractTypes: true - includeBuiltInTypes: true - includeIntrospectionTypes: true - } - ): [IntrospectionType!]! + id: ID! - queryType: IntrospectionType! + """ + The timestamp when the entry was most recently updated. + """ + lastUpdatedAt: Timestamp! - mutationType: IntrospectionType + """ + The user or other entity that most recently updated the entry. + """ + lastUpdatedBy: Identity - subscriptionType: IntrospectionType + """ + The entry's name. + """ + name: String! - directives: [IntrospectionDirective!]! + """ + The entry's lexicographical ordering index within its containing collection. + """ + orderingIndex: String! } """ -__Schema introspection type +Provides fields for modifying an operation in a collection. """ -input IntrospectionSchemaInput { - types: [IntrospectionTypeInput!] +type OperationCollectionEntryMutation { + moveToCollection(collectionId: ID!, lowerOrderingBound: String, upperOrderingBound: String): MoveOperationCollectionEntryResult! - queryType: IntrospectionTypeRefInput! + reorderEntry(lowerOrderingBound: String, upperOrderingBound: String): UpdateOperationCollectionResult - mutationType: IntrospectionTypeRefInput + """ + Updates the name of an operation. + """ + updateName(name: String!): UpdateOperationCollectionEntryResult - subscriptionType: IntrospectionTypeRefInput + """ + Updates the body, headers, and/or variables of an operation. + """ + updateValues(operationInput: OperationCollectionEntryStateInput!): UpdateOperationCollectionEntryResult +} - directives: [IntrospectionDirectiveInput!]! +union OperationCollectionEntryMutationResult = NotFoundError|OperationCollectionEntryMutation|PermissionError - description: String -} +union OperationCollectionEntryResult = NotFoundError|OperationCollectionEntry """ -Object containing all possible values for an introspectionType +The most recent body, variable and header values of a saved operation entry. """ -type IntrospectionType { - kind: IntrospectionTypeKind - - name: String +type OperationCollectionEntryState { + """ + The raw body of the entry's GraphQL operation. + """ + body: String! """ - printed representation of type, including nested nullability and list ofTypes + The timestamp when the entry state was created. """ - printed: String! + createdAt: Timestamp! """ - the base kind of the type this references, ignoring lists and nullability + The user or other entity that created this entry state. """ - baseKind: IntrospectionTypeKind + createdBy: Identity - description: String + """ + Headers for the entry's GraphQL operation. + """ + headers: [OperationHeader!] - fields: [IntrospectionField!] + """ + The workflow automation script for this entry's GraphQL operation + """ + script: String - interfaces: [IntrospectionType!] + """ + Variables for the entry's GraphQL operation, as a JSON string. + """ + variables: String +} - possibleTypes: [IntrospectionType!] +""" +Fields for creating or modifying an operation collection entry. +""" +input OperationCollectionEntryStateInput { + """ + The operation's query body. + """ + body: String! - enumValues(includeDeprecated: Boolean = false): [IntrospectionEnumValue!] + """ + The operation's headers. + """ + headers: [OperationHeaderInput!] - inputFields: [IntrospectionInputValue!] + """ + The operation's workflow script + """ + script: String - ofType: IntrospectionType + """ + The operation's variables. + """ + variables: String } """ -__Type introspection type +Provides fields for modifying an [operation collection](https://www.apollographql.com/docs/studio/explorer/operation-collections/). """ -input IntrospectionTypeInput { - kind: IntrospectionTypeKind! +type OperationCollectionMutation { + """ + Adds an operation to this collection. + """ + addOperation(name: String!, operationInput: OperationCollectionEntryStateInput!): AddOperationCollectionEntryResult - name: String + """ + Adds operations to this collection. + """ + addOperations(operations: [AddOperationInput!]!): AddOperationCollectionEntriesResult - description: String + addToVariant(variantRef: ID!): AddOperationCollectionToVariantResult! @deprecated(reason: "Will throw NotImplemented") - specifiedByUrl: String + """ + Deletes this operation collection. This also deletes all of the collection's associated operations. + """ + delete: DeleteOperationCollectionResult - fields: [IntrospectionFieldInput!] + """ + Deletes an operation from this collection. + """ + deleteOperation(id: ID!): RemoveOperationCollectionEntryResult - interfaces: [IntrospectionTypeInput!] + duplicateCollection(description: String, isSandbox: Boolean!, isShared: Boolean!, name: String!, variantRef: ID): DuplicateOperationCollectionResult! - possibleTypes: [IntrospectionTypeInput!] + operation(id: ID!): OperationCollectionEntryMutationResult - enumValues: [IntrospectionEnumValueInput!] + removeFromVariant(variantRef: ID!): RemoveOperationCollectionFromVariantResult! @deprecated(reason: "Will throw NotImplemented") - inputFields: [IntrospectionInputValueInput!] + """ + Updates the minimum role a user needs to be able to modify this collection. + """ + setMinEditRole(editRole: UserPermission): UpdateOperationCollectionResult - ofType: IntrospectionTypeInput -} + """ + Updates this collection's description. + """ + updateDescription(description: String): UpdateOperationCollectionResult -enum IntrospectionTypeKind { """ - Indicates this type is a scalar. + Updates whether the current user has marked this collection as a favorite. """ - SCALAR + updateIsFavorite(isFavorite: Boolean!): UpdateOperationCollectionResult """ - Indicates this type is an object. 'fields' and 'interfaces' are valid fields. + Updates whether this collection is shared across its associated organization. """ - OBJECT + updateIsShared(isShared: Boolean!): UpdateOperationCollectionResult """ - Indicates this type is an interface. 'fields' and 'possibleTypes' are valid - fields + Updates this operation collection's name. """ - INTERFACE + updateName(name: String!): UpdateOperationCollectionResult +} +""" +Whether the current user can perform various actions on the associated collection. +""" +type OperationCollectionPermissions { """ - Indicates this type is a union. 'possibleTypes' is a valid field. + Whether the current user can edit operations in the associated collection. """ - UNION + canEditOperations: Boolean! """ - Indicates this type is an enum. 'enumValues' is a valid field. + Whether the current user can delete or update the associated collection's metadata, such as its name and description. """ - ENUM + canManage: Boolean! """ - Indicates this type is an input object. 'inputFields' is a valid field. + Whether the current user can read operations in the associated collection. """ - INPUT_OBJECT + canReadOperations: Boolean! +} + +union OperationCollectionResult = NotFoundError|OperationCollection|PermissionError|ValidationError +type OperationDocument { """ - Indicates this type is a list. 'ofType' is a valid field. + Operation document body """ - LIST + body: String! """ - Indicates this type is a non-null. 'ofType' is a valid field. + Operation name + """ + name: String +} + +input OperationDocumentInput { + """ + Operation document body + """ + body: String! + + """ + Operation name """ - NON_NULL + name: String } """ -Shallow __Type introspection type +Saved headers on a saved operation. """ -input IntrospectionTypeRefInput { +type OperationHeader { + """ + The header's name. + """ name: String! - kind: String + """ + The header's value. + """ + value: String! } -""" -An error caused by providing invalid input for a task, such as schema checks. -""" -type InvalidInputError { +input OperationHeaderInput { """ - The error message. + The header's name. """ - message: String! + name: String! + + """ + The header's value. + """ + value: String! } -""" -Generic input error -""" -type InvalidInputErrors implements Error { - errors: [CloudInvalidInputError!]! +type OperationInfoFilter { + id: String! +} - message: String! +input OperationInfoFilterInput { + id: String! } -type InvalidOperation { - signature: ID! +input OperationInsightsListFilterInInput { + clientName: [String] - errors: [OperationValidationError!] + clientVersion: [String] } -""" -This object is returned when a request to fetch a Studio graph variant provides an invalid graph ref. -""" -type InvalidRefFormat implements Error { - message: String! -} +input OperationInsightsListFilterInput { + clientName: String -type InvalidRequest { - message: String! -} + clientVersion: String -type InvalidTarget implements Error { - message: String! -} + in: OperationInsightsListFilterInInput -type Invoice { - closedAt: Timestamp + isUnnamed: Boolean - collectionMethod: String + isUnregistered: Boolean - createdAt: Timestamp! + operationTypes: [OperationType!] - id: ID! + or: [OperationInsightsListFilterInput!] - invoiceNumber: Int! + search: String +} - invoiceNumberV2: String! +type OperationInsightsListItem { + cacheHitRate: Float! - state: InvoiceState! + cacheTtlP50Ms: Float! - totalInCents: Int! + errorCount: Long! - updatedAt: Timestamp! + errorCountPerMin: Float! - uuid: ID! -} + errorPercentage: Float! -type InvoiceLineItem { - """ - Line items may be grouped to help the customer better understand their charges - """ - groupKey: String + id: ID! - """ - Line items may be grouped to help the customer better understand their charges - """ - groupValue: String + name: String - name: String! + requestCount: Long! - """ - The quantity of 'things' in this line item. (e.g. number of operations, seats, etc). - May be null for flat charges. - """ - quantity: Int + requestCountPerMin: Float! - """ - The amount this line item costs. - """ - totalInCents: Int! -} + serviceTimeP50Ms: Float! -enum InvoiceState { - COLLECTED + serviceTimeP90Ms: Float! - FAILED + serviceTimeP95Ms: Float! - OPEN + serviceTimeP99Ms: Float! - PAST_DUE + signatureBytes: Long! - UNKNOWN + totalDurationMs: Float! - VOID + type: OperationType } -enum InvoiceStateV2 { - COLLECTED +enum OperationInsightsListOrderByColumn { + CACHE_HIT_RATE - FAILED + CACHE_TTL_P50 - OPEN + ERROR_COUNT - PAST_DUE + ERROR_COUNT_PER_MIN - UNKNOWN + ERROR_PERCENTAGE - VOID -} + OPERATION_NAME -type InvoiceV2 { - closedAt: Timestamp + REQUEST_COUNT - collectionMethod: String + REQUEST_COUNT_PER_MIN - createdAt: Timestamp! + SERVICE_TIME_P50 - id: ID! + SERVICE_TIME_P90 - invoiceNumber: Int! + SERVICE_TIME_P95 - invoiceNumberV2: String! + SERVICE_TIME_P99 - state: InvoiceStateV2! + SIGNATURE_BYTES - totalInCents: Int! + TOTAL_DURATION_MS +} - updatedAt: Timestamp! +input OperationInsightsListOrderByInput { + """ + The order column used for the operation results. Defaults to ordering by operation names. + """ + column: OperationInsightsListOrderByColumn! - uuid: ID! + """ + The direction used to order operation results. Defaults to ascending order. + """ + direction: Ordering! } -scalar JSON - """ -Represents the complete process of making a set of updates to a deployed graph variant. +Information about pagination in a connection. """ -type Launch { +type OperationInsightsListPageInfo { """ - The unique identifier for this launch. + When paginating forwards, the cursor to continue. """ - id: ID! + endCursor: String """ - The ID of the launch's associated graph. + Not implemented. Always returns true """ - graphId: String! + hasNextPage: Boolean! """ - The name of the launch's associated variant. + Not implemented. Always returns true """ - graphVariant: String! - - order: OrderOrError! + hasPreviousPage: Boolean! """ - The timestamp when the launch was approved. + When paginating backwards, the cursor to continue. """ - approvedAt: Timestamp + startCursor: String +} +""" +Operation name filter configuration for a graph. +""" +type OperationNameFilter { """ - The associated build for this launch (a build includes schema composition and contract filtering). This value is null until the build is initiated. + name of the operation by the user and reported alongside metrics """ - build: Build + name: String! + version: String +} + +""" +Options to filter by operation name. +""" +input OperationNameFilterInput { """ - The inputs provided to this launch's associated build, including subgraph schemas and contract filters. + name of the operation set by the user and reported alongside metrics """ - buildInput: BuildInput! + name: String! + + version: String +} +type OperationsCheckConfiguration { """ - The timestamp when the launch completed. This value is null until the launch completes. + During the operations check, ignore clients matching any of the filters. """ - completedAt: Timestamp + excludedClients: [ClientFilter!]! """ - The timestamp when the launch was initiated. + During the operations check, ignore operations matching any of the filters. """ - createdAt: Timestamp! + excludedOperationNames: [OperationNameFilter!]! """ - Contract launches that were triggered by this launch. + During the operations check, ignore operations matching any of the filters. """ - downstreamLaunches: [Launch!]! + excludedOperations: [OperationInfoFilter!]! - isAvailable: Boolean + """ + The start of the time range for the operations check, expressed as an offset from the time the + check request was received (in seconds) or an ISO-8601 timestamp. This was either provided by the + user or computed from variant- or graph-level settings. + """ + from: String! @deprecated(reason: "Use fromNormalized instead") """ - Whether the launch completed. + The start of the time range for the operations check. """ - isCompleted: Boolean + fromNormalized: Timestamp! """ - Whether the result of the launch has been published to the associated graph and variant. This is always false for a failed launch. + During the operations check, fetch operations from the metrics data for + variants. """ - isPublished: Boolean + includedVariants: [String!]! - isTarget: Boolean + """ + During the operations check, ignore operations that executed less than + times in the time range. + """ + operationCountThreshold: Int! """ - The most recent launch sequence step that has started but not necessarily completed. + Duration the operations check, ignore operations that constituted less than + % of the operations in the time range. """ - latestSequenceStep: LaunchSequenceStep + operationCountThresholdPercentage: Float! """ - A specific publication of a graph variant pertaining to this launch. + The end of the time range for the operations check, expressed as an offset from the time the + check request was received (in seconds) or an ISO-8601 timestamp. This was either provided by the + user or computed from variant- or graph-level settings. """ - publication: SchemaTag + to: String! @deprecated(reason: "Use toNormalized instead") """ - A list of results from the completed launch. The items included in this list vary depending on whether the launch succeeded, failed, or was superseded. + The end of the time range for the operations check. """ - results: [LaunchResult!]! + toNormalized: Timestamp! +} +input OperationsCheckConfigurationOverridesInput { """ - Cloud router configuration associated with this build event. It will be non-null for any cloud-router variant, and null for any not cloudy variant/graph. + During the operations check, ignore clients matching any of the filters. + Providing null will use variant- or graph-level settings instead. """ - routerConfig: String + excludedClients: [ClientFilterInput!] - schemaTag: SchemaTag + """ + During the operations check, ignore operations matching any of the + filters. Providing null will use variant- or graph-level settings instead. + """ + excludedOperationNames: [OperationNameFilterInput!] """ - A list of all serial steps in the launch sequence. This list can change as the launch progresses. For example, a `LaunchCompletedStep` is appended after a launch completes. + During the operations check, ignore operations matching any of the filters. + Providing null will use variant- or graph-level settings instead. """ - sequence: [LaunchSequenceStep!]! + excludedOperations: [OperationInfoFilterInput!] """ - A shortened version of `Launch.id` that includes only the first 8 characters. + The start of the time range for the operations check, expressed as an offset from the time the + check request is received (in seconds) or an ISO-8601 timestamp. Providing null here and + useMaxRetention as false will use variant- or graph-level settings instead. It is an error to + provide a non-null value here and useMaxRetention as true. """ - shortenedID: String! + from: String """ - The launch's status. If a launch is superseded, its status remains `LAUNCH_INITIATED`. To check for a superseded launch, use `supersededAt`. + During the operations check, fetch operations from the metrics data for + variants. Providing null will use variant- or graph-level settings instead. """ - status: LaunchStatus! + includedVariants: [String!] """ - A list of subgraph changes that are included in this launch. + During the operations check, ignore operations that executed less than + times in the time range. Providing null will use variant- or graph-level settings instead. """ - subgraphChanges: [SubgraphChange!] + operationCountThreshold: Int """ - The timestamp when this launch was superseded by another launch. If an active launch is superseded, it terminates. + During the operations check, ignore operations that executed less than + times in the time range. Expected values are between 0% and 5%. Providing null will use variant- + or graph-level settings instead. """ - supersededAt: Timestamp + operationCountThresholdPercentage: Float """ - The launch that superseded this launch, if any. If an active launch is superseded, it terminates. + The end of the time range for the operations check, expressed as an offset from the time the + check request is received (in seconds) or an ISO-8601 timestamp. Providing null here and + useMaxRetention as false will use variant- or graph-level settings instead. It is an error to + provide a non-null value here and useMaxRetention as true. """ - supersededBy: Launch + to: String """ - The source variant launch that caused this launch to be initiated. This value is present only for contract variant launches. Otherwise, it's null. + During the operations check, use the maximum time range allowed by the graph's plan's retention. + Providing false here and from/to as null will use variant- or graph-level settings instead. It is + an error to provide true here and from/to as non-null. """ - upstreamLaunch: Launch + useMaxRetention: Boolean! = false } -union LaunchResult = ChangelogLaunchResult +type OperationsCheckResult { + id: ID! -""" -The timing details for the build step of a launch. -""" -type LaunchSequenceBuildStep { """ - The timestamp when the step completed. + The variant that was used as a base to check against """ - completedAt: Timestamp + checkedVariant: GraphVariant! """ - The timestamp when the step started. + Indication of the success of the change, either failure, warning, or notice. """ - startedAt: Timestamp -} + checkSeverity: ChangeSeverity! -""" -The timing details for the checks step of a launch. -""" -type LaunchSequenceCheckStep { """ - The timestamp when the step completed. + Number of operations that were validated during schema diff """ - completedAt: Timestamp + numberOfCheckedOperations: Int! """ - The timestamp when the step started. + List of schema changes with associated affected clients and operations """ - startedAt: Timestamp -} + changes: [Change!]! -""" -The timing details for the completion step of a launch. -""" -type LaunchSequenceCompletedStep { """ - The timestamp when the step (and therefore the launch) completed. + Summary/counts for all changes in diff """ - completedAt: Timestamp -} + changeSummary: ChangeSummary! -""" -The timing details for the initiation step of a launch. -""" -type LaunchSequenceInitiatedStep { """ - The timestamp when the step (and therefore the launch) started. + Operations affected by all changes in diff """ - startedAt: Timestamp -} + affectedQueries: [AffectedQuery!] -""" -The timing details for the publish step of a launch. -""" -type LaunchSequencePublishStep { """ - The timestamp when the step completed. + Number of affected query operations that are neither marked as SAFE or IGNORED """ - completedAt: Timestamp + numberOfAffectedOperations: Int! - """ - The timestamp when the step started. - """ - startedAt: Timestamp -} + workflowTask: OperationsCheckTask! -union LaunchSequenceStep = LaunchSequenceBuildStep|LaunchSequenceCheckStep|LaunchSequenceCompletedStep|LaunchSequenceInitiatedStep|LaunchSequencePublishStep|LaunchSequenceSupersededStep + createdAt: Timestamp! -""" -The timing details for the superseded step of a launch. This step occurs only if the launch is superseded by another launch. -""" -type LaunchSequenceSupersededStep { """ - The timestamp when the step completed, thereby ending the execution of this launch in favor of the superseding launch. + The threshold that was crossed; null if the threshold was not exceeded """ - completedAt: Timestamp + crossedOperationThreshold: Int } -enum LaunchStatus { - LAUNCH_COMPLETED - - LAUNCH_FAILED - - LAUNCH_INITIATED -} +type OperationsCheckTask implements CheckWorkflowTask { + completedAt: Timestamp -type LinkInfo { createdAt: Timestamp! - id: ID! - - title: String + graphID: ID! - type: LinkInfoType! + id: ID! - url: String! -} + status: CheckWorkflowTaskStatus! -enum LinkInfoType { - DEVELOPER_PORTAL + targetURL: String - OTHER + workflow: CheckWorkflow! - REPOSITORY + """ + The result of the operations check. This will be null when the task is initializing or running, + or when the build task fails (which is a prerequisite task to this one). + """ + result: OperationsCheckResult } -enum LogLevel { - WARN +enum OperationType { + MUTATION - INFO + QUERY - ERROR + SUBSCRIPTION +} - DEBUG +type OperationValidationError { + message: String! } -type LogMessage { +""" +Cloud Router order +""" +type Order { """ - Timestamp in UTC + Order identifier """ - timestamp: DateTime! + id: ID! """ - Log message contents + Order type """ - message: String! + orderType: OrderType! """ - Log level + Order status """ - level: LogLevel! -} - -""" -Long type -""" -scalar Long - -type MarkChangesForOperationAsSafeResult { - success: Boolean! - - message: String! + status: OrderStatus! """ - Nice to have for the frontend since the Apollo cache is already watching for AffectedQuery to update. - This might return null if no behavior changes were found for the affected operation ID. - This is a weird situation that should never happen. + Reason for ERRORED or ROLLING_BACK orders """ - affectedOperation: AffectedQuery -} - -type MediaUploadInfo { - csrfToken: String! - - maxContentLength: Int! - - url: String! -} - -type Message { - auditLog: [AuditLog!]! - - channels: [SlackCommunicationChannel!]! - - confirmations: [MessageConfirmation]! - - content: MessageContent! - - createdAt: Timestamp! - - id: ID! - - modifiedAt: Timestamp! - - state: State! - - user: RequesterUser! -} - -type MessageConfirmation { - channel: SlackCommunicationChannel - - createdAt: Timestamp! - - id: ID! - - modifiedAt: Timestamp! + reason: String - slackMessage: SlackMessageMeta! + """ + Completion percentage of the order (between 0 and 100) - state: SlackPublishState! -} + This will only return data for IN_PROGRESS, COMPLETED, or SUPERSEDED states + """ + completionPercentage: Int -type MessageContent { - body: String! + """ + When this Order was created + """ + createdAt: NaiveDateTime! - buttonText: String + """ + Last time this Order was updated + """ + updatedAt: NaiveDateTime - buttonURL: String + logs: [LogMessage!]! - header: String! -} + """ + Router associated with this Order + """ + router: Router! -input MessageInput { - body_text: String! + """ + Shard associated with this Order + """ + shard: Shard! - button_text: String + """ + Checks if machines are ready to serve requests + """ + ready: Boolean! - button_url: String + """ + Checks if the service is updated + """ + serviceReady: Boolean! - channel_id: [ID!]! + """ + Introspect why call to `ready` failed + """ + introspectReady: String! - header_text: String! + """ + Checks if we can serve requests through the external endpoint + """ + readyExternal: Boolean! } -union MessageMutationResult = CustomerSupportSlackError|Message - -type MetricStatWindow { - timestamp: Timestamp! - - value: Long! - - windowSize: BillingUsageStatsWindowSize! +""" +The order does not exist +""" +type OrderDoesNotExistError { + tryAgainSeconds: Int! } -union MoveOperationCollectionEntryResult = InvalidTarget|MoveOperationCollectionEntrySuccess|PermissionError - -type MoveOperationCollectionEntrySuccess { - operation: OperationCollectionEntry! - - originCollection: OperationCollection! - - targetCollection: OperationCollection! +""" +Catch-all failure result of a failed order mutation. +""" +type OrderError { + """ + Error message + """ + message: String! } -type Mutation { - billing: BillingMutation - - cloud: CloudMutation! +enum Ordering { + ASCENDING - account(id: ID!): AccountMutation + DESCENDING +} +type OrderMutation { """ - Finalize a password reset with a token included in the E-mail link, - returns the corresponding login email when successful + Set default environment variables """ - finalizePasswordReset(newPassword: String!, resetToken: String!): String + setDefaultVars: OrderResult! """ - Provides access to mutation fields for modifying a Studio graph with the provided ID. + Create CNAME record """ - graph(id: ID!): ServiceMutation + createCname: OrderResult! """ - Join an account with a token + Delete API key """ - joinAccount(accountId: ID!, joinToken: String!): Account - - me: IdentityMutation - - newAccount(companyUrl: String, id: ID!, organizationName: String): Account + deleteApiKey: OrderResult! - newService(accountId: ID!, description: String, hiddenFromUninvitedNonAdminAccountMembers: Boolean! = false, id: ID!, isDev: Boolean = false @deprecated(reason: "No longer supported"), name: String, onboardingArchitecture: OnboardingArchitecture, title: String): Service + """ + Delete CNAME + """ + deleteCname: OrderResult! """ - Report a running GraphQL server's schema. + Rollback CNAME record """ - reportSchema("Only sent if previously requested i.e. received ReportSchemaResult with withCoreSchema = true. This is a GraphQL schema document as a string. Note that for a GraphQL server with a core schema, this should be the core schema, not the API schema." coreSchema: String, "Information about server and its schema." report: SchemaReport!): ReportSchemaResult + rollbackCname: OrderResult! """ - Ask for a user's password to be reset by E-mail + Rollback router information """ - resetPassword(email: String!): Void + rollbackInfo: OrderResult! - resolveAllInternalCronExecutions(group: String, name: String): Void + """ + Rollback router information + """ + rollbackSecrets: OrderResult! - resolveInternalCronExecution(id: ID!): CronExecution + """ + Update router information + """ + updateInfo: OrderResult! - service(id: ID!): ServiceMutation + """ + Update order status + """ + updateStatus(status: OrderStatus!): OrderResult! """ - Set the subscriptions for a given email + Update order status with a reason and cause """ - setSubscriptions(email: String!, subscriptions: [EmailCategory!]!, token: String!): EmailPreferences + updateStatusWithReason(status: OrderStatus!, reason: String!, cause: ReasonCause!): OrderResult! """ - Set the studio settings for the current user + Force rollback of the order """ - setUserSettings(newSettings: UserSettingsInput): UserSettings + forceRollback: OrderResult! - signUp(email: String!, fullName: String!, password: String!, referrer: String, trackingGoogleClientId: String, trackingMarketoClientId: String, userSegment: UserSegment, utmCampaign: String, utmMedium: String, utmSource: String): User + """ + Create an ALB rule + """ + createAlbRule: OrderResult! """ - This is called by the form shown to users after they delete their user or organization account. + Create an IAM Role """ - submitPostDeletionFeedback(feedback: String!, targetIdentifier: ID!, targetType: DeletionTargetType!): Void + createIamRole: OrderResult! """ - Mutation for basic engagement tracking in studio + Create a security group """ - track(event: EventEnum!, graphID: String!, graphVariant: String! = "current"): Void + createSecurityGroup: OrderResult! """ - Router usage tracking. Reserved to https://router.apollo.dev/telemetry (https://github.com/apollographql/orbiter). + Create an ECS service """ - trackRouterUsage("If we think the router is being run on continuous integration then this will be populated" ci: String, "The OS that the router is running on" os: String!, "A random ID that is generated on first startup of the Router. It is not persistent between restarts of the Router, but will be persistent for hot reloads" sessionId: ID!, "A list of key count pairs that represents the a path into the config\/arguments and the number of times that it occurred" usage: [RouterUsageInput!]!, "The version of the Router" version: String!): Void + createService: OrderResult! """ - Rover session tracking. Reserved to https://rover.apollo.dev/telemetry (https://github.com/apollographql/orbiter). + Create a target group """ - trackRoverSession(anonymousId: ID!, arguments: [RoverArgumentInput!]!, ci: String, command: String!, cwdHash: SHA256!, os: String!, remoteUrlHash: SHA256, sessionId: ID!, version: String!): Void + createTargetGroup: OrderResult! """ - Unsubscribe a given email from all emails + Create a task definition """ - unsubscribeFromAll(email: String!, token: String!): EmailPreferences + createTaskDefinition: OrderResult! """ - Provides access to mutation fields for modifying an Apollo user with the - provided ID. + Delete an ALB rule """ - user(id: ID!): UserMutation + deleteAlbRule: OrderResult! """ - Creates an [operation collection](https://www.apollographql.com/docs/studio/explorer/operation-collections/) for a given variant, or creates a [sandbox collection](https://www.apollographql.com/docs/studio/explorer/operation-collections/#sandbox-collections) without an associated variant. + Delete an IAM Role """ - createOperationCollection("The collection's description." description: String, "Whether the collection is a [sandbox collection](https:\/\/www.apollographql.com\/docs\/studio\/explorer\/operation-collections\/#sandbox-collections)." isSandbox: Boolean!, "Whether the collection is shared across its associated organization." isShared: Boolean!, "The minimum role a user needs to edit this collection. Valid values: null, CONSUMER, OBSERVER, DOCUMENTER, CONTRIBUTOR, GRAPH_ADMIN. This value is ignored if `isShared` is `false`. The default value is `GRAPH_ADMIN`." minEditRole: UserPermission, "The collection's name." name: String!, "The [graph ref](https:\/\/www.apollographql.com\/docs\/rover\/conventions\/#graph-refs) of the graph variants to associate the collection with." variantRefs: [ID!]): CreateOperationCollectionResult! + deleteIamRole: OrderResult! - operationCollection(id: ID!): OperationCollectionMutation + """ + Delete a security group + """ + deleteSecurityGroup: OrderResult! - approveMessage(messageId: ID!, state: State!): MessageMutationResult! + """ + Delete an ECS service + """ + deleteService: OrderResult! - createMessage(message: MessageInput!): MessageMutationResult! + """ + Delete a target group + """ + deleteTargetGroup: OrderResult! - editMessage(messageId: ID!, messageUpdates: MessageInput!): MessageMutationResult! + """ + Delete a task definition + """ + deleteTaskDefinition: OrderResult! - publishSlackMessage(messageId: ID!): MessageMutationResult! + """ + Rollback an ALB rule + """ + rollbackAlbRule: OrderResult! - publishSlackTest(messageId: ID!): MessageMutationResult! + """ + Rollback an IAM Role + """ + rollbackIamRole: OrderResult! - recallMessage(slackChannelId: ID!, slackMessageId: ID!): MessageMutationResult! -} + """ + Rollback a security group + """ + rollbackSecurityGroup: OrderResult! -""" -ISO 8601 combined date and time without timezone. + """ + Rollback an ECS service + """ + rollbackService: OrderResult! -# Examples + """ + Rollback a target group + """ + rollbackTargetGroup: OrderResult! -* `2015-07-01T08:59:60.123`, -""" -scalar NaiveDateTime + """ + Rollback a task definition + """ + rollbackTaskDefinition: OrderResult! -type NamedIntrospectionArg { - name: String + """ + Update an IAM Role + """ + updateIamRole: OrderResult! - description: String -} + """ + Update a Service + """ + updateService: OrderResult! -type NamedIntrospectionArgNoDescription { - name: String -} + """ + Update a task definition + """ + updateTaskDefinition: OrderResult! -""" -The shared fields for a named introspection type. Currently this is returned for the -top level value affected by a change. In the future, we may update this -type to be an interface, which is extended by the more specific types: -scalar, object, input object, union, interface, and enum + """ + Create a new app + """ + createApp: OrderResult! -For an in-depth look at where these types come from, see: -https://github.com/DefinitelyTyped/DefinitelyTyped/blob/659eb50d3/types/graphql/utilities/introspectionQuery.d.ts#L31-L37 -""" -type NamedIntrospectionType { - kind: IntrospectionTypeKind + """ + Update Etcd cluster + """ + updateEtcd: OrderResult! - name: String + """ + Create machines + """ + createMachines: OrderResult! - description: String -} + """ + Delete application + """ + deleteApp: OrderResult! -type NamedIntrospectionTypeNoDescription { - name: String -} + """ + Delete machines + """ + deleteMachines: OrderResult! -""" -Introspection values that can be children of other types for changes, such -as input fields, objects in interfaces, enum values. In the future, this -value could become an interface to allow fields specific to the types -returned. -""" -type NamedIntrospectionValue { - name: String + """ + Rollback application + """ + rollbackApp: OrderResult! - description: String + """ + Rollback machines + """ + rollbackMachines: OrderResult! - printedType: String + """ + Rollback etcd data + """ + rollbackEtcd: OrderResult! } -type NamedIntrospectionValueNoDescription { - name: String +union OrderOrError = Order|OrderDoesNotExistError - printedType: String -} +union OrderResult = Order|InvalidInputErrors|OrderError """ -A non-federated service for a monolithic graph. +Represents the different status for an order """ -type NonFederatedImplementingService { +enum OrderStatus { """ - Timestamp of when this implementing service was created. + New Order in progress """ - createdAt: Timestamp! + PENDING """ - Identifies which graph this non-implementing service belongs to. - Formerly known as "service_id". + Order was successfully completed """ - graphID: String! + COMPLETED """ - Specifies which variant of a graph this implementing service belongs to". - Formerly known as "tag". + Order is currently rolling back + + All resources created as part of this Order are being deleted """ - graphVariant: String! -} + ROLLING_BACK -""" -An error that occurs when a requested object is not found. -""" -type NotFoundError implements Error { """ - The error message. + Order was unsuccessful """ - message: String! -} - -""" -An arbitrary JSON object. -""" -scalar Object - -type OdysseyAttempt { - id: ID! - - testId: String! - - startedAt: Timestamp! - - completedAt: Timestamp + ERRORED - responses: [OdysseyResponse!]! + """ + Order has been superseded by another, more recent order - pass: Boolean + This can happen if two update orders arrive in close succession and we already + started to process the newer order first. + """ + SUPERSEDED } -type OdysseyCertification { - id: ID! - - certificationId: String! - - earnedAt: Timestamp! - - owner: OdysseyCertificationOwner - - source: String -} +""" +Represents the different types of order +""" +enum OrderType { + """ + Create a new Cloud Router + """ + CREATE_ROUTER -type OdysseyCertificationOwner { - id: ID! + """ + Destroy an existing Cloud Router + """ + DESTROY_ROUTER - fullName: String! + """ + Update an existing Cloud Router + """ + UPDATE_ROUTER } -type OdysseyCourse { - id: ID! - - enrolledAt: Timestamp - - completedAt: Timestamp -} +""" +A reusable invite link for an organization. +""" +type OrganizationInviteLink { + createdAt: Timestamp! -input OdysseyCourseInput { - courseId: String! + """ + A joinToken that can be passed to Mutation.joinAccount to join the organization. + """ + joinToken: String! - completedAt: Timestamp + """ + The role that the user will receive if they join the organization with this link. + """ + role: UserPermission! } -type OdysseyResponse { - id: ID! - - questionId: String! +type OrganizationSSO { + defaultRole: UserPermission! - values: [OdysseyValue!]! + idpid: ID! - correct: Boolean + provider: OrganizationSSOProvider! } -input OdysseyResponseCorrectnessInput { - id: ID! - - correct: Boolean! +enum OrganizationSSOProvider { + PINGONE } -input OdysseyResponseInput { - attemptId: ID! +type OrgCustomerTraits { + healthScore: Float - questionId: String! + nextRenewalDate: Int - correct: Boolean + tier: String - values: [String!]! + usersCount: Int } -type OdysseyTask { - id: ID! - - value: String - - completedAt: Timestamp -} +""" +Information about pagination in a connection. +""" +type PageInfo { + """ + When paginating forwards, the cursor to continue. + """ + endCursor: String -input OdysseyTaskInput { - taskId: String! + """ + When paginating forwards, are there more items? + """ + hasNextPage: Boolean! - value: String + """ + When paginating backwards, are there more items? + """ + hasPreviousPage: Boolean! - completedAt: Timestamp + """ + When paginating backwards, the cursor to continue. + """ + startCursor: String } -type OdysseyValue { +""" +PagerDuty notification channel +""" +type PagerDutyChannel implements Channel { id: ID! - value: String! -} + name: String! -enum OnboardingArchitecture { - MONOLITH + routingKey: String! - SUPERGRAPH + subscriptions: [ChannelSubscription!]! } -type Operation { - id: ID! - +""" +PagerDuty notification channel parameters +""" +input PagerDutyChannelInput { name: String - signature: String - - truncated: Boolean! + routingKey: String! } -type OperationAcceptedChange { - id: ID! - - graphID: ID! - - checkID: ID! - - operationID: String! +type ParentChangeProposalComment implements ChangeProposalComment & ProposalComment { + createdAt: Timestamp! - change: StoredApprovedChange! + """ + null if the user is deleted + """ + createdBy: Identity - acceptedAt: Timestamp! + id: ID! - acceptedBy: Identity -} + message: String! -""" -Columns of OperationCheckStats. -""" -enum OperationCheckStatsColumn { - CACHED_REQUESTS_COUNT + """ + true if the schemaCoordinate this comment is on doesn't exist in the diff between the most recent revision & the base sdl + """ + outdated: Boolean! - CLIENT_NAME + replies: [ReplyChangeProposalComment!]! - CLIENT_VERSION + replyCount: Int! - QUERY_ID + schemaCoordinate: String! - QUERY_NAME + """ + '#@!api!@#' for api schema, '#@!supergraph!@#' for supergraph schema, subgraph otherwise + """ + schemaScope: String! - SCHEMA_TAG + status: CommentStatus! - SERVICE_ID + """ + null if never updated + """ + updatedAt: Timestamp +} - TIMESTAMP +type ParentGeneralProposalComment implements GeneralProposalComment & ProposalComment { + createdAt: Timestamp! - UNCACHED_REQUESTS_COUNT -} + """ + null if the user is deleted + """ + createdBy: Identity -type OperationCheckStatsDimensions { - clientName: String + id: ID! - clientVersion: String + message: String! - queryId: ID + replies: [ReplyGeneralProposalComment!]! - queryName: String + replyCount: Int! - schemaTag: String + status: CommentStatus! - serviceId: ID + """ + null if never updated + """ + updatedAt: Timestamp } +union ParentProposalComment = ParentChangeProposalComment|ParentGeneralProposalComment + """ -Filter for data in OperationCheckStats. Fields with dimension names represent equality checks. All fields are implicitly ANDed together. +The schema for a single published subgraph in Studio. """ -input OperationCheckStatsFilter { - and: [OperationCheckStatsFilter!] - +type PartialSchema { """ - Selects rows whose clientName dimension equals the given value if not null. To query for the null value, use {in: {clientName: [null]}} instead. + The subgraph schema document as SDL. """ - clientName: String + sdl: String! """ - Selects rows whose clientVersion dimension equals the given value if not null. To query for the null value, use {in: {clientVersion: [null]}} instead. + Timestamp for when the partial schema was created """ - clientVersion: String + createdAt: Timestamp! - in: OperationCheckStatsFilterIn + """ + If this sdl is currently actively composed in the gateway, this is true + """ + isLive: Boolean! +} - not: OperationCheckStatsFilter +""" +Input for registering a partial schema to an implementing service. +One of the fields must be specified (validated server-side). - or: [OperationCheckStatsFilter!] +If a new partialSchemaSDL is passed in, this operation will store it before +creating the association. +If both the sdl and hash are specified, an error will be thrown if the provided +hash doesn't match our hash of the sdl contents. If the sdl field is specified, +the hash does not need to be and will be computed server-side. +""" +input PartialSchemaInput { """ - Selects rows whose queryId dimension equals the given value if not null. To query for the null value, use {in: {queryId: [null]}} instead. + Hash of the partial schema to associate; error is thrown if only the hash is + specified and the hash has not been seen before """ - queryId: ID + hash: String """ - Selects rows whose queryName dimension equals the given value if not null. To query for the null value, use {in: {queryName: [null]}} instead. + Contents of the partial schema in SDL syntax, but may reference types + that aren't defined in this document """ - queryName: String + sdl: String +} - """ - Selects rows whose schemaTag dimension equals the given value if not null. To query for the null value, use {in: {schemaTag: [null]}} instead. - """ - schemaTag: String +type Permission { + csAdmin: String - """ - Selects rows whose serviceId dimension equals the given value if not null. To query for the null value, use {in: {serviceId: [null]}} instead. - """ - serviceId: ID + sudo: Boolean! } """ -Filter for data in OperationCheckStats. Fields match if the corresponding dimension's value is in the given list. All fields are implicitly ANDed together. +An error that's returned when the current user doesn't have sufficient permissions to perform an action. """ -input OperationCheckStatsFilterIn { +type PermissionError implements Error { """ - Selects rows whose clientName dimension is in the given list. A null value in the list means a row with null for that dimension. + The error message. """ - clientName: [String] + message: String! +} + +""" +Information about the act of publishing operations to the list +""" +type PersistedQueriesPublish { + operationCounts: PersistedQueriesPublishOperationCounts! + + publishedAt: Timestamp! +} +type PersistedQueriesPublishOperationCounts { """ - Selects rows whose clientVersion dimension is in the given list. A null value in the list means a row with null for that dimension. + The number of new operations added to the list by this publish. """ - clientVersion: [String] + added: Int! """ - Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. + The number of operations included in this publish whose metadata and body were unchanged from the previous list revision. """ - queryId: [ID] + identical: Int! """ - Selects rows whose queryName dimension is in the given list. A null value in the list means a row with null for that dimension. + The number of operations removed from the list by this publish. """ - queryName: [String] + removed: Int! """ - Selects rows whose schemaTag dimension is in the given list. A null value in the list means a row with null for that dimension. + The number of operations in this list that were not mentioned by this publish. """ - schemaTag: [String] + unaffected: Int! """ - Selects rows whose serviceId dimension is in the given list. A null value in the list means a row with null for that dimension. + The number of operations whose metadata or body were changed by this publish. """ - serviceId: [ID] + updated: Int! } -type OperationCheckStatsMetrics { - cachedRequestsCount: Long! +type PersistedQuery { + body: GraphQLDocument! - uncachedRequestsCount: Long! -} + firstPublishedAt: Timestamp! -input OperationCheckStatsOrderBySpec { - column: OperationCheckStatsColumn! + id: ID! - direction: Ordering! + lastPublishedAt: Timestamp! + + name: String! + + type: OperationType! } -type OperationCheckStatsRecord { - """ - Dimensions of OperationCheckStats that can be grouped by. - """ - groupBy: OperationCheckStatsDimensions! +type PersistedQueryConnection { + edges: [PersistedQueryEdge!]! - """ - Metrics of OperationCheckStats that can be aggregated over. - """ - metrics: OperationCheckStatsMetrics! + pageInfo: PageInfo! +} - """ - Starting segment timestamp. - """ - timestamp: Timestamp! +type PersistedQueryEdge { + cursor: String! + + node: PersistedQuery! } """ -A list of saved GraphQL operations. +Operations to be published to the Persisted Query List. """ -type OperationCollection { +input PersistedQueryInput { """ - The timestamp when the collection was created. + The GraphQL document for this operation, including all necessary fragment definitions. """ - createdAt: Timestamp! + body: GraphQLDocument! """ - The user or other entity that created the collection. + An opaque identifier for this operation. This should map uniquely to an operation body; editing the body should generally result in a new ID. Apollo's tools generally use the lowercase hex SHA256 of the operation body. """ - createdBy: Identity + id: ID! """ - The collection's description. A `null` description was never set, and empty string description was set to be empty string by a user, or other entity. + A name for the operation. Typically this is the name of the actual GraphQL operation in the body. This does not need to be unique within a Persisted Query List; as a client project evolves and its operations change, multiple operations with the same name (but different body and id) can be published. """ - description: String + name: String! """ - If a user has any of these roles, they will be able to edit this - collection. + The operation's type. """ - editRoles: [UserPermission!] @deprecated(reason: "deprecated in favour of minEditRole") + type: OperationType! +} - id: ID! +""" +TODO +""" +type PersistedQueryList { + builds(after: String, before: String, first: Int, last: Int): PersistedQueryListBuildConnection! - """ - Whether the current user has marked the collection as a favorite. - """ - isFavorite: Boolean! + createdAt: Timestamp! - """ - Whether the collection is a [sandbox collection](https://www.apollographql.com/docs/studio/explorer/operation-collections/#sandbox-collections). - """ - isSandbox: Boolean! + createdBy: User - """ - Whether the collection is shared across its associated organization. - """ - isShared: Boolean! + currentBuild: PersistedQueryListBuild! - """ - The timestamp when the collection was most recently updated. - """ - lastUpdatedAt: Timestamp! + description: String! - """ - The user or other entity that most recently updated the collection. - """ - lastUpdatedBy: Identity + graph: Service! """ - The minimum role a user needs to edit this collection. Valid values: null, CONSUMER, OBSERVER, DOCUMENTER, CONTRIBUTOR, GRAPH_ADMIN. This value is always `null` if `isShared` is `false`. If `null` when `isShared` is `true`, the minimum role is `GRAPH_ADMIN`. + The immutable ID for this Persisted Query List. """ - minEditRole: UserPermission + id: ID! - """ - The collection's name. - """ - name: String! + lastUpdatedAt: Timestamp! """ - Returns the operation in the collection with the specified ID, if any. + All variants linked to this Persisted Query List, if any. """ - operation(id: ID!): OperationCollectionEntryResult + linkedVariants: [GraphVariant!]! """ - A list of the GraphQL operations that belong to the collection. + The list's name; can be changed and does not need to be unique. """ - operations: [OperationCollectionEntry!]! + name: String! - """ - The permissions that the current user has for the collection. - """ - permissions: OperationCollectionPermissions! + operation(id: ID!): PersistedQuery - variants: [GraphVariant!]! + operations(after: String, before: String, first: Int, last: Int): PersistedQueryConnection! } """ -A saved operation entry within an Operation Collection. +Information about a particular revision of the list, as produced by a particular publish. """ -type OperationCollectionEntry { - collection: OperationCollection! - +type PersistedQueryListBuild { """ - The timestamp when the entry was created. + A unique ID for this build revision; primarily useful as a client cache ID. """ - createdAt: Timestamp! + id: String! """ - The user or other entity that created the entry. + The persisted query list that this build built. """ - createdBy: Identity + list: PersistedQueryList! """ - Details of the entry's associated operation, such as its `body` and `variables`. + The chunks that made up this build. We do not commit to keeping the full contents of older revisions indefinitely, so this may be null for suitably old revisions. """ - currentOperationRevision: OperationCollectionEntryState! - - id: ID! + manifestChunks: [PersistedQueryListManifestChunk!] """ - The timestamp when the entry was most recently updated. + Information about the publish operation that created this build. """ - lastUpdatedAt: Timestamp! + publish: PersistedQueriesPublish! """ - The user or other entity that most recently updated the entry. + The revision of this Persisted Query List. Revision 0 is the initial empty list; each publish increments the revision by 1. """ - lastUpdatedBy: Identity + revision: Int! """ - The entry's name. + The total number of operations in the list after this build. Compare to PersistedQueriesPublish.operationCounts. """ - name: String! + totalOperationsInList: Int! +} - """ - The entry's lexicographical ordering index within its containing collection. - """ - orderingIndex: String! +type PersistedQueryListBuildConnection { + edges: [PersistedQueryListBuildEdge!]! + + pageInfo: PageInfo! } -""" -Provides fields for modifying an operation in a collection. -""" -type OperationCollectionEntryMutation { - moveToCollection(collectionId: ID!, lowerOrderingBound: String, upperOrderingBound: String): MoveOperationCollectionEntryResult! +type PersistedQueryListBuildEdge { + cursor: String! - reorderEntry(lowerOrderingBound: String, upperOrderingBound: String): UpdateOperationCollectionResult + node: PersistedQueryListBuild! +} + +type PersistedQueryListManifestChunk { + id: ID! + + json: String! + + list: PersistedQueryList! +} + +type PersistedQueryListMutation { + delete: DeletePersistedQueryListResultOrError! + + id: ID! """ - Updates the name of an operation. + Updates this Persisted Query List by publishing a set of operations and removing other operations. Operations not mentioned remain in the list unchanged. """ - updateName(name: String!): UpdateOperationCollectionEntryResult + publishOperations(allowOverwrittenOperations: Boolean, operations: [PersistedQueryInput!], removeOperations: [ID!]): PublishOperationsResultOrError! + updateMetadata(description: String, name: String): UpdatePersistedQueryListMetadataResultOrError! +} + +""" +An error related to an organization's Apollo Studio plan. +""" +type PlanError { """ - Updates the body, headers, and/or variables of an operation. + The error message. """ - updateValues(operationInput: OperationCollectionEntryStateInput!): UpdateOperationCollectionEntryResult + message: String! } -union OperationCollectionEntryMutationResult = NotFoundError|OperationCollectionEntryMutation|PermissionError - -union OperationCollectionEntryResult = NotFoundError|OperationCollectionEntry - """ -The most recent body, variable and header values of a saved operation entry. +GraphQL representation of an AWS private subgraph """ -type OperationCollectionEntryState { +type PrivateSubgraph { """ - The raw body of the entry's GraphQL operation. + The name of the subgraph, if set """ - body: String! + name: String """ - The timestamp when the entry state was created. + The cloud provider where the subgraph is hosted """ - createdAt: Timestamp! + cloudProvider: CloudProvider! """ - The user or other entity that created this entry state. + The private subgraph's region """ - createdBy: Identity + region: RegionDescription! """ - Headers for the entry's GraphQL operation. + The domain URL of the private subgraph """ - headers: [OperationHeader!] + domainUrl: String! """ - The workflow automation script for this entry's GraphQL operation + The status of the resource share """ - script: String + status: PrivateSubgraphShareStatus! +} +type PrivateSubgraphMutation { """ - Variables for the entry's GraphQL operation, as a JSON string. + Synchronize private subgraphs to your Apollo account """ - variables: String + sync(input: SyncPrivateSubgraphsInput!): [PrivateSubgraph!]! } """ -Fields for creating or modifying an operation collection entry. +The status of an association between a private subgraph and your Apollo account """ -input OperationCollectionEntryStateInput { +enum PrivateSubgraphShareStatus { """ - The operation's query body. + The private subgraph is connected to the Apollo service network """ - body: String! + CONNECTED """ - The operation's headers. + The private subgraph is disconnected to the Apollo service network """ - headers: [OperationHeaderInput!] + DISCONNECTED """ - The operation's workflow script + The private subgraph's connection to the Apollo service network has errored """ - script: String + ERRORED """ - The operation's variables. + The current state of the association is unknown """ - variables: String + UNKNOWN } -""" -Provides fields for modifying an [operation collection](https://www.apollographql.com/docs/studio/explorer/operation-collections/). -""" -type OperationCollectionMutation { - """ - Adds an operation to this collection. - """ - addOperation(name: String!, operationInput: OperationCollectionEntryStateInput!): AddOperationCollectionEntryResult +type PromoteSchemaError { + code: PromoteSchemaErrorCode! - """ - Adds operations to this collection. - """ - addOperations(operations: [AddOperationInput!]!): AddOperationCollectionEntriesResult + message: String! +} - addToVariant(variantRef: ID!): AddOperationCollectionToVariantResult! @deprecated(reason: "Will throw NotImplemented") +enum PromoteSchemaErrorCode { + CANNOT_PROMOTE_SCHEMA_FOR_FEDERATED_GRAPH +} - """ - Deletes this operation collection. This also deletes all of the collection's associated operations. - """ - delete: DeleteOperationCollectionResult +type PromoteSchemaResponse { + code: PromoteSchemaResponseCode! - """ - Deletes an operation from this collection. - """ - deleteOperation(id: ID!): RemoveOperationCollectionEntryResult + tag: SchemaTag! +} - duplicateCollection(description: String, isSandbox: Boolean!, isShared: Boolean!, name: String!, variantRef: ID): DuplicateOperationCollectionResult! +enum PromoteSchemaResponseCode { + PROMOTION_SUCCESS - operation(id: ID!): OperationCollectionEntryMutationResult + NO_CHANGES_DETECTED +} - removeFromVariant(variantRef: ID!): RemoveOperationCollectionFromVariantResult! @deprecated(reason: "Will throw NotImplemented") +union PromoteSchemaResponseOrError = PromoteSchemaResponse|PromoteSchemaError - """ - Updates the minimum role a user needs to be able to modify this collection. - """ - setMinEditRole(editRole: UserPermission): UpdateOperationCollectionResult +type Proposal { + activities(after: String, before: String, first: Int, last: Int): ProposalActivityConnection! """ - Updates this collection's description. + The variant this Proposal is under the hood. """ - updateDescription(description: String): UpdateOperationCollectionResult + backingVariant: GraphVariant! - """ - Updates whether the current user has marked this collection as a favorite. - """ - updateIsFavorite(isFavorite: Boolean!): UpdateOperationCollectionResult + comment(id: ID!): ProposalCommentResult - """ - Updates whether this collection is shared across its associated organization. - """ - updateIsShared(isShared: Boolean!): UpdateOperationCollectionResult + createdAt: Timestamp! """ - Updates this operation collection's name. + null if user is deleted, or if user removed from org + and others in the org no longer have access to this user's info """ - updateName(name: String!): UpdateOperationCollectionResult -} + createdBy: Identity -""" -Whether the current user can perform various actions on the associated collection. -""" -type OperationCollectionPermissions { - """ - Whether the current user can edit operations in the associated collection. - """ - canEditOperations: Boolean! + displayName: String! - """ - Whether the current user can delete or update the associated collection's metadata, such as its name and description. - """ - canManage: Boolean! + id: ID! """ - Whether the current user can read operations in the associated collection. + True if only some of the changes in this proposal are currently published to the implementation variant """ - canReadOperations: Boolean! -} + isPartiallyImplemented: Boolean! -union OperationCollectionResult = NotFoundError|OperationCollection|PermissionError|ValidationError + latestRevision: ProposalRevision! -type OperationDocument { - """ - Operation document body - """ - body: String! + parentComments(filter: CommentFilter): [ParentProposalComment!]! - """ - Operation name - """ - name: String -} + rebaseConflicts: RebaseConflictResult -input OperationDocumentInput { """ - Operation document body + null if user deleted or removed from org """ - body: String! + requestedReviewers: [ProposalRequestedReviewer]! - """ - Operation name - """ - name: String -} + reviews: [ProposalReview!]! -""" -Saved headers on a saved operation. -""" -type OperationHeader { """ - The header's name. + This resolver only returns revisions with checks associated with them. For all revisions, use launchHistory. """ - name: String! + revisionsWithChecks(filter: ProposalRevisionFilterInput, limit: Int, offset: Int): ProposalRevisionsWithChecksResult! """ - The header's value. + The variant this Proposal was cloned/sourced from. """ - value: String! -} + sourceVariant: GraphVariant! -input OperationHeaderInput { - """ - The header's name. - """ - name: String! + status: ProposalStatus! + + updatedAt: Timestamp! - """ - The header's value. - """ - value: String! + updatedBy: Identity } -type OperationInfoFilter { - id: String! -} +type ProposalActivity { + activity: ProposalActivityAction -input OperationInfoFilterInput { - id: String! -} + createdAt: Timestamp! -""" -Operation name filter configuration for a graph. -""" -type OperationNameFilter { - """ - name of the operation by the user and reported alongside metrics - """ - name: String! + createdBy: Identity - version: String + id: ID! + + target: ProposalActivityTarget } -""" -Options to filter by operation name. -""" -input OperationNameFilterInput { +enum ProposalActivityAction { """ - name of the operation set by the user and reported alongside metrics + When the system changes a Proposal's status back to OPEN from APPROVED when approvals drop below min approvals. """ - name: String! - - version: String -} + APPROVAL_WITHDRAWN -type OperationsCheckConfiguration { """ - During the operations check, ignore clients matching any of the filters. + When a user manually sets a Proposal to Close """ - excludedClients: [ClientFilter!]! + CLOSE_PROPOSAL """ - During the operations check, ignore operations matching any of the filters. + When a Comment is added to a Proposal. """ - excludedOperationNames: [OperationNameFilter!]! + COMMENT_ADDED """ - During the operations check, ignore operations matching any of the filters. + When a subgraph in a Proposal is deleted. """ - excludedOperations: [OperationInfoFilter!]! + DELETE_SUBGRAPH """ - The start of the time range for the operations check, expressed as an offset from the time the - check request was received (in seconds) or an ISO-8601 timestamp. This was either provided by the - user or computed from variant- or graph-level settings. + When a diff in a Proposal publish is found to already be in the Implementation target variant that fully implements the Proposal. Status of the Proposal will change to IMPLEMENTED. """ - from: String! @deprecated(reason: "Use fromNormalized instead") + FULLY_IMPLEMENTED_PROPOSAL_ORIGIN """ - The start of the time range for the operations check. + When a diff in an Implementation variant publish is found in a Proposal that fully implements the Proposal. Status of the Proposal will change to IMPLEMENTED. """ - fromNormalized: Timestamp! + FULLY_IMPLEMENTED_VARIANT_ORIGIN """ - During the operations check, fetch operations from the metrics data for - variants. + When the system changes a Proposal's status to APPROVED when the min approvals have been met. """ - includedVariants: [String!]! + MET_MIN_APPROVALS_PROPOSAL """ - During the operations check, ignore operations that executed less than - times in the time range. + When a user manually sets a Proposal to Open """ - operationCountThreshold: Int! + OPEN_PROPOSAL """ - Duration the operations check, ignore operations that constituted less than - % of the operations in the time range. + When a diff in a Proposal publish is found to already be in the Implementation target variant that partially implements the Proposal. Does not change the status of the Proposal, but isPartiallyImplemented will return true. """ - operationCountThresholdPercentage: Float! + PARTIALLY_IMPLEMENTED_PROPOSAL_ORIGIN """ - The end of the time range for the operations check, expressed as an offset from the time the - check request was received (in seconds) or an ISO-8601 timestamp. This was either provided by the - user or computed from variant- or graph-level settings. + When a diff in an Implementation variant publish is found in a Proposal that partially implements the Proposal. Does not change the status of the Proposal, but isPartiallyImplemented will return true. """ - to: String! @deprecated(reason: "Use toNormalized instead") + PARTIALLY_IMPLEMENTED_VARIANT_ORIGIN """ - The end of the time range for the operations check. + When a new revision is published to subgraphs in a Proposal. """ - toNormalized: Timestamp! -} + PUBLISH_SUBGRAPHS -input OperationsCheckConfigurationOverridesInput { """ - During the operations check, ignore clients matching any of the filters. - Providing null will use variant- or graph-level settings instead. + When a Proposal is moved to DRAFT from another status not on creation. """ - excludedClients: [ClientFilterInput!] + RETURN_TO_DRAFT_PROPOSAL """ - During the operations check, ignore operations matching any of the - filters. Providing null will use variant- or graph-level settings instead. + When a Review is added to a Proposal. """ - excludedOperationNames: [OperationNameFilterInput!] + REVIEW_ADDED +} + +type ProposalActivityConnection { + edges: [ProposalActivityEdge!] + + nodes: [ProposalActivity!]! + pageInfo: PageInfo! + + totalCount: Int! +} + +type ProposalActivityEdge { """ - During the operations check, ignore operations matching any of the filters. - Providing null will use variant- or graph-level settings instead. + A cursor for use in pagination. """ - excludedOperations: [OperationInfoFilterInput!] + cursor: String! + + node: ProposalActivity +} + +union ProposalActivityTarget = ParentChangeProposalComment|ParentGeneralProposalComment|Proposal|ProposalFullImplementationProposalOrigin|ProposalFullImplementationVariantOrigin|ProposalPartialImplementationProposalOrigin|ProposalPartialImplementationVariantOrigin|ProposalReview|ProposalRevision + +enum ProposalChangeMismatchSeverity { + ERROR + + OFF + + WARN +} + +interface ProposalComment { + createdAt: Timestamp! """ - The start of the time range for the operations check, expressed as an offset from the time the - check request is received (in seconds) or an ISO-8601 timestamp. Providing null here and - useMaxRetention as false will use variant- or graph-level settings instead. It is an error to - provide a non-null value here and useMaxRetention as true. + null if the user is deleted """ - from: String + createdBy: Identity + + id: ID! + + message: String! + + status: CommentStatus! """ - During the operations check, fetch operations from the metrics data for - variants. Providing null will use variant- or graph-level settings instead. + null if never updated """ - includedVariants: [String!] + updatedAt: Timestamp +} + +union ProposalCommentResult = NotFoundError|ParentChangeProposalComment|ParentGeneralProposalComment|ReplyChangeProposalComment|ReplyGeneralProposalComment +type ProposalFullImplementationProposalOrigin implements ProposalImplementation { """ - During the operations check, ignore operations that executed less than - times in the time range. Providing null will use variant- or graph-level settings instead. + the time this Proposal became implemented in the implementation target variant. """ - operationCountThreshold: Int + createdAt: Timestamp! + + id: ID! """ - During the operations check, ignore operations that executed less than - times in the time range. Expected values are between 0% and 5%. Providing null will use variant- - or graph-level settings instead. + the diff that was matched between the Proposal and the implementation target variant. TODO to deserialize this back into a DiffItem NEBULA-2726 """ - operationCountThresholdPercentage: Float + jsonDiff: [String!]! """ - The end of the time range for the operations check, expressed as an offset from the time the - check request is received (in seconds) or an ISO-8601 timestamp. Providing null here and - useMaxRetention as false will use variant- or graph-level settings instead. It is an error to - provide a non-null value here and useMaxRetention as true. + Revision containing a diff that fully implements this Proposal in the implementation target variant. """ - to: String + revision: ProposalRevision! """ - During the operations check, use the maximum time range allowed by the graph's plan's retention. - Providing false here and from/to as null will use variant- or graph-level settings instead. It is - an error to provide true here and from/to as non-null. + the target variant this Proposal became implemented in. """ - useMaxRetention: Boolean! = false + variant: GraphVariant! } -type OperationsCheckResult { +type ProposalFullImplementationVariantOrigin implements ProposalImplementation { + """ + the time this Proposal became implemented in the implementation target variant. + """ + createdAt: Timestamp! + id: ID! """ - The variant that was used as a base to check against + the diff that was matched between the Proposal and the implementation target variant. TODO to deserialize this back into a DiffItem NEBULA-2726 """ - checkedVariant: GraphVariant! + jsonDiff: [String!]! """ - Indication of the success of the change, either failure, warning, or notice. + launch containing a diff that fully implements this Proposal in the implementation target variant. null if user does not have access to launches """ - checkSeverity: ChangeSeverity! + launch: Launch """ - Number of operations that were validated during schema diff + the target variant this Proposal became implemented in. """ - numberOfCheckedOperations: Int! + variant: GraphVariant! +} +interface ProposalImplementation { """ - List of schema changes with associated affected clients and operations + the time this Proposal became implemented in the implementation target variant. """ - changes: [Change!]! + createdAt: Timestamp! + + id: ID! """ - Summary/counts for all changes in diff + the diff that was matched between the Proposal and the implementation target variant """ - changeSummary: ChangeSummary! + jsonDiff: [String!]! """ - Operations affected by all changes in diff + the target variant this Proposal became implemented in. """ - affectedQueries: [AffectedQuery!] + variant: GraphVariant! +} + +type ProposalMutation { + addComment(input: AddCommentInput!): AddCommentResult! + + deleteComment(input: DeleteCommentInput!): DeleteCommentResult! """ - Number of affected query operations that are neither marked as SAFE or IGNORED + Delete a subgraph from this proposal. This will write the summary to proposals, record the most up to date diff, and call registry's removeImplementingServiceAndTriggerComposition. If composition is successful, this will update running routers. """ - numberOfAffectedOperations: Int! + deleteSubgraph(input: DeleteProposalSubgraphInput!): DeleteProposalSubgraphResult! - workflowTask: OperationsCheckTask! + editComment(input: EditCommentInput!): EditCommentResult! - createdAt: Timestamp! + proposal: Proposal """ - The threshold that was crossed; null if the threshold was not exceeded + Publish multiple subgraphs. This will write the summary to proposals, record the most up to date diff, and call registry's publishSubgraphs. If composition is successful, this will update running routers. A single launch will be created for this publish. """ - crossedOperationThreshold: Int -} + publishSubgraphs(input: PublishProposalSubgraphsInput!): PublishProposalSubgraphResult! -type OperationsCheckTask implements CheckWorkflowTask { - completedAt: Timestamp + setRequestedReviewers(input: SetRequestedReviewersInput): SetRequestedReviewersResult! @deprecated(reason: "use updateRequestedReviewers instead") - createdAt: Timestamp! + updateDisplayName(displayName: String!): UpdateProposalResult! - graphID: ID! + updateRequestedReviewers(input: UpdateRequestedReviewersInput!): UpdateRequestedReviewersResult! - id: ID! + updateStatus(status: ProposalStatus!): UpdateProposalResult! - status: CheckWorkflowTaskStatus! + updateUpdatedByInfo(timestamp: Timestamp!): UpdateProposalResult! - targetURL: String + upsertReview(input: UpsertReviewInput!): UpsertReviewResult! +} - workflow: CheckWorkflow! +union ProposalMutationResult = NotFoundError|PermissionError|ProposalMutation|ValidationError +type ProposalPartialImplementationProposalOrigin implements ProposalImplementation { """ - The result of the operations check. This will be null when the task is initializing or running, - or when the build task fails (which is a prerequisite task to this one). + the time this Proposal became partially implemented in the implementation target variant. """ - result: OperationsCheckResult -} - -type OperationValidationError { - message: String! -} + createdAt: Timestamp! -type Order { id: ID! - orderType: OrderType! + """ + the diff that was matched between the Proposal and the implementation target variant. TODO to deserialize this back into a DiffItem NEBULA-2726 + """ + jsonDiff: [String!]! - status: OrderStatus! + """ + Revision containing a diff that partially implements this Proposal in the implementation target variant. + """ + revision: ProposalRevision! - reason: String + """ + the target variant this Proposal became partially implemented in. + """ + variant: GraphVariant! +} - logs(first: Int, offset: Int): [LogMessage!]! +type ProposalPartialImplementationVariantOrigin implements ProposalImplementation { + """ + the time this Proposal became partially implemented in the implementation target variant. + """ + createdAt: Timestamp! - router: Router! + id: ID! """ - Checks if machines are ready to serve requests + the diff that was matched between the Proposal and the implementation target variant. TODO to deserialize this back into a DiffItem NEBULA-2726 """ - ready: Boolean! + jsonDiff: [String!]! """ - Introspect why call to `ready` failed + launch containing a diff that partially implements this Proposal in the implementation target variant. null if user does not have access to launches """ - introspectReady: String! + launch: Launch """ - Checks if we can serve requests through the external endpoint + the target variant this Proposal became partially implemented in. """ - readyExternal: Boolean! + variant: GraphVariant! } -type OrderDoesNotExistError { - tryAgainSeconds: Int! -} +type ProposalRequestedReviewer { + currentReview: ProposalReview -""" -Catch-all failure result of a failed destroyRouter mutation. -""" -type OrderError { - message: String! + user: Identity } -enum Ordering { - ASCENDING +type ProposalReview { + comment: ReviewProposalComment - DESCENDING -} + createdAt: Timestamp! -type OrderMutation { - createApp: OrderResult! + createdBy: Identity - setDefaultVars: OrderResult! + decision: ReviewDecision! - createCname: OrderResult! + isDismissed: Boolean! - updateEtcd: OrderResult! + updatedAt: Timestamp - createMachines: OrderResult! + updatedBy: Identity +} - deleteApp: OrderResult! +type ProposalRevision { + checkWorkflows: [CheckWorkflow!]! - deleteApiKey: OrderResult! + createdBy: Identity - deleteCname: OrderResult! + id: ID! - deleteMachines: OrderResult! + launch: Launch - rollbackApp: OrderResult! + """ + null if this is the first revision + """ + previousRevision: ProposalRevision - rollbackCname: OrderResult! + summary: String! +} - rollbackInfo: OrderResult! +input ProposalRevisionFilterInput { + authors: [String!] + + status: CheckFilterInputStatusOption + + subgraphs: [String!] +} + +""" +Proposal variants, limited & offset based on Service.proposalVariants & the total count +""" +type ProposalRevisionsWithChecksResult { + revisions: [ProposalRevision!]! + + """ + The total number of proposal revisions with checks matching filters. + """ + totalCount: Int! +} - rollbackMachines: OrderResult! +type ProposalRoles { + create: UserPermission! - rollbackEtcd: OrderResult! + edit: UserPermission! +} - updateInfo: OrderResult! +type ProposalsCheckTask implements CheckWorkflowTask { + completedAt: Timestamp - updateStatus(status: OrderStatus!): OrderResult! + createdAt: Timestamp! - updateStatusWithReason(status: OrderStatus!, reason: String!, cause: ReasonCause!): OrderResult! + graphID: ID! - forceRollback: OrderResult! -} + id: ID! -union OrderOrError = Order|OrderDoesNotExistError + status: CheckWorkflowTaskStatus! -union OrderResult = Order|InvalidInputErrors|OrderError + targetURL: String -enum OrderStatus { - PENDING + workflow: CheckWorkflow! - COMPLETED + """ + The results of this proposal check were overridden + """ + didOverrideProposalsCheckTask: Boolean! - ROLLING_BACK + """ + Proposals with their state at the time the check was run associated to this check task. + """ + relatedProposalResults: [RelatedProposalResult!]! - ERRORED + relatedProposals: [Proposal!]! @deprecated(reason: "use relatedProposalResults instead") - SUPERSEDED + """ + The configured severity at the time the check was run. If the check failed, this is the severity that should be shown. + """ + severityLevel: ProposalChangeMismatchSeverity! } -enum OrderType { - CREATE_ROUTER +enum ProposalStatus { + APPROVED - DESTROY_ROUTER + CLOSED - UPDATE_ROUTER + DRAFT + + IMPLEMENTED + + OPEN +} + +type ProposalVariantCreationErrors { + """ + A list of all errors that occurred when attempting to create a proposal variant. + """ + errorMessages: [String!]! } +union ProposalVariantCreationResult = GraphVariant|ProposalVariantCreationErrors + """ -A reusable invite link for an organization. +Filtering options for graph connections. """ -type OrganizationInviteLink { - createdAt: Timestamp! - +input ProposalVariantsFilter { """ - A joinToken that can be passed to Mutation.joinAccount to join the organization. + Only include proposals of a certain status """ - joinToken: String! + status: [ProposalStatus!] """ - The role that the user will receive if they join the organization with this link. + Only include proposals that have updated these subgraph names """ - role: UserPermission! + subgraphs: [String!] } -type OrganizationSSO { - defaultRole: UserPermission! - - idpid: ID! +""" +Proposal variants, limited & offset based on Service.proposalVariants & the total count +""" +type ProposalVariantsResult { + """ + The total number of proposal variants on this graph + """ + totalCount: Int! - provider: OrganizationSSOProvider! + variants: [GraphVariant!]! } -enum OrganizationSSOProvider { - PINGONE -} +union ProposedBuildInputChanges = ProposedCompositionBuildInputChanges|ProposedFilterBuildInputChanges -type OrgCustomerTraits { - healthScore: Float +type ProposedCompositionBuildInputChanges { + """ + The proposed new build pipeline track, or null if no such change was proposed. + """ + buildPipelineTrackChange: BuildPipelineTrack - nextRenewalDate: Int + """ + Any proposed upserts to subgraphs, or the empty list if no such changes were proposed. + """ + subgraphUpserts: [ProposedCompositionBuildInputSubgraphUpsert!]! +} - tier: String +type ProposedCompositionBuildInputSubgraphUpsert { + """ + The name of the subgraph changed in this subgraph upsert. + """ + name: String! - usersCount: Int + """ + The SHA-256 of the schema document in this subgraph upsert. + """ + schemaHash: SHA256 } -""" -Information about pagination in a connection. -""" -type PageInfo { +type ProposedFilterBuildInputChanges { """ - When paginating forwards, the cursor to continue. + The proposed new build pipeline track, or null if no such change was proposed. """ - endCursor: String + buildPipelineTrackChange: BuildPipelineTrack """ - When paginating forwards, are there more items? + Any proposed additions to exclude filters, or the empty list if no such changes were proposed. """ - hasNextPage: Boolean! + excludeAdditions: [String!]! """ - When paginating backwards, are there more items? + Any proposed removals to exclude filters, or the empty list if no such changes were proposed. """ - hasPreviousPage: Boolean! + excludeRemovals: [String!]! """ - When paginating backwards, the cursor to continue. + The proposed value for whether to hide unreachable schema elements, or null if no such change was proposed. """ - startCursor: String -} - -""" -PagerDuty notification channel -""" -type PagerDutyChannel implements Channel { - id: ID! + hideUnreachableTypesChange: Boolean - name: String! + """ + Any proposed additions to include filters, or the empty list if no such changes were proposed. + """ + includeAdditions: [String!]! - routingKey: String! + """ + Any proposed removals to include filters, or the empty list if no such changes were proposed. + """ + includeRemovals: [String!]! - subscriptions: [ChannelSubscription!]! + """ + The proposed new build pipeline track, or null if no such change was proposed. + """ + supergraphSchemaHashChange: SHA256 } -""" -PagerDuty notification channel parameters -""" -input PagerDutyChannelInput { - name: String +type Protobuf { + json: String! - routingKey: String! + object: Object! + + raw: Blob! + + text: String! } """ -The schema for a single published subgraph in Studio. +The result of a successful call to PersistedQueryListMutation.publishOperations. """ -type PartialSchema { +type PublishOperationsResult { """ - The subgraph schema document as SDL. + The build created by this publish operation. """ - sdl: String! + build: PersistedQueryListBuild! """ - Timestamp for when the partial schema was created + Returns `true` if no changes were made by this publish (and no new revision was created). Otherwise, returns `false`. """ - createdAt: Timestamp! + unchanged: Boolean! +} - """ - If this sdl is currently actively composed in the gateway, this is true - """ - isLive: Boolean! +union PublishOperationsResultOrError = CannotModifyOperationBodyError|PermissionError|PublishOperationsResult + +union PublishProposalSubgraphResult = NotFoundError|PermissionError|Proposal|ValidationError + +input PublishProposalSubgraphsInput { + gitContext: GitContextInput + + previousLaunchId: ID! + + revision: String! + + subgraphInputs: [PublishSubgraphsSubgraphInput!]! + + summary: String! } -""" -Input for registering a partial schema to an implementing service. -One of the fields must be specified (validated server-side). +input PublishSubgraphsSubgraphInput { + activePartialSchema: PartialSchemaInput! -If a new partialSchemaSDL is passed in, this operation will store it before -creating the association. + name: String! -If both the sdl and hash are specified, an error will be thrown if the provided -hash doesn't match our hash of the sdl contents. If the sdl field is specified, -the hash does not need to be and will be computed server-side. -""" -input PartialSchemaInput { + url: String +} + +input PushMarketoLeadInput { """ - Contents of the partial schema in SDL syntax, but may reference types - that aren't defined in this document + Email address """ - sdl: String + email: String """ - Hash of the partial schema to associate; error is thrown if only the hash is - specified and the hash has not been seen before + First name """ - hash: String -} + firstName: String -type Permission { - csAdmin: String + """ + Last name + """ + lastName: String - sudo: Boolean! -} + """ + Phone number + """ + phone: String -""" -An error that occurs when the current user doesn't have sufficient permissions to perform an action. -""" -type PermissionError implements Error { """ - The error message. + Company name """ - message: String! -} + company: String -""" -An error related to an organization's Apollo Studio plan. -""" -type PlanError { """ - The error message. + Company domain """ - message: String! -} + Company_Domain__c: String -type PromoteSchemaError { - code: PromoteSchemaErrorCode! + """ + Job Function + """ + Job_Function__c: String - message: String! -} + """ + GraphQL Production Stage + """ + GraphQL_Production_Stage__c: String -enum PromoteSchemaErrorCode { - CANNOT_PROMOTE_SCHEMA_FOR_FEDERATED_GRAPH -} + """ + Country + """ + country: String -type PromoteSchemaResponse { - code: PromoteSchemaResponseCode! + """ + Lead Message + """ + Lead_Message__c: String - tag: SchemaTag! -} + """ + Clearbit enriched LinkedIn URL + """ + Clearbit_LinkedIn_URL__c: String -enum PromoteSchemaResponseCode { - PROMOTION_SUCCESS + """ + Lead Source Detail + """ + Lead_Source_Detail__c: String - NO_CHANGES_DETECTED -} + """ + Lead Source Most Recent Detail + """ + Lead_Source_Most_Recent_Detail__c: String -union PromoteSchemaResponseOrError = PromoteSchemaResponse|PromoteSchemaError + """ + Lead Source Most Recent + """ + Lead_Source_Most_Recent__c: String -union ProposedBuildInputChanges = ProposedCompositionBuildInputChanges|ProposedFilterBuildInputChanges + """ + Studio User Id + """ + Studio_User_Id__c: String -type ProposedCompositionBuildInputChanges { """ - The proposed new build pipeline track, or null if no such change was proposed. + UTM Medium """ - buildPipelineTrackChange: BuildPipelineTrack + UTM_Medium__c: String """ - Any proposed upserts to subgraphs, or the empty list if no such changes were proposed. + UTM Source """ - subgraphUpserts: [ProposedCompositionBuildInputSubgraphUpsert!]! -} + UTM_Source__c: String -type ProposedCompositionBuildInputSubgraphUpsert { """ - The name of the subgraph changed in this subgraph upsert. + UTM Campaign """ - name: String! + UTM_Campaign__c: String """ - The SHA-256 of the schema document in this subgraph upsert. + UTM Term """ - schemaHash: SHA256 -} + UTM_Term__c: String -type ProposedFilterBuildInputChanges { """ - The proposed new build pipeline track, or null if no such change was proposed. + UTM ICID """ - buildPipelineTrackChange: BuildPipelineTrack + UTM_ICID__c: String """ - Any proposed additions to exclude filters, or the empty list if no such changes were proposed. + Referrer """ - excludeAdditions: [String!]! + Referrer__c: String """ - Any proposed removals to exclude filters, or the empty list if no such changes were proposed. + UTM Campaign First Touch """ - excludeRemovals: [String!]! + UTM_Campaign_First_Touch__c: String """ - The proposed value for whether to hide unreachable schema elements, or null if no such change was proposed. + UTM Medium First Touch """ - hideUnreachableTypesChange: Boolean + UTM_Medium_First_Touch__c: String """ - Any proposed additions to include filters, or the empty list if no such changes were proposed. + UTM Source First Touch """ - includeAdditions: [String!]! + UTM_Source_First_Touch__c: String """ - Any proposed removals to include filters, or the empty list if no such changes were proposed. + GA Client ID """ - includeRemovals: [String!]! + Google_User_ID__c: String """ - The proposed new build pipeline track, or null if no such change was proposed. + GDPR Explicit Opt in """ - supergraphSchemaHashChange: SHA256 + Explicit_Opt_in__c: Boolean } -type Protobuf { - json: String! - - object: Object! - - raw: Blob! +""" +Queries defined by this subgraph +""" +type Query { + """ + All available billing plan capabilities + """ + allBillingCapabilities: [BillingCapability!]! - text: String! -} + """ + All available billing plan limits + """ + allBillingLimits: [BillingLimit!]! -type Query { """ All available plans """ @@ -9695,6 +13336,13 @@ type Query { billingAdmin: BillingAdminQuery + """ + Retrieves all past and current subscriptions for an account, even if the account has been deleted + """ + billingSubscriptionHistory(id: ID): [BillingSubscription]! + + billingTier(tier: BillingPlanTier!): BillingTier + """ Escaped JSON string of the public key used for verifying entitlement JWTs """ @@ -9706,10 +13354,8 @@ type Query { plan(id: ID): BillingPlan """ - The plan started by AccountMutation.startTeamSubscription + Cloud queries """ - teamPlan(billingPeriod: BillingPeriod!): BillingPlan! - cloud: Cloud! """ @@ -9717,6 +13363,28 @@ type Query { """ account(id: ID!): Account + """ + All auto-renewing team accounts on active annual plans + """ + allRenewingNonEnterpriseAnnualAccounts: [Account!] + + identitySubgraphStatus: String! + + """ + Returns details of the authenticated `User` or `Graph` executing this query. If this is an unauthenticated query (i.e., no API key is provided), this field returns null. + """ + me: Identity + + """ + Returns details of the Studio organization with the provided ID. + """ + organization(id: ID!): Account + + """ + Search all accounts + """ + searchAccounts(search: String): [Account!]! + """ Retrieve account by billing provider identifier """ @@ -9744,11 +13412,6 @@ type Query { allPublicVariants: [GraphVariant!] - """ - All auto-renewing team accounts on active annual plans - """ - allRenewingNonEnterpriseAnnualAccounts: [Account!] - """ All services """ @@ -9774,6 +13437,11 @@ type Query { """ emailPreferences(email: String!, token: String!): EmailPreferences + """ + Past and current enterprise trial accounts + """ + enterpriseTrialAccounts: [Account!] + """ Returns the root URL of the Apollo Studio frontend. """ @@ -9790,16 +13458,6 @@ type Query { internalUnresolvedCronExecutionFailures: [CronExecution!]! - """ - Returns details of the authenticated `User` or `Graph` executing this query. If this is an unauthenticated query (i.e., no API key is provided), this field returns null. - """ - me: Identity - - """ - Returns details of the Studio organization with the provided ID. - """ - organization(id: ID!): Account - """ A list of public variants that have been selected to be shown on our Graph Directory. """ @@ -9849,6 +13507,8 @@ type Query { operationCollectionEntries(collectionEntryIds: [ID!]!): [OperationCollectionEntry!]! + proposal(id: ID!): Proposal + diffSchemas(baseSchema: String!, nextSchema: String!): [Change!]! """ @@ -9875,6 +13535,8 @@ type Query { getRecallLog(messageId: ID!): [AuditLog]! myPermissions: Permission! + + zendeskUploadToken: String! } """ @@ -9912,6 +13574,10 @@ enum QueryStatsColumn { FROM_ENGINEPROXY + OPERATION_SUBTYPE + + OPERATION_TYPE + QUERY_ID QUERY_NAME @@ -9942,12 +13608,18 @@ type QueryStatsDimensions { fromEngineproxy: String + operationSubtype: String + + operationType: String + queryId: ID queryName: String querySignature: String + querySignatureLength: Int + schemaHash: String schemaTag: String @@ -9985,6 +13657,16 @@ input QueryStatsFilter { not: QueryStatsFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [QueryStatsFilter!] """ @@ -10037,6 +13719,16 @@ input QueryStatsFilterIn { """ fromEngineproxy: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -10265,22 +13957,79 @@ type Readme { Responsibility for an errored order """ enum ReasonCause { + """ + Could not complete an order due to invalid User input + + For example, the user provided an invalid router configuration or supergraph schema. + """ USER + """ + Could not complete an order due to internal reason + + This could be due to intermittent issues, bug in our code, etc. + """ INTERNAL } -""" -Region where a Cloud Router is deployed -""" -enum Region { - AMERICA +type RebaseConflictError { + errorMessages: [String!]! } +union RebaseConflictResult = RebaseConflictError|SchemaValidationError + +""" +Description for a Cloud Router region +""" type RegionDescription { + """ + Full name of the region + """ name: String! - code: Region! + """ + Region identifier + """ + code: String! + + """ + Cloud Provider related to this region + """ + provider: CloudProvider! + + """ + State of the Region + """ + state: RegionState! + + """ + Country of the region, in ISO 3166-1 alpha-2 code + """ + country: String! +} + +""" +Possible state of a region +""" +enum RegionState { + """ + Active region + + Can be used for Cloud Routers + """ + ACTIVE + + """ + Inactive region + + Cannot yet be used for Cloud Routers + """ + INACTIVE + + """ + Does not appear in the API + """ + HIDDEN } input RegisteredClientIdentityInput { @@ -10342,6 +14091,26 @@ type RegistrySubscription implements ChannelSubscription { variant: String } +""" +A Proposal related to a Proposal Check Task. +""" +type RelatedProposalResult { + """ + The latest revision at the time the check was run, defaults to current revision if nothing found for time of the check. + """ + latestRevisionAtCheck: ProposalRevision! + + """ + The Proposal related to the check. State may have changed since the Check was run. + """ + proposal: Proposal! + + """ + The status of the Proposal at the time the check was run, defaults to current state if nothing found for time of the check. + """ + statusAtCheck: ProposalStatus! +} + type RelaunchComplete { latestLaunch: Launch! @@ -10360,6 +14129,58 @@ union RemoveOperationCollectionFromVariantResult = GraphVariant|NotFoundError|Pe union ReorderOperationCollectionResult = OperationCollection|PermissionError +type ReplyChangeProposalComment implements ChangeProposalComment & ProposalComment { + createdAt: Timestamp! + + """ + null if the user is deleted + """ + createdBy: Identity + + id: ID! + + message: String! + + """ + true if the schemaCoordinate this comment is on doesn't exist in the diff between the most recent revision & the base sdl + """ + outdated: Boolean! + + schemaCoordinate: String! + + """ + '#@!api!@#' for api schema, '#@!supergraph!@#' for supergraph schema, subgraph otherwise + """ + schemaScope: String! + + status: CommentStatus! + + """ + null if never updated + """ + updatedAt: Timestamp +} + +type ReplyGeneralProposalComment implements GeneralProposalComment & ProposalComment { + createdAt: Timestamp! + + """ + null if the user is deleted + """ + createdBy: Identity + + id: ID! + + message: String! + + status: CommentStatus! + + """ + null if never updated + """ + updatedAt: Timestamp +} + type ReportSchemaError implements ReportSchemaResult { code: ReportSchemaErrorCode! @@ -10488,6 +14309,32 @@ enum ResponseHints { TRACE_TIMINGS } +enum ReviewDecision { + APPROVED + + NOT_APPROVED +} + +type ReviewProposalComment implements ProposalComment { + createdAt: Timestamp! + + """ + null if the user is deleted + """ + createdBy: Identity + + id: ID! + + message: String! + + status: CommentStatus! + + """ + null if never updated + """ + updatedAt: Timestamp +} + type RoleOverride { graph: Service! @@ -10542,16 +14389,82 @@ type Router { Return the list of secrets for this Cloud Router with their hash values """ secrets: [Secret!]! + + """ + Shard associated with this Cloud Router + """ + shard: Shard + + """ + Order currently modifying this Cloud Router + """ + currentOrder: Order + + """ + Number of Graph Compute Units (GCUs) associated with this Cloud Router + + This value is not present for Cloud Routers on the `SERVERLESS` tier. + """ + gcus: Int } +""" +Router configuration input +""" input RouterConfigInput { + """ + URL for the Cloud Router + """ routerUrl: String + """ + Router version for the Cloud Router + """ routerVersion: String + """ + Configuration for the Cloud Router + """ routerConfig: String + """ + Graph composition ID, also known as launch ID + """ graphCompositionId: String + + """ + Number of GCUs allocated for the Cloud Router + + This is ignored for serverless Cloud Routers + """ + gcus: Int +} + +type RouterConfigVersion { + """ + Name of the RouterConfigVersion + """ + name: String! + + """ + JSON schema for validating the router configuration + """ + configSchema(tier: CloudTier!): String +} + +""" +Input to create a RouterConfigVersion +""" +input RouterConfigVersionInput { + """ + Name of the RouterConfigVersion + """ + configVersion: String! + + """ + Configuration schema mapping for the RouterConfigVersion + """ + configSchemas: JSONObject! } type RouterEntitlement { @@ -10592,11 +14505,34 @@ enum RouterEntitlementAudience { SELF_HOSTED } +union RouterGcusResult = RouterGcusSuccess|InvalidInputErrors|InternalServerError + +""" +Success branch of a setGcus mutation +""" +type RouterGcusSuccess { + order: Order! +} + type RouterMutation { + """ + Set the version used for the next update for this Cloud Router + """ setNextVersion(version: String!): SetNextVersionResult! + """ + Set secrets for this Cloud Router + """ setSecrets(input: RouterSecretsInput!): RouterSecretsResult! + """ + Set the number of GCUs associated with this Router + """ + setGcus(gcus: Int!): RouterGcusResult! + + """ + Router mutations for Cloud Routers hosted on Fly + """ fly: FlyRouterMutation } @@ -10604,8 +14540,14 @@ type RouterMutation { User input for a RouterSecrets mutation """ input RouterSecretsInput { + """ + Secrets to create or update + """ secrets: [SecretInput!] + """ + Secrets to remove + """ unsetSecrets: [String!] } @@ -10624,16 +14566,44 @@ type RouterSecretsSuccess { Current status of Cloud Routers """ enum RouterStatus { + """ + Cloud Router is not yet provisioned + """ CREATING + """ + Cloud Router is running, but currently being updated + """ UPDATING + """ + Cloud Router is running, but currently being deleted + + This is the only mutation state that doesn't support rollback. If we fail to + delete a Router, the workflows are configured to stop and keep the router into + the Deleting status. + """ DELETING + """ + Current order is rolling back to the last known good state + + After a RollingBack state, a Router can move either into Running state (from a + Update order) or Deleted (from a Create order). + + If we fail to roll back, the workflows are configured to stop and keep the router + into the RollingBack status. + """ ROLLING_BACK + """ + Current router is running and able to server requests + """ RUNNING + """ + Router has been deleted + """ DELETED } @@ -10650,58 +14620,112 @@ input RouterUsageInput { key: String! } +""" +Router Version +""" type RouterVersion { + """ + Version identifier + """ version: String! + """ + Core version identifier + """ core: String! + """ + Build number + """ build: String! + """ + Status of a router version + """ status: Status! + """ + Config version for this router version + """ configVersion: String! - configSchema: String! + """ + JSON schema for validating the router configuration for this router version + """ + configSchema(tier: CloudTier): String! } +union RouterVersionConfigResult = RouterConfigVersion|CloudInvalidInputError|InternalServerError + +""" +Input to create a new router version +""" input RouterVersionCreateInput { + """ + Version identifier + """ version: String! + """ + Version status + """ status: Status! + """ + Version of the configuration + """ configVersion: String! - - configSchema: String! -} - -input RouterVersionDeleteInput { - version: String! } union RouterVersionResult = RouterVersion|InvalidInputErrors|InternalServerError +""" +List of router versions +""" type RouterVersions { versions: [RouterVersion!]! } +""" +Input for filtering router versions +""" input RouterVersionsInput { + """ + Maximum number of versions to return + """ limit: Int + """ + Name of the branch + """ branch: String + """ + Status of the version + """ status: Status } union RouterVersionsResult = RouterVersions|InvalidInputErrors|InternalServerError +""" +Input for updating a router version +""" input RouterVersionUpdateInput { + """ + Version identifier + """ version: String! + """ + Version status + """ status: Status + """ + Version of the configuration + """ configVersion: String - - configSchema: String } input RoverArgumentInput { @@ -10710,6 +14734,49 @@ input RoverArgumentInput { value: Object } +input RunLintCheckInput { + baseSchema: SchemaHashInput! + + checkStep: CheckStepInput! + + proposedSchema: SchemaHashInput! +} + +""" +Inputs needed to find all relevant proposals to a check workflow +""" +input RunProposalsCheckInput { + """ + List of subgraph names and hashes from the state of this variant when the check was run. + """ + baseSubgraphs: [SubgraphCheckInput!]! + + """ + Supergraph hash that was most recently published when the check was run + """ + baseSupergraphHash: String! + + """ + List of subgraph names and hashes that are being proposed in the check task + """ + proposedSubgraphs: [SubgraphCheckInput!]! + + """ + Supergraph hash that is the output of the check's composition task + """ + proposedSupergraphHash: String! + + """ + The severity to assign the check results if matching proposals are not found + """ + severityLevel: ProposalChangeMismatchSeverity! + + """ + The check workflow task id. Used by Task entities to resolve the results + """ + workflowTaskId: String! +} + type ScheduledSummary implements ChannelSubscription { channel: Channel @deprecated(reason: "Use channels list instead") @@ -10752,6 +14819,13 @@ type Schema { """ typeCount: Int! + """ + The list of schema coordinates ('TypeName.fieldName') in the schema + that can be measured by usage reporting. + Currently only supports object types and interface types. + """ + observableCoordinates: [SchemaCoordinate!] + """ The GraphQL schema document. """ @@ -10780,6 +14854,28 @@ type SchemaCompositionError { code: String } +type SchemaCoordinate { + id: ID! + + """ + The printed coordinate value, e.g. 'ParentType.fieldName' + """ + coordinate: String! + + """ + Whether the coordinate being referred to is marked as deprecated + """ + isDeprecated: Boolean! +} + +input SchemaCoordinateFilterInput { + """ + If true, only include deprecated coordinates. + If false, filter out deprecated coordinates. + """ + deprecated: Boolean +} + """ The result of computing the difference between two schemas, usually as part of schema checks. """ @@ -10883,6 +14979,20 @@ type SchemaDiffValidationConfig { includedVariants: [String!] } +input SchemaHashInput { + """ + If provided fetches build messages that are added to linter results. + """ + buildID: ID + + """ + SHA256 of the schema sdl. + """ + hash: String! + + subgraphs: [SubgraphHashInput!] +} + type SchemaPublishSubscription implements ChannelSubscription { channels: [Channel!]! @@ -10992,13 +15102,13 @@ type SchemaTag { Note: This does not include the history of checked schemas """ - history(limit: Int! = 3, offset: Int = 0, includeUnchanged: Boolean! = true): [SchemaTag!]! + history(limit: Int! = 3, offset: Int = 0, includeUnchanged: Boolean! = true, orderBy: SchemaTagHistoryOrder = CREATED_DESC): [SchemaTag!]! """ Number of tagged schemas created under the same tag name. Also represents the maximum size of the history's limit argument. """ - historyLength: Int! + historyLength(includeUnchanged: Boolean! = true): Int! """ Number of schemas tagged prior to this one under the same tag name, its position @@ -11018,6 +15128,31 @@ type SchemaTag { webhookNotificationBody: String! } +enum SchemaTagHistoryOrder { + CREATED_DESC + + CREATED_ASC +} + +""" +An error that occurs when an invalid schema is passed in as user input +""" +type SchemaValidationError implements Error { + issues: [SchemaValidationIssue!]! + + """ + The error's details. + """ + message: String! +} + +""" +An error that occurs when an invalid schema is passed in as user input +""" +type SchemaValidationIssue { + message: String! +} + """ How many seats of the given types does an organization have (regardless of plan type)? """ @@ -11033,17 +15168,40 @@ type Seats { fullPrice: Int! } +""" +Cloud Router secret +""" type Secret { + """ + When the secret was created + """ createdAt: DateTime! + """ + Name of the secret + """ name: String! + """ + Hash of the secret + """ hash: String! } +""" +Input for creating or updating secrets +""" input SecretInput { + """ + Name of the secret + """ name: String! + """ + Value for that secret + + This can only be used for input, as it is not possible to retrieve the value of secrets. + """ value: String! } @@ -11076,13 +15234,6 @@ Each graph has one or more variants, which correspond to the different environme Each variant has its own GraphQL schema, which means schemas can differ between environments. """ type Service implements Identity { - """ - The organization that this graph belongs to. - """ - account: Account - - accountId: ID - """ A list of the graph API keys that are active for this graph. """ @@ -11093,6 +15244,30 @@ type Service implements Identity { """ asActor: Actor! + """ + The graph's globally unique identifier. + """ + id: ID! + + name: String! + + """ + Describes the permissions that the active user has for this graph. + """ + roles: ServiceRoles + + """ + A list of the variants for this graph. + """ + variants: [GraphVariant!]! + + """ + The organization that this graph belongs to. + """ + account: Account + + accountId: ID + """ Get an URL to which an avatar image can be uploaded. Client uploads by sending a PUT request with the image data to MediaUploadInfo.url. Client SHOULD set the "Content-Type" header to the @@ -11136,6 +15311,11 @@ type Service implements Identity { datadogMetricsConfig: DatadogMetricsConfig + """ + The time the default build pipeline track version was updated. + """ + defaultBuildPipelineTrackUpdatedAt: Timestamp + deletedAt: Timestamp description: String @@ -11155,11 +15335,6 @@ type Service implements Identity { """ hiddenFromUninvitedNonAdminAccountMembers: Boolean! - """ - The graph's globally unique identifier. - """ - id: ID! - lastReportedAt(graphVariant: String): Timestamp """ @@ -11172,8 +15347,6 @@ type Service implements Identity { """ myRole: UserPermission - name: String! - onboardingArchitecture: OnboardingArchitecture """ @@ -11181,6 +15354,12 @@ type Service implements Identity { """ operationCheckRequestsByVariant(from: Timestamp!): [RequestCountsPerGraphVariant!]! + """ + A list of the proposal variants for this graph sorted by created at date. + limit defaults to Int.MAX_VALUE, offset defaults to 0 + """ + proposalVariants(filterBy: ProposalVariantsFilter, limit: Int, offset: Int): ProposalVariantsResult! + """ Get query triggers for a given variant. If variant is null all the triggers for this service will be gotten. """ @@ -11200,11 +15379,6 @@ type Service implements Identity { """ roleOverrides: [RoleOverride!] - """ - Describes the permissions that the active user has for this graph. - """ - roles: ServiceRoles - scheduledSummaries: [ScheduledSummary!]! stats(from: Timestamp!, "Granularity of buckets. Defaults to the entire range (aggregate all data into a single durationBucket) when null." resolution: Resolution, "Defaults to the current time when null." to: Timestamp): ServiceStatsWindow! @deprecated(reason: "use Service.statsWindow instead") @@ -11229,9 +15403,29 @@ type Service implements Identity { variant(name: String!): GraphVariant """ - A list of the variants for this graph. + List of ignored rule violations for the linter """ - variants: [GraphVariant!]! + ignoredLinterViolations: [IgnoredRule!]! + + """ + Linter configuration for this graph. + """ + linterConfiguration: GraphLinterConfiguration! + + """ + The Persisted Query List associated with this graph with the given ID. + """ + persistedQueryList(id: ID!): PersistedQueryList + + persistedQueryLists: [PersistedQueryList!] + + defaultProposalReviewers: [Identity]! + + flatDiff(newSdlHash: SHA256, oldSdlHash: SHA256): FlatDiffResult! + + minProposalApprovers: Int! + + minProposalRoles: ProposalRoles! operation(id: ID!): Operation @@ -11240,7 +15434,12 @@ type Service implements Identity { """ Get a GraphQL document by hash """ - document(hash: SHA256): GraphQLDocument + doc(hash: SHA256): GraphQLDoc + + """ + Get a GraphQL document by hash + """ + document(hash: SHA256): GraphQLDocument @deprecated(reason: "Use doc instead") """ Get a schema by hash or current tag @@ -11337,6 +15536,10 @@ enum ServiceBillingUsageStatsColumn { OPERATION_COUNT_PROVIDED_EXPLICITLY + OPERATION_SUBTYPE + + OPERATION_TYPE + SCHEMA_TAG TIMESTAMP @@ -11349,6 +15552,10 @@ type ServiceBillingUsageStatsDimensions { operationCountProvidedExplicitly: String + operationSubtype: String + + operationType: String + schemaTag: String } @@ -11377,6 +15584,16 @@ input ServiceBillingUsageStatsFilter { """ operationCountProvidedExplicitly: String + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [ServiceBillingUsageStatsFilter!] """ @@ -11404,6 +15621,16 @@ input ServiceBillingUsageStatsFilterIn { """ operationCountProvidedExplicitly: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose schemaTag dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -11994,6 +16221,10 @@ enum ServiceFieldUsageColumn { FIELD_NAME + OPERATION_SUBTYPE + + OPERATION_TYPE + PARENT_TYPE QUERY_ID @@ -12016,6 +16247,10 @@ type ServiceFieldUsageDimensions { fieldName: String + operationSubtype: String + + operationType: String + parentType: String queryId: ID @@ -12052,6 +16287,16 @@ input ServiceFieldUsageFilter { not: ServiceFieldUsageFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [ServiceFieldUsageFilter!] """ @@ -12097,7 +16342,17 @@ input ServiceFieldUsageFilterIn { """ Selects rows whose fieldName dimension is in the given list. A null value in the list means a row with null for that dimension. """ - fieldName: [String] + fieldName: [String] + + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] """ Selects rows whose parentType dimension is in the given list. A null value in the list means a row with null for that dimension. @@ -12156,10 +16411,135 @@ type ServiceFieldUsageRecord { timestamp: Timestamp! } +""" +Columns of ServiceGraphosCloudMetrics. +""" +enum ServiceGraphosCloudMetricsColumn { + AGENT_VERSION + + RESPONSE_SIZE + + RESPONSE_SIZE_THROTTLED + + ROUTER_ID + + ROUTER_OPERATIONS + + ROUTER_OPERATIONS_THROTTLED + + SCHEMA_TAG + + SUBGRAPH_FETCHES + + SUBGRAPH_FETCHES_THROTTLED + + TIMESTAMP +} + +type ServiceGraphosCloudMetricsDimensions { + agentVersion: String + + routerId: String + + schemaTag: String +} + +""" +Filter for data in ServiceGraphosCloudMetrics. Fields with dimension names represent equality checks. All fields are implicitly ANDed together. +""" +input ServiceGraphosCloudMetricsFilter { + """ + Selects rows whose agentVersion dimension equals the given value if not null. To query for the null value, use {in: {agentVersion: [null]}} instead. + """ + agentVersion: String + + and: [ServiceGraphosCloudMetricsFilter!] + + in: ServiceGraphosCloudMetricsFilterIn + + not: ServiceGraphosCloudMetricsFilter + + or: [ServiceGraphosCloudMetricsFilter!] + + """ + Selects rows whose routerId dimension equals the given value if not null. To query for the null value, use {in: {routerId: [null]}} instead. + """ + routerId: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String +} + +""" +Filter for data in ServiceGraphosCloudMetrics. Fields match if the corresponding dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input ServiceGraphosCloudMetricsFilterIn { + """ + Selects rows whose agentVersion dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + agentVersion: [String] + + """ + Selects rows whose routerId dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + routerId: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + schemaTag: [String] +} + +type ServiceGraphosCloudMetricsMetrics { + responseSize: Long! + + responseSizeThrottled: Long! + + routerOperations: Long! + + routerOperationsThrottled: Long! + + subgraphFetches: Long! + + subgraphFetchesThrottled: Long! +} + +input ServiceGraphosCloudMetricsOrderBySpec { + column: ServiceGraphosCloudMetricsColumn! + + direction: Ordering! +} + +type ServiceGraphosCloudMetricsRecord { + """ + Dimensions of ServiceGraphosCloudMetrics that can be grouped by. + """ + groupBy: ServiceGraphosCloudMetricsDimensions! + + """ + Metrics of ServiceGraphosCloudMetrics that can be aggregated over. + """ + metrics: ServiceGraphosCloudMetricsMetrics! + + """ + Starting segment timestamp. + """ + timestamp: Timestamp! +} + """ Provides access to mutation fields for managing Studio graphs and subgraphs. """ type ServiceMutation { + """ + Generates a new graph API key for this graph with the specified permission level. + """ + newKey(keyName: String, role: UserPermission! = GRAPH_ADMIN): GraphApiKey! + + service: Service! + """ Make changes to a check workflow. """ @@ -12167,8 +16547,18 @@ type ServiceMutation { createCompositionStatusSubscription("ID of Slack channel for registry notification." channelID: ID!, "Variant to notify on." variant: String!): SchemaPublishSubscription! + """ + Creates a proposal variant from a source variant and a name, description. Do not call this from any clients, this resolver is exclusively for inter-service proposal -> kotlin registry communication. + """ + createProposalVariant("Description for the proposal, used to pre fill a readme" description: String, "Name of the base variant, used to port over all subgraphs or monograph sdl to the new proposal as a base revision." sourceVariantName: ID!, "Actor of the og user calling this. We call this from the proposals subgraph, we need to pass through the actor." triggeredBy: ActorInput): ProposalVariantCreationResult! + createSchemaPublishSubscription("ID of Slack channel for registry notification." channelID: ID!, "Variant to notify on." variant: String!): SchemaPublishSubscription! + """ + Update the default build pipeline track for this graph. + """ + defaultBuildPipelineTrack(buildPipelineTrack: BuildPipelineTrack!): BuildPipelineTrack + """ Soft delete a graph. Data associated with the graph is not permanently deleted; Apollo support can undo. """ @@ -12216,11 +16606,6 @@ type ServiceMutation { id: ID! @deprecated(reason: "Use service.id") - """ - Generates a new graph API key for this graph with the specified permission level. - """ - newKey(keyName: String, role: UserPermission! = GRAPH_ADMIN): GraphApiKey! - """ Adds an override to the given users permission for this graph """ @@ -12238,8 +16623,6 @@ type ServiceMutation { reportServerInfo("Only sent if previously requested i.e. received ReportServerInfoResult with withExecutableSchema = true. An executable schema is a schema document that describes the full GraphQL schema that an external client could execute queries against. This must be a valid GraphQL schema document, as per the GraphQL specification: https:\/\/spec.graphql.org\/" executableSchema: String, "Information about the edge server, see descriptions for individual fields." info: EdgeServerInfo!): ReportServerInfoResult @deprecated(reason: "use Mutation.reportSchema instead") - service: Service! - """ Test Slack notification channel """ @@ -12297,6 +16680,44 @@ type ServiceMutation { """ variant(name: String!): GraphVariantMutation + """ + Lint a single schema using the graph's linter configuration. + """ + lintSchema("The schema to diff rule violations against, if not provided the full set of rule violations will be returned for the proposed sdl." baseSdl: String, "The schema to lint." sdl: String!): LintResult! + + """ + Update rule violations to ignore for this graph. + """ + updateIgnoredRuleViolations(changes: LinterIgnoredRuleChangesInput!): [IgnoredRule!]! + + """ + Update the linter configuration for this graph. + """ + updateLinterConfiguration(changes: GraphLinterConfigurationChangesInput!): GraphLinterConfiguration! + + createPersistedQueryList(description: String, linkedVariants: [String!], name: String!): CreatePersistedQueryListResultOrError! + + """ + Provides access to mutation fields for modifying a Persisted Query List with the provided ID. + """ + persistedQueryList(id: ID!): PersistedQueryListMutation! + + createProposal(input: CreateProposalInput!): CreateProposalResult! + + """ + Mutation to set whether a proposals check task's results should be overridden or not + """ + overrideProposalsCheckTask(shouldOverride: Boolean!, taskId: ID!): Boolean + + setMinProposalApprovers(input: SetMinProposalApproversInput!): SetMinApproversResult! + + """ + The minimum role for create & edit is observer + """ + setMinProposalRoles(input: SetProposalRolesInput!): SetProposalRolesResult! + + setProposalDefaultReviewers(input: SetProposalDefaultReviewersInput!): SetProposalDefaultReviewersResult! + validateOperations(operations: [OperationDocumentInput!]!, tag: String = "current", gitContext: GitContextInput): ValidateOperationsResult! registerOperationsWithResponse(clientIdentity: RegisteredClientIdentityInput, gitContext: GitContextInput, operations: [RegisteredOperationInput!]!, manifestVersion: Int, "Specifies which variant of a graph these operations belong to.\nFormerly known as \"tag\"\nDefaults to \"current\"" graphVariant: String! = "current"): RegisterOperationsMutationResponse @@ -12325,7 +16746,7 @@ type ServiceMutation { If they do not set `historicParameters` but set `useMaximumRetention`, validation will use the maximum retention the graph has access to. """ - checkSchema("Only one of proposedSchema, proposedSchemaDocument, and proposedSchemaHash\nmay be specified" proposedSchema: IntrospectionSchemaInput, proposedSchemaDocument: String, proposedSchemaHash: String, baseSchemaTag: String = "current", gitContext: GitContextInput, historicParameters: HistoricQueryParameters, useMaximumRetention: Boolean, isSandboxCheck: Boolean! = false, "If this check is triggered for an sdl fetched using introspection, this is the endpoint where that schema was being served." introspectionEndpoint: String, "Deprecated and ignored." frontend: String): CheckSchemaResult! + checkSchema("Only one of proposedSchema, proposedSchemaDocument, and proposedSchemaHash\nmay be specified" proposedSchema: IntrospectionSchemaInput, proposedSchemaDocument: String, proposedSchemaHash: String, baseSchemaTag: String = "current", gitContext: GitContextInput, historicParameters: HistoricQueryParameters, useMaximumRetention: Boolean, isSandboxCheck: Boolean! = false, isProposalCheck: Boolean! = false, "If this check is triggered for an sdl fetched using introspection, this is the endpoint where that schema was being served." introspectionEndpoint: String, "Deprecated and ignored." frontend: String): CheckSchemaResult! """ Delete a variant by name. @@ -12344,7 +16765,10 @@ type ServiceMutation { """ publishSubgraph(graphVariant: String!, name: String!, url: String, revision: String!, activePartialSchema: PartialSchemaInput!, gitContext: GitContextInput): CompositionAndUpsertResult - triggerRepublish(graphVariant: String!): Void + """ + Publishes multiple subgraphs. If composition is successful, this will update running routers. + """ + publishSubgraphs(graphVariant: String!, revision: String!, subgraphInputs: [PublishSubgraphsSubgraphInput!]!, gitContext: GitContextInput): CompositionAndUpsertResult """ This mutation will not result in any changes to the implementing service @@ -12353,7 +16777,7 @@ type ServiceMutation { and any warnings and errors pertaining to composition. This mutation will not run validation against operations. """ - validatePartialSchemaOfImplementingServiceAgainstGraph(graphVariant: String!, implementingServiceName: String!, partialSchema: PartialSchemaInput!): CompositionValidationResult! + validatePartialSchemaOfImplementingServiceAgainstGraph(graphVariant: String!, implementingServiceName: String!, partialSchema: PartialSchemaInput!): CompositionValidationResult! @deprecated(reason: "Use GraphVariant.submitSubgraphCheckAsync instead") """ Removes a subgraph. If composition is successful, this will update running routers. @@ -12364,12 +16788,12 @@ type ServiceMutation { Checks a proposed subgraph schema change against a published subgraph. If the proposal composes successfully, perform a usage check for the resulting supergraph schema. """ - checkPartialSchema("The name of the graph variant to run the check against." graphVariant: String!, "Name of the implementing service to validate the partial schema against" implementingServiceName: String!, "The partial schema to validate against an implementing service" partialSchema: PartialSchemaInput!, gitContext: GitContextInput, historicParameters: HistoricQueryParameters, "Deprecated and ignored." frontend: String, "Whether to use the maximum retention for historical validation. This only takes\neffect if historicParameters is null." useMaximumRetention: Boolean, isSandboxCheck: Boolean! = false, "If this check is triggered for an sdl fetched using introspection, this is the endpoint where that schema was being served." introspectionEndpoint: String): CheckPartialSchemaResult! + checkPartialSchema("The name of the graph variant to run the check against." graphVariant: String!, "Name of the implementing service to validate the partial schema against" implementingServiceName: String!, "The partial schema to validate against an implementing service" partialSchema: PartialSchemaInput!, gitContext: GitContextInput, historicParameters: HistoricQueryParameters, "Deprecated and ignored." frontend: String, "Whether to use the maximum retention for historical validation. This only takes\neffect if historicParameters is null." useMaximumRetention: Boolean, isSandboxCheck: Boolean! = false, isProposalCheck: Boolean! = false, "If this check is triggered for an sdl fetched using introspection, this is the endpoint where that schema was being served." introspectionEndpoint: String, "The user that triggered this check." triggeredBy: ActorInput): CheckPartialSchemaResult! @deprecated(reason: "Use GraphVariant.submitSubgraphCheckAsync instead.\nThis mutation polls to wait for the check to finish,\nwhile subgraphSubgraphCheckAsync triggers returns\nwithout waiting for the check to finish.") """ Update schema check configuration for a graph. """ - updateCheckConfiguration("Operations to ignore during validation." excludedOperations: [ExcludedOperationInput!], "Clients to ignore during validation." excludedClients: [ClientFilterInput!], "Operation names to ignore during validation." excludedOperationNames: [OperationNameFilterInput!], "Variant overrides for validation." includedVariants: [String!], "Only check operations from the last seconds. The default is 7 days (604,800 seconds)." timeRangeSeconds: Long, "Minimum number of requests within the window for a query to be considered." operationCountThreshold: Int, "Number of requests within the window for a query to be considered, relative to\ntotal request count. Expected values are between 0 and 0.05 (minimum 5% of\ntotal request volume)" operationCountThresholdPercentage: Float, "Default configuration to include operations on the base variant." includeBaseVariant: Boolean): CheckConfiguration! + updateCheckConfiguration("Operations to ignore during validation." excludedOperations: [ExcludedOperationInput!], "Clients to ignore during validation." excludedClients: [ClientFilterInput!], "Operation names to ignore during validation." excludedOperationNames: [OperationNameFilterInput!], "Variant overrides for validation." includedVariants: [String!], "Only check operations from the last seconds. The default is 7 days (604,800 seconds)." timeRangeSeconds: Long, "Minimum number of requests within the window for a query to be considered." operationCountThreshold: Int, "Number of requests within the window for a query to be considered, relative to\ntotal request count. Expected values are between 0 and 0.05 (minimum 5% of\ntotal request volume)" operationCountThresholdPercentage: Float, "Default configuration to include operations on the base variant." includeBaseVariant: Boolean, "Whether to run Linting during schema checks." enableLintChecks: Boolean, "How submitted build input diffs are handled when they don't match a Proposal" proposalChangeMismatchSeverity: ProposalChangeMismatchSeverity): CheckConfiguration! """ Mark the changeset that affects an operation in a given check instance as safe. @@ -12409,6 +16833,10 @@ enum ServiceOperationCheckStatsColumn { CLIENT_VERSION + OPERATION_SUBTYPE + + OPERATION_TYPE + QUERY_ID QUERY_NAME @@ -12425,6 +16853,10 @@ type ServiceOperationCheckStatsDimensions { clientVersion: String + operationSubtype: String + + operationType: String + queryId: ID queryName: String @@ -12452,6 +16884,16 @@ input ServiceOperationCheckStatsFilter { not: ServiceOperationCheckStatsFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [ServiceOperationCheckStatsFilter!] """ @@ -12484,6 +16926,16 @@ input ServiceOperationCheckStatsFilterIn { """ clientVersion: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -12547,6 +16999,10 @@ enum ServiceQueryStatsColumn { FROM_ENGINEPROXY + OPERATION_SUBTYPE + + OPERATION_TYPE + QUERY_ID QUERY_NAME @@ -12573,12 +17029,18 @@ type ServiceQueryStatsDimensions { fromEngineproxy: String + operationSubtype: String + + operationType: String + queryId: ID queryName: String querySignature: String + querySignatureLength: Int + schemaHash: String schemaTag: String @@ -12609,6 +17071,16 @@ input ServiceQueryStatsFilter { not: ServiceQueryStatsFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [ServiceQueryStatsFilter!] """ @@ -12651,6 +17123,16 @@ input ServiceQueryStatsFilterIn { """ fromEngineproxy: [String] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -12721,6 +17203,10 @@ type ServiceQueryStatsRecord { Individual permissions for the current user when interacting with a particular Studio graph. """ type ServiceRoles { + canQueryTokens: Boolean! + + service: Service! + """ Whether the currently authenticated user is permitted to perform schema checks (i.e., run `rover (sub)graph check`). """ @@ -12756,6 +17242,16 @@ type ServiceRoles { """ canManageKeys: Boolean! + """ + Whether the currently authenticated user is permitted to manage proposal permission settings for this graph. + """ + canManageProposalPermissions: Boolean! + + """ + Whether the currently authenticated user is permitted to manage proposal settings, like setting the implementation variant, on this graph. + """ + canManageProposalSettings: Boolean! + """ Whether the currently authenticated user is permitted to perform basic administration of variants (e.g., make a variant public). """ @@ -12782,6 +17278,8 @@ type ServiceRoles { canQueryPrivateInfo: Boolean! + canQueryProposals: Boolean! + canQueryPublicInfo: Boolean! canQueryReadmeAuthor: Boolean! @@ -12795,8 +17293,6 @@ type ServiceRoles { canQueryStats: Boolean! - canQueryTokens: Boolean! - canQueryTraces: Boolean! """ @@ -12814,14 +17310,18 @@ type ServiceRoles { canUpdateTitle: Boolean! - canVisualizeStats: Boolean! @deprecated(reason: "Replaced with canQueryTraces and canQueryStats") - """ Whether the currently authenticated user is permitted to make updates to the check configuration for this graph. """ canWriteCheckConfiguration: Boolean! - canWriteTraces: Boolean! @deprecated(reason: "Never worked, not replaced") + canManagePersistedQueryLists: Boolean! + + canQueryPersistedQueryLists: Boolean! + + canCreateProposal: Boolean! + + canEditProposal: Boolean! } """ @@ -12842,6 +17342,8 @@ type ServiceStatsWindow { fieldUsage("Filter to select what rows to return." filter: ServiceFieldUsageFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order ServiceFieldUsage by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [ServiceFieldUsageOrderBySpec!]): [ServiceFieldUsageRecord!]! + graphosCloudMetrics("Filter to select what rows to return." filter: ServiceGraphosCloudMetricsFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order ServiceGraphosCloudMetrics by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [ServiceGraphosCloudMetricsOrderBySpec!]): [ServiceGraphosCloudMetricsRecord!]! + operationCheckStats("Filter to select what rows to return." filter: ServiceOperationCheckStatsFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order ServiceOperationCheckStats by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [ServiceOperationCheckStatsOrderBySpec!]): [ServiceOperationCheckStatsRecord!]! queryStats("Filter to select what rows to return." filter: ServiceQueryStatsFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order ServiceQueryStats by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [ServiceQueryStatsOrderBySpec!]): [ServiceQueryStatsRecord!]! @@ -13093,7 +17595,9 @@ enum ServiceTraceRefsColumn { DURATION_BUCKET - DURATION_NS + OPERATION_SUBTYPE + + OPERATION_TYPE QUERY_ID @@ -13105,9 +17609,9 @@ enum ServiceTraceRefsColumn { TIMESTAMP - TRACE_ID + TRACE_COUNT - TRACE_SIZE_BYTES + TRACE_ID } type ServiceTraceRefsDimensions { @@ -13117,6 +17621,12 @@ type ServiceTraceRefsDimensions { durationBucket: Int + generatedTraceId: String + + operationSubtype: String + + operationType: String + queryId: ID queryName: String @@ -13155,6 +17665,16 @@ input ServiceTraceRefsFilter { not: ServiceTraceRefsFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [ServiceTraceRefsFilter!] """ @@ -13202,6 +17722,16 @@ input ServiceTraceRefsFilterIn { """ durationBucket: [Int] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -13229,9 +17759,7 @@ input ServiceTraceRefsFilterIn { } type ServiceTraceRefsMetrics { - durationNs: Long! - - traceSizeBytes: Long! + traceCount: Long! } input ServiceTraceRefsOrderBySpec { @@ -13257,18 +17785,117 @@ type ServiceTraceRefsRecord { timestamp: Timestamp! } +union SetMinApproversResult = PermissionError|Service|ValidationError + +input SetMinProposalApproversInput { + minApprovers: Int +} + union SetNextVersionResult = RouterVersion|InvalidInputErrors|InternalServerError +input SetProposalDefaultReviewersInput { + reviewerUserIds: [ID!]! +} + +union SetProposalDefaultReviewersResult = PermissionError|Service|ValidationError + +input SetProposalRolesInput { + create: UserPermission + + edit: UserPermission +} + +union SetProposalRolesResult = PermissionError|Service|ValidationError + +input SetRequestedReviewersInput { + reviewerUserIds: [ID!]! +} + +union SetRequestedReviewersResult = PermissionError|Proposal|ValidationError + union SetupIntentResult = NotFoundError|PermissionError|SetupIntentSuccess -type SetupIntentSuccess { - clientSecret: String! +type SetupIntentSuccess { + clientSecret: String! +} + +""" +A SHA-256 hash, represented as a lowercase hexadecimal string. +""" +scalar SHA256 + +""" +Shard for Cloud Routers + +This represents a specific shard where a Cloud Router can run +""" +type Shard { + id: ID! + + region: RegionDescription! + + tier: CloudTier! + + provider: CloudProvider! + + routerUsage: Int! + + routerCapacity: Int + + gcuUsage: Int! + + gcuCapacity: Int + + routers(first: Int, offset: Int): [Router!]! + + """ + Details of this shard for a specific provider + """ + providerDetails: ShardProvider! +} + +union ShardProvider = AwsShard|FlyShard + +union ShardResult = ShardSuccess|InvalidInputErrors|InternalServerError + +""" +Current status of [`Shard`]s +""" +enum ShardStatus { + """ + The Shard is active and ready to accept new Cloud Routers + """ + ACTIVE + + """ + The Shard is suffering from a temporary degradation that might impact provisioning new + Cloud Routers + """ + IMPAIRED + + """ + The Shard is working as expected, but should not be used to provision new Cloud Routers + """ + DEPRECATED + + """ + The Shard is currently being updated and should temporarily not be used to provision new + Cloud Routers + """ + UPDATING + + """ + The Shard no long exists + """ + DELETED } """ -A SHA-256 hash, represented as a lowercase hexadecimal string. +Success branch of an shard mutation """ -scalar SHA256 +type ShardSuccess { + shard: Shard! +} """ Slack notification channel @@ -13392,6 +18019,8 @@ type StatsWindow { fieldUsage("Filter to select what rows to return." filter: FieldUsageFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order FieldUsage by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [FieldUsageOrderBySpec!]): [FieldUsageRecord!]! + graphosCloudMetrics("Filter to select what rows to return." filter: GraphosCloudMetricsFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order GraphosCloudMetrics by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [GraphosCloudMetricsOrderBySpec!]): [GraphosCloudMetricsRecord!]! + operationCheckStats("Filter to select what rows to return." filter: OperationCheckStatsFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order OperationCheckStats by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [OperationCheckStatsOrderBySpec!]): [OperationCheckStatsRecord!]! queryStats("Filter to select what rows to return." filter: QueryStatsFilter, "The maximum number of entries to return, cannot be more than 15000." limit: Int = 10000, "A list of OrderBySpecs to order QueryStats by. The earlier an OrderBySpec appears in the list, the higher priority it has in the final ordering. When empty or null, defaults to sorting by ascending timestamp." orderBy: [QueryStatsOrderBySpec!]): [QueryStatsRecord!]! @@ -13415,10 +18044,25 @@ type StatsWindow { Possible status of a Cloud Router version """ enum Status { + """ + Cloud Router Version is ready to be used by end users + """ STABLE + """ + Upcoming or experimental version of a Cloud Router + + This should only be used internally, or to preview new features to + customers. + """ NEXT + """ + Deprecated version of a Cloud Router + + New Cloud Routers should not use this version, and this will not be + supported at some point in the future. + """ DEPRECATED } @@ -13488,6 +18132,11 @@ type Subgraph { """ numberOfTypes: Int + """ + The revision string of this publish if provided + """ + revision: String + """ The subgraph's routing URL, provided to gateways that use managed federation. """ @@ -13546,6 +18195,11 @@ input SubgraphCheckAsyncInput { """ introspectionEndpoint: String + """ + If `true`, the check was initiated automatically by a Proposal update. + """ + isProposal: Boolean + """ If `true`, the check was initiated by Apollo Sandbox. """ @@ -13556,10 +18210,35 @@ input SubgraphCheckAsyncInput { """ proposedSchema: GraphQLDocument! + """ + The source variant that this check should use the operations check configuration from + """ + sourceVariant: String + """ The name of the subgraph to check schema changes for. """ subgraphName: String! + + """ + The user that triggered this check. If null, defaults to authContext to determine user. + """ + triggeredBy: ActorInput +} + +""" +A subgraph in a federated Studio supergraph. +""" +input SubgraphCheckInput { + """ + The subgraph schema document's SHA256 hash, represented as a hexadecimal string. + """ + hash: String! + + """ + The subgraph's registered name. + """ + name: String! } type SubgraphConfig { @@ -13574,6 +18253,15 @@ type SubgraphConfig { url: String! } +input SubgraphHashInput { + """ + SHA256 of the subgraph schema sdl. + """ + hash: String! + + name: String! +} + input SubgraphInput { """ We are either going to pass in a document or a schema reference @@ -13598,6 +18286,22 @@ type SubgraphKeyMap { keys: [String!]! } +type SubscriptionCapability { + label: String! + + subscription: BillingSubscription! + + value: Boolean! +} + +type SubscriptionLimit { + label: String! + + subscription: BillingSubscription! + + value: Long! +} + type SubscriptionOptions { """ Enables notifications for schema updates @@ -13630,22 +18334,26 @@ enum SubscriptionState { UNKNOWN } -enum SubscriptionStateV2 { - ACTIVE +type Survey { + id: String! - CANCELED + isComplete: Boolean! - EXPIRED + questionAnswers: [SurveyQuestionAnswer!]! - FUTURE + shouldShow: Boolean! +} - PAST_DUE +type SurveyQuestionAnswer { + answerValue: String - PAUSED + questionKey: String! +} - PENDING +input SurveyQuestionInput { + answerValue: String - UNKNOWN + questionKey: String! } union SyncBillingAccountResult = PermissionError|SyncBillingAccountSuccess @@ -13654,6 +18362,21 @@ type SyncBillingAccountSuccess { message: String! } +""" +User input for a resource share mutation +""" +input SyncPrivateSubgraphsInput { + """ + A unique identifier for the private subgraph + """ + identifier: String! + + """ + The cloud provider where the private subgraph is hosted + """ + provider: CloudProvider! +} + type TemporaryURL { url: String! } @@ -13664,6 +18387,15 @@ enum ThemeName { LIGHT } +""" +Throttle error +""" +type ThrottleError implements Error { + message: String! + + retryAfter: Int +} + enum TicketPriority { P0 @@ -14142,7 +18874,9 @@ enum TraceRefsColumn { DURATION_BUCKET - DURATION_NS + OPERATION_SUBTYPE + + OPERATION_TYPE QUERY_ID @@ -14156,9 +18890,9 @@ enum TraceRefsColumn { TIMESTAMP - TRACE_ID + TRACE_COUNT - TRACE_SIZE_BYTES + TRACE_ID } type TraceRefsDimensions { @@ -14168,6 +18902,12 @@ type TraceRefsDimensions { durationBucket: Int + generatedTraceId: String + + operationSubtype: String + + operationType: String + queryId: ID queryName: String @@ -14208,6 +18948,16 @@ input TraceRefsFilter { not: TraceRefsFilter + """ + Selects rows whose operationSubtype dimension equals the given value if not null. To query for the null value, use {in: {operationSubtype: [null]}} instead. + """ + operationSubtype: String + + """ + Selects rows whose operationType dimension equals the given value if not null. To query for the null value, use {in: {operationType: [null]}} instead. + """ + operationType: String + or: [TraceRefsFilter!] """ @@ -14260,6 +19010,16 @@ input TraceRefsFilterIn { """ durationBucket: [Int] + """ + Selects rows whose operationSubtype dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationSubtype: [String] + + """ + Selects rows whose operationType dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + operationType: [String] + """ Selects rows whose queryId dimension is in the given list. A null value in the list means a row with null for that dimension. """ @@ -14292,9 +19052,7 @@ input TraceRefsFilterIn { } type TraceRefsMetrics { - durationNs: Long! - - traceSizeBytes: Long! + traceCount: Long! } input TraceRefsOrderBySpec { @@ -14377,6 +19135,54 @@ type UnignoreOperationsInChecksResult { graph: Service! } +type UnlinkPersistedQueryListResult { + graphVariant: GraphVariant! + + unlinkedPersistedQueryList: PersistedQueryList! +} + +union UnlinkPersistedQueryListResultOrError = PermissionError|UnlinkPersistedQueryListResult|VariantAlreadyUnlinkedError + +""" +Input to update an AWS shard +""" +input UpdateAwsShardInput { + region: String + + endpoint: String + + accountId: String + + iamRoleArn: String + + loadbalancerArn: String + + loadbalancerSecurityGroupId: String + + loadbalancerListenerArn: String + + ecsClusterArn: String + + vpcId: String + + subnetIds: [String!] + + permissionsBoundaryArn: String +} + +""" +Input to update a Fly shard +""" +input UpdateFlyShardInput { + region: String + + organizationId: String + + endpoint: String + + etcdEndpoints: [String!] +} + union UpdateOperationCollectionEntryResult = OperationCollectionEntry|PermissionError|ValidationError union UpdateOperationCollectionResult = OperationCollection|PermissionError|ValidationError @@ -14387,14 +19193,57 @@ type UpdatePaymentMethodSuccess { paymentMethodId: String! } +type UpdatePersistedQueryListMetadataResult { + persistedQueryList: PersistedQueryList! +} + +union UpdatePersistedQueryListMetadataResultOrError = PermissionError|UpdatePersistedQueryListMetadataResult + +union UpdateProposalResult = PermissionError|Proposal|ValidationError + +input UpdateRequestedReviewersInput { + reviewerUserIdsToAdd: [ID!] + + reviewerUserIdsToRemove: [ID!] +} + +union UpdateRequestedReviewersResult = PermissionError|Proposal|ValidationError + +""" +Input for updating a Cloud Router +""" input UpdateRouterInput { + """ + URL for the Cloud Router + """ routerUrl: String + """ + Router version for the Cloud Router + """ routerVersion: String + """ + Configuration for the Cloud Router + """ routerConfig: String + """ + Graph composition ID, also known as launch ID + """ graphCompositionId: String + + """ + Number of GCUs allocated for the Cloud Router + + This is ignored for serverless Cloud Routers + """ + gcus: Int + + """ + Unique identifier for ordering orders + """ + orderingId: String! } union UpdateRouterResult = UpdateRouterSuccess|InvalidInputErrors|InternalServerError @@ -14410,6 +19259,27 @@ type UpdateRouterSuccess { union UpdateRouterVersionResult = RouterVersion|CloudInvalidInputError|InternalServerError +""" +Input to update an existing Shard +""" +input UpdateShardInput { + shardId: String! + + gcuCapacity: Int + + gcuUsage: Int + + routerCapacity: Int + + routerUsage: Int + + status: ShardStatus + + aws: UpdateAwsShardInput + + fly: UpdateFlyShardInput +} + """ Describes the result of publishing a schema to a graph variant. """ @@ -14440,6 +19310,16 @@ type UploadSchemaMutationResponse { publication: SchemaTag } +input UpsertReviewInput { + comment: String + + decision: ReviewDecision! + + revisionId: ID! +} + +union UpsertReviewResult = PermissionError|Proposal|ValidationError + union UpsertRouterResult = GraphVariant|RouterUpsertFailure type URI { @@ -14455,35 +19335,11 @@ A registered Apollo Studio user. type User implements Identity { acceptedPrivacyPolicyAt: Timestamp - accounts: [Account!]! @deprecated(reason: "Replaced with User.memberships.account") - - """ - Returns a list of all active user API keys for the user. - """ - apiKeys(includeCookies: Boolean = false): [UserApiKey!]! - """ Returns a representation of this user as an `Actor` type. Useful when determining which actor (usually a `User` or `Graph`) performed a particular action in Studio. """ asActor: Actor! - """ - Get an URL to which an avatar image can be uploaded. Client uploads by sending a PUT request - with the image data to MediaUploadInfo.url. Client SHOULD set the "Content-Type" header to the - browser-inferred MIME type, and SHOULD set the "x-apollo-content-filename" header to the - filename, if such information is available. Client MUST set the "x-apollo-csrf-token" header to - MediaUploadInfo.csrfToken. - """ - avatarUpload: AvatarUploadResult - - """ - Get an image URL for the user's avatar. Note that CORS is not enabled for these URLs. The size - argument is used for bandwidth reduction, and should be the size of the image as displayed in the - application. Apollo's media server will downscale larger images to at least the requested size, - but this will not happen for third-party media servers. - """ - avatarUrl(size: Int! = 40): String - betaFeaturesOn: Boolean! canUpdateAvatar: Boolean! @@ -14500,8 +19356,6 @@ type User implements Identity { emailVerified: Boolean! - featureIntros: FeatureIntros - fullName: String! """ @@ -14532,11 +19386,6 @@ type User implements Identity { logoutAfterIdleMs: Int - """ - A list of the user's memberships in Apollo Studio organizations. - """ - memberships: [UserMembership!]! - """ The user's first and last name. """ @@ -14544,16 +19393,45 @@ type User implements Identity { synchronized: Boolean! + type: UserType! + + """ + Returns a list of all active user API keys for the user. + """ + apiKeys(includeCookies: Boolean = false): [UserApiKey!]! + + """ + Get an URL to which an avatar image can be uploaded. Client uploads by sending a PUT request + with the image data to MediaUploadInfo.url. Client SHOULD set the "Content-Type" header to the + browser-inferred MIME type, and SHOULD set the "x-apollo-content-filename" header to the + filename, if such information is available. Client MUST set the "x-apollo-csrf-token" header to + MediaUploadInfo.csrfToken. + """ + avatarUpload: AvatarUploadResult + + """ + Get an image URL for the user's avatar. Note that CORS is not enabled for these URLs. The size + argument is used for bandwidth reduction, and should be the size of the image as displayed in the + application. Apollo's media server will downscale larger images to at least the requested size, + but this will not happen for third-party media servers. + """ + avatarUrl(size: Int! = 40): String + + featureIntros: FeatureIntros + + """ + A list of the user's memberships in Apollo Studio organizations. + """ + memberships: [UserMembership!]! + """ List of Zendesk tickets this user has submitted """ tickets: [ZendeskTicket!] - type: UserType! - - odysseyTasks(in: [ID!]): [OdysseyTask!]! + odysseyTasks(in: [ID!]): [OdysseyTask!] - odysseyCourses: [OdysseyCourse!]! + odysseyCourses: [OdysseyCourse!] odysseyCourse(courseId: ID!): OdysseyCourse @@ -14561,13 +19439,13 @@ type User implements Identity { odysseyCertification(certificationId: ID!): OdysseyCertification - odysseyAttempts: [OdysseyAttempt!]! + odysseyAttempts: [OdysseyAttempt!] odysseyAttempt(id: ID!): OdysseyAttempt - odysseyHasEarlyAccess: Boolean! + odysseyHasEarlyAccess: Boolean! @deprecated(reason: "Unused. Remove from application usage") - odysseyHasRequestedEarlyAccess: Boolean! + odysseyHasRequestedEarlyAccess: Boolean! @deprecated(reason: "Unused. Remove from application usage") sandboxOperationCollections: [OperationCollection!]! } @@ -14619,13 +19497,15 @@ type UserMembership { } type UserMutation { - acceptPrivacyPolicy: Void - """ Change the user's password """ changePassword(newPassword: String!, previousPassword: String!): Void + user: User! + + acceptPrivacyPolicy: Void + """ Delete the user's avatar. Requires User.canUpdateAvatar to be true. """ @@ -14693,11 +19573,9 @@ type UserMutation { """ updateRole(newRole: InternalMdgAdminRole): User - user: User! - verifyEmail(token: String!): User - setOdysseyTask(task: OdysseyTaskInput!): OdysseyTask + setOdysseyTask(task: OdysseyTaskInput!, courseId: ID): OdysseyTask createOdysseyTasks(tasks: [OdysseyTaskInput!]!): [OdysseyTask!] @@ -14740,6 +19618,8 @@ enum UserPermission { OBSERVER ORG_ADMIN + + PERSISTED_QUERY_PUBLISHER } enum UserSegment { @@ -14863,6 +19743,14 @@ type ValidationResult { operation: OperationDocument! } +type VariantAlreadyLinkedError implements Error { + message: String! +} + +type VariantAlreadyUnlinkedError implements Error { + message: String! +} + """ Variant-level configuration of checks. """ @@ -15087,8 +19975,12 @@ input ZendeskTicketInput { priority: TicketPriority! subject: String! + + uploadToken: String } +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations. """ @@ -15121,6 +20013,8 @@ type __Schema { directives: [__Directive!]! } +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum. @@ -15148,6 +20042,8 @@ type __Type { ofType: __Type } +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ An enum describing what kind of type a given `__Type` is. """ @@ -15193,6 +20089,8 @@ enum __TypeKind { NON_NULL } +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type. """ @@ -15210,6 +20108,8 @@ type __Field { deprecationReason: String } +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value. """ @@ -15230,6 +20130,8 @@ type __InputValue { deprecationReason: String } +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string. """ @@ -15243,6 +20145,8 @@ type __EnumValue { deprecationReason: String } +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document. @@ -15260,6 +20164,8 @@ type __Directive { args(includeDeprecated: Boolean = false): [__InputValue!]! } +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies. """ @@ -15360,21 +20266,31 @@ enum __DirectiveLocation { INPUT_FIELD_DEFINITION } +directive @defer (label: String, if: Boolean! = true) on FRAGMENT_SPREAD|INLINE_FRAGMENT + +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ Directs the executor to include this field or fragment only when the `if` argument is true. """ directive @include ("Included when true." if: Boolean!) on FIELD|FRAGMENT_SPREAD|INLINE_FRAGMENT +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ Directs the executor to skip this field or fragment when the `if` argument is true. """ directive @skip ("Skipped when true." if: Boolean!) on FIELD|FRAGMENT_SPREAD|INLINE_FRAGMENT +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ Marks an element of a GraphQL schema as no longer supported. """ directive @deprecated ("Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted using the Markdown syntax, as specified by [CommonMark](https:\/\/commonmark.org\/)." reason: String = "No longer supported") on FIELD_DEFINITION|ARGUMENT_DEFINITION|INPUT_FIELD_DEFINITION|ENUM_VALUE +# See https://github.com/JetBrains/js-graphql-intellij-plugin/issues/665 +# noinspection GraphQLTypeRedefinition """ Exposes a URL that specifies the behavior of this scalar. """ diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/FieldInsights.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/FieldInsights.kt index 0e2dcdde48d..a9d5306ff7e 100644 --- a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/FieldInsights.kt +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/FieldInsights.kt @@ -4,6 +4,7 @@ import com.apollographql.apollo3.annotations.ApolloExperimental import com.apollographql.apollo3.exception.ApolloGraphQLException import com.apollographql.apollo3.exception.ApolloHttpException import com.apollographql.apollo3.tooling.platformapi.internal.FieldLatenciesQuery +import java.time.Instant @ApolloExperimental object FieldInsights { @@ -27,7 +28,7 @@ object FieldInsights { val response = apolloClient.query( FieldLatenciesQuery( serviceId = serviceId, - fromTimestamp = -fromSeconds, + fromTimestamp = Instant.ofEpochSecond(Instant.now().epochSecond - fromSeconds), percentile = percentile, ) ).execute() diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/InternalPlatformApi.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/InternalPlatformApi.kt index 933b6fa7339..b83c69c102b 100644 --- a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/InternalPlatformApi.kt +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/InternalPlatformApi.kt @@ -5,13 +5,15 @@ import com.apollographql.apollo3.ApolloClient internal const val INTERNAL_PLATFORM_API_URL = "https://graphql.api.apollographql.com/api/graphql" internal fun newInternalPlatformApiApolloClient( - apiKey: String, + apiKey: String? = null, serverUrl: String = INTERNAL_PLATFORM_API_URL, ): ApolloClient { val apolloClient = ApolloClient.Builder() .serverUrl(serverUrl) .httpExposeErrorBody(true) - .addHttpHeader("x-api-key", apiKey) + .apply { + if (apiKey != null) addHttpHeader("x-api-key", apiKey) + } .build() return apolloClient } diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/RegisterOperations.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/RegisterOperations.kt index 850ab2906fe..8250868e576 100644 --- a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/RegisterOperations.kt +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/RegisterOperations.kt @@ -249,7 +249,7 @@ object RegisterOperations { ) }, manifestVersion = 2, - graphVariant = Optional.present(graphVariant) + graphVariant = graphVariant, ) ) diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/Telemetry.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/Telemetry.kt new file mode 100644 index 00000000000..31b6bac28f6 --- /dev/null +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/Telemetry.kt @@ -0,0 +1,74 @@ +package com.apollographql.apollo3.tooling + +import com.apollographql.apollo3.annotations.ApolloInternal +import com.apollographql.apollo3.api.Optional +import com.apollographql.apollo3.exception.ApolloGraphQLException +import com.apollographql.apollo3.exception.ApolloHttpException +import com.apollographql.apollo3.tooling.platformapi.internal.TrackApolloKotlinUsageMutation +import com.apollographql.apollo3.tooling.platformapi.internal.type.ApolloKotlinUsageEventInput +import com.apollographql.apollo3.tooling.platformapi.internal.type.ApolloKotlinUsagePropertyInput +import java.time.Instant + +@ApolloInternal +object Telemetry { + /** + * Track Apollo Kotlin usage. + */ + suspend fun trackApolloKotlinUsage( + serverUrl: String? = null, + instanceId: String, + properties: List, + events: List, + ): Result { + val apolloClient = newInternalPlatformApiApolloClient(serverUrl = serverUrl ?: INTERNAL_PLATFORM_API_URL) + val response = apolloClient.mutation( + TrackApolloKotlinUsageMutation( + instanceId = instanceId, + properties = properties.map { + ApolloKotlinUsagePropertyInput( + type = it.type, + payload = Optional.presentIfNotNull(it.payload), + ) + }, + events = events.map { + ApolloKotlinUsageEventInput( + type = it.type, + date = it.date, + payload = Optional.presentIfNotNull(it.payload), + ) + }, + ) + ).execute() + return when (val e = response.exception) { + null -> { + Result.success(Unit) + } + + is ApolloHttpException -> { + val body = e.body?.use { it.readUtf8() } ?: "" + Result.failure(Exception("Cannot track Apollo Kotlin usage: (code: ${e.statusCode})\n$body", e)) + } + + is ApolloGraphQLException -> { + Result.failure(Exception("Cannot track Apollo Kotlin usage: ${e.errors.joinToString { it.message }}")) + } + + else -> { + Result.failure(Exception("Cannot track Apollo Kotlin usage: ${e.message}", e)) + } + } + } + + @ApolloInternal + class TelemetryProperty( + val type: String, + val payload: Any?, + ) + + @ApolloInternal + class TelemetryEvent( + val type: String, + val date: Instant, + val payload: Any?, + ) +} diff --git a/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/TimestampAdapter.kt b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/TimestampAdapter.kt new file mode 100644 index 00000000000..2562697229d --- /dev/null +++ b/libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/TimestampAdapter.kt @@ -0,0 +1,18 @@ +package com.apollographql.apollo3.tooling + +import com.apollographql.apollo3.api.Adapter +import com.apollographql.apollo3.api.CustomScalarAdapters +import com.apollographql.apollo3.api.json.JsonReader +import com.apollographql.apollo3.api.json.JsonWriter +import java.time.Instant +import java.time.format.DateTimeFormatter + +internal object TimestampAdapter : Adapter { + override fun fromJson(reader: JsonReader, customScalarAdapters: CustomScalarAdapters): Instant { + return Instant.from(DateTimeFormatter.ISO_INSTANT.parse(reader.nextString())) + } + + override fun toJson(writer: JsonWriter, customScalarAdapters: CustomScalarAdapters, value: Instant) { + writer.value(DateTimeFormatter.ISO_INSTANT.format(value)) + } +}