commit a73e1584fbb0eae6318ed93fc6e847db3952a52a Author: binarydad Date: Tue Apr 20 18:10:07 2021 -0400 initial diff --git a/Annotations/QueryIgnoreAttribute.cs b/Annotations/QueryIgnoreAttribute.cs new file mode 100644 index 0000000..06fa55d --- /dev/null +++ b/Annotations/QueryIgnoreAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Salesforce.NET +{ + /// + /// Instructs the query generator to ignore this property + /// + public class QueryIgnoreAttribute : Attribute { } +} diff --git a/Annotations/SalesforceObjectAttribute.cs b/Annotations/SalesforceObjectAttribute.cs new file mode 100644 index 0000000..e8fd18a --- /dev/null +++ b/Annotations/SalesforceObjectAttribute.cs @@ -0,0 +1,17 @@ +using System; + +namespace Salesforce.NET +{ + /// + /// Associates the entity to an object in Salesforce + /// + public class SalesforceObjectAttribute : Attribute + { + public string ObjectName { get; } + + public SalesforceObjectAttribute(string objectName) + { + ObjectName = objectName; + } + } +} diff --git a/AuthenticationResponse.cs b/AuthenticationResponse.cs new file mode 100644 index 0000000..7216f69 --- /dev/null +++ b/AuthenticationResponse.cs @@ -0,0 +1,35 @@ +using BinaryDad.Extensions; +using Newtonsoft.Json; +using Salesforce.NET.Converters; +using System; + +namespace Salesforce.NET +{ + public class AuthenticationResponse : IApiResponse + { + [JsonProperty("access_token")] + public string AccessToken { get; internal set; } + + [JsonProperty("instance_url")] + public string InstanceUrl { get; internal set; } + + public string Id { get; internal set; } + + [JsonProperty("token_type")] + public TokenType TokenType { get; internal set; } + + [JsonProperty("issued_at")] + [JsonConverter(typeof(UnixTimestampDateConverter))] + public DateTime IssuedAt { get; internal set; } + + [JsonProperty("signature")] + public string Signature { get; internal set; } + + public string Error { get; set; } + + [JsonProperty("error_description")] + public string ErrorDescription { get; set; } + + public bool Success => AccessToken.IsNotEmpty(); + } +} diff --git a/Converters/UnixTimestampDateConverter.cs b/Converters/UnixTimestampDateConverter.cs new file mode 100644 index 0000000..d82ba45 --- /dev/null +++ b/Converters/UnixTimestampDateConverter.cs @@ -0,0 +1,26 @@ +using BinaryDad.Extensions; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; + +namespace Salesforce.NET.Converters +{ + public class UnixTimestampDateConverter : DateTimeConverterBase + { + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (objectType == typeof(DateTime)) + { + var milliseconds = reader.Value.To(); + + var offset = DateTimeOffset.FromUnixTimeMilliseconds(milliseconds); + + return offset.DateTime.ToLocalTime(); + } + + return existingValue; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException(); + } +} diff --git a/CreateResponse.cs b/CreateResponse.cs new file mode 100644 index 0000000..b81c900 --- /dev/null +++ b/CreateResponse.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace Salesforce.NET +{ + public class CreateResponse : IApiResponse + { + [JsonProperty("Id")] + public string RecordId { get; set; } + + public bool Success { get; set; } + } +} diff --git a/Entities/SalesforceEntity.cs b/Entities/SalesforceEntity.cs new file mode 100644 index 0000000..f87e1d8 --- /dev/null +++ b/Entities/SalesforceEntity.cs @@ -0,0 +1,54 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Salesforce.NET.Entities +{ + public abstract class SalesforceEntity + { + /// + /// Instructs the serializer whether to serialize read-only entity properties + /// + [JsonIgnore] + public bool SerializeReadOnlyProperties { get; set; } = true; + + /// + /// The unique ID of the record + /// + [JsonProperty("id")] + public string RecordId { get; set; } + + /// + /// Used to correlate a record insert to a batch + /// + [QueryIgnore] + public int TransactionId { get; set; } + + [QueryIgnore] + public RecordAttributes Attributes { get; set; } + + public bool IsDeleted { get; set; } + public string OwnerId { get; set; } + public string CreatedById { get; set; } + public DateTime CreatedDate { get; set; } + public string LastModifiedById { get; set; } + public DateTime LastModifiedDate { get; set; } + + public bool ShouldSerializeTransactionId() => SerializeReadOnlyProperties; + public bool ShouldSerializeAttributes() => SerializeReadOnlyProperties; + public bool ShouldSerializeId() => SerializeReadOnlyProperties; + public bool ShouldSerializeIsDeleted() => SerializeReadOnlyProperties; + public bool ShouldSerializeOwnerId() => SerializeReadOnlyProperties; + public bool ShouldSerializeCreatedById() => SerializeReadOnlyProperties; + public bool ShouldSerializeCreatedDate() => SerializeReadOnlyProperties; + public bool ShouldSerializeLastModifiedById() => SerializeReadOnlyProperties; + public bool ShouldSerializeLastModifiedDate() => SerializeReadOnlyProperties; + + public class RecordAttributes + { + public string Type { get; set; } + public string Url { get; set; } + } + } +} diff --git a/ErrorCollectionResponse.cs b/ErrorCollectionResponse.cs new file mode 100644 index 0000000..2196685 --- /dev/null +++ b/ErrorCollectionResponse.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace Salesforce.NET +{ + public class ErrorCollectionResponse : Collection, IApiResponse + { + public bool Success => false; + } + + public class ErrorResponse + { + public string Message { get; set; } + public string ErrorCode { get; set; } + public ICollection Fields { get; set; } + } +} diff --git a/IApiResponse.cs b/IApiResponse.cs new file mode 100644 index 0000000..eb4bc8a --- /dev/null +++ b/IApiResponse.cs @@ -0,0 +1,7 @@ +namespace Salesforce.NET +{ + public interface IApiResponse + { + bool Success { get; } + } +} diff --git a/JobCreateResponse.cs b/JobCreateResponse.cs new file mode 100644 index 0000000..8c3fcd5 --- /dev/null +++ b/JobCreateResponse.cs @@ -0,0 +1,12 @@ +using BinaryDad.Extensions; + +namespace Salesforce.NET +{ + public class JobCreateResponse : IApiResponse + { + public string Id { get; set; } + public string State { get; set; } + public string ContentUrl { get; set; } + public bool Success => Id.IsNotEmpty(); + } +} diff --git a/PropertyExtensions.cs b/PropertyExtensions.cs new file mode 100644 index 0000000..47dbe26 --- /dev/null +++ b/PropertyExtensions.cs @@ -0,0 +1,65 @@ +using BinaryDad.Extensions; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Salesforce.NET +{ + internal static class PropertyExtensions + { + internal static IEnumerable WhereIsSerializable(this IEnumerable properties) + { + foreach (var property in properties) + { + var jsonIgnore = property.GetCustomAttribute(); + + if (jsonIgnore == null) + { + yield return property; + } + } + } + + internal static IEnumerable WhereIsQueryable(this IEnumerable properties) + { + foreach (var property in properties) + { + var queryIgnore = property.GetCustomAttribute(); + + if (queryIgnore == null) + { + yield return property; + } + } + } + + internal static IDictionary GetPropertyValues(this IEnumerable properties, object value) + { + return properties + .Select(p => + { + var propertyName = GetSalesforcePropertyName(p); + var propertyValue = p.GetValue(value); + + return new KeyValuePair(propertyName, propertyValue); + }) + .ToDictionary(); + } + + internal static IEnumerable GetPropertyNames(this IEnumerable properties) + { + foreach (var property in properties) + { + yield return GetSalesforcePropertyName(property); + } + } + + private static string GetSalesforcePropertyName(PropertyInfo propertyInfo) + { + var jsonProperty = propertyInfo.GetCustomAttribute(); + + return jsonProperty?.PropertyName ?? propertyInfo.Name; + } + } +} diff --git a/QueryResponse.cs b/QueryResponse.cs new file mode 100644 index 0000000..67900e9 --- /dev/null +++ b/QueryResponse.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace Salesforce.NET +{ + public class QueryResponse + { + public bool Done { get; set; } + + [JsonProperty("totalSize")] + public bool TotalRecords { get; set; } + + public string NextRecordsUrl { get; set; } + public ICollection Records { get; set; } + } +} diff --git a/Result.cs b/Result.cs new file mode 100644 index 0000000..f276c8d --- /dev/null +++ b/Result.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; + +namespace Salesforce.NET +{ + public sealed class Result : Result + { + public T Data { get; set; } + + /// + /// Creates a new failed result ( is false) + /// + public Result() { } + + /// + /// Creates a new result + /// + /// + public Result(bool success) : base(success) { } + + /// + /// Creates a new failed result with error message + /// + /// + public Result(string error) : base(error) { } + } + + public class Result + { + public bool Success { get; set; } + public string Message { get; set; } + + /// + /// Collection of errors that have occurred during the request + /// + public ICollection Errors { get; set; } = new List(); + + #region Constructor + + /// + /// Creates a new failed result ( is false) + /// + public Result() { } + + /// + /// Creates a new result + /// + /// + public Result(bool success) => Success = success; + + /// + /// Creates a new failed result with error message + /// + /// + public Result(string error) => AddError(error); + + #endregion + + /// + /// Adds an error to the collection and sets to false + /// + /// + public void AddError(string error) + { + // force to false if previously true + Success = false; + + AddDistinctError(error); + } + + /// + /// Adds an error to the collection and sets to false + /// + /// + public void AddError(Exception ex) + { + // force to false if previously true + Success = false; + + if (ex == null) + { + return; + } + + AddDistinctError(ex.Message); + } + + /// + /// Adds a list of errors to the collection and sets to false + /// + /// + public void AddErrors(IEnumerable errors) + { + // force to false if previously true + Success = false; + + if (errors == null) + { + return; + } + + foreach (var error in errors) + { + AddDistinctError(error); + } + } + + #region Private Methods + + /// + /// Adds only a distinct error string to the list + /// + /// + private void AddDistinctError(string error) + { + if (!string.IsNullOrWhiteSpace(error) && !Errors.Contains(error)) + { + Errors.Add(error); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Salesforce.NET.csproj b/Salesforce.NET.csproj new file mode 100644 index 0000000..ade6488 --- /dev/null +++ b/Salesforce.NET.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.1 + + + + + + + + + diff --git a/Salesforce.NET.sln b/Salesforce.NET.sln new file mode 100644 index 0000000..c48bfc4 --- /dev/null +++ b/Salesforce.NET.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31205.134 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Salesforce.NET", "Salesforce.NET.csproj", "{2E4FA050-AC57-42EC-A690-63507C6DBA07}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2E4FA050-AC57-42EC-A690-63507C6DBA07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E4FA050-AC57-42EC-A690-63507C6DBA07}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E4FA050-AC57-42EC-A690-63507C6DBA07}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E4FA050-AC57-42EC-A690-63507C6DBA07}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E0346F8C-655F-4744-9E46-CA8AFC8F531C} + EndGlobalSection +EndGlobal diff --git a/SalesforceApiClient.cs b/SalesforceApiClient.cs new file mode 100644 index 0000000..2bcc2d2 --- /dev/null +++ b/SalesforceApiClient.cs @@ -0,0 +1,707 @@ +using BinaryDad.Extensions; +using Newtonsoft.Json; +using Salesforce.NET.Entities; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using Newtonsoft.Json.Converters; +using System.Net; + +namespace Salesforce.NET +{ + public class SalesforceApiClient + { + private const string ContextKey = "SalesforceApiContext"; + + private readonly Task initializationTask; + private readonly string batchProcessingConnectionString; + + const string apiVersion = "51.0"; + + private SalesforceContext SalesforceContext + { + get => CacheHelper.Get(ContextKey); + set => CacheHelper.Add(ContextKey, value, 1440); + } + + public SalesforceApiClient(SalesforceCredentials credentials) + { + if (SalesforceContext == null) + { + // authenticate from constructor, but task is awaited prior to invoking request + initializationTask = AuthenticateAsync(credentials); + } + } + + /// + /// Retrieves a single Salesforce record by ID + /// + /// + /// + /// + public async Task GetAsync(string id) where T : SalesforceEntity + { + var salesforceObject = GetObjectName(); + + var getApiUrl = await GetEndpointUrlAsync($"sobjects/{salesforceObject}/{id}"); + + return await InvokeRequestAsync(async httpClient => + { + var response = await httpClient.GetAsync(getApiUrl); + + //var responseBody = await response.Content.ReadAsStringAsync(); + //return responseBody.Deserialize(); + + return await response.Content.ReadAsAsync(); + }); + } + + /// + /// Retrieves a single Salesforce record matching on an external ID + /// + /// + /// The property representing of the external ID to lookup + /// + /// + public async Task GetAsync(Expression> externalIdProperty, string id) where T : SalesforceEntity + { + var salesforceObject = GetObjectName(); + + if (externalIdProperty.Body is MemberExpression memberExpression) + { + var jsonProperty = memberExpression.Member.GetCustomAttribute(); + + var propertyName = jsonProperty?.PropertyName ?? memberExpression.Member.Name; + + var getApiUrl = await GetEndpointUrlAsync($"sobjects/{salesforceObject}/{propertyName}/{id}"); + + return await InvokeRequestAsync(async httpClient => + { + var response = await httpClient.GetAsync(getApiUrl); + + return await response.Content.ReadAsAsync(); + }); + } + + throw new ArgumentException("External ID must be a property expression", nameof(externalIdProperty)); + } + + /// + /// Creates a new Salesforce record + /// + /// + /// + /// + public async Task> CreateAsync(T record) where T : SalesforceEntity + { + var result = new Result(); + + var salesforceObject = GetObjectName(); + + var createApiUrl = await GetEndpointUrlAsync($"sobjects/{salesforceObject}"); + + return await InvokeRequestAsync(async httpClient => + { + record.SerializeReadOnlyProperties = false; + + var response = await httpClient.PostAsJsonAsync(createApiUrl, record); + + //var responseBody = await response.Content.ReadAsStringAsync(); + //var createResponse = responseBody.Deserialize(); + + var createResponse = await response.Content.ReadAsAsync(); + + if (createResponse.Success) + { + record.RecordId = createResponse.RecordId; + + result.Data = createResponse.RecordId; + result.Success = true; + } + else + { + // TODO: parse error response + result.AddError($"Error creating record"); + } + + return result; + }); + } + + /// + /// Creates a set of new Salesforce records + /// + /// + /// + /// + public async Task CreateAsync(IEnumerable records) where T : SalesforceEntity + { + var result = new Result(); + + var salesforceObject = GetObjectName(); + + var createApiUrl = await GetEndpointUrlAsync($"sobjects/{salesforceObject}"); + + return await InvokeRequestAsync(async httpClient => + { + var messages = new List(); + + // default to true until any fail in loop + result.Success = true; + + foreach (var record in records) + { + record.SerializeReadOnlyProperties = false; + + var response = await httpClient.PostAsJsonAsync(createApiUrl, record); + + var responseBody = await response.Content.ReadAsStringAsync(); + + if (response.IsSuccessStatusCode) + { + var createResponse = responseBody.Deserialize(); + + if (createResponse.Success) + { + record.RecordId = createResponse.RecordId; + + messages.Add($"Created record with ID {record.RecordId}"); + } + else + { + // TODO: follow pattern of batch lead create, consolidate response inti Result + result.AddError($"Error creating record"); + } + } + else + { + var errorResponse = responseBody.Deserialize(); + + var errorMessages = errorResponse + .Select(e => $"[{e.ErrorCode}] {e.Message}") + .ToList(); + + result.AddErrors(errorMessages); + } + + //var createResponse = await response.Content.ReadAsAsync(); + } + + if (messages.Any()) + { + result.Message = messages.Join("; "); + } + + return result; + }); + } + + /// + /// Creates a set of new Salesforce records (TO POSSIBLY REPLACE CreateAsync(IEnumerable)) + /// + /// + /// + /// + public async Task CreateBulkAsync(IEnumerable records) where T : SalesforceEntity + { + var salesforceObject = GetObjectName(); + + #region Create batch job + + var jobCreateResponse = await InvokeRequestAsync(async httpClient => + { + var createApiUrl = await GetEndpointUrlAsync("jobs/ingest"); + + var response = await httpClient.PostAsJsonAsync(createApiUrl, new + { + @object = salesforceObject, + contentType = "CSV", + operation = "insert", + lineEnding = "CRLF" + }); + + return await response.Content.ReadAsAsync(); + }); + + #endregion + + #region Upload content + + var uploadResponse = await InvokeRequestAsync(async httpClient => + { + var insertApiUrl = UrlUtility.Combine(SalesforceContext.InstanceUrl, jobCreateResponse.ContentUrl); + + var recordsTable = records.ToDataTable(info => info.GetCustomAttribute()?.PropertyName); + + var recordsCsv = recordsTable.ToCsv(); + + var recordsEncoded = recordsCsv.Base64Encode(); + + var csvContent = new StringContent(recordsEncoded); + + csvContent.Headers.ContentType = new MediaTypeHeaderValue("text/csv"); + + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + var response = await httpClient.PutAsync(insertApiUrl, csvContent); + + return await response.Content.ReadAsStringAsync(); + }); + + #endregion + + #region Close job + + var closeResponse = await InvokeRequestAsync(async httpClient => + { + var closeApiUrl = await GetEndpointUrlAsync($"jobs/ingest/{jobCreateResponse.Id}"); + + var method = new HttpMethod("PATCH"); + + var body = new + { + state = "UploadComplete" + }; + + var content = new StringContent(body.Serialize(), Encoding.UTF8, "application/json"); + + var message = new HttpRequestMessage(method, closeApiUrl) + { + Content = content + }; + + var response = await httpClient.SendAsync(message); + + return await response.Content.ReadAsStringAsync(); + }); + + #endregion + + #region Get Status + + var statusResponse = await InvokeRequestAsync(async httpClient => + { + var statusApiUrl = await GetEndpointUrlAsync($"jobs/ingest/{jobCreateResponse.Id}"); + + var response = await httpClient.GetAsync(statusApiUrl); + + return await response.Content.ReadAsStringAsync(); + }); + + #endregion + + #region Download results + + var downloadResponse = await InvokeRequestAsync(async httpClient => + { + var downloadApiUrl = await GetEndpointUrlAsync($"jobs/ingest/{jobCreateResponse.Id}/failedResults"); + + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/csv")); + + var response = await httpClient.GetAsync(downloadApiUrl); + + return await response.Content.ReadAsStringAsync(); + }); + + #endregion + + return null; + } + + public Task UpdateAsync(string id, Action update) where T : SalesforceEntity, new() + { + var record = new T() + { + RecordId = id + }; + + var trackable = record.AsTrackable(); + + update(record); + + return UpdateAsync(trackable); + } + + public async Task UpdateAsync(Trackable record) where T : SalesforceEntity + { + if (record.Value.RecordId.IsNullOrWhiteSpace()) + { + throw new ArgumentException("Record ID cannot be null or empty", nameof(record.Value.RecordId)); + } + + var salesforceObject = GetObjectName(); + + var createApiUrl = await GetEndpointUrlAsync($"sobjects/{salesforceObject}/{record.Value.RecordId}"); + + return await InvokeRequestAsync(async httpClient => + { + var method = new HttpMethod("PATCH"); + + var body = JsonConvert.SerializeObject(record.Modified, new StringEnumConverter()); + + var content = new StringContent(body, Encoding.UTF8, "application/json"); + + var message = new HttpRequestMessage(method, createApiUrl) + { + Content = content + }; + + var response = await httpClient.SendAsync(message); + + if (response.IsSuccessStatusCode) + { + return new UpdateResponse(true); + } + + //var responseBody = await response.Content.ReadAsStringAsync(); + + return await response.Content.ReadAsAsync(); + }); + } + + /// + /// Retrieves Salesforce records using an object query expression + /// + /// + /// + /// + public async Task> QueryAsync(Expression> query) where T : SalesforceEntity + { + var salesforceObject = GetObjectName(); + + // build a list of properties used in the "select" portion of the query + var properties = typeof(T) + .GetProperties() + .WhereIsQueryable() + .WhereIsSerializable() + .Select(p => + { + var jsonProperty = p.GetCustomAttribute(); + + return jsonProperty?.PropertyName ?? p.Name; + }) + .WhereNotNull() + .Join(", "); + + // generate a SQL clause from the query expression + var clause = ConvertExpression(query.Body); + + var queryApiUrl = await GetEndpointUrlAsync($"query?q=select {properties} from {salesforceObject} where {clause}"); + + return await InvokeRequestAsync(async httpClient => + { + var response = await httpClient.GetAsync(queryApiUrl); + + var queryResponse = await response.Content.ReadAsAsync>(); + + var records = queryResponse.Records; + + // TODO: incorporate limit + while (!queryResponse.Done) + { + var absoluteNextRecordsUrl = UrlUtility.Combine(SalesforceContext.InstanceUrl, queryResponse.NextRecordsUrl); + + response = await httpClient.GetAsync(absoluteNextRecordsUrl); + + queryResponse = await response.Content.ReadAsAsync>(); + + records.AddRange(queryResponse.Records); + } + + return records; + }); + } + + /// + /// Uploads a binary file (byte array) + /// + /// + /// + /// + /// + /// + public async Task> UploadFileAsync(byte[] file, string fileName, string fileType, string ownerId) + { + /* CONSIDERATIONS: + * 1. change fileType to category? + * 2. if ownerId is always a lead record ID, rename to leadRecordId + * 3. we may or may not need externalSystemId if the lead record will always exist prior to sending up a document + * + * { + * "fileName": "Baby Shark Test.csv", // Name of the file + * "category": "Contract", // Category to set file metadata (We'll need a list of the possible values) + * "leadId": "410916", // Quickbase Record ID for the lead this document is related to + * "encodedFile": "UmVjb3JkIElkLENsaWVudCBGaXJ...=", // Base 64 encoded file. + * "externalSystemId": "12345" // If we don't have lead record ID from Quickbase, use this as an identifier + * } */ + + var result = new Result(); + + var uploadFileApiUrl = await GetApexUrlAsync($"??????"); + + var request = new + { + fileName, + category = fileType, + leadId = ownerId, + encodedFile = Convert.ToBase64String(file) + }; + + return await InvokeRequestAsync(async httpClient => + { + var response = await httpClient.PostAsJsonAsync(uploadFileApiUrl, request); + + var responseBody = await response.Content.ReadAsStringAsync(); + + // TODO: parse actual response + + result.Success = true; + + return result; + }); + } + + /// + /// Retrieves schema information for an entity + /// + /// + /// + public async Task GetSchema() where T : SalesforceEntity + { + var salesforceObject = GetObjectName(); + + var schemaApiUrl = await GetEndpointUrlAsync($"sobjects/{salesforceObject}/describe"); + + return await InvokeRequestAsync(async httpClient => + { + var response = await httpClient.GetAsync(schemaApiUrl); + + var responseBody = await response.Content.ReadAsStringAsync(); + + return await response.Content.ReadAsAsync(); + }); + } + + /// + /// Validates whether the entity is properly mapped to its schema in Salesforce + /// + /// + /// + public async Task> ValidateSchema() where T : SalesforceEntity, new() + { + var result = new Result(); + var schema = await GetSchema(); + + // get the fields from Salesforce + var salesforceFields = schema.Fields + .Select(f => f.Name) + .ToList(); + + // get the fields for the entity + var propertyNames = typeof(T) + .GetProperties() + .WhereIsSerializable() + .WhereIsQueryable() + .GetPropertyNames(); + + // find any orphaned/mismatched fields + var mismatchedFields = propertyNames + .Where(p => !salesforceFields.Contains(p, StringComparer.OrdinalIgnoreCase)) + .ToList(); + + result.Success = mismatchedFields.NoneOrNull(); + + if (result.Success) + { + result.Message = "All fields are valid"; + } + else + { + foreach (var mismatchedField in mismatchedFields) + { + result.AddError($"Field [{mismatchedField}] was not found in source"); + } + } + + return result; + } + + #region Private Methods + + private async Task AuthenticateAsync(SalesforceCredentials credentials) + { + var baseApiUrl = credentials.IsProduction ? "https://login.salesforce.com/services" : "https://test.salesforce.com/services"; + + var authenticationUrl = UrlUtility.Combine(baseApiUrl, "oauth2/token"); + + var httpClient = new HttpClient(); + + var authenticationRequest = new Dictionary + { + ["grant_type"] = "password", + ["client_id"] = credentials.ClientId, + ["client_secret"] = credentials.ClientSecret, + ["username"] = credentials.Username, + ["password"] = WebUtility.UrlEncode(credentials.Password) + credentials.SecurityToken + }; + + // don't use ToQueryString() as it encodes the values + var requestBody = authenticationRequest + .Select(k => $"{k.Key}={k.Value}") + .Join("&"); + + //var serializedRequest = Encoding.UTF8.GetBytes(requestBody); + + //var request = new HttpRequestMessage(HttpMethod.Post, authenticationUrl) + //{ + // Content = new ByteArrayContent(serializedRequest) + //}; + + //request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded"); + + var requestContent = new StringContent(requestBody, Encoding.UTF8, "application/x-www-form-urlencoded"); + + + //var response = await httpClient.SendAsync(request); + var response = await httpClient.PostAsync(authenticationUrl, requestContent); + + //var responseBody = await response.Content.ReadAsStringAsync(); + + var authenticationResponse = await response.Content.ReadAsAsync(); + + if (authenticationResponse.Success) + { + SalesforceContext = new SalesforceContext(authenticationResponse.AccessToken, authenticationResponse.InstanceUrl, authenticationResponse.TokenType); + } + } + + private async Task InvokeRequestAsync(Func> action) + { + await AssertInitializedAsync(); + + var httpClient = new HttpClient(); + + httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(SalesforceContext.TokenType.ToString(), SalesforceContext.AccessToken); + + return await action(httpClient); + } + + private async Task GetEndpointUrlAsync(string relativeApiUrl) + { + await AssertInitializedAsync(); + + return UrlUtility.Combine(SalesforceContext.InstanceUrl, $"services/data/v{apiVersion}/{relativeApiUrl}"); + } + + private async Task GetApexUrlAsync(string relativeApiUrl) + { + await AssertInitializedAsync(); + + return UrlUtility.Combine(SalesforceContext.InstanceUrl, $"services/apexrest/api/{relativeApiUrl}"); + } + + private string GetObjectName() + { + var type = typeof(T); + var objectAttribute = type.GetCustomAttribute(); + + return objectAttribute?.ObjectName ?? type.Name; + } + + /// + /// Converts an expression tree into a SQL query clause + /// + /// + /// + private static string ConvertExpression(Expression expression) + { + /* NOTE: this is a work in progress, as I did not like the built-in + * Expression.ToString(), and this allows us to customize the query to our liking */ + + if (expression is BinaryExpression binaryExpression) + { + // traverse the tree and combine all sub expression groups + var left = ConvertExpression(binaryExpression.Left); + var comparison = GetExpressionType(binaryExpression.NodeType); + var right = ConvertExpression(binaryExpression.Right); + + return $"({left} {comparison} {right})"; + } + + if (expression is ConstantExpression || expression is MethodCallExpression) + { + return GetExpressionValue(expression); + } + + if (expression is MemberExpression memberExpression) + { + if (memberExpression.Expression is ParameterExpression) + { + // NOTE: this should be be the property from the delegate's parameter + + var jsonProperty = memberExpression.Member.GetCustomAttribute(); + + return jsonProperty != null ? jsonProperty.PropertyName : memberExpression.Member.Name; + } + + return GetExpressionValue(expression); + } + + return string.Empty; + } + + private static string GetExpressionValue(Expression expression) + { + var value = Expression.Lambda(expression).Compile().DynamicInvoke(); + + if (expression.Type == typeof(string)) + { + // TODO: escaping single quotes? + return $"'{value}'"; + } + + if (expression.Type == typeof(DateTime)) + { + return ((DateTime)value).ToString("yyyy-MM-ddThh:mm:ssZ"); + } + + if (value == null) + { + return string.Empty; + } + + return value.ToString(); + } + + private static string GetExpressionType(ExpressionType expressionType) + { + return expressionType == ExpressionType.Equal ? "=" + : expressionType == ExpressionType.NotEqual ? "!=" + : expressionType == ExpressionType.GreaterThan ? ">" + : expressionType == ExpressionType.GreaterThanOrEqual ? ">=" + : expressionType == ExpressionType.LessThan ? "<" + : expressionType == ExpressionType.LessThanOrEqual ? "<=" + : expressionType == ExpressionType.AndAlso ? "and" + : expressionType == ExpressionType.And ? "and" + : expressionType == ExpressionType.Or ? "or" + : expressionType == ExpressionType.OrElse ? "or" + : ""; + } + + private async Task AssertInitializedAsync() + { + if (SalesforceContext == null && initializationTask != null) + { + await initializationTask; + } + } + + #endregion + } +} diff --git a/SalesforceContext.cs b/SalesforceContext.cs new file mode 100644 index 0000000..62e2309 --- /dev/null +++ b/SalesforceContext.cs @@ -0,0 +1,19 @@ +namespace Salesforce.NET +{ + /// + /// Maintains context regarding the current Salesforce API connection + /// + public class SalesforceContext + { + public string AccessToken { get; } + public string InstanceUrl { get; } + public TokenType TokenType { get; } + + public SalesforceContext(string accessToken, string instanceUrl, TokenType tokenType) + { + AccessToken = accessToken; + InstanceUrl = instanceUrl; + TokenType = tokenType; + } + } +} diff --git a/SalesforceCredentials.cs b/SalesforceCredentials.cs new file mode 100644 index 0000000..1acbdcf --- /dev/null +++ b/SalesforceCredentials.cs @@ -0,0 +1,34 @@ +namespace Salesforce.NET +{ + public class SalesforceCredentials + { + public bool IsProduction { get; set; } + public string ClientId { get; set; } + public string ClientSecret { get; set; } + public string Username { get; set; } + public string Password { get; set; } + public string SecurityToken { get; set; } + + /// + /// Loads a set of default credentials + /// + /// + public static SalesforceCredentials PocSandbox() + { + return new SalesforceCredentials + { + IsProduction = false, + Username = "integration@clearoneadvantage.com.pocsandbox", + Password = "nanR#Mo8", + SecurityToken = "1jMfMWqmQ0YpjX1JyVh7iUkvV", + ClientId = "3MVG967gVD5fuTmI4keNlyXpELeZ8J5ZsW27nmeeMtpjSjimy5QGiTBEoTnW.c661Af2eV7vEk0NTnp3JYjFA", + ClientSecret = "1168DAD1B619C2EE81EA6C3E248F9B2B24993ACD41E8CB11DE79D83FBE771465" + }; + } + + public SalesforceCredentials() + { + // TODO: validate property data + } + } +} diff --git a/SchemaResponse.cs b/SchemaResponse.cs new file mode 100644 index 0000000..32f8f80 --- /dev/null +++ b/SchemaResponse.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace Salesforce.NET +{ + public class SchemaResponse + { + public ICollection Fields { get; set; } + + public class SchemaField + { + /// + /// User-friendly name for the field + /// + public string Label { get; set; } + + /// + /// Internal name for the field + /// + public string Name { get; set; } + + public string DefaultValue { get; set; } + public string Type { get; set; } + } + } +} \ No newline at end of file diff --git a/TokenType.cs b/TokenType.cs new file mode 100644 index 0000000..043a8e4 --- /dev/null +++ b/TokenType.cs @@ -0,0 +1,7 @@ +namespace Salesforce.NET +{ + public enum TokenType + { + Bearer + } +} diff --git a/Trackable.cs b/Trackable.cs new file mode 100644 index 0000000..59a6284 --- /dev/null +++ b/Trackable.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Salesforce.NET +{ + /// + /// Allows for an object to track changes made + /// + /// + public class Trackable + { + private readonly Type type; + + private T value; + private IDictionary modified; + + private readonly IDictionary originalPropertyValues = new Dictionary(); + private readonly IDictionary latestPropertyValues = new Dictionary(); + + public Trackable(T value) + { + this.value = value; + + type = value.GetType(); + + SetPropertyValues(originalPropertyValues); + } + + public T Value + { + get => value; + protected set => this.value = value; + } + + /// + /// Gets a dictionary of modified fields since the object was created + /// + public IDictionary Modified + { + get + { + SetPropertyValues(latestPropertyValues); + + return originalPropertyValues + .Join(latestPropertyValues, o => o.Key, l => l.Key, (o, l) => new + { + Original = o, + Latest = l + }) + .Where(p => !object.Equals(p.Original.Value, p.Latest.Value)) + .Select(p => p.Latest) + .ToDictionary(t => t.Key, t => t.Value); + } + + protected set => modified = value; + } + + private void SetPropertyValues(IDictionary propertyValues) + { + type + .GetProperties() + .ToList() + .ForEach(p => propertyValues[p.Name] = p.GetValue(value)?.ToString()); + } + } + + public static class Trackable + { + /// + /// Allows an object to track changes for the Salesforce API update + /// + /// + /// + /// + public static Trackable AsTrackable(this T value) + { + return new Trackable(value); + } + } +} diff --git a/UpdateResponse.cs b/UpdateResponse.cs new file mode 100644 index 0000000..7352d5e --- /dev/null +++ b/UpdateResponse.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace Salesforce.NET +{ + public class UpdateResponse : IApiResponse + { + public bool Success { get; set; } + + [JsonProperty("errorCode")] + public string ErrorCode { get; set; } + + [JsonProperty("message")] + public string Message { get; set; } + + public UpdateResponse() { } + + public UpdateResponse(bool success) + { + Success = success; + } + } +} diff --git a/bin/Debug/netstandard2.1/Salesforce.NET.deps.json b/bin/Debug/netstandard2.1/Salesforce.NET.deps.json new file mode 100644 index 0000000..8adfe58 --- /dev/null +++ b/bin/Debug/netstandard2.1/Salesforce.NET.deps.json @@ -0,0 +1,250 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.1/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.1": {}, + ".NETStandard,Version=v2.1/": { + "Salesforce.NET/1.0.0": { + "dependencies": { + "BinaryDad.Extensions": "21.4.20.3", + "Newtonsoft.Json": "13.0.1", + "System.Runtime.Caching": "5.0.0" + }, + "runtime": { + "Salesforce.NET.dll": {} + } + }, + "BinaryDad.Extensions/21.4.20.3": { + "dependencies": { + "Newtonsoft.Json": "13.0.1", + "System.ComponentModel.Annotations": "5.0.0", + "System.Runtime.Caching": "5.0.0" + }, + "runtime": { + "lib/netstandard2.0/BinaryDad.Extensions.dll": { + "assemblyVersion": "21.4.20.3", + "fileVersion": "21.4.20.3" + } + } + }, + "Newtonsoft.Json/13.0.1": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1.25517" + } + } + }, + "System.Buffers/4.5.1": { + "runtime": { + "lib/netstandard2.0/System.Buffers.dll": { + "assemblyVersion": "4.0.3.0", + "fileVersion": "4.6.28619.1" + } + } + }, + "System.ComponentModel.Annotations/5.0.0": { + "runtime": { + "lib/netstandard2.1/System.ComponentModel.Annotations.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "System.Configuration.ConfigurationManager/5.0.0": { + "dependencies": { + "System.Security.Cryptography.ProtectedData": "5.0.0", + "System.Security.Permissions": "5.0.0" + }, + "runtime": { + "lib/netstandard2.0/System.Configuration.ConfigurationManager.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "System.Memory/4.5.4": { + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + }, + "runtime": { + "lib/netstandard2.0/System.Memory.dll": { + "assemblyVersion": "4.0.1.1", + "fileVersion": "4.6.28619.1" + } + } + }, + "System.Numerics.Vectors/4.4.0": { + "runtime": { + "lib/netstandard2.0/System.Numerics.Vectors.dll": { + "assemblyVersion": "4.1.3.0", + "fileVersion": "4.6.25519.3" + } + } + }, + "System.Runtime.Caching/5.0.0": { + "dependencies": { + "System.Configuration.ConfigurationManager": "5.0.0" + }, + "runtime": { + "lib/netstandard2.0/System.Runtime.Caching.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "System.Runtime.CompilerServices.Unsafe/4.5.3": { + "runtime": { + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": { + "assemblyVersion": "4.0.4.1", + "fileVersion": "4.6.28619.1" + } + } + }, + "System.Security.AccessControl/5.0.0": { + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + }, + "runtime": { + "lib/netstandard2.0/System.Security.AccessControl.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "System.Security.Cryptography.ProtectedData/5.0.0": { + "dependencies": { + "System.Memory": "4.5.4" + }, + "runtime": { + "lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "System.Security.Permissions/5.0.0": { + "dependencies": { + "System.Security.AccessControl": "5.0.0" + }, + "runtime": { + "lib/netstandard2.0/System.Security.Permissions.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "System.Security.Principal.Windows/5.0.0": { + "runtime": { + "lib/netstandard2.0/System.Security.Principal.Windows.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + } + } + }, + "libraries": { + "Salesforce.NET/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "BinaryDad.Extensions/21.4.20.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-2JgmHs4yw6WQVM6BQshO05HeB8NcGPLtQnAytDkVNoMD7kHznX5o+f+B0zQe+vIe75559CtBzOT5hZHOd3W+Gg==", + "path": "binarydad.extensions/21.4.20.3", + "hashPath": "binarydad.extensions.21.4.20.3.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "path": "newtonsoft.json/13.0.1", + "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" + }, + "System.Buffers/4.5.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==", + "path": "system.buffers/4.5.1", + "hashPath": "system.buffers.4.5.1.nupkg.sha512" + }, + "System.ComponentModel.Annotations/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==", + "path": "system.componentmodel.annotations/5.0.0", + "hashPath": "system.componentmodel.annotations.5.0.0.nupkg.sha512" + }, + "System.Configuration.ConfigurationManager/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-aM7cbfEfVNlEEOj3DsZP+2g9NRwbkyiAv2isQEzw7pnkDg9ekCU2m1cdJLM02Uq691OaCS91tooaxcEn8d0q5w==", + "path": "system.configuration.configurationmanager/5.0.0", + "hashPath": "system.configuration.configurationmanager.5.0.0.nupkg.sha512" + }, + "System.Memory/4.5.4": { + "type": "package", + "serviceable": true, + "sha512": "sha512-1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "path": "system.memory/4.5.4", + "hashPath": "system.memory.4.5.4.nupkg.sha512" + }, + "System.Numerics.Vectors/4.4.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==", + "path": "system.numerics.vectors/4.4.0", + "hashPath": "system.numerics.vectors.4.4.0.nupkg.sha512" + }, + "System.Runtime.Caching/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-30D6MkO8WF9jVGWZIP0hmCN8l9BTY4LCsAzLIe4xFSXzs+AjDotR7DpSmj27pFskDURzUvqYYY0ikModgBTxWw==", + "path": "system.runtime.caching/5.0.0", + "hashPath": "system.runtime.caching.5.0.0.nupkg.sha512" + }, + "System.Runtime.CompilerServices.Unsafe/4.5.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==", + "path": "system.runtime.compilerservices.unsafe/4.5.3", + "hashPath": "system.runtime.compilerservices.unsafe.4.5.3.nupkg.sha512" + }, + "System.Security.AccessControl/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "path": "system.security.accesscontrol/5.0.0", + "hashPath": "system.security.accesscontrol.5.0.0.nupkg.sha512" + }, + "System.Security.Cryptography.ProtectedData/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-HGxMSAFAPLNoxBvSfW08vHde0F9uh7BjASwu6JF9JnXuEPhCY3YUqURn0+bQV/4UWeaqymmrHWV+Aw9riQCtCA==", + "path": "system.security.cryptography.protecteddata/5.0.0", + "hashPath": "system.security.cryptography.protecteddata.5.0.0.nupkg.sha512" + }, + "System.Security.Permissions/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-uE8juAhEkp7KDBCdjDIE3H9R1HJuEHqeqX8nLX9gmYKWwsqk3T5qZlPx8qle5DPKimC/Fy3AFTdV7HamgCh9qQ==", + "path": "system.security.permissions/5.0.0", + "hashPath": "system.security.permissions.5.0.0.nupkg.sha512" + }, + "System.Security.Principal.Windows/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==", + "path": "system.security.principal.windows/5.0.0", + "hashPath": "system.security.principal.windows.5.0.0.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/bin/Debug/netstandard2.1/Salesforce.NET.dll b/bin/Debug/netstandard2.1/Salesforce.NET.dll new file mode 100644 index 0000000..fa9870e Binary files /dev/null and b/bin/Debug/netstandard2.1/Salesforce.NET.dll differ diff --git a/bin/Debug/netstandard2.1/Salesforce.NET.pdb b/bin/Debug/netstandard2.1/Salesforce.NET.pdb new file mode 100644 index 0000000..a9a2794 Binary files /dev/null and b/bin/Debug/netstandard2.1/Salesforce.NET.pdb differ diff --git a/obj/Debug/netstandard2.1/.NETStandard,Version=v2.1.AssemblyAttributes.cs b/obj/Debug/netstandard2.1/.NETStandard,Version=v2.1.AssemblyAttributes.cs new file mode 100644 index 0000000..bc644cb --- /dev/null +++ b/obj/Debug/netstandard2.1/.NETStandard,Version=v2.1.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.1", FrameworkDisplayName = "")] diff --git a/obj/Debug/netstandard2.1/Salesforce.NET.AssemblyInfo.cs b/obj/Debug/netstandard2.1/Salesforce.NET.AssemblyInfo.cs new file mode 100644 index 0000000..ba931f8 --- /dev/null +++ b/obj/Debug/netstandard2.1/Salesforce.NET.AssemblyInfo.cs @@ -0,0 +1,23 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("Salesforce.NET")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("Salesforce.NET")] +[assembly: System.Reflection.AssemblyTitleAttribute("Salesforce.NET")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// Generated by the MSBuild WriteCodeFragment class. + diff --git a/obj/Debug/netstandard2.1/Salesforce.NET.AssemblyInfoInputs.cache b/obj/Debug/netstandard2.1/Salesforce.NET.AssemblyInfoInputs.cache new file mode 100644 index 0000000..5651959 --- /dev/null +++ b/obj/Debug/netstandard2.1/Salesforce.NET.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +3d639814e268ae7ece407339ad1686c1502f6f44 diff --git a/obj/Debug/netstandard2.1/Salesforce.NET.assets.cache b/obj/Debug/netstandard2.1/Salesforce.NET.assets.cache new file mode 100644 index 0000000..1b568b4 Binary files /dev/null and b/obj/Debug/netstandard2.1/Salesforce.NET.assets.cache differ diff --git a/obj/Debug/netstandard2.1/Salesforce.NET.csproj.CoreCompileInputs.cache b/obj/Debug/netstandard2.1/Salesforce.NET.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..58b6bbc --- /dev/null +++ b/obj/Debug/netstandard2.1/Salesforce.NET.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +273dbaab4e6e24514b4a048450187b085b8e22e9 diff --git a/obj/Debug/netstandard2.1/Salesforce.NET.csproj.FileListAbsolute.txt b/obj/Debug/netstandard2.1/Salesforce.NET.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..0262012 --- /dev/null +++ b/obj/Debug/netstandard2.1/Salesforce.NET.csproj.FileListAbsolute.txt @@ -0,0 +1,9 @@ +D:\Git\Salesforce.NET\Salesforce.NET\obj\Debug\netstandard2.1\Salesforce.NET.csprojAssemblyReference.cache +D:\Git\Salesforce.NET\Salesforce.NET\obj\Debug\netstandard2.1\Salesforce.NET.AssemblyInfoInputs.cache +D:\Git\Salesforce.NET\Salesforce.NET\obj\Debug\netstandard2.1\Salesforce.NET.AssemblyInfo.cs +D:\Git\Salesforce.NET\Salesforce.NET\obj\Debug\netstandard2.1\Salesforce.NET.csproj.CoreCompileInputs.cache +D:\Git\Salesforce.NET\Salesforce.NET\bin\Debug\netstandard2.1\Salesforce.NET.deps.json +D:\Git\Salesforce.NET\Salesforce.NET\bin\Debug\netstandard2.1\Salesforce.NET.dll +D:\Git\Salesforce.NET\Salesforce.NET\bin\Debug\netstandard2.1\Salesforce.NET.pdb +D:\Git\Salesforce.NET\Salesforce.NET\obj\Debug\netstandard2.1\Salesforce.NET.dll +D:\Git\Salesforce.NET\Salesforce.NET\obj\Debug\netstandard2.1\Salesforce.NET.pdb diff --git a/obj/Debug/netstandard2.1/Salesforce.NET.csprojAssemblyReference.cache b/obj/Debug/netstandard2.1/Salesforce.NET.csprojAssemblyReference.cache new file mode 100644 index 0000000..4964b0c Binary files /dev/null and b/obj/Debug/netstandard2.1/Salesforce.NET.csprojAssemblyReference.cache differ diff --git a/obj/Debug/netstandard2.1/Salesforce.NET.dll b/obj/Debug/netstandard2.1/Salesforce.NET.dll new file mode 100644 index 0000000..fa9870e Binary files /dev/null and b/obj/Debug/netstandard2.1/Salesforce.NET.dll differ diff --git a/obj/Debug/netstandard2.1/Salesforce.NET.pdb b/obj/Debug/netstandard2.1/Salesforce.NET.pdb new file mode 100644 index 0000000..a9a2794 Binary files /dev/null and b/obj/Debug/netstandard2.1/Salesforce.NET.pdb differ diff --git a/obj/Salesforce.NET.csproj.nuget.dgspec.json b/obj/Salesforce.NET.csproj.nuget.dgspec.json new file mode 100644 index 0000000..4d8c35e --- /dev/null +++ b/obj/Salesforce.NET.csproj.nuget.dgspec.json @@ -0,0 +1,77 @@ +{ + "format": 1, + "restore": { + "D:\\Git\\Salesforce.NET\\Salesforce.NET\\Salesforce.NET.csproj": {} + }, + "projects": { + "D:\\Git\\Salesforce.NET\\Salesforce.NET\\Salesforce.NET.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\Git\\Salesforce.NET\\Salesforce.NET\\Salesforce.NET.csproj", + "projectName": "Salesforce.NET", + "projectPath": "D:\\Git\\Salesforce.NET\\Salesforce.NET\\Salesforce.NET.csproj", + "packagesPath": "C:\\Users\\rpeters\\.nuget\\packages\\", + "outputPath": "D:\\Git\\Salesforce.NET\\Salesforce.NET\\obj\\", + "projectStyle": "PackageReference", + "configFilePaths": [ + "C:\\Users\\rpeters\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "netstandard2.1" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "http://nuget/nuget": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "netstandard2.1": { + "targetAlias": "netstandard2.1", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "netstandard2.1": { + "targetAlias": "netstandard2.1", + "dependencies": { + "BinaryDad.Extensions": { + "target": "Package", + "version": "[21.4.20.3, )" + }, + "Newtonsoft.Json": { + "target": "Package", + "version": "[13.0.1, )" + }, + "System.Runtime.Caching": { + "target": "Package", + "version": "[5.0.0, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "NETStandard.Library": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\5.0.202\\RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/obj/Salesforce.NET.csproj.nuget.g.props b/obj/Salesforce.NET.csproj.nuget.g.props new file mode 100644 index 0000000..a156baa --- /dev/null +++ b/obj/Salesforce.NET.csproj.nuget.g.props @@ -0,0 +1,18 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + $(UserProfile)\.nuget\packages\ + C:\Users\rpeters\.nuget\packages\ + PackageReference + 5.9.1 + + + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + \ No newline at end of file diff --git a/obj/Salesforce.NET.csproj.nuget.g.targets b/obj/Salesforce.NET.csproj.nuget.g.targets new file mode 100644 index 0000000..53cfaa1 --- /dev/null +++ b/obj/Salesforce.NET.csproj.nuget.g.targets @@ -0,0 +1,6 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + \ No newline at end of file diff --git a/obj/project.assets.json b/obj/project.assets.json new file mode 100644 index 0000000..d04d6b2 --- /dev/null +++ b/obj/project.assets.json @@ -0,0 +1,751 @@ +{ + "version": 3, + "targets": { + ".NETStandard,Version=v2.1": { + "BinaryDad.Extensions/21.4.20.3": { + "type": "package", + "dependencies": { + "Newtonsoft.Json": "13.0.1", + "System.ComponentModel.Annotations": "5.0.0", + "System.Runtime.Caching": "5.0.0" + }, + "compile": { + "lib/netstandard2.0/BinaryDad.Extensions.dll": {} + }, + "runtime": { + "lib/netstandard2.0/BinaryDad.Extensions.dll": {} + } + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "compile": { + "lib/netstandard2.0/Newtonsoft.Json.dll": {} + }, + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": {} + } + }, + "System.Buffers/4.5.1": { + "type": "package", + "compile": { + "ref/netstandard2.0/_._": {} + }, + "runtime": { + "lib/netstandard2.0/System.Buffers.dll": {} + } + }, + "System.ComponentModel.Annotations/5.0.0": { + "type": "package", + "compile": { + "ref/netstandard2.1/System.ComponentModel.Annotations.dll": {} + }, + "runtime": { + "lib/netstandard2.1/System.ComponentModel.Annotations.dll": {} + } + }, + "System.Configuration.ConfigurationManager/5.0.0": { + "type": "package", + "dependencies": { + "System.Security.Cryptography.ProtectedData": "5.0.0", + "System.Security.Permissions": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/_._": {} + }, + "runtime": { + "lib/netstandard2.0/System.Configuration.ConfigurationManager.dll": {} + } + }, + "System.Memory/4.5.4": { + "type": "package", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + }, + "compile": { + "lib/netstandard2.0/_._": {} + }, + "runtime": { + "lib/netstandard2.0/System.Memory.dll": {} + } + }, + "System.Numerics.Vectors/4.4.0": { + "type": "package", + "compile": { + "ref/netstandard2.0/_._": {} + }, + "runtime": { + "lib/netstandard2.0/System.Numerics.Vectors.dll": {} + } + }, + "System.Runtime.Caching/5.0.0": { + "type": "package", + "dependencies": { + "System.Configuration.ConfigurationManager": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/System.Runtime.Caching.dll": {} + }, + "runtime": { + "lib/netstandard2.0/System.Runtime.Caching.dll": {} + }, + "runtimeTargets": { + "runtimes/win/lib/netstandard2.0/System.Runtime.Caching.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "System.Runtime.CompilerServices.Unsafe/4.5.3": { + "type": "package", + "compile": { + "ref/netstandard2.0/_._": {} + }, + "runtime": { + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll": {} + } + }, + "System.Security.AccessControl/5.0.0": { + "type": "package", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/_._": {} + }, + "runtime": { + "lib/netstandard2.0/System.Security.AccessControl.dll": {} + }, + "runtimeTargets": { + "runtimes/win/lib/netstandard1.3/System.Security.AccessControl.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "System.Security.Cryptography.ProtectedData/5.0.0": { + "type": "package", + "dependencies": { + "System.Memory": "4.5.4" + }, + "compile": { + "ref/netstandard2.0/_._": {} + }, + "runtime": { + "lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll": {} + }, + "runtimeTargets": { + "runtimes/win/lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll": { + "assetType": "runtime", + "rid": "win" + } + } + }, + "System.Security.Permissions/5.0.0": { + "type": "package", + "dependencies": { + "System.Security.AccessControl": "5.0.0" + }, + "compile": { + "ref/netstandard2.0/_._": {} + }, + "runtime": { + "lib/netstandard2.0/System.Security.Permissions.dll": {} + } + }, + "System.Security.Principal.Windows/5.0.0": { + "type": "package", + "compile": { + "ref/netstandard2.0/_._": {} + }, + "runtime": { + "lib/netstandard2.0/System.Security.Principal.Windows.dll": {} + }, + "runtimeTargets": { + "runtimes/win/lib/netstandard1.3/System.Security.Principal.Windows.dll": { + "assetType": "runtime", + "rid": "win" + } + } + } + } + }, + "libraries": { + "BinaryDad.Extensions/21.4.20.3": { + "sha512": "2JgmHs4yw6WQVM6BQshO05HeB8NcGPLtQnAytDkVNoMD7kHznX5o+f+B0zQe+vIe75559CtBzOT5hZHOd3W+Gg==", + "type": "package", + "path": "binarydad.extensions/21.4.20.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "binarydad.extensions.21.4.20.3.nupkg.sha512", + "binarydad.extensions.nuspec", + "lib/netstandard2.0/BinaryDad.Extensions.dll" + ] + }, + "Newtonsoft.Json/13.0.1": { + "sha512": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "type": "package", + "path": "newtonsoft.json/13.0.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.1.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "System.Buffers/4.5.1": { + "sha512": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==", + "type": "package", + "path": "system.buffers/4.5.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Buffers.dll", + "lib/net461/System.Buffers.xml", + "lib/netcoreapp2.0/_._", + "lib/netstandard1.1/System.Buffers.dll", + "lib/netstandard1.1/System.Buffers.xml", + "lib/netstandard2.0/System.Buffers.dll", + "lib/netstandard2.0/System.Buffers.xml", + "lib/uap10.0.16299/_._", + "ref/net45/System.Buffers.dll", + "ref/net45/System.Buffers.xml", + "ref/netcoreapp2.0/_._", + "ref/netstandard1.1/System.Buffers.dll", + "ref/netstandard1.1/System.Buffers.xml", + "ref/netstandard2.0/System.Buffers.dll", + "ref/netstandard2.0/System.Buffers.xml", + "ref/uap10.0.16299/_._", + "system.buffers.4.5.1.nupkg.sha512", + "system.buffers.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.ComponentModel.Annotations/5.0.0": { + "sha512": "dMkqfy2el8A8/I76n2Hi1oBFEbG1SfxD2l5nhwXV3XjlnOmwxJlQbYpJH4W51odnU9sARCSAgv7S3CyAFMkpYg==", + "type": "package", + "path": "system.componentmodel.annotations/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/MonoAndroid10/_._", + "lib/MonoTouch10/_._", + "lib/net45/_._", + "lib/net461/System.ComponentModel.Annotations.dll", + "lib/netcore50/System.ComponentModel.Annotations.dll", + "lib/netstandard1.4/System.ComponentModel.Annotations.dll", + "lib/netstandard2.0/System.ComponentModel.Annotations.dll", + "lib/netstandard2.1/System.ComponentModel.Annotations.dll", + "lib/netstandard2.1/System.ComponentModel.Annotations.xml", + "lib/portable-net45+win8/_._", + "lib/win8/_._", + "lib/xamarinios10/_._", + "lib/xamarinmac20/_._", + "lib/xamarintvos10/_._", + "lib/xamarinwatchos10/_._", + "ref/MonoAndroid10/_._", + "ref/MonoTouch10/_._", + "ref/net45/_._", + "ref/net461/System.ComponentModel.Annotations.dll", + "ref/net461/System.ComponentModel.Annotations.xml", + "ref/netcore50/System.ComponentModel.Annotations.dll", + "ref/netcore50/System.ComponentModel.Annotations.xml", + "ref/netcore50/de/System.ComponentModel.Annotations.xml", + "ref/netcore50/es/System.ComponentModel.Annotations.xml", + "ref/netcore50/fr/System.ComponentModel.Annotations.xml", + "ref/netcore50/it/System.ComponentModel.Annotations.xml", + "ref/netcore50/ja/System.ComponentModel.Annotations.xml", + "ref/netcore50/ko/System.ComponentModel.Annotations.xml", + "ref/netcore50/ru/System.ComponentModel.Annotations.xml", + "ref/netcore50/zh-hans/System.ComponentModel.Annotations.xml", + "ref/netcore50/zh-hant/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/System.ComponentModel.Annotations.dll", + "ref/netstandard1.1/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/de/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/es/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/fr/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/it/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/ja/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/ko/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/ru/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/zh-hans/System.ComponentModel.Annotations.xml", + "ref/netstandard1.1/zh-hant/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/System.ComponentModel.Annotations.dll", + "ref/netstandard1.3/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/de/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/es/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/fr/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/it/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/ja/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/ko/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/ru/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/zh-hans/System.ComponentModel.Annotations.xml", + "ref/netstandard1.3/zh-hant/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/System.ComponentModel.Annotations.dll", + "ref/netstandard1.4/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/de/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/es/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/fr/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/it/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/ja/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/ko/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/ru/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/zh-hans/System.ComponentModel.Annotations.xml", + "ref/netstandard1.4/zh-hant/System.ComponentModel.Annotations.xml", + "ref/netstandard2.0/System.ComponentModel.Annotations.dll", + "ref/netstandard2.0/System.ComponentModel.Annotations.xml", + "ref/netstandard2.1/System.ComponentModel.Annotations.dll", + "ref/netstandard2.1/System.ComponentModel.Annotations.xml", + "ref/portable-net45+win8/_._", + "ref/win8/_._", + "ref/xamarinios10/_._", + "ref/xamarinmac20/_._", + "ref/xamarintvos10/_._", + "ref/xamarinwatchos10/_._", + "system.componentmodel.annotations.5.0.0.nupkg.sha512", + "system.componentmodel.annotations.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Configuration.ConfigurationManager/5.0.0": { + "sha512": "aM7cbfEfVNlEEOj3DsZP+2g9NRwbkyiAv2isQEzw7pnkDg9ekCU2m1cdJLM02Uq691OaCS91tooaxcEn8d0q5w==", + "type": "package", + "path": "system.configuration.configurationmanager/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Configuration.ConfigurationManager.dll", + "lib/net461/System.Configuration.ConfigurationManager.xml", + "lib/netstandard2.0/System.Configuration.ConfigurationManager.dll", + "lib/netstandard2.0/System.Configuration.ConfigurationManager.xml", + "ref/net461/System.Configuration.ConfigurationManager.dll", + "ref/net461/System.Configuration.ConfigurationManager.xml", + "ref/netstandard2.0/System.Configuration.ConfigurationManager.dll", + "ref/netstandard2.0/System.Configuration.ConfigurationManager.xml", + "system.configuration.configurationmanager.5.0.0.nupkg.sha512", + "system.configuration.configurationmanager.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Memory/4.5.4": { + "sha512": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "type": "package", + "path": "system.memory/4.5.4", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Memory.dll", + "lib/net461/System.Memory.xml", + "lib/netcoreapp2.1/_._", + "lib/netstandard1.1/System.Memory.dll", + "lib/netstandard1.1/System.Memory.xml", + "lib/netstandard2.0/System.Memory.dll", + "lib/netstandard2.0/System.Memory.xml", + "ref/netcoreapp2.1/_._", + "system.memory.4.5.4.nupkg.sha512", + "system.memory.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Numerics.Vectors/4.4.0": { + "sha512": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==", + "type": "package", + "path": "system.numerics.vectors/4.4.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/MonoAndroid10/_._", + "lib/MonoTouch10/_._", + "lib/net46/System.Numerics.Vectors.dll", + "lib/net46/System.Numerics.Vectors.xml", + "lib/netcoreapp2.0/_._", + "lib/netstandard1.0/System.Numerics.Vectors.dll", + "lib/netstandard1.0/System.Numerics.Vectors.xml", + "lib/netstandard2.0/System.Numerics.Vectors.dll", + "lib/netstandard2.0/System.Numerics.Vectors.xml", + "lib/portable-net45+win8+wp8+wpa81/System.Numerics.Vectors.dll", + "lib/portable-net45+win8+wp8+wpa81/System.Numerics.Vectors.xml", + "lib/xamarinios10/_._", + "lib/xamarinmac20/_._", + "lib/xamarintvos10/_._", + "lib/xamarinwatchos10/_._", + "ref/MonoAndroid10/_._", + "ref/MonoTouch10/_._", + "ref/net46/System.Numerics.Vectors.dll", + "ref/net46/System.Numerics.Vectors.xml", + "ref/netcoreapp2.0/_._", + "ref/netstandard1.0/System.Numerics.Vectors.dll", + "ref/netstandard1.0/System.Numerics.Vectors.xml", + "ref/netstandard2.0/System.Numerics.Vectors.dll", + "ref/netstandard2.0/System.Numerics.Vectors.xml", + "ref/xamarinios10/_._", + "ref/xamarinmac20/_._", + "ref/xamarintvos10/_._", + "ref/xamarinwatchos10/_._", + "system.numerics.vectors.4.4.0.nupkg.sha512", + "system.numerics.vectors.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Runtime.Caching/5.0.0": { + "sha512": "30D6MkO8WF9jVGWZIP0hmCN8l9BTY4LCsAzLIe4xFSXzs+AjDotR7DpSmj27pFskDURzUvqYYY0ikModgBTxWw==", + "type": "package", + "path": "system.runtime.caching/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/MonoAndroid10/_._", + "lib/MonoTouch10/_._", + "lib/net45/_._", + "lib/netstandard2.0/System.Runtime.Caching.dll", + "lib/netstandard2.0/System.Runtime.Caching.xml", + "lib/xamarinios10/_._", + "lib/xamarinmac20/_._", + "lib/xamarintvos10/_._", + "lib/xamarinwatchos10/_._", + "ref/MonoAndroid10/_._", + "ref/MonoTouch10/_._", + "ref/net45/_._", + "ref/netstandard2.0/System.Runtime.Caching.dll", + "ref/netstandard2.0/System.Runtime.Caching.xml", + "ref/xamarinios10/_._", + "ref/xamarinmac20/_._", + "ref/xamarintvos10/_._", + "ref/xamarinwatchos10/_._", + "runtimes/win/lib/net45/_._", + "runtimes/win/lib/netstandard2.0/System.Runtime.Caching.dll", + "runtimes/win/lib/netstandard2.0/System.Runtime.Caching.xml", + "system.runtime.caching.5.0.0.nupkg.sha512", + "system.runtime.caching.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Runtime.CompilerServices.Unsafe/4.5.3": { + "sha512": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==", + "type": "package", + "path": "system.runtime.compilerservices.unsafe/4.5.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Runtime.CompilerServices.Unsafe.dll", + "lib/net461/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netstandard1.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netstandard1.0/System.Runtime.CompilerServices.Unsafe.xml", + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll", + "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/net461/System.Runtime.CompilerServices.Unsafe.dll", + "ref/net461/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard1.0/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard1.0/System.Runtime.CompilerServices.Unsafe.xml", + "ref/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll", + "ref/netstandard2.0/System.Runtime.CompilerServices.Unsafe.xml", + "system.runtime.compilerservices.unsafe.4.5.3.nupkg.sha512", + "system.runtime.compilerservices.unsafe.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.AccessControl/5.0.0": { + "sha512": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", + "type": "package", + "path": "system.security.accesscontrol/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/System.Security.AccessControl.dll", + "lib/net461/System.Security.AccessControl.dll", + "lib/net461/System.Security.AccessControl.xml", + "lib/netstandard1.3/System.Security.AccessControl.dll", + "lib/netstandard2.0/System.Security.AccessControl.dll", + "lib/netstandard2.0/System.Security.AccessControl.xml", + "lib/uap10.0.16299/_._", + "ref/net46/System.Security.AccessControl.dll", + "ref/net461/System.Security.AccessControl.dll", + "ref/net461/System.Security.AccessControl.xml", + "ref/netstandard1.3/System.Security.AccessControl.dll", + "ref/netstandard1.3/System.Security.AccessControl.xml", + "ref/netstandard1.3/de/System.Security.AccessControl.xml", + "ref/netstandard1.3/es/System.Security.AccessControl.xml", + "ref/netstandard1.3/fr/System.Security.AccessControl.xml", + "ref/netstandard1.3/it/System.Security.AccessControl.xml", + "ref/netstandard1.3/ja/System.Security.AccessControl.xml", + "ref/netstandard1.3/ko/System.Security.AccessControl.xml", + "ref/netstandard1.3/ru/System.Security.AccessControl.xml", + "ref/netstandard1.3/zh-hans/System.Security.AccessControl.xml", + "ref/netstandard1.3/zh-hant/System.Security.AccessControl.xml", + "ref/netstandard2.0/System.Security.AccessControl.dll", + "ref/netstandard2.0/System.Security.AccessControl.xml", + "ref/uap10.0.16299/_._", + "runtimes/win/lib/net46/System.Security.AccessControl.dll", + "runtimes/win/lib/net461/System.Security.AccessControl.dll", + "runtimes/win/lib/net461/System.Security.AccessControl.xml", + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.dll", + "runtimes/win/lib/netcoreapp2.0/System.Security.AccessControl.xml", + "runtimes/win/lib/netstandard1.3/System.Security.AccessControl.dll", + "runtimes/win/lib/uap10.0.16299/_._", + "system.security.accesscontrol.5.0.0.nupkg.sha512", + "system.security.accesscontrol.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.Cryptography.ProtectedData/5.0.0": { + "sha512": "HGxMSAFAPLNoxBvSfW08vHde0F9uh7BjASwu6JF9JnXuEPhCY3YUqURn0+bQV/4UWeaqymmrHWV+Aw9riQCtCA==", + "type": "package", + "path": "system.security.cryptography.protecteddata/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/MonoAndroid10/_._", + "lib/MonoTouch10/_._", + "lib/net46/System.Security.Cryptography.ProtectedData.dll", + "lib/net461/System.Security.Cryptography.ProtectedData.dll", + "lib/net461/System.Security.Cryptography.ProtectedData.xml", + "lib/netstandard1.3/System.Security.Cryptography.ProtectedData.dll", + "lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll", + "lib/netstandard2.0/System.Security.Cryptography.ProtectedData.xml", + "lib/xamarinios10/_._", + "lib/xamarinmac20/_._", + "lib/xamarintvos10/_._", + "lib/xamarinwatchos10/_._", + "ref/MonoAndroid10/_._", + "ref/MonoTouch10/_._", + "ref/net46/System.Security.Cryptography.ProtectedData.dll", + "ref/net461/System.Security.Cryptography.ProtectedData.dll", + "ref/net461/System.Security.Cryptography.ProtectedData.xml", + "ref/netstandard1.3/System.Security.Cryptography.ProtectedData.dll", + "ref/netstandard2.0/System.Security.Cryptography.ProtectedData.dll", + "ref/netstandard2.0/System.Security.Cryptography.ProtectedData.xml", + "ref/xamarinios10/_._", + "ref/xamarinmac20/_._", + "ref/xamarintvos10/_._", + "ref/xamarinwatchos10/_._", + "runtimes/win/lib/net46/System.Security.Cryptography.ProtectedData.dll", + "runtimes/win/lib/net461/System.Security.Cryptography.ProtectedData.dll", + "runtimes/win/lib/net461/System.Security.Cryptography.ProtectedData.xml", + "runtimes/win/lib/netstandard1.3/System.Security.Cryptography.ProtectedData.dll", + "runtimes/win/lib/netstandard2.0/System.Security.Cryptography.ProtectedData.dll", + "runtimes/win/lib/netstandard2.0/System.Security.Cryptography.ProtectedData.xml", + "system.security.cryptography.protecteddata.5.0.0.nupkg.sha512", + "system.security.cryptography.protecteddata.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.Permissions/5.0.0": { + "sha512": "uE8juAhEkp7KDBCdjDIE3H9R1HJuEHqeqX8nLX9gmYKWwsqk3T5qZlPx8qle5DPKimC/Fy3AFTdV7HamgCh9qQ==", + "type": "package", + "path": "system.security.permissions/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net461/System.Security.Permissions.dll", + "lib/net461/System.Security.Permissions.xml", + "lib/net5.0/System.Security.Permissions.dll", + "lib/net5.0/System.Security.Permissions.xml", + "lib/netcoreapp3.0/System.Security.Permissions.dll", + "lib/netcoreapp3.0/System.Security.Permissions.xml", + "lib/netstandard2.0/System.Security.Permissions.dll", + "lib/netstandard2.0/System.Security.Permissions.xml", + "ref/net461/System.Security.Permissions.dll", + "ref/net461/System.Security.Permissions.xml", + "ref/net5.0/System.Security.Permissions.dll", + "ref/net5.0/System.Security.Permissions.xml", + "ref/netcoreapp3.0/System.Security.Permissions.dll", + "ref/netcoreapp3.0/System.Security.Permissions.xml", + "ref/netstandard2.0/System.Security.Permissions.dll", + "ref/netstandard2.0/System.Security.Permissions.xml", + "system.security.permissions.5.0.0.nupkg.sha512", + "system.security.permissions.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + }, + "System.Security.Principal.Windows/5.0.0": { + "sha512": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==", + "type": "package", + "path": "system.security.principal.windows/5.0.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "Icon.png", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "lib/net46/System.Security.Principal.Windows.dll", + "lib/net461/System.Security.Principal.Windows.dll", + "lib/net461/System.Security.Principal.Windows.xml", + "lib/netstandard1.3/System.Security.Principal.Windows.dll", + "lib/netstandard2.0/System.Security.Principal.Windows.dll", + "lib/netstandard2.0/System.Security.Principal.Windows.xml", + "lib/uap10.0.16299/_._", + "ref/net46/System.Security.Principal.Windows.dll", + "ref/net461/System.Security.Principal.Windows.dll", + "ref/net461/System.Security.Principal.Windows.xml", + "ref/netcoreapp3.0/System.Security.Principal.Windows.dll", + "ref/netcoreapp3.0/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/System.Security.Principal.Windows.dll", + "ref/netstandard1.3/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/de/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/es/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/fr/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/it/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ja/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ko/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/ru/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/zh-hans/System.Security.Principal.Windows.xml", + "ref/netstandard1.3/zh-hant/System.Security.Principal.Windows.xml", + "ref/netstandard2.0/System.Security.Principal.Windows.dll", + "ref/netstandard2.0/System.Security.Principal.Windows.xml", + "ref/uap10.0.16299/_._", + "runtimes/unix/lib/netcoreapp2.0/System.Security.Principal.Windows.dll", + "runtimes/unix/lib/netcoreapp2.0/System.Security.Principal.Windows.xml", + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll", + "runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.xml", + "runtimes/win/lib/net46/System.Security.Principal.Windows.dll", + "runtimes/win/lib/net461/System.Security.Principal.Windows.dll", + "runtimes/win/lib/net461/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netcoreapp2.0/System.Security.Principal.Windows.dll", + "runtimes/win/lib/netcoreapp2.0/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.dll", + "runtimes/win/lib/netcoreapp2.1/System.Security.Principal.Windows.xml", + "runtimes/win/lib/netstandard1.3/System.Security.Principal.Windows.dll", + "runtimes/win/lib/uap10.0.16299/_._", + "system.security.principal.windows.5.0.0.nupkg.sha512", + "system.security.principal.windows.nuspec", + "useSharedDesignerContext.txt", + "version.txt" + ] + } + }, + "projectFileDependencyGroups": { + ".NETStandard,Version=v2.1": [ + "BinaryDad.Extensions >= 21.4.20.3", + "Newtonsoft.Json >= 13.0.1", + "System.Runtime.Caching >= 5.0.0" + ] + }, + "packageFolders": { + "C:\\Users\\rpeters\\.nuget\\packages\\": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "D:\\Git\\Salesforce.NET\\Salesforce.NET\\Salesforce.NET.csproj", + "projectName": "Salesforce.NET", + "projectPath": "D:\\Git\\Salesforce.NET\\Salesforce.NET\\Salesforce.NET.csproj", + "packagesPath": "C:\\Users\\rpeters\\.nuget\\packages\\", + "outputPath": "D:\\Git\\Salesforce.NET\\Salesforce.NET\\obj\\", + "projectStyle": "PackageReference", + "configFilePaths": [ + "C:\\Users\\rpeters\\AppData\\Roaming\\NuGet\\NuGet.Config", + "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + ], + "originalTargetFrameworks": [ + "netstandard2.1" + ], + "sources": { + "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, + "http://nuget/nuget": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "netstandard2.1": { + "targetAlias": "netstandard2.1", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "netstandard2.1": { + "targetAlias": "netstandard2.1", + "dependencies": { + "BinaryDad.Extensions": { + "target": "Package", + "version": "[21.4.20.3, )" + }, + "Newtonsoft.Json": { + "target": "Package", + "version": "[13.0.1, )" + }, + "System.Runtime.Caching": { + "target": "Package", + "version": "[5.0.0, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "NETStandard.Library": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\5.0.202\\RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/obj/project.nuget.cache b/obj/project.nuget.cache new file mode 100644 index 0000000..af659b6 --- /dev/null +++ b/obj/project.nuget.cache @@ -0,0 +1,22 @@ +{ + "version": 2, + "dgSpecHash": "/lUv+cPqzqvYWmPealOr6F/ozeSJMk50dUaMiaz8DRFtYYcODR3gG/No3o+0zhkhJG0pJa3eFsDkXjVd4lnjtg==", + "success": true, + "projectFilePath": "D:\\Git\\Salesforce.NET\\Salesforce.NET\\Salesforce.NET.csproj", + "expectedPackageFiles": [ + "C:\\Users\\rpeters\\.nuget\\packages\\binarydad.extensions\\21.4.20.3\\binarydad.extensions.21.4.20.3.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\newtonsoft.json\\13.0.1\\newtonsoft.json.13.0.1.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.buffers\\4.5.1\\system.buffers.4.5.1.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.componentmodel.annotations\\5.0.0\\system.componentmodel.annotations.5.0.0.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.configuration.configurationmanager\\5.0.0\\system.configuration.configurationmanager.5.0.0.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.memory\\4.5.4\\system.memory.4.5.4.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.numerics.vectors\\4.4.0\\system.numerics.vectors.4.4.0.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.runtime.caching\\5.0.0\\system.runtime.caching.5.0.0.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\4.5.3\\system.runtime.compilerservices.unsafe.4.5.3.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.security.accesscontrol\\5.0.0\\system.security.accesscontrol.5.0.0.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.security.cryptography.protecteddata\\5.0.0\\system.security.cryptography.protecteddata.5.0.0.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.security.permissions\\5.0.0\\system.security.permissions.5.0.0.nupkg.sha512", + "C:\\Users\\rpeters\\.nuget\\packages\\system.security.principal.windows\\5.0.0\\system.security.principal.windows.5.0.0.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file