diff --git a/CHANGELOG.md b/CHANGELOG.md index 054646e..29bd80a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.5.4] - 2023-12-06 + +### Added + +- Added support for netStandard2.0. + ## [0.5.3] - 2023-11-16 ### Added diff --git a/src/lib/AccessRequest.cs b/src/lib/AccessRequest.cs index d41cbb4..8b9b46d 100644 --- a/src/lib/AccessRequest.cs +++ b/src/lib/AccessRequest.cs @@ -21,7 +21,7 @@ internal static AccessRequest Load(JsonElement content) } public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); if (!String.IsNullOrWhiteSpace(Type)) writer.WriteString(TypeProperty, Type); if (Content != null) diff --git a/src/lib/ApiDependency.cs b/src/lib/ApiDependency.cs index ef50e05..5b71eb9 100644 --- a/src/lib/ApiDependency.cs +++ b/src/lib/ApiDependency.cs @@ -30,7 +30,7 @@ public string? ApiDeploymentBaseUrl // Write method public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); if (!string.IsNullOrWhiteSpace(ApiDescriptionUrl)) writer.WriteString(ApiDescriptionUrlProperty, ApiDescriptionUrl); diff --git a/src/lib/ApiManifestDocument.cs b/src/lib/ApiManifestDocument.cs index 3ea8d35..1a799d3 100644 --- a/src/lib/ApiManifestDocument.cs +++ b/src/lib/ApiManifestDocument.cs @@ -30,7 +30,7 @@ public ApiManifestDocument(JsonElement value) // Write method public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); Validate(); writer.WriteStartObject(); writer.WriteString(ApplicationNameProperty, ApplicationName); diff --git a/src/lib/AuthorizationRequirements.cs b/src/lib/AuthorizationRequirements.cs index 9ee8aa3..3cecc4b 100644 --- a/src/lib/AuthorizationRequirements.cs +++ b/src/lib/AuthorizationRequirements.cs @@ -35,7 +35,7 @@ private static void LoadAccessProperty(AuthorizationRequirements o, JsonElement // Write Method public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); if (!string.IsNullOrWhiteSpace(ClientIdentifier)) writer.WriteString(ClientIdentifierProperty, ClientIdentifier); diff --git a/src/lib/Extensions.cs b/src/lib/Extensions.cs index ed59e94..a5f988e 100644 --- a/src/lib/Extensions.cs +++ b/src/lib/Extensions.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using Microsoft.OpenApi.ApiManifest.Helpers; using System.Text.Json; using System.Text.Json.Nodes; @@ -26,7 +27,7 @@ public static Extensions Load(JsonElement value) public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); foreach (var extension in this) { diff --git a/src/lib/Helpers/ParsingHelpers.cs b/src/lib/Helpers/ParsingHelpers.cs index 30232f8..3f3e1e4 100644 --- a/src/lib/Helpers/ParsingHelpers.cs +++ b/src/lib/Helpers/ParsingHelpers.cs @@ -3,7 +3,6 @@ using Microsoft.OpenApi.Readers; using System.Diagnostics; -using System.Net; using System.Text.Json; namespace Microsoft.OpenApi.ApiManifest.Helpers; @@ -11,10 +10,8 @@ namespace Microsoft.OpenApi.ApiManifest.Helpers; internal static class ParsingHelpers { // The HttpClient will default to SslProtocol of none. This lets the OS pick an appropriate SSL protocol. - private static readonly Lazy s_httpClient = new(() => new HttpClient()) - { - Value = { DefaultRequestVersion = HttpVersion.Version20 } - }; + private static readonly Lazy s_httpClient = new(() => new HttpClient()); + internal static void ParseMap(JsonElement node, T permissionsDocument, FixedFieldMap handlers) { @@ -68,7 +65,7 @@ internal static Dictionary GetMapOfString(JsonElement v) foreach (var item in v.EnumerateObject()) { var value = item.Value.GetString(); - map.Add(item.Name, string.IsNullOrWhiteSpace(value) ? string.Empty : value); + map.Add(item.Name, string.IsNullOrWhiteSpace(value) ? string.Empty : value!); } return map; } @@ -136,18 +133,18 @@ internal static IEnumerable> ParseKey(string key) if (string.IsNullOrEmpty(pair)) continue; - var index = pair.IndexOf('=', StringComparison.OrdinalIgnoreCase); + var index = pair.IndexOf("=", StringComparison.OrdinalIgnoreCase); if (index == -1) throw new InvalidOperationException($"Unable to parse: {key}. Format is name1=value1;name2=value2;..."); - var keyValue = new KeyValuePair(pair[..index], pair[(index + 1)..]); + var keyValue = new KeyValuePair(pair.Substring(0, index), pair.Substring(index + 1)); yield return keyValue; } } internal static async Task ParseOpenApiAsync(Uri openApiFileUri, bool inlineExternal, CancellationToken cancellationToken) { - using var stream = await GetStreamAsync(openApiFileUri, cancellationToken: cancellationToken).ConfigureAwait(false); + using var stream = await GetStreamAsync(openApiFileUri).ConfigureAwait(false); return await ParseOpenApiAsync(stream, openApiFileUri, inlineExternal, cancellationToken).ConfigureAwait(false); } @@ -163,13 +160,13 @@ internal static async Task ParseOpenApiAsync(Stream stream, Uri open return result; } - internal static async Task GetStreamAsync(Uri uri, CancellationToken cancellationToken = default) + internal static async Task GetStreamAsync(Uri uri) { if (!uri.Scheme.StartsWith("http", StringComparison.OrdinalIgnoreCase)) throw new ArgumentException($"The input {uri} is not a valid url", nameof(uri)); try { - return await s_httpClient.Value.GetStreamAsync(uri, cancellationToken).ConfigureAwait(false); + return await s_httpClient.Value.GetStreamAsync(uri).ConfigureAwait(false); } catch (HttpRequestException ex) { diff --git a/src/lib/Helpers/ValidationHelpers.cs b/src/lib/Helpers/ValidationHelpers.cs index 5353d30..d7406fe 100644 --- a/src/lib/Helpers/ValidationHelpers.cs +++ b/src/lib/Helpers/ValidationHelpers.cs @@ -22,16 +22,22 @@ internal static void ValidateEmail(string parameterName, string? value, string p if (string.IsNullOrWhiteSpace(value)) throw new ArgumentNullException(parameterName, string.Format(CultureInfo.InvariantCulture, ErrorMessage.FieldIsRequired, parameterName, parentName)); else - ValidateEmail(parameterName, value); + ValidateEmail(parameterName, value!); } internal static void ValidateBaseUrl(string parameterName, string? baseUrl) { // Check if the baseUrl is a valid URL and ends in a slash. - if (string.IsNullOrWhiteSpace(baseUrl) || !baseUrl.EndsWith("/", StringComparison.Ordinal) || !Uri.TryCreate(baseUrl, UriKind.Absolute, out _)) + if (string.IsNullOrWhiteSpace(baseUrl) || !baseUrl!.EndsWith("/", StringComparison.Ordinal) || !Uri.TryCreate(baseUrl, UriKind.Absolute, out _)) throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, ErrorMessage.BaseUrlIsNotValid, nameof(baseUrl)), parameterName); } + internal static void ThrowIfNull(object? obj, string? paramName = null) + { + if (obj == null) + throw new ArgumentNullException(paramName); + } + private static readonly Regex s_emailRegex = new(@"^[^@\s]+@[^@\s]+$", RegexOptions.Compiled, Constants.DefaultRegexTimeout); private static void ValidateEmail(string parameterName, string value) { diff --git a/src/lib/OpenAI/Api.cs b/src/lib/OpenAI/Api.cs index 464d013..fa8a53e 100644 --- a/src/lib/OpenAI/Api.cs +++ b/src/lib/OpenAI/Api.cs @@ -46,7 +46,7 @@ public static Api Load(JsonElement value) public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); Validate(this); writer.WriteStartObject(); writer.WriteString(TypeProperty, Type); diff --git a/src/lib/OpenAI/Authentication/BaseManifestAuth.cs b/src/lib/OpenAI/Authentication/BaseManifestAuth.cs index f4ce82a..4f3390c 100644 --- a/src/lib/OpenAI/Authentication/BaseManifestAuth.cs +++ b/src/lib/OpenAI/Authentication/BaseManifestAuth.cs @@ -36,7 +36,7 @@ protected void LoadProperties(JsonElement value) /// The to use. protected void WriteProperties(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteString(TypeProperty, Type); if (!string.IsNullOrWhiteSpace(Instructions)) writer.WriteString(InstructionsProperty, Instructions); } diff --git a/src/lib/OpenAI/Authentication/ManifestNoAuth.cs b/src/lib/OpenAI/Authentication/ManifestNoAuth.cs index 3a03d80..0a8e130 100644 --- a/src/lib/OpenAI/Authentication/ManifestNoAuth.cs +++ b/src/lib/OpenAI/Authentication/ManifestNoAuth.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using Microsoft.OpenApi.ApiManifest.Helpers; using System.Text.Json; namespace Microsoft.OpenApi.ApiManifest.OpenAI.Authentication; @@ -21,7 +22,7 @@ public static ManifestNoAuth Load(JsonElement value) public override void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); WriteProperties(writer); writer.WriteEndObject(); diff --git a/src/lib/OpenAI/Authentication/ManifestOAuthAuth.cs b/src/lib/OpenAI/Authentication/ManifestOAuthAuth.cs index fe13c4b..6fee91a 100644 --- a/src/lib/OpenAI/Authentication/ManifestOAuthAuth.cs +++ b/src/lib/OpenAI/Authentication/ManifestOAuthAuth.cs @@ -44,7 +44,7 @@ public static ManifestOAuthAuth Load(JsonElement value) public override void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); WriteProperties(writer); if (!string.IsNullOrWhiteSpace(ClientUrl)) writer.WriteString(ClientUrlPropertyName, ClientUrl); diff --git a/src/lib/OpenAI/Authentication/ManifestServiceHttpAuth.cs b/src/lib/OpenAI/Authentication/ManifestServiceHttpAuth.cs index 6396421..15daef3 100644 --- a/src/lib/OpenAI/Authentication/ManifestServiceHttpAuth.cs +++ b/src/lib/OpenAI/Authentication/ManifestServiceHttpAuth.cs @@ -39,7 +39,7 @@ public static ManifestServiceHttpAuth Load(JsonElement value) public override void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); WriteProperties(writer); writer.WriteString(AuthorizationTypeProperty, AuthorizationType); diff --git a/src/lib/OpenAI/Authentication/ManifestUserHttpAuth.cs b/src/lib/OpenAI/Authentication/ManifestUserHttpAuth.cs index 288f257..4e859b0 100644 --- a/src/lib/OpenAI/Authentication/ManifestUserHttpAuth.cs +++ b/src/lib/OpenAI/Authentication/ManifestUserHttpAuth.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. +using Microsoft.OpenApi.ApiManifest.Helpers; using System.Text.Json; namespace Microsoft.OpenApi.ApiManifest.OpenAI.Authentication; @@ -30,7 +31,7 @@ public static ManifestUserHttpAuth Load(JsonElement value) public override void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); WriteProperties(writer); writer.WriteString(AuthorizationTypeProperty, AuthorizationType); diff --git a/src/lib/OpenAI/Authentication/VerificationTokens.cs b/src/lib/OpenAI/Authentication/VerificationTokens.cs index d03ed64..2355279 100644 --- a/src/lib/OpenAI/Authentication/VerificationTokens.cs +++ b/src/lib/OpenAI/Authentication/VerificationTokens.cs @@ -19,7 +19,7 @@ internal static VerificationTokens Load(JsonElement value) public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); foreach (var verificationToken in this) { diff --git a/src/lib/OpenAI/OpenAIPluginManifest.cs b/src/lib/OpenAI/OpenAIPluginManifest.cs index a73c2d8..64ff9ca 100644 --- a/src/lib/OpenAI/OpenAIPluginManifest.cs +++ b/src/lib/OpenAI/OpenAIPluginManifest.cs @@ -86,7 +86,7 @@ public static OpenAIPluginManifest Load(JsonElement value) //Write method public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); Validate(this); writer.WriteStartObject(); writer.WriteString(SchemaVersionProperty, SchemaVersion); @@ -138,8 +138,8 @@ private void Validate(OpenAIPluginManifest openAIPluginManifest) ValidationHelpers.ValidateLength(nameof(DescriptionForModel), openAIPluginManifest.DescriptionForModel, 8000); ValidationHelpers.ValidateNullOrWhitespace(nameof(SchemaVersion), openAIPluginManifest.SchemaVersion, nameof(OpenAIPluginManifest)); - ArgumentNullException.ThrowIfNull(openAIPluginManifest.Auth); - ArgumentNullException.ThrowIfNull(openAIPluginManifest.Api); + ValidationHelpers.ThrowIfNull(openAIPluginManifest.Auth, "Auth"); + ValidationHelpers.ThrowIfNull(openAIPluginManifest.Api, "Api"); ValidationHelpers.ValidateNullOrWhitespace(nameof(LogoUrl), openAIPluginManifest.LogoUrl, nameof(OpenAIPluginManifest)); ValidationHelpers.ValidateEmail(nameof(ContactEmail), openAIPluginManifest.ContactEmail, nameof(OpenAIPluginManifest)); ValidationHelpers.ValidateNullOrWhitespace(nameof(LegalInfoUrl), openAIPluginManifest.LegalInfoUrl, nameof(OpenAIPluginManifest)); diff --git a/src/lib/Publisher.cs b/src/lib/Publisher.cs index 125dcf5..697c6f2 100644 --- a/src/lib/Publisher.cs +++ b/src/lib/Publisher.cs @@ -26,7 +26,7 @@ private Publisher(JsonElement value) // Write method public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); Validate(); writer.WriteStartObject(); writer.WriteString(NameProperty, Name); diff --git a/src/lib/RequestInfo.cs b/src/lib/RequestInfo.cs index 3bc2aac..17ea735 100644 --- a/src/lib/RequestInfo.cs +++ b/src/lib/RequestInfo.cs @@ -17,7 +17,7 @@ public class RequestInfo // Write method public void Write(Utf8JsonWriter writer) { - ArgumentNullException.ThrowIfNull(writer); + ValidationHelpers.ThrowIfNull(writer, nameof(writer)); writer.WriteStartObject(); if (!String.IsNullOrWhiteSpace(Method)) writer.WriteString(MethodProperty, Method); diff --git a/src/lib/TypeExtensions/ApiManifestDocumentExtensions.cs b/src/lib/TypeExtensions/ApiManifestDocumentExtensions.cs index af0efe3..d08b03e 100644 --- a/src/lib/TypeExtensions/ApiManifestDocumentExtensions.cs +++ b/src/lib/TypeExtensions/ApiManifestDocumentExtensions.cs @@ -21,7 +21,7 @@ public static class ApiManifestDocumentExtensions /// A public static async Task ToOpenAIPluginManifestAsync(this ApiManifestDocument apiManifestDocument, string logoUrl, string legalInfoUrl, string? apiDependencyName = default, string? openApiPath = default, CancellationToken cancellationToken = default) { - ArgumentNullException.ThrowIfNull(apiManifestDocument); + ValidationHelpers.ThrowIfNull(apiManifestDocument, nameof(apiManifestDocument)); if (!TryGetApiDependency(apiManifestDocument.ApiDependencies, apiDependencyName, out ApiDependency? apiDependency)) { throw new ApiManifestException(string.Format(CultureInfo.InvariantCulture, ErrorMessage.ApiDependencyNotFound, nameof(OpenAIPluginManifest))); @@ -32,8 +32,10 @@ public static async Task ToOpenAIPluginManifestAsync(this } else { - var result = await ParsingHelpers.ParseOpenApiAsync(new Uri(apiDependency.ApiDescriptionUrl), false, cancellationToken).ConfigureAwait(false); - return apiManifestDocument.ToOpenAIPluginManifest(result.OpenApiDocument, logoUrl, legalInfoUrl, openApiPath ?? apiDependency.ApiDescriptionUrl); + var result = await ParsingHelpers.ParseOpenApiAsync(new Uri(apiDependency!.ApiDescriptionUrl), false, cancellationToken).ConfigureAwait(false); + if (string.IsNullOrWhiteSpace(openApiPath)) + openApiPath = apiDependency.ApiDescriptionUrl; + return apiManifestDocument.ToOpenAIPluginManifest(result.OpenApiDocument, logoUrl, legalInfoUrl, openApiPath!); } } @@ -48,8 +50,8 @@ public static async Task ToOpenAIPluginManifestAsync(this /// A public static OpenAIPluginManifest ToOpenAIPluginManifest(this ApiManifestDocument apiManifestDocument, OpenApiDocument openApiDocument, string logoUrl, string legalInfoUrl, string openApiPath) { - ArgumentNullException.ThrowIfNull(apiManifestDocument); - ArgumentNullException.ThrowIfNull(openApiDocument); + ValidationHelpers.ThrowIfNull(apiManifestDocument, nameof(apiManifestDocument)); + ValidationHelpers.ThrowIfNull(openApiDocument, nameof(openApiDocument)); // Validates the ApiManifestDocument before generating the OpenAI manifest. This includes the publisher object. apiManifestDocument.Validate(); string contactEmail = apiManifestDocument.Publisher?.ContactEmail!; @@ -75,7 +77,7 @@ private static bool TryGetApiDependency(ApiDependencies apiDependencies, string? if (string.IsNullOrEmpty(apiDependencyName)) apiDependency = apiDependencies.FirstOrDefault().Value; else - _ = apiDependencies.TryGetValue(apiDependencyName, out apiDependency); + _ = apiDependencies.TryGetValue(apiDependencyName!, out apiDependency); return apiDependency != null; } } diff --git a/src/lib/TypeExtensions/OpenApiDocumentExtensions.cs b/src/lib/TypeExtensions/OpenApiDocumentExtensions.cs index e817ff7..bb070af 100644 --- a/src/lib/TypeExtensions/OpenApiDocumentExtensions.cs +++ b/src/lib/TypeExtensions/OpenApiDocumentExtensions.cs @@ -9,8 +9,7 @@ namespace Microsoft.OpenApi.ApiManifest.TypeExtensions { public static partial class OpenApiDocumentExtensions { - [GeneratedRegex("[^a-zA-Z0-9]", RegexOptions.Compiled, 5000)] - private static partial Regex SpecialCharactersInApiNameRegex(); + private static readonly Regex s_specialCharactersInApiNameRegex = new("[^a-zA-Z0-9]", RegexOptions.Compiled, TimeSpan.FromSeconds(5)); internal const string DefaultPublisherName = "publisher-name"; internal const string DefaultPublisherEmail = "publisher-email@example.com"; @@ -34,7 +33,7 @@ public static partial class OpenApiDocumentExtensions /// An . public static ApiManifestDocument ToApiManifest(this OpenApiDocument document, string? apiDescriptionUrl, string applicationName, string? apiDependencyName = default, string? publisherName = default, string? publisherEmail = default) { - ArgumentNullException.ThrowIfNull(document); + ValidationHelpers.ThrowIfNull(document, nameof(document)); ValidationHelpers.ValidateNullOrWhitespace(nameof(apiDescriptionUrl), apiDescriptionUrl, nameof(ApiManifestDocument)); ValidationHelpers.ValidateNullOrWhitespace(nameof(applicationName), applicationName, nameof(ApiManifestDocument)); @@ -44,18 +43,18 @@ public static ApiManifestDocument ToApiManifest(this OpenApiDocument document, s if (string.IsNullOrEmpty(publisherEmail)) publisherEmail = document.Info.Contact?.Email is string cEmail && !string.IsNullOrEmpty(cEmail) ? cEmail : DefaultPublisherEmail; - apiDependencyName = NormalizeApiName(string.IsNullOrEmpty(apiDependencyName) ? document.Info.Title : apiDependencyName); + apiDependencyName = NormalizeApiName(string.IsNullOrEmpty(apiDependencyName) ? document.Info.Title : apiDependencyName!); string? apiDeploymentBaseUrl = GetApiDeploymentBaseUrl(document.Servers.FirstOrDefault()); var apiManifest = new ApiManifestDocument(applicationName) { - Publisher = new(publisherName, publisherEmail), + Publisher = new(publisherName!, publisherEmail!), ApiDependencies = new() { { apiDependencyName, new() { ApiDescriptionUrl = apiDescriptionUrl, ApiDescriptionVersion = document.Info.Version, - ApiDeploymentBaseUrl = apiDeploymentBaseUrl, + ApiDeploymentBaseUrl = apiDeploymentBaseUrl } } } @@ -79,7 +78,7 @@ public static ApiManifestDocument ToApiManifest(this OpenApiDocument document, s private static string NormalizeApiName(string apiName) { // Normalize OpenAPI document title to API dependency name by removing all special characters from the provided api name. - return SpecialCharactersInApiNameRegex().Replace(apiName, string.Empty); + return s_specialCharactersInApiNameRegex.Replace(apiName, string.Empty); } private static string? GetApiDeploymentBaseUrl(OpenApiServer? server) diff --git a/src/lib/apimanifest.csproj b/src/lib/apimanifest.csproj index 6f3238e..cf8b971 100644 --- a/src/lib/apimanifest.csproj +++ b/src/lib/apimanifest.csproj @@ -1,9 +1,9 @@ - net7.0 + netstandard2.0 Microsoft.OpenApi.ApiManifest - 0.5.3 + 0.5.4 preview http://go.microsoft.com/fwlink/?LinkID=288890 https://github.com/Microsoft/OpenApi.ApiManifest @@ -13,6 +13,7 @@ Microsoft © Microsoft Corporation. All rights reserved. ./../../artifacts + 10 enable enable True @@ -30,6 +31,7 @@ + - \ No newline at end of file +