Skip to content

Commit

Permalink
refactor(*): upgrade to v0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmet-cetinkaya committed Feb 7, 2024
1 parent c3b9e3e commit e467661
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static Process GetGitProcess()
gitProcess.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
gitProcess.StartInfo.UseShellExecute = false;
gitProcess.StartInfo.RedirectStandardOutput = true;
gitProcess.StartInfo.RedirectStandardError = true;
gitProcess.StartInfo.RedirectStandardError = false;
return gitProcess;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Core.CodeGen.CommandLine.Git;
using Core.CodeGen.File;
using MediatR;
using System.IO.Compression;
using System.Runtime.CompilerServices;

namespace Application.Features.Create.Commands.New;
Expand Down Expand Up @@ -36,7 +37,7 @@ [EnumeratorCancellation] CancellationToken cancellationToken
response.CurrentStatusMessage = "Cloning starter project and core packages...";
yield return response;
response.OutputMessage = null;
await cloneCorePackagesAndStarterProject(request.ProjectName);
await downloadStarterProject(request.ProjectName);
response.LastOperationMessage =
"Starter project has been cloned from 'https://github.com/kodlamaio-projects/nArchitecture'.";

Expand All @@ -48,9 +49,6 @@ [EnumeratorCancellation] CancellationToken cancellationToken
response.LastOperationMessage =
$"Project has been prepared with {request.ProjectName.ToPascalCase()}.";

DirectoryHelper.DeleteDirectory(
$"{Environment.CurrentDirectory}/{request.ProjectName}/.git"
);
ICollection<string> newFiles = DirectoryHelper.GetFilesInDirectoryTree(
root: $"{Environment.CurrentDirectory}/{request.ProjectName}",
searchPattern: "*"
Expand All @@ -70,10 +68,26 @@ [EnumeratorCancellation] CancellationToken cancellationToken
yield return response;
}

private async Task cloneCorePackagesAndStarterProject(string projectName) =>
await GitCommandHelper.RunAsync(
$"clone https://github.com/kodlamaio-projects/nArchitecture.git ./{projectName}"
private async Task downloadStarterProject(string projectName)
{
// Download zip on url
string releaseUrl =
"https://github.com/kodlamaio-projects/nArchitecture/archive/refs/tags/v0.1.0.zip";
using HttpClient client = new();
using HttpResponseMessage response = await client.GetAsync(releaseUrl);
response.EnsureSuccessStatusCode();
string zipPath = $"{Environment.CurrentDirectory}/{projectName}.zip";
await using Stream zipStream = await response.Content.ReadAsStreamAsync();
await using FileStream fileStream = new(zipPath, FileMode.Create, FileAccess.Write);
await zipStream.CopyToAsync(fileStream);
fileStream.Close();
ZipFile.ExtractToDirectory(zipPath, Environment.CurrentDirectory);
File.Delete(zipPath);
Directory.Move(
sourceDirName: $"{Environment.CurrentDirectory}/nArchitecture-0.1.0",
$"{Environment.CurrentDirectory}/{projectName}"
);
}

private async Task renameProject(string projectName)
{
Expand Down Expand Up @@ -314,50 +328,18 @@ await FileHelper.RemoveContentAsync(
filePath: $"{projectSourcePath}/WebAPI/Program.cs",
contents: new[]
{
"using Core.Security;",
"using Core.Security.Encryption;",
"using Core.Security.JWT;",
"using Core.WebAPI.Extensions.Swagger;",
"using Microsoft.AspNetCore.Authentication.JwtBearer;",
"using Microsoft.IdentityModel.Tokens;",
"using Microsoft.OpenApi.Models;",
"builder.Services.AddSecurityServices();",
@"const string tokenOptionsConfigurationSection = ""TokenOptions"";
TokenOptions tokenOptions =
builder.Configuration.GetSection(tokenOptionsConfigurationSection).Get<TokenOptions>()
?? throw new InvalidOperationException($""\""{tokenOptionsConfigurationSection}\"" section cannot found in configuration."");
builder.Services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = tokenOptions.Issuer,
ValidAudience = tokenOptions.Audience,
ValidateIssuerSigningKey = true,
IssuerSigningKey = SecurityKeyHelper.CreateSecurityKey(tokenOptions.SecurityKey)
};
});",
@"opt.AddSecurityDefinition(
name: ""Bearer"",
securityScheme: new OpenApiSecurityScheme
{
Name = ""Authorization"",
Type = SecuritySchemeType.Http,
Scheme = ""Bearer"",
BearerFormat = ""JWT"",
In = ParameterLocation.Header,
Description =
""JWT Authorization header using the Bearer scheme. Example: \""Authorization: Bearer YOUR_TOKEN\"". \r\n\r\n""
+ ""`Enter your token in the text input below.`""
}
);
opt.OperationFilter<BearerSecurityRequirementOperationFilter>();",
@"app.UseAuthentication();
app.UseAuthorization();"
"using Core.Security;\n",
"using Core.Security.Encryption;\n",
"using Core.Security.JWT;\n",
"using Core.WebAPI.Extensions.Swagger;\n",
"using Microsoft.AspNetCore.Authentication.JwtBearer;\n",
"using Microsoft.IdentityModel.Tokens;\n",
"using Microsoft.OpenApi.Models;\n",
"builder.Services.AddSecurityServices();\n",
"const string tokenOptionsConfigurationSection = \"TokenOptions\";\nTokenOptions tokenOptions =\n builder.Configuration.GetSection(tokenOptionsConfigurationSection).Get<TokenOptions>()\n ?? throw new InvalidOperationException($\"\\\"{tokenOptionsConfigurationSection}\\\" section cannot found in configuration.\");\nbuilder\n .Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)\n .AddJwtBearer(options =>\n {\n options.TokenValidationParameters = new TokenValidationParameters\n {\n ValidateIssuer = true,\n ValidateAudience = true,\n ValidateLifetime = true,\n ValidIssuer = tokenOptions.Issuer,\n ValidAudience = tokenOptions.Audience,\n ValidateIssuerSigningKey = true,\n IssuerSigningKey = SecurityKeyHelper.CreateSecurityKey(tokenOptions.SecurityKey)\n };\n });\n\n",
" opt.AddSecurityDefinition(\n name: \"Bearer\",\n securityScheme: new OpenApiSecurityScheme\n {\n Name = \"Authorization\",\n Type = SecuritySchemeType.Http,\n Scheme = \"Bearer\",\n BearerFormat = \"JWT\",\n In = ParameterLocation.Header,\n Description =\n \"JWT Authorization header using the Bearer scheme. Example: \\\"Authorization: Bearer YOUR_TOKEN\\\". \\r\\n\\r\\n\"\n + \"`Enter your token in the text input below.`\"\n }\n );\n opt.OperationFilter<BearerSecurityRequirementOperationFilter>();\n",
"app.UseAuthentication();\n",
"app.UseAuthorization();\n"
}
);
}
Expand All @@ -367,14 +349,35 @@ private async Task initializeGitRepository(string projectName)
Directory.SetCurrentDirectory($"./{projectName}");
await GitCommandHelper.RunAsync($"init");
await GitCommandHelper.RunAsync($"branch -m master main");
Directory.Delete($"{Environment.CurrentDirectory}/src/corePackages/");
await GitCommandHelper.RunAsync(
"submodule add https://github.com/kodlamaio-projects/nArchitecture.Core ./src/corePackages"
);
await downloadCorePackages(projectName);
await GitCommandHelper.CommitChangesAsync(
"chore: initial commit from nArchitecture.Gen"
);
Directory.SetCurrentDirectory("../");
}

