diff --git a/csharp/.gitignore b/csharp/.gitignore new file mode 100644 index 000000000..0a3438179 --- /dev/null +++ b/csharp/.gitignore @@ -0,0 +1 @@ +.vs \ No newline at end of file diff --git a/csharp/csharp.csproj b/csharp/LookerSdk.Tests/LookerSdk.Tests.csproj similarity index 53% rename from csharp/csharp.csproj rename to csharp/LookerSdk.Tests/LookerSdk.Tests.csproj index 01dda240f..cc630dcee 100644 --- a/csharp/csharp.csproj +++ b/csharp/LookerSdk.Tests/LookerSdk.Tests.csproj @@ -2,17 +2,24 @@ net6.0 false - false 10 + Library - bin\Debug/net6.0/ + bin\Debug - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/csharp/rtl.Tests/ApiMethodsTests.cs b/csharp/LookerSdk.Tests/rtl.Tests/ApiMethodsTests.cs similarity index 99% rename from csharp/rtl.Tests/ApiMethodsTests.cs rename to csharp/LookerSdk.Tests/rtl.Tests/ApiMethodsTests.cs index 5e247fa59..916dd317b 100644 --- a/csharp/rtl.Tests/ApiMethodsTests.cs +++ b/csharp/LookerSdk.Tests/rtl.Tests/ApiMethodsTests.cs @@ -44,4 +44,4 @@ public async Task GetHtmlUrlTest() Assert.Contains(_config.HtmlTestContent, actual); } } -} \ No newline at end of file +} diff --git a/csharp/rtl.Tests/ApiSettingsTests.cs b/csharp/LookerSdk.Tests/rtl.Tests/ApiSettingsTests.cs similarity index 100% rename from csharp/rtl.Tests/ApiSettingsTests.cs rename to csharp/LookerSdk.Tests/rtl.Tests/ApiSettingsTests.cs diff --git a/csharp/rtl.Tests/AuthSessionTests.cs b/csharp/LookerSdk.Tests/rtl.Tests/AuthSessionTests.cs similarity index 100% rename from csharp/rtl.Tests/AuthSessionTests.cs rename to csharp/LookerSdk.Tests/rtl.Tests/AuthSessionTests.cs diff --git a/csharp/rtl.Tests/AuthTokenTests.cs b/csharp/LookerSdk.Tests/rtl.Tests/AuthTokenTests.cs similarity index 100% rename from csharp/rtl.Tests/AuthTokenTests.cs rename to csharp/LookerSdk.Tests/rtl.Tests/AuthTokenTests.cs diff --git a/csharp/rtl.Tests/SdkMethodsTests.cs b/csharp/LookerSdk.Tests/rtl.Tests/SdkMethodsTests.cs similarity index 100% rename from csharp/rtl.Tests/SdkMethodsTests.cs rename to csharp/LookerSdk.Tests/rtl.Tests/SdkMethodsTests.cs diff --git a/csharp/rtl.Tests/SdkUtilsTests.cs b/csharp/LookerSdk.Tests/rtl.Tests/SdkUtilsTests.cs similarity index 100% rename from csharp/rtl.Tests/SdkUtilsTests.cs rename to csharp/LookerSdk.Tests/rtl.Tests/SdkUtilsTests.cs diff --git a/csharp/rtl.Tests/TestUtils.cs b/csharp/LookerSdk.Tests/rtl.Tests/TestUtils.cs similarity index 100% rename from csharp/rtl.Tests/TestUtils.cs rename to csharp/LookerSdk.Tests/rtl.Tests/TestUtils.cs diff --git a/csharp/rtl.Tests/TransportTests.cs b/csharp/LookerSdk.Tests/rtl.Tests/TransportTests.cs similarity index 95% rename from csharp/rtl.Tests/TransportTests.cs rename to csharp/LookerSdk.Tests/rtl.Tests/TransportTests.cs index ed1cefeb6..b7a5bff29 100644 --- a/csharp/rtl.Tests/TransportTests.cs +++ b/csharp/LookerSdk.Tests/rtl.Tests/TransportTests.cs @@ -1,10 +1,9 @@ using System; using System.Net; using System.Net.Http; -using System.Text.Json; using System.Threading.Tasks; using Looker.RTL; -using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel; +using Newtonsoft.Json; using Xunit; using Xunit.Abstractions; @@ -62,7 +61,7 @@ public async Task GetJsonUrlTest() var content = actual.Body.ToString(); Assert.NotNull(content); Assert.Contains("looker_release_version", content); - var json = JsonSerializer.Deserialize(content); + var json = JsonConvert.DeserializeObject(content); Assert.Equal(json.Keys, _versionKeys); } diff --git a/csharp/rtl.Tests/sdkrtl.Tests.csproj b/csharp/LookerSdk.Tests/rtl.Tests/sdkrtl.Tests.csproj similarity index 100% rename from csharp/rtl.Tests/sdkrtl.Tests.csproj rename to csharp/LookerSdk.Tests/rtl.Tests/sdkrtl.Tests.csproj diff --git a/csharp/LookerSdk/LookerSdk.csproj b/csharp/LookerSdk/LookerSdk.csproj new file mode 100644 index 000000000..8cdfcb23b --- /dev/null +++ b/csharp/LookerSdk/LookerSdk.csproj @@ -0,0 +1,14 @@ + + + netstandard2.0 + true + 10 + + + bin\Debug + + + + + + diff --git a/csharp/rtl/ApiMethods.cs b/csharp/LookerSdk/rtl/ApiMethods.cs similarity index 100% rename from csharp/rtl/ApiMethods.cs rename to csharp/LookerSdk/rtl/ApiMethods.cs diff --git a/csharp/rtl/ApiSettings.cs b/csharp/LookerSdk/rtl/ApiSettings.cs similarity index 96% rename from csharp/rtl/ApiSettings.cs rename to csharp/LookerSdk/rtl/ApiSettings.cs index 300264843..50078011a 100644 --- a/csharp/rtl/ApiSettings.cs +++ b/csharp/LookerSdk/rtl/ApiSettings.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using IniParser; @@ -35,6 +36,7 @@ public class ApiSettings : IApiSettings public string AgentTag { get; set; } private string FileName { get; } private string SectionName { get; } + public IDictionary Headers { get; } = new Dictionary(); public ApiSettings() { diff --git a/csharp/rtl/AuthSession.cs b/csharp/LookerSdk/rtl/AuthSession.cs similarity index 98% rename from csharp/rtl/AuthSession.cs rename to csharp/LookerSdk/rtl/AuthSession.cs index e0df018cb..e515739c4 100644 --- a/csharp/rtl/AuthSession.cs +++ b/csharp/LookerSdk/rtl/AuthSession.cs @@ -1,10 +1,7 @@ using System; using System.Net.Http; using System.Net.Http.Headers; -using System.Runtime.CompilerServices; using System.Threading.Tasks; -using Microsoft.VisualBasic.CompilerServices; -using Xunit.Sdk; namespace Looker.RTL { diff --git a/csharp/rtl/AuthToken.cs b/csharp/LookerSdk/rtl/AuthToken.cs similarity index 100% rename from csharp/rtl/AuthToken.cs rename to csharp/LookerSdk/rtl/AuthToken.cs diff --git a/csharp/rtl/Constants.cs b/csharp/LookerSdk/rtl/Constants.cs similarity index 100% rename from csharp/rtl/Constants.cs rename to csharp/LookerSdk/rtl/Constants.cs diff --git a/csharp/rtl/SdkUtils.cs b/csharp/LookerSdk/rtl/SdkUtils.cs similarity index 100% rename from csharp/rtl/SdkUtils.cs rename to csharp/LookerSdk/rtl/SdkUtils.cs diff --git a/csharp/rtl/Transport.cs b/csharp/LookerSdk/rtl/Transport.cs similarity index 84% rename from csharp/rtl/Transport.cs rename to csharp/LookerSdk/rtl/Transport.cs index 14e71e1df..40e66c49b 100644 --- a/csharp/rtl/Transport.cs +++ b/csharp/LookerSdk/rtl/Transport.cs @@ -1,13 +1,13 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Text; -using System.Text.Json; using System.Threading.Tasks; using Newtonsoft.Json; -using JsonSerializer = System.Text.Json.JsonSerializer; namespace Looker.RTL { @@ -19,16 +19,18 @@ namespace Looker.RTL public interface ITransportSettings { /// base URL of API REST web service - string BaseUrl { get; set; } + string BaseUrl { get; } /// whether to verify ssl certs or not. Defaults to true - bool VerifySsl { get; set; } + bool VerifySsl { get; } /// request timeout in seconds. Default to 30 - int Timeout { get; set; } + int Timeout { get; } /// agent tag to use for the SDK requests string AgentTag { get; set; } + + IDictionary Headers { get; } } /// @@ -154,7 +156,7 @@ Task> Request( /// /// HTPP request processor /// - public class Transport : ITransport, ITransportSettings + public class Transport : ITransport { private readonly HttpClient _client; private readonly ITransportSettings _settings; @@ -188,7 +190,7 @@ public string MakeUrl(string path, Values queryParams = null, Authenticator auth || path.StartsWith("https:", StringComparison.InvariantCultureIgnoreCase)) return SdkUtils.AddQueryParams(path, queryParams); // TODO I don't think authenticator is needed here any more? - return SdkUtils.AddQueryParams($"{BaseUrl}{path}", queryParams); + return SdkUtils.AddQueryParams($"{_settings.BaseUrl}{path}", queryParams); } private static RawResponse InitRawResponse(HttpResponseMessage response) @@ -225,6 +227,26 @@ public async Task RawRequest( var request = new HttpRequestMessage(method, url); request.Headers.Add(Constants.LookerAppiId, _settings.AgentTag); + foreach(var h in _settings.Headers) + { + if (request.Headers.Contains(h.Key)) + { + request.Headers.Remove(h.Key); + } + request.Headers.Add(h.Key, h.Value); + } + if (options != null) + { + foreach (var h in options.Headers) + { + if (request.Headers.Contains(h.Key)) + { + request.Headers.Remove(h.Key); + } + request.Headers.Add(h.Key, h.Value); + } + } + if (body != null) { if (body is string) @@ -238,7 +260,7 @@ public async Task RawRequest( { request.Content = new StringContent( - JsonSerializer.Serialize(body, new JsonSerializerOptions { IgnoreNullValues = true }), + JsonConvert.SerializeObject(body, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }), Encoding.UTF8, "application/json"); } @@ -250,27 +272,30 @@ public async Task RawRequest( try { response = await _client.SendAsync(request); + response.EnsureSuccessStatusCode(); result = InitRawResponse(response); // if (response.IsSuccessStatusCode) - await using var stream = await response.Content.ReadAsStreamAsync(); - // Simple content conversion here to make body easily readable in consumers - switch (SdkUtils.ResponseMode(result.ContentType)) + using (var stream = await response.Content.ReadAsStreamAsync()) { - case ResponseMode.Binary: - result.Body = SdkUtils.StreamToByteArray(stream); - break; - case ResponseMode.String: - using (var sr = new StreamReader(stream)) - { - result.Body = await sr.ReadToEndAsync(); - } - - break; - case ResponseMode.Unknown: - result.Body = SdkUtils.StreamToByteArray(stream); - break; - default: - throw new ArgumentOutOfRangeException($"Unrecognized Content Type {result.ContentType}"); + // Simple content conversion here to make body easily readable in consumers + switch (SdkUtils.ResponseMode(result.ContentType)) + { + case ResponseMode.Binary: + result.Body = SdkUtils.StreamToByteArray(stream); + break; + case ResponseMode.String: + using (var sr = new StreamReader(stream)) + { + result.Body = await sr.ReadToEndAsync(); + } + + break; + case ResponseMode.Unknown: + result.Body = SdkUtils.StreamToByteArray(stream); + break; + default: + throw new ArgumentOutOfRangeException($"Unrecognized Content Type {result.ContentType}"); + } } } catch (Exception e) @@ -328,29 +353,5 @@ public async Task> Request( var raw = await RawRequest(method, path, queryParams, body, authenticator, options); return ParseResponse(raw); } - - public string BaseUrl - { - get => _settings.BaseUrl; - set => _settings.BaseUrl = value; - } - - public bool VerifySsl - { - get => _settings.VerifySsl; - set => _settings.VerifySsl = value; - } - - public int Timeout - { - get => _settings.Timeout; - set => _settings.Timeout = value; - } - - public string AgentTag - { - get => _settings.AgentTag; - set => _settings.AgentTag = value; - } } } diff --git a/csharp/rtl/sdkrtl.csproj b/csharp/LookerSdk/rtl/sdkrtl.csproj similarity index 100% rename from csharp/rtl/sdkrtl.csproj rename to csharp/LookerSdk/rtl/sdkrtl.csproj diff --git a/csharp/sdk/4.0/methods.cs b/csharp/LookerSdk/sdk/4.0/methods.cs similarity index 98% rename from csharp/sdk/4.0/methods.cs rename to csharp/LookerSdk/sdk/4.0/methods.cs index 3b3967d09..79f3f1f9f 100644 --- a/csharp/sdk/4.0/methods.cs +++ b/csharp/LookerSdk/sdk/4.0/methods.cs @@ -161,7 +161,7 @@ public async Task> update_alert_field( ITransportSettings? options = null) { alert_id = SdkUtils.EncodeParam(alert_id); - return await AuthRequest(HttpMethod.Patch, $"/alerts/{alert_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/alerts/{alert_id}", null,body,options); } /// ### Delete an alert by a given alert ID @@ -276,7 +276,7 @@ public async Task> read_alert_notific ITransportSettings? options = null) { alert_notification_id = SdkUtils.EncodeParam(alert_notification_id); - return await AuthRequest(HttpMethod.Patch, $"/alert_notifications/{alert_notification_id}", null,null,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/alert_notifications/{alert_notification_id}", null,null,options); } #endregion Alert: Alert @@ -429,15 +429,15 @@ public async Task> artifact_namespac /// /// string Artifact value (application/json) /// - /// Artifact storage namespace + /// Artifact storage namespace /// Artifact storage key. Namespace + Key must be unique public async Task> artifact_value( string @namespace, string? key = null, ITransportSettings? options = null) { - namespace = SdkUtils.EncodeParam(namespace); - return await AuthRequest(HttpMethod.Get, $"/artifact/{namespace}/value", new Values { + @namespace = SdkUtils.EncodeParam(@namespace); + return await AuthRequest(HttpMethod.Get, $"/artifact/{@namespace}/value", new Values { { "key", key }},null,options); } @@ -449,13 +449,13 @@ namespace = SdkUtils.EncodeParam(namespace); /// /// void All artifacts are purged. () /// - /// Artifact storage namespace + /// Artifact storage namespace public async Task> purge_artifacts( string @namespace, ITransportSettings? options = null) { - namespace = SdkUtils.EncodeParam(namespace); - return await AuthRequest(HttpMethod.Delete, $"/artifact/{namespace}/purge", null,null,options); + @namespace = SdkUtils.EncodeParam(@namespace); + return await AuthRequest(HttpMethod.Delete, $"/artifact/{@namespace}/purge", null,null,options); } /// ### Search all key/value pairs in a namespace for matching criteria. @@ -480,7 +480,7 @@ namespace = SdkUtils.EncodeParam(namespace); /// /// Artifact[] Artifacts (application/json) /// - /// Artifact storage namespace + /// Artifact storage namespace /// Comma-delimited names of fields to return in responses. Omit for all fields /// Key pattern to match /// Ids of users who created or updated the artifact (comma-delimited list) @@ -499,8 +499,8 @@ public async Task> search_artifacts( long? offset = null, ITransportSettings? options = null) { - namespace = SdkUtils.EncodeParam(namespace); - return await AuthRequest(HttpMethod.Get, $"/artifact/{namespace}/search", new Values { + @namespace = SdkUtils.EncodeParam(@namespace); + return await AuthRequest(HttpMethod.Get, $"/artifact/{@namespace}/search", new Values { { "fields", fields }, { "key", key }, { "user_ids", user_ids }, @@ -520,7 +520,7 @@ namespace = SdkUtils.EncodeParam(namespace); /// /// Artifact[] Created or updated artifacts (application/json) /// - /// Artifact storage namespace + /// Artifact storage namespace /// Comma-delimited list of keys. Wildcards not allowed. /// Comma-delimited names of fields to return in responses. Omit for all fields /// Number of results to return. (used with offset) @@ -533,8 +533,8 @@ public async Task> artifact( long? offset = null, ITransportSettings? options = null) { - namespace = SdkUtils.EncodeParam(namespace); - return await AuthRequest(HttpMethod.Get, $"/artifact/{namespace}", new Values { + @namespace = SdkUtils.EncodeParam(@namespace); + return await AuthRequest(HttpMethod.Get, $"/artifact/{@namespace}", new Values { { "key", key }, { "fields", fields }, { "limit", limit }, @@ -551,15 +551,15 @@ namespace = SdkUtils.EncodeParam(namespace); /// /// void The artifact is deleted. () /// - /// Artifact storage namespace + /// Artifact storage namespace /// Comma-delimited list of keys. Wildcards not allowed. public async Task> delete_artifact( string @namespace, string key, ITransportSettings? options = null) { - namespace = SdkUtils.EncodeParam(namespace); - return await AuthRequest(HttpMethod.Delete, $"/artifact/{namespace}", new Values { + @namespace = SdkUtils.EncodeParam(@namespace); + return await AuthRequest(HttpMethod.Delete, $"/artifact/{@namespace}", new Values { { "key", key }},null,options); } @@ -594,7 +594,7 @@ namespace = SdkUtils.EncodeParam(namespace); /// /// Artifact[] Created or updated artifacts (application/json) /// - /// Artifact storage namespace + /// Artifact storage namespace /// Comma-delimited names of fields to return in responses. Omit for all fields public async Task> update_artifacts( string @namespace, @@ -602,8 +602,8 @@ public async Task> update_artifacts( string? fields = null, ITransportSettings? options = null) { - namespace = SdkUtils.EncodeParam(namespace); - return await AuthRequest(HttpMethod.Put, $"/artifacts/{namespace}", new Values { + @namespace = SdkUtils.EncodeParam(@namespace); + return await AuthRequest(HttpMethod.Put, $"/artifacts/{@namespace}", new Values { { "fields", fields }},body,options); } @@ -900,7 +900,7 @@ public async Task> update_ldap_config( WriteLDAPConfig body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/ldap_config", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/ldap_config", null,body,options); } /// ### Test the connection settings for an LDAP configuration. @@ -1041,7 +1041,7 @@ public async Task> update_mobile_device_regi ITransportSettings? options = null) { device_id = SdkUtils.EncodeParam(device_id); - return await AuthRequest(HttpMethod.Patch, $"/mobile/device/{device_id}", null,null,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/mobile/device/{device_id}", null,null,options); } /// ### Deregister a mobile device. @@ -1141,7 +1141,7 @@ public async Task> update_oauth_client_ap ITransportSettings? options = null) { client_guid = SdkUtils.EncodeParam(client_guid); - return await AuthRequest(HttpMethod.Patch, $"/oauth_client_apps/{client_guid}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/oauth_client_apps/{client_guid}", new Values { { "fields", fields }},body,options); } @@ -1291,7 +1291,7 @@ public async Task> update_oidc_config( WriteOIDCConfig body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/oidc_config", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/oidc_config", null,body,options); } /// ### Get a OIDC test configuration by test_slug. @@ -1369,7 +1369,7 @@ public async Task> update_password_config WritePasswordConfig body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/password_config", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/password_config", null,body,options); } /// ### Force all credentials_email users to reset their login passwords upon their next login. @@ -1431,7 +1431,7 @@ public async Task> update_saml_config( WriteSamlConfig body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/saml_config", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/saml_config", null,body,options); } /// ### Get a SAML test configuration by test_slug. @@ -1537,7 +1537,7 @@ public async Task> update_session_config( WriteSessionConfig body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/session_config", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/session_config", null,body,options); } /// ### Get Support Access Allowlist Users @@ -1862,7 +1862,7 @@ public async Task> update_board( ITransportSettings? options = null) { board_id = SdkUtils.EncodeParam(board_id); - return await AuthRequest(HttpMethod.Patch, $"/boards/{board_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/boards/{board_id}", new Values { { "fields", fields }},body,options); } @@ -1951,7 +1951,7 @@ public async Task> update_board_item( ITransportSettings? options = null) { board_item_id = SdkUtils.EncodeParam(board_item_id); - return await AuthRequest(HttpMethod.Patch, $"/board_items/{board_item_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/board_items/{board_item_id}", new Values { { "fields", fields }},body,options); } @@ -2037,7 +2037,7 @@ public async Task> update_board_section( ITransportSettings? options = null) { board_section_id = SdkUtils.EncodeParam(board_section_id); - return await AuthRequest(HttpMethod.Patch, $"/board_sections/{board_section_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/board_sections/{board_section_id}", new Values { { "fields", fields }},body,options); } @@ -2218,7 +2218,7 @@ public async Task> update_color_collecti ITransportSettings? options = null) { collection_id = SdkUtils.EncodeParam(collection_id); - return await AuthRequest(HttpMethod.Patch, $"/color_collections/{collection_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/color_collections/{collection_id}", null,body,options); } /// ### Delete a custom color collection by id @@ -2269,7 +2269,7 @@ public async Task> update_cloud_stor WriteBackupConfiguration body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/cloud_storage", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/cloud_storage", null,body,options); } /// ### Get the current status and content of custom welcome emails @@ -2298,7 +2298,7 @@ public async Task> update_custom_welc bool? send_test_welcome_email = null, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/custom_welcome_email", new Values { + return await AuthRequest(new HttpMethod("PATCH"), "/custom_welcome_email", new Values { { "send_test_welcome_email", send_test_welcome_email }},body,options); } @@ -2337,7 +2337,7 @@ public async Task> update_digest_emails_ena DigestEmails body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/digest_emails_enabled", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/digest_emails_enabled", null,body,options); } /// ### Trigger the generation of digest email records and send them to Looker's internal system. This does not send @@ -2392,7 +2392,7 @@ public async Task> update_i WriteInternalHelpResourcesContent body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/internal_help_resources_content", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/internal_help_resources_content", null,body,options); } /// ### Get and set the options for internal help resources @@ -2417,7 +2417,7 @@ public async Task> update_internal WriteInternalHelpResources body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/internal_help_resources", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/internal_help_resources", null,body,options); } /// ### Get all legacy features. @@ -2466,7 +2466,7 @@ public async Task> update_legacy_feature( ITransportSettings? options = null) { legacy_feature_id = SdkUtils.EncodeParam(legacy_feature_id); - return await AuthRequest(HttpMethod.Patch, $"/legacy_features/{legacy_feature_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/legacy_features/{legacy_feature_id}", null,body,options); } /// ### Get a list of locales that Looker supports. @@ -2570,7 +2570,7 @@ public async Task> set_setting( string? fields = null, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/setting", new Values { + return await AuthRequest(new HttpMethod("PATCH"), "/setting", new Values { { "fields", fields }},body,options); } @@ -2750,7 +2750,7 @@ public async Task> update_connection( ITransportSettings? options = null) { connection_name = SdkUtils.EncodeParam(connection_name); - return await AuthRequest(HttpMethod.Patch, $"/connections/{connection_name}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/connections/{connection_name}", null,body,options); } /// ### Delete a connection. @@ -2899,7 +2899,7 @@ public async Task> update_exter ITransportSettings? options = null) { client_id = SdkUtils.EncodeParam(client_id); - return await AuthRequest(HttpMethod.Patch, $"/external_oauth_applications/{client_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/external_oauth_applications/{client_id}", null,body,options); } /// ### Create OAuth User state. @@ -2971,7 +2971,7 @@ public async Task> update_ssh_server( ITransportSettings? options = null) { ssh_server_id = SdkUtils.EncodeParam(ssh_server_id); - return await AuthRequest(HttpMethod.Patch, $"/ssh_server/{ssh_server_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/ssh_server/{ssh_server_id}", null,body,options); } /// ### Delete an SSH Server. @@ -3060,7 +3060,7 @@ public async Task> update_ssh_tunnel( ITransportSettings? options = null) { ssh_tunnel_id = SdkUtils.EncodeParam(ssh_tunnel_id); - return await AuthRequest(HttpMethod.Patch, $"/ssh_tunnel/{ssh_tunnel_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/ssh_tunnel/{ssh_tunnel_id}", null,body,options); } /// ### Delete an SSH Tunnel @@ -3272,7 +3272,7 @@ public async Task> update_content_metadata( ITransportSettings? options = null) { content_metadata_id = SdkUtils.EncodeParam(content_metadata_id); - return await AuthRequest(HttpMethod.Patch, $"/content_metadata/{content_metadata_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/content_metadata/{content_metadata_id}", null,body,options); } /// ### All content metadata access records for a content metadata item. @@ -3783,7 +3783,7 @@ public async Task> sync_lookml_dashboard( ITransportSettings? options = null) { lookml_dashboard_id = SdkUtils.EncodeParam(lookml_dashboard_id); - return await AuthRequest(HttpMethod.Patch, $"/dashboards/{lookml_dashboard_id}/sync", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/dashboards/{lookml_dashboard_id}/sync", new Values { { "raw_locale", raw_locale }},body,options); } @@ -3833,7 +3833,7 @@ public async Task> update_dashboard( ITransportSettings? options = null) { dashboard_id = SdkUtils.EncodeParam(dashboard_id); - return await AuthRequest(HttpMethod.Patch, $"/dashboards/{dashboard_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/dashboards/{dashboard_id}", null,body,options); } /// ### Delete the dashboard with the specified id @@ -3910,7 +3910,7 @@ public async Task> move_dashboard( ITransportSettings? options = null) { dashboard_id = SdkUtils.EncodeParam(dashboard_id); - return await AuthRequest(HttpMethod.Patch, $"/dashboards/{dashboard_id}/move", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/dashboards/{dashboard_id}/move", new Values { { "folder_id", folder_id }},null,options); } @@ -4069,7 +4069,7 @@ public async Task> update_dashboard_ele ITransportSettings? options = null) { dashboard_element_id = SdkUtils.EncodeParam(dashboard_element_id); - return await AuthRequest(HttpMethod.Patch, $"/dashboard_elements/{dashboard_element_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/dashboard_elements/{dashboard_element_id}", new Values { { "fields", fields }},body,options); } @@ -4158,7 +4158,7 @@ public async Task> update_dashboard_filt ITransportSettings? options = null) { dashboard_filter_id = SdkUtils.EncodeParam(dashboard_filter_id); - return await AuthRequest(HttpMethod.Patch, $"/dashboard_filters/{dashboard_filter_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/dashboard_filters/{dashboard_filter_id}", new Values { { "fields", fields }},body,options); } @@ -4244,7 +4244,7 @@ public async Task> update_dashb ITransportSettings? options = null) { dashboard_layout_component_id = SdkUtils.EncodeParam(dashboard_layout_component_id); - return await AuthRequest(HttpMethod.Patch, $"/dashboard_layout_components/{dashboard_layout_component_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/dashboard_layout_components/{dashboard_layout_component_id}", new Values { { "fields", fields }},body,options); } @@ -4299,7 +4299,7 @@ public async Task> update_dashboard_layo ITransportSettings? options = null) { dashboard_layout_id = SdkUtils.EncodeParam(dashboard_layout_id); - return await AuthRequest(HttpMethod.Patch, $"/dashboard_layouts/{dashboard_layout_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/dashboard_layouts/{dashboard_layout_id}", new Values { { "fields", fields }},body,options); } @@ -4426,7 +4426,7 @@ public async Task> update_datagroup( ITransportSettings? options = null) { datagroup_id = SdkUtils.EncodeParam(datagroup_id); - return await AuthRequest(HttpMethod.Patch, $"/datagroups/{datagroup_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/datagroups/{datagroup_id}", null,body,options); } #endregion Datagroup: Manage Datagroups @@ -4624,7 +4624,7 @@ public async Task> update_folder( ITransportSettings? options = null) { folder_id = SdkUtils.EncodeParam(folder_id); - return await AuthRequest(HttpMethod.Patch, $"/folders/{folder_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/folders/{folder_id}", null,body,options); } /// ### Delete the folder with a specific id including any children folders. @@ -5094,7 +5094,7 @@ public async Task> update_group( ITransportSettings? options = null) { group_id = SdkUtils.EncodeParam(group_id); - return await AuthRequest(HttpMethod.Patch, $"/groups/{group_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/groups/{group_id}", new Values { { "fields", fields }},body,options); } @@ -5250,7 +5250,7 @@ public async Task> update_user_a { group_id = SdkUtils.EncodeParam(group_id); user_attribute_id = SdkUtils.EncodeParam(user_attribute_id); - return await AuthRequest(HttpMethod.Patch, $"/groups/{group_id}/attribute_values/{user_attribute_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/groups/{group_id}/attribute_values/{user_attribute_id}", null,body,options); } /// ### Remove a user attribute value from a group. @@ -5362,7 +5362,7 @@ public async Task> update_integration_hub ITransportSettings? options = null) { integration_hub_id = SdkUtils.EncodeParam(integration_hub_id); - return await AuthRequest(HttpMethod.Patch, $"/integration_hubs/{integration_hub_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/integration_hubs/{integration_hub_id}", new Values { { "fields", fields }},body,options); } @@ -5447,7 +5447,7 @@ public async Task> update_integration( ITransportSettings? options = null) { integration_id = SdkUtils.EncodeParam(integration_id); - return await AuthRequest(HttpMethod.Patch, $"/integrations/{integration_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/integrations/{integration_id}", new Values { { "fields", fields }},body,options); } @@ -5675,7 +5675,7 @@ public async Task> update_look( ITransportSettings? options = null) { look_id = SdkUtils.EncodeParam(look_id); - return await AuthRequest(HttpMethod.Patch, $"/looks/{look_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/looks/{look_id}", new Values { { "fields", fields }},body,options); } @@ -5822,7 +5822,7 @@ public async Task> move_look( ITransportSettings? options = null) { look_id = SdkUtils.EncodeParam(look_id); - return await AuthRequest(HttpMethod.Patch, $"/looks/{look_id}/move", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/looks/{look_id}/move", new Values { { "folder_id", folder_id }},null,options); } @@ -5895,7 +5895,7 @@ public async Task> update_lookml_model( ITransportSettings? options = null) { lookml_model_name = SdkUtils.EncodeParam(lookml_model_name); - return await AuthRequest(HttpMethod.Patch, $"/lookml_models/{lookml_model_name}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/lookml_models/{lookml_model_name}", null,body,options); } /// ### Delete a lookml model. @@ -6356,7 +6356,7 @@ public async Task> delete_git_branch( /// /// Id of project /// Branch to deploy to production - /// Ref to deploy to production + /// Ref to deploy to production public async Task> deploy_ref_to_production( string project_id, string? branch = null, @@ -6530,7 +6530,7 @@ public async Task> update_project( ITransportSettings? options = null) { project_id = SdkUtils.EncodeParam(project_id); - return await AuthRequest(HttpMethod.Patch, $"/projects/{project_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/projects/{project_id}", new Values { { "fields", fields }},body,options); } @@ -7844,7 +7844,7 @@ public async Task> update_model_set( ITransportSettings? options = null) { model_set_id = SdkUtils.EncodeParam(model_set_id); - return await AuthRequest(HttpMethod.Patch, $"/model_sets/{model_set_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/model_sets/{model_set_id}", null,body,options); } /// ### Delete the model set with a specific id. @@ -7994,7 +7994,7 @@ public async Task> update_permission_set( ITransportSettings? options = null) { permission_set_id = SdkUtils.EncodeParam(permission_set_id); - return await AuthRequest(HttpMethod.Patch, $"/permission_sets/{permission_set_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/permission_sets/{permission_set_id}", null,body,options); } /// ### Delete the permission set with a specific id. @@ -8222,7 +8222,7 @@ public async Task> update_role( ITransportSettings? options = null) { role_id = SdkUtils.EncodeParam(role_id); - return await AuthRequest(HttpMethod.Patch, $"/roles/{role_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/roles/{role_id}", null,body,options); } /// ### Delete the role with a specific id. @@ -8411,7 +8411,7 @@ public async Task> update_scheduled_plan( ITransportSettings? options = null) { scheduled_plan_id = SdkUtils.EncodeParam(scheduled_plan_id); - return await AuthRequest(HttpMethod.Patch, $"/scheduled_plans/{scheduled_plan_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/scheduled_plans/{scheduled_plan_id}", null,body,options); } /// ### Delete a Scheduled Plan @@ -8864,7 +8864,7 @@ public async Task> update_session( WriteApiSession body, ITransportSettings? options = null) { - return await AuthRequest(HttpMethod.Patch, "/session", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), "/session", null,body,options); } #endregion Session: Session Information @@ -9221,7 +9221,7 @@ public async Task> update_theme( ITransportSettings? options = null) { theme_id = SdkUtils.EncodeParam(theme_id); - return await AuthRequest(HttpMethod.Patch, $"/themes/{theme_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/themes/{theme_id}", null,body,options); } /// ### Delete a specific theme by id @@ -9559,7 +9559,7 @@ public async Task> update_user( ITransportSettings? options = null) { user_id = SdkUtils.EncodeParam(user_id); - return await AuthRequest(HttpMethod.Patch, $"/users/{user_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/users/{user_id}", new Values { { "fields", fields }},body,options); } @@ -9688,7 +9688,7 @@ public async Task> update_user_credenti ITransportSettings? options = null) { user_id = SdkUtils.EncodeParam(user_id); - return await AuthRequest(HttpMethod.Patch, $"/users/{user_id}/credentials_email", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/users/{user_id}/credentials_email", new Values { { "fields", fields }},body,options); } @@ -10292,7 +10292,7 @@ public async Task> set_user_attri { user_id = SdkUtils.EncodeParam(user_id); user_attribute_id = SdkUtils.EncodeParam(user_attribute_id); - return await AuthRequest(HttpMethod.Patch, $"/users/{user_id}/attribute_values/{user_attribute_id}", null,body,options); + return await AuthRequest(new HttpMethod("PATCH"), $"/users/{user_id}/attribute_values/{user_attribute_id}", null,body,options); } /// ### Delete a user attribute value from a user's account settings. @@ -10466,7 +10466,7 @@ public async Task> update_user_attribute( ITransportSettings? options = null) { user_attribute_id = SdkUtils.EncodeParam(user_attribute_id); - return await AuthRequest(HttpMethod.Patch, $"/user_attributes/{user_attribute_id}", new Values { + return await AuthRequest(new HttpMethod("PATCH"), $"/user_attributes/{user_attribute_id}", new Values { { "fields", fields }},body,options); } diff --git a/csharp/sdk/4.0/models.cs b/csharp/LookerSdk/sdk/4.0/models.cs similarity index 100% rename from csharp/sdk/4.0/models.cs rename to csharp/LookerSdk/sdk/4.0/models.cs diff --git a/csharp/README.md b/csharp/README.md index 6aa486e00..99923bc97 100644 --- a/csharp/README.md +++ b/csharp/README.md @@ -7,7 +7,8 @@ Look# was developed using the principles in [Build Your Own SDK](/docs/byosdk.md Look# has: - C# Runtime library with strong typing for HTTP responses -- Uses .NET Core 6.x, an Open Source, cross-platform run-time for macOS, Windows, and Linux +- Targets .NET Standard 2.0, which allows usage in .NET Framework and .NET Core/.NET 6 projects alike. +- Requires .NET 6 to build and test. .NET 6 is an Open Source, cross-platform run-time for macOS, Windows, and Linux - SDK Codegen generates the SDK bindings from the Looker API spec - API 4.0 methods (SDK calls) and models (SDK types) - Includes many unit and some functional tests! diff --git a/csharp/csharp.sln b/csharp/csharp.sln index b0c748c03..e16fa9eaa 100644 --- a/csharp/csharp.sln +++ b/csharp/csharp.sln @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26124.0 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp.csproj", "{62AEDFE2-37D2-4A43-B05F-1853A8344535}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LookerSdk", "LookerSdk\LookerSdk.csproj", "{62AEDFE2-37D2-4A43-B05F-1853A8344535}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LookerSdk.Tests", "LookerSdk.Tests\LookerSdk.Tests.csproj", "{692E3197-1BB6-4922-8CF7-66F22482988B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -14,9 +16,6 @@ Global Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {62AEDFE2-37D2-4A43-B05F-1853A8344535}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {62AEDFE2-37D2-4A43-B05F-1853A8344535}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -30,5 +29,23 @@ Global {62AEDFE2-37D2-4A43-B05F-1853A8344535}.Release|x64.Build.0 = Release|Any CPU {62AEDFE2-37D2-4A43-B05F-1853A8344535}.Release|x86.ActiveCfg = Release|Any CPU {62AEDFE2-37D2-4A43-B05F-1853A8344535}.Release|x86.Build.0 = Release|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Debug|x64.ActiveCfg = Debug|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Debug|x64.Build.0 = Debug|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Debug|x86.ActiveCfg = Debug|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Debug|x86.Build.0 = Debug|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Release|Any CPU.Build.0 = Release|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Release|x64.ActiveCfg = Release|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Release|x64.Build.0 = Release|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Release|x86.ActiveCfg = Release|Any CPU + {692E3197-1BB6-4922-8CF7-66F22482988B}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {74969703-84D1-45C6-9CCC-BCDC0E554320} EndGlobalSection EndGlobal diff --git a/packages/sdk-codegen/src/codeGen.ts b/packages/sdk-codegen/src/codeGen.ts index 7966e8762..790623b6d 100644 --- a/packages/sdk-codegen/src/codeGen.ts +++ b/packages/sdk-codegen/src/codeGen.ts @@ -1290,8 +1290,9 @@ export abstract class CodeGen implements ICodeGen { argList(indent: string, args: Arg[], prefix?: string) { prefix = prefix || ''; + const names = args.map(a => this.reserve(a)); return args && args.length !== 0 - ? `${indent}${prefix}${args.join(this.argDelimiter + prefix)}` + ? `${indent}${prefix}${names.join(this.argDelimiter + prefix)}` : this.nullStr; } @@ -1301,7 +1302,7 @@ export abstract class CodeGen implements ICodeGen { // Don't append trailing optional arguments if none have been set yet return ''; } - return `${args}${current ? this.argDelimiter : ''}${current}`; + return `${args}${current ? this.argDelimiter : ''}${this.reserve(current)}`; } httpPath(path: string, _prefix?: string) { diff --git a/packages/sdk-codegen/src/csharp.gen.spec.ts b/packages/sdk-codegen/src/csharp.gen.spec.ts index 95bfc357e..f472bb705 100644 --- a/packages/sdk-codegen/src/csharp.gen.spec.ts +++ b/packages/sdk-codegen/src/csharp.gen.spec.ts @@ -242,6 +242,47 @@ public async Task> run_sql_query( result_format = SdkUtils.EncodeParam(result_format); return await AuthRequest(HttpMethod.Post, $"/sql_queries/{slug}/run/{result_format}", new Values { { "download", download }},null,options); +}`; + const actual = gen.declareMethod(indent, method); + expect(actual).toEqual(expected); + }); + it('generates bug work around syntax for HttpMethod.Patch', () => { + const method = apiTestModel.methods.update_ssh_server; + const expected = `public async Task> update_ssh_server( + string ssh_server_id, + WriteSshServer body, + ITransportSettings? options = null) +{ + ssh_server_id = SdkUtils.EncodeParam(ssh_server_id); + return await AuthRequest(new HttpMethod("PATCH"), $"/ssh_server/{ssh_server_id}", null,body,options); +}`; + gen.noComment = true; + const actual = gen.declareMethod(indent, method); + gen.noComment = false; + expect(actual).toEqual(expected); + }); + it('escapes namespace as a reserved word', () => { + const method = apiTestModel.methods.delete_artifact; + const expected = `/// ### Delete one or more artifacts +/// +/// To avoid rate limiting on deletion requests, multiple artifacts can be deleted at the same time by using a comma-delimited list of artifact keys. +/// +/// **Note**: The artifact storage API can only be used by Looker-built extensions. +/// +/// DELETE /artifact/{namespace} -> void +/// +/// void The artifact is deleted. () +/// +/// Artifact storage namespace +/// Comma-delimited list of keys. Wildcards not allowed. +public async Task> delete_artifact( + string @namespace, + string key, + ITransportSettings? options = null) +{ + @namespace = SdkUtils.EncodeParam(@namespace); + return await AuthRequest(HttpMethod.Delete, $"/artifact/{@namespace}", new Values { + { "key", key }},null,options); }`; const actual = gen.declareMethod(indent, method); expect(actual).toEqual(expected); diff --git a/packages/sdk-codegen/src/csharp.gen.ts b/packages/sdk-codegen/src/csharp.gen.ts index 53ea20420..7cf67f277 100644 --- a/packages/sdk-codegen/src/csharp.gen.ts +++ b/packages/sdk-codegen/src/csharp.gen.ts @@ -122,7 +122,7 @@ const reservedWords = new Set([ */ export class CSharpGen extends CodeGen { codePath = './csharp'; - packagePath = ''; + packagePath = '/LookerSdk'; itself = 'this'; fileExtension = '.cs'; commentStr = '// '; @@ -139,6 +139,11 @@ export class CSharpGen extends CodeGen { willItStream = false; codeQuote = '"'; + // sdkFileName(baseFileName: string) { + // // return this.fileName(`sdk/${baseFileName}${this.apiRef}`) + // return this.fileName(`LookerSdk/${baseFileName}`); + // } + commentHeader(indent: string, text: string | undefined) { if (this.noComment) return ''; return text ? `${commentBlock(text, indent, '/// ')}\n` : ''; @@ -310,10 +315,16 @@ namespace Looker.SDK.API${this.apiRef} httpPath(path: string, prefix?: string) { prefix = prefix || ''; + let dollah = ''; if (path.indexOf('{') >= 0) { - return `$"${path.replace(/{/gi, '{' + prefix)}"`; + dollah = '$'; + const rx = /{?(\w+)}/gm; + path = path.replace(rx, a => { + const arg = a.substring(1, a.length - 1); + return `${prefix}{${this.reserve(arg)}}`; + }); } - return `'${path}'`; + return `${dollah}"${path}"`; } declareMethod(indent: string, method: IMethod) { @@ -356,14 +367,16 @@ namespace Looker.SDK.API${this.apiRef} httpCall(indent: string, method: IMethod) { const bump = indent + this.indentStr; const args = this.httpArgs(bump, method); - const dollah = method.pathArgs.length ? '$' : ''; // const errors = `(${this.errorResponses(indent, method)})` const bits = this.genericBits(method); - const fragment = `AuthRequest<${ - bits.success - }, Exception>(HttpMethod.${firstCase(method.httpMethod)}, ${dollah}"${ - method.endpoint - }"${args ? ', ' + args : ''})`; + const http = + method.httpMethod === 'PATCH' + ? 'new HttpMethod("PATCH")' + : `HttpMethod.${firstCase(method.httpMethod)}`; + const path = this.httpPath(method.endpoint); + const fragment = `AuthRequest<${bits.success}, Exception>(${http}, ${path}${ + args ? ', ' + args : '' + })`; return `${indent}return await ${fragment};`; } @@ -373,7 +386,8 @@ namespace Looker.SDK.API${this.apiRef} if (method.pathParams.length > 0) { for (const param of method.pathParams) { if (param.doEncode()) { - encodings += `${bump}${param.name} = SdkUtils.EncodeParam(${param.name});\n`; + const name = this.reserve(param.name); + encodings += `${bump}${name} = SdkUtils.EncodeParam(${name});\n`; } } } @@ -391,7 +405,9 @@ namespace Looker.SDK.API${this.apiRef} paramComment(param: IParameter) { return param.description - ? `\n${describeParam(param)}` + ? `\n${describeParam( + param + )}` : ''; } diff --git a/spec/Looker.4.0.json b/spec/Looker.4.0.json index de39111a0..afec51b1e 100644 --- a/spec/Looker.4.0.json +++ b/spec/Looker.4.0.json @@ -2,7 +2,7 @@ "swagger": "2.0", "info": { "version": "4.0.24.20", - "x-looker-release-version": "24.20.9", + "x-looker-release-version": "24.20.12", "title": "Looker API 4.0 Reference", "description": "\nAPI 4.0 is the current release of the Looker API. API 3.x has been removed.\n\n### Authorization\n\nThe classic method of API authorization uses Looker **API** credentials for authorization and access control.\nLooker admins can create API credentials on Looker's **Admin/Users** page.\n\nAPI 4.0 adds additional ways to authenticate API requests, including OAuth and CORS requests.\n\nFor details, see [Looker API Authorization](https://cloud.google.com/looker/docs/r/api/authorization).\n\n\n### API Explorer\n\nThe API Explorer is a Looker-provided utility with many new and unique features for learning and using the Looker API and SDKs.\n\nFor details, see the [API Explorer documentation](https://cloud.google.com/looker/docs/r/api/explorer).\n\n\n### Looker Language SDKs\n\nThe Looker API is a RESTful system that should be usable by any programming language capable of making\nHTTPS requests. SDKs for a variety of programming languages are also provided to streamline using the API. Looker\nhas an OpenSource [sdk-codegen project](https://github.com/looker-open-source/sdk-codegen) that provides several\nlanguage SDKs. Language SDKs generated by `sdk-codegen` have an Authentication manager that can automatically\nauthenticate API requests when needed.\n\nFor details on available Looker SDKs, see [Looker API Client SDKs](https://cloud.google.com/looker/docs/r/api/client_sdks).\n\n\n### API Versioning\n\nFuture releases of Looker expand the latest API version release-by-release to securely expose more and more of the core\npower of the Looker platform to API client applications. API endpoints marked as \"beta\" may receive breaking changes without\nwarning (but we will try to avoid doing that). Stable (non-beta) API endpoints should not receive breaking\nchanges in future releases.\n\nFor details, see [Looker API Versioning](https://cloud.google.com/looker/docs/r/api/versioning).\n\n\n### In This Release\n\nAPI 4.0 is the only supported API version for Looker starting with release 23.18. API 3.0 and 3.1 have been removed.\n\nAPI 4.0 has better support for strongly typed languages like TypeScript, Kotlin, Swift, Go, C#, and more.\n\nSee the [API 4.0 GA announcement](https://developers.looker.com/api/advanced-usage/version-4-ga) for more information\nabout API 4.0.\n\nThe API Explorer can be used to [interactively compare](https://cloud.google.com/looker/docs/r/api/explorer#comparing_api_versions) the differences between API 3.1 and 4.0.\n\n\n### API and SDK Support Policies\n\nLooker API versions and language SDKs have varying support levels. Please read the API and SDK\n[support policies](https://cloud.google.com/looker/docs/r/api/support-policy) for more information.\n\n\n", "contact": { diff --git a/spec/Looker.4.0.oas.json b/spec/Looker.4.0.oas.json index a42bb3392..1c5ef9671 100644 --- a/spec/Looker.4.0.oas.json +++ b/spec/Looker.4.0.oas.json @@ -2,7 +2,7 @@ "openapi": "3.0.0", "info": { "version": "4.0.24.20", - "x-looker-release-version": "24.20.9", + "x-looker-release-version": "24.20.12", "title": "Looker API 4.0 Reference", "description": "\nAPI 4.0 is the current release of the Looker API. API 3.x has been removed.\n\n### Authorization\n\nThe classic method of API authorization uses Looker **API** credentials for authorization and access control.\nLooker admins can create API credentials on Looker's **Admin/Users** page.\n\nAPI 4.0 adds additional ways to authenticate API requests, including OAuth and CORS requests.\n\nFor details, see [Looker API Authorization](https://cloud.google.com/looker/docs/r/api/authorization).\n\n\n### API Explorer\n\nThe API Explorer is a Looker-provided utility with many new and unique features for learning and using the Looker API and SDKs.\n\nFor details, see the [API Explorer documentation](https://cloud.google.com/looker/docs/r/api/explorer).\n\n\n### Looker Language SDKs\n\nThe Looker API is a RESTful system that should be usable by any programming language capable of making\nHTTPS requests. SDKs for a variety of programming languages are also provided to streamline using the API. Looker\nhas an OpenSource [sdk-codegen project](https://github.com/looker-open-source/sdk-codegen) that provides several\nlanguage SDKs. Language SDKs generated by `sdk-codegen` have an Authentication manager that can automatically\nauthenticate API requests when needed.\n\nFor details on available Looker SDKs, see [Looker API Client SDKs](https://cloud.google.com/looker/docs/r/api/client_sdks).\n\n\n### API Versioning\n\nFuture releases of Looker expand the latest API version release-by-release to securely expose more and more of the core\npower of the Looker platform to API client applications. API endpoints marked as \"beta\" may receive breaking changes without\nwarning (but we will try to avoid doing that). Stable (non-beta) API endpoints should not receive breaking\nchanges in future releases.\n\nFor details, see [Looker API Versioning](https://cloud.google.com/looker/docs/r/api/versioning).\n\n\n### In This Release\n\nAPI 4.0 is the only supported API version for Looker starting with release 23.18. API 3.0 and 3.1 have been removed.\n\nAPI 4.0 has better support for strongly typed languages like TypeScript, Kotlin, Swift, Go, C#, and more.\n\nSee the [API 4.0 GA announcement](https://developers.looker.com/api/advanced-usage/version-4-ga) for more information\nabout API 4.0.\n\nThe API Explorer can be used to [interactively compare](https://cloud.google.com/looker/docs/r/api/explorer#comparing_api_versions) the differences between API 3.1 and 4.0.\n\n\n### API and SDK Support Policies\n\nLooker API versions and language SDKs have varying support levels. Please read the API and SDK\n[support policies](https://cloud.google.com/looker/docs/r/api/support-policy) for more information.\n\n\n", "contact": {