opticore-feature-component 1.0.6 → 1.0.8

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.
@@ -2,7 +2,7 @@
2
2
  import process3 from "process";
3
3
  import fs5 from "fs";
4
4
  import path9 from "path";
5
- import { isCancel as isCancel7 } from "@clack/prompts";
5
+ import { isCancel as isCancel9 } from "@clack/prompts";
6
6
 
7
7
  // src/utils/welcomeMessage.utils.ts
8
8
  import cfonts from "cfonts";
@@ -33,10 +33,10 @@ function UWelcomeMessage() {
33
33
 
34
34
  // src/utils/choiceFeatureCleanModule.ts
35
35
  import colors2 from "ansi-colors";
36
- import { isCancel } from "@clack/prompts";
36
+ import { isCancel as isCancel2 } from "@clack/prompts";
37
37
 
38
38
  // src/utils/prompt.utils.ts
39
- import { confirm, select, text } from "@clack/prompts";
39
+ import { confirm, isCancel, select, text } from "@clack/prompts";
40
40
  import colors from "ansi-colors";
41
41
 
42
42
  // src/utils/fsModule.utils.ts
@@ -110,11 +110,14 @@ var UPrompt = class {
110
110
  process.exit(0);
111
111
  }
112
112
  static async select(message, defaultValue, options) {
113
- let optSelected = await select({
113
+ const optSelected = await select({
114
114
  message,
115
115
  initialValue: defaultValue,
116
116
  options
117
117
  });
118
+ if (isCancel(optSelected)) {
119
+ return optSelected;
120
+ }
118
121
  return optSelected[0];
119
122
  }
120
123
  };
@@ -131,7 +134,7 @@ async function choiceFeatureCleanModule() {
131
134
  { label: "Build your own architecture", value: ["custom_feature"] }
132
135
  ]
133
136
  );
134
- if (isCancel(featureSelected)) {
137
+ if (isCancel2(featureSelected)) {
135
138
  console.log(`${colors2.bgRed(`${colors2.white("Operation cancelled.")}`)}`);
136
139
  process.exit(0);
137
140
  } else {
@@ -155,7 +158,7 @@ You have chosen : ${choice === "opticore_clean_module" ? colors3.cyan("OptiCoreJ
155
158
  const diagram = [
156
159
  ` ` + I(`INFRASTRUCTURE`),
157
160
  ` ` + I(`controllers \xB7 repositories \xB7 routes`),
158
- ` ` + I(`presenters \xB7 routes`),
161
+ ` ` + I(`presenters \xB7 routes`),
159
162
  ``,
160
163
  ` ` + A(`APPLICATION`),
161
164
  ` ` + A(`ports \xB7 interfaces \xB7 dtos \xB7 use-cases`),
@@ -179,7 +182,7 @@ var _featureName = async () => {
179
182
  "Enter feature's name :",
180
183
  "login",
181
184
  (value) => {
182
- let pattern = new RegExp("^[a-z][A-Za-z]+$");
185
+ let pattern = new RegExp("^[a-z][A-Za-z_-]+$");
183
186
  if (!value) {
184
187
  return "Please enter a feature's name.";
185
188
  }
@@ -267,7 +270,7 @@ async function _controllerType(messageText, defaultValue, options) {
267
270
  }
268
271
 
269
272
  // src/core/components/application/createController.application.ts
270
- import { isCancel as isCancel3 } from "@clack/prompts";
273
+ import { isCancel as isCancel5 } from "@clack/prompts";
271
274
 
272
275
  // src/core/domains/constants/cleanType.constant.ts
273
276
  var CCleanType = {
@@ -284,6 +287,7 @@ import colors6 from "ansi-colors";
284
287
  import path2 from "path";
285
288
  import colors5 from "ansi-colors";
286
289
  import fs3 from "fs";
290
+ import { isCancel as isCancel3 } from "@clack/prompts";
287
291
  import { LoggerCore as LoggerCore2 } from "opticore-logger";
288
292
 
289
293
  // src/templates/cleanComponents/controller.template.ts
@@ -1387,11 +1391,21 @@ var capitalize15 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
1387
1391
  // src/templates/simpleComponent/simpleRouter.template.ts
1388
1392
  var resolveRoute2 = (methodName, featureName) => {
1389
1393
  const lower = methodName.toLowerCase();
1390
- if (lower.includes("findall") || lower.includes("getall")) return { httpMethod: "get", path: `/${featureName}` };
1391
- if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return { httpMethod: "get", path: `/${featureName}/:id` };
1392
- if (lower.includes("create") || lower.includes("add")) return { httpMethod: "post", path: `/${featureName}` };
1393
- if (lower.includes("update") || lower.includes("edit")) return { httpMethod: "put", path: `/${featureName}/:id` };
1394
- if (lower.includes("delete") || lower.includes("remove")) return { httpMethod: "delete", path: `/${featureName}/:id` };
1394
+ if (lower.includes("findall") || lower.includes("getall")) {
1395
+ return { httpMethod: "get", path: `/${featureName}` };
1396
+ }
1397
+ if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) {
1398
+ return { httpMethod: "get", path: `/${featureName}/:id` };
1399
+ }
1400
+ if (lower.includes("create") || lower.includes("add")) {
1401
+ return { httpMethod: "post", path: `/${featureName}` };
1402
+ }
1403
+ if (lower.includes("update") || lower.includes("edit")) {
1404
+ return { httpMethod: "put", path: `/${featureName}/:id` };
1405
+ }
1406
+ if (lower.includes("delete") || lower.includes("remove")) {
1407
+ return { httpMethod: "delete", path: `/${featureName}/:id` };
1408
+ }
1395
1409
  return { httpMethod: "get", path: `/${featureName}/${lower}` };
1396
1410
  };
1397
1411
  var generateSimpleRouterHandlerTemplate = (featureName, controllerMethods) => {
@@ -1462,7 +1476,7 @@ var FeatureComponentGeneratorUtils = class {
1462
1476
  const entityName = `${this.capitalize(featureName)}Entity`;
1463
1477
  const filePath = path2.join(entityDir, `${featureName}.entity.ts`);
1464
1478
  UFsModule.createFile(filePath, generateEntityTemplate(entityName, featureName));
1465
- console.log(colors5.green(`\u2705 Entity created: ${filePath}`));
1479
+ console.log(colors5.green(`\u2714 Entity created: ${filePath}`));
1466
1480
  }
1467
1481
  /**
1468
1482
  * Creates the domain event file.
@@ -1470,7 +1484,7 @@ var FeatureComponentGeneratorUtils = class {
1470
1484
  static async createEvent(featureName, eventDir) {
1471
1485
  const filePath = path2.join(eventDir, `${featureName}.event.ts`);
1472
1486
  UFsModule.createFile(filePath, generateEventTemplate(featureName));
1473
- console.log(colors5.green(`\u2705 Event created: ${filePath}`));
1487
+ console.log(colors5.green(`\u2714 Event created: ${filePath}`));
1474
1488
  }
1475
1489
  /**
1476
1490
  * Creates the domain exception file.
@@ -1478,7 +1492,7 @@ var FeatureComponentGeneratorUtils = class {
1478
1492
  static async createException(featureName, exceptionDir) {
1479
1493
  const filePath = path2.join(exceptionDir, `${featureName}.exception.ts`);
1480
1494
  UFsModule.createFile(filePath, generateExceptionTemplate(featureName));
1481
- console.log(colors5.green(`\u2705 Exception created: ${filePath}`));
1495
+ console.log(colors5.green(`\u2714 Exception created: ${filePath}`));
1482
1496
  }
1483
1497
  /**
1484
1498
  * Creates the repository port interface.
@@ -1487,7 +1501,7 @@ var FeatureComponentGeneratorUtils = class {
1487
1501
  const interfaceName = `I${this.capitalize(featureName)}Repository`;
1488
1502
  const filePath = path2.join(interfaceDir, `${featureName}.repository.interface.ts`);
1489
1503
  UFsModule.createFile(filePath, generateRepositoryInterfaceTemplate(interfaceName, featureName));
1490
- console.log(colors5.green(`\u2705 Repository interface created: ${filePath}`));
1504
+ console.log(colors5.green(`\u2714 Repository interface created: ${filePath}`));
1491
1505
  }
1492
1506
  /**
1493
1507
  * Creates the presenter port interface.
@@ -1495,7 +1509,7 @@ var FeatureComponentGeneratorUtils = class {
1495
1509
  static async createPresenterInterface(featureName, presenterInterfaceDir) {
1496
1510
  const filePath = path2.join(presenterInterfaceDir, `${featureName}.presenter.interface.ts`);
1497
1511
  UFsModule.createFile(filePath, generatePresenterInterfaceTemplate(featureName));
1498
- console.log(colors5.green(`\u2705 Presenter interface created: ${filePath}`));
1512
+ console.log(colors5.green(`\u2714 Presenter interface created: ${filePath}`));
1499
1513
  }
1500
1514
  /**
1501
1515
  * Creates the application service port interface.
@@ -1503,7 +1517,7 @@ var FeatureComponentGeneratorUtils = class {
1503
1517
  static async createService(featureName, serviceDir) {
1504
1518
  const filePath = path2.join(serviceDir, `${featureName}.service.ts`);
1505
1519
  UFsModule.createFile(filePath, generateServiceTemplate(featureName));
1506
- console.log(colors5.green(`\u2705 Service interface created: ${filePath}`));
1520
+ console.log(colors5.green(`\u2714 Service interface created: ${filePath}`));
1507
1521
  }
1508
1522
  /**
1509
1523
  * Creates the DTO file (input + output shapes + mapper).
@@ -1511,7 +1525,7 @@ var FeatureComponentGeneratorUtils = class {
1511
1525
  static async createDto(featureName, dtoDir) {
1512
1526
  const filePath = path2.join(dtoDir, `${featureName}.dto.ts`);
1513
1527
  UFsModule.createFile(filePath, generateDtoTemplate(featureName));
1514
- console.log(colors5.green(`\u2705 DTO created: ${filePath}`));
1528
+ console.log(colors5.green(`\u2714 DTO created: ${filePath}`));
1515
1529
  }
1516
1530
  /**
1517
1531
  * Creates the use case file.
@@ -1520,7 +1534,7 @@ var FeatureComponentGeneratorUtils = class {
1520
1534
  const useCaseName = `${this.capitalize(featureName)}UseCase`;
1521
1535
  const filePath = path2.join(useCaseDir, `${featureName}.usecase.ts`);
1522
1536
  UFsModule.createFile(filePath, generateUseCaseTemplate(useCaseName, featureName));
1523
- console.log(colors5.green(`\u2705 UseCase created: ${filePath}`));
1537
+ console.log(colors5.green(`\u2714 UseCase created: ${filePath}`));
1524
1538
  }
1525
1539
  /**
1526
1540
  * Creates the concrete repository implementation.
@@ -1529,7 +1543,7 @@ var FeatureComponentGeneratorUtils = class {
1529
1543
  const interfaceImportPath = `../../../application/ports/repositories/${featureName}.repository.interface`;
1530
1544
  const filePath = path2.join(repositoryImplDir, `${featureName}.repository.ts`);
1531
1545
  UFsModule.createFile(filePath, generateRepositoryImplTemplate(featureName, interfaceImportPath));
1532
- console.log(colors5.green(`\u2705 Repository implementation created: ${filePath}`));
1546
+ console.log(colors5.green(`\u2714 Repository implementation created: ${filePath}`));
1533
1547
  }
1534
1548
  /**
1535
1549
  * Creates the concrete presenter implementation.
@@ -1537,7 +1551,7 @@ var FeatureComponentGeneratorUtils = class {
1537
1551
  static async createPresenterImpl(featureName, presenterImplDir) {
1538
1552
  const filePath = path2.join(presenterImplDir, `${featureName}.presenter.ts`);
1539
1553
  UFsModule.createFile(filePath, generatePresenterImplTemplate(featureName));
1540
- console.log(colors5.green(`\u2705 Presenter implementation created: ${filePath}`));
1554
+ console.log(colors5.green(`\u2714 Presenter implementation created: ${filePath}`));
1541
1555
  }
1542
1556
  /**
1543
1557
  * Creates the HTTP controller.
@@ -1551,13 +1565,15 @@ var FeatureComponentGeneratorUtils = class {
1551
1565
  const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
1552
1566
  let methods = [];
1553
1567
  let content;
1554
- if (wantsMethods) {
1568
+ if (wantsMethods && !isCancel3(wantsMethods)) {
1555
1569
  const methodsText = await UPrompt.text(
1556
1570
  "Enter the method names (comma separated):",
1557
1571
  "create, findAll, findById, update, delete",
1558
1572
  (v) => v ? void 0 : "You must enter at least one method."
1559
1573
  );
1560
- methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
1574
+ if (!isCancel3(methodsText)) {
1575
+ methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
1576
+ }
1561
1577
  content = generateControllerTemplate(controllerName, featureName, methods);
1562
1578
  } else {
1563
1579
  content = `import { Request, Response } from "express";
@@ -1566,7 +1582,7 @@ export class ${controllerName} {}
1566
1582
  `;
1567
1583
  }
1568
1584
  UFsModule.createFile(filePath, content);
1569
- console.log(colors5.green(`\u2705 Controller created: ${filePath}`));
1585
+ console.log(colors5.green(`\u2714 Controller created: ${filePath}`));
1570
1586
  return { controllerName, methods };
1571
1587
  }
1572
1588
  /**
@@ -1575,7 +1591,7 @@ export class ${controllerName} {}
1575
1591
  static async createModel(featureName, modelDir) {
1576
1592
  const filePath = path2.join(modelDir, `${featureName}.model.ts`);
1577
1593
  UFsModule.createFile(filePath, generateModelTemplate(featureName));
1578
- console.log(colors5.green(`\u2705 Model created: ${filePath}`));
1594
+ console.log(colors5.green(`\u2714 Model created: ${filePath}`));
1579
1595
  }
1580
1596
  /**
1581
1597
  * Creates the simple repository (no interface, uses the model directly).
@@ -1583,7 +1599,7 @@ export class ${controllerName} {}
1583
1599
  static async createSimpleRepository(featureName, repositoryDir) {
1584
1600
  const filePath = path2.join(repositoryDir, `${featureName}.repository.ts`);
1585
1601
  UFsModule.createFile(filePath, generateSimpleRepositoryTemplate(featureName));
1586
- console.log(colors5.green(`\u2705 Repository created: ${filePath}`));
1602
+ console.log(colors5.green(`\u2714 Repository created: ${filePath}`));
1587
1603
  }
1588
1604
  /**
1589
1605
  * Creates the simple concrete service (no interface, wires the repository).
@@ -1591,7 +1607,7 @@ export class ${controllerName} {}
1591
1607
  static async createSimpleService(featureName, serviceDir) {
1592
1608
  const filePath = path2.join(serviceDir, `${featureName}.service.ts`);
1593
1609
  UFsModule.createFile(filePath, generateSimpleServiceTemplate(featureName));
1594
- console.log(colors5.green(`\u2705 Service created: ${filePath}`));
1610
+ console.log(colors5.green(`\u2714 Service created: ${filePath}`));
1595
1611
  }
1596
1612
  /**
1597
1613
  * Creates the simple controller (delegates to service, no use-case/presenter).
@@ -1602,13 +1618,15 @@ export class ${controllerName} {}
1602
1618
  const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
1603
1619
  let methods = [];
1604
1620
  let content;
1605
- if (wantsMethods) {
1621
+ if (wantsMethods && !isCancel3(wantsMethods)) {
1606
1622
  const methodsText = await UPrompt.text(
1607
1623
  "Enter the method names (comma separated):",
1608
1624
  "create, findAll, findById, update, delete",
1609
1625
  (v) => v ? void 0 : "You must enter at least one method."
1610
1626
  );
1611
- methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
1627
+ if (!isCancel3(methodsText)) {
1628
+ methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
1629
+ }
1612
1630
  content = generateSimpleControllerTemplate(controllerName, featureName, methods);
1613
1631
  } else {
1614
1632
  content = `import { Request, Response } from "express";
@@ -1617,7 +1635,7 @@ export class ${controllerName} {}
1617
1635
  `;
1618
1636
  }
1619
1637
  UFsModule.createFile(filePath, content);
1620
- console.log(colors5.green(`\u2705 Controller created: ${filePath}`));
1638
+ console.log(colors5.green(`\u2714 Controller created: ${filePath}`));
1621
1639
  return { controllerName, methods };
1622
1640
  }
1623
1641
  /**
@@ -1628,7 +1646,7 @@ export class ${controllerName} {}
1628
1646
  const filePath = path2.join(routerHandlerDir, `${featureName}.router.handler.ts`);
1629
1647
  const content = this.structure === "simple" ? generateSimpleRouterHandlerTemplate(featureName, controllerMethods) : generateRouterHandlerTemplate(featureName, controllerMethods);
1630
1648
  UFsModule.createFile(filePath, content);
1631
- console.log(colors5.green(`\u2705 Router Handler created: ${filePath}`));
1649
+ console.log(colors5.green(`\u2714 Router Handler created: ${filePath}`));
1632
1650
  }
1633
1651
  /**
1634
1652
  * Creates the feature router and registers it in register.router.ts.
@@ -1639,7 +1657,7 @@ export class ${controllerName} {}
1639
1657
  const content = this.structure === "simple" ? generateSimpleRouterTemplate(featureName) : generateRouterTemplate(featureName);
1640
1658
  UFsModule.createFile(filePath, content);
1641
1659
  await this.updateRegisterRouter(featureName);
1642
- console.log(colors5.green(`\u2705 Router created: ${filePath}`));
1660
+ console.log(colors5.green(`\u2714 Router created: ${filePath}`));
1643
1661
  }
1644
1662
  static capitalize(str) {
1645
1663
  return str.charAt(0).toUpperCase() + str.slice(1);
@@ -1654,13 +1672,13 @@ export class ${controllerName} {}
1654
1672
  try {
1655
1673
  if (!fs3.existsSync(this.REGISTER_ROUTER_PATH)) {
1656
1674
  console.log(
1657
- colors5.yellow(`\u26A0\uFE0F register.router.ts not found at ${this.REGISTER_ROUTER_PATH}, skipping auto-registration.`)
1675
+ colors5.yellow(`\u26A0 register.router.ts not found at ${this.REGISTER_ROUTER_PATH}, skipping auto-registration.`)
1658
1676
  );
1659
1677
  return;
1660
1678
  }
1661
1679
  let content = fs3.readFileSync(this.REGISTER_ROUTER_PATH, "utf-8");
1662
1680
  if (content.includes(`import { ${routerName} } from`)) {
1663
- console.log(colors5.cyan(`\u2139\uFE0F ${routerName} is already registered.`));
1681
+ console.log(colors5.cyan(`\u2139 ${routerName} is already registered.`));
1664
1682
  return;
1665
1683
  }
1666
1684
  const lines = content.split("\n");
@@ -1678,12 +1696,12 @@ export class ${controllerName} {}
1678
1696
  const ARRAY_CLOSE = "]);";
1679
1697
  const startIdx = content.indexOf(ARRAY_OPEN);
1680
1698
  if (startIdx === -1) {
1681
- console.log(colors5.yellow(`\u26A0\uFE0F Could not find 'registered([' in register.router.ts.`));
1699
+ console.log(colors5.yellow(`\u26A0 Could not find 'registered([' in register.router.ts.`));
1682
1700
  return;
1683
1701
  }
1684
1702
  const endIdx = content.indexOf(ARRAY_CLOSE, startIdx + ARRAY_OPEN.length);
1685
1703
  if (endIdx === -1) {
1686
- console.log(colors5.yellow(`\u26A0\uFE0F Could not find matching ']);' in register.router.ts.`));
1704
+ console.log(colors5.yellow(`\u26A0 Could not find matching ']);' in register.router.ts.`));
1687
1705
  return;
1688
1706
  }
1689
1707
  const arrayContent = content.substring(startIdx + ARRAY_OPEN.length, endIdx);
@@ -1696,9 +1714,9 @@ export class ${controllerName} {}
1696
1714
  ${indentedRoutes}
1697
1715
  ` + content.substring(endIdx);
1698
1716
  fs3.writeFileSync(this.REGISTER_ROUTER_PATH, newContent, "utf-8");
1699
- console.log(colors5.green(`\u2705 register.router.ts updated with ${routerName}.`));
1717
+ console.log(colors5.green(`\u2714 register.router.ts updated with ${routerName}.`));
1700
1718
  } catch (error) {
1701
- console.error(colors5.red(`\u274C Failed to update register.router.ts: ${error.message}`));
1719
+ console.error(colors5.red(`\u2718 Failed to update register.router.ts: ${error.message}`));
1702
1720
  }
1703
1721
  }
1704
1722
  };
@@ -1802,14 +1820,14 @@ var fullCleanComponentTemplate = async (featureName) => {
1802
1820
  // src/templates/cleanComponentByStep/cleanComponentByStep.template.ts
1803
1821
  import path5 from "path";
1804
1822
  import colors8 from "ansi-colors";
1805
- import { isCancel as isCancel2 } from "@clack/prompts";
1823
+ import { isCancel as isCancel4 } from "@clack/prompts";
1806
1824
  var cleanComponentByStepTemplate = async (featureName) => {
1807
1825
  const base = path5.join("src", "features", featureName);
1808
1826
  let created = 0;
1809
1827
  let controller = { controllerName: "", methods: [] };
1810
1828
  const ask = async (label) => {
1811
1829
  const answer = await UPrompt.confirm(label, false);
1812
- if (isCancel2(answer)) {
1830
+ if (isCancel4(answer)) {
1813
1831
  UFsModule.removeDir(base, true, true);
1814
1832
  process.exit(0);
1815
1833
  }
@@ -1818,7 +1836,7 @@ var cleanComponentByStepTemplate = async (featureName) => {
1818
1836
  const track = () => {
1819
1837
  created++;
1820
1838
  };
1821
- console.log(colors8.bold(colors8.cyan("\n\u2500\u2500 Domain \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")));
1839
+ console.log(colors8.bold(colors8.cyan("\n Domain ")));
1822
1840
  const mkDir = (dir) => {
1823
1841
  UFsModule.createDirectoryRecursively(dir);
1824
1842
  return dir;
@@ -1835,7 +1853,7 @@ var cleanComponentByStepTemplate = async (featureName) => {
1835
1853
  await FeatureComponentGeneratorUtils.createException(featureName, mkDir(path5.join(base, "domain", "exceptions")));
1836
1854
  track();
1837
1855
  }
1838
- console.log(colors8.bold(colors8.cyan("\n\u2500\u2500 Application \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")));
1856
+ console.log(colors8.bold(colors8.cyan("\n Application ")));
1839
1857
  if (await ask(`Repo Interface - ${featureName}.repository.interface.ts`)) {
1840
1858
  await FeatureComponentGeneratorUtils.createRepositoryInterface(featureName, mkDir(path5.join(base, "application", "ports", "repositories")));
1841
1859
  track();
@@ -1856,7 +1874,7 @@ var cleanComponentByStepTemplate = async (featureName) => {
1856
1874
  await FeatureComponentGeneratorUtils.createUseCase(featureName, mkDir(path5.join(base, "application", "use-cases")));
1857
1875
  track();
1858
1876
  }
1859
- console.log(colors8.bold(colors8.cyan("\n\u2500\u2500 Infrastructure \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")));
1877
+ console.log(colors8.bold(colors8.cyan("\n Infrastructure ")));
1860
1878
  if (await ask(`Repo Impl - ${featureName}.repository.ts`)) {
1861
1879
  await FeatureComponentGeneratorUtils.createRepositoryImpl(featureName, mkDir(path5.join(base, "infrastructure", "adapters", "repositories")));
1862
1880
  track();
@@ -1879,7 +1897,7 @@ var cleanComponentByStepTemplate = async (featureName) => {
1879
1897
  }
1880
1898
  if (created === 0) {
1881
1899
  console.log(colors8.yellow(`
1882
- \u26A0\uFE0F No files were created for feature "${featureName}".`));
1900
+ \u26A0 No files were created for feature "${featureName}".`));
1883
1901
  } else {
1884
1902
  console.log(
1885
1903
  colors8.bgGreen(colors8.white(`
@@ -1900,7 +1918,7 @@ var createComponentApplication = async (featureDirectory, featureName) => {
1900
1918
  { label: "Full CLEAN Architecture component", value: [CCleanType.full_clean_component] }
1901
1919
  ]
1902
1920
  );
1903
- if (isCancel3(askComponentType) === true || askComponentType === void 0) {
1921
+ if (isCancel5(askComponentType) === true || askComponentType === void 0) {
1904
1922
  BaseService._cancelOperation(featureDirectory);
1905
1923
  } else {
1906
1924
  switch (askComponentType) {
@@ -1917,11 +1935,11 @@ var createComponentApplication = async (featureDirectory, featureName) => {
1917
1935
  }
1918
1936
  };
1919
1937
 
1920
- // src/templates/customModule/customModuleScaffold.template.ts
1938
+ // src/templates/customModule/buildYourOwnArchitectureScaffold.template.ts
1921
1939
  import path6 from "path";
1922
1940
  import fs4 from "fs";
1923
1941
  import colors9 from "ansi-colors";
1924
- import { isCancel as isCancel4 } from "@clack/prompts";
1942
+ import { isCancel as isCancel6 } from "@clack/prompts";
1925
1943
 
1926
1944
  // src/core/domains/constants/resolveRoute.constant.ts
1927
1945
  var CResolveRoute = (methodName, moduleName) => {
@@ -1934,373 +1952,318 @@ var CResolveRoute = (methodName, moduleName) => {
1934
1952
  return { httpMethod: "get", path: `/${moduleName}/${lower}` };
1935
1953
  };
1936
1954
 
1937
- // src/templates/customModule/customModule.template.ts
1938
- var capitalize17 = (s) => s.charAt(0).toUpperCase() + s.slice(1);
1939
- var generateCustomControllerTemplate = (controllerName, moduleName, methods) => {
1940
- const cap = capitalize17(moduleName);
1941
- const serviceName = `${cap}Service`;
1942
- const body = methods.length === 0 ? ` // TODO: add your handler methods here` : methods.map((m) => generateMethod3(m, cap, serviceName)).join("\n");
1943
- const serviceImport = methods.length === 0 ? `` : `import { ${serviceName} } from "./${moduleName}.service";
1944
- `;
1945
- return `import { Request, Response } from "opticore-express";
1946
- import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
1947
- ${serviceImport}
1948
- export class ${controllerName} {${methods.length > 0 ? `
1949
- private static buildService(): ${serviceName} {
1950
- return new ${serviceName}();
1951
- }
1952
- ` : ""}
1953
- ${body}
1954
- private static handleError(error: unknown) {
1955
- const message = error instanceof Error ? error.message : "Internal server error";
1956
- return ResponseHandler.error(message, HttpStatusCode.INTERNAL_SERVER_ERROR);
1957
- }
1958
- }`.trimEnd();
1959
- };
1960
- var generateMethod3 = (method, cap, serviceName) => {
1961
- const lower = method.toLowerCase();
1962
- if (lower.includes("findall") || lower.includes("getall")) return methodFindAll(method, cap);
1963
- if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return methodFindById(method, cap);
1964
- if (lower.includes("create") || lower.includes("add")) return methodCreate(method, cap);
1965
- if (lower.includes("update") || lower.includes("edit")) return methodUpdate(method, cap);
1966
- if (lower.includes("delete") || lower.includes("remove")) return methodDelete(method, cap);
1967
- return `
1955
+ // src/templates/customModule/buildYourOwnArchitecture.template.ts
1956
+ var capitalize17 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
1957
+ var generateBuildYourOwnControllerTemplate = (fileName, methods) => {
1958
+ const controllerName = `${capitalize17(fileName)}Controller`;
1959
+ const body = methods.length === 0 ? ` // TODO: add your handler methods here` : methods.map((method) => `
1968
1960
  static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
1969
1961
  try {
1970
- const service = ${cap}Controller.buildService();
1971
1962
  // TODO: implement ${method}
1972
1963
  return ResponseHandler.success({}, "success", HttpStatusCode.OK);
1973
1964
  } catch (error) {
1974
- return ${cap}Controller.handleError(error);
1975
- }
1976
- }`;
1977
- };
1978
- var methodFindAll = (m, cap) => `
1979
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
1980
- try {
1981
- const service = ${cap}Controller.buildService();
1982
- const results = await service.findAll();
1983
- return ResponseHandler.success(results, "success", HttpStatusCode.OK);
1984
- } catch (error) {
1985
- return ${cap}Controller.handleError(error);
1986
- }
1987
- }`;
1988
- var methodFindById = (m, cap) => `
1989
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
1990
- try {
1991
- const { id } = req.params;
1992
- const service = ${cap}Controller.buildService();
1993
- const result = await service.findById(id);
1994
- if (!result) return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
1995
- return ResponseHandler.success(result, "success", HttpStatusCode.OK);
1996
- } catch (error) {
1997
- return ${cap}Controller.handleError(error);
1998
- }
1999
- }`;
2000
- var methodCreate = (m, cap) => `
2001
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2002
- try {
2003
- const service = ${cap}Controller.buildService();
2004
- const result = await service.create(req.body);
2005
- return ResponseHandler.success(result, "created", HttpStatusCode.CREATED);
2006
- } catch (error) {
2007
- return ${cap}Controller.handleError(error);
2008
- }
2009
- }`;
2010
- var methodUpdate = (m, cap) => `
2011
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2012
- try {
2013
- const { id } = req.params;
2014
- const service = ${cap}Controller.buildService();
2015
- const result = await service.update(id, req.body);
2016
- if (!result) return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
2017
- return ResponseHandler.success(result, "success", HttpStatusCode.OK);
2018
- } catch (error) {
2019
- return ${cap}Controller.handleError(error);
1965
+ const message = error instanceof Error ? error.message : "Internal server error";
1966
+ return ResponseHandler.error(message, HttpStatusCode.INTERNAL_SERVER_ERROR);
2020
1967
  }
2021
- }`;
2022
- var methodDelete = (m, cap) => `
2023
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2024
- try {
2025
- const { id } = req.params;
2026
- const service = ${cap}Controller.buildService();
2027
- const deleted = await service.delete(id);
2028
- if (!deleted) return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
2029
- return ResponseHandler.success(null, "deleted", HttpStatusCode.NO_CONTENT);
2030
- } catch (error) {
2031
- return ${cap}Controller.handleError(error);
2032
- }
2033
- }`;
2034
- var generateCustomServiceTemplate = (moduleName) => {
2035
- const cap = capitalize17(moduleName);
2036
- return `export class ${cap}Service {
2037
- async findAll(): Promise<unknown[]> {
2038
- // TODO: implement
2039
- return [];
2040
- }
2041
- async findById(id: string): Promise<unknown | null> {
2042
- // TODO: implement
2043
- return null;
2044
- }
2045
- async create(data: Record<string, unknown>): Promise<unknown> {
2046
- // TODO: implement
2047
- return data;
2048
- }
2049
- async update(id: string, data: Record<string, unknown>): Promise<unknown | null> {
2050
- // TODO: implement
2051
- return null;
2052
- }
2053
- async delete(id: string): Promise<boolean> {
2054
- // TODO: implement
2055
- return false;
2056
- }
2057
- }`.trimEnd();
1968
+ }`).join("\n");
1969
+ return `import { Request, Response } from "opticore-express";
1970
+ import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
1971
+
1972
+ export class ${controllerName} {
1973
+ ${body}
1974
+ }`.trimEnd() + "\n";
1975
+ };
1976
+ var generateBuildYourOwnServiceClassTemplate = (fileName, methods) => {
1977
+ const serviceName = `${capitalize17(fileName)}Service`;
1978
+ const body = methods.length === 0 ? ` // TODO: add your service methods here` : methods.map((method) => `
1979
+ async ${method}(): Promise<unknown> {
1980
+ // TODO: implement ${method}
1981
+ throw new Error("Not implemented");
1982
+ }`).join("\n");
1983
+ return `export class ${serviceName} {
1984
+ ${body}
1985
+ }`.trimEnd() + "\n";
1986
+ };
1987
+ var generateBuildYourOwnServiceFunctionTemplate = (fileName) => {
1988
+ const functionName = `${fileName}Service`;
1989
+ return `export async function ${functionName}(): Promise<unknown> {
1990
+ // TODO: implement ${functionName}
1991
+ throw new Error("Not implemented");
1992
+ }`.trimEnd() + "\n";
1993
+ };
1994
+ var generateBuildYourOwnDtoTemplate = (fileName, fields) => {
1995
+ const dtoName = `${capitalize17(fileName)}Dto`;
1996
+ const body = fields.length === 0 ? ` // TODO: define the fields of this DTO` : fields.map((field) => ` ${field.name}: ${field.type};`).join("\n");
1997
+ return `export interface ${dtoName} {
1998
+ ${body}
1999
+ }`.trimEnd() + "\n";
2058
2000
  };
2059
- var generateCustomRepositoryTemplate = (moduleName) => {
2060
- const cap = capitalize17(moduleName);
2061
- const name = moduleName.toLowerCase();
2062
- const isAuthRelated = name.includes("auth") || name.includes("authenticate") || name.includes("authentication") || name.includes("login") || name.includes("security") || name.includes("session") || name.includes("connect") || name.includes("connexion") || name.includes("connection");
2063
- if (isAuthRelated) {
2064
- return `export class ${cap}Repository {
2065
- // TODO: inject your data source (ORM, DB client, etc.)
2066
-
2067
- async findByEmail(email: string): Promise<User | null> {
2068
- throw new Error("Not implemented");
2069
- }
2070
-
2071
- async findByUsernameOrEmail(identity: string): Promise<User | null> {
2072
- throw new Error("Not implemented");
2073
- }
2074
-
2075
- async updateLastLogin(userId: string, date: Date): Promise<void> {
2076
- throw new Error("Not implemented");
2077
- }
2078
-
2079
- async incrementLoginAttempts(userId: string): Promise<number> {
2080
- throw new Error("Not implemented");
2081
- }
2082
-
2083
- async resetLoginAttempts(userId: string): Promise<void> {
2084
- throw new Error("Not implemented");
2085
- }
2086
-
2087
- async saveToken(userId: string, token: string): Promise<void> {
2088
- throw new Error("Not implemented");
2089
- }
2090
- }`.trimEnd();
2091
- }
2092
- return `export class ${cap}Repository {
2093
- // TODO: inject your data source (ORM, DB client, etc.)
2094
- async findAll(): Promise<unknown[]> { throw new Error("Not implemented"); }
2095
- async findById(id: string): Promise<unknown | null> { throw new Error("Not implemented"); }
2096
- async create(data: Record<string, unknown>): Promise<unknown> { throw new Error("Not implemented"); }
2097
- async update(id: string, data: Record<string, unknown>): Promise<unknown | null> { throw new Error("Not implemented"); }
2098
- async delete(id: string): Promise<boolean> { throw new Error("Not implemented"); }
2099
- }`.trimEnd();
2100
- };
2101
- var generateCustomModelTemplate = (moduleName) => {
2102
- const cap = capitalize17(moduleName);
2103
- return `export class ${cap}Model {
2001
+ var generateBuildYourOwnEntityTemplate = (fileName, properties) => {
2002
+ const entityName = `${capitalize17(fileName)}Entity`;
2003
+ const ctorParams = properties.length === 0 ? ` // TODO: define the properties of this entity` : properties.map((prop) => ` public readonly ${prop.name}: ${prop.type},`).join("\n");
2004
+ return `export class ${entityName} {
2104
2005
  constructor(
2105
- public readonly id: string,
2106
- // TODO: add your fields here
2006
+ ${ctorParams}
2107
2007
  ) {}
2108
- }`.trimEnd();
2109
- };
2110
- var generateCustomTypesTemplate = (moduleName) => `// ${moduleName} types
2111
- export type ${capitalize17(moduleName)}Id = string;
2112
- // TODO: add your domain types here`.trimEnd();
2113
- var generateCustomMiddlewareTemplate = (moduleName) => {
2114
- const cap = capitalize17(moduleName);
2115
- return `import { Request, Response, NextFunction } from "opticore-express";
2116
-
2117
- export function ${moduleName}Middleware(req: Request, res: Response, next: NextFunction): void {
2118
- // TODO: implement ${cap} middleware logic
2119
- next();
2120
- }`.trimEnd();
2121
- };
2122
- var generateCustomUtilsTemplate = (moduleName) => `// ${moduleName} utilities
2123
- // TODO: add helper functions here`.trimEnd();
2124
- var generateCustomErrorsTemplate = (moduleName) => {
2125
- const cap = capitalize17(moduleName);
2126
- return `export class ${cap}NotFoundError extends Error {
2127
- constructor(id: string) {
2128
- super(\`${cap} not found: \${id}\`);
2129
- this.name = "${cap}NotFoundError";
2130
- }
2131
- }
2132
- export class ${cap}ValidationError extends Error {
2133
- constructor(message: string) {
2134
- super(message);
2135
- this.name = "${cap}ValidationError";
2136
- }
2137
- }`.trimEnd();
2008
+ }`.trimEnd() + "\n";
2138
2009
  };
2139
- var generateCustomConstantsTemplate = (moduleName) => `// ${moduleName} constants
2140
- export const ${moduleName.toUpperCase()}_PREFIX = "/${moduleName}";
2141
- // TODO: add your constants here`.trimEnd();
2142
- var generateCustomRouterHandlerTemplate = (moduleName, controllerMethods) => {
2143
- const cap = capitalize17(moduleName);
2144
- const handlerName = `${cap}HandlerRouter`;
2145
- const controllerName = `${cap}Controller`;
2146
- const routesCode = (controllerMethods || []).map((method) => {
2147
- const { httpMethod, path: path10 } = CResolveRoute(method, moduleName);
2148
- return `{
2149
- path: \`${path10}\`,
2150
- method: "${httpMethod}",
2010
+ var generateBuildYourOwnRepositoryTemplate = (fileName, methods) => {
2011
+ const repositoryName = `${capitalize17(fileName)}Repository`;
2012
+ const body = methods.length === 0 ? ` // TODO: define the actions this repository can perform` : methods.map((method) => ` async ${method}(): Promise<unknown> { throw new Error("Not implemented"); }`).join("\n");
2013
+ return `export class ${repositoryName} {
2014
+ // TODO: inject your data source (ORM, DB client, etc.)
2015
+ ${body}
2016
+ }`.trimEnd() + "\n";
2017
+ };
2018
+ var generateBuildYourOwnRouteTemplate = (fileName, actions) => {
2019
+ const capitalized = capitalize17(fileName);
2020
+ const handlerName = `${capitalized}HandlerRouter`;
2021
+ const controllerName = `${capitalized}Controller`;
2022
+ const routes = actions.map((action) => {
2023
+ const { httpMethod, path: path10 } = CResolveRoute(action, fileName);
2024
+ return { httpMethod, path: path10, action };
2025
+ });
2026
+ const body = routes.length === 0 ? ` // TODO: define the routes for this module` : routes.map((route) => `{
2027
+ path: "${route.path}",
2028
+ method: "${route.httpMethod}",
2151
2029
  middlewares: [],
2152
- handler: async (ctx: ICustomContext) => await ${controllerName}.${method}(ctx.req, ctx.res)
2153
- }`;
2154
- }).join(",\n");
2030
+ handler: async (ctx: ICustomContext) => await ${controllerName}.${route.action}(ctx.req, ctx.res)
2031
+ }`).join(",\n").replace(/\n/g, "\n ");
2155
2032
  return `import { OpticoreRoutingFactory, ICustomContext, IMultipleRouteDefinition } from "opticore-router";
2156
- import { ${controllerName} } from "../../app/${moduleName}.controller";
2033
+ // TODO: adjust this import if "${controllerName}" lives in a different folder
2034
+ import { ${controllerName} } from "./${fileName}.controller";
2157
2035
 
2158
2036
  export const ${handlerName}: () => IMultipleRouteDefinition = () => {
2159
2037
  return OpticoreRoutingFactory.routes(
2160
2038
  ${controllerName},
2161
2039
  [
2162
- ${routesCode ? routesCode.replace(/\n/g, "\n ") : ""}
2040
+ ${body}
2163
2041
  ]
2164
2042
  );
2165
- };`.trimEnd();
2166
- };
2167
- var generateCustomRouterTemplate = (moduleName) => {
2168
- const cap = capitalize17(moduleName);
2169
- const handlerName = `${cap}HandlerRouter`;
2170
- const routerName = `${cap}Router`;
2171
- return `import { ${handlerName} } from "./core/handler/${moduleName}.router.handler";
2172
- import { TFeatureRoutes } from "opticore-router";
2173
-
2174
- export const ${routerName}: TFeatureRoutes = {
2175
- routes: [
2176
- {
2177
- path: ${handlerName}().path,
2178
- handler: ${handlerName}().handler
2179
- }
2180
- ]
2181
- };`.trimEnd();
2043
+ };`.trimEnd() + "\n";
2182
2044
  };
2183
2045
 
2184
- // src/templates/customModule/customModuleScaffold.template.ts
2046
+ // src/templates/customModule/buildYourOwnArchitectureScaffold.template.ts
2185
2047
  var ok = (msg) => {
2186
- console.log(colors9.green(`\u2705 ${msg}`));
2048
+ console.log(colors9.green(`\u2714 ${msg}`));
2187
2049
  };
2188
- var tip = (msg) => {
2189
- console.log(colors9.yellow(` ${msg}`));
2050
+ var info = (msg) => {
2051
+ console.log(colors9.cyan(`\u2139 ${msg}`));
2190
2052
  };
2191
- var capitalize18 = (s) => s.charAt(0).toUpperCase() + s.slice(1);
2192
- async function askFile(label) {
2193
- const answer = await UPrompt.confirm(`Create ${label}?`, false);
2194
- return answer === true;
2195
- }
2196
- async function askMethods() {
2197
- const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
2198
- if (!wantsMethods) return [];
2199
- const raw = await UPrompt.text(
2200
- "Enter the method names (comma separated):",
2201
- "create, findAll, findById, update, delete",
2202
- (v) => v ? void 0 : "Enter at least one method name."
2203
- );
2204
- if (isCancel4(raw)) return [];
2205
- return raw.split(",").map((m) => m.trim()).filter(Boolean);
2206
- }
2207
- var customModuleScaffoldTemplate = async () => {
2208
- const rawName = await _featureName();
2209
- if (isCancel4(rawName)) {
2210
- console.log(colors9.bgRed(colors9.white("Operation cancelled.")));
2211
- process.exit(0);
2053
+ var NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
2054
+ var askName = async (message, placeholder) => {
2055
+ const raw = await UPrompt.text(message, placeholder, (value) => {
2056
+ if (!value) {
2057
+ return "Please enter a name.";
2058
+ }
2059
+ if (!NAME_PATTERN.test(value)) {
2060
+ return "Use letters, numbers, - or _, starting with a letter.";
2061
+ }
2062
+ });
2063
+ if (isCancel6(raw)) {
2064
+ return void 0;
2212
2065
  }
2213
- const moduleName = rawName.toString();
2214
- const moduleDir = path6.join(process.cwd(), "src", "features", moduleName);
2215
- if (fs4.existsSync(moduleDir)) {
2216
- console.log(colors9.bgCyan(colors9.white(`Module "${moduleName}" already exists.`)));
2217
- process.exit(0);
2066
+ return raw;
2067
+ };
2068
+ var askCommaSeparatedList = async (message, placeholder) => {
2069
+ const raw = await UPrompt.text(message, placeholder, () => void 0);
2070
+ if (isCancel6(raw) || !raw) return [];
2071
+ return raw.split(",").map((v) => v.trim()).filter(Boolean);
2072
+ };
2073
+ var parseFieldDefinitions = (raw) => raw.map((entry) => {
2074
+ const [name, type] = entry.split(":").map((v) => v.trim());
2075
+ return { name: name || entry, type: type || "string" };
2076
+ });
2077
+ var renderTree = (node, prefix = "") => {
2078
+ const lines = [];
2079
+ const children = node.children ?? [];
2080
+ children.forEach((child, index) => {
2081
+ const isLast = index === children.length - 1;
2082
+ const branch = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
2083
+ lines.push(`${prefix}${branch}${child.name}${child.type === "dir" ? "/" : ""}`);
2084
+ if (child.type === "dir") {
2085
+ const nextPrefix = prefix + (isLast ? " " : "\u2502 ");
2086
+ lines.push(...renderTree(child, nextPrefix));
2087
+ }
2088
+ });
2089
+ return lines;
2090
+ };
2091
+ var printTree = (root) => {
2092
+ console.log(colors9.yellow(`${root.name}/`));
2093
+ renderTree(root).forEach((line) => console.log(colors9.yellow(line)));
2094
+ };
2095
+ async function handleFileCreation(dirPath) {
2096
+ const fileType = await UPrompt.select(
2097
+ "What type of file do you want to create?",
2098
+ ["controller"],
2099
+ [
2100
+ { label: "Controller", value: ["controller"] },
2101
+ { label: "Service", value: ["service"] },
2102
+ { label: "DTO", value: ["dto"] },
2103
+ { label: "Entity", value: ["entity"] },
2104
+ { label: "Repository", value: ["repository"] },
2105
+ { label: "Route", value: ["route"] }
2106
+ ]
2107
+ );
2108
+ if (isCancel6(fileType)) return void 0;
2109
+ const baseName = await askName(`Enter the name of this ${fileType} (without extension):`, "user");
2110
+ if (!baseName) return void 0;
2111
+ let fileName;
2112
+ let content;
2113
+ switch (fileType) {
2114
+ case "controller": {
2115
+ const wantsMethods = await UPrompt.confirm("Do you want to create methods for this controller?");
2116
+ let methods = [];
2117
+ if (wantsMethods === true) {
2118
+ methods = await askCommaSeparatedList(
2119
+ "Enter the method names (comma separated):",
2120
+ "create, findAll, findById, update, delete"
2121
+ );
2122
+ }
2123
+ fileName = `${baseName}.controller.ts`;
2124
+ content = generateBuildYourOwnControllerTemplate(baseName, methods);
2125
+ break;
2126
+ }
2127
+ case "service": {
2128
+ const kind = await UPrompt.select(
2129
+ "Do you want a class with methods, or a service that is just a function?",
2130
+ ["class"],
2131
+ [
2132
+ { label: "Class with methods", value: ["class"] },
2133
+ { label: "Single function", value: ["function"] }
2134
+ ]
2135
+ );
2136
+ if (isCancel6(kind)) return void 0;
2137
+ fileName = `${baseName}.service.ts`;
2138
+ if (kind === "class") {
2139
+ const methods = await askCommaSeparatedList(
2140
+ "Enter the method names (comma separated):",
2141
+ "findAll, findById, create, update, delete"
2142
+ );
2143
+ content = generateBuildYourOwnServiceClassTemplate(baseName, methods);
2144
+ } else {
2145
+ content = generateBuildYourOwnServiceFunctionTemplate(baseName);
2146
+ }
2147
+ break;
2148
+ }
2149
+ case "dto": {
2150
+ const raw = await askCommaSeparatedList(
2151
+ "Enter the DTO fields as name:type pairs, comma separated:",
2152
+ "name:string, email:string"
2153
+ );
2154
+ fileName = `${baseName}.dto.ts`;
2155
+ content = generateBuildYourOwnDtoTemplate(baseName, parseFieldDefinitions(raw));
2156
+ break;
2157
+ }
2158
+ case "entity": {
2159
+ const raw = await askCommaSeparatedList(
2160
+ "Enter the entity properties as name:type pairs, comma separated:",
2161
+ "id:string, name:string, createdAt:Date"
2162
+ );
2163
+ fileName = `${baseName}.entity.ts`;
2164
+ content = generateBuildYourOwnEntityTemplate(baseName, parseFieldDefinitions(raw));
2165
+ break;
2166
+ }
2167
+ case "repository": {
2168
+ const methods = await askCommaSeparatedList(
2169
+ "Enter the actions this repository should perform (comma separated):",
2170
+ "findAll, findById, save, update, delete"
2171
+ );
2172
+ fileName = `${baseName}.repository.ts`;
2173
+ content = generateBuildYourOwnRepositoryTemplate(baseName, methods);
2174
+ break;
2175
+ }
2176
+ case "route": {
2177
+ const actions = await askCommaSeparatedList(
2178
+ "Enter the actions to expose as routes (comma separated):",
2179
+ "findAll, findById, create, update, delete"
2180
+ );
2181
+ fileName = `${baseName}.route.ts`;
2182
+ content = generateBuildYourOwnRouteTemplate(baseName, actions);
2183
+ break;
2184
+ }
2218
2185
  }
2219
- const appDir = path6.join(moduleDir, "app");
2220
- const coreMiddlewaresDir = path6.join(moduleDir, "core", "middlewares");
2221
- const coreHandlerDir = path6.join(moduleDir, "core", "handler");
2222
- const sharedUtilsDir = path6.join(moduleDir, "shared", "utils");
2223
- const sharedErrorsDir = path6.join(moduleDir, "shared", "errors");
2224
- const sharedConstantsDir = path6.join(moduleDir, "shared", "constants");
2225
- UFsModule.createDirectoryRecursively(appDir);
2226
- UFsModule.createDirectoryRecursively(coreHandlerDir);
2227
- UFsModule.createDirectoryRecursively(sharedUtilsDir);
2228
- UFsModule.createDirectoryRecursively(sharedErrorsDir);
2229
- UFsModule.createDirectoryRecursively(sharedConstantsDir);
2230
- let controllerMethods = [];
2231
- if (await askFile(`${moduleName}.controller.ts`)) {
2232
- controllerMethods = await askMethods();
2233
- UFsModule.createFile(
2234
- path6.join(appDir, `${moduleName}.controller.ts`),
2235
- generateCustomControllerTemplate(`${capitalize18(moduleName)}Controller`, moduleName, controllerMethods)
2186
+ const filePath = path6.join(dirPath, fileName);
2187
+ UFsModule.createFile(filePath, content);
2188
+ ok(fileName);
2189
+ return { name: fileName, type: "file" };
2190
+ }
2191
+ async function handleDirectory(dirPath, node) {
2192
+ let keepGoing = true;
2193
+ while (keepGoing) {
2194
+ const choice = await UPrompt.select(
2195
+ `Inside "${node.name}", do you want to create a file or a folder?`,
2196
+ ["file"],
2197
+ [
2198
+ { label: "File", value: ["file"] },
2199
+ { label: "Folder", value: ["folder"] }
2200
+ ]
2236
2201
  );
2237
- ok(`app/${moduleName}.controller.ts`);
2238
- }
2239
- if (await askFile(`${moduleName}.service.ts`)) {
2240
- UFsModule.createFile(path6.join(appDir, `${moduleName}.service.ts`), generateCustomServiceTemplate(moduleName));
2241
- ok(`app/${moduleName}.service.ts`);
2242
- }
2243
- if (await askFile(`${moduleName}.repository.ts`)) {
2244
- UFsModule.createFile(path6.join(appDir, `${moduleName}.repository.ts`), generateCustomRepositoryTemplate(moduleName));
2245
- ok(`app/${moduleName}.repository.ts`);
2246
- }
2247
- if (await askFile(`${moduleName}.model.ts`)) {
2248
- UFsModule.createFile(path6.join(appDir, `${moduleName}.model.ts`), generateCustomModelTemplate(moduleName));
2249
- ok(`app/${moduleName}.model.ts`);
2250
- }
2251
- if (await askFile(`${moduleName}.types.ts`)) {
2252
- UFsModule.createFile(path6.join(appDir, `${moduleName}.types.ts`), generateCustomTypesTemplate(moduleName));
2253
- ok(`app/${moduleName}.types.ts`);
2254
- }
2255
- const wantsMiddleware = await UPrompt.confirm("Does your module need a middleware?", false);
2256
- if (wantsMiddleware === true) {
2257
- UFsModule.createDirectoryRecursively(coreMiddlewaresDir);
2258
- UFsModule.createFile(
2259
- path6.join(coreMiddlewaresDir, `${moduleName}.middleware.ts`),
2260
- generateCustomMiddlewareTemplate(moduleName)
2202
+ if (isCancel6(choice)) return;
2203
+ if (choice === "folder") {
2204
+ const folderName = await askName("Enter the folder name:", "core");
2205
+ if (!folderName) return;
2206
+ const subDir = path6.join(dirPath, folderName);
2207
+ UFsModule.createDirectoryRecursively(subDir);
2208
+ const subNode = { name: folderName, type: "dir", children: [] };
2209
+ node.children.push(subNode);
2210
+ ok(`${folderName}/`);
2211
+ await handleDirectory(subDir, subNode);
2212
+ } else {
2213
+ const fileNode = await handleFileCreation(dirPath);
2214
+ if (fileNode) {
2215
+ node.children.push(fileNode);
2216
+ }
2217
+ }
2218
+ info(`Current structure of "${node.name}":`);
2219
+ printTree(node);
2220
+ const wantsContinue = await UPrompt.confirm(`Continue creating files/folders inside "${node.name}"?`);
2221
+ if (isCancel6(wantsContinue) || wantsContinue !== true) {
2222
+ keepGoing = false;
2223
+ }
2224
+ }
2225
+ }
2226
+ var buildYourOwnArchitectureScaffoldTemplate = async () => {
2227
+ const featuresDir = path6.join(process.cwd(), "src", "features");
2228
+ const forest = [];
2229
+ let creatingNewRoot = true;
2230
+ while (creatingNewRoot) {
2231
+ const rootName = await askName("Enter the name of the root folder for your architecture:", "myArchitecture");
2232
+ if (!rootName) {
2233
+ console.log(colors9.bgRed(colors9.white("Operation cancelled.")));
2234
+ process.exit(0);
2235
+ }
2236
+ const rootDir = path6.join(featuresDir, rootName);
2237
+ if (fs4.existsSync(rootDir)) {
2238
+ info(`Folder "${rootName}" already exists, new files/folders will be added inside it.`);
2239
+ }
2240
+ UFsModule.createDirectoryRecursively(rootDir);
2241
+ const rootNode = { name: rootName, type: "dir", children: [] };
2242
+ forest.push(rootNode);
2243
+ await handleDirectory(rootDir, rootNode);
2244
+ const wantsNewRoot = await UPrompt.confirm(
2245
+ "Do you want to create a new folder at the root of your architecture?",
2246
+ false
2261
2247
  );
2262
- ok(`core/middlewares/${moduleName}.middleware.ts`);
2248
+ if (isCancel6(wantsNewRoot) || wantsNewRoot !== true) {
2249
+ console.log(colors9.cyan("En disant non, ce sera la fin de la cr\xE9ation de votre propre architecture."));
2250
+ creatingNewRoot = false;
2251
+ }
2263
2252
  }
2264
- UFsModule.createFile(
2265
- path6.join(coreHandlerDir, `${moduleName}.router.handler.ts`),
2266
- generateCustomRouterHandlerTemplate(moduleName, controllerMethods)
2267
- );
2268
- ok(`core/handler/${moduleName}.router.handler.ts`);
2269
- UFsModule.createFile(path6.join(sharedUtilsDir, `${moduleName}.utils.ts`), generateCustomUtilsTemplate(moduleName));
2270
- UFsModule.createFile(path6.join(sharedErrorsDir, `${moduleName}.errors.ts`), generateCustomErrorsTemplate(moduleName));
2271
- UFsModule.createFile(path6.join(sharedConstantsDir, `${moduleName}.constants.ts`), generateCustomConstantsTemplate(moduleName));
2272
- ok(`shared/utils/${moduleName}.utils.ts`);
2273
- ok(`shared/errors/${moduleName}.errors.ts`);
2274
- ok(`shared/constants/${moduleName}.constants.ts`);
2275
- UFsModule.createFile(path6.join(moduleDir, `${moduleName}.router.ts`), generateCustomRouterTemplate(moduleName));
2276
- ok(`${moduleName}.router.ts`);
2277
- FeatureComponentGeneratorUtils.setStructure("custom");
2278
- await FeatureComponentGeneratorUtils.registerModuleRouter(moduleName);
2279
- tip(`src/features/${moduleName}/`);
2280
- tip(`\u251C\u2500\u2500 app/`);
2281
- tip(`\u251C\u2500\u2500 core/`);
2282
- tip(`\u2502 \u251C\u2500\u2500 middlewares/`);
2283
- tip(`\u2502 \u2514\u2500\u2500 handler/`);
2284
- tip(`\u251C\u2500\u2500 shared/`);
2285
- tip(`\u2502 \u251C\u2500\u2500 utils/`);
2286
- tip(`\u2502 \u251C\u2500\u2500 errors/`);
2287
- tip(`\u2502 \u2514\u2500\u2500 constants/`);
2288
- tip(`\u2514\u2500\u2500 ${moduleName}.router.ts`);
2289
2253
  console.log(`
2290
- ${colors9.bgGreen(colors9.white(`
2291
- \u{1F389} Custom module "${moduleName}" scaffolded successfully!
2292
- `))}`);
2254
+ ${colors9.bgGreen(colors9.white("\n\u{1F389} Your custom architecture has been created!\n"))}`);
2255
+ forest.forEach((root) => printTree(root));
2293
2256
  };
2294
2257
 
2295
2258
  // src/templates/mvcModule/mvcModuleScaffold.template.ts
2296
2259
  import path7 from "path";
2297
2260
  import colors10 from "ansi-colors";
2298
- import { isCancel as isCancel5 } from "@clack/prompts";
2261
+ import { isCancel as isCancel7 } from "@clack/prompts";
2299
2262
 
2300
2263
  // src/templates/mvcModule/mvcModule.template.ts
2301
- var capitalize19 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2264
+ var capitalize18 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2302
2265
  var generateMvcModelTemplate = (featureName) => {
2303
- const capitalized = capitalize19(featureName);
2266
+ const capitalized = capitalize18(featureName);
2304
2267
  const modelName = `${capitalized}Model`;
2305
2268
  return `/**
2306
2269
  * ${modelName} \u2014 Model
@@ -2358,7 +2321,7 @@ export class ${modelName} {
2358
2321
  `;
2359
2322
  };
2360
2323
  var generateMvcViewTemplate = (featureName) => {
2361
- const capitalized = capitalize19(featureName);
2324
+ const capitalized = capitalize18(featureName);
2362
2325
  const modelName = `${capitalized}Model`;
2363
2326
  const viewName = `${capitalized}View`;
2364
2327
  return `import { ${modelName} } from "../models/${featureName}.model";
@@ -2384,10 +2347,10 @@ export class ${viewName} {
2384
2347
  `;
2385
2348
  };
2386
2349
  var generateMvcControllerTemplate = (controllerName, featureName, methods) => {
2387
- const capitalized = capitalize19(featureName);
2350
+ const capitalized = capitalize18(featureName);
2388
2351
  const modelName = `${capitalized}Model`;
2389
2352
  const viewName = `${capitalized}View`;
2390
- const methodsCode = methods.map((method) => generateMethod4(method, capitalized, modelName, viewName)).join("\n");
2353
+ const methodsCode = methods.map((method) => generateMethod3(method, capitalized, modelName, viewName)).join("\n");
2391
2354
  return `import { Request, Response } from "opticore-express";
2392
2355
  import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
2393
2356
  import { ${modelName} } from "../models/${featureName}.model";
@@ -2402,13 +2365,23 @@ ${methodsCode}
2402
2365
  }
2403
2366
  `;
2404
2367
  };
2405
- var generateMethod4 = (method, capitalized, modelName, viewName) => {
2368
+ var generateMethod3 = (method, capitalized, modelName, viewName) => {
2406
2369
  const lower = method.toLowerCase();
2407
- if (lower.includes("findall") || lower.includes("getall")) return generateFindAllMethod3(method, capitalized, modelName, viewName);
2408
- if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return generateFindByIdMethod3(method, capitalized, modelName, viewName);
2409
- if (lower.includes("create") || lower.includes("add")) return generateCreateMethod3(method, capitalized, modelName, viewName);
2410
- if (lower.includes("update") || lower.includes("edit")) return generateUpdateMethod3(method, capitalized, modelName, viewName);
2411
- if (lower.includes("delete") || lower.includes("remove")) return generateDeleteMethod3(method, capitalized, modelName);
2370
+ if (lower.includes("findall") || lower.includes("getall")) {
2371
+ return generateFindAllMethod3(method, capitalized, modelName, viewName);
2372
+ }
2373
+ if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) {
2374
+ return generateFindByIdMethod3(method, capitalized, modelName, viewName);
2375
+ }
2376
+ if (lower.includes("create") || lower.includes("add")) {
2377
+ return generateCreateMethod3(method, capitalized, modelName, viewName);
2378
+ }
2379
+ if (lower.includes("update") || lower.includes("edit")) {
2380
+ return generateUpdateMethod3(method, capitalized, modelName, viewName);
2381
+ }
2382
+ if (lower.includes("delete") || lower.includes("remove")) {
2383
+ return generateDeleteMethod3(method, capitalized, modelName);
2384
+ }
2412
2385
  return `
2413
2386
  static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2414
2387
  try {
@@ -2483,7 +2456,7 @@ var generateDeleteMethod3 = (method, capitalized, modelName) => `
2483
2456
  }
2484
2457
  `;
2485
2458
  var generateMvcRouterHandlerTemplate = (featureName, controllerMethods) => {
2486
- const capitalized = capitalize19(featureName);
2459
+ const capitalized = capitalize18(featureName);
2487
2460
  const handlerName = `${capitalized}HandlerRouter`;
2488
2461
  const controllerName = `${capitalized}Controller`;
2489
2462
  const routesCode = (controllerMethods || []).map((method) => {
@@ -2509,7 +2482,7 @@ export const ${handlerName}: () => IMultipleRouteDefinition = () => {
2509
2482
  `;
2510
2483
  };
2511
2484
  var generateMvcRouterTemplate = (featureName) => {
2512
- const capitalized = capitalize19(featureName);
2485
+ const capitalized = capitalize18(featureName);
2513
2486
  const handlerName = `${capitalized}HandlerRouter`;
2514
2487
  const routerName = `${capitalized}Router`;
2515
2488
  return `import { ${handlerName} } from "./${featureName}.router.handler";
@@ -2527,16 +2500,26 @@ export const ${routerName}: TFeatureRoutes = {
2527
2500
  };
2528
2501
  var resolveRoute3 = (methodName, featureName) => {
2529
2502
  const lower = methodName.toLowerCase();
2530
- if (lower.includes("findall") || lower.includes("getall")) return { httpMethod: "get", path: `/${featureName}` };
2531
- if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return { httpMethod: "get", path: `/${featureName}/:id` };
2532
- if (lower.includes("create") || lower.includes("add")) return { httpMethod: "post", path: `/${featureName}` };
2533
- if (lower.includes("update") || lower.includes("edit")) return { httpMethod: "put", path: `/${featureName}/:id` };
2534
- if (lower.includes("delete") || lower.includes("remove")) return { httpMethod: "delete", path: `/${featureName}/:id` };
2503
+ if (lower.includes("findall") || lower.includes("getall")) {
2504
+ return { httpMethod: "get", path: `/${featureName}` };
2505
+ }
2506
+ if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) {
2507
+ return { httpMethod: "get", path: `/${featureName}/:id` };
2508
+ }
2509
+ if (lower.includes("create") || lower.includes("add")) {
2510
+ return { httpMethod: "post", path: `/${featureName}` };
2511
+ }
2512
+ if (lower.includes("update") || lower.includes("edit")) {
2513
+ return { httpMethod: "put", path: `/${featureName}/:id` };
2514
+ }
2515
+ if (lower.includes("delete") || lower.includes("remove")) {
2516
+ return { httpMethod: "delete", path: `/${featureName}/:id` };
2517
+ }
2535
2518
  return { httpMethod: "get", path: `/${featureName}/${lower}` };
2536
2519
  };
2537
2520
 
2538
2521
  // src/templates/mvcModule/mvcModuleScaffold.template.ts
2539
- var capitalize20 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2522
+ var capitalize19 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2540
2523
  var mvcModuleTemplate = async (featureName) => {
2541
2524
  FeatureComponentGeneratorUtils.setStructure("mvc");
2542
2525
  const basePath = path7.join("src", "features", featureName);
@@ -2547,21 +2530,23 @@ var mvcModuleTemplate = async (featureName) => {
2547
2530
  routesDir: path7.join(basePath, "routes")
2548
2531
  };
2549
2532
  Object.values(paths).forEach((dir) => UFsModule.createDirectoryRecursively(dir));
2550
- const controllerName = `${capitalize20(featureName)}Controller`;
2533
+ const controllerName = `${capitalize19(featureName)}Controller`;
2551
2534
  UFsModule.createFile(path7.join(paths.modelsDir, `${featureName}.model.ts`), generateMvcModelTemplate(featureName));
2552
- console.log(colors10.green(`\u2705 Model created: ${path7.join(paths.modelsDir, `${featureName}.model.ts`)}`));
2535
+ console.log(colors10.green(`\u2714 Model created: ${path7.join(paths.modelsDir, `${featureName}.model.ts`)}`));
2553
2536
  UFsModule.createFile(path7.join(paths.viewsDir, `${featureName}.view.ts`), generateMvcViewTemplate(featureName));
2554
- console.log(colors10.green(`\u2705 View created: ${path7.join(paths.viewsDir, `${featureName}.view.ts`)}`));
2537
+ console.log(colors10.green(`\u2714 View created: ${path7.join(paths.viewsDir, `${featureName}.view.ts`)}`));
2555
2538
  const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
2556
2539
  let methods = [];
2557
2540
  let controllerContent;
2558
- if (wantsMethods && !isCancel5(wantsMethods)) {
2541
+ if (wantsMethods && !isCancel7(wantsMethods)) {
2559
2542
  const methodsText = await UPrompt.text(
2560
2543
  "Enter the method names (comma separated):",
2561
2544
  "create, findAll, findById, update, delete",
2562
2545
  (v) => v ? void 0 : "You must enter at least one method."
2563
2546
  );
2564
- methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
2547
+ if (!isCancel7(methodsText)) {
2548
+ methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
2549
+ }
2565
2550
  controllerContent = generateMvcControllerTemplate(controllerName, featureName, methods);
2566
2551
  } else {
2567
2552
  controllerContent = `import { Request, Response } from "opticore-express";
@@ -2571,18 +2556,18 @@ export class ${controllerName} {}
2571
2556
  }
2572
2557
  const controllerPath = path7.join(paths.controllersDir, `${featureName}.controller.ts`);
2573
2558
  UFsModule.createFile(controllerPath, controllerContent);
2574
- console.log(colors10.green(`\u2705 Controller created: ${controllerPath}`));
2559
+ console.log(colors10.green(`\u2714 Controller created: ${controllerPath}`));
2575
2560
  UFsModule.createFile(
2576
2561
  path7.join(paths.routesDir, `${featureName}.router.handler.ts`),
2577
2562
  generateMvcRouterHandlerTemplate(featureName, methods)
2578
2563
  );
2579
- console.log(colors10.green(`\u2705 Router Handler created: ${path7.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
2564
+ console.log(colors10.green(`\u2714 Router Handler created: ${path7.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
2580
2565
  UFsModule.createFile(
2581
2566
  path7.join(paths.routesDir, `${featureName}.router.ts`),
2582
2567
  generateMvcRouterTemplate(featureName)
2583
2568
  );
2584
2569
  await FeatureComponentGeneratorUtils.registerModuleRouter(featureName);
2585
- console.log(colors10.green(`\u2705 Router created: ${path7.join(paths.routesDir, `${featureName}.router.ts`)}`));
2570
+ console.log(colors10.green(`\u2714 Router created: ${path7.join(paths.routesDir, `${featureName}.router.ts`)}`));
2586
2571
  console.log(
2587
2572
  colors10.bgGreen(
2588
2573
  colors10.white(`
@@ -2595,12 +2580,12 @@ export class ${controllerName} {}
2595
2580
  // src/templates/layeredModule/layeredModuleScaffold.template.ts
2596
2581
  import path8 from "path";
2597
2582
  import colors11 from "ansi-colors";
2598
- import { isCancel as isCancel6 } from "@clack/prompts";
2583
+ import { isCancel as isCancel8 } from "@clack/prompts";
2599
2584
 
2600
2585
  // src/templates/layeredModule/layeredModule.template.ts
2601
- var capitalize21 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2586
+ var capitalize20 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2602
2587
  var generateLayeredEntityTemplate = (featureName) => {
2603
- const capitalized = capitalize21(featureName);
2588
+ const capitalized = capitalize20(featureName);
2604
2589
  const entityName = `${capitalized}Entity`;
2605
2590
  return `/**
2606
2591
  * ${entityName} \u2014 Entity
@@ -2617,7 +2602,7 @@ export class ${entityName} {
2617
2602
  `;
2618
2603
  };
2619
2604
  var generateLayeredDtoTemplate = (featureName) => {
2620
- const capitalized = capitalize21(featureName);
2605
+ const capitalized = capitalize20(featureName);
2621
2606
  const entityName = `${capitalized}Entity`;
2622
2607
  return `import { ${entityName} } from "../entities/${featureName}.entity";
2623
2608
 
@@ -2644,7 +2629,7 @@ export const to${capitalized}ResponseDto = (entity: ${entityName}): ${capitalize
2644
2629
  `;
2645
2630
  };
2646
2631
  var generateLayeredRepositoryTemplate = (featureName) => {
2647
- const capitalized = capitalize21(featureName);
2632
+ const capitalized = capitalize20(featureName);
2648
2633
  const entityName = `${capitalized}Entity`;
2649
2634
  const repoName = `${capitalized}Repository`;
2650
2635
  return `import { ${entityName} } from "../entities/${featureName}.entity";
@@ -2683,7 +2668,7 @@ export class ${repoName} {
2683
2668
  `;
2684
2669
  };
2685
2670
  var generateLayeredServiceTemplate = (featureName) => {
2686
- const capitalized = capitalize21(featureName);
2671
+ const capitalized = capitalize20(featureName);
2687
2672
  const entityName = `${capitalized}Entity`;
2688
2673
  const repoName = `${capitalized}Repository`;
2689
2674
  const serviceName = `${capitalized}Service`;
@@ -2732,9 +2717,9 @@ export class ${serviceName} {
2732
2717
  `;
2733
2718
  };
2734
2719
  var generateLayeredControllerTemplate = (controllerName, featureName, methods) => {
2735
- const capitalized = capitalize21(featureName);
2720
+ const capitalized = capitalize20(featureName);
2736
2721
  const serviceName = `${capitalized}Service`;
2737
- const methodsCode = methods.map((method) => generateMethod5(method, capitalized, serviceName)).join("\n");
2722
+ const methodsCode = methods.map((method) => generateMethod4(method, capitalized, serviceName)).join("\n");
2738
2723
  return `import { Request, Response } from "opticore-express";
2739
2724
  import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
2740
2725
  import { ${serviceName} } from "../services/${featureName}.service";
@@ -2752,7 +2737,7 @@ ${methodsCode}
2752
2737
  }
2753
2738
  `;
2754
2739
  };
2755
- var generateMethod5 = (method, capitalized, serviceName) => {
2740
+ var generateMethod4 = (method, capitalized, serviceName) => {
2756
2741
  const lower = method.toLowerCase();
2757
2742
  if (lower.includes("findall") || lower.includes("getall")) return generateFindAllMethod4(method, capitalized);
2758
2743
  if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return generateFindByIdMethod4(method, capitalized);
@@ -2839,7 +2824,7 @@ var generateDeleteMethod4 = (method, capitalized) => `
2839
2824
  }
2840
2825
  `;
2841
2826
  var generateLayeredRouterHandlerTemplate = (featureName, controllerMethods) => {
2842
- const capitalized = capitalize21(featureName);
2827
+ const capitalized = capitalize20(featureName);
2843
2828
  const handlerName = `${capitalized}HandlerRouter`;
2844
2829
  const controllerName = `${capitalized}Controller`;
2845
2830
  const routesCode = (controllerMethods || []).map((method) => {
@@ -2865,7 +2850,7 @@ export const ${handlerName}: () => IMultipleRouteDefinition = () => {
2865
2850
  `;
2866
2851
  };
2867
2852
  var generateLayeredRouterTemplate = (featureName) => {
2868
- const capitalized = capitalize21(featureName);
2853
+ const capitalized = capitalize20(featureName);
2869
2854
  const handlerName = `${capitalized}HandlerRouter`;
2870
2855
  const routerName = `${capitalized}Router`;
2871
2856
  return `import { ${handlerName} } from "./${featureName}.router.handler";
@@ -2892,7 +2877,7 @@ var resolveRoute4 = (methodName, featureName) => {
2892
2877
  };
2893
2878
 
2894
2879
  // src/templates/layeredModule/layeredModuleScaffold.template.ts
2895
- var capitalize22 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2880
+ var capitalize21 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2896
2881
  var layeredModuleTemplate = async (featureName) => {
2897
2882
  FeatureComponentGeneratorUtils.setStructure("layered");
2898
2883
  const basePath = path8.join("src", "features", featureName);
@@ -2905,25 +2890,27 @@ var layeredModuleTemplate = async (featureName) => {
2905
2890
  routesDir: path8.join(basePath, "routes")
2906
2891
  };
2907
2892
  Object.values(paths).forEach((dir) => UFsModule.createDirectoryRecursively(dir));
2908
- const controllerName = `${capitalize22(featureName)}Controller`;
2893
+ const controllerName = `${capitalize21(featureName)}Controller`;
2909
2894
  UFsModule.createFile(path8.join(paths.entitiesDir, `${featureName}.entity.ts`), generateLayeredEntityTemplate(featureName));
2910
- console.log(colors11.green(`\u2705 Entity created: ${path8.join(paths.entitiesDir, `${featureName}.entity.ts`)}`));
2895
+ console.log(colors11.green(`\u2714 Entity created: ${path8.join(paths.entitiesDir, `${featureName}.entity.ts`)}`));
2911
2896
  UFsModule.createFile(path8.join(paths.dtoDir, `${featureName}.dto.ts`), generateLayeredDtoTemplate(featureName));
2912
- console.log(colors11.green(`\u2705 DTO created: ${path8.join(paths.dtoDir, `${featureName}.dto.ts`)}`));
2897
+ console.log(colors11.green(`\u2714 DTO created: ${path8.join(paths.dtoDir, `${featureName}.dto.ts`)}`));
2913
2898
  UFsModule.createFile(path8.join(paths.repositoriesDir, `${featureName}.repository.ts`), generateLayeredRepositoryTemplate(featureName));
2914
- console.log(colors11.green(`\u2705 Repository created: ${path8.join(paths.repositoriesDir, `${featureName}.repository.ts`)}`));
2899
+ console.log(colors11.green(`\u2714 Repository created: ${path8.join(paths.repositoriesDir, `${featureName}.repository.ts`)}`));
2915
2900
  UFsModule.createFile(path8.join(paths.servicesDir, `${featureName}.service.ts`), generateLayeredServiceTemplate(featureName));
2916
- console.log(colors11.green(`\u2705 Service created: ${path8.join(paths.servicesDir, `${featureName}.service.ts`)}`));
2901
+ console.log(colors11.green(`\u2714 Service created: ${path8.join(paths.servicesDir, `${featureName}.service.ts`)}`));
2917
2902
  const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
2918
2903
  let methods = [];
2919
2904
  let controllerContent;
2920
- if (wantsMethods && !isCancel6(wantsMethods)) {
2905
+ if (wantsMethods && !isCancel8(wantsMethods)) {
2921
2906
  const methodsText = await UPrompt.text(
2922
2907
  "Enter the method names (comma separated):",
2923
2908
  "create, findAll, findById, update, delete",
2924
2909
  (v) => v ? void 0 : "You must enter at least one method."
2925
2910
  );
2926
- methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
2911
+ if (!isCancel8(methodsText)) {
2912
+ methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
2913
+ }
2927
2914
  controllerContent = generateLayeredControllerTemplate(controllerName, featureName, methods);
2928
2915
  } else {
2929
2916
  controllerContent = `import { Request, Response } from "opticore-express";
@@ -2933,18 +2920,18 @@ export class ${controllerName} {}
2933
2920
  }
2934
2921
  const controllerPath = path8.join(paths.controllersDir, `${featureName}.controller.ts`);
2935
2922
  UFsModule.createFile(controllerPath, controllerContent);
2936
- console.log(colors11.green(`\u2705 Controller created: ${controllerPath}`));
2923
+ console.log(colors11.green(`\u2714 Controller created: ${controllerPath}`));
2937
2924
  UFsModule.createFile(
2938
2925
  path8.join(paths.routesDir, `${featureName}.router.handler.ts`),
2939
2926
  generateLayeredRouterHandlerTemplate(featureName, methods)
2940
2927
  );
2941
- console.log(colors11.green(`\u2705 Router Handler created: ${path8.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
2928
+ console.log(colors11.green(`\u2714 Router Handler created: ${path8.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
2942
2929
  UFsModule.createFile(
2943
2930
  path8.join(paths.routesDir, `${featureName}.router.ts`),
2944
2931
  generateLayeredRouterTemplate(featureName)
2945
2932
  );
2946
2933
  await FeatureComponentGeneratorUtils.registerModuleRouter(featureName);
2947
- console.log(colors11.green(`\u2705 Router created: ${path8.join(paths.routesDir, `${featureName}.router.ts`)}`));
2934
+ console.log(colors11.green(`\u2714 Router created: ${path8.join(paths.routesDir, `${featureName}.router.ts`)}`));
2948
2935
  console.log(
2949
2936
  colors11.bgGreen(
2950
2937
  colors11.white(`
@@ -2959,7 +2946,7 @@ export class ${controllerName} {}
2959
2946
  UWelcomeMessage();
2960
2947
  const featureChoice = await choiceFeatureCleanModule();
2961
2948
  if (featureChoice === "custom_feature") {
2962
- await customModuleScaffoldTemplate();
2949
+ await buildYourOwnArchitectureScaffoldTemplate();
2963
2950
  return;
2964
2951
  }
2965
2952
  if (featureChoice === "mvc_architecture" || featureChoice === "layered_architecture") {
@@ -2969,7 +2956,7 @@ export class ${controllerName} {}
2969
2956
  if (BaseService._isSubdirectoryExists(featureName2)) {
2970
2957
  BaseService._featureFounded(featureName2);
2971
2958
  }
2972
- if (isCancel7(featureName2)) {
2959
+ if (isCancel9(featureName2)) {
2973
2960
  BaseService._cancelOperation(featureDirectory2);
2974
2961
  return;
2975
2962
  }
@@ -2995,7 +2982,7 @@ export class ${controllerName} {}
2995
2982
  if (featureCleanModule) {
2996
2983
  BaseService._featureFounded(featureName);
2997
2984
  }
2998
- if (isCancel7(featureName)) {
2985
+ if (isCancel9(featureName)) {
2999
2986
  BaseService._cancelOperation(featureDirectory);
3000
2987
  } else {
3001
2988
  try {