private async Task downloadCorePackages(string projectName)
{
string releaseUrl =
"https://github.com/kodlamaio-projects/nArchitecture.Core/archive/refs/tags/v0.1.0.zip";
using HttpClient client = new();
using HttpResponseMessage response = await client.GetAsync(releaseUrl);
response.EnsureSuccessStatusCode();
string zipPath = $"{Environment.CurrentDirectory}/{projectName}.zip";
await using Stream zipStream = await response.Content.ReadAsStreamAsync();
await using FileStream fileStream = new(zipPath, FileMode.Create, FileAccess.Write);
await zipStream.CopyToAsync(fileStream);
fileStream.Close();
ZipFile.ExtractToDirectory(zipPath, Environment.CurrentDirectory);
File.Delete(zipPath);

string corePackagesDir = $"{Environment.CurrentDirectory}/src/corePackages";
if (Directory.Exists(corePackagesDir))
Directory.Delete(corePackagesDir, recursive: true);
Directory.Move(
sourceDirName: $"{Environment.CurrentDirectory}/nArchitecture.Core-0.1.0",
$"{Environment.CurrentDirectory}/src/corePackages"
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class Settings : CommandSettings
[CommandArgument(position: 0, template: "[ProjectName]")]
public string? ProjectName { get; set; }

[CommandOption("--no-security")]
[CommandOption("--security")]
public bool IsThereSecurityMechanism { get; set; }

public void CheckProjectNameArgument()
Expand All @@ -30,7 +30,7 @@ public void CheckIsThereSecurityMechanismArgument()
return;
IsThereSecurityMechanism = AnsiConsole.Confirm(
prompt: "Do you want to add security mechanism to your project?",
defaultValue: true
defaultValue: false
);
}
}
Expand Down
25 changes: 3 additions & 22 deletions src/nArchGen/Domain/Domain.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,14 @@
</PropertyGroup>

