diff --git a/Pipelines/bld.rel.CodeCore.ODataClient.yml b/Pipelines/bld.rel.CodeCore.ODataClient.yml index e0a0fd8..f3cb5c1 100644 --- a/Pipelines/bld.rel.CodeCore.ODataClient.yml +++ b/Pipelines/bld.rel.CodeCore.ODataClient.yml @@ -1,4 +1,4 @@ -name: rel.OBB.Backend-$(date:yyyyMMdd)$(rev:.rr) +name: rel.CodeCore.ODataClient-$(date:yyyyMMdd)$(rev:.rr) trigger: branches: @@ -38,7 +38,7 @@ steps: BuildVersion: $(GitVersion.SemVer) - task: DotNetCoreInstaller@2 - displayName: 'Use .NET Core sdk $(DotNetCoreSdkVersion)' + displayName: 'Use .NET Core sdk' inputs: version: 2.x includePreviewVersions: true @@ -46,7 +46,7 @@ steps: - task: NuGetToolInstaller@0 displayName: 'Use NuGet 4.x' inputs: - versionSpec: 4.x + versionSpec: 5.x checkLatest: true - task: NuGetCommand@2 @@ -65,6 +65,8 @@ steps: msbuildArchitecture: x64 - task: NuGetCommand@2 + displayName: 'NuGet pack' + condition: and(succeeded(), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/fix/'),startsWith(variables['Build.SourceBranch'], 'refs/heads/bug/'))) inputs: command: pack packagesToPack: '**/*.csproj' diff --git a/Source/CodeCore.Configuration/CodeCore.Configuration.csproj b/Source/CodeCore.Configuration/CodeCore.Configuration.csproj index 497d40c..e42e587 100644 --- a/Source/CodeCore.Configuration/CodeCore.Configuration.csproj +++ b/Source/CodeCore.Configuration/CodeCore.Configuration.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netstandard2.1 latest 0.1.0.0 0.1.0.0 @@ -14,7 +14,7 @@ - + diff --git a/Source/CodeCore.ODataClient.Abstract/CodeCore.ODataClient.Abstract.csproj b/Source/CodeCore.ODataClient.Abstract/CodeCore.ODataClient.Abstract.csproj index 018d73a..704a1db 100644 --- a/Source/CodeCore.ODataClient.Abstract/CodeCore.ODataClient.Abstract.csproj +++ b/Source/CodeCore.ODataClient.Abstract/CodeCore.ODataClient.Abstract.csproj @@ -1,13 +1,13 @@  - netstandard2.0 + netstandard2.1 latest - - + + diff --git a/Source/CodeCore.ODataClient.Abstract/ProxyGeneratorBase.cs b/Source/CodeCore.ODataClient.Abstract/ProxyGeneratorBase.cs index f1d14f3..b61506f 100644 --- a/Source/CodeCore.ODataClient.Abstract/ProxyGeneratorBase.cs +++ b/Source/CodeCore.ODataClient.Abstract/ProxyGeneratorBase.cs @@ -14,6 +14,7 @@ public abstract class ProxyGeneratorBase public void Initialize(string uri) { // Reset the generator + EdmModel = null; StringBuilder.Length = 0; diff --git a/Source/CodeCore.ODataClient.DotNet/CodeCore.ODataClient.DotNet.csproj b/Source/CodeCore.ODataClient.DotNet/CodeCore.ODataClient.DotNet.csproj new file mode 100644 index 0000000..f913d5a --- /dev/null +++ b/Source/CodeCore.ODataClient.DotNet/CodeCore.ODataClient.DotNet.csproj @@ -0,0 +1,27 @@ + + + + netcoreapp3.1 + latest + + Exe + + true + codecore.odataclient.dotnet + 0.0.0 + https://github.com/NetTecture/CodeCore.ODataClient + + + + + + + + + + + + + + + diff --git a/Source/CodeCore.ODataClient.DotNet/Program.cs b/Source/CodeCore.ODataClient.DotNet/Program.cs new file mode 100644 index 0000000..2a92054 --- /dev/null +++ b/Source/CodeCore.ODataClient.DotNet/Program.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using CodeCore.ODataClient.Abstract; + +namespace CodeCore.ODataClient.DotNet +{ + class Program + { + static void Main(string[] args) + { + ProgramAbstract.RealMain(args); + } + } +} diff --git a/Source/CodeCore.ODataClient.DotNet/ProxyGenerator.cs b/Source/CodeCore.ODataClient.DotNet/ProxyGenerator.cs new file mode 100644 index 0000000..7c84aa0 --- /dev/null +++ b/Source/CodeCore.ODataClient.DotNet/ProxyGenerator.cs @@ -0,0 +1,943 @@ +using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Xml; +using CodeCore.ODataClient.Abstract; +using Microsoft.OData.Edm; + +namespace CodeCore.ODataClient.DotNet +{ + class ProxyGenerator : ProxyGeneratorBase + { + + protected override void PrepareTarget(bool initialize) + { + if (initialize) + { + foreach (var file in Directory.EnumerateFiles(TargetPath)) + { + File.Delete(file); + } + } + + CompileUnit = new CodeCompileUnit(); + } + + protected CodeCompileUnit CompileUnit { get; set; } + + public override void Generate(string tsNamespace, string contextName) + { + var outputPath = Path.Combine(TargetPath, $"{tsNamespace}.cs"); + + GenerateHeaders(); + GenerateImportStatements(); + + //var prefix1 = ""; + //GenerateEnumerations(prefix1); + //GenerateComplexTypes(prefix1); + //GenerateEntityTypes(prefix1); + //GenerateActions(prefix1); + //GenerateFunctions(prefix1); + //GenerateEntitySets(prefix1); + //GenerateContainer(prefix1, contextName); + + CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); + CodeGeneratorOptions options = new CodeGeneratorOptions(); + options.BracingStyle = "C"; + using (StreamWriter sourceWriter = new StreamWriter(outputPath)) + { + provider.GenerateCodeFromCompileUnit(CompileUnit, sourceWriter, options); + CompileUnit = null; + } + } + + void GenerateHeaders() + { + var codeNamespace = new CodeNamespace("blabla"); + codeNamespace.Comments.Add(new CodeCommentStatement( + new CodeComment("This is generated code. Do not add properties. If bugs need fixing, inform the author of the") + )); + codeNamespace.Comments.Add(new CodeCommentStatement( + new CodeComment("code generator to fix the bugs also in the backend.") + )); + codeNamespace.Imports.Add(new CodeNamespaceImport("System")); + CompileUnit.Namespaces.Add(codeNamespace); + } + + void GenerateImportStatements() + { + this.StringBuilder.AppendLine($"import {{ Injectable }} from '@angular/core';"); + this.StringBuilder.AppendLine($"import {{ map }} from 'rxjs/operators';"); + this.StringBuilder.AppendLine($"import {{"); + this.StringBuilder.AppendLine($"\tODataLiteral, ODataType,"); + this.StringBuilder.AppendLine($"\tODataContext, ODataSettings, ODataEntitySet,"); + this.StringBuilder.AppendLine($"\tODataOperationSet, ODataActionOperation, ODataFunctionOperation, ODataFunctionSetOperation, ODataGetOperation,"); + this.StringBuilder.AppendLine($"\tODataQueryResult"); + this.StringBuilder.AppendLine($"}} from './odataclient';"); + } + + public void GenerateEnumerations(string prefix) + { + foreach (var group in EdmModel.SchemaElements.OrderBy(x => x.Name).OfType().GroupBy(x => x.Namespace)) + { + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}//Namespace: {group.Key}"); + this.StringBuilder.AppendLine($"{prefix}export namespace {group.Key} {{"); + + foreach (var item in group) + { + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\t//Enum: {item.Name}"); + this.StringBuilder.AppendLine($"{prefix}\texport enum {item.Name} {{"); + + var first = true; + foreach (var member in item.Members) + { + if (!first) + { + this.StringBuilder.AppendLine(","); + } + var name = member.Name; + var value = member.Value.Value; + this.StringBuilder.Append($"{prefix}\t\t{name} = \"{name}\""); + first = false; + } + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + } + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}}}"); + } + } + + public void GenerateComplexTypes(string prefix) + { + foreach (var group in EdmModel.SchemaElements.OrderBy(x => x.Name).OfType().GroupBy(x => x.Namespace)) + { + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}//Namespace: {group.Key}"); + this.StringBuilder.AppendLine($"{prefix}export namespace {group.Key} {{"); + this.StringBuilder.AppendLine(); + foreach (var item in group) + { + this.StringBuilder.AppendLine($"{prefix}\t//Complex Type: {item.Name}"); + this.StringBuilder.Append($"{prefix}\texport interface {item.Name} "); + var baseType = item.BaseComplexType(); + if (baseType != null) + { + var baseName = baseType.ShortQualifiedName(); + this.StringBuilder.Append($" extends {baseName}"); + } + this.StringBuilder.AppendLine($" {{"); + foreach (var property in item.DeclaredStructuralProperties()) + { + var name = property.Name; + var type = GetPropertyTypeName(property, group.Key); + if (type.Name == default) + { + // No support for this one + continue; + } + if (type.Optional) + { + name = name + "?"; + } + this.StringBuilder.AppendLine($"{prefix}\t\t{name}: {type.Name};"); + } + foreach (var property in item.DeclaredNavigationProperties()) + { + var name = property.Name; + var typeName = GetPropertyTypeName(property, group.Key); + this.StringBuilder.AppendLine($"{prefix}\t\t{name}?: {typeName};"); + } + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + } + this.StringBuilder.AppendLine($"{prefix}}}"); + } + this.StringBuilder.AppendLine(); + } + + public void GenerateEntityTypes (string prefix) + { + foreach (var group in EdmModel.SchemaElements.OrderBy(x=>x.Name).OfType().GroupBy(x => x.Namespace)) + { + + this.StringBuilder.AppendLine($"{prefix}//Namespace: {group.Key}"); + this.StringBuilder.AppendLine($"{prefix}export namespace {group.Key} {{"); + this.StringBuilder.AppendLine(); + foreach (var item in group) + { + this.StringBuilder.AppendLine($"{prefix}\t//Entity Type: {item.Name}"); + this.StringBuilder.Append($"{prefix}\texport interface {item.Name}"); + var baseType = item.BaseEntityType(); + if (baseType != null) + { + var baseName = baseType.ShortQualifiedName(); + this.StringBuilder.Append($" extends {baseName}"); + } + this.StringBuilder.AppendLine($" {{"); + foreach (var property in item.DeclaredStructuralProperties()) + { + var name = property.Name; + var type = GetPropertyTypeName(property, group.Key); + if (type.Name == default) + { + continue; + } + if (type.Optional) + { + name = name + "?"; + } + this.StringBuilder.AppendLine($"{prefix}\t\t{name}: {type.Name};"); + } + foreach (var property in item.DeclaredNavigationProperties()) + { + var name = property.Name; + var typeName = GetPropertyTypeName(property, group.Key); + this.StringBuilder.AppendLine($"{prefix}\t\t{name}?: {typeName};"); + } + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + } + this.StringBuilder.AppendLine($"{prefix}}}"); + this.StringBuilder.AppendLine(); + } + } + + void GenerateActions(string prefix) + { + foreach (var actionModel in EdmModel.SchemaElements.OrderBy(x => x.Name).OfType().Where(x=>x.IsAction())) + { + //if (actionModel.Name.StartsWith("Geo")) + //{ + // System.Diagnostics.Debugger.Break(); + //} + var name = $"{actionModel.Name}In{actionModel.Namespace}"; + var nameInUrl = $"{actionModel.Namespace}.{actionModel.Name}"; + if (actionModel.IsBound) + { + var bindingParameter = actionModel.Parameters.Where(x => x.Name == "bindingParameter").First(); + switch (bindingParameter.Type.Definition) + { + case IEdmEntityType bindingType: + { + name = $"{name}On{bindingType.Name}In{bindingType.Namespace}"; + } + break; + case IEdmCollectionType collectionType: + { + var elementType = collectionType.ElementType; + var bindingType = (IEdmEntityType)elementType.Definition; + + name = $"{name}On{bindingType.Name}In{bindingType.Namespace}OnEntitySet"; + } + break; + default: + break; + + } + } + this.StringBuilder.AppendLine($"{prefix}export class {name} extends ODataActionOperation {{"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, url: string) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, url + '/{nameInUrl}');"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\trequest: object = {{}};"); + this.StringBuilder.AppendLine(); + this.StringBuilder.Append($"{prefix}\tpublic Parameters("); + var first = false; + foreach (var bindingParameter in actionModel.Parameters.Where(x=>x.Name != "bindingParameter")) + { + if (first) + { + this.StringBuilder.Append(", "); + } else + { + first = true; + } + + this.StringBuilder.Append($"{bindingParameter.Name}"); + if (bindingParameter.Type.IsNullable) + { + this.StringBuilder.Append("?"); + } + this.StringBuilder.Append($": "); + this.StringBuilder.Append(GetEdmTypeRefereceString(bindingParameter.Type)); + } + this.StringBuilder.AppendLine($") {{"); + foreach (var bindingParameter in actionModel.Parameters.Where(x => x.Name != "bindingParameter")) + { + if (bindingParameter.Type.IsNullable) + { + this.StringBuilder.AppendLine($"{prefix}\t\tif ({bindingParameter.Name}) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\t\tthis.request['{bindingParameter.Name}'] = {bindingParameter.Name};"); + this.StringBuilder.AppendLine($"{prefix}\t\t}}"); + } else { + this.StringBuilder.AppendLine($"{prefix}\t\tthis.request['{bindingParameter.Name}'] = {bindingParameter.Name};"); + } + } + this.StringBuilder.AppendLine($"{prefix}\t\treturn this;"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + this.StringBuilder.Append($"{prefix}\tpublic async Execute() "); + if (actionModel.ReturnType != null) + { + this.StringBuilder.Append($" : Promise<{GetEdmTypeRefereceString(actionModel.ReturnType)}>"); + } + this.StringBuilder.AppendLine($"{{"); + this.StringBuilder.AppendLine($"{prefix}\t\tlet subscription = this.settings.http.post(this.getBaseUrl(), JSON.stringify(this.request), {{"); + this.StringBuilder.AppendLine($"{prefix}\t\t\twithCredentials: false,"); + this.StringBuilder.AppendLine($"{prefix}\t\t\theaders: this.settings.headers,"); + if (actionModel.ReturnType != null) + { + this.StringBuilder.AppendLine($"{prefix}\t\t}}).pipe(map(a => {{"); + this.StringBuilder.Append($"{prefix}\t\t\treturn"); + this.StringBuilder.Append($" a as {GetEdmTypeRefereceString(actionModel.ReturnType)}"); + this.StringBuilder.AppendLine($";"); + this.StringBuilder.AppendLine($"{prefix}\t\t}}));"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn subscription.toPromise();"); + } else + { + this.StringBuilder.AppendLine($"{prefix}\t\t}});"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn subscription.toPromise();"); + } + + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + } + } + + void GenerateFunctions(string prefix) + { + foreach (var actionModel in EdmModel.SchemaElements.OrderBy(x => x.Name).OfType().Where(x => x.IsFunction())) + { + var name = $"{actionModel.Name}In{actionModel.Namespace}"; + var nameInUrl = $"{actionModel.Namespace}.{actionModel.Name}"; + if (actionModel.IsBound) + { + var bindingParameter = actionModel.Parameters.Where(x => x.Name == "bindingParameter").First(); + switch (bindingParameter.Type.Definition) + { + case IEdmEntityType bindingType: + { + name = $"{name}On{bindingType.Name}In{bindingType.Namespace}"; + } + break; + case IEdmCollectionType collectionType: + { + var elementType = collectionType.ElementType; + var bindingType = (IEdmEntityType)elementType.Definition; + + name = $"{name}On{bindingType.Name}In{bindingType.Namespace}OnEntitySet"; + } + break; + default: + break; + } + + } + switch (actionModel.ReturnType.Definition.TypeKind) + { + case EdmTypeKind.Collection: + var am = actionModel.ReturnType.Definition; + var rt = am.AsElementType(); + var collectionReturnType = rt.FullTypeName(); + this.StringBuilder.AppendLine($"{prefix}export class {name} extends ODataFunctionSetOperation<{collectionReturnType}> {{"); + break; + default: + this.StringBuilder.AppendLine($"{prefix}export class {name} extends ODataFunctionOperation {{"); + break; + } + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, url: string) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, url + '/{nameInUrl}');"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + this.StringBuilder.Append($"{prefix}\tpublic Parameters("); + var first = false; + foreach (var bindingParameter in actionModel.Parameters.Where(x => x.Name != "bindingParameter")) + { + if (first) + { + this.StringBuilder.Append(", "); + } + else + { + first = true; + } + + this.StringBuilder.Append($"{bindingParameter.Name}"); + if (bindingParameter.Type.IsNullable) + { + this.StringBuilder.Append("?"); + } + this.StringBuilder.Append($": "); + this.StringBuilder.Append(GetEdmTypeRefereceString(bindingParameter.Type)); + } + this.StringBuilder.AppendLine($") {{"); + // build the parameters string from the parameters + first = true; + foreach (var bindingParameter in actionModel.Parameters.Where(x => x.Name != "bindingParameter")) + { + if (first) + { + first = false; + } + else + { + this.StringBuilder.AppendLine($"{prefix}\t\tthis.parameters += ','"); + } + this.StringBuilder.AppendLine($"{prefix}\t\tthis.parameters += '{bindingParameter.Name}=' + ODataLiteral.For({bindingParameter.Name}).toUrlString();"); + } + this.StringBuilder.AppendLine($"{prefix}\t\treturn this;"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + this.StringBuilder.Append($"{prefix}\tpublic async Execute()"); + if (actionModel.ReturnType != null) + { + this.StringBuilder.Append(": Promise<"); + switch (actionModel.ReturnType.Definition.TypeKind) + { + case EdmTypeKind.Collection: + var am = actionModel.ReturnType.Definition; + var rt = am.AsElementType(); + var collectionReturnType = rt.FullTypeName(); + this.StringBuilder.Append($"ODataQueryResult<{collectionReturnType}>"); + break; + default: + this.StringBuilder.Append(GetEdmTypeRefereceString(actionModel.ReturnType)); + break; + } + this.StringBuilder.Append(">"); + } + this.StringBuilder.AppendLine($" {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tvar url = this.getBaseUrl();"); + this.StringBuilder.AppendLine($"{prefix}\t\tlet subscription = this.settings.http.get(url, {{"); + this.StringBuilder.AppendLine($"{prefix}\t\t\twithCredentials: false,"); + this.StringBuilder.AppendLine($"{prefix}\t\t\theaders: this.settings.headers,"); + this.StringBuilder.AppendLine($"{prefix}\t\t}}).pipe(map(a => {{"); + this.StringBuilder.Append($"{prefix}\t\t\treturn a as "); + switch (actionModel.ReturnType.Definition.TypeKind) + { + case EdmTypeKind.Collection: + var am = actionModel.ReturnType.Definition; + var rt = am.AsElementType(); + var collectionReturnType = rt.FullTypeName(); + this.StringBuilder.Append($"ODataQueryResult<{collectionReturnType}>"); + break; + default: + this.StringBuilder.Append(GetEdmTypeRefereceString(actionModel.ReturnType)); + break; + } + this.StringBuilder.AppendLine($";"); + this.StringBuilder.AppendLine($"{prefix}\t\t}}));"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn subscription.toPromise();"); + //if (actionModel.ReturnType == null) + //{ + // this.StringBuilder.AppendLine($"{prefix}\t\treturn;"); + //} + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + } + } + + void GenerateEntitySets(string prefix) + { + + foreach (var set in EdmModel.EntityContainer.Elements.OfType()) + { + var name = set.Name; + var key = (IEdmStructuralProperty)set.EntityType().Key().First(); + var keyName = key.Name; + + // Entity Actions container class + + this.StringBuilder.AppendLine($"{prefix}export class {name}EntityActions extends ODataOperationSet {{"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, baseUrl: string) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, baseUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + FillActions(set.EntityType(), prefix + "\t"); + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + + // Entity Functions container class + + this.StringBuilder.AppendLine($"{prefix}export class {name}EntityFunctions extends ODataOperationSet {{"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, baseUrl: string) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, baseUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + FillFunctions(set.EntityType(), prefix + "\t"); + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + + // EntitySet Actions container class + + this.StringBuilder.AppendLine($"{prefix}export class {name}EntitySetActions extends ODataOperationSet {{"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, baseUrl: string) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, baseUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + FillActions(set, prefix + "\t"); + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + + // EntitySet Functions container class + + this.StringBuilder.AppendLine($"{prefix}export class {name}EntitySetFunctions extends ODataOperationSet {{"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, baseUrl: string) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, baseUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + FillFunctions(set, prefix + "\t"); + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + + // EntityGet implementation + + this.StringBuilder.AppendLine($"{prefix}export class {name}EntityGetOperation extends ODataGetOperation<{key.DeclaringType.FullTypeName()}> {{"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, url: string) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, url);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + // actions + this.StringBuilder.AppendLine($"{prefix}\tpublic Actions() {{"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntityActions(this.settings, this.buildQueryUrl());"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + // functions + this.StringBuilder.AppendLine($"{prefix}\tpublic Functions() {{"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntityFunctions(this.settings, this.buildQueryUrl());"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + + // EntitySet + + this.StringBuilder.AppendLine($"{prefix}export class {name}EntitySet extends ODataEntitySet<{key.DeclaringType.FullTypeName()}> {{"); + this.StringBuilder.AppendLine(); + // constructor + this.StringBuilder.AppendLine($"{prefix}\tconstructor(odatasettings: ODataSettings) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(odatasettings, \"{name}\");"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + // get + this.StringBuilder.AppendLine($"{prefix}\tGet(): {name}EntityGetOperation {{"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntityGetOperation(this.settings, this.definedname);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + // actions + this.StringBuilder.AppendLine($"{prefix}\tpublic Actions() {{"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntitySetActions(this.settings, this.definedname);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + // functions + this.StringBuilder.AppendLine($"{prefix}\tpublic Functions() {{"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntitySetFunctions(this.settings, this.definedname);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + } + + } + + void FillActions(IEdmEntitySet entitySetType, string prefix) + { + var refType = entitySetType.EntityType(); + foreach (var actionModel in EdmModel.SchemaElements.OfType() + .Where(x => x.IsAction() && x.IsBound) + ) + { + var bindingParameter = actionModel.Parameters.Where(x => x.Name == "bindingParameter").First(); + var bindingTypeDefinition = bindingParameter.Type.Definition as IEdmCollectionType; + if (bindingTypeDefinition == null) + { + continue; + } + if (bindingTypeDefinition.TypeKind != EdmTypeKind.Collection) + { + continue; + } + var entityType = bindingTypeDefinition.ElementType.Definition; + if (refType != entityType) + { + continue; + } + FillAction(actionModel, prefix, $"{refType.Name}In{refType.Namespace}OnEntitySet"); + } + } + + void FillFunctions(IEdmEntitySet entitySetType, string prefix) + { + var refType = entitySetType.EntityType(); + foreach (var functionModel in EdmModel.SchemaElements.OfType() + .Where(x => x.IsFunction() && x.IsBound) + ) + { + var bindingParameter = functionModel.Parameters.Where(x => x.Name == "bindingParameter").First(); + var bindingTypeDefinition = bindingParameter.Type.Definition as IEdmCollectionType; + if (bindingTypeDefinition == null) + { + continue; + } + if (bindingTypeDefinition.TypeKind != EdmTypeKind.Collection) + { + continue; + } + var entityType = bindingTypeDefinition.ElementType.Definition; + if (refType != entityType) + { + continue; + } + FillFunction(functionModel, prefix, $"{refType.Name}In{refType.Namespace}OnEntitySet"); + } + } + + void FillActions(IEdmEntityType entityType, string prefix) + { + foreach (var actionModel in EdmModel.SchemaElements.OfType() + .Where(x => x.IsAction() && x.IsBound) + ) { + var bindingParameter = actionModel.Parameters.Where(x => x.Name == "bindingParameter").First(); + var bindingTypeDefinition = bindingParameter.Type.Definition as IEdmEntityType; + if (bindingTypeDefinition != entityType) + { + continue; + } + FillAction(actionModel, prefix, $"{entityType.Name}In{entityType.Namespace}"); + } + } + + void FillFunctions(IEdmEntityType entityType, string prefix) + { + foreach (var functionModel in EdmModel.SchemaElements.OfType() + .Where(x => x.IsFunction() && x.IsBound) + ) { + var bindingParameter = functionModel.Parameters.Where(x => x.Name == "bindingParameter").First(); + var bindingTypeDefinition = bindingParameter.Type.Definition as IEdmEntityType; + if (bindingTypeDefinition != entityType) + { + continue; + } + FillFunction(functionModel, prefix, $"{entityType.Name}In{entityType.Namespace}"); + } + } + + void FillActions(string prefix) + { + foreach (var actionModel in EdmModel.SchemaElements.OfType() + //.Select(x=>x.Action) + .Where(x => x.IsAction() && !x.IsBound) + ) + { + FillAction(actionModel, prefix); + } + } + + void FillFunctions(string prefix) + { + foreach (var functionModel in EdmModel.SchemaElements.OfType() + //.Select(x => x.Function) + .Where(x => x.IsFunction() && !x.IsBound) + ) + { + FillFunction(functionModel, prefix); + } + } + + void FillAction(IEdmAction actionType, string prefix, string nameSuffix = null) + { + var name = $"{actionType.Name }In{ actionType.Namespace}"; + if (nameSuffix != null) + { + name = $"{name}On{nameSuffix}"; + } + + this.StringBuilder.AppendLine($"{prefix}public {name}() {{"); + this.StringBuilder.AppendLine($"{prefix}\treturn new {name}(this.settings, this.baseUrl)"); + this.StringBuilder.AppendLine($"{prefix}}}"); + this.StringBuilder.AppendLine(); + } + + void FillFunction (IEdmFunction functionType, string prefix, string nameSuffix = null) + { + var name = $"{functionType.Name }In{ functionType.Namespace}"; + if (nameSuffix != null) + { + name = $"{name}On{nameSuffix}"; + } + + this.StringBuilder.AppendLine($"{prefix}public {name}() {{"); + this.StringBuilder.AppendLine($"{prefix}\treturn new {name}(this.settings, this.baseUrl)"); + this.StringBuilder.AppendLine($"{prefix}}}"); + this.StringBuilder.AppendLine(); + } + + void GenerateContainer(string prefix, string contextName) + { + + // Types container + this.StringBuilder.AppendLine($"{prefix}export class {contextName}ODataTypes {{"); + this.StringBuilder.AppendLine(); + foreach (var element in EdmModel.SchemaElements.OfType().OrderBy(x=>x.Name)) { + this.StringBuilder.AppendLine($"{prefix}\tpublic {element.Name}() {{"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn ODataType.For('{element.Name}','{element.Namespace}')"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + } + this.StringBuilder.AppendLine($"{prefix}}}"); + this.StringBuilder.AppendLine(); + + // Entity Actions container class + + this.StringBuilder.AppendLine($"{prefix}export class {contextName}ContainerActions extends ODataOperationSet {{"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, baseUrl: string) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, baseUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + FillActions(prefix + "\t"); + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + + // Entity Functions container class + + this.StringBuilder.AppendLine($"{prefix}export class {contextName}ContainerFunctions extends ODataOperationSet {{"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, baseUrl: string) {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, baseUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + FillFunctions(prefix + "\t"); + this.StringBuilder.AppendLine($"}}"); + this.StringBuilder.AppendLine(); + + this.StringBuilder.AppendLine($"@Injectable()"); + this.StringBuilder.AppendLine($"{prefix}export class {contextName} extends ODataContext {{"); + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}\tconstructor() {{"); + this.StringBuilder.AppendLine($"{prefix}\t\tsuper();"); + this.StringBuilder.AppendLine(); + + // Container + foreach (var set in EdmModel.EntityContainer.Elements.OfType().OrderBy(x => x.Name)) + { + var name = set.Name; + var key = (IEdmStructuralProperty) set.EntityType().Key().First(); + var keyName = key.Name; + + this.StringBuilder.AppendLine($"{prefix}\t\tthis.{name} = new {name}EntitySet(this.ODataSettings);"); + } + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + + // types + + this.StringBuilder.AppendLine($"{prefix}\tpublic ODataTypes() {{"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {contextName}ODataTypes();"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + + // actions + + this.StringBuilder.AppendLine($"{prefix}\tpublic Actions() {{"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {contextName}ContainerActions(this.ODataSettings, '');"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + // functions + + this.StringBuilder.AppendLine($"{prefix}\tpublic Functions() {{"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {contextName}ContainerFunctions(this.ODataSettings, '');"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); + this.StringBuilder.AppendLine(); + + // Container variables + + this.StringBuilder.AppendLine($"{prefix}\t// Entity Set Variables"); + foreach (var set in EdmModel.EntityContainer.Elements.OfType().OrderBy(x => x.Name)) + { + var name = set.Name; + //this.StringBuilder.AppendLine($"{prefix}\t{name}: ODataEntitySet<{set.EntityType().FullName()}>;"); + this.StringBuilder.AppendLine($"{prefix}\t{name}: {name}EntitySet;"); + } + this.StringBuilder.AppendLine(); + this.StringBuilder.AppendLine($"{prefix}}}"); + } + + (string Name, bool Optional) GetPropertyTypeName (IEdmStructuralProperty property, string forNamespace) + { + var retval = String.Empty; + var optional = false; + + switch (property.Type.Definition) + { + case IEdmCollectionType ct: + { + switch (ct.ElementType) + { + case IEdmPrimitiveType inner: + { + retval = GetPropertyEdmPrimtiveTypeString(inner.PrimitiveKind) + "[]"; + } + break; + case IEdmPrimitiveTypeReference inner: + { + retval = GetPropertyEdmPrimtiveTypeString(inner.PrimitiveKind()) + "[]"; + } + break; + case IEdmTypeReference inner: + { + retval = inner.AsTypeDefinition().FullName(); + if (retval.StartsWith("Edm.")) { System.Diagnostics.Debugger.Break(); } + optional = true; + } + break; + default: + { + throw new NotImplementedException("Not prepared for property of this kind."); + } + } + } + break; + case IEdmEnumType et: + { + retval = et.FullTypeName(); + } + break; + case IEdmComplexType ct: + { + retval = ct.FullTypeName(); + } + break; + case IEdmPrimitiveType pt: + { + retval = GetPropertyEdmPrimtiveTypeString(pt.PrimitiveKind); + } + break; + default: + { + throw new NotImplementedException("Not prepared for property of this kind."); + } + } + if (retval.StartsWith("Microsoft.OData.Edm.Csdl")) + { + System.Diagnostics.Debugger.Break(); + } + if (retval == default) + { + return (null, false); + } + if (retval.StartsWith(forNamespace + ".", StringComparison.InvariantCultureIgnoreCase)) + { + retval = retval.Substring(forNamespace.Length + 1); + } + return (retval, optional); + } + + private string GetPropertyEdmPrimtiveTypeString(EdmPrimitiveTypeKind typeKind) + { + switch (typeKind) + { + case EdmPrimitiveTypeKind.Binary: + return "string"; + case EdmPrimitiveTypeKind.Boolean: + return "boolean"; + case EdmPrimitiveTypeKind.Byte: + return "number"; + case EdmPrimitiveTypeKind.Date: + case EdmPrimitiveTypeKind.DateTimeOffset: + return "Date"; + case EdmPrimitiveTypeKind.Decimal: + case EdmPrimitiveTypeKind.Double: + return "number"; + case EdmPrimitiveTypeKind.Duration: + return "string"; + //case EdmPrimitiveTypeKind.Geography: + //case EdmPrimitiveTypeKind.GeographyCollection: + //case EdmPrimitiveTypeKind.GeographyLineString: + //case EdmPrimitiveTypeKind.GeographyMultiLineString: + //case EdmPrimitiveTypeKind.GeographyMultiPoint: + //case EdmPrimitiveTypeKind.GeographyMultiPolygon: + //case EdmPrimitiveTypeKind.GeographyPoint: + //case EdmPrimitiveTypeKind.GeographyPolygon: + // break; + case EdmPrimitiveTypeKind.Guid: + return "string"; + case EdmPrimitiveTypeKind.Int16: + case EdmPrimitiveTypeKind.Int32: + case EdmPrimitiveTypeKind.Int64: + return "number"; + case EdmPrimitiveTypeKind.None: + return default; + //case EdmPrimitiveTypeKind.PrimitiveType: + // break; + case EdmPrimitiveTypeKind.SByte: + case EdmPrimitiveTypeKind.Single: + return "number"; + //case EdmPrimitiveTypeKind.Stream: + // break; + case EdmPrimitiveTypeKind.String: + return "string"; + case EdmPrimitiveTypeKind.TimeOfDay: + return "string"; + } + // Seems our switch statement is not complete. + throw new NotImplementedException($"Please add handling for EdmKind {typeKind}"); + } + + private string GetEdmTypeRefereceString(IEdmTypeReference typeReference) + { + switch (typeReference) + { + case IEdmCollectionTypeReference ctr: + var elementType = (IEdmTypeReference) ctr.ElementType(); + return GetEdmTypeRefereceString(elementType) + " []"; + case IEdmPrimitiveTypeReference ptr: + return GetPropertyEdmPrimtiveTypeString(ptr.PrimitiveKind()); + case IEdmTypeReference tr: + return tr.Definition.FullTypeName(); + } + throw new NotImplementedException($"Please add handling for EdmTypeReference {typeReference}"); + } + + string GetPropertyTypeName(IEdmNavigationProperty property, string forNamespace) + { + var retval = String.Empty; + switch (property.Type) + { + case EdmCollectionTypeReference ctr: + retval = ctr.ElementType().ShortQualifiedName() + "[]"; + break; + case EdmTypeReference tr: + retval = tr.ShortQualifiedName().ToString(); + break; + } + if (retval.StartsWith(forNamespace + ".", StringComparison.InvariantCultureIgnoreCase)) + { + retval = retval.Substring(forNamespace.Length + 1); + } + return retval; + } + + } +} diff --git a/Source/CodeCore.ODataClient.TypeScript/CodeCore.ODataClient.TypeScript.csproj b/Source/CodeCore.ODataClient.TypeScript/CodeCore.ODataClient.TypeScript.csproj index 6d54e88..5efe76b 100644 --- a/Source/CodeCore.ODataClient.TypeScript/CodeCore.ODataClient.TypeScript.csproj +++ b/Source/CodeCore.ODataClient.TypeScript/CodeCore.ODataClient.TypeScript.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2 + netcoreapp3.1 latest Exe @@ -23,8 +23,8 @@ - - + + diff --git a/Source/CodeCore.ODataClient.TypeScript/ProxyGenerator.cs b/Source/CodeCore.ODataClient.TypeScript/ProxyGenerator.cs index 92dc05a..5f5bc94 100644 --- a/Source/CodeCore.ODataClient.TypeScript/ProxyGenerator.cs +++ b/Source/CodeCore.ODataClient.TypeScript/ProxyGenerator.cs @@ -78,12 +78,11 @@ void GenerateHeaders() void GenerateImportStatements() { this.StringBuilder.AppendLine($"import {{ Injectable }} from '@angular/core';"); - this.StringBuilder.AppendLine($"import {{ map }} from 'rxjs/operators';"); this.StringBuilder.AppendLine($"import {{"); this.StringBuilder.AppendLine($"\tODataLiteral, ODataType,"); this.StringBuilder.AppendLine($"\tODataContext, ODataSettings, ODataEntitySet,"); this.StringBuilder.AppendLine($"\tODataOperationSet, ODataActionOperation, ODataFunctionOperation, ODataFunctionSetOperation, ODataGetOperation,"); - this.StringBuilder.AppendLine($"\tODataQueryResult"); + this.StringBuilder.AppendLine($"\tODataQueryResult, ODataScalarResult"); this.StringBuilder.AppendLine($"}} from './odataclient';"); } @@ -220,10 +219,6 @@ void GenerateActions(string prefix) { foreach (var actionModel in EdmModel.SchemaElements.OrderBy(x => x.Name).OfType().Where(x=>x.IsAction())) { - //if (actionModel.Name.StartsWith("Geo")) - //{ - // System.Diagnostics.Debugger.Break(); - //} var name = $"{actionModel.Name}In{actionModel.Namespace}"; var nameInUrl = $"{actionModel.Namespace}.{actionModel.Name}"; if (actionModel.IsBound) @@ -252,7 +247,13 @@ void GenerateActions(string prefix) this.StringBuilder.AppendLine($"{prefix}export class {name} extends ODataActionOperation {{"); this.StringBuilder.AppendLine(); this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, url: string) {{"); - this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, url + '/{nameInUrl}');"); + if (actionModel.IsBound) + { + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, url + '/{nameInUrl}');"); + } else + { + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, url + '{nameInUrl}');"); + } this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); this.StringBuilder.AppendLine($"{prefix}\trequest: object = {{}};"); @@ -292,29 +293,27 @@ void GenerateActions(string prefix) this.StringBuilder.AppendLine($"{prefix}\t\treturn this;"); this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); - this.StringBuilder.Append($"{prefix}\tpublic async Execute() "); + this.StringBuilder.Append($"{prefix}\tpublic Execute()"); if (actionModel.ReturnType != null) { - this.StringBuilder.Append($" : Promise<{GetEdmTypeRefereceString(actionModel.ReturnType)}>"); + this.StringBuilder.AppendLine($" : Promise<{GetEdmTypeRefereceString(actionModel.ReturnType)}> {{"); + } else + { + this.StringBuilder.AppendLine($" : Promise {{"); } - this.StringBuilder.AppendLine($"{{"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet subscription = this.settings.http.post(this.baseUrl, JSON.stringify(this.request), {{"); - this.StringBuilder.AppendLine($"{prefix}\t\t\twithCredentials: false,"); - this.StringBuilder.AppendLine($"{prefix}\t\t\theaders: this.settings.headers,"); if (actionModel.ReturnType != null) { - this.StringBuilder.AppendLine($"{prefix}\t\t}}).pipe(map(a => {{"); - this.StringBuilder.Append($"{prefix}\t\t\treturn"); - this.StringBuilder.Append($" a as {GetEdmTypeRefereceString(actionModel.ReturnType)}"); - this.StringBuilder.AppendLine($";"); - this.StringBuilder.AppendLine($"{prefix}\t\t}}));"); - this.StringBuilder.AppendLine($"{prefix}\t\treturn subscription.toPromise();"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn this.settings.http.post<{GetEdmTypeRefereceString(actionModel.ReturnType)}>(this.getBaseUrl(), JSON.stringify(this.request),"); } else { - this.StringBuilder.AppendLine($"{prefix}\t\t}});"); - this.StringBuilder.AppendLine($"{prefix}\t\treturn subscription.toPromise();"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn this.settings.http.post(this.getBaseUrl(), JSON.stringify(this.request),"); } - + this.StringBuilder.AppendLine($"{prefix}\t\t{{"); + this.StringBuilder.AppendLine($"{prefix}\t\t\twithCredentials: false,"); + this.StringBuilder.AppendLine($"{prefix}\t\t\theaders: this.settings.headers,"); + this.StringBuilder.AppendLine($"{prefix}\t\t}})"); + this.StringBuilder.AppendLine($"{prefix}\t\t.toPromise();"); + this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); this.StringBuilder.AppendLine($"}}"); @@ -326,6 +325,10 @@ void GenerateFunctions(string prefix) { foreach (var actionModel in EdmModel.SchemaElements.OrderBy(x => x.Name).OfType().Where(x => x.IsFunction())) { + //if (actionModel.Name.Contains("EncodeValue")) { + // System.Diagnostics.Debugger.Break(); + //} + var name = $"{actionModel.Name}In{actionModel.Namespace}"; var nameInUrl = $"{actionModel.Namespace}.{actionModel.Name}"; if (actionModel.IsBound) @@ -365,7 +368,13 @@ void GenerateFunctions(string prefix) } this.StringBuilder.AppendLine(); this.StringBuilder.AppendLine($"{prefix}\tconstructor(settings: ODataSettings, url: string) {{"); - this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, url + '/{nameInUrl}');"); + if (actionModel.IsBound) + { + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, url + '/{nameInUrl}');"); + } else + { + this.StringBuilder.AppendLine($"{prefix}\t\tsuper(settings, url + '{nameInUrl}');"); + } this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); this.StringBuilder.Append($"{prefix}\tpublic Parameters("); @@ -407,10 +416,11 @@ void GenerateFunctions(string prefix) this.StringBuilder.AppendLine($"{prefix}\t\treturn this;"); this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); - this.StringBuilder.Append($"{prefix}\tpublic async Execute()"); + this.StringBuilder.Append($"{prefix}\tpublic Execute()"); + this.StringBuilder.Append(": Promise<"); if (actionModel.ReturnType != null) { - this.StringBuilder.Append(": Promise<"); + switch (actionModel.ReturnType.Definition.TypeKind) { case EdmTypeKind.Collection: @@ -423,15 +433,14 @@ void GenerateFunctions(string prefix) this.StringBuilder.Append(GetEdmTypeRefereceString(actionModel.ReturnType)); break; } - this.StringBuilder.Append(">"); + + } else + { + StringBuilder.Append("any"); } - this.StringBuilder.AppendLine($" {{"); + this.StringBuilder.AppendLine($"> {{"); this.StringBuilder.AppendLine($"{prefix}\t\tvar url = this.getBaseUrl();"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet subscription = this.settings.http.get(url, {{"); - this.StringBuilder.AppendLine($"{prefix}\t\t\twithCredentials: false,"); - this.StringBuilder.AppendLine($"{prefix}\t\t\theaders: this.settings.headers,"); - this.StringBuilder.AppendLine($"{prefix}\t\t}}).pipe(map(a => {{"); - this.StringBuilder.Append($"{prefix}\t\t\treturn a as "); + this.StringBuilder.Append($"{prefix}\t\treturn this.settings.http.get<"); switch (actionModel.ReturnType.Definition.TypeKind) { case EdmTypeKind.Collection: @@ -444,9 +453,14 @@ void GenerateFunctions(string prefix) this.StringBuilder.Append(GetEdmTypeRefereceString(actionModel.ReturnType)); break; } - this.StringBuilder.AppendLine($";"); - this.StringBuilder.AppendLine($"{prefix}\t\t}}));"); - this.StringBuilder.AppendLine($"{prefix}\t\treturn subscription.toPromise();"); + this.StringBuilder.AppendLine($">(url,"); + this.StringBuilder.AppendLine($"{prefix}\t\t{{"); + + this.StringBuilder.AppendLine($"{prefix}\t\t\twithCredentials: false,"); + this.StringBuilder.AppendLine($"{prefix}\t\t\theaders: this.settings.headers,"); + this.StringBuilder.AppendLine($"{prefix}\t\t}})"); + this.StringBuilder.AppendLine($"{prefix}\t\t.toPromise();"); + //if (actionModel.ReturnType == null) //{ // this.StringBuilder.AppendLine($"{prefix}\t\treturn;"); @@ -548,23 +562,17 @@ void GenerateEntitySets(string prefix) this.StringBuilder.AppendLine(); // get this.StringBuilder.AppendLine($"{prefix}\tGet(): {name}EntityGetOperation {{"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet entitySetUrl = this.settings.Url + this.definedname;"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet settings = this.settings;"); - this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntityGetOperation(settings, entitySetUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntityGetOperation(this.settings, this.definedname);"); this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); // actions this.StringBuilder.AppendLine($"{prefix}\tpublic Actions() {{"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet entitySetUrl = this.settings.Url + this.definedname;"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet settings = this.settings;"); - this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntitySetActions(settings, entitySetUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntitySetActions(this.settings, this.definedname);"); this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); // functions this.StringBuilder.AppendLine($"{prefix}\tpublic Functions() {{"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet entitySetUrl = this.settings.Url + this.definedname;"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet settings = this.settings;"); - this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntitySetFunctions(settings, entitySetUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {name}EntitySetFunctions(this.settings, this.definedname);"); this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); @@ -774,17 +782,13 @@ void GenerateContainer(string prefix, string contextName) // actions this.StringBuilder.AppendLine($"{prefix}\tpublic Actions() {{"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet entitySetUrl = this.ODataSettings.Url;"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet settings = this.ODataSettings;"); - this.StringBuilder.AppendLine($"{prefix}\t\treturn new {contextName}ContainerActions(settings, entitySetUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {contextName}ContainerActions(this.ODataSettings, '');"); this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); // functions this.StringBuilder.AppendLine($"{prefix}\tpublic Functions() {{"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet entitySetUrl = this.ODataSettings.Url;"); - this.StringBuilder.AppendLine($"{prefix}\t\tlet settings = this.ODataSettings;"); - this.StringBuilder.AppendLine($"{prefix}\t\treturn new {contextName}ContainerFunctions(settings, entitySetUrl);"); + this.StringBuilder.AppendLine($"{prefix}\t\treturn new {contextName}ContainerFunctions(this.ODataSettings, '');"); this.StringBuilder.AppendLine($"{prefix}\t}}"); this.StringBuilder.AppendLine(); @@ -803,9 +807,9 @@ void GenerateContainer(string prefix, string contextName) (string Name, bool Optional) GetPropertyTypeName (IEdmStructuralProperty property, string forNamespace) { - var retval = String.Empty; var optional = false; + string retval; switch (property.Type.Definition) { case IEdmCollectionType ct: @@ -825,6 +829,9 @@ void GenerateContainer(string prefix, string contextName) case IEdmTypeReference inner: { retval = inner.AsTypeDefinition().FullName(); + if (ct.TypeKind == EdmTypeKind.Collection) { + retval = retval + "[]"; + } if (retval.StartsWith("Edm.")) { System.Diagnostics.Debugger.Break(); } optional = true; } @@ -833,7 +840,7 @@ void GenerateContainer(string prefix, string contextName) { throw new NotImplementedException("Not prepared for property of this kind."); } - } + } } break; case IEdmEnumType et: diff --git a/Source/CodeCore.ODataClient.sln b/Source/CodeCore.ODataClient.sln index 04a0829..77b3ab2 100644 --- a/Source/CodeCore.ODataClient.sln +++ b/Source/CodeCore.ODataClient.sln @@ -14,6 +14,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution CodeCore.ODataClient.vsext = CodeCore.ODataClient.vsext EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCore.ODataClient.DotNet", "CodeCore.ODataClient.DotNet\CodeCore.ODataClient.DotNet.csproj", "{1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -88,6 +90,26 @@ Global {45D04722-8B09-4265-9795-DD4DEFC3E592}.Release|x64.Build.0 = Release|Any CPU {45D04722-8B09-4265-9795-DD4DEFC3E592}.Release|x86.ActiveCfg = Release|Any CPU {45D04722-8B09-4265-9795-DD4DEFC3E592}.Release|x86.Build.0 = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|ARM.ActiveCfg = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|ARM.Build.0 = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|ARM64.Build.0 = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|x64.ActiveCfg = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|x64.Build.0 = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|x86.ActiveCfg = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Debug|x86.Build.0 = Debug|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|Any CPU.Build.0 = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|ARM.ActiveCfg = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|ARM.Build.0 = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|ARM64.ActiveCfg = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|ARM64.Build.0 = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|x64.ActiveCfg = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|x64.Build.0 = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|x86.ActiveCfg = Release|Any CPU + {1B3A82C9-E503-4AEF-B7B5-68D01EBF0237}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/gitversion.yml b/gitversion.yml new file mode 100644 index 0000000..f8d9856 --- /dev/null +++ b/gitversion.yml @@ -0,0 +1,21 @@ +assembly-versioning-scheme: MajorMinorPatch +branches: + master: + regex: master + tag: '' + is-release-branch: true + fix: + regex: fix[/-] + tag: fix-ci + release: + regex: release + tag: beta + bug: + regex: bug[/-] + tag: beta-ci + develop: + regex: develop + tag: alpha + dev: + regex: dev[/-] + tag: dev-ci \ No newline at end of file