netcore-blueprint 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Modules/__MODULE__/__ITEM__Module.API/Controllers/Public/__ITEM__Controller.cs +65 -0
- package/Modules/__MODULE__/__ITEM__Module.API/Mappers/Dto__ITEM__MappingProfile.cs +26 -0
- package/Modules/__MODULE__/__ITEM__Module.API/__ITEM__Module.API.csproj +27 -0
- package/Modules/__MODULE__/__ITEM__Module.API/__ITEM__Module.cs +24 -0
- package/Modules/__MODULE__/__ITEM__Module.Core/Dtos/Admin/__ITEM__RequestDto.cs +8 -0
- package/Modules/__MODULE__/__ITEM__Module.Core/Dtos/Admin/__ITEM__ResponseDto.cs +8 -0
- package/Modules/__MODULE__/__ITEM__Module.Core/Entities/__ITEM__.cs +8 -0
- package/Modules/__MODULE__/__ITEM__Module.Core/Interfaces/API/I__ITEM__Service.cs +9 -0
- package/Modules/__MODULE__/__ITEM__Module.Core/Interfaces/SPI/I__ITEM__Infra.cs +9 -0
- package/Modules/__MODULE__/__ITEM__Module.Core/Services/__ITEM__Service.cs +20 -0
- package/Modules/__MODULE__/__ITEM__Module.Core/__ITEM__CoreDependencyInjection.cs +19 -0
- package/Modules/__MODULE__/__ITEM__Module.Core/__ITEM__Module.Core.csproj +18 -0
- package/Modules/__MODULE__/__ITEM__Module.Infrastructure/Database/Seeder.cs +21 -0
- package/Modules/__MODULE__/__ITEM__Module.Infrastructure/Database/__ITEM__Configuration.cs +22 -0
- package/Modules/__MODULE__/__ITEM__Module.Infrastructure/Services/MySQL__ITEM__Infra.cs +16 -0
- package/Modules/__MODULE__/__ITEM__Module.Infrastructure/__ITEM__InfraDependencyInjection.cs +21 -0
- package/Modules/__MODULE__/__ITEM__Module.Infrastructure/__ITEM__Module.Infrastructure.csproj +14 -0
- package/README.md +2 -1
- package/bin/copy-module.js +123 -0
- package/bin/create-module.js +1 -1
- package/lib/replacer.js +45 -0
- package/package.json +5 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
using AutoMapper;
|
|
2
|
+
using __ITEM__Module.Core.Dtos.Admin;
|
|
3
|
+
using __ITEM__Module.Core.Entities;
|
|
4
|
+
using __ITEM__Module.Core.Interfaces.API;
|
|
5
|
+
using Microsoft.AspNetCore.Http;
|
|
6
|
+
using Microsoft.AspNetCore.Mvc;
|
|
7
|
+
using Microsoft.Extensions.Logging;
|
|
8
|
+
using Shared.Core.Shared.Models;
|
|
9
|
+
using System.Diagnostics;
|
|
10
|
+
|
|
11
|
+
namespace __ITEM__Module.API.Controllers.Public
|
|
12
|
+
{
|
|
13
|
+
/// <summary>
|
|
14
|
+
/// __ITEM__ Controller
|
|
15
|
+
/// </summary>
|
|
16
|
+
[Route("rest/v{version:apiVersion}/__item__s")]
|
|
17
|
+
[Produces("application/json")]
|
|
18
|
+
[ApiController]
|
|
19
|
+
public class __ITEM__Controller : Controller
|
|
20
|
+
{
|
|
21
|
+
private readonly IMapper _mapper;
|
|
22
|
+
private ILogger _logger;
|
|
23
|
+
private readonly I__ITEM__Service ___item__Service;
|
|
24
|
+
|
|
25
|
+
/// <summary>
|
|
26
|
+
/// Constructor
|
|
27
|
+
/// </summary>
|
|
28
|
+
/// <param name="logger"></param>
|
|
29
|
+
/// <param name="mapper"></param>
|
|
30
|
+
/// <param name="__item__Service"></param>
|
|
31
|
+
public __ITEM__Controller(
|
|
32
|
+
ILogger<__ITEM__Controller> logger,
|
|
33
|
+
IMapper mapper,
|
|
34
|
+
I__ITEM__Service __item__Service)
|
|
35
|
+
{
|
|
36
|
+
_mapper = mapper;
|
|
37
|
+
_logger = logger;
|
|
38
|
+
___item__Service = __item__Service;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/// <summary>
|
|
42
|
+
/// Get __item__s
|
|
43
|
+
/// </summary>
|
|
44
|
+
/// <param name="pagingParams"></param>
|
|
45
|
+
/// <returns></returns>
|
|
46
|
+
[HttpGet]
|
|
47
|
+
[ProducesResponseType(typeof(PagerData<__ITEM__ResponseDto>), StatusCodes.Status200OK)]
|
|
48
|
+
public async Task<IActionResult> Get__ITEM__s([FromQuery] PagingParams pagingParams)
|
|
49
|
+
{
|
|
50
|
+
_logger.LogInformation($"Start getting __item__s");
|
|
51
|
+
var stopwatch = Stopwatch.StartNew();
|
|
52
|
+
|
|
53
|
+
PagerData<__ITEM__> __item__s = await ___item__Service.Get__ITEM__sAsync(pagingParams);
|
|
54
|
+
PagerData<__ITEM__ResponseDto> __item__Response = _mapper.Map<PagerData<__ITEM__ResponseDto>>(__item__s);
|
|
55
|
+
|
|
56
|
+
// Add custom headers
|
|
57
|
+
Response.Headers.Append("X-WP-Total", __item__s.TotalRecords.ToString());
|
|
58
|
+
|
|
59
|
+
stopwatch.Stop();
|
|
60
|
+
_logger.LogInformation($"Getting __item__s done in {stopwatch.ElapsedMilliseconds}");
|
|
61
|
+
|
|
62
|
+
return Ok(__item__Response.__ITEM__s);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
using AutoMapper;
|
|
2
|
+
using __ITEM__Module.Core.Dtos.Admin;
|
|
3
|
+
using __ITEM__Module.Core.Entities;
|
|
4
|
+
using Shared.Core.Shared.Models;
|
|
5
|
+
|
|
6
|
+
namespace __ITEM__Module.API.Mappers
|
|
7
|
+
{
|
|
8
|
+
/// <summary>
|
|
9
|
+
/// Dto__ITEM__MappingProfile
|
|
10
|
+
/// </summary>
|
|
11
|
+
public class Dto__ITEM__MappingProfile : Profile
|
|
12
|
+
{
|
|
13
|
+
/// <summary>
|
|
14
|
+
/// Constructor
|
|
15
|
+
/// </summary>
|
|
16
|
+
public Dto__ITEM__MappingProfile()
|
|
17
|
+
{
|
|
18
|
+
CreateMap<__ITEM__, __ITEM__RequestDto>().ReverseMap();
|
|
19
|
+
|
|
20
|
+
CreateMap<PagerData<__ITEM__>, PagerData<__ITEM__ResponseDto>>().ReverseMap();
|
|
21
|
+
|
|
22
|
+
CreateMap<__ITEM__, __ITEM__ResponseDto>()
|
|
23
|
+
.ReverseMap();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
|
+
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<TargetFramework>net10.0</TargetFramework>
|
|
5
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
6
|
+
<Nullable>enable</Nullable>
|
|
7
|
+
</PropertyGroup>
|
|
8
|
+
|
|
9
|
+
<__ITEM__Group>
|
|
10
|
+
<Folder Include="Controllers\Admin\" />
|
|
11
|
+
</__ITEM__Group>
|
|
12
|
+
|
|
13
|
+
<__ITEM__Group>
|
|
14
|
+
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.1" />
|
|
15
|
+
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.1" />
|
|
16
|
+
<PackageReference Include="AutoMapper" Version="16.0.0" />
|
|
17
|
+
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="10.0.2" />
|
|
18
|
+
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.3.9" />
|
|
19
|
+
</__ITEM__Group>
|
|
20
|
+
|
|
21
|
+
<__ITEM__Group>
|
|
22
|
+
<ProjectReference Include="..\__ITEM__Module.Core\__ITEM__Module.Core.csproj" />
|
|
23
|
+
<ProjectReference Include="..\__ITEM__Module.Infrastructure\__ITEM__Module.Infrastructure.csproj" />
|
|
24
|
+
<ProjectReference Include="..\Shared.Core\Shared.Core.csproj" />
|
|
25
|
+
</__ITEM__Group>
|
|
26
|
+
|
|
27
|
+
</Project>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
using __ITEM__Module.API.Controllers.Public;
|
|
2
|
+
using __ITEM__Module.API.Mappers;
|
|
3
|
+
using __ITEM__Module.Core;
|
|
4
|
+
using __ITEM__Module.Infrastructure;
|
|
5
|
+
using Microsoft.Extensions.Configuration;
|
|
6
|
+
using Microsoft.Extensions.DependencyInjection;
|
|
7
|
+
using Shared.Core.Interfaces.Modules;
|
|
8
|
+
using System.Reflection;
|
|
9
|
+
|
|
10
|
+
namespace __ITEM__Module.API
|
|
11
|
+
{
|
|
12
|
+
public class __ITEM__Module : IModule
|
|
13
|
+
{
|
|
14
|
+
public string Name => "__ITEM__";
|
|
15
|
+
public void Register(IServiceCollection services, IConfiguration config)
|
|
16
|
+
{
|
|
17
|
+
__ITEM__CoreDependencyInjection.AddModule(services);
|
|
18
|
+
__ITEM__InfraDependencyInjection.AddModule(services);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public Assembly ApiAssembly => typeof(__ITEM__Controller).Assembly;
|
|
22
|
+
public Assembly MappingAssembly => typeof(Dto__ITEM__MappingProfile).Assembly;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
using __ITEM__Module.Core.Entities;
|
|
2
|
+
using __ITEM__Module.Core.Interfaces.API;
|
|
3
|
+
using __ITEM__Module.Core.Interfaces.SPI;
|
|
4
|
+
using Microsoft.Extensions.Logging;
|
|
5
|
+
using Shared.Core.Interfaces.SPI;
|
|
6
|
+
using Shared.Core.Services;
|
|
7
|
+
|
|
8
|
+
namespace __ITEM__Module.Core.Services
|
|
9
|
+
{
|
|
10
|
+
public class __ITEM__Service : __ITEM__Service<__ITEM__>, I__ITEM__Service
|
|
11
|
+
{
|
|
12
|
+
private readonly I__ITEM__Infra _userInfra;
|
|
13
|
+
public __ITEM__Service(ILogger<__ITEM__Service> logger,
|
|
14
|
+
IRepositoryFactory<__ITEM__> repositoryFactory,
|
|
15
|
+
I__ITEM__Infra userInfra) : base(logger, repositoryFactory)
|
|
16
|
+
{
|
|
17
|
+
_userInfra = userInfra;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
using __ITEM__Module.Core.Interfaces.API;
|
|
2
|
+
using __ITEM__Module.Core.Services;
|
|
3
|
+
using Microsoft.Extensions.DependencyInjection;
|
|
4
|
+
using Shared.Core.Interfaces.API;
|
|
5
|
+
using Shared.Core.Services;
|
|
6
|
+
|
|
7
|
+
namespace __ITEM__Module.Core
|
|
8
|
+
{
|
|
9
|
+
public static class __ITEM__CoreDependencyInjection
|
|
10
|
+
{
|
|
11
|
+
public static IServiceCollection AddModule(
|
|
12
|
+
this IServiceCollection services)
|
|
13
|
+
{
|
|
14
|
+
services.AddScoped(typeof(I__ITEM__Service<>), typeof(__ITEM__Service<>));
|
|
15
|
+
services.AddScoped<I__ITEM__Service, __ITEM__Service>();
|
|
16
|
+
return services;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
|
+
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<TargetFramework>net10.0</TargetFramework>
|
|
5
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
6
|
+
<Nullable>enable</Nullable>
|
|
7
|
+
</PropertyGroup>
|
|
8
|
+
|
|
9
|
+
<__ITEM__Group>
|
|
10
|
+
<ProjectReference Include="..\Shared.Core\Shared.Core.csproj" />
|
|
11
|
+
</__ITEM__Group>
|
|
12
|
+
|
|
13
|
+
<__ITEM__Group>
|
|
14
|
+
<Folder Include="Dtos\Public\" />
|
|
15
|
+
<Folder Include="Enums\" />
|
|
16
|
+
</__ITEM__Group>
|
|
17
|
+
|
|
18
|
+
</Project>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
using __ITEM__Module.Core.Entities;
|
|
2
|
+
using Microsoft.EntityFrameworkCore;
|
|
3
|
+
using Shared.Core.Enums;
|
|
4
|
+
using Shared.Core.Interfaces.SPI;
|
|
5
|
+
|
|
6
|
+
namespace __ITEM__Module.Infrastructure.Database
|
|
7
|
+
{
|
|
8
|
+
public class Seeder : IModuleSeeder
|
|
9
|
+
{
|
|
10
|
+
public void Seed(ModelBuilder modelBuilder)
|
|
11
|
+
{
|
|
12
|
+
modelBuilder.Entity<__ITEM__>().HasData(
|
|
13
|
+
new __ITEM__
|
|
14
|
+
{
|
|
15
|
+
Id = Guid.Parse("11111111-1111-1111-1111-111111111111"),
|
|
16
|
+
Status = EntityStatus.Active,
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
using __ITEM__Module.Core.Entities;
|
|
2
|
+
using Microsoft.EntityFrameworkCore;
|
|
3
|
+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
4
|
+
|
|
5
|
+
namespace __ITEM__Module.Infrastructure.Database
|
|
6
|
+
{
|
|
7
|
+
internal class __ITEM__Configuration : IEntityTypeConfiguration<__ITEM__>
|
|
8
|
+
{
|
|
9
|
+
public void Configure(EntityTypeBuilder<__ITEM__> builder)
|
|
10
|
+
{
|
|
11
|
+
// Table
|
|
12
|
+
builder.ToTable("__ITEM__s");
|
|
13
|
+
|
|
14
|
+
// Primary key
|
|
15
|
+
builder.HasKey(x => x.Id);
|
|
16
|
+
|
|
17
|
+
// BaseEntity (nếu có)
|
|
18
|
+
builder.Property(x => x.Id)
|
|
19
|
+
.IsRequired();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
using __ITEM__Module.Core.Entities;
|
|
2
|
+
using __ITEM__Module.Core.Interfaces.SPI;
|
|
3
|
+
using Microsoft.Extensions.Logging;
|
|
4
|
+
using Shared.Infrastructure.Database;
|
|
5
|
+
using Shared.Infrastructure.Services.MySQL;
|
|
6
|
+
|
|
7
|
+
namespace __ITEM__Module.Infrastructure.Services
|
|
8
|
+
{
|
|
9
|
+
public class MySQL__ITEM__Infra : MySQL__ITEM__Infra<__ITEM__>, I__ITEM__Infra
|
|
10
|
+
{
|
|
11
|
+
public MySQL__ITEM__Infra(MyDbContext dbContext, ILogger<MySQL__ITEM__Infra> logger)
|
|
12
|
+
: base(dbContext, logger)
|
|
13
|
+
{
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
using __ITEM__Module.Core.Interfaces.SPI;
|
|
2
|
+
using __ITEM__Module.Infrastructure.Database;
|
|
3
|
+
using __ITEM__Module.Infrastructure.Services;
|
|
4
|
+
using Microsoft.Extensions.DependencyInjection;
|
|
5
|
+
using Shared.Core.Interfaces.SPI;
|
|
6
|
+
using Shared.Infrastructure.Services.MySQL;
|
|
7
|
+
|
|
8
|
+
namespace __ITEM__Module.Infrastructure
|
|
9
|
+
{
|
|
10
|
+
public static class __ITEM__InfraDependencyInjection
|
|
11
|
+
{
|
|
12
|
+
public static IServiceCollection AddModule(
|
|
13
|
+
this IServiceCollection services)
|
|
14
|
+
{
|
|
15
|
+
services.AddScoped<IModuleSeeder, Seeder>();
|
|
16
|
+
services.AddScoped<I__ITEM__Infra, MySQL__ITEM__Infra>();
|
|
17
|
+
services.AddScoped(typeof(I__ITEM__Infra<>), typeof(MySQL__ITEM__Infra<>));
|
|
18
|
+
return services;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
|
+
|
|
3
|
+
<PropertyGroup>
|
|
4
|
+
<TargetFramework>net10.0</TargetFramework>
|
|
5
|
+
<ImplicitUsings>enable</ImplicitUsings>
|
|
6
|
+
<Nullable>enable</Nullable>
|
|
7
|
+
</PropertyGroup>
|
|
8
|
+
|
|
9
|
+
<__ITEM__Group>
|
|
10
|
+
<ProjectReference Include="..\__ITEM__Module.Core\__ITEM__Module.Core.csproj" />
|
|
11
|
+
<ProjectReference Include="..\Shared.Infrastructure\Shared.Infrastructure.csproj" />
|
|
12
|
+
</__ITEM__Group>
|
|
13
|
+
|
|
14
|
+
</Project>
|
package/README.md
CHANGED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const moduleName = process.argv[2];
|
|
8
|
+
|
|
9
|
+
if (!moduleName) {
|
|
10
|
+
console.error("❌ Usage: copy-module <ModuleName>");
|
|
11
|
+
console.error(" Example: copy-module Item");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Assume current working directory is Modules/
|
|
16
|
+
const modulesPath = process.cwd();
|
|
17
|
+
const templateRoot = path.join(modulesPath, '_MODULE_');
|
|
18
|
+
const targetModuleRoot = path.join(modulesPath, `${moduleName}Module`);
|
|
19
|
+
|
|
20
|
+
const solutionFile = findSolutionFileUpwards(modulesPath);
|
|
21
|
+
|
|
22
|
+
if (!fs.existsSync(templateRoot)) {
|
|
23
|
+
console.error(`❌ Template folder not found: ${templateRoot}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!solutionFile) {
|
|
28
|
+
console.error("❌ Could not find .sln file in parent directories.");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log(`🚀 Creating module: ${moduleName}Module`);
|
|
33
|
+
console.log(`📁 From template: ${templateRoot}`);
|
|
34
|
+
console.log(`🧩 Solution: ${solutionFile}`);
|
|
35
|
+
|
|
36
|
+
// 1. Create module root
|
|
37
|
+
fs.mkdirSync(targetModuleRoot, { recursive: true });
|
|
38
|
+
|
|
39
|
+
// 2. Create projects
|
|
40
|
+
const projects = [
|
|
41
|
+
{ name: `${moduleName}Module.API`, type: 'webapi' },
|
|
42
|
+
{ name: `${moduleName}Module.Core`, type: 'classlib' },
|
|
43
|
+
{ name: `${moduleName}Module.Infrastructure`, type: 'classlib' },
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
projects.forEach(p => {
|
|
47
|
+
const projectPath = path.join(targetModuleRoot, p.name);
|
|
48
|
+
|
|
49
|
+
console.log(`📦 Creating project: ${p.name}`);
|
|
50
|
+
execSync(`dotnet new ${p.type} -n ${p.name}`, {
|
|
51
|
+
cwd: targetModuleRoot,
|
|
52
|
+
stdio: 'inherit'
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// 3. Copy template files
|
|
56
|
+
const templateSubFolder = getTemplateSubFolder(p.name, templateRoot);
|
|
57
|
+
|
|
58
|
+
if (fs.existsSync(templateSubFolder)) {
|
|
59
|
+
console.log(`📄 Copying template from: ${templateSubFolder}`);
|
|
60
|
+
copyRecursive(templateSubFolder, projectPath);
|
|
61
|
+
} else {
|
|
62
|
+
console.warn(`⚠️ Template subfolder not found: ${templateSubFolder}`);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// 4. Add projects to solution
|
|
67
|
+
projects.forEach(p => {
|
|
68
|
+
const csproj = path.join(
|
|
69
|
+
targetModuleRoot,
|
|
70
|
+
p.name,
|
|
71
|
+
`${p.name}.csproj`
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
console.log(`➕ Adding to solution: ${csproj}`);
|
|
75
|
+
execSync(`dotnet sln "${solutionFile}" add "${csproj}"`, {
|
|
76
|
+
stdio: 'inherit'
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
console.log(`🎉 Module "${moduleName}Module" created successfully!`);
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
// ---------------- Helpers ----------------
|
|
84
|
+
|
|
85
|
+
function getTemplateSubFolder(projectName, templateRoot) {
|
|
86
|
+
if (projectName.endsWith('.API')) return path.join(templateRoot, 'API');
|
|
87
|
+
if (projectName.endsWith('.Core')) return path.join(templateRoot, 'Core');
|
|
88
|
+
if (projectName.endsWith('.Infrastructure')) return path.join(templateRoot, 'Infrastructure');
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function copyRecursive(src, dest) {
|
|
93
|
+
if (!fs.existsSync(dest)) {
|
|
94
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
98
|
+
|
|
99
|
+
for (const entry of entries) {
|
|
100
|
+
const srcPath = path.join(src, entry.name);
|
|
101
|
+
const destPath = path.join(dest, entry.name);
|
|
102
|
+
|
|
103
|
+
if (entry.isDirectory()) {
|
|
104
|
+
copyRecursive(srcPath, destPath);
|
|
105
|
+
} else {
|
|
106
|
+
fs.copyFileSync(srcPath, destPath);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function findSolutionFileUpwards(startDir) {
|
|
112
|
+
let current = startDir;
|
|
113
|
+
|
|
114
|
+
while (true) {
|
|
115
|
+
const files = fs.readdirSync(current);
|
|
116
|
+
const sln = files.find(f => f.endsWith('.sln'));
|
|
117
|
+
if (sln) return path.join(current, sln);
|
|
118
|
+
|
|
119
|
+
const parent = path.dirname(current);
|
|
120
|
+
if (parent === current) return null;
|
|
121
|
+
current = parent;
|
|
122
|
+
}
|
|
123
|
+
}
|
package/bin/create-module.js
CHANGED
package/lib/replacer.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// scripts/replacer.js
|
|
2
|
+
|
|
3
|
+
function buildReplaceMap({
|
|
4
|
+
sourceModuleName, // "__MODULE__"
|
|
5
|
+
newModuleName, // e.g. Product
|
|
6
|
+
sourceEntityName, // "__ITEM__"
|
|
7
|
+
newEntityName // e.g. Order
|
|
8
|
+
}) {
|
|
9
|
+
return [
|
|
10
|
+
// =====================
|
|
11
|
+
// Module placeholders
|
|
12
|
+
// =====================
|
|
13
|
+
{ from: "__MODULE__", to: newModuleName },
|
|
14
|
+
{ from: "__module__", to: newModuleName.toLowerCase() },
|
|
15
|
+
|
|
16
|
+
// =====================
|
|
17
|
+
// Entity placeholders
|
|
18
|
+
// =====================
|
|
19
|
+
{ from: "__ITEM__", to: newEntityName },
|
|
20
|
+
{ from: "__item__", to: newEntityName.toLowerCase() },
|
|
21
|
+
|
|
22
|
+
// =====================
|
|
23
|
+
// (Optional) Legacy fallback
|
|
24
|
+
// =====================
|
|
25
|
+
{ from: "Item", to: newEntityName },
|
|
26
|
+
{ from: "item", to: newEntityName.toLowerCase() },
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function applyReplacements(text, replaceMap) {
|
|
31
|
+
let result = text;
|
|
32
|
+
|
|
33
|
+
for (const { from, to } of replaceMap) {
|
|
34
|
+
// Escape regex special chars just in case
|
|
35
|
+
const escapedFrom = from.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
36
|
+
result = result.replace(new RegExp(escapedFrom, 'g'), to);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = {
|
|
43
|
+
buildReplaceMap,
|
|
44
|
+
applyReplacements
|
|
45
|
+
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "netcore-blueprint",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"description": "A custom project blueprint",
|
|
5
5
|
"main": "create.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"create-app": "./bin/create-app.js",
|
|
8
|
-
"create-module": "./bin/create-module.js"
|
|
8
|
+
"create-module": "./bin/create-module.js",
|
|
9
|
+
"copy-module": "./bin/copy-module.js"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
11
12
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
@@ -17,6 +18,8 @@
|
|
|
17
18
|
"author": "",
|
|
18
19
|
"license": "ISC",
|
|
19
20
|
"files": [
|
|
21
|
+
"bin/**",
|
|
22
|
+
"lib/**",
|
|
20
23
|
"Modules/**",
|
|
21
24
|
"BlueprintTemplate/**"
|
|
22
25
|
]
|