<ItemGroup>
<Folder Include="Templates\Crud\Folders\" />
<ProjectReference Include="..\..\corePackages\Core.CodeGen\Core.CodeGen.csproj" />
<ProjectReference Include="..\..\corePackages\Core.CrossCuttingConcerns\Core.CrossCuttingConcerns.csproj" />
</ItemGroup>

<ItemGroup>
<ContentWithTargetPath Include="Templates\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>Templates\%(RecursiveDir)\%(Filename)%(Extension)</TargetPath>
</ContentWithTargetPath>
</ItemGroup>

<ItemGroup>
<ContentWithTargetPath Remove="Templates\CRUD\Folders\Application\Services\PLURAL_ENTITY\ENTITYManager.cs.sbn" />
<ContentWithTargetPath Remove="Templates\CRUD\Folders\Application\Services\PLURAL_ENTITY\IENTITYService.cs.sbn" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\corePackages\Core.CodeGen\Core.CodeGen.csproj" />
<ProjectReference Include="..\..\corePackages\Core.CrossCuttingConcerns\Core.CrossCuttingConcerns.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="Templates\CRUD\Folders\Application\Services\PLURAL_ENTITY\ENTITYManager.cs.sbn">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Templates\CRUD\Folders\Application\Services\PLURAL_ENTITY\IENTITYService.cs.sbn">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class Create{{ entity.name | string.pascalcase }}Command : IRequest<Creat
{%{{}%}{{ for propertyItem in entity.properties }}
public {{ propertyItem.type }} {{ propertyItem.name | string.pascalcase }} { get; set; }{{ end }}{{ if is_secured_operation_used }}

public string[] Roles => new[] { Admin, Write, {{ entity.name | string.pascalcase | string.plural }}OperationClaims.Create };{{ end }}{{ if is_caching_used }}
public string[] Roles => [Admin, Write, {{ entity.name | string.pascalcase | string.plural }}OperationClaims.Create];{{ end }}{{ if is_caching_used }}

public bool BypassCache { get; }
public string? CacheKey { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class Delete{{ entity.name | string.pascalcase }}Command : IRequest<Delet
{
public {{ entity.id_type }} Id { get; set; }{{ if is_secured_operation_used }}

public string[] Roles => new[] { Admin, Write, {{ entity.name | string.pascalcase | string.plural }}OperationClaims.Delete };{{ end }}{{ if is_caching_used }}
public string[] Roles => [Admin, Write, {{ entity.name | string.pascalcase | string.plural }}OperationClaims.Delete];{{ end }}{{ if is_caching_used }}

public bool BypassCache { get; }
public string? CacheKey { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class Update{{ entity.name | string.pascalcase }}Command : IRequest<Updat
public {{ entity.id_type }} Id { get; set; }{{ for propertyItem in entity.properties }}
public {{ propertyItem.type }} {{ propertyItem.name | string.pascalcase }} { get; set; }{{ end }}{{ if is_secured_operation_used }}

public string[] Roles => new[] { Admin, Write, {{ entity.name | string.pascalcase | string.plural }}OperationClaims.Update };{{ end }}{{ if is_caching_used }}
public string[] Roles => [Admin, Write, {{ entity.name | string.pascalcase | string.plural }}OperationClaims.Update];{{ end }}{{ if is_caching_used }}

public bool BypassCache { get; }
public string? CacheKey { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ namespace Application.Features.{{ entity.name | string.pascalcase | string.plura

public static class {{ entity.name | string.pascalcase | string.plural }}BusinessMessages
{
public const string {{ entity.name | string.pascalcase }}NotExists = "{{ entity.name | string.words | string.downcase | string.capitalize }} not exists.";
public const string SectionName = "{{ entity.name | string.pascalcase }}";

public const string {{ entity.name | string.pascalcase }}NotExists = "{{ entity.name | string.pascalcase }}NotExists";
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class GetById{{ entity.name | string.pascalcase }}Query : IRequest<GetByI
{
public {{ entity.id_type }} Id { get; set; }{{ if is_secured_operation_used }}

public string[] Roles => new[] { Admin, Read };{{ end }}
public string[] Roles => [Admin, Read];{{ end }}

public class GetById{{ entity.name | string.pascalcase }}QueryHandler : IRequestHandler<GetById{{ entity.name | string.pascalcase }}Query, GetById{{ entity.name | string.pascalcase }}Response>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class GetList{{ entity.name | string.pascalcase }}Query : IRequest<GetLis
{
public PageRequest PageRequest { get; set; }{{ if is_secured_operation_used }}

public string[] Roles => new[] { Admin, Read };{{ end }}{{ if is_caching_used }}
public string[] Roles => [Admin, Read];{{ end }}{{ if is_caching_used }}

public bool BypassCache { get; }
public string? CacheKey => $"GetList{{ entity.name | string.pascalcase | string.plural }}({PageRequest.PageIndex},{PageRequest.PageSize})";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ entity.name | string.pascalcase }}NotExists: "{{ entity.name | string.words | string.downcase | string.capitalize }} don't exists."
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,32 @@
using Application.Services.Repositories;
using Core.Application.Rules;
using Core.CrossCuttingConcerns.Exceptions.Types;
using Core.Localization.Abstraction;
using Domain.Entities;

namespace Application.Features.{{ entity.name | string.pascalcase | string.plural }}.Rules;

public class {{ entity.name | string.pascalcase }}BusinessRules : BaseBusinessRules
{
private readonly I{{ entity.name | string.pascalcase }}Repository _{{ entity.name | string.camelcase }}Repository;
private readonly ILocalizationService _localizationService;

public {{ entity.name | string.pascalcase }}BusinessRules(I{{ entity.name | string.pascalcase }}Repository {{ entity.name | string.camelcase }}Repository)
public {{ entity.name | string.pascalcase }}BusinessRules(I{{ entity.name | string.pascalcase }}Repository {{ entity.name | string.camelcase }}Repository, ILocalizationService localizationService)
{
_{{ entity.name | string.camelcase }}Repository = {{ entity.name | string.camelcase }}Repository;
_localizationService = localizationService;
}

public Task {{ entity.name | string.pascalcase }}ShouldExistWhenSelected({{ entity.name | string.pascalcase }}? {{ entity.name | string.camelcase }})
private async Task throwBusinessException(string messageKey)
{
string message = await _localizationService.GetLocalizedAsync(messageKey, {{ entity.name | string.pascalcase | string.plural }}BusinessMessages.SectionName);
throw new BusinessException(message);
}

public async Task {{ entity.name | string.pascalcase }}ShouldExistWhenSelected({{ entity.name | string.pascalcase }}? {{ entity.name | string.camelcase }})
{
if ({{ entity.name | string.camelcase }} == null)
throw new BusinessException({{ entity.name | string.pascalcase | string.plural }}BusinessMessages.{{ entity.name | string.pascalcase }}NotExists);
return Task.CompletedTask;
await throwBusinessException({{ entity.name | string.pascalcase | string.plural }}BusinessMessages.{{ entity.name | string.pascalcase }}NotExists);
}

public async Task {{ entity.name | string.pascalcase }}IdShouldExistWhenSelected({{ entity.id_type }} id, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Application.Features.{{ feature_name }}.Commands.{{ command_name | str
public class {{ command_name | string.pascalcase }}Command : IRequest<{{ command_name | string.pascalcase }}Response>{{ if is_secured_operation_used }}, ISecuredRequest{{ end }}{{ if is_caching_used }}, ICacheRemoverRequest{{ end }}{{ if is_logging_used }}, ILoggableRequest{{ end }}{{ if is_transaction_used }}, ITransactionalRequest{{ end }}
{%{{}%}{{ if is_secured_operation_used }}

public string[] Roles => new[] { Admin, Write, {{ feature_name | string.pascalcase }}OperationClaims.{{ command_name }} };{{ end }}{{ if is_caching_used }}
public string[] Roles => [Admin, Write, {{ feature_name | string.pascalcase }}OperationClaims.{{ command_name }}];{{ end }}{{ if is_caching_used }}

public bool BypassCache { get; }
public string? CacheKey { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ using static Application.Features.{{ feature_name }}.Constants.{{ feature_name }

namespace Application.Features.{{ feature_name }}.Queries.{{ query_name | string.pascalcase }};

public class {{ query_name | string.pascalcase }}Query : IRequest<{{ query_name | string.pascalcase }}Response>{{ if is_secured_operation_used }}, ISecuredRequest{{ end }}{{ if is_caching_used }}, ICacheRemoverRequest{{ end }}{{ if is_logging_used }}, ILoggableRequest{{ end }}
public class {{ query_name | string.pascalcase }}Query : IRequest<{{ query_name | string.pascalcase }}Response>{{ if is_secured_operation_used }}, ISecuredRequest{{ end }}{{ if is_caching_used }}, ICachableRequest{{ end }}{{ if is_logging_used }}, ILoggableRequest{{ end }}
{%{{}%}{{ if is_secured_operation_used }}

public string[] Roles => new[] { Admin, Read, {{ feature_name | string.pascalcase }}OperationClaims.{{ query_name }} };{{ end }}{{ if is_caching_used }}
public string[] Roles => [Admin, Read, {{ feature_name | string.pascalcase }}OperationClaims.{{ query_name }}];{{ end }}{{ if is_caching_used }}

public bool BypassCache { get; }
public string? CacheKey => $"{{ query_name }}";
Expand Down

0 comments on commit e467661

Please sign in to comment.