diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index bf4ce5d0c..987233c0e 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Artemis.UI/ArtemisBootstrapper.cs b/src/Artemis.UI/ArtemisBootstrapper.cs index 1056070e1..c1dd988a9 100644 --- a/src/Artemis.UI/ArtemisBootstrapper.cs +++ b/src/Artemis.UI/ArtemisBootstrapper.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Reactive; -using System.Threading.Tasks; using Artemis.Core; using Artemis.Core.DryIoc; using Artemis.UI.DryIoc; @@ -12,7 +11,6 @@ using Artemis.UI.Shared.DataModelPicker; using Artemis.UI.Shared.DryIoc; using Artemis.UI.Shared.Services; using Artemis.VisualScripting.DryIoc; -using Artemis.WebClient.Updating; using Artemis.WebClient.Updating.DryIoc; using Avalonia; using Avalonia.Controls; diff --git a/src/Artemis.WebClient.Updating/.config/dotnet-tools.json b/src/Artemis.WebClient.Updating/.config/dotnet-tools.json new file mode 100644 index 000000000..7d8626c03 --- /dev/null +++ b/src/Artemis.WebClient.Updating/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "strawberryshake.tools": { + "version": "13.0.0-rc.4", + "commands": [ + "dotnet-graphql" + ] + } + } +} \ No newline at end of file diff --git a/src/Artemis.WebClient.Updating/.graphqlconfig b/src/Artemis.WebClient.Updating/.graphqlconfig new file mode 100644 index 000000000..727ec86a0 --- /dev/null +++ b/src/Artemis.WebClient.Updating/.graphqlconfig @@ -0,0 +1,15 @@ +{ + "name": "Untitled GraphQL Schema", + "schemaPath": "schema.graphql", + "extensions": { + "endpoints": { + "Default GraphQL Endpoint": { + "url": "https://updating.artemis-rgb.com/graphql", + "headers": { + "user-agent": "JS GraphQL" + }, + "introspect": true + } + } + } +} \ No newline at end of file diff --git a/src/Artemis.WebClient.Updating/.graphqlrc.json b/src/Artemis.WebClient.Updating/.graphqlrc.json new file mode 100644 index 000000000..d500e1cee --- /dev/null +++ b/src/Artemis.WebClient.Updating/.graphqlrc.json @@ -0,0 +1,22 @@ +{ + "schema": "schema.graphql", + "documents": "**/*.graphql", + "extensions": { + "strawberryShake": { + "name": "UpdatingClient", + "namespace": "Artemis.WebClient.Updating", + "url": "https://updating.artemis-rgb.com/graphql/", + "emitGeneratedCode": false, + "records": { + "inputs": false, + "entities": false + }, + "transportProfiles": [ + { + "default": "Http", + "subscription": "WebSocket" + } + ] + } + } +} \ No newline at end of file diff --git a/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj new file mode 100644 index 000000000..7f2bb002f --- /dev/null +++ b/src/Artemis.WebClient.Updating/Artemis.WebClient.Updating.csproj @@ -0,0 +1,16 @@ + + + + net6.0 + enable + enable + + + + + + + + + + diff --git a/src/Artemis.WebClient.Updating/DryIoc/ContainerExtensions.cs b/src/Artemis.WebClient.Updating/DryIoc/ContainerExtensions.cs new file mode 100644 index 000000000..e52e454d3 --- /dev/null +++ b/src/Artemis.WebClient.Updating/DryIoc/ContainerExtensions.cs @@ -0,0 +1,26 @@ +using DryIoc; +using DryIoc.Microsoft.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; + +namespace Artemis.WebClient.Updating.DryIoc; + +/// +/// Provides an extension method to register services onto a DryIoc . +/// +public static class ContainerExtensions +{ + /// + /// Registers the updating client into the container. + /// + /// The builder building the current container + public static void RegisterUpdatingClient(this IContainer container) + { + ServiceCollection serviceCollection = new(); + serviceCollection + .AddHttpClient() + .AddUpdatingClient() + .ConfigureHttpClient(client => client.BaseAddress = new Uri("https://updating.artemis-rgb.com/graphql")); + + container.WithDependencyInjectionAdapter(serviceCollection); + } +} \ No newline at end of file diff --git a/src/Artemis.WebClient.Updating/Queries/GetReleaseById.graphql b/src/Artemis.WebClient.Updating/Queries/GetReleaseById.graphql new file mode 100644 index 000000000..fa17ed4f0 --- /dev/null +++ b/src/Artemis.WebClient.Updating/Queries/GetReleaseById.graphql @@ -0,0 +1,16 @@ +query GetReleaseById { + release(id: "63b71dd69a5bb32a0a81a410") { + branch + commit + version + artifacts { + platform + artifactId + fileInfo { + md5Hash + downloadSize + downloads + } + } + } +} diff --git a/src/Artemis.WebClient.Updating/schema.extensions.graphql b/src/Artemis.WebClient.Updating/schema.extensions.graphql new file mode 100644 index 000000000..0b5fbd98b --- /dev/null +++ b/src/Artemis.WebClient.Updating/schema.extensions.graphql @@ -0,0 +1,13 @@ +scalar _KeyFieldSet + +directive @key(fields: _KeyFieldSet!) on SCHEMA | OBJECT + +directive @serializationType(name: String!) on SCALAR + +directive @runtimeType(name: String!) on SCALAR + +directive @enumValue(value: String!) on ENUM_VALUE + +directive @rename(name: String!) on INPUT_FIELD_DEFINITION | INPUT_OBJECT | ENUM | ENUM_VALUE + +extend schema @key(fields: "id") \ No newline at end of file diff --git a/src/Artemis.WebClient.Updating/schema.graphql b/src/Artemis.WebClient.Updating/schema.graphql new file mode 100644 index 000000000..8a4840e8e --- /dev/null +++ b/src/Artemis.WebClient.Updating/schema.graphql @@ -0,0 +1,262 @@ +# This file was generated based on ".graphqlconfig". Do not edit manually. + +schema { + query: Query + mutation: Mutation +} + +"The `@defer` directive may be provided for fragment spreads and inline fragments to inform the executor to delay the execution of the current fragment to indicate deprioritization of the current fragment. A query with `@defer` directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred is delivered in a subsequent response. `@include` and `@skip` take precedence over `@defer`." +directive @defer( + "Deferred when true." + if: Boolean, + "If this argument label has a value other than null, it will be passed on to the result of this defer directive. This label is intended to give client applications a way to identify to which fragment a deferred result belongs to." + label: String +) on FRAGMENT_SPREAD | INLINE_FRAGMENT + +"The `@stream` directive may be provided for a field of `List` type so that the backend can leverage technology such as asynchronous iterators to provide a partial list in the initial response, and additional list items in subsequent responses. `@include` and `@skip` take precedence over `@stream`." +directive @stream( + "Streamed when true." + if: Boolean, + "The initial elements that shall be send down to the consumer." + initialCount: Int! = 0, + "If this argument label has a value other than null, it will be passed on to the result of this stream directive. This label is intended to give client applications a way to identify to which fragment a streamed result belongs to." + label: String +) on FIELD + +directive @authorize( + "Defines when when the resolver shall be executed.By default the resolver is executed after the policy has determined that the current user is allowed to access the field." + apply: ApplyPolicy! = BEFORE_RESOLVER, + "The name of the authorization policy that determines access to the annotated resource." + policy: String, + "Roles that are allowed to access the annotated resource." + roles: [String!] +) on SCHEMA | OBJECT | FIELD_DEFINITION + +type ArtemisChannel { + branch: String! + releases: Int! +} + +type Artifact { + artifactId: Long! + deltaFileInfo: ArtifactFileInfo! + fileInfo: ArtifactFileInfo! + fileName(deltaFile: Boolean!): String! + platform: Platform! +} + +type ArtifactFileInfo { + downloadSize: Long! + downloads: Long! + md5Hash: String +} + +type Mutation { + updateReleaseChangelog(input: UpdateReleaseChangelogInput!): UpdateReleaseChangelogPayload! +} + +type Query { + channelByBranch(branch: String!): ArtemisChannel + channels: [ArtemisChannel!]! + nextRelease(branch: String!, platform: Platform!, version: String!): Release + release(id: String!): Release + releaseStatistics(order: [ReleaseStatisticSortInput!], where: ReleaseStatisticFilterInput): [ReleaseStatistic!]! + releases(order: [ReleaseSortInput!], where: ReleaseFilterInput): [Release!]! +} + +type Release { + artifacts: [Artifact!]! + branch: String! + changelog: String! + commit: String! + createdAt: DateTime! + id: String! + isDraft: Boolean! + previousRelease: String + version: String! + workflowRunId: Long! +} + +type ReleaseStatistic { + count: Int! + lastReportedUsage: DateTime! + linuxCount: Int! + oSXCount: Int! + releaseId: String! + windowsCount: Int! +} + +type UpdateReleaseChangelogPayload { + release: Release +} + +enum ApplyPolicy { + AFTER_RESOLVER + BEFORE_RESOLVER +} + +enum Platform { + LINUX + OSX + WINDOWS +} + +enum SortEnumType { + ASC + DESC +} + +"The `DateTime` scalar represents an ISO-8601 compliant date time type." +scalar DateTime + +"The `Long` scalar type represents non-fractional signed whole 64-bit numeric values. Long can represent values between -(2^63) and 2^63 - 1." +scalar Long + +input ArtifactFileInfoFilterInput { + and: [ArtifactFileInfoFilterInput!] + downloadSize: ComparableInt64OperationFilterInput + downloads: ComparableInt64OperationFilterInput + md5Hash: StringOperationFilterInput + or: [ArtifactFileInfoFilterInput!] +} + +input ArtifactFilterInput { + and: [ArtifactFilterInput!] + artifactId: ComparableInt64OperationFilterInput + deltaFileInfo: ArtifactFileInfoFilterInput + fileInfo: ArtifactFileInfoFilterInput + or: [ArtifactFilterInput!] + platform: PlatformOperationFilterInput +} + +input BooleanOperationFilterInput { + eq: Boolean + neq: Boolean +} + +input ComparableDateTimeOffsetOperationFilterInput { + eq: DateTime + gt: DateTime + gte: DateTime + in: [DateTime!] + lt: DateTime + lte: DateTime + neq: DateTime + ngt: DateTime + ngte: DateTime + nin: [DateTime!] + nlt: DateTime + nlte: DateTime +} + +input ComparableInt32OperationFilterInput { + eq: Int + gt: Int + gte: Int + in: [Int!] + lt: Int + lte: Int + neq: Int + ngt: Int + ngte: Int + nin: [Int!] + nlt: Int + nlte: Int +} + +input ComparableInt64OperationFilterInput { + eq: Long + gt: Long + gte: Long + in: [Long!] + lt: Long + lte: Long + neq: Long + ngt: Long + ngte: Long + nin: [Long!] + nlt: Long + nlte: Long +} + +input ListFilterInputTypeOfArtifactFilterInput { + all: ArtifactFilterInput + any: Boolean + none: ArtifactFilterInput + some: ArtifactFilterInput +} + +input PlatformOperationFilterInput { + eq: Platform + in: [Platform!] + neq: Platform + nin: [Platform!] +} + +input ReleaseFilterInput { + and: [ReleaseFilterInput!] + artifacts: ListFilterInputTypeOfArtifactFilterInput + branch: StringOperationFilterInput + changelog: StringOperationFilterInput + commit: StringOperationFilterInput + createdAt: ComparableDateTimeOffsetOperationFilterInput + id: StringOperationFilterInput + isDraft: BooleanOperationFilterInput + or: [ReleaseFilterInput!] + previousRelease: StringOperationFilterInput + version: StringOperationFilterInput + workflowRunId: ComparableInt64OperationFilterInput +} + +input ReleaseSortInput { + branch: SortEnumType + changelog: SortEnumType + commit: SortEnumType + createdAt: SortEnumType + id: SortEnumType + isDraft: SortEnumType + previousRelease: SortEnumType + version: SortEnumType + workflowRunId: SortEnumType +} + +input ReleaseStatisticFilterInput { + and: [ReleaseStatisticFilterInput!] + count: ComparableInt32OperationFilterInput + lastReportedUsage: ComparableDateTimeOffsetOperationFilterInput + linuxCount: ComparableInt32OperationFilterInput + oSXCount: ComparableInt32OperationFilterInput + or: [ReleaseStatisticFilterInput!] + releaseId: StringOperationFilterInput + windowsCount: ComparableInt32OperationFilterInput +} + +input ReleaseStatisticSortInput { + count: SortEnumType + lastReportedUsage: SortEnumType + linuxCount: SortEnumType + oSXCount: SortEnumType + releaseId: SortEnumType + windowsCount: SortEnumType +} + +input StringOperationFilterInput { + and: [StringOperationFilterInput!] + contains: String + endsWith: String + eq: String + in: [String] + ncontains: String + nendsWith: String + neq: String + nin: [String] + nstartsWith: String + or: [StringOperationFilterInput!] + startsWith: String +} + +input UpdateReleaseChangelogInput { + changelog: String! + id: String! + isDraft: Boolean! +} diff --git a/src/Artemis.sln b/src/Artemis.sln index dec26a200..2e53b5d9a 100644 --- a/src/Artemis.sln +++ b/src/Artemis.sln @@ -19,6 +19,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Artemis.UI.MacOS", "Artemis EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Artemis.VisualScripting", "Artemis.VisualScripting\Artemis.VisualScripting.csproj", "{412B921A-26F5-4AE6-8B32-0C19BE54F421}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis.WebClient.Updating", "Artemis.WebClient.Updating\Artemis.WebClient.Updating.csproj", "{7C8C6F50-0CC8-45B3-B608-A7218C005E4B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -57,6 +59,10 @@ Global {412B921A-26F5-4AE6-8B32-0C19BE54F421}.Debug|x64.Build.0 = Debug|x64 {412B921A-26F5-4AE6-8B32-0C19BE54F421}.Release|x64.ActiveCfg = Release|x64 {412B921A-26F5-4AE6-8B32-0C19BE54F421}.Release|x64.Build.0 = Release|x64 + {7C8C6F50-0CC8-45B3-B608-A7218C005E4B}.Debug|x64.ActiveCfg = Debug|Any CPU + {7C8C6F50-0CC8-45B3-B608-A7218C005E4B}.Debug|x64.Build.0 = Debug|Any CPU + {7C8C6F50-0CC8-45B3-B608-A7218C005E4B}.Release|x64.ActiveCfg = Release|Any CPU + {7C8C6F50-0CC8-45B3-B608-A7218C005E4B}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE