netcore-blueprint 0.0.16 → 0.0.18

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.
@@ -0,0 +1,65 @@
1
+ using AutoMapper;
2
+ using ItemModule.Core.Dtos.Admin;
3
+ using ItemModule.Core.Entities;
4
+ using ItemModule.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 ItemModule.API.Controllers.Public
12
+ {
13
+ /// <summary>
14
+ /// Item Controller
15
+ /// </summary>
16
+ [Route("rest/v{version:apiVersion}/items")]
17
+ [Produces("application/json")]
18
+ [ApiController]
19
+ public class ItemController : Controller
20
+ {
21
+ private readonly IMapper _mapper;
22
+ private ILogger _logger;
23
+ private readonly IItemService _itemService;
24
+
25
+ /// <summary>
26
+ /// Constructor
27
+ /// </summary>
28
+ /// <param name="logger"></param>
29
+ /// <param name="mapper"></param>
30
+ /// <param name="itemService"></param>
31
+ public ItemController(
32
+ ILogger<ItemController> logger,
33
+ IMapper mapper,
34
+ IItemService itemService)
35
+ {
36
+ _mapper = mapper;
37
+ _logger = logger;
38
+ _itemService = itemService;
39
+ }
40
+
41
+ /// <summary>
42
+ /// Get items
43
+ /// </summary>
44
+ /// <param name="pagingParams"></param>
45
+ /// <returns></returns>
46
+ [HttpGet]
47
+ [ProducesResponseType(typeof(PagerData<ItemResponseDto>), StatusCodes.Status200OK)]
48
+ public async Task<IActionResult> GetItems([FromQuery] PagingParams pagingParams)
49
+ {
50
+ _logger.LogInformation($"Start getting items");
51
+ var stopwatch = Stopwatch.StartNew();
52
+
53
+ PagerData<Item> items = await _itemService.GetItemsAsync(pagingParams);
54
+ PagerData<ItemResponseDto> itemResponse = _mapper.Map<PagerData<ItemResponseDto>>(items);
55
+
56
+ // Add custom headers
57
+ Response.Headers.Append("X-WP-Total", items.TotalRecords.ToString());
58
+
59
+ stopwatch.Stop();
60
+ _logger.LogInformation($"Getting items done in {stopwatch.ElapsedMilliseconds}");
61
+
62
+ return Ok(itemResponse.Items);
63
+ }
64
+ }
65
+ }
@@ -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
+ <ItemGroup>
10
+ <Folder Include="Controllers\Admin\" />
11
+ </ItemGroup>
12
+
13
+ <ItemGroup>
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
+ </ItemGroup>
20
+
21
+ <ItemGroup>
22
+ <ProjectReference Include="..\ItemModule.Core\ItemModule.Core.csproj" />
23
+ <ProjectReference Include="..\ItemModule.Infrastructure\ItemModule.Infrastructure.csproj" />
24
+ <ProjectReference Include="..\Shared.Core\Shared.Core.csproj" />
25
+ </ItemGroup>
26
+
27
+ </Project>
@@ -0,0 +1,24 @@
1
+ using ItemModule.API.Controllers.Public;
2
+ using ItemModule.API.Mappers;
3
+ using ItemModule.Core;
4
+ using ItemModule.Infrastructure;
5
+ using Microsoft.Extensions.Configuration;
6
+ using Microsoft.Extensions.DependencyInjection;
7
+ using Shared.Core.Interfaces.Modules;
8
+ using System.Reflection;
9
+
10
+ namespace ItemModule.API
11
+ {
12
+ public class ItemModule : IModule
13
+ {
14
+ public string Name => "Item";
15
+ public void Register(IServiceCollection services, IConfiguration config)
16
+ {
17
+ ItemCoreDependencyInjection.AddModule(services);
18
+ ItemInfraDependencyInjection.AddModule(services);
19
+ }
20
+
21
+ public Assembly ApiAssembly => typeof(ItemController).Assembly;
22
+ public Assembly MappingAssembly => typeof(DtoItemMappingProfile).Assembly;
23
+ }
24
+ }
@@ -0,0 +1,26 @@
1
+ using AutoMapper;
2
+ using ItemModule.Core.Dtos.Admin;
3
+ using ItemModule.Core.Entities;
4
+ using Shared.Core.Shared.Models;
5
+
6
+ namespace ItemModule.API.Mappers
7
+ {
8
+ /// <summary>
9
+ /// DtoItemMappingProfile
10
+ /// </summary>
11
+ public class DtoItemMappingProfile : Profile
12
+ {
13
+ /// <summary>
14
+ /// Constructor
15
+ /// </summary>
16
+ public DtoItemMappingProfile()
17
+ {
18
+ CreateMap<Item, ItemRequestDto>().ReverseMap();
19
+
20
+ CreateMap<PagerData<Item>, PagerData<ItemResponseDto>>().ReverseMap();
21
+
22
+ CreateMap<Item, ItemResponseDto>()
23
+ .ReverseMap();
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,8 @@
1
+ using Shared.Core.Dtos.Requests;
2
+
3
+ namespace ItemModule.Core.Dtos.Admin
4
+ {
5
+ public class ItemRequestDto : BaseRequestDto
6
+ {
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ using Shared.Core.Dtos.Responses;
2
+
3
+ namespace ItemModule.Core.Dtos.Admin
4
+ {
5
+ public class ItemResponseDto : BaseResponseDto
6
+ {
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ using Shared.Core.Entities;
2
+
3
+ namespace ItemModule.Core.Entities
4
+ {
5
+ public class Item : BaseEntity
6
+ {
7
+ }
8
+ }
@@ -0,0 +1,9 @@
1
+ using ItemModule.Core.Entities;
2
+ using Shared.Core.Interfaces.API;
3
+
4
+ namespace ItemModule.Core.Interfaces.API
5
+ {
6
+ public interface IItemService : IItemService<Item>
7
+ {
8
+ }
9
+ }
@@ -0,0 +1,9 @@
1
+ using ItemModule.Core.Entities;
2
+ using Shared.Core.Interfaces.SPI;
3
+
4
+ namespace ItemModule.Core.Interfaces.SPI
5
+ {
6
+ public interface IItemInfra : IItemInfra<Item>
7
+ {
8
+ }
9
+ }
@@ -0,0 +1,19 @@
1
+ using ItemModule.Core.Interfaces.API;
2
+ using ItemModule.Core.Services;
3
+ using Microsoft.Extensions.DependencyInjection;
4
+ using Shared.Core.Interfaces.API;
5
+ using Shared.Core.Services;
6
+
7
+ namespace ItemModule.Core
8
+ {
9
+ public static class ItemCoreDependencyInjection
10
+ {
11
+ public static IServiceCollection AddModule(
12
+ this IServiceCollection services)
13
+ {
14
+ services.AddScoped(typeof(IItemService<>), typeof(ItemService<>));
15
+ services.AddScoped<IItemService, ItemService>();
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
+ <ItemGroup>
10
+ <ProjectReference Include="..\Shared.Core\Shared.Core.csproj" />
11
+ </ItemGroup>
12
+
13
+ <ItemGroup>
14
+ <Folder Include="Dtos\Public\" />
15
+ <Folder Include="Enums\" />
16
+ </ItemGroup>
17
+
18
+ </Project>
@@ -0,0 +1,20 @@
1
+ using ItemModule.Core.Entities;
2
+ using ItemModule.Core.Interfaces.API;
3
+ using ItemModule.Core.Interfaces.SPI;
4
+ using Microsoft.Extensions.Logging;
5
+ using Shared.Core.Interfaces.SPI;
6
+ using Shared.Core.Services;
7
+
8
+ namespace ItemModule.Core.Services
9
+ {
10
+ public class ItemService : ItemService<Item>, IItemService
11
+ {
12
+ private readonly IItemInfra _userInfra;
13
+ public ItemService(ILogger<ItemService> logger,
14
+ IRepositoryFactory<Item> repositoryFactory,
15
+ IItemInfra userInfra) : base(logger, repositoryFactory)
16
+ {
17
+ _userInfra = userInfra;
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,22 @@
1
+ using ItemModule.Core.Entities;
2
+ using Microsoft.EntityFrameworkCore;
3
+ using Microsoft.EntityFrameworkCore.Metadata.Builders;
4
+
5
+ namespace ItemModule.Infrastructure.Database
6
+ {
7
+ internal class ItemConfiguration : IEntityTypeConfiguration<Item>
8
+ {
9
+ public void Configure(EntityTypeBuilder<Item> builder)
10
+ {
11
+ // Table
12
+ builder.ToTable("Items");
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,21 @@
1
+ using ItemModule.Core.Entities;
2
+ using Microsoft.EntityFrameworkCore;
3
+ using Shared.Core.Enums;
4
+ using Shared.Core.Interfaces.SPI;
5
+
6
+ namespace ItemModule.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,21 @@
1
+ using ItemModule.Core.Interfaces.SPI;
2
+ using ItemModule.Infrastructure.Database;
3
+ using ItemModule.Infrastructure.Services;
4
+ using Microsoft.Extensions.DependencyInjection;
5
+ using Shared.Core.Interfaces.SPI;
6
+ using Shared.Infrastructure.Services.MySQL;
7
+
8
+ namespace ItemModule.Infrastructure
9
+ {
10
+ public static class ItemInfraDependencyInjection
11
+ {
12
+ public static IServiceCollection AddModule(
13
+ this IServiceCollection services)
14
+ {
15
+ services.AddScoped<IModuleSeeder, Seeder>();
16
+ services.AddScoped<IItemInfra, MySQLItemInfra>();
17
+ services.AddScoped(typeof(IItemInfra<>), typeof(MySQLItemInfra<>));
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
+ <ItemGroup>
10
+ <ProjectReference Include="..\ItemModule.Core\ItemModule.Core.csproj" />
11
+ <ProjectReference Include="..\Shared.Infrastructure\Shared.Infrastructure.csproj" />
12
+ </ItemGroup>
13
+
14
+ </Project>
@@ -0,0 +1,16 @@
1
+ using ItemModule.Core.Entities;
2
+ using ItemModule.Core.Interfaces.SPI;
3
+ using Microsoft.Extensions.Logging;
4
+ using Shared.Infrastructure.Database;
5
+ using Shared.Infrastructure.Services.MySQL;
6
+
7
+ namespace ItemModule.Infrastructure.Services
8
+ {
9
+ public class MySQLItemInfra : MySQLItemInfra<Item>, IItemInfra
10
+ {
11
+ public MySQLItemInfra(MyDbContext dbContext, ILogger<MySQLItemInfra> logger)
12
+ : base(dbContext, logger)
13
+ {
14
+ }
15
+ }
16
+ }
@@ -1,3 +1,5 @@
1
+ #!/usr/bin/env node
2
+
1
3
  const fs = require('fs');
2
4
  const path = require('path');
3
5
 
@@ -8,59 +10,70 @@ if (!newModuleName) {
8
10
  }
9
11
 
10
12
  const sourceModuleName = "ItemModule";
11
- const templatePath = path.join(__dirname, "..", "BlueprintTemplate");
12
- const destinationRoot = process.cwd(); // project root
13
13
 
14
- if (!fs.existsSync(templatePath)) {
15
- console.error(`❌ BlueprintTemplate not found: ${templatePath}`);
14
+ // 🔥 NEW: Modules folder (not BlueprintTemplate)
15
+ const modulesTemplateRoot = path.join(__dirname, "..", "Modules");
16
+ const sourceModulePath = path.join(modulesTemplateRoot, sourceModuleName);
17
+
18
+ // Project root where new module will be created
19
+ const destinationRoot = process.cwd();
20
+ const destinationModulePath = path.join(destinationRoot, newModuleName);
21
+
22
+ if (!fs.existsSync(sourceModulePath)) {
23
+ console.error(`❌ Source module not found: ${sourceModulePath}`);
16
24
  process.exit(1);
17
25
  }
18
26
 
19
- // Find all ItemModule.* folders
20
- const sourceFolders = fs.readdirSync(templatePath, { withFileTypes: true })
21
- .filter(d => d.isDirectory() && d.name.startsWith(sourceModuleName));
22
-
23
- if (sourceFolders.length === 0) {
24
- console.error(`❌ No ItemModule templates found in: ${templatePath}`);
27
+ if (fs.existsSync(destinationModulePath)) {
28
+ console.error(`❌ Destination module already exists: ${destinationModulePath}`);
25
29
  process.exit(1);
26
30
  }
27
31
 
28
- for (const dir of sourceFolders) {
29
- const srcPath = path.join(templatePath, dir.name);
30
- const destName = dir.name.replace(
31
- new RegExp(sourceModuleName, 'g'),
32
- newModuleName
33
- );
34
- const destPath = path.join(destinationRoot, destName);
35
-
36
- if (fs.existsSync(destPath)) {
37
- console.error(`❌ Destination already exists: ${destPath}`);
38
- process.exit(1);
39
- }
32
+ console.log(`📦 Creating module: ${newModuleName}`);
33
+ console.log(`📁 From template: ${sourceModulePath}`);
34
+ console.log(`📁 To: ${destinationModulePath}`);
40
35
 
41
- console.log(`📦 Copying ${dir.name} -> ${destName}`);
42
- copyAndRenameFiles(srcPath, destPath, sourceModuleName, newModuleName);
43
- }
36
+ copyAndRenameFiles(
37
+ sourceModulePath,
38
+ destinationModulePath,
39
+ sourceModuleName,
40
+ newModuleName
41
+ );
44
42
 
45
43
  console.log(`🎉 Module "${newModuleName}" created successfully!`);
46
44
 
47
45
  // ===== CORE LOGIC =====
48
46
 
49
47
  function copyAndRenameFiles(src, dest, oldName, newName) {
50
- if (fs.lstatSync(src).isDirectory()) {
48
+ const stat = fs.lstatSync(src);
49
+
50
+ if (stat.isDirectory()) {
51
51
  fs.mkdirSync(dest, { recursive: true });
52
+
52
53
  const entries = fs.readdirSync(src, { withFileTypes: true });
53
54
 
54
- for (let entry of entries) {
55
+ for (const entry of entries) {
55
56
  const srcPath = path.join(src, entry.name);
56
- const destName = entry.name.replace(new RegExp(oldName, 'g'), newName);
57
- const destPath = path.join(dest, destName);
57
+
58
+ // 🔁 Rename folder/file if contains old module name
59
+ const renamed = entry.name.replace(
60
+ new RegExp(oldName, 'g'),
61
+ newName
62
+ );
63
+
64
+ const destPath = path.join(dest, renamed);
58
65
 
59
66
  copyAndRenameFiles(srcPath, destPath, oldName, newName);
60
67
  }
61
68
  } else {
62
69
  let content = fs.readFileSync(src, 'utf8');
63
- content = content.replace(new RegExp(oldName, 'g'), newName);
70
+
71
+ // 🔁 Replace namespace + content
72
+ content = content.replace(
73
+ new RegExp(oldName, 'g'),
74
+ newName
75
+ );
76
+
64
77
  fs.writeFileSync(dest, content, 'utf8');
65
78
  }
66
79
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "netcore-blueprint",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "description": "A custom project blueprint",
5
5
  "main": "create.js",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "author": "",
18
18
  "license": "ISC",
19
19
  "files": [
20
- "bin",
20
+ "Modules/**",
21
21
  "BlueprintTemplate/**"
22
22
  ]
23
23
  }