Main to dev (#18)
* Add Instances base (#6) * Use Uri for checks in GetAccounts function (#8) * Add integration and perf tests to sln (#9) * Remove perf tests (#10) * remove perf tests * do all unit tests * Code coverage (#11) * code coverage * enable codecov for GA * Update README.md * Update coverage and dependencies (#12) * Update coverage and dependencies * fmt * add codecov config * merge DUI3/Alpha into sdk (#13) * merge DUI3/Alpha into sdk * formatting * Merge Objects dui3/alpha -> dev (#14) * merge DUI3/Alpha into sdk * formatting * Objects changes * Objects tests * Unit test project * update codecov to be less intrusive (#15) * update codecov to be less intrusive * fix codecov yaml * add coverage exclusion * Merge sharp `dui3/alpha` -> sdk `main` (#16) * Merge * csharpier format * Fixed polysharp issues * Integration Tests * Fixes * Some nullability fixes (#17) * add coverage exclusion * fix some tests and fix nullability errors --------- Co-authored-by: Oğuzhan Koral <45078678+oguzhankoral@users.noreply.github.com> Co-authored-by: Jedd Morgan <45512892+JR-Morgan@users.noreply.github.com>
This commit is contained in:
@@ -19,8 +19,12 @@ jobs:
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-nuget-
|
||||
|
||||
- name: 🔫 Build All
|
||||
run: ./build.sh
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
files: tests/**/coverage.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -29,5 +29,11 @@ jobs:
|
||||
- name: 🔫 Build and Pack
|
||||
run: ./build.sh pack
|
||||
|
||||
- name: Upload coverage reports to Codecov with GitHub Action
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
files: tests/**/coverage.xml
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: Push to nuget.org
|
||||
run: dotnet nuget push output/*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.CONNECTORS_NUGET_TOKEN }} --skip-duplicate
|
||||
|
||||
+1
-1
@@ -18,4 +18,4 @@ tools
|
||||
|
||||
.DS_Store
|
||||
*.snupkg
|
||||
/tests/TestArchives/6d23a38c-f064-4ef1-ad89-b942396f53b9/Scratch
|
||||
coverage.xml
|
||||
@@ -1,5 +1,6 @@
|
||||
<Project>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="altcover" Version="8.8.74" />
|
||||
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageVersion Include="GraphQL.Client" Version="6.0.0" />
|
||||
<PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
@@ -14,16 +15,15 @@
|
||||
<PackageVersion Include="Serilog.Sinks.Console" Version="4.1.0" />
|
||||
<PackageVersion Include="Serilog.Sinks.Seq" Version="5.2.2" />
|
||||
<PackageVersion Include="SerilogTimings" Version="3.0.1" />
|
||||
<PackageVersion Include="Shouldly" Version="4.2.1" />
|
||||
<PackageVersion Include="Speckle.Newtonsoft.Json" Version="13.0.2" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="7.0.5" />
|
||||
<PackageVersion Include="System.DoubleNumerics" Version="3.1.3" />
|
||||
<PackageVersion Include="Speckle.DoubleNumerics" Version="4.0.1-alpha.3" />
|
||||
<PackageVersion Include="Microsoft.Data.Sqlite" Version="8.0.6" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
|
||||
<PackageVersion Include="NUnit3TestAdapter" Version="4.5.0" />
|
||||
<PackageVersion Include="Moq" Version="4.20.70" />
|
||||
<PackageVersion Include="NUnit" Version="4.1.0" />
|
||||
<PackageVersion Include="NUnit.Analyzers" Version="4.2.0" />
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
|
||||
<PackageVersion Include="JunitXml.TestLogger" Version="3.0.124" />
|
||||
<PackageVersion Include="Bullseye" Version="5.0.0" />
|
||||
<PackageVersion Include="Glob" Version="1.1.9" />
|
||||
<PackageVersion Include="SimpleExec" Version="12.0.0" />
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
[](https://twitter.com/SpeckleSystems) [](https://discourse.speckle.works) [](https://speckle.systems) [](https://speckle.guide/dev/)
|
||||
|
||||
[](https://codecov.io/gh/specklesystems/speckle-sharp-sdk)
|
||||
|
||||
## **Disclaimer**
|
||||
|
||||
This is an early alpha release, not meant for use in production! We're working to stabilise the 2.0 API, and until then there will be breaking changes. You have been warned!
|
||||
This is an early alpha release, not meant for use in production! We're working to stabilise the 3.0 API, and until then there will be breaking changes. You have been warned!
|
||||
|
||||
## Introduction
|
||||
|
||||
|
||||
@@ -32,6 +32,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Transports.MongoDB"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Core.Serialization.Tests", "tests\Speckle.Core.Serialization.Tests\Speckle.Core.Serialization.Tests.csproj", "{AA1E1E51-49AE-4F71-84B1-938E19695BE0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.Core.Tests.Integration", "tests\Speckle.Core.Tests.Integration\Speckle.Core.Tests.Integration.csproj", "{4FB41A6D-D139-4111-8115-E3F9F6BEAF24}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{B623BD21-5CAA-43F9-A539-1835276C220E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.github\workflows\main.yml = .github\workflows\main.yml
|
||||
.github\workflows\ci.yml = .github\workflows\ci.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -74,6 +82,10 @@ Global
|
||||
{AA1E1E51-49AE-4F71-84B1-938E19695BE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AA1E1E51-49AE-4F71-84B1-938E19695BE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AA1E1E51-49AE-4F71-84B1-938E19695BE0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4FB41A6D-D139-4111-8115-E3F9F6BEAF24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4FB41A6D-D139-4111-8115-E3F9F6BEAF24}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4FB41A6D-D139-4111-8115-E3F9F6BEAF24}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4FB41A6D-D139-4111-8115-E3F9F6BEAF24}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{A413E196-3696-4F48-B635-04B5F76BF9C9} = {5CB96C27-FC5B-4A41-86B6-951AF99B8116}
|
||||
@@ -84,5 +96,7 @@ Global
|
||||
{9B8DDEB5-37C7-49B5-984D-C65DE5FCB7B7} = {58D37DA9-F948-48CA-9A73-F5BBBD533DBF}
|
||||
{68078752-7C54-471A-9CB6-E8AEF34A9EFF} = {5CB96C27-FC5B-4A41-86B6-951AF99B8116}
|
||||
{AA1E1E51-49AE-4F71-84B1-938E19695BE0} = {35047EE7-AD1D-4741-80A7-8F0E874718E9}
|
||||
{4FB41A6D-D139-4111-8115-E3F9F6BEAF24} = {35047EE7-AD1D-4741-80A7-8F0E874718E9}
|
||||
{B623BD21-5CAA-43F9-A539-1835276C220E} = {DA2AED52-58F9-471E-8AD8-102FD36129E3}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
+7
-4
@@ -43,19 +43,22 @@ Target(FORMAT, DependsOn(RESTORE_TOOLS), () => RunAsync("dotnet", "csharpier --c
|
||||
|
||||
Target(RESTORE, () => RunAsync("dotnet", "restore Speckle.Sdk.sln --locked-mode"));
|
||||
|
||||
Target(BUILD, DependsOn(RESTORE), () => RunAsync("dotnet", $"build Speckle.Sdk.sln -c Release --no-restore"));
|
||||
Target(BUILD, DependsOn(RESTORE), () => RunAsync("dotnet", "build Speckle.Sdk.sln -c Release --no-restore"));
|
||||
|
||||
Target(
|
||||
TEST,
|
||||
DependsOn(BUILD),
|
||||
Glob.Files(".", "**/*.Tests.Unit.csproj"),
|
||||
Glob.Files(".", "**/*.Tests.Unit.csproj").Concat(Glob.Files(".", "**/*.Tests.csproj")),
|
||||
async file =>
|
||||
{
|
||||
await RunAsync("dotnet", $"test {file} -c Release --no-build --verbosity=normal");
|
||||
await RunAsync(
|
||||
"dotnet",
|
||||
$"test {file} -c Release --no-build --no-restore --verbosity=normal /p:AltCover=true /p:AltCoverAttributeFilter=ExcludeFromCodeCoverage"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Target(PACK, DependsOn(BUILD), () => RunAsync("dotnet", "pack Speckle.Sdk.sln -c Release -o output --no-build"));
|
||||
Target(PACK, DependsOn(TEST), () => RunAsync("dotnet", "pack Speckle.Sdk.sln -c Release -o output --no-build"));
|
||||
|
||||
Target("default", DependsOn(FORMAT, TEST), () => Console.WriteLine("Done!"));
|
||||
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
||||
target: auto
|
||||
threshold: 1%
|
||||
base: auto
|
||||
patch:
|
||||
default:
|
||||
informational: true
|
||||
github_checks:
|
||||
annotations: false
|
||||
@@ -9,50 +9,55 @@ namespace Speckle.Core.Api;
|
||||
/// <summary>
|
||||
/// Base class for GraphQL API exceptions
|
||||
/// </summary>
|
||||
public class SpeckleGraphQLException<T> : SpeckleException
|
||||
public class SpeckleGraphQLException<T> : SpeckleGraphQLException
|
||||
{
|
||||
private readonly GraphQLRequest _request;
|
||||
public GraphQLResponse<T>? Response { get; }
|
||||
public new GraphQLResponse<T>? Response => (GraphQLResponse<T>?)base.Response;
|
||||
|
||||
public SpeckleGraphQLException(string message, GraphQLRequest request, GraphQLResponse<T>? response)
|
||||
: base(message)
|
||||
{
|
||||
_request = request;
|
||||
Response = response;
|
||||
}
|
||||
|
||||
public SpeckleGraphQLException(string message, Exception inner, GraphQLRequest request, GraphQLResponse<T>? response)
|
||||
: this(message, inner)
|
||||
{
|
||||
_request = request;
|
||||
Response = response;
|
||||
}
|
||||
public SpeckleGraphQLException(
|
||||
string message,
|
||||
GraphQLRequest request,
|
||||
GraphQLResponse<T>? response,
|
||||
Exception? innerException = null
|
||||
)
|
||||
: base(message, request, response, innerException) { }
|
||||
|
||||
public SpeckleGraphQLException() { }
|
||||
|
||||
public SpeckleGraphQLException(string message)
|
||||
public SpeckleGraphQLException(string? message)
|
||||
: base(message) { }
|
||||
|
||||
public SpeckleGraphQLException(string message, Exception innerException)
|
||||
public SpeckleGraphQLException(string? message, Exception? innerException)
|
||||
: base(message, innerException) { }
|
||||
}
|
||||
|
||||
public class SpeckleGraphQLException : SpeckleException
|
||||
{
|
||||
private readonly GraphQLRequest _request;
|
||||
public IGraphQLResponse? Response { get; }
|
||||
|
||||
public IEnumerable<string> ErrorMessages =>
|
||||
Response?.Errors != null ? Response.Errors.Select(e => e.Message) : Enumerable.Empty<string>();
|
||||
|
||||
public IDictionary<string, object>? Extensions => Response?.Extensions;
|
||||
}
|
||||
|
||||
public class SpeckleGraphQLException : SpeckleGraphQLException<object>
|
||||
public SpeckleGraphQLException(
|
||||
string? message,
|
||||
GraphQLRequest request,
|
||||
IGraphQLResponse? response,
|
||||
Exception? innerException = null
|
||||
)
|
||||
: base(message, innerException)
|
||||
{
|
||||
public SpeckleGraphQLException(string message, GraphQLRequest request, GraphQLResponse<object>? response)
|
||||
: base(message, request, response) { }
|
||||
_request = request;
|
||||
Response = response;
|
||||
}
|
||||
|
||||
public SpeckleGraphQLException() { }
|
||||
|
||||
public SpeckleGraphQLException(string message)
|
||||
public SpeckleGraphQLException(string? message)
|
||||
: base(message) { }
|
||||
|
||||
public SpeckleGraphQLException(string message, Exception innerException)
|
||||
public SpeckleGraphQLException(string? message, Exception? innerException)
|
||||
: base(message, innerException) { }
|
||||
}
|
||||
|
||||
@@ -61,44 +66,56 @@ public class SpeckleGraphQLException : SpeckleGraphQLException<object>
|
||||
/// https://www.apollographql.com/docs/apollo-server/v2/data/errors/#unauthenticated
|
||||
/// https://www.apollographql.com/docs/apollo-server/v2/data/errors/#forbidden
|
||||
/// </summary>
|
||||
public class SpeckleGraphQLForbiddenException<T> : SpeckleGraphQLException<T>
|
||||
public class SpeckleGraphQLForbiddenException : SpeckleGraphQLException
|
||||
{
|
||||
public SpeckleGraphQLForbiddenException(GraphQLRequest request, GraphQLResponse<T> response)
|
||||
: base("Your request was forbidden", request, response) { }
|
||||
public SpeckleGraphQLForbiddenException(
|
||||
GraphQLRequest request,
|
||||
IGraphQLResponse response,
|
||||
Exception? innerException = null
|
||||
)
|
||||
: base("Your request was forbidden", request, response, innerException) { }
|
||||
|
||||
public SpeckleGraphQLForbiddenException() { }
|
||||
|
||||
public SpeckleGraphQLForbiddenException(string message)
|
||||
public SpeckleGraphQLForbiddenException(string? message)
|
||||
: base(message) { }
|
||||
|
||||
public SpeckleGraphQLForbiddenException(string message, Exception innerException)
|
||||
public SpeckleGraphQLForbiddenException(string? message, Exception? innerException)
|
||||
: base(message, innerException) { }
|
||||
}
|
||||
|
||||
public class SpeckleGraphQLInternalErrorException<T> : SpeckleGraphQLException<T>
|
||||
public class SpeckleGraphQLInternalErrorException : SpeckleGraphQLException
|
||||
{
|
||||
public SpeckleGraphQLInternalErrorException(GraphQLRequest request, GraphQLResponse<T> response)
|
||||
: base("Your request failed on the server side", request, response) { }
|
||||
public SpeckleGraphQLInternalErrorException(
|
||||
GraphQLRequest request,
|
||||
IGraphQLResponse response,
|
||||
Exception? innerException = null
|
||||
)
|
||||
: base("Your request failed on the server side", request, response, innerException) { }
|
||||
|
||||
public SpeckleGraphQLInternalErrorException() { }
|
||||
|
||||
public SpeckleGraphQLInternalErrorException(string message)
|
||||
public SpeckleGraphQLInternalErrorException(string? message)
|
||||
: base(message) { }
|
||||
|
||||
public SpeckleGraphQLInternalErrorException(string message, Exception innerException)
|
||||
public SpeckleGraphQLInternalErrorException(string? message, Exception? innerException)
|
||||
: base(message, innerException) { }
|
||||
}
|
||||
|
||||
public class SpeckleGraphQLStreamNotFoundException<TStreamData> : SpeckleGraphQLException<TStreamData>
|
||||
public class SpeckleGraphQLStreamNotFoundException : SpeckleGraphQLException
|
||||
{
|
||||
public SpeckleGraphQLStreamNotFoundException(GraphQLRequest request, GraphQLResponse<TStreamData> response)
|
||||
: base("Stream not found", request, response) { }
|
||||
public SpeckleGraphQLStreamNotFoundException(
|
||||
GraphQLRequest request,
|
||||
IGraphQLResponse response,
|
||||
Exception? innerException = null
|
||||
)
|
||||
: base("Stream not found", request, response, innerException) { }
|
||||
|
||||
public SpeckleGraphQLStreamNotFoundException() { }
|
||||
|
||||
public SpeckleGraphQLStreamNotFoundException(string message)
|
||||
public SpeckleGraphQLStreamNotFoundException(string? message)
|
||||
: base(message) { }
|
||||
|
||||
public SpeckleGraphQLStreamNotFoundException(string message, Exception innerException)
|
||||
public SpeckleGraphQLStreamNotFoundException(string? message, Exception? innerException)
|
||||
: base(message, innerException) { }
|
||||
}
|
||||
|
||||
-250
@@ -1,250 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
|
||||
[SuppressMessage("Design", "CA1068:CancellationToken parameters must come last")]
|
||||
public partial class Client
|
||||
{
|
||||
#region Stream Grant Permission
|
||||
|
||||
/// <summary>
|
||||
/// Grants permissions to a user on a given stream.
|
||||
/// </summary>
|
||||
/// <param name="permissionInput"></param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Please use the `StreamUpdatePermission` method", true)]
|
||||
public Task<bool> StreamGrantPermission(StreamPermissionInput permissionInput)
|
||||
{
|
||||
return StreamGrantPermission(CancellationToken.None, permissionInput);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Grants permissions to a user on a given stream.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <param name="permissionInput"></param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Please use the `StreamUpdatePermission` method", true)]
|
||||
public async Task<bool> StreamGrantPermission(
|
||||
CancellationToken cancellationToken,
|
||||
StreamPermissionInput permissionInput
|
||||
)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
{
|
||||
Query =
|
||||
@"
|
||||
mutation streamGrantPermission($permissionParams: StreamGrantPermissionInput!) {
|
||||
streamGrantPermission(permissionParams:$permissionParams)
|
||||
}",
|
||||
Variables = new { permissionParams = permissionInput }
|
||||
};
|
||||
|
||||
var res = await ExecuteGraphQLRequest<Dictionary<string, object>>(request, cancellationToken).ConfigureAwait(false);
|
||||
return (bool)res["streamGrantPermission"];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Cancellation token as last param
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<List<ActivityItem>> StreamGetActivity(
|
||||
CancellationToken cancellationToken,
|
||||
string id,
|
||||
DateTime? after = null,
|
||||
DateTime? before = null,
|
||||
DateTime? cursor = null,
|
||||
string actionType = "",
|
||||
int limit = 25
|
||||
)
|
||||
{
|
||||
return StreamGetActivity(id, after, before, cursor, actionType, limit, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<List<Branch>> StreamGetBranches(
|
||||
CancellationToken cancellationToken,
|
||||
string streamId,
|
||||
int branchesLimit = 10,
|
||||
int commitsLimit = 10
|
||||
)
|
||||
{
|
||||
return StreamGetBranches(streamId, branchesLimit, commitsLimit, CancellationToken.None);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<string> BranchCreate(CancellationToken cancellationToken, BranchCreateInput branchInput)
|
||||
{
|
||||
return BranchCreate(branchInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<Branch> BranchGet(
|
||||
CancellationToken cancellationToken,
|
||||
string streamId,
|
||||
string branchName,
|
||||
int commitsLimit = 10
|
||||
)
|
||||
{
|
||||
return BranchGet(streamId, branchName, commitsLimit, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<bool> BranchUpdate(CancellationToken cancellationToken, BranchUpdateInput branchInput)
|
||||
{
|
||||
return BranchUpdate(branchInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<bool> BranchDelete(CancellationToken cancellationToken, BranchDeleteInput branchInput)
|
||||
{
|
||||
return BranchDelete(branchInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<Comments> StreamGetComments(
|
||||
CancellationToken cancellationToken,
|
||||
string streamId,
|
||||
int limit = 25,
|
||||
string? cursor = null
|
||||
)
|
||||
{
|
||||
return StreamGetComments(streamId, limit, cursor, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<string> StreamGetCommentScreenshot(CancellationToken cancellationToken, string id, string streamId)
|
||||
{
|
||||
return StreamGetCommentScreenshot(id, streamId, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<Commit> CommitGet(CancellationToken cancellationToken, string streamId, string commitId)
|
||||
{
|
||||
return CommitGet(streamId, commitId, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<List<Commit>> StreamGetCommits(CancellationToken cancellationToken, string streamId, int limit = 10)
|
||||
{
|
||||
return StreamGetCommits(streamId, limit, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<string> CommitCreate(CancellationToken cancellationToken, CommitCreateInput commitInput)
|
||||
{
|
||||
return CommitCreate(commitInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<bool> CommitUpdate(CancellationToken cancellationToken, CommitUpdateInput commitInput)
|
||||
{
|
||||
return CommitUpdate(commitInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<bool> CommitDelete(CancellationToken cancellationToken, CommitDeleteInput commitInput)
|
||||
{
|
||||
return CommitDelete(commitInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<bool> CommitReceived(CancellationToken cancellationToken, CommitReceivedInput commitReceivedInput)
|
||||
{
|
||||
return CommitReceived(commitReceivedInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<SpeckleObject> ObjectGet(CancellationToken cancellationToken, string streamId, string objectId)
|
||||
{
|
||||
return ObjectGet(streamId, objectId, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<SpeckleObject> ObjectCountGet(CancellationToken cancellationToken, string streamId, string objectId)
|
||||
{
|
||||
return ObjectCountGet(streamId, objectId, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<Stream> StreamGet(CancellationToken cancellationToken, string id, int branchesLimit = 10)
|
||||
{
|
||||
return StreamGet(id, branchesLimit, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<List<Stream>> StreamsGet(CancellationToken cancellationToken, int limit = 10)
|
||||
{
|
||||
return StreamsGet(limit, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<List<Stream>> FavoriteStreamsGet(CancellationToken cancellationToken, int limit = 10)
|
||||
{
|
||||
return FavoriteStreamsGet(limit, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<List<Stream>> StreamSearch(CancellationToken cancellationToken, string query, int limit = 10)
|
||||
{
|
||||
return StreamSearch(query, limit, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<string> StreamCreate(CancellationToken cancellationToken, StreamCreateInput streamInput)
|
||||
{
|
||||
return StreamCreate(streamInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<bool> StreamUpdate(CancellationToken cancellationToken, StreamUpdateInput streamInput)
|
||||
{
|
||||
return StreamUpdate(streamInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<bool> StreamDelete(CancellationToken cancellationToken, string id)
|
||||
{
|
||||
return StreamDelete(id, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<bool> StreamRevokePermission(
|
||||
CancellationToken cancellationToken,
|
||||
StreamRevokePermissionInput permissionInput
|
||||
)
|
||||
{
|
||||
return StreamRevokePermission(permissionInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<Stream> StreamGetPendingCollaborators(CancellationToken cancellationToken, string id)
|
||||
{
|
||||
return StreamGetPendingCollaborators(id, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<bool> StreamInviteCreate(CancellationToken cancellationToken, StreamInviteCreateInput inviteCreateInput)
|
||||
{
|
||||
return StreamInviteCreate(inviteCreateInput, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<LimitedUser?> OtherUserGet(CancellationToken cancellationToken, string id)
|
||||
{
|
||||
return OtherUserGet(id, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("Use overload with cancellation token parameter last")]
|
||||
public Task<List<LimitedUser>> UserSearch(CancellationToken cancellationToken, string query, int limit = 10)
|
||||
{
|
||||
return UserSearch(query, limit, cancellationToken);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
|
||||
public partial class Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the currently active user profile.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<User> ActiveUserGet(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
{
|
||||
Query =
|
||||
@"query User {
|
||||
activeUser {
|
||||
id,
|
||||
email,
|
||||
name,
|
||||
bio,
|
||||
company,
|
||||
avatar,
|
||||
verified,
|
||||
profiles,
|
||||
role,
|
||||
}
|
||||
}"
|
||||
};
|
||||
return (await ExecuteGraphQLRequest<ActiveUserData>(request, cancellationToken).ConfigureAwait(false)).activeUser;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get another user's profile by its user id.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the user you are looking for</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<LimitedUser?> OtherUserGet(string id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
{
|
||||
Query =
|
||||
@"query LimitedUser($id: String!) {
|
||||
otherUser(id: $id){
|
||||
id,
|
||||
name,
|
||||
bio,
|
||||
company,
|
||||
avatar,
|
||||
verified,
|
||||
role,
|
||||
}
|
||||
}",
|
||||
Variables = new { id }
|
||||
};
|
||||
return (await ExecuteGraphQLRequest<LimitedUserData>(request, cancellationToken).ConfigureAwait(false)).otherUser;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for a user on the server.
|
||||
/// </summary>
|
||||
/// <param name="query">String to search for. Must be at least 3 characters</param>
|
||||
/// <param name="limit">Max number of users to return</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<LimitedUser>> UserSearch(
|
||||
string query,
|
||||
int limit = 10,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
{
|
||||
Query =
|
||||
@"query UserSearch($query: String!, $limit: Int!) {
|
||||
userSearch(query: $query, limit: $limit) {
|
||||
cursor,
|
||||
items {
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
}",
|
||||
Variables = new { query, limit }
|
||||
};
|
||||
return (await ExecuteGraphQLRequest<UserSearchData>(request, cancellationToken).ConfigureAwait(false))
|
||||
.userSearch
|
||||
.items;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,9 @@ using Polly.Contrib.WaitAndRetry;
|
||||
using Serilog.Context;
|
||||
using Serilog.Core;
|
||||
using Serilog.Core.Enrichers;
|
||||
using Serilog.Events;
|
||||
using Speckle.Core.Api.GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Resources;
|
||||
using Speckle.Core.Api.GraphQL.Serializer;
|
||||
using Speckle.Core.Credentials;
|
||||
using Speckle.Core.Helpers;
|
||||
@@ -23,71 +26,55 @@ using Speckle.Newtonsoft.Json;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
|
||||
public sealed partial class Client : IDisposable
|
||||
public sealed partial class Client : ISpeckleGraphQLClient, IDisposable
|
||||
{
|
||||
[Obsolete]
|
||||
internal Client() { }
|
||||
|
||||
public Client(Account account)
|
||||
{
|
||||
Account = account ?? throw new SpeckleException("Provided account is null.");
|
||||
|
||||
HttpClient = Http.GetHttpProxyClient(null, TimeSpan.FromSeconds(30));
|
||||
Http.AddAuthHeader(HttpClient, account.token);
|
||||
|
||||
HttpClient.DefaultRequestHeaders.Add("apollographql-client-name", Setup.HostApplication);
|
||||
HttpClient.DefaultRequestHeaders.Add(
|
||||
"apollographql-client-version",
|
||||
Assembly.GetExecutingAssembly().GetName().Version.ToString()
|
||||
);
|
||||
|
||||
GQLClient = new GraphQLHttpClient(
|
||||
new GraphQLHttpClientOptions
|
||||
{
|
||||
EndPoint = new Uri(new Uri(account.serverInfo.url), "/graphql"),
|
||||
UseWebSocketForQueriesAndMutations = false,
|
||||
WebSocketProtocol = "graphql-ws",
|
||||
ConfigureWebSocketConnectionInitPayload = _ =>
|
||||
{
|
||||
return Http.CanAddAuth(account.token, out string? authValue) ? new { Authorization = authValue } : null;
|
||||
},
|
||||
},
|
||||
new NewtonsoftJsonSerializer(),
|
||||
HttpClient
|
||||
);
|
||||
|
||||
GQLClient.WebSocketReceiveErrors.Subscribe(e =>
|
||||
{
|
||||
if (e is WebSocketException we)
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"WebSocketException: {we.Message} (WebSocketError {we.WebSocketErrorCode}, ErrorCode {we.ErrorCode}, NativeErrorCode {we.NativeErrorCode}"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Exception in websocket receive stream: {e}");
|
||||
}
|
||||
});
|
||||
}
|
||||
public ProjectResource Project { get; }
|
||||
public ModelResource Model { get; }
|
||||
public VersionResource Version { get; }
|
||||
public ActiveUserResource ActiveUser { get; }
|
||||
public OtherUserResource OtherUser { get; }
|
||||
public ProjectInviteResource ProjectInvite { get; }
|
||||
public CommentResource Comment { get; }
|
||||
public SubscriptionResource Subscription { get; }
|
||||
|
||||
public string ServerUrl => Account.serverInfo.url;
|
||||
|
||||
public string ApiToken => Account.token;
|
||||
|
||||
public System.Version? ServerVersion { get; set; }
|
||||
public System.Version? ServerVersion { get; private set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Account Account { get; set; }
|
||||
public Account Account { get; }
|
||||
|
||||
private HttpClient HttpClient { get; set; }
|
||||
private HttpClient HttpClient { get; }
|
||||
|
||||
public GraphQLHttpClient GQLClient { get; set; }
|
||||
public GraphQLHttpClient GQLClient { get; }
|
||||
|
||||
/// <param name="account"></param>
|
||||
/// <exception cref="ArgumentException"><paramref name="account"/> was null</exception>
|
||||
public Client(Account account)
|
||||
{
|
||||
Account = account ?? throw new ArgumentException("Provided account is null.");
|
||||
|
||||
Project = new(this);
|
||||
Model = new(this);
|
||||
Version = new(this);
|
||||
ActiveUser = new(this);
|
||||
OtherUser = new(this);
|
||||
ProjectInvite = new(this);
|
||||
Comment = new(this);
|
||||
Subscription = new(this);
|
||||
|
||||
HttpClient = CreateHttpClient(account);
|
||||
|
||||
GQLClient = CreateGraphQLClient(account, HttpClient);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
Subscription.Dispose();
|
||||
UserStreamAddedSubscription?.Dispose();
|
||||
UserStreamRemovedSubscription?.Dispose();
|
||||
StreamUpdatedSubscription?.Dispose();
|
||||
@@ -116,18 +103,14 @@ public sealed partial class Client : IDisposable
|
||||
|
||||
var delay = Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromSeconds(1), 5);
|
||||
var graphqlRetry = Policy
|
||||
.Handle<SpeckleGraphQLInternalErrorException<T>>()
|
||||
.Handle<SpeckleGraphQLInternalErrorException>()
|
||||
.WaitAndRetryAsync(
|
||||
delay,
|
||||
(ex, timeout, context) =>
|
||||
(ex, timeout, _) =>
|
||||
{
|
||||
var graphqlEx = (SpeckleGraphQLException<T>)ex;
|
||||
SpeckleLog
|
||||
.Logger.ForContext("graphqlExtensions", graphqlEx.Extensions)
|
||||
.ForContext("graphqlErrorMessages", graphqlEx.ErrorMessages)
|
||||
.Warning(
|
||||
SpeckleLog.Logger.Debug(
|
||||
ex,
|
||||
"The previous attempt at executing function to get {resultType} failed with {exceptionMessage}. Retrying after {timeout}.",
|
||||
"The previous attempt at executing function to get {resultType} failed with {exceptionMessage}. Retrying after {timeout}",
|
||||
typeof(T).Name,
|
||||
ex.Message,
|
||||
timeout
|
||||
@@ -138,20 +121,16 @@ public sealed partial class Client : IDisposable
|
||||
return await graphqlRetry.ExecuteAsync(func).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <exception cref="SpeckleGraphQLForbiddenException{T}">"FORBIDDEN" on "UNAUTHORIZED" response from server</exception>
|
||||
/// <exception cref="SpeckleGraphQLException{T}">All other request errors</exception>
|
||||
/// <exception cref="OperationCanceledException">The <paramref name="cancellationToken"/> requested a cancel</exception>
|
||||
/// <inheritdoc/>
|
||||
public async Task<T> ExecuteGraphQLRequest<T>(GraphQLRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
using IDisposable context0 = LogContext.Push(CreateEnrichers<T>(request));
|
||||
var timer = Stopwatch.StartNew();
|
||||
|
||||
SpeckleLog.Logger.Debug("Starting execution of graphql request to get {resultType}", typeof(T).Name);
|
||||
var timer = new Stopwatch();
|
||||
var success = false;
|
||||
timer.Start();
|
||||
Exception? exception = null;
|
||||
try
|
||||
{
|
||||
var result = await ExecuteWithResiliencePolicies(async () =>
|
||||
return await ExecuteWithResiliencePolicies(async () =>
|
||||
{
|
||||
GraphQLResponse<T> result = await GQLClient
|
||||
.SendMutationAsync<T>(request, cancellationToken)
|
||||
@@ -160,58 +139,28 @@ public sealed partial class Client : IDisposable
|
||||
return result.Data;
|
||||
})
|
||||
.ConfigureAwait(false);
|
||||
success = true;
|
||||
return result;
|
||||
}
|
||||
// cancellations are bubbling up with no logging
|
||||
catch (OperationCanceledException)
|
||||
catch (Exception ex)
|
||||
{
|
||||
exception = ex;
|
||||
throw;
|
||||
}
|
||||
// we catch forbidden to rethrow, making sure its not logged.
|
||||
catch (SpeckleGraphQLForbiddenException<T>)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
// anything else related to graphql gets logged
|
||||
catch (SpeckleGraphQLException<T> gqlException)
|
||||
{
|
||||
SpeckleLog
|
||||
.Logger.ForContext("graphqlResponse", gqlException.Response)
|
||||
.ForContext("graphqlExtensions", gqlException.Extensions)
|
||||
.ForContext("graphqlErrorMessages", gqlException.ErrorMessages.ToList())
|
||||
.Warning(
|
||||
gqlException,
|
||||
"Execution of the graphql request to get {resultType} failed with {graphqlExceptionType} {exceptionMessage}.",
|
||||
typeof(T).Name,
|
||||
gqlException.GetType().Name,
|
||||
gqlException.Message
|
||||
);
|
||||
throw;
|
||||
}
|
||||
// we log and wrap anything that is not a graphql exception.
|
||||
// this makes sure, that any graphql operation only throws SpeckleGraphQLExceptions
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
SpeckleLog.Logger.Warning(
|
||||
ex,
|
||||
"Execution of the graphql request to get {resultType} failed without a graphql response. Cause {exceptionMessage}",
|
||||
typeof(T).Name,
|
||||
ex.Message
|
||||
);
|
||||
throw new SpeckleGraphQLException<T>("The graphql request failed without a graphql response", ex, request, null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// this is a performance metric log operation
|
||||
// this makes sure that both success and failed operations report
|
||||
// the same performance log
|
||||
timer.Stop();
|
||||
var status = success ? "succeeded" : "failed";
|
||||
SpeckleLog.Logger.Information(
|
||||
"Execution of graphql request to get {resultType} {resultStatus} after {elapsed} seconds",
|
||||
LogEventLevel logLevel = exception switch
|
||||
{
|
||||
null => LogEventLevel.Information,
|
||||
OperationCanceledException
|
||||
=> cancellationToken.IsCancellationRequested ? LogEventLevel.Debug : LogEventLevel.Error,
|
||||
SpeckleException => LogEventLevel.Warning,
|
||||
_ => LogEventLevel.Error,
|
||||
};
|
||||
SpeckleLog.Logger.Write(
|
||||
logLevel,
|
||||
exception,
|
||||
"Execution of the graphql request to get {resultType} completed with success:{status} after {elapsed} seconds",
|
||||
typeof(T).Name,
|
||||
status,
|
||||
exception is null,
|
||||
timer.Elapsed.TotalSeconds
|
||||
);
|
||||
}
|
||||
@@ -235,7 +184,7 @@ public sealed partial class Client : IDisposable
|
||||
)
|
||||
)
|
||||
{
|
||||
throw new SpeckleGraphQLForbiddenException<T>(request, response);
|
||||
throw new SpeckleGraphQLForbiddenException(request, response);
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -244,7 +193,7 @@ public sealed partial class Client : IDisposable
|
||||
)
|
||||
)
|
||||
{
|
||||
throw new SpeckleGraphQLStreamNotFoundException<T>(request, response);
|
||||
throw new SpeckleGraphQLStreamNotFoundException(request, response);
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -254,7 +203,7 @@ public sealed partial class Client : IDisposable
|
||||
)
|
||||
)
|
||||
{
|
||||
throw new SpeckleGraphQLInternalErrorException<T>(request, response);
|
||||
throw new SpeckleGraphQLInternalErrorException(request, response);
|
||||
}
|
||||
|
||||
throw new SpeckleGraphQLException<T>("Request failed with errors", request, response);
|
||||
@@ -296,6 +245,10 @@ public sealed partial class Client : IDisposable
|
||||
};
|
||||
}
|
||||
|
||||
IDisposable ISpeckleGraphQLClient.SubscribeTo<T>(GraphQLRequest request, Action<object, T> callback) =>
|
||||
SubscribeTo(request, callback);
|
||||
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.SubscribeTo{T}"/>
|
||||
internal IDisposable SubscribeTo<T>(GraphQLRequest request, Action<object, T> callback)
|
||||
{
|
||||
using (LogContext.Push(CreateEnrichers<T>(request)))
|
||||
@@ -322,7 +275,7 @@ public sealed partial class Client : IDisposable
|
||||
}
|
||||
}
|
||||
// we catch forbidden to rethrow, making sure its not logged.
|
||||
catch (SpeckleGraphQLForbiddenException<T>)
|
||||
catch (SpeckleGraphQLForbiddenException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
@@ -353,7 +306,7 @@ public sealed partial class Client : IDisposable
|
||||
// so far we've swallowed these errors
|
||||
SpeckleLog.Logger.Error(
|
||||
ex,
|
||||
"Subscription request for {resultType} failed with {exceptionMessage}",
|
||||
"Subscription for {resultType} terminated unexpectedly with {exceptionMessage}",
|
||||
typeof(T).Name,
|
||||
ex.Message
|
||||
);
|
||||
@@ -372,11 +325,57 @@ public sealed partial class Client : IDisposable
|
||||
);
|
||||
throw new SpeckleGraphQLException<T>(
|
||||
"The graphql request failed without a graphql response",
|
||||
ex,
|
||||
request,
|
||||
null
|
||||
null,
|
||||
ex
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static GraphQLHttpClient CreateGraphQLClient(Account account, HttpClient httpClient)
|
||||
{
|
||||
var gQLClient = new GraphQLHttpClient(
|
||||
new GraphQLHttpClientOptions
|
||||
{
|
||||
EndPoint = new Uri(new Uri(account.serverInfo.url), "/graphql"),
|
||||
UseWebSocketForQueriesAndMutations = false,
|
||||
WebSocketProtocol = "graphql-ws",
|
||||
ConfigureWebSocketConnectionInitPayload = _ =>
|
||||
{
|
||||
return Http.CanAddAuth(account.token, out string? authValue) ? new { Authorization = authValue } : null;
|
||||
},
|
||||
},
|
||||
new NewtonsoftJsonSerializer(),
|
||||
httpClient
|
||||
);
|
||||
|
||||
gQLClient.WebSocketReceiveErrors.Subscribe(e =>
|
||||
{
|
||||
if (e is WebSocketException we)
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"WebSocketException: {we.Message} (WebSocketError {we.WebSocketErrorCode}, ErrorCode {we.ErrorCode}, NativeErrorCode {we.NativeErrorCode}"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Exception in websocket receive stream: {e}");
|
||||
}
|
||||
});
|
||||
return gQLClient;
|
||||
}
|
||||
|
||||
private static HttpClient CreateHttpClient(Account account)
|
||||
{
|
||||
var httpClient = Http.GetHttpProxyClient(null, TimeSpan.FromSeconds(30));
|
||||
Http.AddAuthHeader(httpClient, account.token);
|
||||
|
||||
httpClient.DefaultRequestHeaders.Add("apollographql-client-name", Setup.HostApplication);
|
||||
httpClient.DefaultRequestHeaders.Add(
|
||||
"apollographql-client-version",
|
||||
Assembly.GetExecutingAssembly().GetName().Version.ToString()
|
||||
);
|
||||
return httpClient;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
//This enum isn't explicitly defined in the schema, instead its usages are int typed (But represent an enum)
|
||||
public enum FileUploadConversionStatus
|
||||
{
|
||||
Queued = 0,
|
||||
Processing = 1,
|
||||
Success = 2,
|
||||
Error = 3,
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
public enum ProjectCommentsUpdatedMessageType
|
||||
{
|
||||
ARCHIVED,
|
||||
CREATED,
|
||||
UPDATED,
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
public enum ProjectFileImportUpdatedMessageType
|
||||
{
|
||||
CREATED,
|
||||
UPDATED,
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
public enum ProjectModelsUpdatedMessageType
|
||||
{
|
||||
CREATED,
|
||||
DELETED,
|
||||
UPDATED,
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
public enum ProjectPendingModelsUpdatedMessageType
|
||||
{
|
||||
CREATED,
|
||||
UPDATED,
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
public enum ProjectUpdatedMessageType
|
||||
{
|
||||
DELETED,
|
||||
UPDATED,
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
public enum ProjectVersionsUpdatedMessageType
|
||||
{
|
||||
CREATED,
|
||||
DELETED,
|
||||
UPDATED,
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
public enum ProjectVisibility
|
||||
{
|
||||
Private,
|
||||
Public,
|
||||
Unlisted
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
public enum ResourceType
|
||||
{
|
||||
commit,
|
||||
stream,
|
||||
@object,
|
||||
comment
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
public enum UserProjectsUpdatedMessageType
|
||||
{
|
||||
ADDED,
|
||||
REMOVED,
|
||||
}
|
||||
@@ -3,6 +3,8 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using GraphQL.Client.Http;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL;
|
||||
|
||||
@@ -13,7 +15,7 @@ public static class GraphQLHttpClientExtensions
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">[Optional] defaults to an empty cancellation token</param>
|
||||
/// <returns><see cref="Version"/> object excluding any strings (eg "2.7.2-alpha.6995" becomes "2.7.2.6995")</returns>
|
||||
/// <exception cref="SpeckleGraphQLException"></exception>
|
||||
/// <exception cref="SpeckleGraphQLException{ServerInfoResponse}"></exception>
|
||||
public static async Task<System.Version> GetServerVersion(
|
||||
this GraphQLHttpClient client,
|
||||
CancellationToken cancellationToken = default
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL;
|
||||
|
||||
internal interface ISpeckleGraphQLClient
|
||||
{
|
||||
/// <exception cref="SpeckleGraphQLForbiddenException">"FORBIDDEN" on "UNAUTHORIZED" response from server</exception>
|
||||
/// <exception cref="SpeckleGraphQLException">All other request errors</exception>
|
||||
/// <exception cref="OperationCanceledException">The <paramref name="cancellationToken"/> requested a cancel</exception>
|
||||
/// <exception cref="ObjectDisposedException">This <see cref="Client"/> already been disposed</exception>
|
||||
internal Task<T> ExecuteGraphQLRequest<T>(GraphQLRequest request, CancellationToken cancellationToken);
|
||||
|
||||
/// <exception cref="SpeckleGraphQLForbiddenException">"FORBIDDEN" on "UNAUTHORIZED" response from server</exception>
|
||||
/// <exception cref="SpeckleGraphQLException">All other request errors</exception>
|
||||
/// <exception cref="ObjectDisposedException">This <see cref="Client"/> already been disposed</exception>
|
||||
internal IDisposable SubscribeTo<T>(GraphQLRequest request, Action<object, T> callback);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Inputs;
|
||||
|
||||
public sealed record CreateCommentInput(
|
||||
CommentContentInput content,
|
||||
string projectId,
|
||||
string resourceIdString,
|
||||
string? screenshot,
|
||||
object? viewerState
|
||||
);
|
||||
|
||||
public sealed record EditCommentInput(CommentContentInput content, string commentId);
|
||||
|
||||
public sealed record CreateCommentReplyInput(CommentContentInput content, string threadId);
|
||||
|
||||
public sealed record CommentContentInput(IReadOnlyCollection<string>? blobIds, object? doc);
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Inputs;
|
||||
|
||||
public sealed record CreateModelInput(string name, string? description, string projectId);
|
||||
|
||||
public sealed record DeleteModelInput(string id, string projectId);
|
||||
|
||||
public sealed record UpdateModelInput(string id, string? name, string? description, string projectId);
|
||||
|
||||
public sealed record ModelVersionsFilter(IReadOnlyList<string> priorityIds, bool? priorityIdsOnly);
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
using Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Inputs;
|
||||
|
||||
public sealed record ProjectCommentsFilter(bool? includeArchived, bool? loadedVersionsOnly, string? resourceIdString);
|
||||
|
||||
public sealed record ProjectCreateInput(string? name, string? description, ProjectVisibility? visibility);
|
||||
|
||||
public sealed record ProjectInviteCreateInput(string? email, string? role, string? serverRole, string? userId);
|
||||
|
||||
public sealed record ProjectInviteUseInput(bool accept, string projectId, string token);
|
||||
|
||||
public sealed record ProjectModelsFilter(
|
||||
IReadOnlyList<string>? contributors,
|
||||
IReadOnlyList<string>? excludeIds,
|
||||
IReadOnlyList<string>? ids,
|
||||
bool? onlyWithVersions,
|
||||
string? search,
|
||||
IReadOnlyList<string> sourceApps
|
||||
);
|
||||
|
||||
public sealed record ProjectModelsTreeFilter(
|
||||
IReadOnlyList<string>? contributors,
|
||||
string? search,
|
||||
IReadOnlyList<string>? sourceApps
|
||||
);
|
||||
|
||||
public sealed record ProjectUpdateInput(
|
||||
string id,
|
||||
string? name = null,
|
||||
string? description = null,
|
||||
bool? allowPublicComments = null,
|
||||
ProjectVisibility? visibility = null
|
||||
);
|
||||
|
||||
public sealed record ProjectUpdateRoleInput(string userId, string projectId, string? role);
|
||||
|
||||
public sealed record UserProjectsFilter(string search, IReadOnlyList<string>? onlyWithRoles = null);
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Inputs;
|
||||
|
||||
public sealed record ViewerUpdateTrackingTarget(
|
||||
string projectId,
|
||||
string resourceIdString,
|
||||
bool? loadedVersionsOnly = null
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Inputs;
|
||||
|
||||
public sealed record UpdateVersionInput(string versionId, string? message);
|
||||
|
||||
public sealed record MoveVersionsInput(string targetModelName, IReadOnlyList<string> versionIds);
|
||||
|
||||
public sealed record DeleteVersionsInput(IReadOnlyList<string> versionIds);
|
||||
+2
-1
@@ -8,6 +8,7 @@ namespace Speckle.Core.Api;
|
||||
|
||||
public partial class Client
|
||||
{
|
||||
//TODO: API gap
|
||||
/// <summary>
|
||||
/// Gets the activity of a stream
|
||||
/// </summary>
|
||||
@@ -25,7 +26,7 @@ public partial class Client
|
||||
DateTime? before = null,
|
||||
DateTime? cursor = null,
|
||||
string actionType = "",
|
||||
int limit = 25,
|
||||
int limit = ServerLimits.DEFAULT_PAGINATION_REQUEST,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
+20
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
|
||||
@@ -14,6 +16,9 @@ public partial class Client
|
||||
/// <param name="streamId">Id of the stream to get the branches from</param>
|
||||
/// <param name="commitsLimit">Max number of commits to retrieve</param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectResource.GetWithModels"/>
|
||||
/// <seealso cref="GraphQL.Resources.ModelResource.GetModels"/>
|
||||
[Obsolete($"Use client.{nameof(Model)}.{nameof(ModelResource.GetModels)}")]
|
||||
public async Task<List<Branch>> StreamGetBranchesWithLimitRetry(string streamId, int commitsLimit = 10)
|
||||
{
|
||||
List<Branch> branches;
|
||||
@@ -38,6 +43,9 @@ public partial class Client
|
||||
/// <param name="commitsLimit">Max number of commits to retrieve</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectResource.GetWithModels"/>
|
||||
/// <seealso cref="GraphQL.Resources.ModelResource.GetModels"/>
|
||||
[Obsolete($"Use client.{nameof(Model)}.{nameof(ModelResource.GetModels)}")]
|
||||
public async Task<List<Branch>> StreamGetBranches(
|
||||
string streamId,
|
||||
int branchesLimit = 10,
|
||||
@@ -86,6 +94,8 @@ public partial class Client
|
||||
/// <param name="branchInput"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>The branch id.</returns>
|
||||
/// <seealso cref="GraphQL.Resources.ModelResource.Create"/>
|
||||
[Obsolete($"Use client.{nameof(Model)}.{nameof(ModelResource.Create)}")]
|
||||
public async Task<string> BranchCreate(BranchCreateInput branchInput, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -105,6 +115,10 @@ public partial class Client
|
||||
/// <param name="branchName">Name of the branch to get</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>The requested branch</returns>
|
||||
/// <remarks>Updated to Model.GetWithVersions</remarks>
|
||||
/// <seealso cref="GraphQL.Resources.ModelResource.Get"/>
|
||||
/// <seealso cref="GraphQL.Resources.ModelResource.GetWithVersions"/>
|
||||
[Obsolete($"Use client.{nameof(Model)}.{nameof(ModelResource.Get)}")]
|
||||
public async Task<Branch> BranchGet(
|
||||
string streamId,
|
||||
string branchName,
|
||||
@@ -154,6 +168,8 @@ public partial class Client
|
||||
/// <param name="projectId">Id of the project to get the model from</param>
|
||||
/// <param name="modelId">Id of the model</param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ModelResource.Get"/>
|
||||
[Obsolete($"Use client.{nameof(Model)}.{nameof(ModelResource.Get)}")]
|
||||
public async Task<Branch> ModelGet(string projectId, string modelId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -190,6 +206,8 @@ public partial class Client
|
||||
/// </summary>
|
||||
/// <param name="branchInput"></param>
|
||||
/// <returns>The stream's id.</returns>
|
||||
/// <seealso cref="GraphQL.Resources.ModelResource.Update"/>
|
||||
[Obsolete($"Use client.{nameof(Model)}.{nameof(ModelResource.Update)}")]
|
||||
public async Task<bool> BranchUpdate(BranchUpdateInput branchInput, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -208,6 +226,8 @@ public partial class Client
|
||||
/// <param name="branchInput"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ModelResource.Delete"/>
|
||||
[Obsolete($"Use client.{nameof(Model)}.{nameof(ModelResource.Delete)}")]
|
||||
public async Task<bool> BranchDelete(BranchDeleteInput branchInput, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
+6
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
|
||||
@@ -14,6 +16,8 @@ public partial class Client
|
||||
/// <param name="cursor">Time to filter the comments with</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="CommentResource.GetProjectComments"/>
|
||||
[Obsolete($"Use client.{nameof(CommentResource)}.{nameof(CommentResource.GetProjectComments)}")]
|
||||
public async Task<Comments> StreamGetComments(
|
||||
string streamId,
|
||||
int limit = 25,
|
||||
@@ -78,6 +82,8 @@ public partial class Client
|
||||
/// <param name="streamId">Id of the stream to get the comment from</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="CommentResource.GetProjectComments"/>
|
||||
[Obsolete($"Use client.{nameof(CommentResource)}.{nameof(CommentResource.GetProjectComments)}")]
|
||||
public async Task<string> StreamGetCommentScreenshot(
|
||||
string id,
|
||||
string streamId,
|
||||
+14
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
|
||||
@@ -14,6 +16,8 @@ public partial class Client
|
||||
/// <param name="commitId">Id of the commit to get</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.VersionResource.Get"/>
|
||||
[Obsolete($"Use client.{nameof(Version)}.{nameof(VersionResource.Get)}")]
|
||||
public async Task<Commit> CommitGet(string streamId, string commitId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -48,6 +52,8 @@ public partial class Client
|
||||
/// <param name="limit">Max number of commits to get</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>The requested commits</returns>
|
||||
/// <seealso cref="GraphQL.Resources.VersionResource.GetVersions"/>
|
||||
[Obsolete($"Use client.{nameof(Version)}.{nameof(VersionResource.GetVersions)}")]
|
||||
public async Task<List<Commit>> StreamGetCommits(
|
||||
string streamId,
|
||||
int limit = 10,
|
||||
@@ -88,6 +94,8 @@ public partial class Client
|
||||
/// </summary>
|
||||
/// <param name="commitInput"></param>
|
||||
/// <returns>The commit id.</returns>
|
||||
/// <seealso cref="GraphQL.Resources.VersionResource.Create"/>
|
||||
[Obsolete($"Use client.{nameof(VersionResource)}.{nameof(VersionResource.Create)}")]
|
||||
public async Task<string> CommitCreate(CommitCreateInput commitInput, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -106,6 +114,8 @@ public partial class Client
|
||||
/// <param name="commitInput"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>The stream's id.</returns>
|
||||
/// <seealso cref="GraphQL.Resources.VersionResource.Update"/>
|
||||
[Obsolete($"Use client.{nameof(VersionResource)}.{nameof(VersionResource.Update)}")]
|
||||
public async Task<bool> CommitUpdate(CommitUpdateInput commitInput, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -124,6 +134,8 @@ public partial class Client
|
||||
/// <param name="commitInput"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.VersionResource.Delete"/>
|
||||
[Obsolete($"Use client.{nameof(VersionResource)}.{nameof(VersionResource.Delete)}")]
|
||||
public async Task<bool> CommitDelete(CommitDeleteInput commitInput, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -143,6 +155,8 @@ public partial class Client
|
||||
/// <param name="commitReceivedInput"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.VersionResource.Received"/>
|
||||
[Obsolete($"Use client.{nameof(VersionResource)}.{nameof(VersionResource.Received)}")]
|
||||
public async Task<bool> CommitReceived(
|
||||
CommitReceivedInput commitReceivedInput,
|
||||
CancellationToken cancellationToken = default
|
||||
+1
@@ -6,6 +6,7 @@ namespace Speckle.Core.Api;
|
||||
|
||||
public partial class Client
|
||||
{
|
||||
//TODO: API Gap
|
||||
/// <summary>
|
||||
/// Gets data about the requested Speckle object from a stream.
|
||||
/// </summary>
|
||||
+1
@@ -3,6 +3,7 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
using Speckle.Core.Logging;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
+38
-4
@@ -4,6 +4,9 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
using Speckle.Core.Api.GraphQL.Resources;
|
||||
using Speckle.Core.Logging;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
@@ -34,11 +37,11 @@ public partial class Client
|
||||
|
||||
return stream.id == id;
|
||||
}
|
||||
catch (SpeckleGraphQLForbiddenException<StreamData>)
|
||||
catch (SpeckleGraphQLForbiddenException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (SpeckleGraphQLStreamNotFoundException<StreamData>)
|
||||
catch (SpeckleGraphQLStreamNotFoundException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -52,6 +55,9 @@ public partial class Client
|
||||
/// <param name="branchesLimit">Max number of branches to retrieve</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectResource.Get"/>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectResource.GetWithModels"/>
|
||||
[Obsolete($"Use client.{nameof(Project)}.{nameof(ProjectResource.GetWithModels)}")]
|
||||
public async Task<Stream> StreamGet(string id, int branchesLimit = 10, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -100,6 +106,8 @@ public partial class Client
|
||||
/// <param name="limit">Max number of streams to return</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="ActiveUserResource.GetProjects"/>
|
||||
[Obsolete($"Use client.{nameof(ActiveUser)}.{nameof(ActiveUserResource.GetProjects)}")]
|
||||
public async Task<List<Stream>> StreamsGet(int limit = 10, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -142,7 +150,7 @@ public partial class Client
|
||||
}}"
|
||||
};
|
||||
|
||||
var res = await ExecuteGraphQLRequest<ActiveUserData>(request, cancellationToken).ConfigureAwait(false);
|
||||
var res = await ExecuteGraphQLRequest<ActiveUserResponse>(request, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (res?.activeUser == null)
|
||||
{
|
||||
@@ -154,6 +162,7 @@ public partial class Client
|
||||
return res.activeUser.streams.items;
|
||||
}
|
||||
|
||||
//TODO: API GAP
|
||||
/// <summary>
|
||||
/// Gets all favorite streams for the current user
|
||||
/// </summary>
|
||||
@@ -201,7 +210,7 @@ public partial class Client
|
||||
}}
|
||||
}}"
|
||||
};
|
||||
return (await ExecuteGraphQLRequest<ActiveUserData>(request, cancellationToken).ConfigureAwait(false))
|
||||
return (await ExecuteGraphQLRequest<ActiveUserResponse>(request, cancellationToken).ConfigureAwait(false))
|
||||
.activeUser
|
||||
.favoriteStreams
|
||||
.items;
|
||||
@@ -214,6 +223,8 @@ public partial class Client
|
||||
/// <param name="limit">Max number of streams to return</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ActiveUserResource.GetProjects"/>
|
||||
[Obsolete($"Use client.{nameof(ActiveUser)}.{nameof(ActiveUserResource.GetProjects)}")]
|
||||
public async Task<List<Stream>> StreamSearch(
|
||||
string query,
|
||||
int limit = 10,
|
||||
@@ -258,6 +269,8 @@ public partial class Client
|
||||
/// <param name="streamInput"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>The stream's id.</returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectResource.Create"/>
|
||||
[Obsolete($"Use client.{nameof(Project)}.{nameof(ProjectResource.Create)}")]
|
||||
public async Task<string> StreamCreate(StreamCreateInput streamInput, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -275,6 +288,8 @@ public partial class Client
|
||||
/// <param name="streamInput">Note: the id field needs to be a valid stream id.</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>The stream's id.</returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectResource.Update"/>
|
||||
[Obsolete($"Use client.{nameof(Project)}.{nameof(ProjectResource.Update)}")]
|
||||
public async Task<bool> StreamUpdate(StreamUpdateInput streamInput, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -294,6 +309,8 @@ public partial class Client
|
||||
/// <param name="id">Id of the stream to be deleted</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectResource.Delete"/>
|
||||
[Obsolete($"Use client.{nameof(Project)}.{nameof(ProjectResource.Delete)}")]
|
||||
public async Task<bool> StreamDelete(string id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
@@ -336,6 +353,8 @@ public partial class Client
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="SpeckleException"></exception>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectResource.UpdateRole"/>
|
||||
[Obsolete($"Use client.{nameof(Project)}.{nameof(ProjectResource.UpdateRole)}")]
|
||||
public async Task<bool> StreamUpdatePermission(
|
||||
StreamPermissionInput updatePermissionInput,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -362,6 +381,8 @@ public partial class Client
|
||||
/// <param name="streamId"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectResource.GetWithTeam"/>
|
||||
[Obsolete($"Use client.{nameof(Project)}.{nameof(ProjectResource.GetWithTeam)}")]
|
||||
public async Task<Stream> StreamGetPendingCollaborators(
|
||||
string streamId,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -396,6 +417,8 @@ public partial class Client
|
||||
/// <param name="inviteCreateInput"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectInviteResource.Create"/>
|
||||
[Obsolete($"Use client.{nameof(ProjectInvite)}.{nameof(ProjectInviteResource.Create)}")]
|
||||
public async Task<bool> StreamInviteCreate(
|
||||
StreamInviteCreateInput inviteCreateInput,
|
||||
CancellationToken cancellationToken = default
|
||||
@@ -427,6 +450,8 @@ public partial class Client
|
||||
/// <param name="inviteId">Id of the invite to cancel</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectInviteResource.Cancel"/>
|
||||
[Obsolete($"Use client.{nameof(ProjectInvite)}.{nameof(ProjectInviteResource.Cancel)}")]
|
||||
public async Task<bool> StreamInviteCancel(
|
||||
string streamId,
|
||||
string inviteId,
|
||||
@@ -456,6 +481,8 @@ public partial class Client
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="SpeckleException"></exception>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectInviteResource.Use"/>
|
||||
[Obsolete($"Use client.{nameof(ProjectInvite)}.{nameof(ProjectInviteResource.Use)}")]
|
||||
public async Task<bool> StreamInviteUse(
|
||||
string streamId,
|
||||
string token,
|
||||
@@ -482,6 +509,13 @@ public partial class Client
|
||||
return (bool)res["streamInviteUse"];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="GraphQL.Resources.ProjectInviteResource.Use"/>
|
||||
[Obsolete($"Use client.{nameof(ActiveUser)}.{nameof(ActiveUserResource.ProjectInvites)}")]
|
||||
public async Task<List<PendingStreamCollaborator>> GetAllPendingInvites(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GraphQLRequest
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
|
||||
public partial class Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the currently active user profile.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="ActiveUserResource.Get"/>
|
||||
[Obsolete($"Use client.{nameof(ActiveUser)}.{nameof(ActiveUserResource.Get)}")]
|
||||
public async Task<User?> ActiveUserGet(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await ActiveUser.Get(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get another user's profile by its user id.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the user you are looking for</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="OtherUserResource.Get"/>
|
||||
[Obsolete($"Use client.{nameof(OtherUser)}.{nameof(OtherUserResource.Get)}")]
|
||||
public async Task<LimitedUser?> OtherUserGet(string id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await OtherUser.Get(id, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for a user on the server.
|
||||
/// </summary>
|
||||
/// <param name="query">String to search for. Must be at least 3 characters</param>
|
||||
/// <param name="limit">Max number of users to return</param>
|
||||
/// <returns></returns>
|
||||
/// <seealso cref="OtherUserResource.Get"/>
|
||||
[Obsolete($"Use client.{nameof(OtherUser)}.{nameof(OtherUserResource.UserSearch)}")]
|
||||
public async Task<List<LimitedUser>> UserSearch(
|
||||
string query,
|
||||
int limit = 10,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
var res = await OtherUser.UserSearch(query, limit, cancellationToken: cancellationToken).ConfigureAwait(false);
|
||||
return res.items;
|
||||
}
|
||||
}
|
||||
+49
-230
@@ -1,13 +1,20 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
using Speckle.Core.Api.GraphQL.Enums;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
namespace Speckle.Core.Api;
|
||||
|
||||
#region inputs
|
||||
|
||||
internal static class DeprecationMessages
|
||||
{
|
||||
public const string FE2_DEPRECATION_MESSAGE =
|
||||
$"Stream/Branch/Commit API is now deprecated, Use the new Project/Model/Version API functions in {nameof(Client)}";
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamCreateInput
|
||||
{
|
||||
public string name { get; set; }
|
||||
@@ -15,6 +22,7 @@ public class StreamCreateInput
|
||||
public bool isPublic { get; set; } = true;
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamUpdateInput
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -23,6 +31,7 @@ public class StreamUpdateInput
|
||||
public bool isPublic { get; set; } = true;
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamPermissionInput
|
||||
{
|
||||
public string streamId { get; set; }
|
||||
@@ -30,12 +39,14 @@ public class StreamPermissionInput
|
||||
public string role { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamRevokePermissionInput
|
||||
{
|
||||
public string streamId { get; set; }
|
||||
public string userId { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamInviteCreateInput
|
||||
{
|
||||
public string streamId { get; set; }
|
||||
@@ -45,6 +56,7 @@ public class StreamInviteCreateInput
|
||||
public string role { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class BranchCreateInput
|
||||
{
|
||||
public string streamId { get; set; }
|
||||
@@ -52,6 +64,7 @@ public class BranchCreateInput
|
||||
public string description { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class BranchUpdateInput
|
||||
{
|
||||
public string streamId { get; set; }
|
||||
@@ -60,6 +73,7 @@ public class BranchUpdateInput
|
||||
public string description { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class BranchDeleteInput
|
||||
{
|
||||
public string streamId { get; set; }
|
||||
@@ -80,6 +94,7 @@ public class CommitCreateInput
|
||||
public List<string> previousCommitIds { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommitUpdateInput
|
||||
{
|
||||
public string streamId { get; set; }
|
||||
@@ -87,12 +102,14 @@ public class CommitUpdateInput
|
||||
public string message { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommitDeleteInput
|
||||
{
|
||||
public string streamId { get; set; }
|
||||
public string id { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommitReceivedInput
|
||||
{
|
||||
public string streamId { get; set; }
|
||||
@@ -103,6 +120,7 @@ public class CommitReceivedInput
|
||||
|
||||
#endregion
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Stream
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -147,6 +165,7 @@ public class Stream
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Collaborator
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -160,24 +179,13 @@ public class Collaborator
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamInvitesResponse
|
||||
{
|
||||
public List<PendingStreamCollaborator> streamInvites { get; set; }
|
||||
}
|
||||
|
||||
public class PendingStreamCollaborator
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string inviteId { get; set; }
|
||||
public string streamId { get; set; }
|
||||
public string streamName { get; set; }
|
||||
public string title { get; set; }
|
||||
public string role { get; set; }
|
||||
public User invitedBy { get; set; }
|
||||
public User user { get; set; }
|
||||
public string token { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Branches
|
||||
{
|
||||
public int totalCount { get; set; }
|
||||
@@ -185,6 +193,7 @@ public class Branches
|
||||
public List<Branch> items { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Commits
|
||||
{
|
||||
public int totalCount { get; set; }
|
||||
@@ -192,6 +201,7 @@ public class Commits
|
||||
public List<Commit> items { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Commit
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -247,6 +257,7 @@ public class InfoCommit
|
||||
public string branchName { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class SpeckleObject
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -256,6 +267,7 @@ public class SpeckleObject
|
||||
public DateTime createdAt { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Branch
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -269,6 +281,7 @@ public class Branch
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Streams
|
||||
{
|
||||
public int totalCount { get; set; }
|
||||
@@ -276,51 +289,14 @@ public class Streams
|
||||
public List<Stream> items { get; set; }
|
||||
}
|
||||
|
||||
public class UserBase
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string bio { get; set; }
|
||||
public string company { get; set; }
|
||||
public string avatar { get; set; }
|
||||
public bool verified { get; set; }
|
||||
public string role { get; set; }
|
||||
public Streams streams { get; set; }
|
||||
}
|
||||
|
||||
public class LimitedUser : UserBase
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Other user profile: ({name} | {id})";
|
||||
}
|
||||
}
|
||||
|
||||
public class User : UserBase
|
||||
{
|
||||
public string email { get; set; }
|
||||
public Streams favoriteStreams { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"User ({email} | {name} | {id})";
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Resource
|
||||
{
|
||||
public string resourceId { get; set; }
|
||||
public ResourceType resourceType { get; set; }
|
||||
}
|
||||
|
||||
public enum ResourceType
|
||||
{
|
||||
commit,
|
||||
stream,
|
||||
@object,
|
||||
comment
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Location
|
||||
{
|
||||
public double x { get; set; }
|
||||
@@ -328,105 +304,33 @@ public class Location
|
||||
public double z { get; set; }
|
||||
}
|
||||
|
||||
public class UserData
|
||||
{
|
||||
public User user { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GraphQL DTO model for active user data
|
||||
/// </summary>
|
||||
public class ActiveUserData
|
||||
{
|
||||
/// <summary>
|
||||
/// User profile of the active user.
|
||||
/// </summary>
|
||||
public User activeUser { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GraphQL DTO model for limited user data. Mostly referring to other user's profile.
|
||||
/// </summary>
|
||||
public class LimitedUserData
|
||||
{
|
||||
/// <summary>
|
||||
/// The limited user profile of another (non active user)
|
||||
/// </summary>
|
||||
public LimitedUser otherUser { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class UserSearchData
|
||||
{
|
||||
public UserSearch userSearch { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class UserSearch
|
||||
{
|
||||
public string cursor { get; set; }
|
||||
public List<LimitedUser> items { get; set; }
|
||||
}
|
||||
|
||||
public class ServerInfoResponse
|
||||
{
|
||||
// TODO: server and user models are duplicated here and in Speckle.Core.Credentials.Responses
|
||||
// a bit weird and unnecessary - shouldn't both Credentials and Api share the same models since they're
|
||||
// all server models that should be consistent? am creating a new obj here as to not reference Credentials in
|
||||
// this file but it should prob be refactored in the futrue
|
||||
public ServerInfo serverInfo { get; set; }
|
||||
}
|
||||
|
||||
// TODO: prob remove and bring one level up and shared w Speckle.Core.Credentials
|
||||
[ClassInterface(ClassInterfaceType.AutoDual)]
|
||||
[ComVisible(true)]
|
||||
public class ServerInfo
|
||||
{
|
||||
public string name { get; set; }
|
||||
public string company { get; set; }
|
||||
public string version { get; set; }
|
||||
public string adminContact { get; set; }
|
||||
public string description { get; set; }
|
||||
|
||||
/// <remarks>
|
||||
/// This field is not returned from the GQL API,
|
||||
/// it should populated on construction from the response headers.
|
||||
/// see <see cref="Speckle.Core.Credentials.AccountManager"/>
|
||||
/// </remarks>
|
||||
public bool frontend2 { get; set; }
|
||||
|
||||
/// <remarks>
|
||||
/// This field is not returned from the GQL API,
|
||||
/// it should populated on construction.
|
||||
/// see <see cref="Speckle.Core.Credentials.AccountManager"/>
|
||||
/// </remarks>
|
||||
public string url { get; set; }
|
||||
|
||||
public ServerMigration migration { get; set; }
|
||||
}
|
||||
|
||||
public class ServerMigration
|
||||
{
|
||||
/// <summary>
|
||||
/// New URI where this server is now deployed
|
||||
/// </summary>
|
||||
public Uri movedTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Previous URI where this server used to be deployed
|
||||
/// </summary>
|
||||
public Uri movedFrom { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamData
|
||||
{
|
||||
public Stream stream { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamsData
|
||||
{
|
||||
public Streams streams { get; set; }
|
||||
}
|
||||
|
||||
#region comments
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Comments
|
||||
{
|
||||
public int totalCount { get; set; }
|
||||
@@ -434,16 +338,18 @@ public class Comments
|
||||
public List<CommentItem> items { get; set; }
|
||||
}
|
||||
|
||||
public class CommentData
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public sealed class CommentData
|
||||
{
|
||||
public Comments comments { get; set; }
|
||||
public List<double> camPos { get; set; }
|
||||
public object filters { get; set; }
|
||||
public Location location { get; set; }
|
||||
public object selection { get; set; }
|
||||
public object sectionBox { get; set; }
|
||||
public Comments comments { get; init; }
|
||||
public List<double> camPos { get; init; }
|
||||
public object filters { get; init; }
|
||||
public Location location { get; init; }
|
||||
public object selection { get; init; }
|
||||
public object sectionBox { get; init; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommentItem
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -460,6 +366,7 @@ public class CommentItem
|
||||
public List<Resource> resources { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class ContentContent
|
||||
{
|
||||
public string Type { get; set; }
|
||||
@@ -468,116 +375,28 @@ public class ContentContent
|
||||
public string Text { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommentsData
|
||||
{
|
||||
public Comments comments { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommentItemData
|
||||
{
|
||||
public CommentItem comment { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommentActivityMessage
|
||||
{
|
||||
public string type { get; set; }
|
||||
public CommentItem comment { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommentActivityResponse
|
||||
{
|
||||
public CommentActivityMessage commentActivity { get; set; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region manager api
|
||||
|
||||
public class Connector
|
||||
{
|
||||
public List<Version> Versions { get; set; } = new();
|
||||
}
|
||||
|
||||
public class Version
|
||||
{
|
||||
public Version(string number, string url, Os os = Os.Win, Architecture architecture = Architecture.Any)
|
||||
{
|
||||
Number = number;
|
||||
Url = url;
|
||||
Date = DateTime.Now;
|
||||
Prerelease = Number.Contains("-");
|
||||
Os = os;
|
||||
Architecture = architecture;
|
||||
}
|
||||
|
||||
public string Number { get; set; }
|
||||
public string Url { get; set; }
|
||||
public Os Os { get; set; }
|
||||
public Architecture Architecture { get; set; } = Architecture.Any;
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string DateTimeAgo => Helpers.TimeAgo(Date);
|
||||
|
||||
public bool Prerelease { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OS
|
||||
/// NOTE: do not edit order and only append new items as they are serialized to ints
|
||||
/// </summary>
|
||||
public enum Os
|
||||
{
|
||||
Win, //0
|
||||
OSX, //1
|
||||
Linux, //2
|
||||
Any //3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Architecture
|
||||
/// NOTE: do not edit order and only append new items as they are serialized to ints
|
||||
/// </summary>
|
||||
public enum Architecture
|
||||
{
|
||||
Any, //0
|
||||
Arm, //1
|
||||
Intel //2
|
||||
}
|
||||
|
||||
//GHOST API
|
||||
public class Meta
|
||||
{
|
||||
public Pagination pagination { get; set; }
|
||||
}
|
||||
|
||||
public class Pagination
|
||||
{
|
||||
public int page { get; set; }
|
||||
public string limit { get; set; }
|
||||
public int pages { get; set; }
|
||||
public int total { get; set; }
|
||||
public object next { get; set; }
|
||||
public object prev { get; set; }
|
||||
}
|
||||
|
||||
public class Tags
|
||||
{
|
||||
public List<Tag> tags { get; set; }
|
||||
public Meta meta { get; set; }
|
||||
}
|
||||
|
||||
public class Tag
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string slug { get; set; }
|
||||
public string description { get; set; }
|
||||
public string feature_image { get; set; }
|
||||
public string visibility { get; set; }
|
||||
public string codeinjection_head { get; set; }
|
||||
public object codeinjection_foot { get; set; }
|
||||
public object canonical_url { get; set; }
|
||||
public string accent_color { get; set; }
|
||||
public string url { get; set; }
|
||||
}
|
||||
#endregion
|
||||
@@ -0,0 +1,98 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL;
|
||||
|
||||
#region manager api
|
||||
|
||||
public class Connector
|
||||
{
|
||||
public List<ConnectorVersion> Versions { get; set; } = new();
|
||||
}
|
||||
|
||||
public class ConnectorVersion
|
||||
{
|
||||
public ConnectorVersion(string number, string url, Os os = Os.Win, Architecture architecture = Architecture.Any)
|
||||
{
|
||||
Number = number;
|
||||
Url = url;
|
||||
Date = DateTime.Now;
|
||||
Prerelease = Number.Contains("-");
|
||||
Os = os;
|
||||
Architecture = architecture;
|
||||
}
|
||||
|
||||
public string Number { get; set; }
|
||||
public string Url { get; set; }
|
||||
public Os Os { get; set; }
|
||||
public Architecture Architecture { get; set; } = Architecture.Any;
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string DateTimeAgo => Helpers.TimeAgo(Date);
|
||||
|
||||
public bool Prerelease { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OS
|
||||
/// NOTE: do not edit order and only append new items as they are serialized to ints
|
||||
/// </summary>
|
||||
public enum Os
|
||||
{
|
||||
Win, //0
|
||||
OSX, //1
|
||||
Linux, //2
|
||||
Any //3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Architecture
|
||||
/// NOTE: do not edit order and only append new items as they are serialized to ints
|
||||
/// </summary>
|
||||
public enum Architecture
|
||||
{
|
||||
Any, //0
|
||||
Arm, //1
|
||||
Intel //2
|
||||
}
|
||||
|
||||
//GHOST API
|
||||
public class Meta
|
||||
{
|
||||
public Pagination pagination { get; set; }
|
||||
}
|
||||
|
||||
public class Pagination
|
||||
{
|
||||
public int page { get; set; }
|
||||
public string limit { get; set; }
|
||||
public int pages { get; set; }
|
||||
public int total { get; set; }
|
||||
public object next { get; set; }
|
||||
public object prev { get; set; }
|
||||
}
|
||||
|
||||
public class Tags
|
||||
{
|
||||
public List<Tag> tags { get; set; }
|
||||
public Meta meta { get; set; }
|
||||
}
|
||||
|
||||
public class Tag
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string slug { get; set; }
|
||||
public string description { get; set; }
|
||||
public string feature_image { get; set; }
|
||||
public string visibility { get; set; }
|
||||
public string codeinjection_head { get; set; }
|
||||
public object codeinjection_foot { get; set; }
|
||||
public object canonical_url { get; set; }
|
||||
public string accent_color { get; set; }
|
||||
public string url { get; set; }
|
||||
}
|
||||
#endregion
|
||||
+12
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
namespace Speckle.Core.Api.SubscriptionModels;
|
||||
|
||||
#region streams
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamInfo
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -13,16 +14,19 @@ public class StreamInfo
|
||||
public string sharedBy { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class UserStreamAddedResult
|
||||
{
|
||||
public StreamInfo userStreamAdded { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class StreamUpdatedResult
|
||||
{
|
||||
public StreamInfo streamUpdated { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class UserStreamRemovedResult
|
||||
{
|
||||
public StreamInfo userStreamRemoved { get; set; }
|
||||
@@ -31,6 +35,7 @@ public class UserStreamRemovedResult
|
||||
|
||||
#region branches
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class BranchInfo
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -40,16 +45,19 @@ public class BranchInfo
|
||||
public string authorId { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class BranchCreatedResult
|
||||
{
|
||||
public BranchInfo branchCreated { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class BranchUpdatedResult
|
||||
{
|
||||
public BranchInfo branchUpdated { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class BranchDeletedResult
|
||||
{
|
||||
public BranchInfo branchDeleted { get; set; }
|
||||
@@ -58,6 +66,7 @@ public class BranchDeletedResult
|
||||
|
||||
#region commits
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommitInfo
|
||||
{
|
||||
public string id { get; set; }
|
||||
@@ -74,16 +83,19 @@ public class CommitInfo
|
||||
public IList<string> previousCommitIds { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommitCreatedResult
|
||||
{
|
||||
public CommitInfo commitCreated { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommitUpdatedResult
|
||||
{
|
||||
public CommitInfo commitUpdated { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class CommitDeletedResult
|
||||
{
|
||||
public CommitInfo commitDeleted { get; set; }
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public class ResourceCollection<T>
|
||||
{
|
||||
public int totalCount { get; init; }
|
||||
|
||||
public List<T> items { get; init; }
|
||||
|
||||
public string? cursor { get; init; }
|
||||
}
|
||||
|
||||
public sealed class CommentReplyAuthorCollection : ResourceCollection<LimitedUser> { }
|
||||
|
||||
public sealed class ProjectCommentCollection : ResourceCollection<Comment>
|
||||
{
|
||||
public int totalArchivedCount { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class Comment
|
||||
{
|
||||
public bool archived { get; init; }
|
||||
public LimitedUser author { get; init; }
|
||||
public string authorId { get; init; }
|
||||
public DateTime createdAt { get; init; }
|
||||
public bool hasParent { get; init; }
|
||||
public string id { get; init; }
|
||||
public Comment parent { get; init; }
|
||||
public string rawText { get; init; }
|
||||
public ResourceCollection<Comment> replies { get; init; }
|
||||
public CommentReplyAuthorCollection replyAuthors { get; init; }
|
||||
public List<ResourceIdentifier> resources { get; init; }
|
||||
public string screenshot { get; init; }
|
||||
public DateTime updatedAt { get; init; }
|
||||
public DateTime? viewedAt { get; init; }
|
||||
public List<ViewerResourceItem> viewerResources { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class FileUpload
|
||||
{
|
||||
public string convertedCommitId { get; init; }
|
||||
public DateTime convertedLastUpdate { get; init; }
|
||||
public FileUploadConversionStatus convertedStatus { get; init; }
|
||||
public string convertedVersionId { get; init; }
|
||||
public string fileName { get; init; }
|
||||
public int fileSize { get; init; }
|
||||
public string fileType { get; init; }
|
||||
public string id { get; init; }
|
||||
public Model model { get; init; }
|
||||
public string modelName { get; init; }
|
||||
public string projectId { get; init; }
|
||||
public bool uploadComplete { get; init; }
|
||||
public DateTime uploadDate { get; init; }
|
||||
public string userId { get; init; }
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public string branchName { get; init; }
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public string streamId { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class Model
|
||||
{
|
||||
public LimitedUser author { get; init; }
|
||||
public List<ModelsTreeItem> childrenTree { get; init; }
|
||||
public ResourceCollection<Comment> commentThreads { get; init; }
|
||||
public DateTime createdAt { get; init; }
|
||||
public string description { get; init; }
|
||||
public string displayName { get; init; }
|
||||
public string id { get; init; }
|
||||
public string name { get; init; }
|
||||
public List<FileUpload> pendingImportedVersions { get; init; }
|
||||
public Uri previewUrl { get; init; }
|
||||
public DateTime updatedAt { get; init; }
|
||||
public ResourceCollection<Version> versions { get; init; }
|
||||
public Version version { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class ModelsTreeItem
|
||||
{
|
||||
public List<ModelsTreeItem> children { get; init; }
|
||||
public string fullName { get; init; }
|
||||
public bool hasChildren { get; init; }
|
||||
public string id { get; init; }
|
||||
public Model model { get; init; }
|
||||
public string name { get; init; }
|
||||
public DateTime updatedAt { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class PendingStreamCollaborator
|
||||
{
|
||||
public string id { get; init; }
|
||||
public string inviteId { get; init; }
|
||||
|
||||
public string projectId { get; init; }
|
||||
|
||||
public string projectName { get; init; }
|
||||
public string title { get; init; }
|
||||
public string role { get; init; }
|
||||
public LimitedUser invitedBy { get; init; }
|
||||
public LimitedUser user { get; init; }
|
||||
public string token { get; init; }
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public string streamId { get; init; }
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public string streamName { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class Project
|
||||
{
|
||||
public bool AllowPublicComments { get; init; }
|
||||
public ProjectCommentCollection commentThreads { get; init; }
|
||||
public DateTime createdAt { get; init; }
|
||||
public string description { get; init; }
|
||||
public string id { get; init; }
|
||||
public List<PendingStreamCollaborator> invitedTeam { get; init; }
|
||||
public ResourceCollection<Model> models { get; init; }
|
||||
public string name { get; init; }
|
||||
public List<FileUpload> pendingImportedModels { get; init; }
|
||||
public string role { get; init; }
|
||||
public List<string> sourceApps { get; init; }
|
||||
public List<ProjectCollaborator> team { get; init; }
|
||||
public DateTime updatedAt { get; init; }
|
||||
public ProjectVisibility visibility { get; init; }
|
||||
|
||||
public List<ViewerResourceGroup> viewerResources { get; init; }
|
||||
public ResourceCollection<Version> versions { get; init; }
|
||||
public Model model { get; init; }
|
||||
public List<ModelsTreeItem> modelChildrenTree { get; init; }
|
||||
public ResourceCollection<ModelsTreeItem> modelsTree { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#nullable disable
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class ProjectCollaborator
|
||||
{
|
||||
public string role { get; init; }
|
||||
public LimitedUser user { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#nullable disable
|
||||
using Speckle.Core.Api.GraphQL.Enums;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class ResourceIdentifier
|
||||
{
|
||||
public string resourceId { get; init; }
|
||||
public ResourceType resourceType { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
namespace Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
#nullable disable
|
||||
internal sealed class ProjectMutation
|
||||
{
|
||||
public Project create { get; init; }
|
||||
public Project update { get; init; }
|
||||
public bool delete { get; init; }
|
||||
public ProjectInviteMutation invites { get; init; }
|
||||
|
||||
public Project updateRole { get; init; }
|
||||
}
|
||||
|
||||
internal sealed class ProjectInviteMutation
|
||||
{
|
||||
public Project create { get; init; }
|
||||
public bool use { get; init; }
|
||||
public Project cancel { get; init; }
|
||||
}
|
||||
|
||||
internal sealed class ModelMutation
|
||||
{
|
||||
public Model create { get; init; }
|
||||
public Model update { get; init; }
|
||||
public bool delete { get; init; }
|
||||
}
|
||||
|
||||
internal sealed class VersionMutation
|
||||
{
|
||||
public bool delete { get; init; }
|
||||
public Model moveToModel { get; init; }
|
||||
public Version update { get; init; }
|
||||
}
|
||||
|
||||
internal sealed class CommentMutation
|
||||
{
|
||||
public bool archive { get; init; }
|
||||
public Comment create { get; init; }
|
||||
public Comment edit { get; init; }
|
||||
public bool markViewed { get; init; }
|
||||
public Comment reply { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Speckle.Newtonsoft.Json;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
// This file holds simple records that represent the root GraphQL response data
|
||||
// For this reason, we're keeping them internal, allowing us to be flexible without the concern for breaking.
|
||||
// It also exposes fewer similarly named types to dependent assemblies
|
||||
|
||||
internal record ProjectResponse([property: JsonRequired] Project project);
|
||||
|
||||
internal record ActiveUserResponse(User? activeUser);
|
||||
|
||||
internal record LimitedUserResponse(LimitedUser? otherUser);
|
||||
|
||||
internal record ServerInfoResponse([property: JsonRequired] ServerInfo serverInfo);
|
||||
|
||||
internal record ProjectMutationResponse([property: JsonRequired] ProjectMutation projectMutations);
|
||||
|
||||
internal record ModelMutationResponse([property: JsonRequired] ModelMutation modelMutations);
|
||||
|
||||
internal record VersionMutationResponse([property: JsonRequired] VersionMutation versionMutations);
|
||||
|
||||
internal record ProjectInviteResponse(PendingStreamCollaborator? projectInvite);
|
||||
|
||||
internal record UserSearchResponse([property: JsonRequired] ResourceCollection<LimitedUser> userSearch);
|
||||
|
||||
//All of the above records could be replaced by either RequiredResponse or OptionalResponse, if we use an alias (see https://www.baeldung.com/graphql-field-name)
|
||||
internal record RequiredResponse<T>([property: JsonRequired] T data);
|
||||
|
||||
internal record OptionalResponse<T>(T? data);
|
||||
@@ -0,0 +1,45 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
[ClassInterface(ClassInterfaceType.AutoDual)]
|
||||
[ComVisible(true)]
|
||||
public sealed class ServerInfo
|
||||
{
|
||||
public string name { get; init; }
|
||||
public string company { get; init; }
|
||||
public string version { get; init; }
|
||||
public string adminContact { get; init; }
|
||||
public string description { get; init; }
|
||||
|
||||
/// <remarks>
|
||||
/// This field is not returned from the GQL API,
|
||||
/// it should be populated after construction from the response headers.
|
||||
/// see <see cref="Speckle.Core.Credentials.AccountManager"/>
|
||||
/// </remarks>
|
||||
public bool frontend2 { get; set; }
|
||||
|
||||
/// <remarks>
|
||||
/// This field is not returned from the GQL API,
|
||||
/// it should be populated after construction.
|
||||
/// see <see cref="Speckle.Core.Credentials.AccountManager"/>
|
||||
/// </remarks>
|
||||
public string url { get; set; }
|
||||
|
||||
public ServerMigration migration { get; init; }
|
||||
}
|
||||
|
||||
public sealed class ServerMigration
|
||||
{
|
||||
/// <summary>
|
||||
/// New URI where this server is now deployed
|
||||
/// </summary>
|
||||
public Uri movedTo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Previous URI where this server used to be deployed
|
||||
/// </summary>
|
||||
public Uri movedFrom { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using Speckle.Core.Api.GraphQL.Enums;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class UserProjectsUpdatedMessage : EventArgs
|
||||
{
|
||||
[JsonRequired]
|
||||
public string id { get; init; }
|
||||
|
||||
[JsonRequired]
|
||||
public UserProjectsUpdatedMessageType type { get; init; }
|
||||
|
||||
public Project? project { get; init; }
|
||||
}
|
||||
|
||||
public sealed class ProjectCommentsUpdatedMessage : EventArgs
|
||||
{
|
||||
[JsonRequired]
|
||||
public string id { get; init; }
|
||||
|
||||
[JsonRequired]
|
||||
public ProjectCommentsUpdatedMessageType type { get; init; }
|
||||
|
||||
public Comment? comment { get; init; }
|
||||
}
|
||||
|
||||
public sealed class ProjectFileImportUpdatedMessage : EventArgs
|
||||
{
|
||||
[JsonRequired]
|
||||
public string id { get; init; }
|
||||
|
||||
[JsonRequired]
|
||||
public ProjectFileImportUpdatedMessageType type { get; init; }
|
||||
|
||||
public FileUpload? upload { get; init; }
|
||||
}
|
||||
|
||||
public sealed class ProjectModelsUpdatedMessage : EventArgs
|
||||
{
|
||||
[JsonRequired]
|
||||
public string id { get; init; }
|
||||
|
||||
[JsonRequired]
|
||||
public ProjectModelsUpdatedMessageType type { get; init; }
|
||||
|
||||
public Model? model { get; init; }
|
||||
}
|
||||
|
||||
public sealed class ProjectPendingModelsUpdatedMessage : EventArgs
|
||||
{
|
||||
[JsonRequired]
|
||||
public string id { get; init; }
|
||||
|
||||
[JsonRequired]
|
||||
public ProjectPendingModelsUpdatedMessageType type { get; init; }
|
||||
|
||||
public FileUpload? model { get; init; }
|
||||
}
|
||||
|
||||
public sealed class ProjectUpdatedMessage : EventArgs
|
||||
{
|
||||
[JsonRequired]
|
||||
public string id { get; init; }
|
||||
|
||||
[JsonRequired]
|
||||
public ProjectUpdatedMessageType type { get; init; }
|
||||
|
||||
public Project? project { get; init; }
|
||||
}
|
||||
|
||||
public sealed class ProjectVersionsUpdatedMessage : EventArgs
|
||||
{
|
||||
[JsonRequired]
|
||||
public string id { get; init; }
|
||||
|
||||
[JsonRequired]
|
||||
public ProjectVersionsUpdatedMessageType type { get; init; }
|
||||
|
||||
public string? modelId { get; init; }
|
||||
|
||||
public Version? version { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public abstract class UserBase
|
||||
{
|
||||
public ResourceCollection<Activity> activity { get; init; }
|
||||
public string avatar { get; init; }
|
||||
public string bio { get; init; }
|
||||
public string company { get; set; }
|
||||
public string id { get; init; }
|
||||
public string name { get; init; }
|
||||
public string role { get; init; }
|
||||
|
||||
public ResourceCollection<Activity> timeline { get; init; }
|
||||
public int totalOwnedStreamsFavorites { get; init; }
|
||||
public bool? verified { get; init; }
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public ResourceCollection<Commit> commits { get; init; }
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public ResourceCollection<Stream> streams { get; init; }
|
||||
}
|
||||
|
||||
public sealed class LimitedUser : UserBase
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Other user profile: ({name} | {id})";
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class User : UserBase
|
||||
{
|
||||
public DateTime? createdAt { get; init; }
|
||||
public string email { get; init; }
|
||||
public bool? hasPendingVerification { get; init; }
|
||||
public bool? isOnboardingFinished { get; init; }
|
||||
public List<PendingStreamCollaborator> projectInvites { get; init; }
|
||||
public ResourceCollection<Project> projects { get; init; }
|
||||
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public ResourceCollection<Stream> favoriteStreams { get; init; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"User ({email} | {name} | {id})";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public sealed class Version
|
||||
{
|
||||
public LimitedUser authorUser { get; init; }
|
||||
public ResourceCollection<Comment> commentThreads { get; init; }
|
||||
public DateTime createdAt { get; init; }
|
||||
public string id { get; init; }
|
||||
public string message { get; init; }
|
||||
public Model model { get; init; }
|
||||
public Uri previewUrl { get; init; }
|
||||
public string referencedObject { get; init; }
|
||||
public string sourceApplication { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#nullable disable
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public class ViewerResourceGroup
|
||||
{
|
||||
public string identifier { get; init; }
|
||||
public List<ViewerResourceItem> items { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#nullable disable
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
public class ViewerResourceItem
|
||||
{
|
||||
public string modelId { get; init; }
|
||||
public string objectId { get; init; }
|
||||
public string versionId { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Inputs;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
public sealed class ActiveUserResource
|
||||
{
|
||||
private readonly ISpeckleGraphQLClient _client;
|
||||
|
||||
internal ActiveUserResource(ISpeckleGraphQLClient client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently active user profile.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <returns>the requested user, or null if the user does not exist (i.e. <see cref="Client"/> was initialised with an unauthenticated account)</returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<User?> Get(CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query User {
|
||||
activeUser {
|
||||
id,
|
||||
email,
|
||||
name,
|
||||
bio,
|
||||
company,
|
||||
avatar,
|
||||
verified,
|
||||
profiles,
|
||||
role,
|
||||
}
|
||||
}
|
||||
""";
|
||||
var request = new GraphQLRequest { Query = QUERY };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ActiveUserResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.activeUser;
|
||||
}
|
||||
|
||||
/// <param name="limit">Max number of projects to fetch</param>
|
||||
/// <param name="cursor">Optional cursor for pagination</param>
|
||||
/// <param name="filter">Optional filter</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<ResourceCollection<Project>> GetProjects(
|
||||
int limit = ServerLimits.DEFAULT_PAGINATION_REQUEST,
|
||||
string? cursor = null,
|
||||
UserProjectsFilter? filter = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query User($limit : Int!, $cursor: String, $filter: UserProjectsFilter) {
|
||||
activeUser {
|
||||
projects(limit: $limit, cursor: $cursor, filter: $filter) {
|
||||
totalCount
|
||||
items {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
sourceApps
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
var request = new GraphQLRequest
|
||||
{
|
||||
Query = QUERY,
|
||||
Variables = new
|
||||
{
|
||||
limit,
|
||||
cursor,
|
||||
filter
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ActiveUserResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (response.activeUser is null)
|
||||
{
|
||||
throw new SpeckleGraphQLException("GraphQL response indicated that the ActiveUser could not be found");
|
||||
}
|
||||
|
||||
return response.activeUser.projects;
|
||||
}
|
||||
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<List<PendingStreamCollaborator>> ProjectInvites(CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query ProjectInvites {
|
||||
activeUser {
|
||||
projectInvites {
|
||||
id
|
||||
inviteId
|
||||
invitedBy {
|
||||
avatar
|
||||
bio
|
||||
company
|
||||
id
|
||||
name
|
||||
role
|
||||
verified
|
||||
}
|
||||
projectId
|
||||
projectName
|
||||
role
|
||||
streamId
|
||||
streamName
|
||||
title
|
||||
token
|
||||
user {
|
||||
id,
|
||||
name,
|
||||
bio,
|
||||
company,
|
||||
verified,
|
||||
role,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
var request = new GraphQLRequest { Query = QUERY };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ActiveUserResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (response.activeUser is null)
|
||||
{
|
||||
throw new SpeckleGraphQLException("GraphQL response indicated that the ActiveUser could not be found");
|
||||
}
|
||||
|
||||
return response.activeUser.projectInvites;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Inputs;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
public sealed class CommentResource
|
||||
{
|
||||
private readonly ISpeckleGraphQLClient _client;
|
||||
|
||||
internal CommentResource(ISpeckleGraphQLClient client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="limit">Max number of comments to fetch</param>
|
||||
/// <param name="cursor">Optional cursor for pagination</param>
|
||||
/// <param name="filter">Optional filter</param>
|
||||
/// <param name="repliesLimit">Max number of comment replies to fetch</param>
|
||||
/// <param name="repliesCursor">Optional cursor for pagination</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<ResourceCollection<Comment>> GetProjectComments(
|
||||
string projectId,
|
||||
int limit = ServerLimits.DEFAULT_PAGINATION_REQUEST,
|
||||
string? cursor = null,
|
||||
ProjectCommentsFilter? filter = null,
|
||||
int repliesLimit = ServerLimits.DEFAULT_PAGINATION_REQUEST,
|
||||
string? repliesCursor = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query CommentThreads($projectId: String!, $cursor: String, $limit: Int!, $filter: ProjectCommentsFilter, $repliesLimit: Int, $repliesCursor: String) {
|
||||
project(id: $projectId) {
|
||||
commentThreads(cursor: $cursor, limit: $limit, filter: $filter) {
|
||||
cursor
|
||||
totalArchivedCount
|
||||
totalCount
|
||||
items {
|
||||
archived
|
||||
authorId
|
||||
createdAt
|
||||
hasParent
|
||||
id
|
||||
rawText
|
||||
replies(limit: $repliesLimit, cursor: $repliesCursor) {
|
||||
cursor
|
||||
items {
|
||||
archived
|
||||
authorId
|
||||
createdAt
|
||||
hasParent
|
||||
id
|
||||
rawText
|
||||
updatedAt
|
||||
viewedAt
|
||||
}
|
||||
totalCount
|
||||
}
|
||||
resources {
|
||||
resourceId
|
||||
resourceType
|
||||
}
|
||||
screenshot
|
||||
updatedAt
|
||||
viewedAt
|
||||
viewerResources {
|
||||
modelId
|
||||
objectId
|
||||
versionId
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
GraphQLRequest request =
|
||||
new()
|
||||
{
|
||||
Query = QUERY,
|
||||
Variables = new
|
||||
{
|
||||
projectId,
|
||||
cursor,
|
||||
limit,
|
||||
filter,
|
||||
repliesLimit,
|
||||
repliesCursor,
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.project.commentThreads;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// This function only exists here to be able to integration tests the queries.
|
||||
/// The process of creating a comment is more complex and javascript specific than we can expose to our SDKs at this time.
|
||||
/// </remarks>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
internal async Task<Comment> Create(CreateCommentInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation Mutation($input: CreateCommentInput!) {
|
||||
data:commentMutations {
|
||||
create(input: $input) {
|
||||
archived
|
||||
authorId
|
||||
createdAt
|
||||
hasParent
|
||||
id
|
||||
rawText
|
||||
resources {
|
||||
resourceId
|
||||
resourceType
|
||||
}
|
||||
screenshot
|
||||
updatedAt
|
||||
viewedAt
|
||||
viewerResources {
|
||||
modelId
|
||||
objectId
|
||||
versionId
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new(QUERY, variables: new { input });
|
||||
var res = await _client
|
||||
.ExecuteGraphQLRequest<RequiredResponse<CommentMutation>>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return res.data.create;
|
||||
}
|
||||
|
||||
/// <remarks><inheritdoc cref="Create"/></remarks>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
internal async Task<Comment> Edit(EditCommentInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation Mutation($input: EditCommentInput!) {
|
||||
data:commentMutations {
|
||||
edit(input: $input) {
|
||||
archived
|
||||
authorId
|
||||
createdAt
|
||||
hasParent
|
||||
id
|
||||
rawText
|
||||
resources {
|
||||
resourceId
|
||||
resourceType
|
||||
}
|
||||
screenshot
|
||||
updatedAt
|
||||
viewedAt
|
||||
viewerResources {
|
||||
modelId
|
||||
objectId
|
||||
versionId
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new(QUERY, variables: new { input });
|
||||
var res = await _client
|
||||
.ExecuteGraphQLRequest<RequiredResponse<CommentMutation>>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return res.data.edit;
|
||||
}
|
||||
|
||||
/// <param name="commentId"></param>
|
||||
/// <param name="archive"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<bool> Archive(string commentId, bool archive = true, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation Mutation($commentId: String!, $archive: Boolean!) {
|
||||
data:commentMutations {
|
||||
archive(commentId: $commentId, archived: $archive)
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new(QUERY, variables: new { commentId, archive });
|
||||
var res = await _client
|
||||
.ExecuteGraphQLRequest<RequiredResponse<CommentMutation>>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return res.data.archive;
|
||||
}
|
||||
|
||||
/// <param name="commentId"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<bool> MarkViewed(string commentId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation Mutation($commentId: String!) {
|
||||
data:commentMutations {
|
||||
markViewed(commentId: $commentId)
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new(QUERY, variables: new { commentId });
|
||||
var res = await _client
|
||||
.ExecuteGraphQLRequest<RequiredResponse<CommentMutation>>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return res.data.markViewed;
|
||||
}
|
||||
|
||||
/// <remarks><inheritdoc cref="Create"/></remarks>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
internal async Task<Comment> Reply(CreateCommentReplyInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation Mutation($input: CreateCommentReplyInput!) {
|
||||
data:commentMutations {
|
||||
reply(input: $input) {
|
||||
archived
|
||||
authorId
|
||||
createdAt
|
||||
hasParent
|
||||
id
|
||||
rawText
|
||||
resources {
|
||||
resourceId
|
||||
resourceType
|
||||
}
|
||||
screenshot
|
||||
updatedAt
|
||||
viewedAt
|
||||
viewerResources {
|
||||
modelId
|
||||
objectId
|
||||
versionId
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new(QUERY, variables: new { input });
|
||||
var res = await _client
|
||||
.ExecuteGraphQLRequest<RequiredResponse<CommentMutation>>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return res.data.reply;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Inputs;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
public sealed class ModelResource
|
||||
{
|
||||
private readonly ISpeckleGraphQLClient _client;
|
||||
|
||||
internal ModelResource(ISpeckleGraphQLClient client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
/// <param name="modelId"></param>
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
/// <seealso cref="GetWithVersions"/>
|
||||
public async Task<Model> Get(string modelId, string projectId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query ModelGet($modelId: String!, $projectId: String!) {
|
||||
project(id: $projectId) {
|
||||
model(id: $modelId) {
|
||||
id
|
||||
name
|
||||
previewUrl
|
||||
updatedAt
|
||||
description
|
||||
displayName
|
||||
createdAt
|
||||
author {
|
||||
avatar
|
||||
bio
|
||||
company
|
||||
id
|
||||
name
|
||||
role
|
||||
totalOwnedStreamsFavorites
|
||||
verified
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
var request = new GraphQLRequest { Query = QUERY, Variables = new { modelId, projectId } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.project.model;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="modelId"></param>
|
||||
/// <param name="versionsLimit">Max number of versions to fetch</param>
|
||||
/// <param name="versionsCursor">Optional cursor for pagination</param>
|
||||
/// <param name="versionsFilter">Optional versions filter</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
/// <see cref="Get"/>
|
||||
public async Task<Model> GetWithVersions(
|
||||
string modelId,
|
||||
string projectId,
|
||||
int versionsLimit = ServerLimits.DEFAULT_PAGINATION_REQUEST,
|
||||
string? versionsCursor = null,
|
||||
ModelVersionsFilter? versionsFilter = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query ModelGetWithVersions($modelId: String!, $projectId: String!, $versionsLimit: Int!, $versionsCursor: String, $versionsFilter: ModelVersionsFilter) {
|
||||
project(id: $projectId) {
|
||||
model(id: $modelId) {
|
||||
id
|
||||
name
|
||||
previewUrl
|
||||
updatedAt
|
||||
versions(limit: $versionsLimit, cursor: $versionsCursor, filter: $versionsFilter) {
|
||||
items {
|
||||
id
|
||||
referencedObject
|
||||
message
|
||||
sourceApplication
|
||||
createdAt
|
||||
previewUrl
|
||||
authorUser {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
totalCount
|
||||
cursor
|
||||
}
|
||||
description
|
||||
displayName
|
||||
createdAt
|
||||
author {
|
||||
avatar
|
||||
bio
|
||||
company
|
||||
id
|
||||
name
|
||||
role
|
||||
totalOwnedStreamsFavorites
|
||||
verified
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
var request = new GraphQLRequest
|
||||
{
|
||||
Query = QUERY,
|
||||
Variables = new
|
||||
{
|
||||
projectId,
|
||||
modelId,
|
||||
versionsLimit,
|
||||
versionsCursor,
|
||||
versionsFilter,
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.project.model;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="modelsLimit">Max number of models to fetch</param>
|
||||
/// <param name="modelsCursor">Optional cursor for pagination</param>
|
||||
/// <param name="modelsFilter">Optional models filter</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<ResourceCollection<Model>> GetModels(
|
||||
string projectId,
|
||||
int modelsLimit = ServerLimits.DEFAULT_PAGINATION_REQUEST,
|
||||
string? modelsCursor = null,
|
||||
ProjectModelsFilter? modelsFilter = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query ProjectGetWithModels($projectId: String!, $modelsLimit: Int!, $modelsCursor: String, $modelsFilter: ProjectModelsFilter) {
|
||||
project(id: $projectId) {
|
||||
models(limit: $modelsLimit, cursor: $modelsCursor, filter: $modelsFilter) {
|
||||
items {
|
||||
id
|
||||
name
|
||||
previewUrl
|
||||
updatedAt
|
||||
displayName
|
||||
description
|
||||
createdAt
|
||||
}
|
||||
totalCount
|
||||
cursor
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request =
|
||||
new()
|
||||
{
|
||||
Query = QUERY,
|
||||
Variables = new
|
||||
{
|
||||
projectId,
|
||||
modelsLimit,
|
||||
modelsCursor,
|
||||
modelsFilter
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.project.models;
|
||||
}
|
||||
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<Model> Create(CreateModelInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ModelCreate($input: CreateModelInput!) {
|
||||
modelMutations {
|
||||
create(input: $input) {
|
||||
id
|
||||
displayName
|
||||
name
|
||||
description
|
||||
createdAt
|
||||
updatedAt
|
||||
previewUrl
|
||||
author {
|
||||
avatar
|
||||
bio
|
||||
company
|
||||
id
|
||||
name
|
||||
role
|
||||
totalOwnedStreamsFavorites
|
||||
verified
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input } };
|
||||
|
||||
var res = await _client
|
||||
.ExecuteGraphQLRequest<ModelMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return res.modelMutations.create;
|
||||
}
|
||||
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<bool> Delete(DeleteModelInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ModelDelete($input: DeleteModelInput!) {
|
||||
modelMutations {
|
||||
delete(input: $input)
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input } };
|
||||
|
||||
var res = await _client
|
||||
.ExecuteGraphQLRequest<ModelMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return res.modelMutations.delete;
|
||||
}
|
||||
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<Model> Update(UpdateModelInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ModelUpdate($input: UpdateModelInput!) {
|
||||
modelMutations {
|
||||
update(input: $input) {
|
||||
id
|
||||
name
|
||||
displayName
|
||||
description
|
||||
createdAt
|
||||
updatedAt
|
||||
previewUrl
|
||||
author {
|
||||
avatar
|
||||
bio
|
||||
company
|
||||
id
|
||||
name
|
||||
role
|
||||
totalOwnedStreamsFavorites
|
||||
verified
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input } };
|
||||
|
||||
var res = await _client
|
||||
.ExecuteGraphQLRequest<ModelMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return res.modelMutations.update;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
public sealed class OtherUserResource
|
||||
{
|
||||
private readonly ISpeckleGraphQLClient _client;
|
||||
|
||||
internal OtherUserResource(ISpeckleGraphQLClient client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>the requested user, or null if the user does not exist</returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<LimitedUser?> Get(string id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query LimitedUser($id: String!) {
|
||||
otherUser(id: $id){
|
||||
id,
|
||||
name,
|
||||
bio,
|
||||
company,
|
||||
avatar,
|
||||
verified,
|
||||
role,
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
var request = new GraphQLRequest { Query = QUERY, Variables = new { id } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<LimitedUserResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.otherUser;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for a user on the server.
|
||||
/// </summary>
|
||||
/// <param name="query">String to search for. Must be at least 3 characters</param>
|
||||
/// <param name="limit">Max number of users to fetch</param>
|
||||
/// <param name="cursor">Optional cursor for pagination</param>
|
||||
/// <param name="archived"></param>
|
||||
/// <param name="emailOnly"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<ResourceCollection<LimitedUser>> UserSearch(
|
||||
string query,
|
||||
int limit = ServerLimits.DEFAULT_PAGINATION_REQUEST,
|
||||
string? cursor = null,
|
||||
bool archived = false,
|
||||
bool emailOnly = false,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query UserSearch($query: String!, $limit: Int!, $cursor: String, $archived: Boolean, $emailOnly: Boolean) {
|
||||
userSearch(query: $query, limit: $limit, cursor: $cursor, archived: $archived, emailOnly: $emailOnly) {
|
||||
cursor,
|
||||
items {
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
var request = new GraphQLRequest
|
||||
{
|
||||
Query = QUERY,
|
||||
Variables = new
|
||||
{
|
||||
query,
|
||||
limit,
|
||||
cursor,
|
||||
archived,
|
||||
emailOnly
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<UserSearchResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.userSearch;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Inputs;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
public sealed class ProjectInviteResource
|
||||
{
|
||||
private readonly ISpeckleGraphQLClient _client;
|
||||
|
||||
internal ProjectInviteResource(ISpeckleGraphQLClient client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<Project> Create(
|
||||
string projectId,
|
||||
ProjectInviteCreateInput input,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ProjectInviteCreate($projectId: ID!, $input: ProjectInviteCreateInput!) {
|
||||
projectMutations {
|
||||
invites {
|
||||
create(projectId: $projectId, input: $input) {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
team {
|
||||
role
|
||||
user {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
invitedTeam {
|
||||
id
|
||||
inviteId
|
||||
projectId
|
||||
projectName
|
||||
streamName
|
||||
title
|
||||
role
|
||||
streamId
|
||||
token
|
||||
user {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
invitedBy {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { projectId, input } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.projectMutations.invites.create;
|
||||
}
|
||||
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<bool> Use(ProjectInviteUseInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ProjectInviteUse($input: ProjectInviteUseInput!) {
|
||||
projectMutations {
|
||||
invites {
|
||||
use(input: $input)
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.projectMutations.invites.use;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns>The invite, or null if no invite exists</returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<PendingStreamCollaborator?> Get(
|
||||
string projectId,
|
||||
string? token,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query ProjectInvite($projectId: String!, $token: String) {
|
||||
projectInvite(projectId: $projectId, token: $token) {
|
||||
id
|
||||
inviteId
|
||||
invitedBy {
|
||||
avatar
|
||||
bio
|
||||
company
|
||||
id
|
||||
name
|
||||
role
|
||||
totalOwnedStreamsFavorites
|
||||
verified
|
||||
}
|
||||
projectId
|
||||
projectName
|
||||
role
|
||||
streamId
|
||||
streamName
|
||||
title
|
||||
token
|
||||
user {
|
||||
avatar
|
||||
bio
|
||||
company
|
||||
id
|
||||
name
|
||||
role
|
||||
totalOwnedStreamsFavorites
|
||||
verified
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { projectId, token } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectInviteResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.projectInvite;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="inviteId"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<Project> Cancel(string projectId, string inviteId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ProjectInviteCancel($projectId: ID!, $inviteId: String!) {
|
||||
projectMutations {
|
||||
invites {
|
||||
cancel(projectId: $projectId, inviteId: $inviteId) {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
team {
|
||||
role
|
||||
user {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
invitedTeam {
|
||||
id
|
||||
inviteId
|
||||
projectId
|
||||
projectName
|
||||
streamName
|
||||
title
|
||||
role
|
||||
streamId
|
||||
token
|
||||
user {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
invitedBy {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { projectId, inviteId } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.projectMutations.invites.cancel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Inputs;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
public sealed class ProjectResource
|
||||
{
|
||||
private readonly ISpeckleGraphQLClient _client;
|
||||
|
||||
internal ProjectResource(ISpeckleGraphQLClient client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
/// <seealso cref="GetWithModels"/>
|
||||
/// <seealso cref="GetWithTeam"/>
|
||||
public async Task<Project> Get(string projectId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query Project($projectId: String!) {
|
||||
project(id: $projectId) {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
sourceApps
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { projectId } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.project;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="modelsLimit">Max number of models to fetch</param>
|
||||
/// <param name="modelsCursor">Optional cursor for pagination</param>
|
||||
/// <param name="modelsFilter">Optional models filter</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
/// <seealso cref="Get"/>
|
||||
/// <seealso cref="GetWithTeam"/>
|
||||
public async Task<Project> GetWithModels(
|
||||
string projectId,
|
||||
int modelsLimit = ServerLimits.DEFAULT_PAGINATION_REQUEST,
|
||||
string? modelsCursor = null,
|
||||
ProjectModelsFilter? modelsFilter = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query ProjectGetWithModels($projectId: String!, $modelsLimit: Int!, $modelsCursor: String, $modelsFilter: ProjectModelsFilter) {
|
||||
project(id: $projectId) {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
sourceApps
|
||||
models(limit: $modelsLimit, cursor: $modelsCursor, filter: $modelsFilter) {
|
||||
items {
|
||||
id
|
||||
name
|
||||
previewUrl
|
||||
updatedAt
|
||||
displayName
|
||||
description
|
||||
createdAt
|
||||
}
|
||||
cursor
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request =
|
||||
new()
|
||||
{
|
||||
Query = QUERY,
|
||||
Variables = new
|
||||
{
|
||||
projectId,
|
||||
modelsLimit,
|
||||
modelsCursor,
|
||||
modelsFilter
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.project;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
/// <seealso cref="Get"/>
|
||||
/// <seealso cref="GetWithModels"/>
|
||||
public async Task<Project> GetWithTeam(string projectId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query ProjectGetWithTeam($projectId: String!) {
|
||||
project(id: $projectId) {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
team {
|
||||
role
|
||||
user {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
invitedTeam {
|
||||
id
|
||||
inviteId
|
||||
projectId
|
||||
projectName
|
||||
streamId
|
||||
streamName
|
||||
title
|
||||
role
|
||||
token
|
||||
user {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
invitedBy {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { projectId } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.project;
|
||||
}
|
||||
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<Project> Create(ProjectCreateInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ProjectCreate($input: ProjectCreateInput) {
|
||||
projectMutations {
|
||||
create(input: $input) {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
sourceApps
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.projectMutations.create;
|
||||
}
|
||||
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<Project> Update(ProjectUpdateInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ProjectUpdate($input: ProjectUpdateInput!) {
|
||||
projectMutations{
|
||||
update(update: $input) {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.projectMutations.update;
|
||||
}
|
||||
|
||||
/// <param name="projectId">The id of the Project to delete</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<bool> Delete(string projectId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ProjectDelete($projectId: String!) {
|
||||
projectMutations {
|
||||
delete(id: $projectId)
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { projectId } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.projectMutations.delete;
|
||||
}
|
||||
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<Project> UpdateRole(ProjectUpdateRoleInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation ProjectUpdateRole($input: ProjectUpdateRoleInput!) {
|
||||
projectMutations {
|
||||
updateRole(input: $input) {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
team {
|
||||
role
|
||||
user {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
invitedTeam {
|
||||
id
|
||||
inviteId
|
||||
projectId
|
||||
projectName
|
||||
streamId
|
||||
streamName
|
||||
title
|
||||
role
|
||||
token
|
||||
user {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
invitedBy {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
avatar
|
||||
verified
|
||||
role
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.projectMutations.updateRole;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Inputs;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
public sealed class Subscription<TEventArgs> : IDisposable
|
||||
where TEventArgs : EventArgs
|
||||
{
|
||||
internal Subscription(ISpeckleGraphQLClient client, GraphQLRequest request)
|
||||
{
|
||||
_subscription = client.SubscribeTo<RequiredResponse<TEventArgs>>(request, (o, t) => Listeners?.Invoke(o, t.data));
|
||||
}
|
||||
|
||||
public event EventHandler<TEventArgs>? Listeners;
|
||||
|
||||
private readonly IDisposable _subscription;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_subscription.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SubscriptionResource : IDisposable
|
||||
{
|
||||
private readonly ISpeckleGraphQLClient _client;
|
||||
private readonly List<IDisposable> _subscriptions;
|
||||
|
||||
internal SubscriptionResource(ISpeckleGraphQLClient client)
|
||||
{
|
||||
_client = client;
|
||||
_subscriptions = new();
|
||||
}
|
||||
|
||||
/// <summary>Track newly added or deleted projects owned by the active user</summary>
|
||||
/// <remarks>
|
||||
/// You should add event listeners to the returned <see cref="Subscription{TEventArgs}"/> object.<br/>
|
||||
/// You can add multiple listeners to a <see cref="Subscription{TEventArgs}"/>, and this should be preferred over creating many subscriptions.<br/>
|
||||
/// You should ensure proper disposal of the <see cref="Subscription{TEventArgs}"/> when you're done (see <see cref="IDisposable"/>)<br/>
|
||||
/// Disposing of the <see cref="Client"/> or <see cref="SubscriptionResource"/> will also dispose any <see cref="Subscription{TEventArgs}"/>s it created.
|
||||
/// </remarks>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.SubscribeTo{T}"/>
|
||||
public Subscription<UserProjectsUpdatedMessage> CreateUserProjectsUpdatedSubscription()
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
subscription UserProjectsUpdated {
|
||||
data:userProjectsUpdated {
|
||||
id
|
||||
project {
|
||||
id
|
||||
}
|
||||
type
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY };
|
||||
|
||||
Subscription<UserProjectsUpdatedMessage> subscription = new(_client, request);
|
||||
_subscriptions.Add(subscription);
|
||||
return subscription;
|
||||
}
|
||||
|
||||
/// <summary>Subscribe to updates to resource comments/threads. Optionally specify resource ID string to only receive updates regarding comments for those resources</summary>
|
||||
/// <remarks><inheritdoc cref="CreateUserProjectsUpdatedSubscription"/></remarks>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.SubscribeTo{T}"/>
|
||||
public Subscription<ProjectCommentsUpdatedMessage> CreateProjectCommentsUpdatedSubscription(
|
||||
ViewerUpdateTrackingTarget target
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
subscription Subscription($target: ViewerUpdateTrackingTarget!) {
|
||||
data:projectCommentsUpdated(target: $target) {
|
||||
comment {
|
||||
id
|
||||
}
|
||||
id
|
||||
type
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { target } };
|
||||
|
||||
Subscription<ProjectCommentsUpdatedMessage> subscription = new(_client, request);
|
||||
_subscriptions.Add(subscription);
|
||||
return subscription;
|
||||
}
|
||||
|
||||
/// <summary>Subscribe to changes to a project's models. Optionally specify <paramref name="modelIds"/> to track</summary>
|
||||
/// <remarks><inheritdoc cref="CreateUserProjectsUpdatedSubscription"/></remarks>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.SubscribeTo{T}"/>
|
||||
public Subscription<ProjectModelsUpdatedMessage> CreateProjectModelsUpdatedSubscription(
|
||||
string id,
|
||||
IReadOnlyList<string>? modelIds = null
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
subscription ProjectModelsUpdated($id: String!, $modelIds: [String!]) {
|
||||
data:projectModelsUpdated(id: $id, modelIds: $modelIds) {
|
||||
id
|
||||
model {
|
||||
id
|
||||
name
|
||||
previewUrl
|
||||
updatedAt
|
||||
description
|
||||
displayName
|
||||
createdAt
|
||||
author {
|
||||
avatar
|
||||
bio
|
||||
company
|
||||
id
|
||||
name
|
||||
role
|
||||
totalOwnedStreamsFavorites
|
||||
verified
|
||||
}
|
||||
}
|
||||
type
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { id, modelIds } };
|
||||
|
||||
Subscription<ProjectModelsUpdatedMessage> subscription = new(_client, request);
|
||||
_subscriptions.Add(subscription);
|
||||
return subscription;
|
||||
}
|
||||
|
||||
/// <summary>Track updates to a specific project</summary>
|
||||
/// <remarks><inheritdoc cref="CreateUserProjectsUpdatedSubscription"/></remarks>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.SubscribeTo{T}"/>
|
||||
public Subscription<ProjectUpdatedMessage> CreateProjectUpdatedSubscription(string id)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
subscription ProjectUpdated($id: String!) {
|
||||
data:projectUpdated(id: $id) {
|
||||
id
|
||||
project {
|
||||
id
|
||||
name
|
||||
description
|
||||
visibility
|
||||
allowPublicComments
|
||||
role
|
||||
createdAt
|
||||
updatedAt
|
||||
sourceApps
|
||||
}
|
||||
type
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { id } };
|
||||
|
||||
Subscription<ProjectUpdatedMessage> subscription = new(_client, request);
|
||||
_subscriptions.Add(subscription);
|
||||
return subscription;
|
||||
}
|
||||
|
||||
/// <summary>Subscribe to changes to a project's versions.</summary>
|
||||
/// <remarks><inheritdoc cref="CreateUserProjectsUpdatedSubscription"/></remarks>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.SubscribeTo{T}"/>
|
||||
public Subscription<ProjectVersionsUpdatedMessage> CreateProjectVersionsUpdatedSubscription(string id)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
subscription ProjectVersionsUpdated($id: String!) {
|
||||
data:projectVersionsUpdated(id: $id) {
|
||||
id
|
||||
modelId
|
||||
type
|
||||
version {
|
||||
id
|
||||
referencedObject
|
||||
message
|
||||
sourceApplication
|
||||
createdAt
|
||||
previewUrl
|
||||
authorUser {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
verified
|
||||
role
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { id } };
|
||||
|
||||
Subscription<ProjectVersionsUpdatedMessage> subscription = new(_client, request);
|
||||
_subscriptions.Add(subscription);
|
||||
return subscription;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var subscription in _subscriptions)
|
||||
{
|
||||
subscription.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Inputs;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
using Version = Speckle.Core.Api.GraphQL.Models.Version;
|
||||
|
||||
namespace Speckle.Core.Api.GraphQL.Resources;
|
||||
|
||||
public sealed class VersionResource
|
||||
{
|
||||
private readonly ISpeckleGraphQLClient _client;
|
||||
|
||||
internal VersionResource(ISpeckleGraphQLClient client)
|
||||
{
|
||||
_client = client;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="modelId"></param>
|
||||
/// <param name="versionId"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<Version> Get(
|
||||
string versionId,
|
||||
string modelId,
|
||||
string projectId,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query VersionGet($projectId: String!, $modelId: String!, $versionId: String!) {
|
||||
project(id: $projectId) {
|
||||
model(id: $modelId) {
|
||||
version(id: $versionId) {
|
||||
id
|
||||
referencedObject
|
||||
message
|
||||
sourceApplication
|
||||
createdAt
|
||||
previewUrl
|
||||
authorUser {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
verified
|
||||
role
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request =
|
||||
new()
|
||||
{
|
||||
Query = QUERY,
|
||||
Variables = new
|
||||
{
|
||||
projectId,
|
||||
modelId,
|
||||
versionId
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.project.model.version;
|
||||
}
|
||||
|
||||
/// <param name="projectId"></param>
|
||||
/// <param name="modelId"></param>
|
||||
/// <param name="limit">Max number of versions to fetch</param>
|
||||
/// <param name="cursor">Optional cursor for pagination</param>
|
||||
/// <param name="filter">Optional filter</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<ResourceCollection<Version>> GetVersions(
|
||||
string modelId,
|
||||
string projectId,
|
||||
int limit = ServerLimits.DEFAULT_PAGINATION_REQUEST,
|
||||
string? cursor = null,
|
||||
ModelVersionsFilter? filter = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
query VersionGetVersions($projectId: String!, $modelId: String!, $limit: Int!, $cursor: String, $filter: ModelVersionsFilter) {
|
||||
project(id: $projectId) {
|
||||
model(id: $modelId) {
|
||||
versions(limit: $limit, cursor: $cursor, filter: $filter) {
|
||||
items {
|
||||
id
|
||||
referencedObject
|
||||
message
|
||||
sourceApplication
|
||||
createdAt
|
||||
previewUrl
|
||||
authorUser {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
verified
|
||||
role
|
||||
avatar
|
||||
}
|
||||
}
|
||||
cursor
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
GraphQLRequest request =
|
||||
new()
|
||||
{
|
||||
Query = QUERY,
|
||||
Variables = new
|
||||
{
|
||||
projectId,
|
||||
modelId,
|
||||
limit,
|
||||
cursor,
|
||||
filter,
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<ProjectResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.project.model.versions;
|
||||
}
|
||||
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<string> Create(CommitCreateInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//TODO: Implement on server
|
||||
return await ((Client)_client).CommitCreate(input, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<Version> Update(UpdateVersionInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation VersionUpdate($input: UpdateVersionInput!) {
|
||||
versionMutations {
|
||||
update(input: $input) {
|
||||
id
|
||||
referencedObject
|
||||
message
|
||||
sourceApplication
|
||||
createdAt
|
||||
previewUrl
|
||||
authorUser {
|
||||
totalOwnedStreamsFavorites
|
||||
id
|
||||
name
|
||||
bio
|
||||
company
|
||||
verified
|
||||
role
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input, } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<VersionMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.versionMutations.update;
|
||||
}
|
||||
|
||||
//TODO: Would we rather return the full model here? with or with out versions?
|
||||
/// <param name="input"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<string> MoveToModel(MoveVersionsInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation VersionMoveToModel($input: MoveVersionsInput!) {
|
||||
versionMutations {
|
||||
moveToModel(input: $input) {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input, } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<VersionMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
return response.versionMutations.moveToModel.id;
|
||||
}
|
||||
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<bool> Delete(DeleteVersionsInput input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
//language=graphql
|
||||
const string QUERY = """
|
||||
mutation VersionDelete($input: DeleteVersionsInput!) {
|
||||
versionMutations {
|
||||
delete(input: $input)
|
||||
}
|
||||
}
|
||||
""";
|
||||
GraphQLRequest request = new() { Query = QUERY, Variables = new { input } };
|
||||
|
||||
var response = await _client
|
||||
.ExecuteGraphQLRequest<VersionMutationResponse>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return response.versionMutations.delete;
|
||||
}
|
||||
|
||||
/// <param name="commitReceivedInput"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="ISpeckleGraphQLClient.ExecuteGraphQLRequest{T}"/>
|
||||
public async Task<bool> Received(
|
||||
CommitReceivedInput commitReceivedInput,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
//TODO: Implement on server
|
||||
return await ((Client)_client).CommitReceived(commitReceivedInput, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: https://app.speckle.systems/graphql
|
||||
documents: '**/*.graphql'
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Speckle.Core.Api.GraphQL;
|
||||
|
||||
/// <summary>
|
||||
/// These are the default roles used by the server
|
||||
/// </summary>
|
||||
public static class StreamRoles
|
||||
{
|
||||
public const string STREAM_OWNER = "stream:owner";
|
||||
public const string STREAM_CONTRIBUTOR = "stream:contributor";
|
||||
public const string STREAM_REVIEWER = "stream:reviewer";
|
||||
public const string? REVOKE = null;
|
||||
}
|
||||
@@ -10,6 +10,8 @@ using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Speckle.Core.Api.GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Credentials;
|
||||
using Speckle.Core.Helpers;
|
||||
using Speckle.Core.Kits;
|
||||
|
||||
@@ -11,4 +11,7 @@ public static class ServerLimits
|
||||
{
|
||||
public const int BRANCH_GET_LIMIT = 500;
|
||||
public const int OLD_BRANCH_GET_LIMIT = 100;
|
||||
|
||||
/// <summary>the default `limit` argument value for paginated requests</summary>
|
||||
public const int DEFAULT_PAGINATION_REQUEST = 25;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Speckle.Core.Api;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Common;
|
||||
using Speckle.Core.Helpers;
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ using GraphQL;
|
||||
using GraphQL.Client.Http;
|
||||
using Speckle.Core.Api;
|
||||
using Speckle.Core.Api.GraphQL;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
using Speckle.Core.Api.GraphQL.Models.Responses;
|
||||
using Speckle.Core.Api.GraphQL.Serializer;
|
||||
using Speckle.Core.Common;
|
||||
using Speckle.Core.Helpers;
|
||||
@@ -115,22 +117,29 @@ public static class AccountManager
|
||||
new NewtonsoftJsonSerializer(),
|
||||
httpClient
|
||||
);
|
||||
|
||||
//language=graphql
|
||||
var request = new GraphQLRequest { Query = " query { activeUser { name email id company } }" };
|
||||
const string QUERY = """
|
||||
query {
|
||||
data:activeUser {
|
||||
name
|
||||
email
|
||||
id
|
||||
company
|
||||
}
|
||||
}
|
||||
""";
|
||||
var request = new GraphQLRequest { Query = QUERY };
|
||||
|
||||
var response = await gqlClient.SendQueryAsync<ActiveUserResponse>(request, cancellationToken).ConfigureAwait(false);
|
||||
var response = await gqlClient
|
||||
.SendQueryAsync<RequiredResponse<UserInfo>>(request, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (response.Errors != null)
|
||||
{
|
||||
throw new SpeckleGraphQLException<ActiveUserResponse>(
|
||||
$"GraphQL request {nameof(GetUserInfo)} failed",
|
||||
request,
|
||||
response
|
||||
);
|
||||
throw new SpeckleGraphQLException($"GraphQL request {nameof(GetUserInfo)} failed", request, response);
|
||||
}
|
||||
|
||||
return response.Data.activeUser;
|
||||
return response.Data.data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -272,21 +281,25 @@ public static class AccountManager
|
||||
await s_accountStorage.WriteComplete().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static IEnumerable<Account> GetAccounts(string serverUrl)
|
||||
{
|
||||
return GetAccounts(new Uri(serverUrl));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all unique accounts matching the serverUrl provided. If an account exists on more than one server,
|
||||
/// typically because it has been migrated, then only the upgraded account (and therefore server) are returned.
|
||||
/// Accounts are deemed to be the same when the Account.Id matches.
|
||||
/// </summary>
|
||||
/// <param name="serverUrl"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<Account> GetAccounts(string serverUrl)
|
||||
/// <param name="serverUrl">Uri for server.</param>
|
||||
public static IEnumerable<Account> GetAccounts(Uri serverUrl)
|
||||
{
|
||||
var accounts = GetAccounts().ToList();
|
||||
List<Account> filtered = new();
|
||||
|
||||
foreach (var acc in accounts)
|
||||
{
|
||||
if (acc.serverInfo?.migration?.movedFrom == new Uri(serverUrl))
|
||||
if (acc.serverInfo?.migration?.movedFrom == serverUrl)
|
||||
{
|
||||
filtered.Add(acc);
|
||||
}
|
||||
@@ -296,7 +309,7 @@ public static class AccountManager
|
||||
{
|
||||
// we use the userInfo to detect the same account rather than the account.id
|
||||
// which should NOT match for essentially the same accounts but on different servers - i.e. FE1 & FE2
|
||||
if (acc.serverInfo.url == serverUrl && !filtered.Any(x => x.userInfo.id == acc.userInfo.id))
|
||||
if (new Uri(acc.serverInfo.url) == serverUrl && !filtered.Any(x => x.userInfo.id == acc.userInfo.id))
|
||||
{
|
||||
filtered.Add(acc);
|
||||
}
|
||||
|
||||
@@ -1,56 +1,42 @@
|
||||
#nullable disable
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Speckle.Core.Api;
|
||||
using Speckle.Core.Api.GraphQL.Models;
|
||||
|
||||
namespace Speckle.Core.Credentials;
|
||||
|
||||
[Obsolete("Use activeUser query and ActiveUserServerInfoResponse instead", true)]
|
||||
public class UserServerInfoResponse
|
||||
internal sealed class ActiveUserServerInfoResponse
|
||||
{
|
||||
public UserInfo user { get; set; }
|
||||
public ServerInfo serverInfo { get; set; }
|
||||
public UserInfo activeUser { get; init; }
|
||||
public ServerInfo serverInfo { get; init; }
|
||||
}
|
||||
|
||||
public class ActiveUserServerInfoResponse
|
||||
internal sealed class TokenExchangeResponse
|
||||
{
|
||||
public UserInfo activeUser { get; set; }
|
||||
public ServerInfo serverInfo { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete("Use activeUser query and ActiveUserResponse instead", true)]
|
||||
public class UserInfoResponse
|
||||
{
|
||||
public UserInfo user { get; set; }
|
||||
}
|
||||
|
||||
public class ActiveUserResponse
|
||||
{
|
||||
public UserInfo activeUser { get; set; }
|
||||
public string token { get; init; }
|
||||
public string refreshToken { get; init; }
|
||||
}
|
||||
|
||||
[ClassInterface(ClassInterfaceType.AutoDual)]
|
||||
[ComVisible(true)]
|
||||
public class UserInfo
|
||||
public sealed class UserInfo
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string email { get; set; }
|
||||
public string company { get; set; }
|
||||
public string avatar { get; set; }
|
||||
public string id { get; init; }
|
||||
public string name { get; init; }
|
||||
public string email { get; init; }
|
||||
public string? company { get; init; }
|
||||
public string? avatar { get; init; }
|
||||
|
||||
public Streams streams { get; set; }
|
||||
public Commits commits { get; set; }
|
||||
}
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public Streams streams { get; init; }
|
||||
|
||||
public class TokenExchangeResponse
|
||||
{
|
||||
public string token { get; set; }
|
||||
public string refreshToken { get; set; }
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public Commits commits { get; init; }
|
||||
}
|
||||
|
||||
[ClassInterface(ClassInterfaceType.AutoDual)]
|
||||
[ComVisible(true)]
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Streams
|
||||
{
|
||||
public int totalCount { get; set; }
|
||||
@@ -58,6 +44,7 @@ public class Streams
|
||||
|
||||
[ClassInterface(ClassInterfaceType.AutoDual)]
|
||||
[ComVisible(true)]
|
||||
[Obsolete(DeprecationMessages.FE2_DEPRECATION_MESSAGE)]
|
||||
public class Commits
|
||||
{
|
||||
public int totalCount { get; set; }
|
||||
|
||||
@@ -417,7 +417,7 @@ public class StreamWrapper
|
||||
// Check if the branch exists
|
||||
if (Type == StreamWrapperType.Branch)
|
||||
{
|
||||
var branch = await client.BranchGet(StreamId, BranchName!, 1).ConfigureAwait(false);
|
||||
var branch = await client.BranchGet(StreamId, BranchName.NotNull(), 1).ConfigureAwait(false);
|
||||
if (branch == null)
|
||||
{
|
||||
throw new SpeckleException(
|
||||
|
||||
@@ -12,6 +12,7 @@ using Polly.Contrib.WaitAndRetry;
|
||||
using Polly.Extensions.Http;
|
||||
using Polly.Retry;
|
||||
using Serilog.Context;
|
||||
using Speckle.Core.Common;
|
||||
using Speckle.Core.Credentials;
|
||||
using Speckle.Core.Logging;
|
||||
|
||||
@@ -165,7 +166,7 @@ public static class Http
|
||||
{
|
||||
if (!string.IsNullOrEmpty(authToken))
|
||||
{
|
||||
bearerHeader = authToken!.ToLowerInvariant().Contains("bearer") ? authToken : $"Bearer {authToken}";
|
||||
bearerHeader = authToken.NotNull().ToLowerInvariant().Contains("bearer") ? authToken : $"Bearer {authToken}";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -236,7 +237,7 @@ public sealed class SpeckleHttpClientHandler : HttpClientHandler
|
||||
);
|
||||
if (policyResult.Outcome == OutcomeType.Successful)
|
||||
{
|
||||
return policyResult.Result!;
|
||||
return policyResult.Result.NotNull();
|
||||
}
|
||||
|
||||
// if the policy failed due to a cancellation, AND it was our cancellation token, then don't wrap the exception, and rethrow an new cancellation
|
||||
|
||||
@@ -8,6 +8,7 @@ using Serilog;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
using Serilog.Exceptions;
|
||||
using Speckle.Core.Common;
|
||||
using Speckle.Core.Credentials;
|
||||
using Speckle.Core.Helpers;
|
||||
|
||||
@@ -104,7 +105,7 @@ public static class SpeckleLog
|
||||
Initialize("Speckle.Core", "unknown");
|
||||
}
|
||||
|
||||
return s_logger!;
|
||||
return s_logger.NotNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using Speckle.Core.Api;
|
||||
using Speckle.Core.Common;
|
||||
using Speckle.Core.Helpers;
|
||||
using Speckle.Core.Kits;
|
||||
using Speckle.Core.Logging;
|
||||
@@ -65,7 +66,7 @@ public class Base : DynamicBase
|
||||
if (_type == null)
|
||||
{
|
||||
List<string> bases = new();
|
||||
Type myType = GetType();
|
||||
var myType = GetType().NotNull();
|
||||
|
||||
while (myType.Name != nameof(Base))
|
||||
{
|
||||
@@ -74,7 +75,7 @@ public class Base : DynamicBase
|
||||
bases.Add(myType.FullName);
|
||||
}
|
||||
|
||||
myType = myType.BaseType!;
|
||||
myType = myType.BaseType;
|
||||
}
|
||||
|
||||
if (bases.Count == 0)
|
||||
@@ -104,11 +105,11 @@ public class Base : DynamicBase
|
||||
/// <returns>the resulting id (hash)</returns>
|
||||
public string GetId(bool decompose = false)
|
||||
{
|
||||
var transports = decompose ? new[] { new MemoryTransport() } : Array.Empty<ITransport>();
|
||||
var transports = decompose ? [new MemoryTransport()] : Array.Empty<ITransport>();
|
||||
var serializer = new BaseObjectSerializerV2(transports);
|
||||
|
||||
string obj = serializer.Serialize(this);
|
||||
return JObject.Parse(obj).GetValue(nameof(id))!.ToString();
|
||||
return JObject.Parse(obj).GetValue(nameof(id))?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Speckle.Core.Common;
|
||||
|
||||
namespace Speckle.Core.Models.GraphTraversal;
|
||||
|
||||
@@ -52,7 +53,7 @@ public sealed class TraversalRule : ITraversalBuilderReturn, ITraversalBuilderTr
|
||||
|
||||
IEnumerable<string> ITraversalRule.MembersToTraverse(Base o)
|
||||
{
|
||||
return _membersToTraverse!(o).Distinct(); //TODO distinct is expensive, there may be a better way for us to avoid duplicates
|
||||
return _membersToTraverse.NotNull()(o).Distinct(); //TODO distinct is expensive, there may be a better way for us to avoid duplicates
|
||||
}
|
||||
|
||||
/// <returns>a new Traversal Rule to be initialised using the Builder Pattern interfaces</returns>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Speckle.Core.Models.Instances;
|
||||
|
||||
/// <summary>
|
||||
/// Abstracts over <see cref="InstanceProxy"/> and <see cref="InstanceDefinitionProxy"/> for sorting and grouping in receive operations.
|
||||
/// </summary>
|
||||
public interface IInstanceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The maximum "depth" at which this <see cref="InstanceProxy"/> or <see cref="InstanceDefinitionProxy"/> was found. On receive, as instances can be composed of other instances, we need to start from the deepest instance elements first when reconstructing them, starting with definitions first.
|
||||
/// </summary>
|
||||
public int MaxDepth { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Speckle.Core.Models.Instances;
|
||||
|
||||
/// <summary>
|
||||
/// A proxy class for an instance definition.
|
||||
/// </summary>
|
||||
public class InstanceDefinitionProxy : Base, IInstanceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The original ids of the objects that are part of this definition, as present in the source host app. On receive, they will be mapped to corresponding newly created definition ids.
|
||||
/// </summary>
|
||||
public List<string> Objects { get; set; } // source app application ids for the objects
|
||||
|
||||
public int MaxDepth { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Speckle.DoubleNumerics;
|
||||
|
||||
namespace Speckle.Core.Models.Instances;
|
||||
|
||||
/// <summary>
|
||||
/// A proxy class for an instance (e.g, a rhino block, or an autocad block reference).
|
||||
/// </summary>
|
||||
public class InstanceProxy : Base, IInstanceComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The definition id as present in the original host app. On receive, it will be mapped to the newly created definition id.
|
||||
/// </summary>
|
||||
public string DefinitionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The transform of the instance reference.
|
||||
/// </summary>
|
||||
public Matrix4x4 Transform { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The units of the host application file.
|
||||
/// </summary>
|
||||
public string Units { get; set; } = Kits.Units.Meters;
|
||||
|
||||
public int MaxDepth { get; set; }
|
||||
}
|
||||
@@ -151,7 +151,7 @@ public sealed class BaseObjectDeserializerV2
|
||||
return null;
|
||||
}
|
||||
// Try background work
|
||||
Task<object?>? bgResult = _workerThreads!.TryStartTask(WorkerThreadTaskType.Deserialize, objectJson); //BUG: Because we don't guarantee this task will ever be awaited, this may lead to unobserved exceptions!
|
||||
Task<object?>? bgResult = _workerThreads?.TryStartTask(WorkerThreadTaskType.Deserialize, objectJson); //BUG: Because we don't guarantee this task will ever be awaited, this may lead to unobserved exceptions!
|
||||
if (bgResult != null)
|
||||
{
|
||||
return bgResult;
|
||||
@@ -340,7 +340,7 @@ public sealed class BaseObjectDeserializerV2
|
||||
|
||||
private Base Dict2Base(Dictionary<string, object?> dictObj)
|
||||
{
|
||||
string typeName = (string)dictObj[TYPE_DISCRIMINATOR]!;
|
||||
string typeName = (string)dictObj[TYPE_DISCRIMINATOR].NotNull();
|
||||
Type type = BaseObjectSerializationUtilities.GetType(typeName);
|
||||
Base baseObj = (Base)Activator.CreateInstance(type);
|
||||
|
||||
|
||||
@@ -2,17 +2,19 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.DoubleNumerics;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Speckle.Core.Helpers;
|
||||
using Sentry;
|
||||
using Speckle.Core.Common;
|
||||
using Speckle.Core.Logging;
|
||||
using Speckle.Core.Models;
|
||||
using Speckle.Core.Transports;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
using Constants = Speckle.Core.Helpers.Constants;
|
||||
using Utilities = Speckle.Core.Models.Utilities;
|
||||
|
||||
namespace Speckle.Core.Serialisation;
|
||||
@@ -87,14 +89,19 @@ public class BaseObjectSerializerV2
|
||||
IDictionary<string, object?> converted;
|
||||
try
|
||||
{
|
||||
converted = PreserializeBase(baseObj, true)!;
|
||||
var x = PreserializeBase(baseObj, true);
|
||||
if (x is null)
|
||||
{
|
||||
throw new SpeckleSerializeException("Already serialized");
|
||||
}
|
||||
converted = x;
|
||||
}
|
||||
catch (Exception ex) when (!ex.IsFatal())
|
||||
{
|
||||
throw new SpeckleSerializeException($"Failed to extract (pre-serialize) properties from the {baseObj}", ex);
|
||||
}
|
||||
string serialized = Dict2Json(converted);
|
||||
StoreObject((string)converted["id"]!, serialized);
|
||||
StoreObject((string)converted["id"].NotNull(), serialized);
|
||||
return serialized;
|
||||
}
|
||||
finally
|
||||
@@ -239,7 +246,7 @@ public class BaseObjectSerializerV2
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, object?>? PreserializeBase(
|
||||
private IDictionary<string, object?>? PreserializeBase(
|
||||
Base baseObj,
|
||||
bool computeClosures = false,
|
||||
PropertyAttributeInfo inheritedDetachInfo = default
|
||||
@@ -332,8 +339,8 @@ public class BaseObjectSerializerV2
|
||||
|
||||
if (inheritedDetachInfo.IsDetachable && WriteTransports.Count > 0)
|
||||
{
|
||||
string json = Dict2Json(convertedBase);
|
||||
string id = (string)convertedBase["id"]!;
|
||||
var json = Dict2Json(convertedBase);
|
||||
var id = (string)convertedBase["id"].NotNull();
|
||||
StoreObject(id, json);
|
||||
ObjectReference objRef = new() { referencedId = id };
|
||||
var objRefConverted = (IDictionary<string, object?>?)PreserializeObject(objRef);
|
||||
@@ -413,6 +420,10 @@ public class BaseObjectSerializerV2
|
||||
|
||||
private static string Dict2Json(IDictionary<string, object?>? obj)
|
||||
{
|
||||
if (obj is null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
string serialized = JsonConvert.SerializeObject(obj);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.DoubleNumerics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using Speckle.Core.Logging;
|
||||
using Speckle.DoubleNumerics;
|
||||
using Numerics = System.Numerics;
|
||||
|
||||
namespace Speckle.Core.Serialisation.SerializationUtilities;
|
||||
@@ -157,16 +158,17 @@ internal static class ValueConverter
|
||||
#endregion
|
||||
}
|
||||
|
||||
// Handle List<?>
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
|
||||
// Handle List<>, IList<>, and IReadOnlyList<>
|
||||
if (type.IsGenericType && IsGenericList(type))
|
||||
{
|
||||
if (value is not List<object> valueList)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var targetType = typeof(List<>).MakeGenericType(type.GenericTypeArguments);
|
||||
Type listElementType = type.GenericTypeArguments[0];
|
||||
IList ret = (IList)Activator.CreateInstance(type, valueList.Count);
|
||||
IList ret = (IList)Activator.CreateInstance(targetType, valueList.Count);
|
||||
foreach (object inputListElement in valueList)
|
||||
{
|
||||
if (!ConvertValue(listElementType, inputListElement, out object? convertedListElement))
|
||||
@@ -311,4 +313,21 @@ internal static class ValueConverter
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that the given <paramref name="type"/> is assignable from a generic type def <see cref="List{T}"/>
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
[Pure]
|
||||
private static bool IsGenericList(Type type)
|
||||
{
|
||||
if (!type.IsGenericType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Type typeDef = type.GetGenericTypeDefinition();
|
||||
return typeDef == typeof(List<>) || typeDef == typeof(IList<>) || typeDef == typeof(IReadOnlyList<>);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<Description>Core is the .NET SDK for Speckle</Description>
|
||||
<PackageTags>$(PackageTags) core</PackageTags>
|
||||
<IsPackable>true</IsPackable>
|
||||
<PolySharpExcludeGeneratedTypes>System.Runtime.CompilerServices.IsExternalInit;System.Runtime.CompilerServices.RequiresLocationAttribute</PolySharpExcludeGeneratedTypes>
|
||||
<PolySharpExcludeGeneratedTypes>System.Runtime.CompilerServices.RequiresLocationAttribute</PolySharpExcludeGeneratedTypes>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -34,7 +34,7 @@
|
||||
<PackageReference Include="SerilogTimings" />
|
||||
<PackageReference Include="Speckle.Newtonsoft.Json"/>
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" />
|
||||
<PackageReference Include="System.DoubleNumerics" />
|
||||
<PackageReference Include="Speckle.DoubleNumerics" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -21,12 +21,12 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite": {
|
||||
"type": "Direct",
|
||||
"requested": "[7.0.5, )",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "KGxbPeWsQMnmQy43DSBxAFtHz3l2JX8EWBSGUCvT3CuZ8KsuzbkqMIJMDOxWtG8eZSoCDI04aiVQjWuuV8HmSw==",
|
||||
"requested": "[8.0.6, )",
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "YVzVtU1IoGsTiMAe0BNV9ssKyrUm6lBQJP6w2N4W29YrBYYtyCmTFmrNGjxaJtJXVqttu0sYkPxmStj/OnMFdg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.Sqlite.Core": "7.0.5",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.4"
|
||||
"Microsoft.Data.Sqlite.Core": "8.0.6",
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.6"
|
||||
}
|
||||
},
|
||||
"Microsoft.SourceLink.GitHub": {
|
||||
@@ -157,21 +157,18 @@
|
||||
"Serilog": "2.10.0"
|
||||
}
|
||||
},
|
||||
"Speckle.DoubleNumerics": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.0.1-alpha.3, )",
|
||||
"resolved": "4.0.1-alpha.3",
|
||||
"contentHash": "7/lg9LDI3TZLiI7FhI2IhRrTzsZyDrQw1rG/S3kRtx0IU3raWzRHL4W5zvHV8LdWkqJEztS/9dUgLNYHV70o5Q=="
|
||||
},
|
||||
"Speckle.Newtonsoft.Json": {
|
||||
"type": "Direct",
|
||||
"requested": "[13.0.2, )",
|
||||
"resolved": "13.0.2",
|
||||
"contentHash": "g1BejUZwax5PRfL6xHgLEK23sqHWOgOj9hE7RvfRRlN00AGt8GnPYt8HedSK7UB3HiRW8zCA9Pn0iiYxCK24BA=="
|
||||
},
|
||||
"System.DoubleNumerics": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.1.3, )",
|
||||
"resolved": "3.1.3",
|
||||
"contentHash": "KRKEM/L3KBodjA9VOg3EifFVWUY6EOqaMB05UvPEDm7Zeby/kZW+4kdWUEPzW6xtkwf46p661L9NrbeeQhtLzw==",
|
||||
"dependencies": {
|
||||
"NETStandard.Library": "1.6.1"
|
||||
}
|
||||
},
|
||||
"GraphQL.Client.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
@@ -246,10 +243,10 @@
|
||||
},
|
||||
"Microsoft.Data.Sqlite.Core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.5",
|
||||
"contentHash": "FTerRmQPqHrCrnoUzhBu+E+1DNGwyrAMLqHkAqOOOu5pGfyMOj8qQUBxI/gDtWtG11p49UxSfWmBzRNlwZqfUg==",
|
||||
"resolved": "8.0.6",
|
||||
"contentHash": "umhZ0ZF2RI81rGFTnYmCxI+Euj4Aqe/6Y4+8CxN9OVJNGDNIqB5laJ3wxQTU8zXCcm2k9F7FL+/6RVoOT4z1Fw==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
"SQLitePCLRaw.core": "2.1.6"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": {
|
||||
@@ -330,32 +327,32 @@
|
||||
},
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "EWI1olKDjFEBMJu0+3wuxwziIAdWDVMYLhuZ3Qs84rrz+DHwD00RzWPZCa+bLnHCf3oJwuFZIRsHT5p236QXww==",
|
||||
"resolved": "2.1.6",
|
||||
"contentHash": "BmAf6XWt4TqtowmiWe4/5rRot6GerAeklmOPfviOvwLoF5WwgxcJHAxZtySuyW9r9w+HLILnm8VfJFLCUJYW8A==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.4",
|
||||
"SQLitePCLRaw.provider.e_sqlite3": "2.1.4"
|
||||
"SQLitePCLRaw.lib.e_sqlite3": "2.1.6",
|
||||
"SQLitePCLRaw.provider.e_sqlite3": "2.1.6"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "inBjvSHo9UDKneGNzfUfDjK08JzlcIhn1+SP5Y3m6cgXpCxXKCJDy6Mka7LpgSV+UZmKSnC8rTwB0SQ0xKu5pA==",
|
||||
"resolved": "2.1.6",
|
||||
"contentHash": "wO6v9GeMx9CUngAet8hbO7xdm+M42p1XeJq47ogyRoYSvNSp0NGLI+MgC0bhrMk9C17MTVFlLiN6ylyExLCc5w==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.3"
|
||||
}
|
||||
},
|
||||
"SQLitePCLRaw.lib.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "2C9Q9eX7CPLveJA0rIhf9RXAvu+7nWZu1A2MdG6SD/NOu26TakGgL1nsbc0JAspGijFOo3HoN79xrx8a368fBg=="
|
||||
"resolved": "2.1.6",
|
||||
"contentHash": "2ObJJLkIUIxRpOUlZNGuD4rICpBnrBR5anjyfUFQep4hMOIeqW+XGQYzrNmHSVz5xSWZ3klSbh7sFR6UyDj68Q=="
|
||||
},
|
||||
"SQLitePCLRaw.provider.e_sqlite3": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.1.4",
|
||||
"contentHash": "CSlb5dUp1FMIkez9Iv5EXzpeq7rHryVNqwJMWnpq87j9zWZexaEMdisDktMsnnrzKM6ahNrsTkjqNodTBPBxtQ==",
|
||||
"resolved": "2.1.6",
|
||||
"contentHash": "PQ2Oq3yepLY4P7ll145P3xtx2bX8xF4PzaKPRpw9jZlKvfe4LE/saAV82inND9usn1XRpmxXk7Lal3MTI+6CNg==",
|
||||
"dependencies": {
|
||||
"SQLitePCLRaw.core": "2.1.4"
|
||||
"SQLitePCLRaw.core": "2.1.6"
|
||||
}
|
||||
},
|
||||
"System.Buffers": {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System.Collections.Generic;
|
||||
using Objects.Geometry;
|
||||
using Objects.Structural.Materials;
|
||||
using Objects.Structural.Properties.Profiles;
|
||||
using Speckle.Core.Kits;
|
||||
@@ -7,7 +5,7 @@ using Speckle.Core.Models;
|
||||
|
||||
namespace Objects.BuiltElements.AdvanceSteel;
|
||||
|
||||
public class AsteelBeam : Beam, IDisplayValue<List<Mesh>>, IHasVolume, IHasArea, IAsteelObject
|
||||
public class AsteelBeam : Beam, IHasVolume, IHasArea, IAsteelObject
|
||||
{
|
||||
[DetachProperty]
|
||||
public SectionProfile profile { get; set; }
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Collections.Generic;
|
||||
using Objects.Geometry;
|
||||
using Speckle.Core.Kits;
|
||||
using Speckle.Core.Models;
|
||||
|
||||
namespace Objects.BuiltElements.Archicad;
|
||||
|
||||
public class ArchicadOpening : Opening
|
||||
{
|
||||
[SchemaInfo("ArchicadOpening", "Creates an Archicad opening.", "Archicad", "Structure")]
|
||||
public ArchicadOpening() { }
|
||||
|
||||
public string parentApplicationId { get; set; }
|
||||
|
||||
// Element base
|
||||
public string? elementType { get; set; } /*APINullabe*/
|
||||
|
||||
public List<Classification>? classifications { get; set; } /*APINullabe*/
|
||||
public Base? elementProperties { get; set; }
|
||||
public Base? componentProperties { get; set; }
|
||||
|
||||
// Floor Plan Parameters
|
||||
public string? floorPlanDisplayMode { get; set; } /*APINullabe*/
|
||||
public string? connectionMode { get; set; } /*APINullabe*/
|
||||
|
||||
// Cut Surfaces Parameters
|
||||
public bool? cutsurfacesUseLineOfCutElements { get; set; } /*APINullabe*/
|
||||
public short? cutsurfacesLinePenIndex { get; set; } /*APINullabe*/
|
||||
public string? cutsurfacesLineIndex { get; set; } /*APINullabe*/
|
||||
|
||||
// Outlines Parameters
|
||||
public string? outlinesStyle { get; set; } /*APINullabe*/
|
||||
public bool? outlinesUseLineOfCutElements { get; set; } /*APINullabe*/
|
||||
public string? outlinesUncutLineIndex { get; set; } /*APINullabe*/
|
||||
public string? outlinesOverheadLineIndex { get; set; } /*APINullabe*/
|
||||
public short? outlinesUncutLinePenIndex { get; set; } /*APINullabe*/
|
||||
public short? outlinesOverheadLinePenIndex { get; set; } /*APINullabe*/
|
||||
|
||||
// Opening Cover Fills Parameters
|
||||
public bool? useCoverFills { get; set; } /*APINullabe*/
|
||||
public bool? useFillsOfCutElements { get; set; } /*APINullabe*/
|
||||
public string? coverFillIndex { get; set; } /*APINullabe*/
|
||||
public short? coverFillPenIndex { get; set; } /*APINullabe*/
|
||||
public short? coverFillBackgroundPenIndex { get; set; } /*APINullabe*/
|
||||
public string? coverFillOrientation { get; set; } /*APINullabe*/ // Kérdéses..
|
||||
|
||||
// Cover Fill Transformation Parameters
|
||||
public double? coverFillTransformationOrigoX { get; set; }
|
||||
public double? coverFillTransformationOrigoY { get; set; }
|
||||
public double? coverFillTransformationOrigoZ { get; set; }
|
||||
public double? coverFillTransformationXAxisX { get; set; }
|
||||
public double? coverFillTransformationXAxisY { get; set; }
|
||||
public double? coverFillTransformationXAxisZ { get; set; }
|
||||
public double? coverFillTransformationYAxisX { get; set; }
|
||||
public double? coverFillTransformationYAxisY { get; set; }
|
||||
public double? coverFillTransformationYAxisZ { get; set; }
|
||||
|
||||
// Reference Axis Parameters
|
||||
public bool? showReferenceAxis { get; set; } /*APINullabe*/
|
||||
public short? referenceAxisPenIndex { get; set; } /*APINullabe*/
|
||||
public string? referenceAxisLineTypeIndex { get; set; } /*APINullabe*/
|
||||
public double? referenceAxisOverhang { get; set; } /*APINullabe*/
|
||||
|
||||
// Extrusion Geometry Parameters
|
||||
// Plane Frame
|
||||
public Point extrusionGeometryBasePoint { get; set; }
|
||||
public Vector extrusionGeometryXAxis { get; set; }
|
||||
public Vector extrusionGeometryYAxis { get; set; }
|
||||
public Vector extrusionGeometryZAxis { get; set; }
|
||||
|
||||
// Opening Extrustion Parameters
|
||||
public string? basePolygonType { get; set; } /*APINullabe*/
|
||||
public double? width { get; set; } /*APINullabe*/
|
||||
public double? height { get; set; } /*APINullabe*/
|
||||
public string? constraint { get; set; } /*APINullabe*/
|
||||
public string? anchor { get; set; } /*APINullabe */
|
||||
public int? anchorIndex { get; set; } /*APINullabe*/
|
||||
public double? anchorAltitude { get; set; } /*APINullabe*/
|
||||
public string? limitType { get; set; } /*APINullabe*/
|
||||
public double? extrusionStartOffSet { get; set; } /*APINullabe*/
|
||||
public double? finiteBodyLength { get; set; } /*APINullabe*/
|
||||
public string? linkedStatus { get; set; } /*APINullabe*/
|
||||
}
|
||||
@@ -16,7 +16,10 @@ public class DirectShape : Base
|
||||
|
||||
// Element base
|
||||
public string elementType { get; set; }
|
||||
|
||||
public List<Classification> classifications { get; set; }
|
||||
public Base? elementProperties { get; set; }
|
||||
public Base? componentProperties { get; set; }
|
||||
|
||||
public ArchicadLevel level { get; set; }
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using Objects.Geometry;
|
||||
using Objects.Primitive;
|
||||
using Speckle.Core.Kits;
|
||||
using Speckle.Core.Models;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
|
||||
namespace Objects.BuiltElements.Archicad;
|
||||
|
||||
@@ -19,6 +21,9 @@ public sealed class ElementShape : Base
|
||||
|
||||
public List<Polyline>? holePolylines { get; set; }
|
||||
|
||||
/// <remarks>
|
||||
/// This class is only used for Archicad interop
|
||||
/// </remarks>
|
||||
public sealed class PolylineSegment : Base, ICurve
|
||||
{
|
||||
public PolylineSegment() { }
|
||||
@@ -33,21 +38,30 @@ public sealed class ElementShape : Base
|
||||
|
||||
public Point startPoint { get; set; }
|
||||
public Point endPoint { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string units => Units.Meters;
|
||||
public double arcAngle { get; set; }
|
||||
public bool? bodyFlag { get; set; }
|
||||
public double length { get; set; }
|
||||
public Interval domain { get; set; } = new(0, 1);
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// This class is only used for Archicad interop
|
||||
/// </remarks>
|
||||
public sealed class Polyline : Base, ICurve
|
||||
{
|
||||
public Polyline() { }
|
||||
|
||||
public Polyline(List<PolylineSegment> segments)
|
||||
{
|
||||
polylineSegments = segments;
|
||||
this.polylineSegments = segments;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public string units => Units.Meters;
|
||||
|
||||
public List<PolylineSegment> polylineSegments { get; set; } = new();
|
||||
public double length { get; set; }
|
||||
public Interval domain { get; set; } = new(0, 1);
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
using Speckle.Core.Models;
|
||||
using Speckle.Newtonsoft.Json;
|
||||
|
||||
namespace Objects.BuiltElements;
|
||||
|
||||
public abstract class Baseline : Base
|
||||
{
|
||||
protected Baseline() { }
|
||||
|
||||
protected Baseline(string name, bool isFeaturelineBased)
|
||||
{
|
||||
this.name = name;
|
||||
this.isFeaturelineBased = isFeaturelineBased;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of this baseline
|
||||
/// </summary>
|
||||
public string name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The horizontal component of this baseline
|
||||
/// </summary>
|
||||
public abstract Alignment? alignment { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The vertical component of this baseline
|
||||
/// </summary>
|
||||
public abstract Profile? profile { get; internal set; }
|
||||
|
||||
[DetachProperty]
|
||||
public Featureline? featureline { get; internal set; }
|
||||
|
||||
public bool isFeaturelineBased { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generic instance class
|
||||
/// </summary>
|
||||
public abstract class Baseline<TA, TP> : Baseline
|
||||
where TA : Alignment
|
||||
where TP : Profile
|
||||
{
|
||||
protected Baseline(string name, TA alignment, TP profile, Featureline? featureline, bool isFeaturelineBased)
|
||||
: base(name, isFeaturelineBased)
|
||||
{
|
||||
this.name = name;
|
||||
typedAlignment = alignment;
|
||||
typedProfile = profile;
|
||||
this.featureline = featureline;
|
||||
this.isFeaturelineBased = isFeaturelineBased;
|
||||
}
|
||||
|
||||
protected Baseline()
|
||||
: base(string.Empty, false) { }
|
||||
|
||||
[JsonIgnore]
|
||||
public TA typedAlignment { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public TP typedProfile { get; set; }
|
||||
|
||||
[DetachProperty]
|
||||
public override Alignment? alignment
|
||||
{
|
||||
get => typedAlignment;
|
||||
internal set
|
||||
{
|
||||
if (value is TA typeA)
|
||||
{
|
||||
typedAlignment = typeA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DetachProperty]
|
||||
public override Profile? profile
|
||||
{
|
||||
get => typedProfile;
|
||||
internal set
|
||||
{
|
||||
if (value is TP typeP)
|
||||
{
|
||||
typedProfile = typeP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,22 +5,31 @@ using Speckle.Core.Models;
|
||||
|
||||
namespace Objects.BuiltElements;
|
||||
|
||||
public class Beam : Base, IDisplayValue<List<Mesh>>
|
||||
public class Beam : Base, IDisplayValue<IReadOnlyList<Base>>
|
||||
{
|
||||
public Beam() { }
|
||||
|
||||
[SchemaInfo("Beam", "Creates a Speckle beam", "BIM", "Structure")]
|
||||
public Beam([SchemaMainParam] ICurve baseLine)
|
||||
public Beam(ICurve baseLine, Level? level, string? units, IReadOnlyList<Mesh>? displayValue = null)
|
||||
{
|
||||
this.baseLine = baseLine;
|
||||
this.level = level;
|
||||
this.units = units;
|
||||
this.displayValue = ((IReadOnlyList<Base>?)displayValue) ?? new[] { (Base)baseLine };
|
||||
}
|
||||
|
||||
public ICurve baseLine { get; set; }
|
||||
|
||||
public virtual Level? level { get; internal set; }
|
||||
|
||||
public string units { get; set; }
|
||||
public string? units { get; set; }
|
||||
|
||||
[DetachProperty]
|
||||
public List<Mesh> displayValue { get; set; }
|
||||
public IReadOnlyList<Base> displayValue { get; set; }
|
||||
|
||||
#region Schema Info Constructors
|
||||
[SchemaInfo("Beam", "Creates a Speckle beam", "BIM", "Structure")]
|
||||
public Beam([SchemaMainParam] ICurve baseLine)
|
||||
: this(baseLine, null, null) { }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -5,20 +5,25 @@ using Speckle.Core.Models;
|
||||
|
||||
namespace Objects.BuiltElements;
|
||||
|
||||
public class Brace : Base, IDisplayValue<List<Mesh>>
|
||||
public class Brace : Base, IDisplayValue<IReadOnlyList<Base>>
|
||||
{
|
||||
public Brace() { }
|
||||
|
||||
[SchemaInfo("Brace", "Creates a Speckle brace", "BIM", "Structure")]
|
||||
public Brace([SchemaMainParam] ICurve baseLine)
|
||||
public Brace(ICurve baseLine, string? units, IReadOnlyList<Mesh>? displayValue = null)
|
||||
{
|
||||
this.baseLine = baseLine;
|
||||
this.units = units;
|
||||
this.displayValue = ((IReadOnlyList<Base>?)displayValue) ?? new[] { (Base)baseLine };
|
||||
}
|
||||
|
||||
public ICurve baseLine { get; set; }
|
||||
|
||||
public string units { get; set; }
|
||||
public string? units { get; set; }
|
||||
|
||||
[DetachProperty]
|
||||
public List<Mesh> displayValue { get; set; }
|
||||
public IReadOnlyList<Base> displayValue { get; set; }
|
||||
|
||||
[SchemaInfo("Brace", "Creates a Speckle brace", "BIM", "Structure")]
|
||||
public Brace([SchemaMainParam] ICurve baseLine)
|
||||
: this(baseLine, null) { }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using Speckle.Core.Models;
|
||||
|
||||
namespace Objects.BuiltElements.Civil;
|
||||
|
||||
public class CivilAppliedAssembly : Base
|
||||
{
|
||||
public CivilAppliedAssembly() { }
|
||||
|
||||
public CivilAppliedAssembly(
|
||||
List<CivilAppliedSubassembly> appliedSubassemblies,
|
||||
double adjustedElevation,
|
||||
string units
|
||||
)
|
||||
{
|
||||
this.appliedSubassemblies = appliedSubassemblies;
|
||||
this.adjustedElevation = adjustedElevation;
|
||||
this.units = units;
|
||||
}
|
||||
|
||||
public List<CivilAppliedSubassembly> appliedSubassemblies { get; set; }
|
||||
|
||||
public double adjustedElevation { get; set; }
|
||||
|
||||
public string units { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using Objects.Geometry;
|
||||
using Objects.Other.Civil;
|
||||
using Speckle.Core.Models;
|
||||
|
||||
namespace Objects.BuiltElements.Civil;
|
||||
|
||||
public class CivilAppliedSubassembly : Base
|
||||
{
|
||||
public CivilAppliedSubassembly() { }
|
||||
|
||||
public CivilAppliedSubassembly(
|
||||
string subassemblyId,
|
||||
string subassemblyName,
|
||||
List<CivilCalculatedShape> shapes,
|
||||
Point stationOffsetElevationToBaseline,
|
||||
List<CivilDataField> parameters
|
||||
)
|
||||
{
|
||||
this.subassemblyId = subassemblyId;
|
||||
this.subassemblyName = subassemblyName;
|
||||
this.shapes = shapes;
|
||||
this.stationOffsetElevationToBaseline = stationOffsetElevationToBaseline;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public string subassemblyId { get; set; }
|
||||
|
||||
public string subassemblyName { get; set; }
|
||||
|
||||
public List<CivilCalculatedShape> shapes { get; set; }
|
||||
|
||||
public Point stationOffsetElevationToBaseline { get; set; }
|
||||
|
||||
[DetachProperty]
|
||||
public List<CivilDataField> parameters { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Objects.BuiltElements.Civil;
|
||||
|
||||
public class CivilBaseline : Baseline<CivilAlignment, CivilProfile>
|
||||
{
|
||||
public CivilBaseline() { }
|
||||
|
||||
public CivilBaseline(
|
||||
string name,
|
||||
List<CivilBaselineRegion> regions,
|
||||
List<double> stations,
|
||||
double startStation,
|
||||
double endStation,
|
||||
CivilAlignment alignment,
|
||||
CivilProfile profile
|
||||
)
|
||||
{
|
||||
this.name = name;
|
||||
this.regions = regions;
|
||||
this.stations = stations;
|
||||
this.startStation = startStation;
|
||||
this.endStation = endStation;
|
||||
this.alignment = alignment;
|
||||
this.profile = profile;
|
||||
isFeaturelineBased = false;
|
||||
}
|
||||
|
||||
public CivilBaseline(
|
||||
string name,
|
||||
List<CivilBaselineRegion> regions,
|
||||
List<double> stations,
|
||||
double startStation,
|
||||
double endStation,
|
||||
Featureline featureline
|
||||
)
|
||||
{
|
||||
this.name = name;
|
||||
this.regions = regions;
|
||||
this.stations = stations;
|
||||
this.startStation = startStation;
|
||||
this.endStation = endStation;
|
||||
this.featureline = featureline;
|
||||
isFeaturelineBased = true;
|
||||
}
|
||||
|
||||
public List<CivilBaselineRegion> regions { get; set; }
|
||||
|
||||
public List<double> stations { get; set; }
|
||||
|
||||
public double startStation { get; set; }
|
||||
|
||||
public double endStation { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using Speckle.Core.Models;
|
||||
|
||||
namespace Objects.BuiltElements.Civil;
|
||||
|
||||
public class CivilBaselineRegion : Base
|
||||
{
|
||||
public CivilBaselineRegion() { }
|
||||
|
||||
public CivilBaselineRegion(
|
||||
string name,
|
||||
double startStation,
|
||||
double endStation,
|
||||
string assemblyId,
|
||||
string? assemblyName,
|
||||
List<CivilAppliedAssembly> appliedAssemblies
|
||||
)
|
||||
{
|
||||
this.name = name;
|
||||
this.startStation = startStation;
|
||||
this.endStation = endStation;
|
||||
this.assemblyId = assemblyId;
|
||||
this.assemblyName = assemblyName;
|
||||
this.appliedAssemblies = appliedAssemblies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the region
|
||||
/// </summary>
|
||||
public string name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The id of the assembly of the region
|
||||
/// </summary>
|
||||
public string assemblyId { get; set; }
|
||||
|
||||
public string? assemblyName { get; set; }
|
||||
|
||||
public double startStation { get; set; }
|
||||
|
||||
public double endStation { get; set; }
|
||||
|
||||
[DetachProperty]
|
||||
public List<CivilAppliedAssembly> appliedAssemblies { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using Speckle.Core.Models;
|
||||
|
||||
namespace Objects.BuiltElements.Civil;
|
||||
|
||||
public class CivilCalculatedLink : Base, ICivilCalculatedObject
|
||||
{
|
||||
public CivilCalculatedLink() { }
|
||||
|
||||
public CivilCalculatedLink(List<string> codes, List<CivilCalculatedPoint> points)
|
||||
{
|
||||
this.codes = codes;
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
public List<string> codes { get; set; }
|
||||
|
||||
[DetachProperty]
|
||||
public List<CivilCalculatedPoint> points { get; set; }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user