diff --git a/.gitignore b/.gitignore
index e2c97967..039c0ab7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -297,3 +297,5 @@ __pycache__/
/Nuget
/Xml
/Svn
+/Examples/Angular/Fluent/NpmPackage/package/*.tgz
+/Examples/Angular/Fluent/NpmPackage/package
diff --git a/Angular.Tests/FullStageTests.cs b/Angular.Tests/FullStageTests.cs
index eeeb5661..1b4595aa 100644
--- a/Angular.Tests/FullStageTests.cs
+++ b/Angular.Tests/FullStageTests.cs
@@ -1,9 +1,7 @@
using System;
-using System.Collections.Generic;
using KY.Core.Dependency;
using KY.Generator.Angular.Tests.Properties;
using KY.Generator.AspDotNet;
-using KY.Generator.Configuration;
using KY.Generator.Csharp;
using KY.Generator.Mappings;
using KY.Generator.Output;
diff --git a/Angular.Tests/KY.Generator.Angular.Tests.csproj b/Angular.Tests/KY.Generator.Angular.Tests.csproj
index 83f3483c..33feef6a 100644
--- a/Angular.Tests/KY.Generator.Angular.Tests.csproj
+++ b/Angular.Tests/KY.Generator.Angular.Tests.csproj
@@ -1,13 +1,15 @@
- netcoreapp2.1
+ net6.0
false
+
+ latest
-
+
@@ -16,7 +18,7 @@
-
+
@@ -35,4 +37,10 @@
+
+
+ ..\..\Assemblies\Core.Common.Standard\bin\Debug\netstandard2.0\KY.Core.Common.dll
+
+
+
diff --git a/Angular/AngularModule.cs b/Angular/AngularModule.cs
index dedc8c9b..4b857417 100644
--- a/Angular/AngularModule.cs
+++ b/Angular/AngularModule.cs
@@ -1,25 +1,21 @@
using KY.Core.Dependency;
using KY.Core.Module;
using KY.Generator.Angular.Commands;
-using KY.Generator.Angular.Configurations;
-using KY.Generator.Angular.Writers;
+using KY.Generator.Angular.Languages;
using KY.Generator.Command;
-using KY.Generator.Configuration;
+using KY.Generator.Languages;
-namespace KY.Generator.Angular
+namespace KY.Generator.Angular;
+
+public class AngularModule : ModuleBase
{
- public class AngularModule : ModuleBase
+ public AngularModule(IDependencyResolver dependencyResolver)
+ : base(dependencyResolver)
{
- public AngularModule(IDependencyResolver dependencyResolver)
- : base(dependencyResolver)
- {
- this.DependencyResolver.Bind().To();
- this.DependencyResolver.Bind().To();
- }
-
- public override void Initialize()
- {
- this.DependencyResolver.Get().Map("angular");
- }
+ this.DependencyResolver.Get().Register(AngularServiceCommand.Names);
+ this.DependencyResolver.Get().Register(AngularModelCommand.Names);
+ this.DependencyResolver.Get().Register(AngularPackageCommand.Names);
+ this.DependencyResolver.Bind().To();
+ this.DependencyResolver.Bind().ToSingleton();
}
}
\ No newline at end of file
diff --git a/Angular/Commands/AngularModelCommand.cs b/Angular/Commands/AngularModelCommand.cs
index e4295655..55f9d56a 100644
--- a/Angular/Commands/AngularModelCommand.cs
+++ b/Angular/Commands/AngularModelCommand.cs
@@ -1,58 +1,38 @@
-using System.Collections.Generic;
-using System.Linq;
-using KY.Core.Dependency;
-using KY.Generator.Angular.Configurations;
+using KY.Core.Dependency;
+using KY.Generator.Angular.Languages;
using KY.Generator.Angular.Writers;
using KY.Generator.Command;
+using KY.Generator.Command.Extensions;
using KY.Generator.Output;
-using KY.Generator.Templates;
-using KY.Generator.Transfer;
using KY.Generator.TypeScript;
using KY.Generator.TypeScript.Transfer;
-namespace KY.Generator.Angular.Commands
-{
- public class AngularModelCommand : GeneratorCommand
- {
- private readonly IDependencyResolver resolver;
-
- public override string[] Names { get; } = { "angular-model" };
-
- public AngularModelCommand(IDependencyResolver resolver)
- {
- this.resolver = resolver;
- }
-
- public override IGeneratorCommandResult Run(IOutput output)
- {
- AngularWriteConfiguration writeConfiguration = new AngularWriteConfiguration();
- writeConfiguration.AddHeader = !this.Parameters.SkipHeader;
- writeConfiguration.FormatNames = this.Parameters.FormatNames;
- writeConfiguration.OutputId = this.TransferObjects.OfType().FirstOrDefault()?.Value;
- writeConfiguration.Model = new AngularWriteModelConfiguration();
- writeConfiguration.Model.CopyBaseFrom(writeConfiguration);
- writeConfiguration.Model.Namespace = this.Parameters.Namespace;
- writeConfiguration.Model.RelativePath = this.Parameters.RelativePath;
- writeConfiguration.Model.SkipNamespace = this.Parameters.SkipNamespace;
- writeConfiguration.Model.PropertiesToFields = this.Parameters.PropertiesToFields;
- writeConfiguration.Model.FieldsToProperties = this.Parameters.FieldsToProperties;
- writeConfiguration.Model.PreferInterfaces = this.Parameters.PreferInterfaces;
- writeConfiguration.Model.WithOptionalProperties = this.Parameters.WithOptionalProperties;
- writeConfiguration.Model.FormatNames = this.Parameters.FormatNames;
+namespace KY.Generator.Angular.Commands;
- output.DeleteAllRelatedFiles(writeConfiguration.OutputId, this.Parameters.RelativePath);
-
- if (this.Parameters.Strict && !this.TransferObjects.OfType().Any())
- {
- this.TransferObjects.Add(new TsConfig { CompilerOptions = { Strict = true } });
- }
- TypeScriptStrictHelper.Read(this.Parameters.RelativePath, output, this.resolver, this.TransferObjects);
+public class AngularModelCommand(IDependencyResolver resolver) : GeneratorCommand
+{
+ public static string[] Names { get; } = [ToCommand(nameof(AngularModelCommand)), "angular-model"];
- List files = new List();
- this.resolver.Create().Write(writeConfiguration, this.TransferObjects, files);
- files.ForEach(file => writeConfiguration.Language.Write(file, output));
+ public override void Prepare()
+ {
+ Options options = resolver.Get();
+ GeneratorOptions generatorOptions = options.Get();
+ generatorOptions.SetFromParameter(this.Parameters);
+ generatorOptions.Language = resolver.Get();
+ generatorOptions.Formatting.AllowedSpecialCharacters = "$";
+ generatorOptions.SkipNamespace = true;
+ generatorOptions.PropertiesToFields = true;
+ TypeScriptOptions typeScriptOptions = options.Get();
+ // TODO: Fix path is null
+ typeScriptOptions.SetStrict(this.Parameters.RelativePath, resolver);
+ }
- return this.Success();
- }
+ public override IGeneratorCommandResult Run()
+ {
+ // TODO: Fix path is null
+ resolver.Get().DeleteAllRelatedFiles(this.Parameters.RelativePath);
+ resolver.Create().FormatNames().Write(this.Parameters.RelativePath);
+ resolver.Create().Execute(this.Parameters.RelativePath);
+ return this.Success();
}
-}
+}
\ No newline at end of file
diff --git a/Angular/Commands/AngularModelCommandParameters.cs b/Angular/Commands/AngularModelCommandParameters.cs
deleted file mode 100644
index 2d6ea6a0..00000000
--- a/Angular/Commands/AngularModelCommandParameters.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using KY.Generator.Command;
-
-namespace KY.Generator.Angular.Commands
-{
- public class AngularModelCommandParameters : GeneratorCommandParameters
- {
- public string Namespace { get; set; }
- public bool Strict { get; set; }
- }
-}
diff --git a/Angular/Commands/AngularPackageCommand.cs b/Angular/Commands/AngularPackageCommand.cs
new file mode 100644
index 00000000..34818e4f
--- /dev/null
+++ b/Angular/Commands/AngularPackageCommand.cs
@@ -0,0 +1,84 @@
+using KY.Core;
+using KY.Core.DataAccess;
+using KY.Core.Dependency;
+using KY.Generator.Angular.Languages;
+using KY.Generator.Angular.Writers;
+using KY.Generator.Command;
+using KY.Generator.Command.Extensions;
+using KY.Generator.Output;
+using KY.Generator.TypeScript;
+
+namespace KY.Generator.Angular.Commands;
+
+public class AngularPackageCommand : GeneratorCommand
+{
+ private readonly IDependencyResolver resolver;
+ private readonly IOutput output;
+ private string nameWithoutScope;
+ private string packagePath;
+ private string relativePackagePath;
+
+ public static string[] Names { get; } = [ToCommand(nameof(AngularPackageCommand)), "angular-package"];
+ public List Commands { get; } = [];
+
+ public AngularPackageCommand(IDependencyResolver resolver, IOutput output)
+ {
+ this.resolver = resolver;
+ this.output = output;
+ }
+
+ public override void Prepare()
+ {
+ this.nameWithoutScope = this.Parameters.Name.Split('/').Last();
+ this.relativePackagePath = FileSystem.Combine(this.Parameters.RelativePath, AngularPackageWriter.BasePackageName, "projects", this.nameWithoutScope);
+ this.packagePath = FileSystem.Combine(this.output.ToString(), this.relativePackagePath);
+ base.Prepare();
+ this.Commands.ForEach(command => command.Prepare());
+ }
+
+ public override IGeneratorCommandResult Run()
+ {
+ Options options = this.resolver.Get();
+ GeneratorOptions generatorOptions = options.Get();
+ generatorOptions.SetFromParameter(this.Parameters);
+ generatorOptions.Language = this.resolver.Get();
+ generatorOptions.Formatting.AllowedSpecialCharacters = "$";
+ generatorOptions.SkipNamespace = true;
+ generatorOptions.PropertiesToFields = true;
+ TypeScriptOptions typeScriptOptions = options.Get();
+ typeScriptOptions.SetStrict(this.Parameters.RelativePath, this.resolver);
+ typeScriptOptions.ForceIndex = true;
+
+ string servicePath = this.Commands.OfType().FirstOrDefault()?.Parameters.RelativePath;
+ string modelPath = this.Commands.OfType().FirstOrDefault()?.Parameters.RelativePath;
+ string libPath = FileSystem.Combine(this.relativePackagePath, "src", "lib");
+ this.Commands.ForEach(command => command.Parameters.RelativePath = FileSystem.Combine(libPath, command.Parameters.RelativePath));
+ this.Commands.OfType().ForEach(command => command.Parameters.RelativeModelPath = FileSystem.Combine(libPath, command.Parameters.RelativeModelPath));
+
+ AngularPackageWriter writer = this.resolver.Create();
+ writer.Write(this.nameWithoutScope, this.Parameters.Name, this.Parameters.Version, this.packagePath, this.Parameters.DependsOn, this.Parameters.CliVersion, servicePath, modelPath, this.Parameters.IncrementVersion, this.Parameters.VersionFromNpm);
+ this.Commands.ForEach(command => command.Run());
+ return this.Success();
+ }
+
+ public override void FollowUp()
+ {
+ base.FollowUp();
+ this.Commands.ForEach(command => command.FollowUp());
+ bool publish = this.Parameters.Publish || this.Parameters.PublishLocal;
+ if (!this.Parameters.Build && !publish)
+ {
+ return;
+ }
+ AngularPackageBuilder builder = this.resolver.Create();
+ builder.Build(this.packagePath);
+ if (this.Parameters.Publish)
+ {
+ builder.Publish(this.packagePath);
+ }
+ if (this.Parameters.PublishLocal)
+ {
+ builder.PublishLocal(this.packagePath);
+ }
+ }
+}
diff --git a/Angular/Commands/AngularPackageCommandParameters.cs b/Angular/Commands/AngularPackageCommandParameters.cs
new file mode 100644
index 00000000..692838d9
--- /dev/null
+++ b/Angular/Commands/AngularPackageCommandParameters.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+using KY.Generator.Angular.Models;
+using KY.Generator.Command;
+
+namespace KY.Generator.Angular.Commands
+{
+ public class AngularPackageCommandParameters : GeneratorCommandParameters
+ {
+ public string Name { get; set; }
+ public string Version { get; set; }
+ public string CliVersion { get; set; }
+ public List DependsOn { get; set; } = new();
+ public bool Build { get; set; }
+ public bool Publish { get; set; }
+ public bool PublishLocal { get; set; }
+ public bool VersionFromNpm { get; set; }
+ public IncrementVersion IncrementVersion { get; set; }
+ }
+}
diff --git a/Angular/Commands/AngularPackageDependsOnParameter.cs b/Angular/Commands/AngularPackageDependsOnParameter.cs
new file mode 100644
index 00000000..6d6b770b
--- /dev/null
+++ b/Angular/Commands/AngularPackageDependsOnParameter.cs
@@ -0,0 +1,14 @@
+namespace KY.Generator.Angular.Commands
+{
+ public class AngularPackageDependsOnParameter
+ {
+ public string Name { get; }
+ public string Version { get; }
+
+ public AngularPackageDependsOnParameter(string name, string version)
+ {
+ this.Name = name;
+ this.Version = version;
+ }
+ }
+}
diff --git a/Angular/Commands/AngularServiceCommand.cs b/Angular/Commands/AngularServiceCommand.cs
index 08ceac09..2131bcaa 100644
--- a/Angular/Commands/AngularServiceCommand.cs
+++ b/Angular/Commands/AngularServiceCommand.cs
@@ -1,65 +1,62 @@
-using System.Collections.Generic;
-using System.Linq;
-using KY.Core.Dependency;
+using KY.Core.Dependency;
using KY.Generator.Angular.Configurations;
+using KY.Generator.Angular.Languages;
using KY.Generator.Angular.Writers;
using KY.Generator.Command;
+using KY.Generator.Command.Extensions;
using KY.Generator.Output;
-using KY.Generator.Templates;
-using KY.Generator.Transfer;
using KY.Generator.TypeScript;
using KY.Generator.TypeScript.Transfer;
-namespace KY.Generator.Angular.Commands
+namespace KY.Generator.Angular.Commands;
+
+public class AngularServiceCommand : GeneratorCommand
{
- public class AngularServiceCommand : GeneratorCommand
- {
- private readonly IDependencyResolver resolver;
- public override string[] Names { get; } = { "angular-service" };
+ private readonly IDependencyResolver resolver;
+ public static string[] Names { get; } = [ToCommand(nameof(AngularServiceCommand)), "angular-service"];
- public AngularServiceCommand(IDependencyResolver resolver)
- {
- this.resolver = resolver;
- }
+ public AngularServiceCommand(IDependencyResolver resolver)
+ {
+ this.resolver = resolver;
+ }
- public override IGeneratorCommandResult Run(IOutput output)
- {
- AngularWriteConfiguration writeConfiguration = new AngularWriteConfiguration();
- writeConfiguration.AddHeader = !this.Parameters.SkipHeader;
- writeConfiguration.FormatNames = this.Parameters.FormatNames;
- writeConfiguration.OutputId = this.TransferObjects.OfType().FirstOrDefault()?.Value;
- writeConfiguration.Service = new AngularWriteServiceConfiguration();
- writeConfiguration.Service.Name = this.Parameters.Name;
- writeConfiguration.Service.RelativePath = this.Parameters.RelativePath;
- writeConfiguration.Service.EndlessTries = this.Parameters.EndlessTries;
- writeConfiguration.Service.Timeouts = this.Parameters.Timeouts;
- writeConfiguration.Model.RelativePath = this.Parameters.RelativeModelPath;
- writeConfiguration.Service.HttpClient.Name = this.Parameters.HttpClient;
- writeConfiguration.Service.HttpClient.Import = this.Parameters.HttpClientUsing;
- writeConfiguration.Service.HttpClient.Get = this.Parameters.HttpClientGet;
- writeConfiguration.Service.HttpClient.HasGetOptions = this.Parameters.HttpClientGetOptions;
- writeConfiguration.Service.HttpClient.Post = this.Parameters.HttpClientPost;
- writeConfiguration.Service.HttpClient.HasPostOptions = this.Parameters.HttpClientPostOptions;
- writeConfiguration.Service.HttpClient.Patch = this.Parameters.HttpClientPatch;
- writeConfiguration.Service.HttpClient.HasPatchOptions = this.Parameters.HttpClientPatchOptions;
- writeConfiguration.Service.HttpClient.Put = this.Parameters.HttpClientPut;
- writeConfiguration.Service.HttpClient.HasPutOptions = this.Parameters.HttpClientPutOptions;
- writeConfiguration.Service.HttpClient.Delete = this.Parameters.HttpClientDelete;
- writeConfiguration.Service.HttpClient.HasDeleteOptions = this.Parameters.HttpClientDeleteOptions;
+ public override IGeneratorCommandResult Run()
+ {
+ Options options = this.resolver.Get();
+ GeneratorOptions generatorOptions = options.Get();
+ generatorOptions.SetFromParameter(this.Parameters);
+ generatorOptions.Language = this.resolver.Get();
+ generatorOptions.Formatting.AllowedSpecialCharacters = "$";
+ generatorOptions.SkipNamespace = true;
+ generatorOptions.PropertiesToFields = true;
+ TypeScriptOptions typeScriptOptions = options.Get();
+ typeScriptOptions.SetStrict(this.Parameters.RelativePath, this.resolver);
- output.DeleteAllRelatedFiles(writeConfiguration.OutputId, this.Parameters.RelativePath);
+ AngularWriteConfiguration writeConfiguration = new();
+ writeConfiguration.Service = new AngularWriteServiceConfiguration();
+ writeConfiguration.Service.Name = this.Parameters.Name;
+ writeConfiguration.Service.RelativePath = this.Parameters.RelativePath;
+ writeConfiguration.Service.EndlessTries = this.Parameters.EndlessTries;
+ writeConfiguration.Service.Timeouts = this.Parameters.Timeouts;
+ writeConfiguration.Model.RelativePath = this.Parameters.RelativeModelPath;
+ writeConfiguration.Service.HttpClient.Name = this.Parameters.HttpClient;
+ writeConfiguration.Service.HttpClient.Import = this.Parameters.HttpClientUsing;
+ writeConfiguration.Service.HttpClient.Get = this.Parameters.HttpClientGet;
+ writeConfiguration.Service.HttpClient.HasGetOptions = this.Parameters.HttpClientGetOptions;
+ writeConfiguration.Service.HttpClient.Post = this.Parameters.HttpClientPost;
+ writeConfiguration.Service.HttpClient.HasPostOptions = this.Parameters.HttpClientPostOptions;
+ writeConfiguration.Service.HttpClient.Patch = this.Parameters.HttpClientPatch;
+ writeConfiguration.Service.HttpClient.HasPatchOptions = this.Parameters.HttpClientPatchOptions;
+ writeConfiguration.Service.HttpClient.Put = this.Parameters.HttpClientPut;
+ writeConfiguration.Service.HttpClient.HasPutOptions = this.Parameters.HttpClientPutOptions;
+ writeConfiguration.Service.HttpClient.Delete = this.Parameters.HttpClientDelete;
+ writeConfiguration.Service.HttpClient.HasDeleteOptions = this.Parameters.HttpClientDeleteOptions;
- if (this.Parameters.Strict && !this.TransferObjects.OfType().Any())
- {
- this.TransferObjects.Add(new TsConfig { CompilerOptions = { Strict = true } });
- }
- TypeScriptStrictHelper.Read(this.Parameters.RelativePath, output, this.resolver, this.TransferObjects);
+ this.resolver.Get().DeleteAllRelatedFiles(this.Parameters.RelativePath);
- List files = new List();
- this.resolver.Create().Write(writeConfiguration, this.TransferObjects, files);
- files.ForEach(file => writeConfiguration.Language.Write(file, output));
+ this.resolver.Create().Write(writeConfiguration);
+ this.resolver.Create().Execute(this.Parameters.RelativePath);
- return this.Success();
- }
+ return this.Success();
}
}
diff --git a/Angular/Commands/AngularServiceCommandParameters.cs b/Angular/Commands/AngularServiceCommandParameters.cs
index 0afc6546..3004d805 100644
--- a/Angular/Commands/AngularServiceCommandParameters.cs
+++ b/Angular/Commands/AngularServiceCommandParameters.cs
@@ -9,7 +9,6 @@ public class AngularServiceCommandParameters : GeneratorCommandParameters
public string RelativeModelPath { get; set; }
public bool EndlessTries { get; set; }
public List Timeouts { get; set; }
- public bool Strict { get; set; }
public string HttpClient { get; set; }
public string HttpClientUsing { get; set; }
public string HttpClientGet { get; set; }
diff --git a/Angular/Configurations/AngularWriteConfiguration.cs b/Angular/Configurations/AngularWriteConfiguration.cs
index aff09256..58678ea8 100644
--- a/Angular/Configurations/AngularWriteConfiguration.cs
+++ b/Angular/Configurations/AngularWriteConfiguration.cs
@@ -1,27 +1,15 @@
-using System;
-using KY.Generator.Angular.Languages;
-using KY.Generator.Configurations;
-
-namespace KY.Generator.Angular.Configurations
+namespace KY.Generator.Angular.Configurations
{
- public class AngularWriteConfiguration : ConfigurationBase, IFormattableConfiguration
+ public class AngularWriteConfiguration
{
public AngularWriteServiceConfiguration Service { get; set; }
public AngularWriteModelConfiguration Model { get; set; }
- public bool FormatNames { get; set; }
public bool WriteModels { get; set; }
- public AngularWriteConfiguration(ConfigurationBase copyFrom = null)
+ public AngularWriteConfiguration()
{
- if (copyFrom != null)
- {
- this.CopyBaseFrom(copyFrom);
- }
- this.Language = new AngularTypeScriptLanguage();
- this.FormatNames = true;
this.WriteModels = true;
this.Model = new AngularWriteModelConfiguration();
- this.Formatting.AllowedSpecialCharacters = "$";
}
}
-}
\ No newline at end of file
+}
diff --git a/Angular/Configurations/AngularWriteModelConfiguration.cs b/Angular/Configurations/AngularWriteModelConfiguration.cs
index 81f8c1f2..0de80cea 100644
--- a/Angular/Configurations/AngularWriteModelConfiguration.cs
+++ b/Angular/Configurations/AngularWriteModelConfiguration.cs
@@ -5,10 +5,5 @@ namespace KY.Generator.Angular.Configurations
{
public class AngularWriteModelConfiguration : ModelWriteConfiguration
{
- public AngularWriteModelConfiguration()
- {
- this.Language = TypeScriptLanguage.Instance;
- this.SkipNamespace = true;
- }
}
}
diff --git a/Angular/Fluent/AngularModelSyntax.cs b/Angular/Fluent/AngularModelSyntax.cs
index d24921bb..9808be57 100644
--- a/Angular/Fluent/AngularModelSyntax.cs
+++ b/Angular/Fluent/AngularModelSyntax.cs
@@ -1,23 +1,24 @@
using System.Linq;
using KY.Core;
using KY.Generator.Angular.Commands;
+using KY.Generator.Syntax;
namespace KY.Generator.Angular.Fluent
{
internal class AngularModelSyntax : IAngularModelSyntax
{
- private readonly AngularWriteSyntax syntax;
+ private readonly IExecutableSyntax syntax;
private readonly AngularModelCommand command;
- public AngularModelSyntax(AngularWriteSyntax syntax, AngularModelCommand command)
+ public AngularModelSyntax(IExecutableSyntax syntax, AngularModelCommand command)
{
this.syntax = syntax;
this.command = command;
}
- public IAngularModelSyntax SkipHeader()
+ public IAngularModelSyntax NoHeader()
{
- this.command.Parameters.SkipHeader = true;
+ this.command.Parameters.NoHeader = true;
return this;
}
@@ -52,12 +53,6 @@ public IAngularModelSyntax FieldsToProperties(bool value = true)
return this;
}
- public IAngularModelSyntax Strict(bool value = true)
- {
- this.command.Parameters.Strict = value;
- return this;
- }
-
public IAngularModelSyntax PreferInterfaces()
{
this.command.Parameters.PreferInterfaces = true;
diff --git a/Angular/Fluent/AngularPackageSyntax.cs b/Angular/Fluent/AngularPackageSyntax.cs
new file mode 100644
index 00000000..a2c9c150
--- /dev/null
+++ b/Angular/Fluent/AngularPackageSyntax.cs
@@ -0,0 +1,112 @@
+using System;
+using System.Collections.Generic;
+using KY.Core.Dependency;
+using KY.Generator.Angular.Commands;
+using KY.Generator.Angular.Models;
+using KY.Generator.Command;
+using KY.Generator.Syntax;
+
+namespace KY.Generator.Angular.Fluent
+{
+ internal class AngularPackageSyntax : IAngularPackageSyntax, IExecutableSyntax
+ {
+ private readonly IDependencyResolver resolver;
+ private readonly AngularPackageCommand command;
+
+ public List Commands => this.command.Commands;
+
+ public AngularPackageSyntax(IDependencyResolver resolver, AngularPackageCommand command)
+ {
+ this.resolver = resolver;
+ this.command = command;
+ }
+
+ public IAngularPackageSyntax Name(string packageName)
+ {
+ this.command.Parameters.Name = packageName;
+ return this;
+ }
+
+ public IAngularPackageSyntax Version(string version)
+ {
+ this.command.Parameters.Version = version;
+ return this;
+ }
+
+ public IAngularPackageSyntax VersionFromNpm()
+ {
+ this.command.Parameters.VersionFromNpm = true;
+ return this;
+ }
+
+ public IAngularPackageSyntax IncrementMajorVersion()
+ {
+ this.command.Parameters.IncrementVersion = IncrementVersion.Major;
+ return this;
+ }
+
+ public IAngularPackageSyntax IncrementMinorVersion()
+ {
+ this.command.Parameters.IncrementVersion = IncrementVersion.Minor;
+ return this;
+ }
+
+ public IAngularPackageSyntax IncrementPatchVersion()
+ {
+ this.command.Parameters.IncrementVersion = IncrementVersion.Patch;
+ return this;
+ }
+
+ public IAngularPackageSyntax CliVersion(string version)
+ {
+ this.command.Parameters.CliVersion = version;
+ return this;
+ }
+
+ public IAngularPackageSyntax DependsOn(string packageName, string version)
+ {
+ this.command.Parameters.DependsOn.Add(new AngularPackageDependsOnParameter(packageName, version));
+ return this;
+ }
+
+ public IAngularPackageSyntax OutputPath(string path)
+ {
+ this.command.Parameters.RelativePath = path;
+ return this;
+ }
+
+ public IAngularPackageSyntax Build()
+ {
+ this.command.Parameters.Build = true;
+ return this;
+ }
+
+ public IAngularPackageSyntax Publish()
+ {
+ this.command.Parameters.Publish = true;
+ return this;
+ }
+
+ public IAngularPackageSyntax PublishLocal()
+ {
+ this.command.Parameters.PublishLocal = true;
+ return this;
+ }
+
+ public IAngularPackageSyntax Models(Action action = null)
+ {
+ AngularModelCommand modelCommand = this.resolver.Create();
+ this.Commands.Add(modelCommand);
+ action?.Invoke(new AngularModelSyntax(this, modelCommand));
+ return this;
+ }
+
+ public IAngularPackageSyntax Services(Action action = null)
+ {
+ AngularServiceCommand serviceCommand = this.resolver.Create();
+ this.Commands.Add(serviceCommand);
+ action?.Invoke(new AngularServiceSyntax(this, serviceCommand));
+ return this;
+ }
+ }
+}
diff --git a/Angular/Fluent/AngularServiceSyntax.cs b/Angular/Fluent/AngularServiceSyntax.cs
index d4ac863f..8dcfd3a0 100644
--- a/Angular/Fluent/AngularServiceSyntax.cs
+++ b/Angular/Fluent/AngularServiceSyntax.cs
@@ -1,24 +1,25 @@
using System;
using System.Linq;
using KY.Generator.Angular.Commands;
+using KY.Generator.Syntax;
namespace KY.Generator.Angular.Fluent
{
internal class AngularServiceSyntax : IAngularServiceSyntax, IAngularHttpClientSyntax
{
- private readonly AngularWriteSyntax syntax;
+ private readonly IExecutableSyntax syntax;
private readonly AngularServiceCommand command;
- public AngularServiceSyntax(AngularWriteSyntax syntax, AngularServiceCommand command)
+ public AngularServiceSyntax(IExecutableSyntax syntax, AngularServiceCommand command)
{
this.syntax = syntax;
this.command = command;
this.command.Parameters.RelativeModelPath = this.syntax.Commands.OfType().FirstOrDefault()?.Parameters.RelativePath;
}
- public IAngularServiceSyntax SkipHeader()
+ public IAngularServiceSyntax NoHeader()
{
- this.command.Parameters.SkipHeader = true;
+ this.command.Parameters.NoHeader = true;
return this;
}
@@ -34,12 +35,6 @@ public IAngularServiceSyntax OutputPath(string path)
return this;
}
- public IAngularServiceSyntax Strict(bool value = true)
- {
- this.command.Parameters.Strict = value;
- return this;
- }
-
public IAngularServiceSyntax Name(string name)
{
this.command.Parameters.Name = name;
diff --git a/Angular/Fluent/AngularWriteSyntax.cs b/Angular/Fluent/AngularWriteSyntax.cs
index d4578ad1..61fb5e70 100644
--- a/Angular/Fluent/AngularWriteSyntax.cs
+++ b/Angular/Fluent/AngularWriteSyntax.cs
@@ -1,36 +1,47 @@
using System;
using System.Collections.Generic;
+using KY.Core;
+using KY.Core.Dependency;
using KY.Generator.Angular.Commands;
using KY.Generator.Command;
using KY.Generator.Syntax;
namespace KY.Generator.Angular.Fluent
{
- internal class AngularWriteSyntax : IAngularWriteSyntax
+ internal class AngularWriteSyntax : IAngularWriteSyntax, IExecutableSyntax
{
- private readonly IWriteFluentSyntaxInternal syntax;
+ private readonly IDependencyResolver resolver;
- public List Commands => this.syntax.Commands;
+ public List Commands { get; } = new();
- public AngularWriteSyntax(IWriteFluentSyntaxInternal syntax)
+ public AngularWriteSyntax(IDependencyResolver resolver)
{
- this.syntax = syntax;
+ this.resolver = resolver;
}
public IAngularWriteSyntax Models(Action action = null)
{
- AngularModelCommand command = new(this.syntax.Resolver);
- this.syntax.Commands.Add(command);
+ AngularModelCommand command = this.resolver.Create();
+ this.Commands.Add(command);
action?.Invoke(new AngularModelSyntax(this, command));
return this;
}
public IAngularWriteSyntax Services(Action action = null)
{
- AngularServiceCommand command = new(this.syntax.Resolver);
- this.syntax.Commands.Add(command);
+ AngularServiceCommand command = this.resolver.Create();
+ this.Commands.Add(command);
action?.Invoke(new AngularServiceSyntax(this, command));
return this;
}
+
+ public IAngularWriteSyntax Package(Action action)
+ {
+ action.AssertIsNotNull();
+ AngularPackageCommand command = this.resolver.Create();
+ this.Commands.Add(command);
+ action.Invoke(new AngularPackageSyntax(this.resolver, command));
+ return this;
+ }
}
}
diff --git a/Angular/Fluent/Extensions/WriteFluentSyntaxExtension.cs b/Angular/Fluent/Extensions/WriteFluentSyntaxExtension.cs
new file mode 100644
index 00000000..ea709286
--- /dev/null
+++ b/Angular/Fluent/Extensions/WriteFluentSyntaxExtension.cs
@@ -0,0 +1,24 @@
+using System;
+using KY.Core;
+using KY.Generator.Angular.Fluent;
+using KY.Generator.Syntax;
+
+// ReSharper disable once CheckNamespace
+namespace KY.Generator
+{
+ public static class WriteFluentSyntaxExtension
+ {
+ ///
+ /// Executes the Angular write commands. Use at least one command!
+ ///
+ public static IWriteFluentSyntax Angular(this IWriteFluentSyntax syntax, Action action)
+ {
+ IFluentInternalSyntax internalSyntax = syntax.CastTo();
+ AngularWriteSyntax writeSyntax = internalSyntax.Resolver.Create();
+ internalSyntax.Syntaxes.Add(writeSyntax);
+ action(writeSyntax);
+ writeSyntax.Commands.Count.AssertIsPositive(message: $"The {nameof(Angular)} action requires at least one command. E.g. '.{nameof(Angular)}(write => write.{nameof(IAngularWriteSyntax.Models)}(...))'");
+ return syntax;
+ }
+ }
+}
diff --git a/Angular/Fluent/IAngularModelSyntax.cs b/Angular/Fluent/IAngularModelSyntax.cs
index 35c2e2a2..88c09d03 100644
--- a/Angular/Fluent/IAngularModelSyntax.cs
+++ b/Angular/Fluent/IAngularModelSyntax.cs
@@ -5,7 +5,7 @@ public interface IAngularModelSyntax
///
/// Skips the <auto-generated>
header. DO NOT USE THIS IN PRODUCTION. This is only meant unit testing
///
- IAngularModelSyntax SkipHeader();
+ IAngularModelSyntax NoHeader();
///
/// If set to false, stops formatting the language specific naming like from C# property MyProperty
to TypeScript property myProperty
@@ -35,13 +35,6 @@ public interface IAngularModelSyntax
///
IAngularModelSyntax FieldsToProperties(bool value = true);
- ///
- /// Generates code, valid for strict mode
- ///
- ///
- ///
- IAngularModelSyntax Strict(bool value = true);
-
///
/// Tries to generate all models as interfaces
///
diff --git a/Angular/Fluent/IAngularPackageSyntax.cs b/Angular/Fluent/IAngularPackageSyntax.cs
new file mode 100644
index 00000000..248a29b9
--- /dev/null
+++ b/Angular/Fluent/IAngularPackageSyntax.cs
@@ -0,0 +1,63 @@
+namespace KY.Generator.Angular.Fluent
+{
+ public interface IAngularPackageSyntax : IAngularWriteBaseSyntax
+ {
+ ///
+ /// Set the name of the packages (scope is optional) e.g. @scope/my-lib [REQUIRED]
+ ///
+ IAngularPackageSyntax Name(string packageName);
+
+ ///
+ /// Set the version of the package (semver is allowed) [REQUIRED]
+ ///
+ IAngularPackageSyntax Version(string version);
+
+ ///
+ /// Reads the latest version from npm
+ ///
+ IAngularPackageSyntax VersionFromNpm();
+
+ ///
+ /// Increments the major (1.0.0) version of the package when changes are found
+ ///
+ IAngularPackageSyntax IncrementMajorVersion();
+
+ ///
+ /// Increments the minor (0.1.0) version of the package when changes are found
+ ///
+ IAngularPackageSyntax IncrementMinorVersion();
+
+ ///
+ /// Increments the patch/bugfix/revision (0.0.1) version of the package when changes are found
+ ///
+ IAngularPackageSyntax IncrementPatchVersion();
+
+ ///
+ /// Set the version of the angular cli (semver is allowed)
+ ///
+ IAngularPackageSyntax CliVersion(string version);
+
+ ///
+ /// Adds a peer dependency to the package. Version is required and can look like: ^1.2.3
+ ///
+ IAngularPackageSyntax DependsOn(string packageName, string version);
+
+ ///
+ IAngularPackageSyntax OutputPath(string path);
+
+ ///
+ /// Builds the package after generation is done
+ ///
+ IAngularPackageSyntax Build();
+
+ ///
+ /// Builds and publish the package after generation is done
+ ///
+ IAngularPackageSyntax Publish();
+
+ ///
+ /// Builds and publish the package to the root folder of the package after generation is done
+ ///
+ IAngularPackageSyntax PublishLocal();
+ }
+}
diff --git a/Angular/Fluent/IAngularServiceSyntax.cs b/Angular/Fluent/IAngularServiceSyntax.cs
index 16a6c9f3..e880cc83 100644
--- a/Angular/Fluent/IAngularServiceSyntax.cs
+++ b/Angular/Fluent/IAngularServiceSyntax.cs
@@ -2,8 +2,8 @@
{
public interface IAngularServiceSyntax
{
- ///
- IAngularServiceSyntax SkipHeader();
+ ///
+ IAngularServiceSyntax NoHeader();
///
IAngularServiceSyntax FormatNames(bool value = true);
@@ -11,9 +11,6 @@ public interface IAngularServiceSyntax
///
IAngularServiceSyntax OutputPath(string path);
- ///
- IAngularServiceSyntax Strict(bool value = true);
-
///
/// Renames the controller. Use {0} to inject the controller name without "Controller"
///
diff --git a/Angular/Fluent/IAngularWriteBaseSyntax.cs b/Angular/Fluent/IAngularWriteBaseSyntax.cs
new file mode 100644
index 00000000..b24fb495
--- /dev/null
+++ b/Angular/Fluent/IAngularWriteBaseSyntax.cs
@@ -0,0 +1,17 @@
+using System;
+
+namespace KY.Generator.Angular.Fluent
+{
+ public interface IAngularWriteBaseSyntax
+ {
+ ///
+ /// Writes all models (POCOs) from all previous read actions to the output, with some angular specific modifications
+ ///
+ T Models(Action action = null);
+
+ ///
+ /// Writes all services from all previous read actions to the output
+ ///
+ T Services(Action action = null);
+ }
+}
diff --git a/Angular/Fluent/IAngularWriteSyntax.cs b/Angular/Fluent/IAngularWriteSyntax.cs
index bb6a26b6..b577e6a9 100644
--- a/Angular/Fluent/IAngularWriteSyntax.cs
+++ b/Angular/Fluent/IAngularWriteSyntax.cs
@@ -2,16 +2,11 @@
namespace KY.Generator.Angular.Fluent
{
- public interface IAngularWriteSyntax
+ public interface IAngularWriteSyntax : IAngularWriteBaseSyntax
{
///
- /// Writes all models (POCOs) from all previous read actions to the output, with some angular specific modifications
+ /// Creates the code for a npm package
///
- IAngularWriteSyntax Models(Action action = null);
-
- ///
- /// Writes all services from all previous read actions to the output
- ///
- IAngularWriteSyntax Services(Action action = null);
+ IAngularWriteSyntax Package(Action action);
}
-}
\ No newline at end of file
+}
diff --git a/Angular/Fluent/WriteFluentSyntaxExtension.cs b/Angular/Fluent/WriteFluentSyntaxExtension.cs
deleted file mode 100644
index dfe45351..00000000
--- a/Angular/Fluent/WriteFluentSyntaxExtension.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using KY.Generator.Angular.Fluent;
-using KY.Generator.Syntax;
-
-// ReSharper disable once CheckNamespace
-namespace KY.Generator
-{
- public static class WriteFluentSyntaxExtension
- {
- public static IWriteFluentSyntax Angular(this IWriteFluentSyntax syntax, Action action)
- {
- action(new AngularWriteSyntax((IWriteFluentSyntaxInternal)syntax));
- return syntax;
- }
- }
-}
\ No newline at end of file
diff --git a/Angular/KY.Generator.Angular.csproj b/Angular/KY.Generator.Angular.csproj
index 64878b1f..7b45b348 100644
--- a/Angular/KY.Generator.Angular.csproj
+++ b/Angular/KY.Generator.Angular.csproj
@@ -1,41 +1,47 @@
-
- netstandard2.0
- KY-Programming
- KY-Programming
- KY.Generator
- 7.6.0
- 2021 - KY-Programming
- Angular Module for KY-Generator
-Download KY.Generator to use this module
- GPL-3.0-or-later
- https://generator.ky-programming.de
- https://ky-programming.de/images/logos/128.png
- https://github.com/KY-Programming/generator
- KY-Generator KY Generator Angular
- latest
-
+
+ netstandard2.0
+ enable
+ enable
+ KY-Programming
+ KY-Programming
+ KY.Generator
+ 10.0.0-preview.2
+ 2025 - KY-Programming
+ Angular Module for KY-Generator
+ Download KY.Generator to use this module
+
+ README.md
+ MIT
+ https://generator.ky-programming.de
+ assets\icon.png
+ https://github.com/KY-Programming/generator
+ KY-Generator KY.Generator Angular
+ latest
+
-
- ..\bin\Debug
- 1701;1702
-
+
+ ..\bin\Debug
+ 1701;1702
+
-
- ..\bin\Release
- 1701;1702;1591
- ..\bin\Release\KY.Generator.Angular.xml
-
+
+ ..\bin\Release
+ 1701;1702;1591
+ ..\bin\Release\KY.Generator.Angular.xml
+
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
diff --git a/Angular/KY.Generator.Angular.csproj.DotSettings b/Angular/KY.Generator.Angular.csproj.DotSettings
new file mode 100644
index 00000000..e46c24fe
--- /dev/null
+++ b/Angular/KY.Generator.Angular.csproj.DotSettings
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file
diff --git a/Angular/Languages/AngularTypeScriptLanguage.cs b/Angular/Languages/AngularTypeScriptLanguage.cs
index 71a82cb3..7e5600bc 100644
--- a/Angular/Languages/AngularTypeScriptLanguage.cs
+++ b/Angular/Languages/AngularTypeScriptLanguage.cs
@@ -1,23 +1,15 @@
-using System;
+using KY.Core.Dependency;
+using KY.Generator.Models;
using KY.Generator.TypeScript.Languages;
namespace KY.Generator.Angular.Languages
{
internal class AngularTypeScriptLanguage : TypeScriptLanguage
{
- public AngularTypeScriptLanguage()
+ public AngularTypeScriptLanguage(IDependencyResolver resolver)
+ : base(resolver)
{
- this.Key = TypeScriptLanguage.Instance.Key;
- }
-
- public override string FormatFileName(string fileName, string fileType = null)
- {
- string formattedFileName = base.FormatFileName(fileName, fileType);
- if ("service".Equals(fileType, StringComparison.CurrentCultureIgnoreCase))
- {
- formattedFileName = formattedFileName.Replace("-service.ts", ".service.ts");
- }
- return formattedFileName;
+ this.Formatting.Add(new FileNameReplacer("angular-service", "^(.*)-service$", "$1.service", "service"));
}
}
-}
\ No newline at end of file
+}
diff --git a/Angular/Models/IncrementVersion.cs b/Angular/Models/IncrementVersion.cs
new file mode 100644
index 00000000..24f4d870
--- /dev/null
+++ b/Angular/Models/IncrementVersion.cs
@@ -0,0 +1,10 @@
+namespace KY.Generator.Angular.Models
+{
+ public enum IncrementVersion
+ {
+ None,
+ Major,
+ Minor,
+ Patch
+ }
+}
diff --git a/Angular/Options/AngularOptions.cs b/Angular/Options/AngularOptions.cs
new file mode 100644
index 00000000..5cce1837
--- /dev/null
+++ b/Angular/Options/AngularOptions.cs
@@ -0,0 +1,20 @@
+namespace KY.Generator.Angular;
+
+public class AngularOptions(AngularOptions? parent, AngularOptions? global, object? target = null)
+ : OptionsBase(parent, global, target)
+{
+ private string? modelOutput;
+ private string? serviceOutput;
+
+ public string? ModelOutput
+ {
+ get => this.GetValue(x => x.modelOutput);
+ set => this.modelOutput = value;
+ }
+
+ public string? ServiceOutput
+ {
+ get => this.GetValue(x => x.serviceOutput);
+ set => this.serviceOutput = value;
+ }
+}
diff --git a/Angular/Options/AngularOptionsFactory.cs b/Angular/Options/AngularOptionsFactory.cs
new file mode 100644
index 00000000..8ad9d9bc
--- /dev/null
+++ b/Angular/Options/AngularOptionsFactory.cs
@@ -0,0 +1,47 @@
+using System.Reflection;
+
+namespace KY.Generator.Angular;
+
+public class AngularOptionsFactory : IOptionsFactory
+{
+ public bool CanCreate(Type optionsType)
+ {
+ return optionsType == typeof(AngularOptions);
+ }
+
+ public object Create(Type optionsType, object key, object? parent, object global)
+ {
+ return new AngularOptions(parent as AngularOptions, global as AngularOptions, key);
+ }
+
+ public object CreateGlobal(Type optionsType, object key, object? parent)
+ {
+ return key switch
+ {
+ Assembly assembly => this.CreateFromCustomAttributes(assembly.GetCustomAttributes(), key, parent as AngularOptions),
+ MemberInfo member => this.CreateFromCustomAttributes(member.GetCustomAttributes(), key, parent as AngularOptions),
+ ParameterInfo parameter => this.CreateFromCustomAttributes(parameter.GetCustomAttributes(), key, parent as AngularOptions),
+ Options.GlobalKey => new AngularOptions(parent as AngularOptions, null, "global"),
+ _ => new AngularOptions(parent as AngularOptions, null, key)
+ // _ => throw new InvalidOperationException($"Could not create {nameof(AngularOptions)} {key.GetType()}")
+ };
+ }
+
+ private AngularOptions CreateFromCustomAttributes(IEnumerable customAttributes, object key, AngularOptions parent)
+ {
+ AngularOptions options = new(parent, null, key);
+ foreach (Attribute attribute in customAttributes)
+ {
+ switch (attribute)
+ {
+ case GenerateServiceOutputAttribute serviceOutputAttribute:
+ options.ServiceOutput = serviceOutputAttribute.RelativePath;
+ break;
+ case GenerateModelOutputAttribute modelOutputAttribute:
+ options.ModelOutput = modelOutputAttribute.RelativePath;
+ break;
+ }
+ }
+ return options;
+ }
+}
diff --git a/Angular/Writers/AngularModelWriter.cs b/Angular/Writers/AngularModelWriter.cs
index fe77fe0b..7d26c9a0 100644
--- a/Angular/Writers/AngularModelWriter.cs
+++ b/Angular/Writers/AngularModelWriter.cs
@@ -1,29 +1,24 @@
using System.Collections.Generic;
using System.Linq;
-using KY.Generator.Angular.Configurations;
-using KY.Generator.Templates;
using KY.Generator.Transfer;
using KY.Generator.TypeScript.Transfer;
-namespace KY.Generator.Angular.Writers
+namespace KY.Generator.Angular.Writers;
+
+public class AngularModelWriter(TypeScriptModelWriter modelWriter, IEnumerable transferObjects, Options options)
{
- public class AngularModelWriter
+ public AngularModelWriter FormatNames()
{
- private readonly TypeScriptModelWriter modelWriter;
-
- public AngularModelWriter(TypeScriptModelWriter modelWriter)
- {
- this.modelWriter = modelWriter;
- }
+ modelWriter.FormatNames();
+ return this;
+ }
- public void Write(AngularWriteConfiguration configuration, List transferObjects, List files)
+ public void Write(string relativePath)
+ {
+ foreach (ModelTransferObject model in transferObjects.OfType())
{
- if (configuration.Model != null)
- {
- configuration.Model.FormatNames = configuration.FormatNames;
- configuration.Model.OutputId = configuration.OutputId;
- this.modelWriter.Write(configuration.Model, transferObjects).ForEach(files.Add);
- }
+ AngularOptions angularOptions = options.Get(model);
+ modelWriter.Write(relativePath ?? angularOptions.ModelOutput ?? "/ClientApp/src/app/models");
}
}
}
diff --git a/Angular/Writers/AngularPackageBuilder.cs b/Angular/Writers/AngularPackageBuilder.cs
new file mode 100644
index 00000000..e7afebff
--- /dev/null
+++ b/Angular/Writers/AngularPackageBuilder.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using KY.Core;
+using KY.Core.DataAccess;
+
+namespace KY.Generator.Angular.Writers
+{
+ public class AngularPackageBuilder
+ {
+ public void Build(string packagePath)
+ {
+ Logger.Trace("Build npm package. This can take a few minutes...");
+ StringBuilder builder = new();
+ builder.AppendLine($"cd {FileSystem.Combine(packagePath, "../..")}");
+ builder.AppendLine(packagePath.Substring(0, 2));
+ builder.AppendLine($"npm run build");
+ if (!CommandLineHelper.RunWithTrace(builder))
+ {
+ Logger.Error("Package build failed. See error above...");
+ }
+ }
+
+ public void Publish(string packagePath)
+ {
+ Logger.Trace("Publish npm package. This can take a few minutes...");
+ StringBuilder builder = new();
+ builder.AppendLine($"cd {FileSystem.Combine(packagePath, "../..")}");
+ builder.AppendLine(packagePath.Substring(0, 2));
+ builder.AppendLine($"npm run publish");
+ if (!CommandLineHelper.RunWithTrace(builder))
+ {
+ Logger.Error("Package publish failed. See error above...");
+ }
+ }
+
+ public void PublishLocal(string packagePath)
+ {
+ Logger.Trace("Publish npm package local. This can take a few minutes...");
+ StringBuilder builder = new();
+ builder.AppendLine($"cd {FileSystem.Combine(packagePath, "../..")}");
+ builder.AppendLine(packagePath.Substring(0, 2));
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ builder.AppendLine($"npm run publish:local:linux");
+ }
+ else
+ {
+ builder.AppendLine($"npm run publish:local:windows");
+ }
+ if (!CommandLineHelper.RunWithTrace(builder))
+ {
+ Logger.Error("Package local publish failed. See error above...");
+ }
+ }
+ }
+}
diff --git a/Angular/Writers/AngularPackageWriter.cs b/Angular/Writers/AngularPackageWriter.cs
new file mode 100644
index 00000000..4ec3b6c4
--- /dev/null
+++ b/Angular/Writers/AngularPackageWriter.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using KY.Core;
+using KY.Core.DataAccess;
+using KY.Generator.Angular.Commands;
+using KY.Generator.Angular.Models;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace KY.Generator.Angular.Writers
+{
+ public class AngularPackageWriter
+ {
+ public const string BasePackageName = "package";
+
+ public void Write(string name, string fullName, string version, string packagePath, List dependsOn, string cliVersion, string servicePath, string modelPath, IncrementVersion incrementVersion, bool versionFromNpm)
+ {
+ if (!InitializeProject(dependsOn, packagePath, name, cliVersion, servicePath, modelPath))
+ {
+ return;
+ }
+ if (!UpdateProjectPackageJson(name, fullName, version, dependsOn, packagePath, incrementVersion, versionFromNpm))
+ {
+ return;
+ }
+ if (!UpdatePackageJson(packagePath, name))
+ {
+ return;
+ }
+ }
+
+ private static bool InitializeProject(List dependsOn, string packagePath, string name, string cliVersion, string servicePath, string modelPath)
+ {
+ if (FileSystem.FileExists(packagePath, "../../angular.json"))
+ {
+ return true;
+ }
+ cliVersion = cliVersion != null ? "@" + cliVersion.TrimStart('@') : null;
+ Logger.Trace("Prepare angular workspace and create a default npm package. This can take a few minutes...");
+ StringBuilder builder = new();
+ builder.AppendLine($"cd {FileSystem.Combine(packagePath, "../../..")}");
+ builder.AppendLine(packagePath.Substring(0, 2));
+ builder.AppendLine($"npx -p @angular/cli{cliVersion} ng new {BasePackageName} --create-application false --strict=false");
+ builder.AppendLine($"cd {BasePackageName}");
+ if (dependsOn.Count > 0)
+ {
+ IEnumerable dependsOnNames = dependsOn.Select(package => $"{package.Name}@{package.Version}");
+ builder.AppendLine($"npm i {string.Join(" ", dependsOnNames)} --save");
+ }
+ builder.AppendLine($"npm run-script ng g library {name}");
+ if (!CommandLineHelper.RunWithTrace(builder))
+ {
+ Logger.Error("Prepare package failed. See error above...");
+ return false;
+ }
+ string sourcePath = FileSystem.Combine(packagePath, "src");
+ FileSystem.DeleteDirectory(sourcePath, "lib");
+ modelPath = FileSystem.Combine("./lib", modelPath).Replace(FileSystem.DirectorySeparator(), "/");
+ servicePath = FileSystem.Combine("./lib", servicePath).Replace(FileSystem.DirectorySeparator(), "/");
+ FileSystem.WriteAllText(FileSystem.Combine(sourcePath, "public-api.ts"), $"export * from '{modelPath}';" + Environment.NewLine + $"export * from '{servicePath}';" + Environment.NewLine);
+ return true;
+ }
+
+ private static bool UpdateProjectPackageJson(string name, string fullName, string version, List dependsOn, string packagePath, IncrementVersion incrementVersion, bool versionFromNpm)
+ {
+ Logger.Trace("Update package.json...");
+ string packageJsonPath = FileSystem.Combine(packagePath, "package.json");
+ if (!FileSystem.FileExists(packageJsonPath))
+ {
+ Logger.Error("package.json not found. Try to delete the whole package folder");
+ return false;
+ }
+ JObject packageJson = JsonConvert.DeserializeObject(FileSystem.ReadAllText(packageJsonPath));
+ JProperty nameProperty = packageJson.Property("name");
+ JProperty versionProperty = packageJson.Property("version");
+ JObject peerDependencies = packageJson.Property("peerDependencies")?.Value as JObject;
+ if (nameProperty == null || versionProperty == null || peerDependencies == null)
+ {
+ Logger.Error("Invalid package.json structure. Try to delete the whole package folder");
+ return false;
+ }
+ nameProperty.Value = fullName;
+ versionProperty.Value = UpdateVersion(fullName, version, versionProperty.Value.ToString(), incrementVersion, versionFromNpm);
+ foreach (AngularPackageDependsOnParameter package in dependsOn)
+ {
+ peerDependencies[package.Name] = package.Version;
+ }
+ Logger.Trace("Write package.json to disk...");
+ FileSystem.WriteAllText(packageJsonPath, JsonConvert.SerializeObject(packageJson, Formatting.Indented));
+ return true;
+ }
+
+ private static bool UpdatePackageJson(string packagePath, string name)
+ {
+ Logger.Trace("Add some scripts...");
+ string packageJsonPath = FileSystem.Combine(packagePath, "../../package.json");
+ if (!FileSystem.FileExists(packageJsonPath))
+ {
+ Logger.Error("package.json not found. Try to delete the whole package folder");
+ return false;
+ }
+ JObject packageJson = JsonConvert.DeserializeObject(FileSystem.ReadAllText(packageJsonPath));
+ JObject scriptsProperty = packageJson.Property("scripts")?.Value as JObject;
+ if (scriptsProperty == null)
+ {
+ Logger.Error("Invalid package.json structure. Try to delete the whole package folder");
+ return false;
+ }
+ if (scriptsProperty["build"]?.Value() == "ng build")
+ {
+ scriptsProperty["build"] = $"ng build {name}";
+ }
+ scriptsProperty["publish"] ??= $"cd ./dist/{name} && npm publish && cd ../..";
+ scriptsProperty["publish:local:linux"] ??= $"cd ./dist/{name} && npm pack && cp *.tgz ../../ && cd ../..";
+ scriptsProperty["publish:local:windows"] ??= $"cd ./dist/{name} && npm pack && copy *.tgz ..\\..\\ && cd ../..";
+ Logger.Trace("Write package.json to disk...");
+ FileSystem.WriteAllText(packageJsonPath, JsonConvert.SerializeObject(packageJson, Formatting.Indented));
+ return true;
+ }
+
+ private static string UpdateVersion(string fullName, string templateVersionString, string packageJsonVersionString, IncrementVersion incrementVersion, bool versionFromNpm)
+ {
+ SemanticVersion packageJsonVersion = new(packageJsonVersionString);
+ SemanticVersion templateVersion = new(templateVersionString);
+ if (versionFromNpm)
+ {
+ Logger.Trace("Read version from npm...");
+ if (!CommandLineHelper.RunWithResult($"npm view {fullName} version", out string npmVersionString))
+ {
+ return templateVersionString;
+ }
+ SemanticVersion npmVersion = new(npmVersionString);
+ if (templateVersion.Major > npmVersion.Major
+ || templateVersion.Major == npmVersion.Major && templateVersion.Minor > npmVersion.Minor
+ || templateVersion.Major == npmVersion.Major && templateVersion.Minor == npmVersion.Minor && templateVersion.Build > npmVersion.Build
+ )
+ {
+ return templateVersionString;
+ }
+ return IncrementVersionBy(templateVersion, npmVersion, incrementVersion);
+ }
+ return IncrementVersionBy(templateVersion, packageJsonVersion, incrementVersion);
+ }
+
+ private static string IncrementVersionBy(SemanticVersion templateVersion, SemanticVersion currentVersion, IncrementVersion incrementVersion)
+ {
+ switch (incrementVersion)
+ {
+ case IncrementVersion.None:
+ return templateVersion.ToString();
+ case IncrementVersion.Major:
+ return new SemanticVersion(currentVersion.Major + 1, 0, 0).ToString();
+ case IncrementVersion.Minor:
+ return new SemanticVersion(currentVersion.Major, currentVersion.Minor + 1, 0).ToString();
+ case IncrementVersion.Patch:
+ return new SemanticVersion(currentVersion.Major, currentVersion.Minor, currentVersion.Build + 1).ToString();
+ default:
+ throw new ArgumentOutOfRangeException(nameof(incrementVersion), incrementVersion, null);
+ }
+ }
+ }
+}
diff --git a/Angular/Writers/AngularServiceWriter.cs b/Angular/Writers/AngularServiceWriter.cs
index f1415336..03f56e5b 100644
--- a/Angular/Writers/AngularServiceWriter.cs
+++ b/Angular/Writers/AngularServiceWriter.cs
@@ -1,11 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using KY.Core;
+using KY.Core;
using KY.Core.DataAccess;
using KY.Generator.Angular.Commands;
using KY.Generator.Angular.Configurations;
-using KY.Generator.Configurations;
using KY.Generator.Extensions;
using KY.Generator.Languages;
using KY.Generator.Mappings;
@@ -18,634 +14,749 @@
using KY.Generator.TypeScript.Extensions;
using KY.Generator.TypeScript.Languages;
using KY.Generator.TypeScript.Templates;
+using KY.Generator.TypeScript.Templates.Extensions;
-namespace KY.Generator.Angular.Writers
+namespace KY.Generator.Angular.Writers;
+
+public class AngularServiceWriter : TransferWriter
{
- public class AngularServiceWriter : TransferWriter
- {
- private const string apiVersionKey = "{version:apiVersion}";
+ private const string apiVersionKey = "{version:apiVersion}";
+ private readonly List transferObjects;
+ private readonly List files;
- public AngularServiceWriter(ITypeMapping typeMapping)
- : base(typeMapping)
- { }
+ public AngularServiceWriter(Options options, ITypeMapping typeMapping, List transferObjects, List files)
+ : base(options, typeMapping)
+ {
+ this.transferObjects = transferObjects;
+ this.files = files;
+ }
- public virtual void Write(AngularWriteConfiguration configuration, List transferObjects, List files)
+ public virtual void Write(AngularWriteConfiguration configuration)
+ {
+ Logger.Trace("Generate angular service for ASP.NET controller...");
+ GeneratorOptions generatorOptions = this.Options.Get();
+ if (!generatorOptions.Language.IsTypeScript())
{
- Logger.Trace("Generate angular service for ASP.NET controller...");
- if (!configuration.Language.IsTypeScript())
- {
- throw new InvalidOperationException($"Can not generate service for ASP.NET controller for language {configuration.Language?.Name ?? "Empty"}");
- }
- if (configuration.Model?.RelativePath == null && configuration.Service.RelativePath?.Count(x => x == '/' || x == '\\') > 1)
- {
- Logger.Warning("No model path found for Angular Service command. This may lead to wrong model imports!");
- }
- string httpClient = configuration.Service.HttpClient?.Name ?? "HttpClient";
- string httpClientImport = configuration.Service.HttpClient?.Import ?? "@angular/common/http";
- Dictionary actionTypeMapping = new()
- {
- { HttpServiceActionTypeTransferObject.Get, configuration.Service?.HttpClient?.Get ?? "get" },
- { HttpServiceActionTypeTransferObject.Post, configuration.Service?.HttpClient?.Post ?? "post" },
- { HttpServiceActionTypeTransferObject.Put, configuration.Service?.HttpClient?.Put ?? "put" },
- { HttpServiceActionTypeTransferObject.Patch, configuration.Service?.HttpClient?.Patch ?? "patch" },
- { HttpServiceActionTypeTransferObject.Delete, configuration.Service?.HttpClient?.Delete ?? "delete" }
- };
- Dictionary actionTypeOptions = new()
- {
- { HttpServiceActionTypeTransferObject.Get, configuration.Service?.HttpClient?.HasGetOptions },
- { HttpServiceActionTypeTransferObject.Post, configuration.Service?.HttpClient?.HasPostOptions },
- { HttpServiceActionTypeTransferObject.Put, configuration.Service?.HttpClient?.HasPutOptions },
- { HttpServiceActionTypeTransferObject.Patch, configuration.Service?.HttpClient?.HasPatchOptions },
- { HttpServiceActionTypeTransferObject.Delete, configuration.Service?.HttpClient?.HasDeleteOptions }
- };
- foreach (HttpServiceTransferObject controller in transferObjects.OfType())
+ throw new InvalidOperationException($"Can not generate service for ASP.NET controller for language {generatorOptions.Language?.Name ?? "Empty"}");
+ }
+ if (configuration.Model?.RelativePath == null && configuration.Service.RelativePath?.Count(x => x == '/' || x == '\\') > 1)
+ {
+ Logger.Warning("No model path found for Angular Service command. This may lead to wrong model imports!");
+ }
+ string httpClient = configuration.Service.HttpClient?.Name ?? "HttpClient";
+ string httpClientImport = configuration.Service.HttpClient?.Import ?? "@angular/common/http";
+ Dictionary actionTypeMapping = new()
+ {
+ { HttpServiceActionTypeTransferObject.Get, configuration.Service?.HttpClient?.Get ?? "get" },
+ { HttpServiceActionTypeTransferObject.Post, configuration.Service?.HttpClient?.Post ?? "post" },
+ { HttpServiceActionTypeTransferObject.Put, configuration.Service?.HttpClient?.Put ?? "put" },
+ { HttpServiceActionTypeTransferObject.Patch, configuration.Service?.HttpClient?.Patch ?? "patch" },
+ { HttpServiceActionTypeTransferObject.Delete, configuration.Service?.HttpClient?.Delete ?? "delete" }
+ };
+ Dictionary actionTypeOptions = new()
+ {
+ { HttpServiceActionTypeTransferObject.Get, configuration.Service?.HttpClient?.HasGetOptions },
+ { HttpServiceActionTypeTransferObject.Post, configuration.Service?.HttpClient?.HasPostOptions },
+ { HttpServiceActionTypeTransferObject.Put, configuration.Service?.HttpClient?.HasPutOptions },
+ { HttpServiceActionTypeTransferObject.Patch, configuration.Service?.HttpClient?.HasPatchOptions },
+ { HttpServiceActionTypeTransferObject.Delete, configuration.Service?.HttpClient?.HasDeleteOptions }
+ };
+ foreach (HttpServiceTransferObject controller in this.transferObjects.OfType())
+ {
+ GeneratorOptions controllerOptions = this.Options.Get(controller);
+ Dictionary mapping = new();
+ string controllerName = controller.Name.TrimEnd("Controller");
+ string className = configuration.Service.Name?.Replace("{0}", controllerName) ?? controllerName + "Service";
+ FileTemplate file = this.files.AddFile(configuration.Service.RelativePath, controllerOptions)
+ .WithName(Formatter.FormatFile(className, controllerOptions, "service"));
+ ClassTemplate classTemplate = file.AddNamespace(string.Empty)
+ .AddClass(className)
+ .FormatName(controllerOptions, true)
+ .FormatPrefix(controllerOptions)
+ .WithUsing(httpClient, httpClientImport)
+ .WithUsing("Injectable", "@angular/core")
+ .WithUsing("Observable", "rxjs")
+ .WithUsing("Subject", "rxjs")
+ .WithAttribute("Injectable", Code.AnonymousObject().WithProperty("providedIn", Code.String("root")));
+ FieldTemplate httpField = classTemplate.AddField("http", Code.Type(httpClient)).Readonly().FormatName(controllerOptions);
+ FieldTemplate serviceUrlField = classTemplate.AddField("serviceUrlValue", Code.Type("string")).FormatName(controllerOptions).Default(Code.String(string.Empty));
+ FieldTemplate httpOptionsField = classTemplate.AddField("httpOptions", Code.Type("{}")).Public().FormatName(controllerOptions).Default(Code.Local("{}"));
+ PropertyTemplate serviceUrlProperty = classTemplate.AddProperty("serviceUrl", Code.Type("string"))
+ .WithGetter(Code.Return(Code.This().Field(serviceUrlField)))
+ .WithSetter(Code.This().Field(serviceUrlField).Assign(Code.Local("value").Method("replace", Code.TypeScript(@"/\/+$/"), Code.String(""))).Close());
+ classTemplate.AddConstructor().WithParameter(Code.Type(httpClient), "http")
+ .WithCode(Code.This().Field(httpField).Assign(Code.Local("http")).Close())
+ .WithCode(Code.This().Property(serviceUrlProperty).Assign(Code.Local("document").Property("baseURI").NullCoalescing(Code.String(string.Empty).Close())));
+
+ List convertDateMethods = new();
+ string relativeModelPath = FileSystem.RelativeTo(configuration.Model?.RelativePath ?? ".", configuration.Service.RelativePath);
+ relativeModelPath = string.IsNullOrEmpty(relativeModelPath) ? "." : relativeModelPath;
+ bool addAppendMethod = false;
+ bool addAppendDateMethod = false;
+ bool appendConvertDateMethod = false;
+ foreach (HttpServiceActionTransferObject action in controller.Actions)
{
- IMappableLanguage controllerLanguage = controller.Language as IMappableLanguage;
- IMappableLanguage configurationLanguage = configuration.Language as IMappableLanguage;
- Dictionary mapping = new Dictionary();
- string controllerName = controller.Name.TrimEnd("Controller");
- FileTemplate file = files.AddFile(configuration.Service.RelativePath, configuration.AddHeader, configuration.OutputId)
- .WithType("service");
- ClassTemplate classTemplate = file.AddNamespace(string.Empty)
- .AddClass(configuration.Service.Name?.Replace("{0}", controllerName) ?? controllerName + "Service")
- .FormatName(configuration, true)
- .WithUsing(httpClient, httpClientImport)
- .WithUsing("Injectable", "@angular/core")
- .WithUsing("Observable", "rxjs")
- .WithUsing("Subject", "rxjs")
- .WithAttribute("Injectable", Code.AnonymousObject().WithProperty("providedIn", Code.String("root")));
- FieldTemplate httpField = classTemplate.AddField("http", Code.Type(httpClient)).Readonly().FormatName(configuration);
- FieldTemplate serviceUrlField = classTemplate.AddField("serviceUrlValue", Code.Type("string")).FormatName(configuration).Default(Code.String(string.Empty));
- PropertyTemplate serviceUrlProperty = classTemplate.AddProperty("serviceUrl", Code.Type("string"))
- .WithGetter(Code.Return(Code.This().Field(serviceUrlField)))
- .WithSetter(Code.This().Field(serviceUrlField).Assign(Code.Local("value").Method("replace", Code.TypeScript(@"/\/+$/"), Code.String(""))).Close());
- classTemplate.AddConstructor().WithParameter(Code.Type(httpClient), "http")
- .WithCode(Code.This().Field(httpField).Assign(Code.Local("http")).Close());
- string relativeModelPath = FileSystem.RelativeTo(configuration.Model?.RelativePath ?? ".", configuration.Service.RelativePath);
- relativeModelPath = string.IsNullOrEmpty(relativeModelPath) ? "." : relativeModelPath;
- bool appendConvertAnyMethod = false;
- bool appendConvertFromDateMethod = false;
- bool appendConvertToDateMethod = false;
- foreach (HttpServiceActionTransferObject action in controller.Actions)
- {
- string subjectName = action.Parameters.Any(x => x.Name == "subject") ? "rxjsSubject" : "subject";
- bool isEnumerable = action.ReturnType.IsEnumerable();
- bool isGuidReturnType = action.ReturnType.Name.Equals(nameof(Guid), StringComparison.CurrentCultureIgnoreCase);
- bool isDateReturnType = action.ReturnType.Name.Equals(nameof(DateTime), StringComparison.CurrentCultureIgnoreCase);
- bool isDateArrayReturnType = isEnumerable && action.ReturnType.Generics.Count == 1 && action.ReturnType.Generics.First().Type.Name.Equals(nameof(DateTime), StringComparison.CurrentCultureIgnoreCase);
- bool isStringReturnType = action.ReturnType.Name.Equals(nameof(String), StringComparison.CurrentCultureIgnoreCase);
- ICodeFragment errorCode = Code.Lambda("error", Code.Local(subjectName).Method("error", Code.Local("error")));
- if (controllerLanguage != null && configurationLanguage != null)
+ string subjectName = action.Parameters.Any(x => x.Name == "subject") ? "rxjsSubject" : "subject";
+ bool isEnumerable = action.ReturnType.IsEnumerable();
+ bool isGuidReturnType = action.ReturnType.Name.Equals(nameof(Guid), StringComparison.CurrentCultureIgnoreCase);
+ bool isDateReturnType = action.ReturnType.Name.Equals(nameof(DateTime), StringComparison.CurrentCultureIgnoreCase);
+ bool isDateArrayReturnType = isEnumerable && action.ReturnType.Generics.Count == 1 && action.ReturnType.Generics.First().Type.Name.Equals(nameof(DateTime), StringComparison.CurrentCultureIgnoreCase);
+ bool isStringReturnType = action.ReturnType.Name.Equals(nameof(String), StringComparison.CurrentCultureIgnoreCase);
+ ICodeFragment errorCode = Code.Lambda("error", Code.Local(subjectName).Method("error", Code.Local("error")));
+ if (controller.Language != null && controllerOptions.Language != null)
+ {
+ this.MapType(controller.Language, controllerOptions.Language, action.ReturnType);
+ }
+ TypeTemplate returnType = action.ReturnType.ToTemplate();
+ TypeTransferObject returnModelType = isEnumerable ? action.ReturnType.Generics.First().Type : action.ReturnType;
+ ModelTransferObject returnModel = returnModelType as ModelTransferObject ?? this.transferObjects.OfType().FirstOrDefault(x => x.Equals(returnModelType));
+ this.AddUsing(action.ReturnType, classTemplate, controllerOptions, relativeModelPath);
+ TypeTemplate aliasType = null;
+ if (returnType.Name == "unknown")
+ {
+ aliasType = Code.Type("TDefault");
+ returnType = aliasType;
+ }
+ MethodTemplate methodTemplate = classTemplate.AddMethod(action.Name, Code.Generic("Observable", returnType))
+ .FormatName(controllerOptions);
+ if (aliasType != null)
+ {
+ methodTemplate.WithGeneric(aliasType.Name, Code.Type("unknown"));
+ }
+ TypeTemplate subjectType = Code.Generic("Subject", returnType);
+ methodTemplate.WithCode(Code.Declare(subjectType, subjectName, Code.New(subjectType)));
+ foreach (HttpServiceActionParameterTransferObject parameter in action.Parameters)
+ {
+ if (controller.Language != null && controllerOptions.Language != null)
{
- this.MapType(controllerLanguage, configurationLanguage, action.ReturnType);
+ this.MapType(controller.Language, controllerOptions.Language, parameter.Type);
}
- TypeTemplate returnType = action.ReturnType.ToTemplate();
- TypeTransferObject returnModelType = isEnumerable ? action.ReturnType.Generics.First().Type : action.ReturnType;
- ModelTransferObject returnModel = returnModelType as ModelTransferObject ?? transferObjects.OfType().FirstOrDefault(x => x.Equals(returnModelType));
- this.AddUsing(action.ReturnType, classTemplate, configuration, relativeModelPath);
- TypeTemplate aliasType = null;
- if (returnType.Name == "unknown")
+ this.AddUsing(parameter.Type, classTemplate, controllerOptions, relativeModelPath);
+ string parameterName = this.GetAllowedName(controllerOptions.Language, parameter.Name);
+ ParameterTemplate parameterTemplate = methodTemplate.AddParameter(parameter.Type.ToTemplate(), parameterName).FormatName(controllerOptions);
+ if (parameter.IsOptional)
{
- aliasType = Code.Type("TDefault");
- returnType = aliasType;
+ parameterTemplate.Optional();
}
- MethodTemplate methodTemplate = classTemplate.AddMethod(action.Name, Code.Generic("Observable", returnType))
- .FormatName(configuration);
- if (aliasType != null)
+ mapping.Add(parameter, parameterTemplate);
+ }
+ if (actionTypeOptions[action.Type]?.HasHttpOptions ?? true)
+ {
+ methodTemplate.AddParameter(Code.Type("{}"), "httpOptions").Optional();
+ if (isStringReturnType)
{
- methodTemplate.WithGeneric(aliasType.Name, Code.Type("unknown"));
+ methodTemplate.WithCode(Code.TypeScript("httpOptions = { responseType: 'text', ...this.httpOptions, ...httpOptions}").Close());
}
- TypeTemplate subjectType = Code.Generic("Subject", returnType);
- methodTemplate.WithCode(Code.Declare(subjectType, subjectName, Code.New(subjectType)));
- foreach (HttpServiceActionParameterTransferObject parameter in action.Parameters)
+ else
{
- if (controllerLanguage != null && configurationLanguage != null)
- {
- this.MapType(controllerLanguage, configurationLanguage, parameter.Type);
- }
- this.AddUsing(parameter.Type, classTemplate, configuration, relativeModelPath);
- string parameterName = this.GetAllowedName(configuration.Language, parameter.Name);
- ParameterTemplate parameterTemplate = methodTemplate.AddParameter(parameter.Type.ToTemplate(), parameterName).FormatName(configuration);
- if (parameter.IsOptional)
- {
- parameterTemplate.Optional();
- }
- mapping.Add(parameter, parameterTemplate);
- if (action.Type == HttpServiceActionTypeTransferObject.Get && parameter.Type.Name == "Array")
- {
- methodTemplate.WithCode(Code.Declare(
- Code.Type("string"),
- $"{parameterTemplate.Name}Join",
- Code.Local(parameterTemplate).Method("map", Code.Lambda(new[] { "x", "index" },
- Code.InlineIf(Code.Local("index"),
- Code.String($"{parameter.Name}=").Append(Code.This().Method("convertAny", Code.Local("x"))),
- Code.This().Method("convertAny", Code.Local("x")))
- )).Method("join", Code.String("&"))));
- }
+ methodTemplate.WithCode(Code.TypeScript("httpOptions = { ...this.httpOptions, ...httpOptions}").Close());
}
- if (actionTypeOptions[action.Type]?.HasHttpOptions ?? true)
+ }
+ if (isDateReturnType && isDateArrayReturnType)
+ {
+ appendConvertDateMethod = true;
+ }
+ string controllerRoute = controller.Route?.Trim('/').Replace("[controller]", controllerName.ToLower()) ?? controllerName.ToLower();
+ string actionRoute = action.Route?.TrimEnd('/').Replace("[action]", action.Name.ToLower()).Replace("[controller]", controllerName.ToLower());
+ string uri = actionRoute == null ? $"/{controllerRoute}" : actionRoute.StartsWith("/") ? actionRoute : $"/{controllerRoute}/{actionRoute}";
+
+ List inlineParameters = action.Parameters
+ .Where(x => (!x.FromBody || !action.CanHaveBodyParameter) && x.Inline)
+ .OrderBy(x => x.InlineIndex)
+ .ToList();
+ List urlParameters = action.Parameters
+ .Where(x => (!x.FromBody || !action.CanHaveBodyParameter) && !x.Inline && x.AppendName)
+ .ToList();
+ List urlDirectParameters = action.Parameters
+ .Where(x => (!x.FromBody || !action.CanHaveBodyParameter) && !x.Inline && !x.AppendName)
+ .ToList();
+ MultilineCodeFragment code = Code.Multiline();
+ bool hasReturnType = returnType.Name != "void" && returnType.Name != "Task";
+ ExecuteMethodTemplate nextMethod = Code.Local(subjectName).Method("next");
+ if (hasReturnType)
+ {
+ LocalVariableTemplate localCode = Code.Local("result");
+ ICodeFragment nextCode = localCode;
+ if (isGuidReturnType)
{
- methodTemplate.AddParameter(Code.Type("{}"), "httpOptions").Optional();
- if (isStringReturnType)
- {
- methodTemplate.WithCode(Code.TypeScript("httpOptions = { responseType: 'text', ...httpOptions}").Close());
- }
+ nextCode = localCode.NullConditional().Method("replace", Code.TypeScript("/(^\"|\"$)/g"), Code.String(string.Empty));
}
- if (isDateReturnType && isDateArrayReturnType)
+ if (isDateReturnType)
{
- appendConvertToDateMethod = true;
+ nextCode = Code.This().Method("convertDate", nextCode);
}
- string uri = ("/" + (controller.Route?.Replace("[controller]", controllerName.ToLower()).TrimEnd('/') ?? controllerName.ToLower()) + "/" + action.Route?.Replace("[action]", action.Name.ToLower())).TrimEnd('/');
-
- List inlineParameters = action.Parameters.Where(x => !x.FromBody && x.Inline).OrderBy(x => x.InlineIndex).ToList();
- List urlParameters = action.Parameters.Where(x => !x.FromBody && !x.Inline && x.AppendName).ToList();
- List urlDirectParameters = action.Parameters.Where(x => !x.FromBody && !x.Inline && !x.AppendName).ToList();
- MultilineCodeFragment code = Code.Multiline();
- bool hasReturnType = returnType.Name != "void" && returnType.Name != "Task";
- ExecuteMethodTemplate nextMethod = Code.Local(subjectName).Method("next");
- if (hasReturnType)
+ if (isDateArrayReturnType)
{
- LocalVariableTemplate localCode = Code.Local("result");
- ICodeFragment nextCode = localCode;
- if (isGuidReturnType)
- {
- nextCode = localCode.Method("replace", Code.TypeScript("/(^\"|\"$)/g"), Code.String(string.Empty));
- }
- if (isDateReturnType)
- {
- nextCode = Code.This().Method("convertToDate", nextCode);
- }
- if (isDateArrayReturnType)
- {
- nextCode = localCode.Method("map", Code.Lambda("entry", Code.This().Method("convertToDate", Code.Local("entry"))));
- }
- nextMethod.WithParameter(nextCode);
- appendConvertToDateMethod = this.WriteDateFixes(returnModel, isEnumerable, code, new List { "result" }, new List { returnModel }, transferObjects, configuration) || appendConvertToDateMethod;
+ nextCode = localCode.Method("map", Code.Lambda("entry", Code.This().Method("convertDate", Code.Local("entry"))));
}
- if (action.FixCasingWithMapping)
+ nextMethod.WithParameter(Code.This().Method("fixUndefined", nextCode));
+ if (this.WriteDateFixes(classTemplate, convertDateMethods, returnModel, controllerOptions, relativeModelPath))
{
- IEnumerable members = (returnModel?.Fields ?? new List()).Concat(returnModel?.Properties ?? new List());
+ appendConvertDateMethod = true;
+ string methodName = $"convert{returnModel.Name.ToPascalCase()}Date";
if (isEnumerable)
{
- MultilineCodeFragment innerCode = new MultilineCodeFragment();
- foreach (MemberTransferObject member in members)
- {
- string formattedName = member is PropertyTransferObject ? Formatter.FormatProperty(member.Name, configuration) : Formatter.FormatField(member.Name, configuration);
- if (formattedName != member.Name)
- {
- innerCode.AddLine(Code.Local("entry").Field(formattedName).Assign(Code.Local("entry").Field(formattedName).Or().Local("entry").Index(Code.String(member.Name))).Close())
- .AddLine(Code.TypeScript($"delete entry['{member.Name}']").Close());
- }
- }
- code.AddLine(Code.If(Code.Local("result")).WithCode(Code.Local("result").Method("forEach", Code.Lambda("entry", innerCode))));
+ code.AddLine(Code.Local("result").Method("forEach", Code.Lambda("m",
+ Code.This().Method(methodName, Code.Local("m"))
+ )).Close());
}
else
{
- foreach (MemberTransferObject member in members)
- {
- string formattedName = member is PropertyTransferObject ? Formatter.FormatProperty(member.Name, configuration) : Formatter.FormatField(member.Name, configuration);
- if (formattedName != member.Name)
- {
- code.AddLine(Code.Local("result").Field(formattedName).Assign(Code.Local("result").Field(formattedName).Or().Local("result").Index(Code.String(member.Name))).Close())
- .AddLine(Code.TypeScript($"delete result['{member.Name}']").Close());
- }
- }
+ code.AddLine(Code.This().Method(methodName, Code.Local("result")).Close());
}
}
- code.AddLine(nextMethod.Close())
- .AddLine(Code.Local(subjectName).Method("complete").Close());
- ChainedCodeFragment parameterUrl = Code.This().Property(serviceUrlProperty);
- string actionVersion = action.Version ?? controller.Version;
- bool isUrlApiVersion = false;
- if (uri?.Contains(apiVersionKey) ?? false)
- {
- isUrlApiVersion = true;
- uri = uri.Replace(apiVersionKey, actionVersion);
- }
- foreach (HttpServiceActionParameterTransferObject parameter in inlineParameters)
- {
- string[] chunks = uri.Split(new[] { $"{{{parameter.Name}}}" }, StringSplitOptions.RemoveEmptyEntries);
- parameterUrl = parameterUrl.Append(Code.String(chunks[0])).Append(Code.Local(mapping[parameter]));
- uri = chunks.Length == 1 ? string.Empty : chunks[1];
- }
- if (!string.IsNullOrEmpty(uri))
- {
- parameterUrl = parameterUrl.Append(Code.String(uri));
- }
- bool isFirst = true;
- if (actionVersion != null && !isUrlApiVersion)
- {
- isFirst = false;
- parameterUrl = parameterUrl.Append(Code.String($"?api-version={actionVersion}"));
- }
- foreach (HttpServiceActionParameterTransferObject parameter in urlDirectParameters)
+ }
+ if (action.FixCasingWithMapping)
+ {
+ IEnumerable members = (returnModel?.Fields ?? new List()).Concat(returnModel?.Properties ?? new List());
+ if (isEnumerable)
{
- if (isFirst)
+ MultilineCodeFragment innerCode = new();
+ foreach (MemberTransferObject member in members)
{
- isFirst = false;
- parameterUrl = parameterUrl.Append(Code.String("?")).Append(Code.Local(parameter.Name));
+ string formattedName = member is PropertyTransferObject ? Formatter.FormatProperty(member.Name, controllerOptions) : Formatter.FormatField(member.Name, controllerOptions);
+ if (formattedName != member.Name)
+ {
+ innerCode.AddLine(Code.Local("entry").Field(formattedName).Assign(Code.Local("entry").Field(formattedName).Or().Local("entry").Index(Code.String(member.Name))).Close())
+ .AddLine(Code.TypeScript($"delete entry['{member.Name}']").Close());
+ }
}
- else
+ code.AddLine(Code.If(Code.Local("result")).WithCode(Code.Local("result").Method("forEach", Code.Lambda("entry", innerCode))));
+ }
+ else
+ {
+ foreach (MemberTransferObject member in members)
{
- parameterUrl = parameterUrl.Append(Code.String("&")).Append(Code.Local(parameter.Name));
+ string formattedName = member is PropertyTransferObject ? Formatter.FormatProperty(member.Name, controllerOptions) : Formatter.FormatField(member.Name, controllerOptions);
+ if (formattedName != member.Name)
+ {
+ code.AddLine(Code.Local("result").Field(formattedName).Assign(Code.Local("result").Field(formattedName).Or().Local("result").Index(Code.String(member.Name))).Close())
+ .AddLine(Code.TypeScript($"delete result['{member.Name}']").Close());
+ }
}
}
- foreach (HttpServiceActionParameterTransferObject parameter in urlParameters)
+ }
+ code.AddLine(nextMethod.Close())
+ .AddLine(Code.Local(subjectName).Method("complete").Close());
+ ExecutePropertyTemplate propertyTemplate = Code.This().Property(serviceUrlProperty);
+ DeclareTemplate urlTemplate = Code.Declare(Code.Type("string"), "url", propertyTemplate);
+ methodTemplate.WithCode(urlTemplate);
+ string actionVersion = action.Version ?? controller.Version;
+ bool isUrlApiVersion = false;
+ if (uri?.Contains(apiVersionKey) ?? false)
+ {
+ isUrlApiVersion = true;
+ uri = uri.Replace(apiVersionKey, actionVersion);
+ }
+ foreach (HttpServiceActionParameterTransferObject parameter in inlineParameters)
+ {
+ string[] chunks = uri.Split(new[] { $"{{{parameter.Name}}}" }, StringSplitOptions.RemoveEmptyEntries)
+ .Select(chunk => chunk.TrimEnd("/")).ToArray();
+ if (chunks[0].Length > 0)
{
- parameterUrl = parameterUrl.Append(isFirst ? Code.String($"?{parameter.Name}=") : Code.String($"&{parameter.Name}="));
- if (parameter.FromQuery && parameter.Type.Name == "Array")
+ if (propertyTemplate != null)
{
- appendConvertAnyMethod = true;
- parameterUrl = parameterUrl.Append(Code.This().Method("convertAny", Code.Local(mapping[parameter].Name + "Join")));
+ propertyTemplate.Append(Code.String(chunks[0]));
}
else
{
- if (parameter.Type.IgnoreNullable().Name == "Date")
- {
- appendConvertFromDateMethod = true;
- parameterUrl = parameterUrl.Append(Code.This().Method("convertFromDate", Code.Local(mapping[parameter])));
- }
- else
- {
- appendConvertAnyMethod = true;
- parameterUrl = parameterUrl.Append(Code.This().Method("convertAny", Code.Local(mapping[parameter])));
- }
+ methodTemplate.WithCode(Code.Local(urlTemplate).AppendAssign(Code.String(chunks[0])).Close());
}
- isFirst = false;
- }
- ChainedCodeFragment executeAction = Code.This().Field(httpField);
- List parameters = new() { parameterUrl };
- if (action.Parameters.Any(x => x.FromBody))
- {
- parameters.Add(Code.Local(action.Parameters.Single(x => x.FromBody).Name));
}
- if (actionTypeOptions[action.Type]?.HasHttpOptions ?? false)
- {
- parameters.Add(Code.Local("httpOptions"));
- }
- if (actionTypeOptions[action.Type]?.NotGeneric ?? false)
- {
- executeAction = executeAction.Method(actionTypeMapping[action.Type], parameters);
- }
- else if (actionTypeOptions[action.Type]?.ParameterGeneric ?? false)
+ propertyTemplate = null;
+ addAppendMethod = true;
+ methodTemplate.WithCode(Code.Local(urlTemplate).Assign(Code.This().Method("append", Code.Local(urlTemplate), Code.Local(mapping[parameter]), Code.Null(), Code.String("/"))).Close());
+ uri = chunks.Length == 1 ? string.Empty : chunks[1];
+ }
+ if (!string.IsNullOrEmpty(uri))
+ {
+ if (propertyTemplate == null)
{
- executeAction = executeAction.GenericMethod(actionTypeMapping[action.Type], Code.Type("unknown"), parameters.ToArray());
+ methodTemplate.WithCode(Code.Local(urlTemplate).AppendAssign(Code.String(uri)).Close());
}
else
{
- executeAction = executeAction.GenericMethod(actionTypeMapping[action.Type], returnType, parameters.ToArray());
+ propertyTemplate.Append(Code.String(uri));
+ propertyTemplate = null;
}
- LambdaTemplate lambda;
- if (actionTypeOptions[action.Type]?.ReturnsAny ?? false)
+ }
+ if (actionVersion != null && !isUrlApiVersion)
+ {
+ methodTemplate.WithCode(Code.Local(urlTemplate).AppendAssign(Code.String($"?api-version={actionVersion}")).Close());
+ }
+ foreach (HttpServiceActionParameterTransferObject parameter in urlDirectParameters)
+ {
+ addAppendMethod = true;
+ methodTemplate.WithCode(Code.Local(urlTemplate).Assign(Code.This().Method("append",
+ Code.Local(urlTemplate),
+ Code.Local(mapping[parameter]),
+ Code.String(parameter.Name))).Close());
+ }
+ foreach (HttpServiceActionParameterTransferObject parameter in urlParameters)
+ {
+ if (parameter.FromQuery && parameter.Type.Name == "Array")
{
- lambda = Code.Lambda(hasReturnType ? new ParameterTemplate(returnType, "result") : null, code);
+ addAppendMethod = true;
+ LambdaTemplate forEachLambda = Code.Lambda("entry", Code.Local(urlTemplate).Assign(
+ Code.This().Method("append",
+ Code.Local(urlTemplate),
+ Code.Local("entry"),
+ Code.String(parameter.Name)
+ )));
+ methodTemplate.WithCode(Code.Local(mapping[parameter]).NullConditional().Method("forEach", forEachLambda).Close());
}
else
{
- lambda = Code.Lambda(hasReturnType ? "result" : null, code);
+ string appendMethodName = "append";
+ if (parameter.Type.IgnoreNullable().Name == "Date")
+ {
+ addAppendDateMethod = true;
+ appendMethodName = "appendDate";
+ }
+ else
+ {
+ addAppendMethod = true;
+ }
+
+ methodTemplate.WithCode(Code.Local(urlTemplate).Assign(Code.This().Method(appendMethodName,
+ Code.Local(urlTemplate),
+ Code.Local(mapping[parameter]),
+ Code.String(parameter.Name))).Close());
}
- methodTemplate.WithCode(executeAction.Method("subscribe", lambda, errorCode).Close())
- .WithCode(Code.Return(Code.Local(subjectName)));
}
-
- if (appendConvertAnyMethod)
+ ChainedCodeFragment executeAction = Code.This().Field(httpField);
+ List parameters = new() { Code.Local(urlTemplate) };
+ if (action.CanHaveBodyParameter)
+ {
+ HttpServiceActionParameterTransferObject bodyParameter = action.Parameters.SingleOrDefault(x => x.FromBody);
+ parameters.Add(bodyParameter == null ? Code.Undefined() : Code.Local(mapping[bodyParameter]));
+ }
+ if (actionTypeOptions[action.Type]?.HasHttpOptions ?? false)
{
- this.AppendConvertAnyMethod(classTemplate);
+ parameters.Add(Code.Local("httpOptions"));
}
- if (appendConvertFromDateMethod)
+ if (actionTypeOptions[action.Type]?.NotGeneric ?? false)
{
- this.AppendConvertFromDateMethod(classTemplate);
+ executeAction = executeAction.Method(actionTypeMapping[action.Type], parameters);
}
- if (appendConvertToDateMethod)
+ else if (actionTypeOptions[action.Type]?.ParameterGeneric ?? false)
{
- this.AppendConvertToDateMethod(classTemplate);
+ executeAction = executeAction.GenericMethod(actionTypeMapping[action.Type], Code.Type("unknown"), parameters.ToArray());
}
+ else
+ {
+ executeAction = executeAction.GenericMethod(actionTypeMapping[action.Type], returnType, parameters.ToArray());
+ }
+ LambdaTemplate lambda;
+ if (actionTypeOptions[action.Type]?.ReturnsAny ?? false)
+ {
+ lambda = Code.Lambda(hasReturnType ? new ParameterTemplate(returnType, "result") : null, code);
+ }
+ else
+ {
+ lambda = Code.Lambda(hasReturnType ? "result" : null, code);
+ }
+ methodTemplate.WithCode(executeAction.Method("subscribe", lambda, errorCode).Close())
+ .WithCode(Code.Return(Code.Local(subjectName)));
}
- List hubs = transferObjects.OfType().ToList();
- FileTemplate connectionStatusFileTemplate = null;
- EnumTemplate connectionStatusEnum = null;
- if (hubs.Count > 0)
+
+ if (addAppendMethod || addAppendDateMethod)
{
- connectionStatusFileTemplate = files.AddFile(configuration.Model.RelativePath, configuration.AddHeader, configuration.OutputId);
- connectionStatusEnum = connectionStatusFileTemplate
- .AddNamespace(string.Empty)
- .AddEnum("ConnectionStatus")
- .FormatName(configuration)
- .AddValue("connecting")
- .AddValue("connected")
- .AddValue("sleeping")
- .AddValue("disconnected");
+ this.AddAppendMethod(classTemplate);
}
- foreach (SignalRHubTransferObject hub in hubs)
+ if (addAppendDateMethod)
{
- string relativeModelPath = FileSystem.RelativeTo(configuration.Model?.RelativePath ?? ".", configuration.Service.RelativePath);
- IMappableLanguage hubLanguage = hub.Language as IMappableLanguage;
- IMappableLanguage configurationLanguage = configuration.Language as IMappableLanguage;
- FileTemplate file = files.AddFile(configuration.Service.RelativePath, configuration.AddHeader, configuration.OutputId)
- .WithType("service");
- NamespaceTemplate namespaceTemplate = file.AddNamespace(string.Empty);
- ClassTemplate classTemplate = namespaceTemplate
- .AddClass(configuration.Service.Name?.Replace("{0}", hub.Name) ?? hub.Name + "Service")
- .FormatName(configuration, true)
- .WithUsing("Injectable", "@angular/core")
- .WithUsing("Subject", "rxjs")
- .WithUsing("Observable", "rxjs")
- .WithUsing("ReplaySubject", "rxjs")
- .WithUsing("filter", "rxjs/operators")
- .WithUsing("map", "rxjs/operators")
- .WithUsing("mergeMap", "rxjs/operators")
- .WithUsing("take", "rxjs/operators")
- .WithUsing("HubConnectionBuilder", "@microsoft/signalr")
- .WithUsing("HubConnection", "@microsoft/signalr")
- .WithUsing("IHttpConnectionOptions", "@microsoft/signalr")
- .WithUsing("LogLevel", "@microsoft/signalr")
- .WithUsing(connectionStatusEnum.Name, FileSystem.Combine(relativeModelPath, Formatter.FormatFile(connectionStatusFileTemplate.Name, configuration, true)).Replace("\\", "/"))
- .WithAttribute("Injectable", Code.AnonymousObject().WithProperty("providedIn", Code.String("root")));
- FieldTemplate isClosedField = classTemplate.AddField("isClosed", Code.Type("boolean"));
- FieldTemplate serviceUrlField = classTemplate.AddField("serviceUrl", Code.Type("string")).Public().FormatName(configuration).Default(Code.String(string.Empty));
- FieldTemplate optionsField = classTemplate.AddField("options", Code.Type("IHttpConnectionOptions")).Public().FormatName(configuration);
- FieldTemplate logLevelField = classTemplate.AddField("logLevel", Code.Type("LogLevel")).Public().FormatName(configuration).Default(Code.Static(Code.Type("LogLevel")).Field("Error"));
- FieldTemplate connectionField = classTemplate.AddField("connection", Code.Generic("ReplaySubject", Code.Type("HubConnection")));
- FieldTemplate timeoutsField = null;
- if (configuration.Service.Timeouts?.Count > 0)
- {
- timeoutsField = classTemplate.AddField("timeouts", Code.Generic("Array", Code.Type("number"))).Readonly()
- .Default(Code.TypeScript($"[{string.Join(", ", configuration.Service.Timeouts)}]"));
- }
- FieldTemplate statusSubjectField = classTemplate.AddField("statusSubject", Code.Generic("ReplaySubject", connectionStatusEnum.ToType())).Readonly()
- .Default(Code.New(Code.Generic("ReplaySubject", connectionStatusEnum.ToType()), Code.Number(1)));
- classTemplate.AddField("status$", Code.Generic("Observable", connectionStatusEnum.ToType())).FormatName(configuration).Readonly().Public()
- .Default(Code.This().Local(statusSubjectField).Method("asObservable"));
- MultilineCodeFragment createConnectionCode = Code.Multiline();
- MultilineCodeFragment errorCode = Code.Multiline();
- if (timeoutsField != null)
- {
- errorCode.AddLine(Code.If(Code.This().Field(isClosedField)).WithCode(Code.Return()))
- .AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local(connectionStatusEnum.Name).Field("sleeping")).Close())
- .AddLine(Code.Declare(Code.Type("number"), "timeout", Code.This().Field(timeoutsField).Index(Code.Local("trial"))))
- .AddLine(Code.Local("trial++").Close());
- if (configuration.Service.EndlessTries)
- {
- errorCode.AddLine(Code.Local("timeout").Assign(Code.Local("timeout").Or().This().Field(timeoutsField).Index(Code.This().Field(timeoutsField).Field("length").Subtract().Number(1)).Or().Number(0)).Close());
- }
- else
- {
- errorCode.AddLine(Code.If(Code.Local("timeout").Equals().Undefined())
- .WithCode(Code.This().Method("disconnect").Close())
- .WithCode(Code.Local("subject").Method("error", Code.Local("error")).Close()).WithCode(Code.Return()));
- }
- errorCode.AddLine(Code.Method("setTimeout",
- Code.Lambda(Code.Multiline()
- .AddLine(Code.If(Code.This().Field(isClosedField)).WithCode(Code.Return()))
- .AddLine(Code.Method("startConnection").Method("subscribe",
- Code.Lambda(Code.Multiline()
- .AddLine(Code.Local("subject").Method("next").Close())
- .AddLine(Code.Local("subject").Method("complete").Close())),
- Code.Lambda("innerError", Code.Local("subject").Method("error", Code.Local("innerError")))
- ))),
- Code.Local("timeout")
- ).Close());
+ this.AddAppendDateMethod(classTemplate);
+ }
+ if (appendConvertDateMethod)
+ {
+ this.AppendConvertDateMethod(classTemplate);
+ }
+ classTemplate.Methods.RemoveRange(convertDateMethods);
+ classTemplate.Methods.AddRange(convertDateMethods);
+ this.AppendFixUndefined(classTemplate);
+ }
+ List hubs = this.transferObjects.OfType().ToList();
+ FileTemplate connectionStatusFileTemplate = null;
+ EnumTemplate connectionStatusEnum = null;
+ if (hubs.Count > 0)
+ {
+ string className = "ConnectionStatus";
+ GeneratorOptions anyOptions = this.Options.Get(hubs.First());
+ connectionStatusFileTemplate = this.files.AddFile(configuration.Model.RelativePath, anyOptions)
+ .WithName(Formatter.FormatFile(className, anyOptions));
+ connectionStatusEnum = connectionStatusFileTemplate
+ .AddNamespace(string.Empty)
+ .AddEnum(className)
+ .FormatName(this.Options.Get(hubs.First()))
+ .AddValue("connecting")
+ .AddValue("connected")
+ .AddValue("sleeping")
+ .AddValue("disconnected");
+ }
+ foreach (SignalRHubTransferObject hub in hubs)
+ {
+ GeneratorOptions hubOptions = this.Options.Get(hub);
+ string relativeModelPath = FileSystem.RelativeTo(configuration.Model?.RelativePath ?? ".", configuration.Service.RelativePath);
+ string className = configuration.Service.Name?.Replace("{0}", hub.Name) ?? hub.Name + "Service";
+ FileTemplate file = this.files.AddFile(configuration.Service.RelativePath, hubOptions)
+ .WithName(Formatter.FormatFile(className, hubOptions, "service"));
+ NamespaceTemplate namespaceTemplate = file.AddNamespace(string.Empty);
+ ClassTemplate classTemplate = namespaceTemplate
+ .AddClass(className)
+ .FormatName(hubOptions, true)
+ .FormatPrefix(hubOptions)
+ .WithUsing("Injectable", "@angular/core")
+ .WithUsing("Subject", "rxjs")
+ .WithUsing("Observable", "rxjs")
+ .WithUsing("ReplaySubject", "rxjs")
+ .WithUsing("filter", "rxjs/operators")
+ .WithUsing("map", "rxjs/operators")
+ .WithUsing("mergeMap", "rxjs/operators")
+ .WithUsing("take", "rxjs/operators")
+ .WithUsing("HubConnectionBuilder", "@microsoft/signalr")
+ .WithUsing("HubConnection", "@microsoft/signalr")
+ .WithUsing("IHttpConnectionOptions", "@microsoft/signalr")
+ .WithUsing("LogLevel", "@microsoft/signalr")
+ .WithUsing(connectionStatusEnum.Name, FileSystem.Combine(relativeModelPath, connectionStatusFileTemplate.Name).Replace("\\", "/"))
+ .WithAttribute("Injectable", Code.AnonymousObject().WithProperty("providedIn", Code.String("root")));
+ FieldTemplate isClosedField = classTemplate.AddField("isClosed", Code.Type("boolean")).Default(Code.Boolean(true));
+ FieldTemplate serviceUrlField = classTemplate.AddField("serviceUrl", Code.Type("string")).Public().FormatName(hubOptions).Default(Code.String(string.Empty));
+ FieldTemplate optionsField = classTemplate.AddField("options", Code.Type("IHttpConnectionOptions")).Public().FormatName(hubOptions).Default(Code.AnonymousObject());
+ FieldTemplate logLevelField = classTemplate.AddField("logLevel", Code.Type("LogLevel")).Public().FormatName(hubOptions).Default(Code.Static(Code.Type("LogLevel")).Field("Error"));
+ FieldTemplate connectionField = classTemplate.AddField("connection", Code.Generic("ReplaySubject", Code.Type("HubConnection"))).Optional();
+ FieldTemplate timeoutsField = null;
+ if (configuration.Service.Timeouts?.Count > 0)
+ {
+ timeoutsField = classTemplate.AddField("timeouts", Code.Generic("Array", Code.Type("number"))).Readonly()
+ .Default(Code.TypeScript($"[{string.Join(", ", configuration.Service.Timeouts)}]"));
+ }
+ FieldTemplate statusSubjectField = classTemplate.AddField("statusSubject", Code.Generic("ReplaySubject", connectionStatusEnum.ToType())).Readonly()
+ .Default(Code.New(Code.Generic("ReplaySubject", connectionStatusEnum.ToType()), Code.Number(1)));
+ classTemplate.AddField("status$", Code.Generic("Observable", connectionStatusEnum.ToType())).FormatName(hubOptions).Readonly().Public()
+ .Default(Code.This().Local(statusSubjectField).Method("asObservable"));
+ MultilineCodeFragment createConnectionCode = Code.Multiline();
+ MultilineCodeFragment errorCode = Code.Multiline();
+ if (timeoutsField != null)
+ {
+ errorCode.AddLine(Code.If(Code.This().Field(isClosedField)).WithCode(Code.Return()))
+ .AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local(connectionStatusEnum.Name).Field("sleeping")).Close())
+ .AddLine(Code.Declare(Code.Type("number"), "timeout", Code.This().Field(timeoutsField).Index(Code.Local("trial"))))
+ .AddLine(Code.Local("trial++").Close());
+ if (configuration.Service.EndlessTries)
+ {
+ errorCode.AddLine(Code.Local("timeout").Assign(Code.Local("timeout").Or().This().Field(timeoutsField).Index(Code.This().Field(timeoutsField).Field("length").Subtract().Number(1)).Or().Number(0)).Close());
}
else
{
- errorCode.AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local(connectionStatusEnum.Name).Field("disconnected")).Close())
- .AddLine(Code.Local("subject").Method("error", Code.Local("error")).Close());
+ errorCode.AddLine(Code.If(Code.Local("timeout").Equals().Undefined())
+ .WithCode(Code.This().Method("disconnect").Close())
+ .WithCode(Code.Local("subject").Method("error", Code.Local("error")).Close()).WithCode(Code.Return()));
}
+ errorCode.AddLine(Code.Method("setTimeout",
+ Code.Lambda(Code.Multiline()
+ .AddLine(Code.If(Code.This().Field(isClosedField)).WithCode(Code.Return()))
+ .AddLine(Code.Method("startConnection").Method("subscribe",
+ Code.Lambda(Code.Multiline()
+ .AddLine(Code.Local("subject").Method("next").Close())
+ .AddLine(Code.Local("subject").Method("complete").Close())),
+ Code.Lambda("innerError", Code.Local("subject").Method("error", Code.Local("innerError")))
+ ))),
+ Code.Local("timeout")
+ ).Close());
+ }
+ else
+ {
+ errorCode.AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local(connectionStatusEnum.Name).Field("disconnected")).Close())
+ .AddLine(Code.Local("subject").Method("error", Code.Local("error")).Close());
+ }
- MethodTemplate connectMethod = classTemplate.AddMethod("Connect", Code.Generic("Observable", Code.Void())).FormatName(configuration)
- .WithComment("Connects to the hub via given serviceUrl.\nAutomatically reconnects on connection loss. \nIf timeout is configured, goes to sleeping state and reconnects after the timeout")
- .WithCode(Code.If(Code.Not().This().Local(serviceUrlField))
- .WithCode(Code.Throw(Code.Type("Error"), Code.String("serviceUrl can not be empty. Set it via service.serviceUrl."))))
- .WithCode(Code.If(Code.This().Field(connectionField).And().Not().This().Field(isClosedField))
- .WithCode(Code.Return(Code.This().Local("status$").Method("pipe",
- Code.Method("filter", Code.Lambda("status", Code.Local("status").Equals().Local("ConnectionStatus").Field("connected"))),
- Code.Method("take", Code.Number(1)),
- Code.Method("map", Code.Lambda(Code.AnonymousObject()))
- ))))
- .WithCode(Code.This().Field(isClosedField).Assign(Code.Boolean(false)).Close())
- .WithCode(Code.This().Field(connectionField).Assign(Code.InlineIf(Code.This().Field(connectionField), Code.This().Field(connectionField), Code.New(connectionField.Type, Code.Number(1)))).Close())
- .WithCode(Code.Declare(Code.Type("HubConnection"), "hubConnection", Code.New(Code.Type("HubConnectionBuilder"))
- .Method("withUrl", Code.This().Local(serviceUrlField), Code.This().Local(optionsField))
- .Method("configureLogging", Code.This().Field(logLevelField))
- .Method("build")))
- .WithCode(Code.Declare(Code.Type("() => Observable"), "startConnection", Code.Lambda(
- Code.Multiline()
- .AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local(connectionStatusEnum.Name).Local("connecting")).Close())
- .AddLine(Code.Declare(Code.Generic("Subject", Code.Void()), "subject", Code.New(Code.Generic("Subject", Code.Void()))))
- .AddLine(Code.Local("hubConnection").Method("start")
- .Method("then", Code.Lambda(Code.Multiline()
- .AddLine(Code.Local("subject").Method("next").Close())
- .AddLine(Code.Local("subject").Method("complete").Close())
- .AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local(connectionStatusEnum.Name).Field("connected")).Close())))
- .Method("catch", Code.Lambda("error", errorCode)).Close())
- .AddLine(Code.Return(Code.Local("subject")))
- )))
- .WithCode(createConnectionCode)
- .WithCode(Code.Local("hubConnection").Method("onclose", Code.Lambda(Code.Multiline()
- .AddLine(Code.If(Code.Not().This().Field(isClosedField))
- .WithCode(Code.Method("startConnection").Close())))
- ).Close())
- .WithCode(Code.This().Field(connectionField).Method("next", Code.Local("hubConnection")).Close())
- .WithCode(Code.Return(Code.Method("startConnection")));
+ MethodTemplate connectMethod = classTemplate.AddMethod("Connect", Code.Generic("Observable", Code.Void())).FormatName(hubOptions)
+ .WithComment("Connects to the hub via given serviceUrl.\nAutomatically reconnects on connection loss. \nIf timeout is configured, goes to sleeping state and reconnects after the timeout")
+ .WithCode(Code.If(Code.Not().This().Local(serviceUrlField))
+ .WithCode(Code.Throw(Code.Type("Error"), Code.String("serviceUrl can not be empty. Set it via service.serviceUrl."))))
+ .WithCode(Code.If(Code.This().Field(connectionField).And().Not().This().Field(isClosedField))
+ .WithCode(Code.Return(Code.This().Local("status$").Method("pipe",
+ Code.Method("filter", Code.Lambda("status", Code.Local("status").Equals().Local("ConnectionStatus").Field("connected"))),
+ Code.Method("take", Code.Number(1)),
+ Code.Method("map", Code.Lambda(Code.AnonymousObject()))
+ ))))
+ .WithCode(Code.This().Field(isClosedField).Assign(Code.Boolean(false)).Close())
+ .WithCode(Code.This().Field(connectionField).Assign(Code.InlineIf(Code.This().Field(connectionField), Code.This().Field(connectionField), Code.New(connectionField.Type, Code.Number(1)))).Close())
+ .WithCode(Code.Declare(Code.Type("HubConnection"), "hubConnection", Code.New(Code.Type("HubConnectionBuilder"))
+ .Method("withUrl", Code.This().Local(serviceUrlField), Code.This().Local(optionsField))
+ .Method("configureLogging", Code.This().Field(logLevelField))
+ .Method("build")))
+ .WithCode(Code.Declare(Code.Type("() => Observable"), "startConnection", Code.Lambda(
+ Code.Multiline()
+ .AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local(connectionStatusEnum.Name).Local("connecting")).Close())
+ .AddLine(Code.Declare(Code.Generic("Subject", Code.Void()), "subject", Code.New(Code.Generic("Subject", Code.Void()))))
+ .AddLine(Code.Local("hubConnection").Method("start")
+ .Method("then", Code.Lambda(Code.Multiline()
+ .AddLine(Code.Local("subject").Method("next").Close())
+ .AddLine(Code.Local("subject").Method("complete").Close())
+ .AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local(connectionStatusEnum.Name).Field("connected")).Close())))
+ .Method("catch", Code.Lambda("error", errorCode)).Close())
+ .AddLine(Code.Return(Code.Local("subject")))
+ )))
+ .WithCode(createConnectionCode)
+ .WithCode(Code.Local("hubConnection").Method("onclose", Code.Lambda(Code.Multiline()
+ .AddLine(Code.If(Code.Not().This().Field(isClosedField))
+ .WithCode(Code.Method("startConnection").Close())))
+ ).Close())
+ .WithCode(Code.This().Field(connectionField).Method("next", Code.Local("hubConnection")).Close())
+ .WithCode(Code.Return(Code.Method("startConnection")));
- classTemplate.AddMethod("disconnect", Code.Void())
- .WithComment("Close an active connection to the hub.\nIf the service is reconnecting/sleeping the connection attempt will be canceled")
- .WithCode(Code.This().Field(isClosedField).Assign(Code.Boolean(true)).Close())
- .WithCode(Code.This().Field(connectionField).NullConditional().Method("pipe", Code.Method("take", Code.Number(1)))
- .Method("subscribe", Code.Lambda("hubConnection", Code.Multiline()
- .AddLine(Code.Local("hubConnection").Method("stop").Method("then", Code.Lambda(Code.Multiline().AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local("ConnectionStatus").Field("disconnected")).Close()))).Close())
- )).Close());
+ classTemplate.AddMethod("disconnect", Code.Void())
+ .WithComment("Close an active connection to the hub.\nIf the service is reconnecting/sleeping the connection attempt will be canceled")
+ .WithCode(Code.This().Field(isClosedField).Assign(Code.Boolean(true)).Close())
+ .WithCode(Code.This().Field(connectionField).NullConditional().Method("pipe", Code.Method("take", Code.Number(1)))
+ .Method("subscribe", Code.Lambda("hubConnection", Code.Multiline()
+ .AddLine(Code.Local("hubConnection").Method("stop").Method("then", Code.Lambda(Code.Multiline().AddLine(Code.This().Field(statusSubjectField).Method("next", Code.Local("ConnectionStatus").Field("disconnected")).Close()))).Close())
+ )).Close());
- if (timeoutsField != null)
- {
- connectMethod.AddParameter(Code.Type("number"), "trial", Code.Number(0));
- }
+ if (timeoutsField != null)
+ {
+ connectMethod.AddParameter(Code.Type("number"), "trial", Code.Number(0));
+ }
- foreach (HttpServiceActionTransferObject action in hub.Actions)
+ foreach (HttpServiceActionTransferObject action in hub.Actions)
+ {
+ MethodTemplate methodTemplate = classTemplate.AddMethod(action.Name, Code.Generic("Observable", Code.Type("void")))
+ .FormatName(hubOptions)
+ .WithComment($"Send a \"{action.Name}\" message to the hub with the given parameters. Automatically connects to the hub.");
+ foreach (HttpServiceActionParameterTransferObject parameter in action.Parameters)
{
- MethodTemplate methodTemplate = classTemplate.AddMethod(action.Name, Code.Generic("Observable", Code.Type("void")))
- .FormatName(configuration)
- .WithComment($"Send a \"{action.Name}\" message to the hub with the given parameters. Automatically connects to the hub.");
- foreach (HttpServiceActionParameterTransferObject parameter in action.Parameters)
+ if (hub.Language != null && hubOptions.Language != null)
{
- if (hubLanguage != null && configurationLanguage != null)
- {
- this.MapType(hubLanguage, configurationLanguage, parameter.Type);
- }
- this.AddUsing(parameter.Type, classTemplate, configuration, relativeModelPath);
- methodTemplate.AddParameter(parameter.Type.ToTemplate(), parameter.Name, parameter.IsOptional ? Code.Null() : null).FormatName(configuration);
+ this.MapType(hub.Language, hubOptions.Language, parameter.Type);
}
+ this.AddUsing(parameter.Type, classTemplate, hubOptions, relativeModelPath);
+ methodTemplate.AddParameter(parameter.Type.ToTemplate(), parameter.Name, parameter.IsOptional ? Code.Null() : null).FormatName(hubOptions);
+ }
- List parameters = new List();
- parameters.Add(Code.String(action.Name));
- parameters.AddRange(action.Parameters.Select(parameter => Code.Local(parameter.Name)));
+ List parameters = new();
+ parameters.Add(Code.String(action.Name));
+ parameters.AddRange(action.Parameters.Select(parameter => Code.Local(parameter.Name)));
- string subjectName = action.Parameters.Any(x => x.Name == "subject") ? "rxjsSubject" : "subject";
- methodTemplate.WithCode(Code.Declare(Code.Generic("Subject", Code.Void()), subjectName, Code.New(Code.Generic("Subject", Code.Void()))))
- .WithCode(
- Code.This().Method(connectMethod).Method("pipe",
- Code.Method("mergeMap", Code.Lambda(Code.This().Field(connectionField))),
- Code.Method("take", Code.Number(1)),
- Code.Method("mergeMap", Code.Lambda("connection", Code.Local("connection").Method("send", parameters))
- ))
- .Method("subscribe", Code.Lambda(Code.Multiline()
- .AddLine(Code.Local(subjectName).Method("next").Close())
- .AddLine(Code.Local(subjectName).Method("complete").Close())),
- Code.Lambda("error", Code.Local(subjectName).Method("error", Code.Local("error")))).Close())
- .WithCode(Code.Return(Code.Local(subjectName)));
- }
- foreach (HttpServiceActionTransferObject action in hub.Events)
+ string subjectName = action.Parameters.Any(x => x.Name == "subject") ? "rxjsSubject" : "subject";
+ methodTemplate.WithCode(Code.Declare(Code.Generic("Subject", Code.Void()), subjectName, Code.New(Code.Generic("Subject", Code.Void()))))
+ .WithCode(
+ Code.This().Method(connectMethod).Method("pipe",
+ Code.Method("mergeMap", Code.Lambda(Code.This().Field(connectionField.Name + "!"))),
+ Code.Method("take", Code.Number(1)),
+ Code.Method("mergeMap", Code.Lambda("connection", Code.Local("connection").Method("send", parameters))
+ ))
+ .Method("subscribe", Code.Lambda(Code.Multiline()
+ .AddLine(Code.Local(subjectName).Method("next").Close())
+ .AddLine(Code.Local(subjectName).Method("complete").Close())),
+ Code.Lambda("error", Code.Local(subjectName).Method("error", Code.Local("error")))).Close())
+ .WithCode(Code.Return(Code.Local(subjectName)));
+ }
+ foreach (HttpServiceActionTransferObject action in hub.Events)
+ {
+ foreach (HttpServiceActionParameterTransferObject parameter in action.Parameters)
{
- foreach (HttpServiceActionParameterTransferObject parameter in action.Parameters)
- {
- if (hubLanguage != null && configurationLanguage != null)
- {
- this.MapType(hubLanguage, configurationLanguage, parameter.Type);
- }
- this.AddUsing(parameter.Type, classTemplate, configuration, relativeModelPath);
- }
- TypeTemplate eventType;
- List eventResult = new List();
- if (action.Parameters.Count == 0)
+ if (hub.Language != null && hubOptions.Language != null)
{
- eventType = Code.Void();
+ this.MapType(hub.Language, hubOptions.Language, parameter.Type);
}
- else if (action.Parameters.Count == 1)
- {
- eventType = action.Parameters.First().Type.ToTemplate();
- eventResult.Add(Code.Local(action.Parameters.Single().Name));
- }
- else
+ this.AddUsing(parameter.Type, classTemplate, hubOptions, relativeModelPath);
+ }
+ TypeTemplate eventType;
+ List eventResult = new();
+ if (action.Parameters.Count == 0)
+ {
+ eventType = Code.Void();
+ }
+ else if (action.Parameters.Count == 1)
+ {
+ eventType = action.Parameters.First().Type.ToTemplate();
+ eventResult.Add(Code.Local(action.Parameters.Single().Name));
+ }
+ else
+ {
+ AnonymousObjectTemplate eventTypeObject = Code.AnonymousObject();
+ AnonymousObjectTemplate resultObject = Code.AnonymousObject();
+ foreach (HttpServiceActionParameterTransferObject parameter in action.Parameters)
{
- AnonymousObjectTemplate anonymousObject = Code.AnonymousObject();
- action.Parameters.ForEach(parameter => anonymousObject.AddProperty(parameter.Name).FormatName(configuration));
- DeclareTypeTemplate declareTypeTemplate = namespaceTemplate.AddDeclareType(action.Name + "Event", anonymousObject).FormatName(configuration);
- eventType = Code.Type(declareTypeTemplate.Name);
- eventResult.Add(anonymousObject);
+ eventTypeObject.AddProperty(parameter.Name, parameter.Type.ToTemplate()).FormatName(hubOptions);
+ resultObject.AddProperty(parameter.Name).FormatName(hubOptions);
}
- GenericTypeTemplate subjectType = Code.Generic("Subject", eventType);
- FieldTemplate eventPrivateField = classTemplate.AddField(action.Name + "Subject", subjectType).Readonly().FormatName(configuration).Default(Code.New(subjectType));
- FieldTemplate eventPublicField = classTemplate.AddField(action.Name + "$", Code.Generic("Observable", eventType)).Public().Readonly().FormatName(configuration)
- .Default(Code.This().Local(eventPrivateField).Method("asObservable"));
- MultilineCodeFragment code = new MultilineCodeFragment();
- code.AddLine(Code.This().Local(eventPrivateField).Method("next", eventResult.ToArray()).Close());
- List parameters = new List();
- parameters.Add(Code.String(action.Name));
- parameters.Add(Code.Lambda(action.Parameters.Select(x => new ParameterTemplate(x.Type.ToTemplate(), x.Name)).ToList(), code));
- createConnectionCode.AddLine(Code.Local("hubConnection").Method("on", parameters).Close());
+ DeclareTypeTemplate declareTypeTemplate = namespaceTemplate.AddDeclareType(action.Name + "Event", eventTypeObject).FormatName(hubOptions);
+ eventType = Code.Type(declareTypeTemplate.Name);
+ eventResult.Add(resultObject);
}
+ GenericTypeTemplate subjectType = Code.Generic("Subject", eventType);
+ FieldTemplate eventPrivateField = classTemplate.AddField(action.Name + "Subject", subjectType).Readonly().FormatName(hubOptions).Default(Code.New(subjectType));
+ FieldTemplate eventPublicField = classTemplate.AddField(action.Name + "$", Code.Generic("Observable", eventType)).Public().Readonly().FormatName(hubOptions)
+ .Default(Code.This().Local(eventPrivateField).Method("asObservable"));
+ MultilineCodeFragment code = new();
+ code.AddLine(Code.This().Local(eventPrivateField).Method("next", eventResult.ToArray()).Close());
+ List parameters = new();
+ parameters.Add(Code.String(action.Name));
+ parameters.Add(Code.Lambda(action.Parameters.Select(x => new ParameterTemplate(x.Type.ToTemplate(), x.Name)).ToList(), code));
+ createConnectionCode.AddLine(Code.Local("hubConnection").Method("on", parameters).Close());
}
}
+ }
- private bool WriteDateFixes(ModelTransferObject model, bool isModelEnumerable, MultilineCodeFragment code, IReadOnlyList chain, IReadOnlyList typeChain, List transferObjects, IConfiguration configuration)
+ private bool WriteDateFixes(ClassTemplate classTemplate, List convertDateMethods, ModelTransferObject model, GeneratorOptions controllerOptions, string relativeModelPath)
+ {
+ if (model == null)
{
- if (model == null)
- {
- return false;
- }
- bool datePropertyFound = false;
- IfTemplate ifTemplate = Code.If(this.WriteFieldChain(chain));
- MultilineCodeFragment innerCode = ifTemplate.Code;
- if (isModelEnumerable)
- {
- innerCode = Code.Multiline();
- ifTemplate.WithCode(this.WriteFieldChain(chain).Method("forEach", Code.Lambda("entry", innerCode)).Close());
- chain = new List { "entry" };
- }
- foreach (PropertyTransferObject property in model.Properties)
+ return false;
+ }
+ string methodName = $"convert{model.Name.ToPascalCase()}Date";
+ if (convertDateMethods.Any(x => x.Name.Equals(methodName, StringComparison.InvariantCultureIgnoreCase)))
+ {
+ return true;
+ }
+ this.AddUsing(model, classTemplate, controllerOptions, relativeModelPath);
+ bool hasLocalDateProperty = false;
+ MethodTemplate convertDateMethodTemplate = classTemplate.AddMethod(methodName, Code.Void())
+ .WithParameter(model.ToTemplate(), "model?")
+ .WithCode(Code.If(Code.Local("!model")).WithCode(Code.Return()));
+ convertDateMethods.Add(convertDateMethodTemplate);
+ foreach (PropertyTransferObject property in model.Properties)
+ {
+ TypeTransferObject type = model.Generics.FirstOrDefault(generic => generic.Alias?.Name == property.Name)?.Type ?? property.Type;
+ GeneratorOptions propertyOptions = this.Options.Get(property);
+ string propertyName = Formatter.FormatProperty(property.Name, propertyOptions);
+ if (type.IgnoreNullable().OriginalName == nameof(DateTime))
{
- TypeTransferObject type = model.Generics.FirstOrDefault(generic => generic.Alias?.Name == property.Name)?.Type ?? property.Type;
- if (typeChain.Any(typeFromChain => typeFromChain.Name == property.Type.Name && typeFromChain.Namespace == property.Type.Namespace))
+ hasLocalDateProperty = true;
+ AssignTemplate assignTemplate = Code.Local("model").Field(propertyName).Assign(Code.This().Method("convertDate", Code.Local("model").Field(propertyName)));
+ ICodeFragment lineTemplate;
+ if (property.IsOptional || property.Type.IsNullable)
{
- continue;
+ lineTemplate = assignTemplate.Close();
}
- string propertyName = Formatter.FormatProperty(property.Name, configuration);
- if (type.Name == nameof(DateTime))
+ else
{
- datePropertyFound = true;
- if (isModelEnumerable)
- {
- innerCode.AddLine(Code.Local("entry").Field(propertyName).Assign(Code.This().Method("convertToDate", Code.Local("entry").Field(propertyName))).Close());
- }
- else
- {
- innerCode.AddLine(this.WriteFieldChain(chain).Field(propertyName).Assign(Code.This().Method("convertToDate", this.WriteFieldChain(chain).Field(propertyName))).Close());
- }
+ lineTemplate = assignTemplate.NullCoalescing(Code.Local("model").Field(propertyName).Close());
}
- ModelTransferObject propertyModel = type as ModelTransferObject;
- TypeTransferObject entryType = propertyModel?.Generics.FirstOrDefault()?.Type;
- entryType = entryType == null ? null : model.Generics.FirstOrDefault(generic => generic.Alias?.Name == entryType.Name)?.Type ?? entryType;
- ModelTransferObject entryModel = entryType as ModelTransferObject ?? transferObjects.OfType().FirstOrDefault(x => x.Name == entryType?.Name && x.Namespace == entryType?.Namespace);
- List nextChain = new List(chain);
- nextChain.Add(propertyName);
- List nextTypeChain = new List(typeChain);
- nextTypeChain.Add(type);
- if (propertyModel != null && propertyModel.IsEnumerable() && entryModel != null)
+ convertDateMethodTemplate.WithCode(lineTemplate);
+ }
+ ModelTransferObject propertyModel = type as ModelTransferObject;
+ TypeTransferObject entryType = propertyModel?.Generics.FirstOrDefault()?.Type;
+ entryType = entryType == null ? null : model.Generics.FirstOrDefault(generic => generic.Alias?.Name == entryType.Name)?.Type ?? entryType;
+ ModelTransferObject entryModel = entryType as ModelTransferObject ?? this.transferObjects.OfType().FirstOrDefault(x => x.Name == entryType?.Name && x.Namespace == entryType?.Namespace);
+ if (propertyModel != null && propertyModel.IsEnumerable() && entryModel != null)
+ {
+ if (entryModel.OriginalName == nameof(DateTime))
{
- datePropertyFound = this.WriteDateFixes(entryModel, true, innerCode, nextChain, nextTypeChain, transferObjects, configuration) || datePropertyFound;
+ hasLocalDateProperty = true;
+ convertDateMethodTemplate.WithCode(Code.Local("model").Field(propertyName).Assign(
+ Code.Local("model").Field(propertyName).Method("map", Code.Lambda("m",
+ Code.This().Method("convertDate", Code.Local("m"))
+ )))
+ );
}
- else if (propertyModel != null && propertyModel.Properties.Count > 0)
+ else if (this.WriteDateFixes(classTemplate, convertDateMethods, entryModel, controllerOptions, relativeModelPath))
{
- datePropertyFound = this.WriteDateFixes(propertyModel, false, innerCode, nextChain, nextTypeChain, transferObjects, configuration) || datePropertyFound;
+ hasLocalDateProperty = true;
+ GenericAliasTransferObject aliasedType = model.Generics.FirstOrDefault(x => x.Alias.Name == property.Type.Generics.Single().Alias.Name)
+ ?? property.Type.Generics.Single();
+ string convertMethodName = $"convert{aliasedType.Type.Name.ToPascalCase()}Date";
+ convertDateMethodTemplate.WithCode(Code.Local("model").Field(propertyName + "?").Method("forEach", Code.Lambda("m", Code.This().Method(convertMethodName, Code.Local("m")))).Close());
}
}
- if (datePropertyFound)
+ else if (propertyModel != null && propertyModel.Properties.Count > 0)
{
- code.AddLine(ifTemplate);
+ if (this.WriteDateFixes(classTemplate, convertDateMethods, propertyModel, controllerOptions, relativeModelPath))
+ {
+ hasLocalDateProperty = true;
+ string convertMethodName = $"convert{property.Type.Name.ToPascalCase()}Date";
+ convertDateMethodTemplate.WithCode(Code.This().Method(convertMethodName, Code.Local("model").Field(propertyName)).Close());
+ }
}
- return datePropertyFound;
}
-
- private ChainedCodeFragment WriteFieldChain(IEnumerable chain)
+ if (hasLocalDateProperty)
{
- List chainList = chain.ToList();
- ChainedCodeFragment code = Code.Local(chainList.First());
- foreach (string field in chainList.Skip(1))
- {
- code = code.Field(field);
- }
- return code;
+ return true;
}
+ convertDateMethods.Remove(convertDateMethodTemplate);
+ classTemplate.Methods.Remove(convertDateMethodTemplate);
+ return false;
+ }
- private void AppendConvertAnyMethod(ClassTemplate classTemplate)
- {
- classTemplate.AddMethod("convertAny", Code.Type("string"))
- .WithParameter(Code.Type("any"), "value")
- .WithCode(Code.Return(Code.InlineIf(Code.Local("value").Equals().ForceNull().Or().Local("value").Equals().Undefined(),
- Code.String(string.Empty),
- Code.Local("value").Method("toString")
- )
- ));
- }
+ private void AddAppendMethod(ClassTemplate classTemplate)
+ {
+ MultilineCodeFragment code = Code.Multiline().AddLine(
+ Code.If(Code.Not().Local("parameterName"))
+ .WithCode(Code.Return(Code.Local("url")
+ .Append(Code.Local("separator"))
+ .Append(Code.Parenthesis(Code.InlineIf(Code.Local("value").Equals().ForceNull().Or().Local("value").Equals().Undefined(),
+ Code.String(string.Empty),
+ Code.Local("value").Method("toString")
+ )))
+ ))
+ );
+ code.AddLine(Code.If(Code.Local("value").NotEquals().ForceNull().And().Local("value").NotEquals().Undefined())
+ .WithCode(Code.Return(Code.Local("url")
+ .Append(Code.Parenthesis(Code.InlineIf(Code.Local("url").Method("indexOf", Code.String("?")).Equals().Number(-1), Code.String("?"), Code.String("&"))))
+ .Append(Code.Local("parameterName"))
+ .Append(Code.String("="))
+ .Append(Code.Local("value").Method("toString"))
+ ))
+ );
+ code.AddLine(Code.Return(Code.Local("url")));
+ classTemplate.AddMethod("append", Code.Type("string"))
+ .WithParameter(Code.Type("string"), "url")
+ .WithParameter(Code.Type("{toString(): string} | undefined | null"), "value")
+ .WithParameter(Code.Type("string"), "parameterName", Code.String(string.Empty))
+ .WithParameter(Code.Type("string"), "separator", Code.String(string.Empty))
+ .WithCode(code);
+ }
- private void AppendConvertFromDateMethod(ClassTemplate classTemplate)
- {
- classTemplate.AddMethod("convertFromDate", Code.Type("string"))
- .WithParameter(Code.Type("Date"), "date")
- .WithCode(Code.Return(Code.InlineIf(Code.Local("date").Equals().ForceNull().Or().Local("date").Equals().Undefined(),
- Code.String(string.Empty),
- Code.InlineIf(Code.TypeScript($"typeof(date) === \"string\""),
- Code.Local("date"),
- Code.Local("date").Method("toISOString")
- )
- )
- ));
- }
+ private void AddAppendDateMethod(ClassTemplate classTemplate)
+ {
+ ICodeFragment code = Code.InlineIf(Code.Local("date").Equals().ForceNull().Or().Local("date").Equals().Undefined(),
+ Code.String(string.Empty),
+ Code.InlineIf(Code.TypeScript("typeof(date) === \"string\""),
+ Code.Local("date"),
+ Code.Local("date").Method("toISOString")
+ )
+ );
+ classTemplate.AddMethod("appendDate", Code.Type("string")).Private()
+ .WithParameter(Code.Type("string"), "url")
+ .WithParameter(Code.Type("Date | null | undefined | string"), "date")
+ .WithParameter(Code.Type("string"), "parameterName", Code.String(string.Empty))
+ .WithParameter(Code.Type("string"), "separator", Code.String(string.Empty))
+ .WithCode(Code.Return(Code.This().Method("append", Code.Local("url"), code, Code.Local("parameterName"), Code.Local("separator"))));
+ }
- private void AppendConvertToDateMethod(ClassTemplate classTemplate)
- {
- classTemplate.AddMethod("convertToDate", Code.Type("Date"))
- .WithParameter(Code.Type("string | Date"), "value")
- .WithCode(Code.Return(Code.InlineIf(Code.TypeScript($"typeof(value) === \"string\""),
- Code.New(Code.Type("Date"), Code.Local("value")),
- Code.Local("value")
- )
- ));
- }
+ private void AppendConvertDateMethod(ClassTemplate classTemplate)
+ {
+ classTemplate.AddMethod("convertDate", Code.UnionType(Code.Type("Date"), Code.Undefined())).Private()
+ .WithParameter(Code.UnionType(Code.Type("string"), Code.Type("Date"), Code.Undefined()), "value")
+ .AddOverload(overload => overload
+ .WithParameter(Code.UnionType(Code.Type("string"), Code.Type("Date")), "value")
+ .WithReturnType(Code.Type("Date"))
+ )
+ .WithCode(Code.Return(Code.InlineIf(Code.Local("value").Equals().String("0001-01-01T00:00:00"),
+ Code.New(Code.Type("Date"), Code.String("0001-01-01T00:00:00Z")),
+ Code.InlineIf(Code.TypeScript("typeof(value) === \"string\""),
+ Code.New(Code.Type("Date"), Code.Local("value")),
+ Code.Local("value")
+ )
+ )));
+ }
- private string GetAllowedName(ILanguage language, string name)
- {
- return language.ReservedKeywords.ContainsKey(name) ? language.ReservedKeywords[name] : name;
- }
+ private void AppendFixUndefined(ClassTemplate classTemplate)
+ {
+ classTemplate.AddMethod("fixUndefined", Code.Type("any")).Private()
+ .WithParameter(Code.Type("any"), "value")
+ .WithCode(Code.If(Code.Not().Local("value")).WithCode(Code.Return(Code.Local("value").NullCoalescing().Local("undefined"))))
+ .WithCode(Code.If(Code.Static(Code.Type("Array")).Method("isArray", Code.Local("value")))
+ .WithCode(Code.TypeScript("value.forEach((entry, index) => value[index] = this.fixUndefined(entry));")))
+ .WithCode(Code.If(Code.TypeScript("typeof value === 'object'")).WithCode(Code.TypeScript("for (const key of Object.keys(value)) { value[key] = this.fixUndefined(value[key]); }")))
+ .WithCode(Code.Return(Code.Local("value")));
+ }
+
+ private string GetAllowedName(ILanguage language, string name)
+ {
+ return language.ReservedKeywords.ContainsKey(name) ? language.ReservedKeywords[name] : name;
}
}
diff --git a/Angular/Writers/AngularWriter.cs b/Angular/Writers/AngularWriter.cs
deleted file mode 100644
index 04a5fe4d..00000000
--- a/Angular/Writers/AngularWriter.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System.Collections.Generic;
-using KY.Core.Dependency;
-using KY.Generator.Angular.Configurations;
-using KY.Generator.Configuration;
-using KY.Generator.Configurations;
-using KY.Generator.Output;
-using KY.Generator.Templates;
-using KY.Generator.Transfer;
-using KY.Generator.Transfer.Writers;
-
-namespace KY.Generator.Angular.Writers
-{
- internal class AngularWriter : ITransferWriter
- {
- private readonly IDependencyResolver resolver;
-
- public AngularWriter(IDependencyResolver resolver)
- {
- this.resolver = resolver;
- }
-
- public void Write(ConfigurationBase configurationBase, List transferObjects, IOutput output)
- {
- AngularWriteConfiguration configuration = (AngularWriteConfiguration)configurationBase;
- List files = new List();
- if (configuration.Service != null)
- {
- this.resolver.Create().Write(configuration, transferObjects, files);
- }
- if (configuration.WriteModels)
- {
- this.resolver.Create().Write(configuration, transferObjects, files);
- }
- files.ForEach(file => configuration.Language.Write(file, output));
- }
- }
-}
\ No newline at end of file
diff --git a/Annotations/Angular/GenerateAngularHubAttribute.cs b/Annotations/Angular/GenerateAngularHubAttribute.cs
index 27ded871..e6cc6bfe 100644
--- a/Annotations/Angular/GenerateAngularHubAttribute.cs
+++ b/Annotations/Angular/GenerateAngularHubAttribute.cs
@@ -13,12 +13,12 @@ public IEnumerable Commands
return new[]
{
new AttributeCommandConfiguration("asp-read-hub", "-namespace=$NAMESPACE$", "-name=$NAME$"),
- new AttributeCommandConfiguration("angular-service", this.ServiceParameters),
- new AttributeCommandConfiguration("angular-model", this.ModelParameters)
+ new AttributeCommandConfiguration("angular-model", this.ModelParameters),
+ new AttributeCommandConfiguration("angular-service", this.ServiceParameters)
};
}
}
-
+
private List ServiceParameters
{
get
@@ -36,30 +36,6 @@ private List ServiceParameters
{
parameter.Add($"-name={this.Name}");
}
- if (this.PropertiesToFields == Option.Yes)
- {
- parameter.Add("-propertiesToFields");
- }
- else if (this.PropertiesToFields == Option.No)
- {
- parameter.Add("-propertiesToFields=false");
- }
- if (this.FieldsToProperties == Option.Yes)
- {
- parameter.Add("-fieldsToProperties");
- }
- else if (this.FieldsToProperties == Option.No)
- {
- parameter.Add("-fieldsToProperties=false");
- }
- if (this.FormatHubNames == Option.Yes)
- {
- parameter.Add("-formatNames");
- }
- else if (this.FormatHubNames == Option.No)
- {
- parameter.Add("-formatNames=false");
- }
return parameter;
}
}
@@ -73,30 +49,6 @@ private List ModelParameters
{
parameter.Add($"-relativePath={this.RelativeModelPath}");
}
- if (this.PropertiesToFields == Option.Yes)
- {
- parameter.Add("-propertiesToFields");
- }
- else if (this.PropertiesToFields == Option.No)
- {
- parameter.Add("-propertiesToFields=false");
- }
- if (this.FieldsToProperties == Option.Yes)
- {
- parameter.Add("-fieldsToProperties");
- }
- else if (this.FieldsToProperties == Option.No)
- {
- parameter.Add("-fieldsToProperties=false");
- }
- if (this.FormatModelNames == Option.Yes)
- {
- parameter.Add("-formatNames");
- }
- else if (this.FormatModelNames == Option.No)
- {
- parameter.Add("-formatNames=false");
- }
return parameter;
}
}
@@ -104,23 +56,15 @@ private List ModelParameters
public string RelativePath { get; }
public string RelativeModelPath { get; set; }
public string Name { get; }
- public Option PropertiesToFields { get; }
- public Option FieldsToProperties { get; }
- public Option FormatHubNames { get; }
- public Option FormatModelNames { get; }
public GenerateAngularHubAttribute()
{ }
- public GenerateAngularHubAttribute(string relativeServicePath, string relativeModelPath, string name = null, Option propertiesToFields = Option.Inherit, Option fieldsToProperties = Option.Inherit, Option formatNames = Option.Inherit, Option formatHubNames = Option.Inherit, Option formatModelNames = Option.Inherit)
+ public GenerateAngularHubAttribute(string relativeServicePath, string relativeModelPath, string name = null)
{
this.RelativePath = relativeServicePath;
this.RelativeModelPath = relativeModelPath;
this.Name = name;
- this.PropertiesToFields = propertiesToFields;
- this.FieldsToProperties = fieldsToProperties;
- this.FormatHubNames = formatNames == Option.Inherit ? formatHubNames : formatNames;
- this.FormatModelNames = formatNames == Option.Inherit ? formatModelNames : formatNames;
}
}
-}
\ No newline at end of file
+}
diff --git a/Annotations/Angular/GenerateAngularIndexAttribute.cs b/Annotations/Angular/GenerateAngularIndexAttribute.cs
deleted file mode 100644
index d6010a8c..00000000
--- a/Annotations/Angular/GenerateAngularIndexAttribute.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace KY.Generator
-{
- [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
- public class GenerateAngularIndexAttribute : Attribute, IGeneratorCommandAttribute
- {
- public IEnumerable Commands
- {
- get { return new[]
- {
- new AttributeCommandConfiguration("reflection-read", "-namespace=$NAMESPACE$", "-name=$NAME$", "-skipSelf"),
- new AttributeCommandConfiguration("angular-model", this.Parameters)
- }; }
- }
-
- private List Parameters
- {
- get
- {
- List parameter = new List();
- if (this.RelativePath != null)
- {
- parameter.Add($"-relativePath={this.RelativePath}");
- }
- if (this.SkipNamespace == Option.Yes)
- {
- parameter.Add("-skipNamespace");
- }
- else if (this.SkipNamespace == Option.No)
- {
- parameter.Add("-skipNamespace=false");
- }
- if (this.PropertiesToFields == Option.Yes)
- {
- parameter.Add("-propertiesToFields");
- }
- else if (this.PropertiesToFields == Option.No)
- {
- parameter.Add("-propertiesToFields=false");
- }
- if (this.FieldsToProperties == Option.Yes)
- {
- parameter.Add("-fieldsToProperties");
- }
- else if (this.FieldsToProperties == Option.No)
- {
- parameter.Add("-fieldsToProperties=false");
- }
- if (this.FormatNames == Option.Yes)
- {
- parameter.Add("-formatNames");
- }
- else if (this.FormatNames == Option.No)
- {
- parameter.Add("-formatNames=false");
- }
- return parameter;
- }
- }
-
- public string RelativePath { get; }
- public Option SkipNamespace { get; }
- public Option PropertiesToFields { get; }
- public Option FieldsToProperties { get; }
- public Option FormatNames { get; }
-
- public GenerateAngularIndexAttribute(string relativePath = null, Option skipNamespace = Option.Inherit, Option propertiesToFields = Option.Inherit, Option fieldsToProperties = Option.Inherit, Option formatNames = Option.Inherit)
- {
- this.RelativePath = relativePath;
- this.SkipNamespace = skipNamespace;
- this.PropertiesToFields = propertiesToFields;
- this.FieldsToProperties = fieldsToProperties;
- this.FormatNames = formatNames;
- }
- }
-}
\ No newline at end of file
diff --git a/Annotations/Angular/GenerateAngularModelAttribute.cs b/Annotations/Angular/GenerateAngularModelAttribute.cs
index 69d94f4e..dbef90e1 100644
--- a/Annotations/Angular/GenerateAngularModelAttribute.cs
+++ b/Annotations/Angular/GenerateAngularModelAttribute.cs
@@ -1,78 +1,27 @@
-using System;
-using System.Collections.Generic;
+namespace KY.Generator;
-namespace KY.Generator
+[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
+public class GenerateAngularModelAttribute(string relativePath = "")
+ : Attribute, IGeneratorCommandAttribute
{
- [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
- public class GenerateAngularModelAttribute : Attribute, IGeneratorCommandAttribute
- {
- public IEnumerable Commands
- {
- get { return new[]
- {
- new AttributeCommandConfiguration("reflection-read", "-namespace=$NAMESPACE$", "-name=$NAME$"),
- new AttributeCommandConfiguration("angular-model", this.Parameters)
- }; }
- }
+ public string RelativePath { get; } = relativePath;
- private List Parameters
+ public IEnumerable Commands =>
+ [
+ new("reflection-read", "-namespace=$NAMESPACE$", "-name=$NAME$"),
+ new("angular-model", this.Parameters)
+ ];
+
+ private List Parameters
+ {
+ get
{
- get
+ List parameter = [];
+ if (this.RelativePath != string.Empty)
{
- List parameter = new List();
- if (this.RelativePath != null)
- {
- parameter.Add($"-relativePath={this.RelativePath}");
- }
- if (this.SkipNamespace == Option.Yes)
- {
- parameter.Add("-skipNamespace");
- }
- else if (this.SkipNamespace == Option.No)
- {
- parameter.Add("-skipNamespace=false");
- }
- if (this.PropertiesToFields == Option.Yes)
- {
- parameter.Add("-propertiesToFields");
- }
- else if (this.PropertiesToFields == Option.No)
- {
- parameter.Add("-propertiesToFields=false");
- }
- if (this.FieldsToProperties == Option.Yes)
- {
- parameter.Add("-fieldsToProperties");
- }
- else if (this.FieldsToProperties == Option.No)
- {
- parameter.Add("-fieldsToProperties=false");
- }
- if (this.FormatNames == Option.Yes)
- {
- parameter.Add("-formatNames");
- }
- else if (this.FormatNames == Option.No)
- {
- parameter.Add("-formatNames=false");
- }
- return parameter;
+ parameter.Add($"-relativePath={this.RelativePath}");
}
- }
-
- public string RelativePath { get; }
- public Option SkipNamespace { get; }
- public Option PropertiesToFields { get; }
- public Option FieldsToProperties { get; }
- public Option FormatNames { get; }
-
- public GenerateAngularModelAttribute(string relativePath = null, Option skipNamespace = Option.Inherit, Option propertiesToFields = Option.Inherit, Option fieldsToProperties = Option.Inherit, Option formatNames = Option.Inherit)
- {
- this.RelativePath = relativePath;
- this.SkipNamespace = skipNamespace;
- this.PropertiesToFields = propertiesToFields;
- this.FieldsToProperties = fieldsToProperties;
- this.FormatNames = formatNames;
+ return parameter;
}
}
-}
\ No newline at end of file
+}
diff --git a/Annotations/Angular/GenerateAngularServiceAttribute.cs b/Annotations/Angular/GenerateAngularServiceAttribute.cs
index 24a9f731..2f0e1091 100644
--- a/Annotations/Angular/GenerateAngularServiceAttribute.cs
+++ b/Annotations/Angular/GenerateAngularServiceAttribute.cs
@@ -1,126 +1,69 @@
using System;
using System.Collections.Generic;
-namespace KY.Generator
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
+public class GenerateAngularServiceAttribute : Attribute, IGeneratorCommandAttribute
{
- [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
- public class GenerateAngularServiceAttribute : Attribute, IGeneratorCommandAttribute
+ public IEnumerable Commands
{
- public IEnumerable Commands
+ get
{
- get
- {
- return new[]
- {
- new AttributeCommandConfiguration("asp-read-controller", "-namespace=$NAMESPACE$", "-name=$NAME$"),
- new AttributeCommandConfiguration("angular-service", this.ServiceParameters),
- new AttributeCommandConfiguration("angular-model", this.ModelParameters)
- };
- }
+ return new[]
+ {
+ new AttributeCommandConfiguration("asp-read-controller", "-namespace=$NAMESPACE$", "-name=$NAME$"),
+ new AttributeCommandConfiguration("angular-model", this.ModelParameters),
+ new AttributeCommandConfiguration("angular-service", this.ServiceParameters)
+ };
}
+ }
- private List ServiceParameters
+ private List ServiceParameters
+ {
+ get
{
- get
+ List parameter = [];
+ if (this.RelativePath != null)
+ {
+ parameter.Add($"-relativePath={this.RelativePath}");
+ }
+ if (this.RelativeModelPath != null)
{
- List parameter = new List();
- if (this.RelativePath != null)
- {
- parameter.Add($"-relativePath={this.RelativePath}");
- }
- if (this.RelativeModelPath != null)
- {
- parameter.Add($"-relativeModelPath={this.RelativeModelPath}");
- }
- if (this.Name != null)
- {
- parameter.Add($"-name={this.Name}");
- }
- if (this.PropertiesToFields == Option.Yes)
- {
- parameter.Add("-propertiesToFields");
- }
- else if (this.PropertiesToFields == Option.No)
- {
- parameter.Add("-propertiesToFields=false");
- }
- if (this.FieldsToProperties == Option.Yes)
- {
- parameter.Add("-fieldsToProperties");
- }
- else if (this.FieldsToProperties == Option.No)
- {
- parameter.Add("-fieldsToProperties=false");
- }
- if (this.FormatServiceNames == Option.Yes)
- {
- parameter.Add("-formatNames");
- }
- else if (this.FormatServiceNames == Option.No)
- {
- parameter.Add("-formatNames=false");
- }
- return parameter;
+ parameter.Add($"-relativeModelPath={this.RelativeModelPath}");
}
+ if (this.Name != null)
+ {
+ parameter.Add($"-name={this.Name}");
+ }
+ return parameter;
}
+ }
- private List ModelParameters
+ private List ModelParameters
+ {
+ get
{
- get
+ List parameter = [];
+ if (this.RelativePath != null)
{
- List parameter = new List();
- if (this.RelativePath != null)
- {
- parameter.Add($"-relativePath={this.RelativeModelPath}");
- }
- if (this.PropertiesToFields == Option.Yes)
- {
- parameter.Add("-propertiesToFields");
- }
- else if (this.PropertiesToFields == Option.No)
- {
- parameter.Add("-propertiesToFields=false");
- }
- if (this.FieldsToProperties == Option.Yes)
- {
- parameter.Add("-fieldsToProperties");
- }
- else if (this.FieldsToProperties == Option.No)
- {
- parameter.Add("-fieldsToProperties=false");
- }
- if (this.FormatModelNames == Option.Yes)
- {
- parameter.Add("-formatNames");
- }
- else if (this.FormatModelNames == Option.No)
- {
- parameter.Add("-formatNames=false");
- }
- return parameter;
+ parameter.Add($"-relativePath={this.RelativeModelPath}");
}
+ return parameter;
}
+ }
- public string RelativePath { get; }
- public string RelativeModelPath { get; set; }
- public string Name { get; }
- public Option PropertiesToFields { get; }
- public Option FieldsToProperties { get; }
- public Option FormatServiceNames { get; }
- public Option FormatModelNames { get; }
+ public string RelativePath { get; }
+ public string RelativeModelPath { get; set; }
+ public string Name { get; }
- public GenerateAngularServiceAttribute()
- { }
+ public GenerateAngularServiceAttribute()
+ { }
- public GenerateAngularServiceAttribute(string relativeServicePath, string relativeModelPath, string name = null, Option propertiesToFields = Option.Inherit, Option fieldsToProperties = Option.Inherit, Option formatNames = Option.Inherit, Option formatServiceNames = Option.Inherit, Option formatModelNames = Option.Inherit)
- {
- this.RelativePath = relativeServicePath;
- this.RelativeModelPath = relativeModelPath;
- this.Name = name;
- this.PropertiesToFields = propertiesToFields;
- this.FieldsToProperties = fieldsToProperties;
- this.FormatServiceNames = formatNames == Option.Inherit ? formatServiceNames : formatNames;
- this.FormatModelNames = formatNames == Option.Inherit ? formatModelNames : formatNames;
- }
+ public GenerateAngularServiceAttribute(string relativeServicePath = null, string relativeModelPath = null, string name = null)
+ {
+ this.RelativePath = relativeServicePath;
+ this.RelativeModelPath = relativeModelPath;
+ this.Name = name;
}
-}
\ No newline at end of file
+}
diff --git a/Annotations/Angular/GenerateServiceOutputAttribute.cs b/Annotations/Angular/GenerateServiceOutputAttribute.cs
new file mode 100644
index 00000000..0e489917
--- /dev/null
+++ b/Annotations/Angular/GenerateServiceOutputAttribute.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+public class GenerateServiceOutputAttribute(string relativePath) : Attribute, IGeneratorCommandAdditionalParameterAttribute
+{
+ public string RelativePath { get; } = relativePath;
+
+ public IEnumerable Commands =>
+ [
+ new AttributeCommandConfiguration("angular-model", this.Parameters),
+ new AttributeCommandConfiguration("angular-service", this.Parameters)
+ ];
+
+ private List Parameters
+ {
+ get
+ {
+ List parameter = [];
+ if (this.RelativePath != null)
+ {
+ parameter.Add($"-relativePath={this.RelativePath}");
+ }
+ return parameter;
+ }
+ }
+}
diff --git a/Annotations/Core/GenerateFieldsAsPropertiesAttribute.cs b/Annotations/Core/GenerateFieldsAsPropertiesAttribute.cs
new file mode 100644
index 00000000..b38f2219
--- /dev/null
+++ b/Annotations/Core/GenerateFieldsAsPropertiesAttribute.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace KY.Generator
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+ public class GenerateFieldsAsPropertiesAttribute : Attribute
+ { }
+}
diff --git a/Annotations/Core/GenerateFormatNamesAttribute.cs b/Annotations/Core/GenerateFormatNamesAttribute.cs
new file mode 100644
index 00000000..0c435e22
--- /dev/null
+++ b/Annotations/Core/GenerateFormatNamesAttribute.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace KY.Generator
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+ public class GenerateFormatNamesAttribute : Attribute
+ {
+ public bool FormatNames { get; }
+
+ public GenerateFormatNamesAttribute(bool formatNames = true)
+ {
+ this.FormatNames = formatNames;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Annotations/Core/GenerateModelOutputAttribute.cs b/Annotations/Core/GenerateModelOutputAttribute.cs
new file mode 100644
index 00000000..186cfb45
--- /dev/null
+++ b/Annotations/Core/GenerateModelOutputAttribute.cs
@@ -0,0 +1,27 @@
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+public class GenerateModelOutputAttribute(string relativePath) : Attribute, IGeneratorCommandAdditionalParameterAttribute
+{
+ public string RelativePath { get; } = relativePath;
+
+ public IEnumerable Commands =>
+ [
+ new("angular-model", this.Parameters),
+ new("angular-service", this.Parameters),
+ new("reflection", this.Parameters)
+ ];
+
+ private List Parameters
+ {
+ get
+ {
+ List parameter = [];
+ if (!string.IsNullOrEmpty(this.RelativePath))
+ {
+ parameter.Add($"-relativeModelPath={this.RelativePath}");
+ }
+ return parameter;
+ }
+ }
+}
diff --git a/Annotations/Core/GenerateNoHeaderAttribute.cs b/Annotations/Core/GenerateNoHeaderAttribute.cs
new file mode 100644
index 00000000..f2d4c317
--- /dev/null
+++ b/Annotations/Core/GenerateNoHeaderAttribute.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+public class GenerateNoHeaderAttribute : Attribute
+{ }
diff --git a/Annotations/Core/GenerateNoOptionalAttribute.cs b/Annotations/Core/GenerateNoOptionalAttribute.cs
new file mode 100644
index 00000000..f3818da3
--- /dev/null
+++ b/Annotations/Core/GenerateNoOptionalAttribute.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+public class GenerateNoOptionalAttribute : Attribute
+{ }
diff --git a/Annotations/Core/GenerateOnlySubTypesAttribute.cs b/Annotations/Core/GenerateOnlySubTypesAttribute.cs
new file mode 100644
index 00000000..11d34d26
--- /dev/null
+++ b/Annotations/Core/GenerateOnlySubTypesAttribute.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace KY.Generator
+{
+ [AttributeUsage(AttributeTargets.Class, Inherited = false)]
+ public class GenerateOnlySubTypesAttribute : Attribute
+ { }
+}
diff --git a/Annotations/Core/GenerateOption.cs b/Annotations/Core/GenerateOption.cs
deleted file mode 100644
index 90fc517e..00000000
--- a/Annotations/Core/GenerateOption.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace KY.Generator
-{
- public static class GenerateOption
- {
- public const string SkipHeader = "-skipHeader";
- }
-}
\ No newline at end of file
diff --git a/Annotations/Core/GenerateOptionAttribute.cs b/Annotations/Core/GenerateOptionAttribute.cs
deleted file mode 100644
index e538c007..00000000
--- a/Annotations/Core/GenerateOptionAttribute.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace KY.Generator
-{
- [AttributeUsage(AttributeTargets.Class)]
- public class GenerateOptionAttribute : Attribute, IGeneratorCommandAdditionalParameterAttribute
- {
- private readonly string[] options;
-
- public IEnumerable Commands
- {
- get
- {
- return new[]
- {
- new AttributeCommandConfiguration("*", this.options)
- };
- }
- }
-
- public GenerateOptionAttribute(params string[] options)
- {
- this.options = options;
- }
- }
-}
\ No newline at end of file
diff --git a/Annotations/Core/GeneratePreferInterfacesAttribute.cs b/Annotations/Core/GeneratePreferInterfacesAttribute.cs
index 07544810..cadd0ddb 100644
--- a/Annotations/Core/GeneratePreferInterfacesAttribute.cs
+++ b/Annotations/Core/GeneratePreferInterfacesAttribute.cs
@@ -1,20 +1,13 @@
using System;
using System.Collections.Generic;
-namespace KY.Generator
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+public class GeneratePreferInterfacesAttribute : Attribute, IGeneratorCommandAdditionalParameterAttribute
{
- [AttributeUsage(AttributeTargets.Class, Inherited = false)]
- public class GeneratePreferInterfacesAttribute : Attribute, IGeneratorCommandAdditionalParameterAttribute
- {
- public IEnumerable Commands
- {
- get
- {
- return new[]
- {
- new AttributeCommandConfiguration("angular-model", "-prefer-interfaces")
- };
- }
- }
- }
+ public IEnumerable Commands =>
+ [
+ new AttributeCommandConfiguration("angular-model", "-prefer-interfaces")
+ ];
}
diff --git a/Annotations/Core/GeneratePropertiesAsFieldsAttribute.cs b/Annotations/Core/GeneratePropertiesAsFieldsAttribute.cs
new file mode 100644
index 00000000..91b8e374
--- /dev/null
+++ b/Annotations/Core/GeneratePropertiesAsFieldsAttribute.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace KY.Generator
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+ public class GeneratePropertiesAsFieldsAttribute : Attribute
+ {
+ }
+}
diff --git a/Annotations/Core/GenerateRenameAttribute.cs b/Annotations/Core/GenerateRenameAttribute.cs
index 8809d7e5..f45fbcf6 100644
--- a/Annotations/Core/GenerateRenameAttribute.cs
+++ b/Annotations/Core/GenerateRenameAttribute.cs
@@ -1,36 +1,13 @@
using System;
-using System.Collections.Generic;
namespace KY.Generator
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
- public class GenerateRenameAttribute : Attribute, IGeneratorCommandAdditionalParameterAttribute
+ public class GenerateRenameAttribute : Attribute
{
public string Replace { get; }
public string With { get; }
- public IEnumerable Commands
- {
- get
- {
- return new[]
- {
- new AttributeCommandConfiguration("asp-read-controller", this.Parameters)
- };
- }
- }
-
- private List Parameters
- {
- get
- {
- List parameter = new List();
- parameter.Add($"-replace-name={this.Replace}");
- parameter.Add($"-replace-with-name={this.With}");
- return parameter;
- }
- }
-
public GenerateRenameAttribute(string replace, string with = null)
{
this.Replace = replace;
diff --git a/Annotations/Core/GenerateReturnTypeAttribute.cs b/Annotations/Core/GenerateReturnTypeAttribute.cs
new file mode 100644
index 00000000..d5090b3f
--- /dev/null
+++ b/Annotations/Core/GenerateReturnTypeAttribute.cs
@@ -0,0 +1,33 @@
+using System;
+
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
+public class GenerateReturnTypeAttribute : Attribute
+{
+ public string FileName { get; }
+ public Type Type { get; }
+ public string TypeName { get; set; }
+ public string OverrideName { get; set; }
+
+ ///
+ /// Changes the return type
+ ///
+ public GenerateReturnTypeAttribute(Type type)
+ {
+ this.Type = type;
+ }
+
+ ///
+ /// Changes the return type with an custom import
+ ///
+ /// Type used for the return of the property/method
+ /// File used for the using/import
+ /// Optional import type. Overrides the type on the using/import
+ public GenerateReturnTypeAttribute(string type, string fileName, string importType = null)
+ {
+ this.FileName = fileName;
+ this.TypeName = type;
+ this.OverrideName = importType;
+ }
+}
diff --git a/Annotations/Core/Option.cs b/Annotations/Core/Option.cs
deleted file mode 100644
index 40165c78..00000000
--- a/Annotations/Core/Option.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace KY.Generator
-{
- public enum Option
- {
- Inherit,
- Yes,
- No
- }
-}
\ No newline at end of file
diff --git a/Annotations/Csharp/GenerateCsharpModelAttribute.cs b/Annotations/Csharp/GenerateCsharpModelAttribute.cs
new file mode 100644
index 00000000..a05a0b3d
--- /dev/null
+++ b/Annotations/Csharp/GenerateCsharpModelAttribute.cs
@@ -0,0 +1,37 @@
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
+public class GenerateCsharpModelAttribute(string relativePath = "", bool onlySubTypes = false)
+ : Attribute, IGeneratorCommandAttribute
+{
+ public string RelativePath { get; } = relativePath;
+ public bool OnlySubTypes { get; } = onlySubTypes;
+
+ public IEnumerable Commands =>
+ [
+ new("reflection", this.Parameters)
+ ];
+
+ private IEnumerable Parameters
+ {
+ get
+ {
+ List parameter =
+ [
+ "-namespace=$NAMESPACE$",
+ "-name=$NAME$",
+ $"-language={OutputLanguage.Csharp}"
+ ];
+
+ if (this.RelativePath != string.Empty)
+ {
+ parameter.Add($"-relativePath={this.RelativePath}");
+ }
+ if (this.OnlySubTypes)
+ {
+ parameter.Add("-onlySubTypes");
+ }
+ return parameter;
+ }
+ }
+}
diff --git a/Annotations/KY.Generator.Annotations.csproj b/Annotations/KY.Generator.Annotations.csproj
index ef9371d1..e63fdda8 100644
--- a/Annotations/KY.Generator.Annotations.csproj
+++ b/Annotations/KY.Generator.Annotations.csproj
@@ -1,28 +1,37 @@
-
- netstandard2.0
- KY-Programming
- KY-Programming
- 7.6.0
- KY.Generator
- Annotations for KY-Generator
- 2021 - KY-Programming
- GPL-3.0-or-later
- https://generator.ky-programming.de
- https://ky-programming.de/images/logos/128.png
- https://github.com/KY-Programming/generator
-
- KY-Generator KY Generator Annotations
- KY.Generator
-
+
+ netstandard2.0
+ enable
+ enable
+ KY-Programming
+ KY-Programming
+ 10.0.0-preview.2
+ KY.Generator
+ Annotations for KY-Generator
+ 2025 - KY-Programming
+ README.md
+ MIT
+ https://generator.ky-programming.de
+ assets\icon.png
+ https://github.com/KY-Programming/generator
+ git
+ KY-Generator KY.Generator Annotations
+ KY.Generator
+ latest
+
-
- ..\bin\Debug
-
+
+ ..\bin\Debug
+
-
- ..\bin\Release
-
+
+ ..\bin\Release
+
+
+
+
+
+
diff --git a/Annotations/KY.Generator.Annotations.csproj.DotSettings b/Annotations/KY.Generator.Annotations.csproj.DotSettings
index f6563b48..61d9014f 100644
--- a/Annotations/KY.Generator.Annotations.csproj.DotSettings
+++ b/Annotations/KY.Generator.Annotations.csproj.DotSettings
@@ -1,6 +1,7 @@
True
True
+ True
False
True
True
diff --git a/Annotations/README.md b/Annotations/README.md
new file mode 100644
index 00000000..83f126af
--- /dev/null
+++ b/Annotations/README.md
@@ -0,0 +1,33 @@
+# KY.Generator.Annotations 
+
+[Documentation](https://generator.ky-programming.de) | [Getting Started](https://generator.ky-programming.de/start) | [Supported Platforms](https://generator.ky-programming.de/start/platforms) | [Need Help?](https://generator.ky-programming.de/start/help)
+
+## Generate via Attributes
+
+Annotations are attributes on classes, methods or properties.
+
+The annotations are found in the KY.Generator.Annotations package
+
+In example decorate an ASP.NET Core controller with an GenerateAngularService attribute to generate a full Angular service with all http request to your controller
+
+```
+using KY.Generator;
+...
+
+namespace ServiceFromAspNetCoreAnnotation.Controllers
+{
+ [GenerateAngularService("\\ClientApp\\src\\app\\services", "\\ClientApp\\src\\app\\models")]
+ [ApiController]
+ [Route("[controller]")]
+ public class WeatherForecastController : ControllerBase
+ {
+ ...
+ }
+}
+```
+
+## This is a library package!
+This package does not contains any directly executable assemblies. You need at least the [KY.Generator](https://www.nuget.org/packages/KY.Generator/)  package
+
+## Read More
+Continue reading with [Annotations Overview](https://generator.ky-programming.de/start/code/annotations)
diff --git a/Annotations/Reflection/GenerateAttribute.cs b/Annotations/Reflection/GenerateAttribute.cs
deleted file mode 100644
index 1907ee4c..00000000
--- a/Annotations/Reflection/GenerateAttribute.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace KY.Generator
-{
- [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
- public class GenerateAttribute : Attribute, IGeneratorCommandAttribute
- {
- public IEnumerable Commands
- {
- get { return new[] { new AttributeCommandConfiguration("reflection", this.Parameters) }; }
- }
-
- private IEnumerable Parameters
- {
- get
- {
- List parameter = new List
- {
- "-namespace=$NAMESPACE$",
- "-name=$NAME$"
- };
- if (this.Language != OutputLanguage.Inherit)
- {
- parameter.Add($"-language={this.Language}");
- }
- if (this.RelativePath != null)
- {
- parameter.Add($"-relativePath={this.RelativePath}");
- }
- if (this.SkipNamespace == Option.Yes)
- {
- parameter.Add("-skipNamespace");
- }
- else if (this.SkipNamespace == Option.No)
- {
- parameter.Add("-skipNamespace=false");
- }
- if (this.PropertiesToFields == Option.Yes)
- {
- parameter.Add("-propertiesToFields");
- }
- else if (this.PropertiesToFields == Option.No)
- {
- parameter.Add("-propertiesToFields=false");
- }
- if (this.FieldsToProperties == Option.Yes)
- {
- parameter.Add("-fieldsToProperties");
- }
- else if (this.FieldsToProperties == Option.No)
- {
- parameter.Add("-fieldsToProperties=false");
- }
- if (this.FormatNames == Option.Yes)
- {
- parameter.Add("-formatNames");
- }
- else if (this.FormatNames == Option.No)
- {
- parameter.Add("-formatNames=false");
- }
- if (this.SkipSelf == Option.Yes)
- {
- parameter.Add("-skipSelf");
- }
- else if (this.SkipSelf == Option.No)
- {
- parameter.Add("-skipSelf=false");
- }
- return parameter;
- }
- }
-
- public OutputLanguage Language { get; }
- public string RelativePath { get; }
- public Option SkipNamespace { get; }
- public Option PropertiesToFields { get; }
- public Option FieldsToProperties { get; }
- public Option FormatNames { get; }
- public Option SkipSelf { get; }
-
- public GenerateAttribute(OutputLanguage language = OutputLanguage.Inherit, string relativePath = null, Option skipNamespace = Option.Inherit, Option propertiesToFields = Option.Inherit, Option fieldsToProperties = Option.Inherit, Option formatNames = Option.Inherit, Option skipSelf = Option.Inherit)
- {
- this.Language = language;
- this.RelativePath = relativePath;
- this.SkipNamespace = skipNamespace;
- this.PropertiesToFields = propertiesToFields;
- this.FieldsToProperties = fieldsToProperties;
- this.FormatNames = formatNames;
- this.SkipSelf = skipSelf;
- }
- }
-}
\ No newline at end of file
diff --git a/Annotations/Reflection/GenerateIgnoreAttribute.cs b/Annotations/Reflection/GenerateIgnoreAttribute.cs
index 7f6c66cc..16079853 100644
--- a/Annotations/Reflection/GenerateIgnoreAttribute.cs
+++ b/Annotations/Reflection/GenerateIgnoreAttribute.cs
@@ -2,7 +2,7 @@
namespace KY.Generator
{
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, Inherited = false)]
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, Inherited = false)]
public class GenerateIgnoreAttribute : Attribute
{ }
-}
\ No newline at end of file
+}
diff --git a/Annotations/Reflection/GenerateIndexAttribute.cs b/Annotations/Reflection/GenerateIndexAttribute.cs
deleted file mode 100644
index ad7ac865..00000000
--- a/Annotations/Reflection/GenerateIndexAttribute.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-
-namespace KY.Generator
-{
- [AttributeUsage(AttributeTargets.Class, Inherited = false)]
- public class GenerateIndexAttribute : GenerateAttribute
- {
- public GenerateIndexAttribute(OutputLanguage language = OutputLanguage.Inherit, string relativePath = null, Option skipNamespace = Option.Inherit, Option propertiesToFields = Option.Inherit, Option fieldsToProperties = Option.Inherit, Option formatNames = Option.Inherit)
- : base(language, relativePath, skipNamespace, propertiesToFields, fieldsToProperties, formatNames, Option.Yes)
- {
- }
- }
-}
\ No newline at end of file
diff --git a/Annotations/TypeScript/GenerateForceIndexAttribute.cs b/Annotations/TypeScript/GenerateForceIndexAttribute.cs
new file mode 100644
index 00000000..adab8ba2
--- /dev/null
+++ b/Annotations/TypeScript/GenerateForceIndexAttribute.cs
@@ -0,0 +1,8 @@
+using System;
+
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+public class GenerateForceIndexAttribute : Attribute
+{
+}
\ No newline at end of file
diff --git a/Annotations/TypeScript/GenerateImportAttribute.cs b/Annotations/TypeScript/GenerateImportAttribute.cs
new file mode 100644
index 00000000..ec0941f0
--- /dev/null
+++ b/Annotations/TypeScript/GenerateImportAttribute.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+public class GenerateImportAttribute : Attribute
+{
+ public Type Type { get; }
+ public string FileName { get; }
+ public string TypeName { get; }
+
+ public GenerateImportAttribute(Type type, string fileName, string typeName)
+ {
+ this.Type = type;
+ this.FileName = fileName;
+ this.TypeName = typeName;
+ }
+}
diff --git a/Annotations/TypeScript/GenerateNoIndexAttribute.cs b/Annotations/TypeScript/GenerateNoIndexAttribute.cs
new file mode 100644
index 00000000..d20430ce
--- /dev/null
+++ b/Annotations/TypeScript/GenerateNoIndexAttribute.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
+public class GenerateNoIndexAttribute : Attribute
+{ }
\ No newline at end of file
diff --git a/Annotations/TypeScript/GenerateStrictAttribute.cs b/Annotations/TypeScript/GenerateStrictAttribute.cs
index e3c9f6db..1dd29d13 100644
--- a/Annotations/TypeScript/GenerateStrictAttribute.cs
+++ b/Annotations/TypeScript/GenerateStrictAttribute.cs
@@ -4,12 +4,13 @@
namespace KY.Generator
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, Inherited = false)]
- public class GenerateStrictAttribute : Attribute, IGeneratorCommandAdditionalParameterAttribute
+ public class GenerateStrictAttribute : Attribute
{
- public IEnumerable Commands { get; } = new[]
- {
- new AttributeCommandConfiguration("angular-service", "-strict"),
- new AttributeCommandConfiguration("angular-model", "-strict")
- };
+ public bool Strict { get; }
+
+ public GenerateStrictAttribute(bool strict = true)
+ {
+ this.Strict = strict;
+ }
}
}
diff --git a/Annotations/TypeScript/GenerateTypeScriptModelAttribute.cs b/Annotations/TypeScript/GenerateTypeScriptModelAttribute.cs
new file mode 100644
index 00000000..5b9e3cc4
--- /dev/null
+++ b/Annotations/TypeScript/GenerateTypeScriptModelAttribute.cs
@@ -0,0 +1,32 @@
+namespace KY.Generator;
+
+[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
+public class GenerateTypeScriptModelAttribute(string relativePath = "", bool onlySubTypes = false)
+ : Attribute, IGeneratorCommandAttribute
+{
+ public string RelativePath { get; } = relativePath;
+ public bool OnlySubTypes { get; } = onlySubTypes;
+
+ public IEnumerable Commands =>
+ [
+ new("reflection-read", "-namespace=$NAMESPACE$", "-name=$NAME$"),
+ new("typescript-model", this.Parameters)
+ ];
+
+ private IEnumerable Parameters
+ {
+ get
+ {
+ List parameter = [];
+ if (this.RelativePath != string.Empty)
+ {
+ parameter.Add($"-relativePath={this.RelativePath}");
+ }
+ if (this.OnlySubTypes)
+ {
+ parameter.Add("-onlySubTypes");
+ }
+ return parameter;
+ }
+ }
+}
diff --git a/AspDotNet.Tests/FullStageTests.cs b/AspDotNet.Tests/FullStageTests.cs
index 96116783..51646ce5 100644
--- a/AspDotNet.Tests/FullStageTests.cs
+++ b/AspDotNet.Tests/FullStageTests.cs
@@ -1,8 +1,6 @@
using System;
-using System.Collections.Generic;
using KY.Core.Dependency;
using KY.Generator.AspDotNet.Tests.Properties;
-using KY.Generator.Configuration;
using KY.Generator.Csharp;
using KY.Generator.Mappings;
using KY.Generator.Output;
@@ -21,7 +19,6 @@ public void Initialize()
{
this.resolver = new DependencyResolver();
this.resolver.Bind().ToSingleton();
- this.resolver.Bind().ToSingleton();
this.resolver.Create().Initialize();
this.resolver.Create().Initialize();
this.resolver.Create().Initialize();
diff --git a/AspDotNet.Tests/KY.Generator.AspDotNet.Tests.csproj b/AspDotNet.Tests/KY.Generator.AspDotNet.Tests.csproj
index 25c66ca0..463fa503 100644
--- a/AspDotNet.Tests/KY.Generator.AspDotNet.Tests.csproj
+++ b/AspDotNet.Tests/KY.Generator.AspDotNet.Tests.csproj
@@ -1,13 +1,15 @@
- netcoreapp2.1
+ net6.0
false
+
+ latest
-
+
@@ -15,7 +17,7 @@
-
+
diff --git a/AspDotNet.Tests/Properties/Resources.Designer.cs b/AspDotNet.Tests/Properties/Resources.Designer.cs
index dd4a31a6..c1e21a7e 100644
--- a/AspDotNet.Tests/Properties/Resources.Designer.cs
+++ b/AspDotNet.Tests/Properties/Resources.Designer.cs
@@ -118,7 +118,7 @@ internal static string generator_controller_generator {
///using System.Linq;
///using System.Web.Http;
///using KY.Generator;
- ///using KY.Generator.Output;
+ ///using KY.Generator.RelativePath;
///
///namespace KY.Generator.Test.Controllers
///{
@@ -144,7 +144,7 @@ internal static string GeneratorController_cs {
///using System.Collections.Generic;
///using System.Linq;
///using KY.Generator;
- ///using KY.Generator.Output;
+ ///using KY.Generator.RelativePath;
///using Microsoft.AspNetCore.Mvc;
///
///namespace KY.Generator.Test.Controllers
diff --git a/AspDotNet.Tests/more-tests.md b/AspDotNet.Tests/more-tests.md
index 4839b31b..8f1057d8 100644
--- a/AspDotNet.Tests/more-tests.md
+++ b/AspDotNet.Tests/more-tests.md
@@ -1 +1 @@
-More ASP.NET tests are found in [KY.Generator.Angular.Tests](https://github.com/KY-Programming/generator/tree/master/Angular.Tests)
\ No newline at end of file
+More ASP.NET tests are found in [KY.Generator.Angular.Tests](https://github.com/KY-Programming/generator/tree/master/Angular.Tests)
diff --git a/AspDotNet/AspDotNetModule.cs b/AspDotNet/AspDotNetModule.cs
index 6a56a350..e23dbd88 100644
--- a/AspDotNet/AspDotNetModule.cs
+++ b/AspDotNet/AspDotNetModule.cs
@@ -1,29 +1,17 @@
using KY.Core.Dependency;
using KY.Core.Module;
using KY.Generator.AspDotNet.Commands;
-using KY.Generator.AspDotNet.Configurations;
-using KY.Generator.AspDotNet.Readers;
-using KY.Generator.AspDotNet.Writers;
using KY.Generator.Command;
-using KY.Generator.Configuration;
-namespace KY.Generator.AspDotNet
+namespace KY.Generator.AspDotNet;
+
+public class AspDotNetModule : ModuleBase
{
- public class AspDotNetModule : ModuleBase
+ public AspDotNetModule(IDependencyResolver dependencyResolver)
+ : base(dependencyResolver)
{
- public AspDotNetModule(IDependencyResolver dependencyResolver)
- : base(dependencyResolver)
- {
- this.DependencyResolver.Bind().To();
- this.DependencyResolver.Bind().To();
- }
-
- public override void Initialize()
- {
- this.DependencyResolver.Get()
- .Map("asp")
- .Map("asp")
- .Map("asp-core");
- }
+ this.DependencyResolver.Get().Register(AspDotNetReadControllerCommand.Names);
+ this.DependencyResolver.Get().Register(AspDotNetReadHubCommand.Names);
+ this.DependencyResolver.Bind().ToSingleton();
}
}
\ No newline at end of file
diff --git a/AspDotNet/Commands/AspDotNetReadControllerCommand.cs b/AspDotNet/Commands/AspDotNetReadControllerCommand.cs
index df3cdca3..8ecfb732 100644
--- a/AspDotNet/Commands/AspDotNetReadControllerCommand.cs
+++ b/AspDotNet/Commands/AspDotNetReadControllerCommand.cs
@@ -2,33 +2,33 @@
using KY.Generator.AspDotNet.Configurations;
using KY.Generator.AspDotNet.Readers;
using KY.Generator.Command;
-using KY.Generator.Output;
+using KY.Generator.Command.Extensions;
-namespace KY.Generator.AspDotNet.Commands
+namespace KY.Generator.AspDotNet.Commands;
+
+internal class AspDotNetReadControllerCommand : GeneratorCommand
{
- internal class AspDotNetReadControllerCommand : GeneratorCommand
+ private readonly IDependencyResolver resolver;
+ public static string[] Names { get; } = [ToCommand(nameof(AspDotNetReadControllerCommand)), "asp-read-controller"];
+
+ public AspDotNetReadControllerCommand(IDependencyResolver resolver)
{
- private readonly IDependencyResolver resolver;
- public override string[] Names { get; } = { "asp-read-controller" };
+ this.resolver = resolver;
+ }
- public AspDotNetReadControllerCommand(IDependencyResolver resolver)
- {
- this.resolver = resolver;
- }
+ public override IGeneratorCommandResult Run()
+ {
+ Options options = this.resolver.Get();
+ GeneratorOptions generatorOptions = options.Get();
+ generatorOptions.SetFromParameter(this.Parameters);
- public override IGeneratorCommandResult Run(IOutput output)
- {
- AspDotNetReadConfiguration readConfiguration = new AspDotNetReadConfiguration();
- readConfiguration.AddHeader = !this.Parameters.SkipHeader;
- readConfiguration.Controller = new AspDotNetReadControllerConfiguration();
- readConfiguration.Controller.Namespace = this.Parameters.Namespace;
- readConfiguration.Controller.Name = this.Parameters.Name;
- readConfiguration.Controller.ReplaceName = this.Parameters.ReplaceName;
- readConfiguration.Controller.ReplaceWithName = this.Parameters.ReplaceWithName;
+ AspDotNetReadConfiguration readConfiguration = new();
+ readConfiguration.Controller = new AspDotNetReadControllerConfiguration();
+ readConfiguration.Controller.Namespace = this.Parameters.Namespace;
+ readConfiguration.Controller.Name = this.Parameters.Name;
- this.resolver.Create().Read(readConfiguration, this.TransferObjects);
+ this.resolver.Create().Read(readConfiguration);
- return this.Success();
- }
+ return this.Success();
}
}
diff --git a/AspDotNet/Commands/AspDotNetReadControllerCommandParameters.cs b/AspDotNet/Commands/AspDotNetReadControllerCommandParameters.cs
index 854400ef..9b2702df 100644
--- a/AspDotNet/Commands/AspDotNetReadControllerCommandParameters.cs
+++ b/AspDotNet/Commands/AspDotNetReadControllerCommandParameters.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using KY.Generator.Command;
+using KY.Generator.Command;
namespace KY.Generator.AspDotNet.Commands
{
@@ -7,7 +6,5 @@ internal class AspDotNetReadControllerCommandParameters : GeneratorCommandParame
{
public string Namespace { get; set; }
public string Name { get; set; }
- public List