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.
package/dist/index.cjs CHANGED
@@ -158,11 +158,14 @@ var init_prompt_utils = __esm({
158
158
  process.exit(0);
159
159
  }
160
160
  static async select(message, defaultValue, options) {
161
- let optSelected = await (0, import_prompts.select)({
161
+ const optSelected = await (0, import_prompts.select)({
162
162
  message,
163
163
  initialValue: defaultValue,
164
164
  options
165
165
  });
166
+ if ((0, import_prompts.isCancel)(optSelected)) {
167
+ return optSelected;
168
+ }
166
169
  return optSelected[0];
167
170
  }
168
171
  };
@@ -214,7 +217,7 @@ You have chosen : ${choice === "opticore_clean_module" ? import_ansi_colors3.def
214
217
  const diagram = [
215
218
  ` ` + I(`INFRASTRUCTURE`),
216
219
  ` ` + I(`controllers \xB7 repositories \xB7 routes`),
217
- ` ` + I(`presenters \xB7 routes`),
220
+ ` ` + I(`presenters \xB7 routes`),
218
221
  ``,
219
222
  ` ` + A(`APPLICATION`),
220
223
  ` ` + A(`ports \xB7 interfaces \xB7 dtos \xB7 use-cases`),
@@ -252,7 +255,7 @@ var init_featureName_service = __esm({
252
255
  "Enter feature's name :",
253
256
  "login",
254
257
  (value) => {
255
- let pattern = new RegExp("^[a-z][A-Za-z]+$");
258
+ let pattern = new RegExp("^[a-z][A-Za-z_-]+$");
256
259
  if (!value) {
257
260
  return "Please enter a feature's name.";
258
261
  }
@@ -1581,11 +1584,21 @@ var init_simpleRouter_template = __esm({
1581
1584
  init_cjs_shims();
1582
1585
  resolveRoute2 = (methodName, featureName) => {
1583
1586
  const lower = methodName.toLowerCase();
1584
- if (lower.includes("findall") || lower.includes("getall")) return { httpMethod: "get", path: `/${featureName}` };
1585
- if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return { httpMethod: "get", path: `/${featureName}/:id` };
1586
- if (lower.includes("create") || lower.includes("add")) return { httpMethod: "post", path: `/${featureName}` };
1587
- if (lower.includes("update") || lower.includes("edit")) return { httpMethod: "put", path: `/${featureName}/:id` };
1588
- if (lower.includes("delete") || lower.includes("remove")) return { httpMethod: "delete", path: `/${featureName}/:id` };
1587
+ if (lower.includes("findall") || lower.includes("getall")) {
1588
+ return { httpMethod: "get", path: `/${featureName}` };
1589
+ }
1590
+ if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) {
1591
+ return { httpMethod: "get", path: `/${featureName}/:id` };
1592
+ }
1593
+ if (lower.includes("create") || lower.includes("add")) {
1594
+ return { httpMethod: "post", path: `/${featureName}` };
1595
+ }
1596
+ if (lower.includes("update") || lower.includes("edit")) {
1597
+ return { httpMethod: "put", path: `/${featureName}/:id` };
1598
+ }
1599
+ if (lower.includes("delete") || lower.includes("remove")) {
1600
+ return { httpMethod: "delete", path: `/${featureName}/:id` };
1601
+ }
1589
1602
  return { httpMethod: "get", path: `/${featureName}/${lower}` };
1590
1603
  };
1591
1604
  generateSimpleRouterHandlerTemplate = (featureName, controllerMethods) => {
@@ -1636,7 +1649,7 @@ export const ${routerName}: TFeatureRoutes = {
1636
1649
  });
1637
1650
 
1638
1651
  // src/utils/featureComponentGenerator.utils.ts
1639
- var import_path2, import_ansi_colors5, import_fs2, import_opticore_logger2, FeatureComponentGeneratorUtils;
1652
+ var import_path2, import_ansi_colors5, import_fs2, import_prompts3, import_opticore_logger2, FeatureComponentGeneratorUtils;
1640
1653
  var init_featureComponentGenerator_utils = __esm({
1641
1654
  "src/utils/featureComponentGenerator.utils.ts"() {
1642
1655
  "use strict";
@@ -1644,6 +1657,7 @@ var init_featureComponentGenerator_utils = __esm({
1644
1657
  import_path2 = __toESM(require("path"), 1);
1645
1658
  import_ansi_colors5 = __toESM(require("ansi-colors"), 1);
1646
1659
  import_fs2 = __toESM(require("fs"), 1);
1660
+ import_prompts3 = require("@clack/prompts");
1647
1661
  init_prompt_utils();
1648
1662
  init_fsModule_utils();
1649
1663
  import_opticore_logger2 = require("opticore-logger");
@@ -1685,7 +1699,7 @@ var init_featureComponentGenerator_utils = __esm({
1685
1699
  const entityName = `${this.capitalize(featureName)}Entity`;
1686
1700
  const filePath = import_path2.default.join(entityDir, `${featureName}.entity.ts`);
1687
1701
  UFsModule.createFile(filePath, generateEntityTemplate(entityName, featureName));
1688
- console.log(import_ansi_colors5.default.green(`\u2705 Entity created: ${filePath}`));
1702
+ console.log(import_ansi_colors5.default.green(`\u2714 Entity created: ${filePath}`));
1689
1703
  }
1690
1704
  /**
1691
1705
  * Creates the domain event file.
@@ -1693,7 +1707,7 @@ var init_featureComponentGenerator_utils = __esm({
1693
1707
  static async createEvent(featureName, eventDir) {
1694
1708
  const filePath = import_path2.default.join(eventDir, `${featureName}.event.ts`);
1695
1709
  UFsModule.createFile(filePath, generateEventTemplate(featureName));
1696
- console.log(import_ansi_colors5.default.green(`\u2705 Event created: ${filePath}`));
1710
+ console.log(import_ansi_colors5.default.green(`\u2714 Event created: ${filePath}`));
1697
1711
  }
1698
1712
  /**
1699
1713
  * Creates the domain exception file.
@@ -1701,7 +1715,7 @@ var init_featureComponentGenerator_utils = __esm({
1701
1715
  static async createException(featureName, exceptionDir) {
1702
1716
  const filePath = import_path2.default.join(exceptionDir, `${featureName}.exception.ts`);
1703
1717
  UFsModule.createFile(filePath, generateExceptionTemplate(featureName));
1704
- console.log(import_ansi_colors5.default.green(`\u2705 Exception created: ${filePath}`));
1718
+ console.log(import_ansi_colors5.default.green(`\u2714 Exception created: ${filePath}`));
1705
1719
  }
1706
1720
  /**
1707
1721
  * Creates the repository port interface.
@@ -1710,7 +1724,7 @@ var init_featureComponentGenerator_utils = __esm({
1710
1724
  const interfaceName = `I${this.capitalize(featureName)}Repository`;
1711
1725
  const filePath = import_path2.default.join(interfaceDir, `${featureName}.repository.interface.ts`);
1712
1726
  UFsModule.createFile(filePath, generateRepositoryInterfaceTemplate(interfaceName, featureName));
1713
- console.log(import_ansi_colors5.default.green(`\u2705 Repository interface created: ${filePath}`));
1727
+ console.log(import_ansi_colors5.default.green(`\u2714 Repository interface created: ${filePath}`));
1714
1728
  }
1715
1729
  /**
1716
1730
  * Creates the presenter port interface.
@@ -1718,7 +1732,7 @@ var init_featureComponentGenerator_utils = __esm({
1718
1732
  static async createPresenterInterface(featureName, presenterInterfaceDir) {
1719
1733
  const filePath = import_path2.default.join(presenterInterfaceDir, `${featureName}.presenter.interface.ts`);
1720
1734
  UFsModule.createFile(filePath, generatePresenterInterfaceTemplate(featureName));
1721
- console.log(import_ansi_colors5.default.green(`\u2705 Presenter interface created: ${filePath}`));
1735
+ console.log(import_ansi_colors5.default.green(`\u2714 Presenter interface created: ${filePath}`));
1722
1736
  }
1723
1737
  /**
1724
1738
  * Creates the application service port interface.
@@ -1726,7 +1740,7 @@ var init_featureComponentGenerator_utils = __esm({
1726
1740
  static async createService(featureName, serviceDir) {
1727
1741
  const filePath = import_path2.default.join(serviceDir, `${featureName}.service.ts`);
1728
1742
  UFsModule.createFile(filePath, generateServiceTemplate(featureName));
1729
- console.log(import_ansi_colors5.default.green(`\u2705 Service interface created: ${filePath}`));
1743
+ console.log(import_ansi_colors5.default.green(`\u2714 Service interface created: ${filePath}`));
1730
1744
  }
1731
1745
  /**
1732
1746
  * Creates the DTO file (input + output shapes + mapper).
@@ -1734,7 +1748,7 @@ var init_featureComponentGenerator_utils = __esm({
1734
1748
  static async createDto(featureName, dtoDir) {
1735
1749
  const filePath = import_path2.default.join(dtoDir, `${featureName}.dto.ts`);
1736
1750
  UFsModule.createFile(filePath, generateDtoTemplate(featureName));
1737
- console.log(import_ansi_colors5.default.green(`\u2705 DTO created: ${filePath}`));
1751
+ console.log(import_ansi_colors5.default.green(`\u2714 DTO created: ${filePath}`));
1738
1752
  }
1739
1753
  /**
1740
1754
  * Creates the use case file.
@@ -1743,7 +1757,7 @@ var init_featureComponentGenerator_utils = __esm({
1743
1757
  const useCaseName = `${this.capitalize(featureName)}UseCase`;
1744
1758
  const filePath = import_path2.default.join(useCaseDir, `${featureName}.usecase.ts`);
1745
1759
  UFsModule.createFile(filePath, generateUseCaseTemplate(useCaseName, featureName));
1746
- console.log(import_ansi_colors5.default.green(`\u2705 UseCase created: ${filePath}`));
1760
+ console.log(import_ansi_colors5.default.green(`\u2714 UseCase created: ${filePath}`));
1747
1761
  }
1748
1762
  /**
1749
1763
  * Creates the concrete repository implementation.
@@ -1752,7 +1766,7 @@ var init_featureComponentGenerator_utils = __esm({
1752
1766
  const interfaceImportPath = `../../../application/ports/repositories/${featureName}.repository.interface`;
1753
1767
  const filePath = import_path2.default.join(repositoryImplDir, `${featureName}.repository.ts`);
1754
1768
  UFsModule.createFile(filePath, generateRepositoryImplTemplate(featureName, interfaceImportPath));
1755
- console.log(import_ansi_colors5.default.green(`\u2705 Repository implementation created: ${filePath}`));
1769
+ console.log(import_ansi_colors5.default.green(`\u2714 Repository implementation created: ${filePath}`));
1756
1770
  }
1757
1771
  /**
1758
1772
  * Creates the concrete presenter implementation.
@@ -1760,7 +1774,7 @@ var init_featureComponentGenerator_utils = __esm({
1760
1774
  static async createPresenterImpl(featureName, presenterImplDir) {
1761
1775
  const filePath = import_path2.default.join(presenterImplDir, `${featureName}.presenter.ts`);
1762
1776
  UFsModule.createFile(filePath, generatePresenterImplTemplate(featureName));
1763
- console.log(import_ansi_colors5.default.green(`\u2705 Presenter implementation created: ${filePath}`));
1777
+ console.log(import_ansi_colors5.default.green(`\u2714 Presenter implementation created: ${filePath}`));
1764
1778
  }
1765
1779
  /**
1766
1780
  * Creates the HTTP controller.
@@ -1774,13 +1788,15 @@ var init_featureComponentGenerator_utils = __esm({
1774
1788
  const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
1775
1789
  let methods = [];
1776
1790
  let content;
1777
- if (wantsMethods) {
1791
+ if (wantsMethods && !(0, import_prompts3.isCancel)(wantsMethods)) {
1778
1792
  const methodsText = await UPrompt.text(
1779
1793
  "Enter the method names (comma separated):",
1780
1794
  "create, findAll, findById, update, delete",
1781
1795
  (v) => v ? void 0 : "You must enter at least one method."
1782
1796
  );
1783
- methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
1797
+ if (!(0, import_prompts3.isCancel)(methodsText)) {
1798
+ methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
1799
+ }
1784
1800
  content = generateControllerTemplate(controllerName, featureName, methods);
1785
1801
  } else {
1786
1802
  content = `import { Request, Response } from "express";
@@ -1789,7 +1805,7 @@ export class ${controllerName} {}
1789
1805
  `;
1790
1806
  }
1791
1807
  UFsModule.createFile(filePath, content);
1792
- console.log(import_ansi_colors5.default.green(`\u2705 Controller created: ${filePath}`));
1808
+ console.log(import_ansi_colors5.default.green(`\u2714 Controller created: ${filePath}`));
1793
1809
  return { controllerName, methods };
1794
1810
  }
1795
1811
  /**
@@ -1798,7 +1814,7 @@ export class ${controllerName} {}
1798
1814
  static async createModel(featureName, modelDir) {
1799
1815
  const filePath = import_path2.default.join(modelDir, `${featureName}.model.ts`);
1800
1816
  UFsModule.createFile(filePath, generateModelTemplate(featureName));
1801
- console.log(import_ansi_colors5.default.green(`\u2705 Model created: ${filePath}`));
1817
+ console.log(import_ansi_colors5.default.green(`\u2714 Model created: ${filePath}`));
1802
1818
  }
1803
1819
  /**
1804
1820
  * Creates the simple repository (no interface, uses the model directly).
@@ -1806,7 +1822,7 @@ export class ${controllerName} {}
1806
1822
  static async createSimpleRepository(featureName, repositoryDir) {
1807
1823
  const filePath = import_path2.default.join(repositoryDir, `${featureName}.repository.ts`);
1808
1824
  UFsModule.createFile(filePath, generateSimpleRepositoryTemplate(featureName));
1809
- console.log(import_ansi_colors5.default.green(`\u2705 Repository created: ${filePath}`));
1825
+ console.log(import_ansi_colors5.default.green(`\u2714 Repository created: ${filePath}`));
1810
1826
  }
1811
1827
  /**
1812
1828
  * Creates the simple concrete service (no interface, wires the repository).
@@ -1814,7 +1830,7 @@ export class ${controllerName} {}
1814
1830
  static async createSimpleService(featureName, serviceDir) {
1815
1831
  const filePath = import_path2.default.join(serviceDir, `${featureName}.service.ts`);
1816
1832
  UFsModule.createFile(filePath, generateSimpleServiceTemplate(featureName));
1817
- console.log(import_ansi_colors5.default.green(`\u2705 Service created: ${filePath}`));
1833
+ console.log(import_ansi_colors5.default.green(`\u2714 Service created: ${filePath}`));
1818
1834
  }
1819
1835
  /**
1820
1836
  * Creates the simple controller (delegates to service, no use-case/presenter).
@@ -1825,13 +1841,15 @@ export class ${controllerName} {}
1825
1841
  const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
1826
1842
  let methods = [];
1827
1843
  let content;
1828
- if (wantsMethods) {
1844
+ if (wantsMethods && !(0, import_prompts3.isCancel)(wantsMethods)) {
1829
1845
  const methodsText = await UPrompt.text(
1830
1846
  "Enter the method names (comma separated):",
1831
1847
  "create, findAll, findById, update, delete",
1832
1848
  (v) => v ? void 0 : "You must enter at least one method."
1833
1849
  );
1834
- methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
1850
+ if (!(0, import_prompts3.isCancel)(methodsText)) {
1851
+ methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
1852
+ }
1835
1853
  content = generateSimpleControllerTemplate(controllerName, featureName, methods);
1836
1854
  } else {
1837
1855
  content = `import { Request, Response } from "express";
@@ -1840,7 +1858,7 @@ export class ${controllerName} {}
1840
1858
  `;
1841
1859
  }
1842
1860
  UFsModule.createFile(filePath, content);
1843
- console.log(import_ansi_colors5.default.green(`\u2705 Controller created: ${filePath}`));
1861
+ console.log(import_ansi_colors5.default.green(`\u2714 Controller created: ${filePath}`));
1844
1862
  return { controllerName, methods };
1845
1863
  }
1846
1864
  /**
@@ -1851,7 +1869,7 @@ export class ${controllerName} {}
1851
1869
  const filePath = import_path2.default.join(routerHandlerDir, `${featureName}.router.handler.ts`);
1852
1870
  const content = this.structure === "simple" ? generateSimpleRouterHandlerTemplate(featureName, controllerMethods) : generateRouterHandlerTemplate(featureName, controllerMethods);
1853
1871
  UFsModule.createFile(filePath, content);
1854
- console.log(import_ansi_colors5.default.green(`\u2705 Router Handler created: ${filePath}`));
1872
+ console.log(import_ansi_colors5.default.green(`\u2714 Router Handler created: ${filePath}`));
1855
1873
  }
1856
1874
  /**
1857
1875
  * Creates the feature router and registers it in register.router.ts.
@@ -1862,7 +1880,7 @@ export class ${controllerName} {}
1862
1880
  const content = this.structure === "simple" ? generateSimpleRouterTemplate(featureName) : generateRouterTemplate(featureName);
1863
1881
  UFsModule.createFile(filePath, content);
1864
1882
  await this.updateRegisterRouter(featureName);
1865
- console.log(import_ansi_colors5.default.green(`\u2705 Router created: ${filePath}`));
1883
+ console.log(import_ansi_colors5.default.green(`\u2714 Router created: ${filePath}`));
1866
1884
  }
1867
1885
  static capitalize(str) {
1868
1886
  return str.charAt(0).toUpperCase() + str.slice(1);
@@ -1877,13 +1895,13 @@ export class ${controllerName} {}
1877
1895
  try {
1878
1896
  if (!import_fs2.default.existsSync(this.REGISTER_ROUTER_PATH)) {
1879
1897
  console.log(
1880
- import_ansi_colors5.default.yellow(`\u26A0\uFE0F register.router.ts not found at ${this.REGISTER_ROUTER_PATH}, skipping auto-registration.`)
1898
+ import_ansi_colors5.default.yellow(`\u26A0 register.router.ts not found at ${this.REGISTER_ROUTER_PATH}, skipping auto-registration.`)
1881
1899
  );
1882
1900
  return;
1883
1901
  }
1884
1902
  let content = import_fs2.default.readFileSync(this.REGISTER_ROUTER_PATH, "utf-8");
1885
1903
  if (content.includes(`import { ${routerName} } from`)) {
1886
- console.log(import_ansi_colors5.default.cyan(`\u2139\uFE0F ${routerName} is already registered.`));
1904
+ console.log(import_ansi_colors5.default.cyan(`\u2139 ${routerName} is already registered.`));
1887
1905
  return;
1888
1906
  }
1889
1907
  const lines = content.split("\n");
@@ -1901,12 +1919,12 @@ export class ${controllerName} {}
1901
1919
  const ARRAY_CLOSE = "]);";
1902
1920
  const startIdx = content.indexOf(ARRAY_OPEN);
1903
1921
  if (startIdx === -1) {
1904
- console.log(import_ansi_colors5.default.yellow(`\u26A0\uFE0F Could not find 'registered([' in register.router.ts.`));
1922
+ console.log(import_ansi_colors5.default.yellow(`\u26A0 Could not find 'registered([' in register.router.ts.`));
1905
1923
  return;
1906
1924
  }
1907
1925
  const endIdx = content.indexOf(ARRAY_CLOSE, startIdx + ARRAY_OPEN.length);
1908
1926
  if (endIdx === -1) {
1909
- console.log(import_ansi_colors5.default.yellow(`\u26A0\uFE0F Could not find matching ']);' in register.router.ts.`));
1927
+ console.log(import_ansi_colors5.default.yellow(`\u26A0 Could not find matching ']);' in register.router.ts.`));
1910
1928
  return;
1911
1929
  }
1912
1930
  const arrayContent = content.substring(startIdx + ARRAY_OPEN.length, endIdx);
@@ -1919,9 +1937,9 @@ export class ${controllerName} {}
1919
1937
  ${indentedRoutes}
1920
1938
  ` + content.substring(endIdx);
1921
1939
  import_fs2.default.writeFileSync(this.REGISTER_ROUTER_PATH, newContent, "utf-8");
1922
- console.log(import_ansi_colors5.default.green(`\u2705 register.router.ts updated with ${routerName}.`));
1940
+ console.log(import_ansi_colors5.default.green(`\u2714 register.router.ts updated with ${routerName}.`));
1923
1941
  } catch (error) {
1924
- console.error(import_ansi_colors5.default.red(`\u274C Failed to update register.router.ts: ${error.message}`));
1942
+ console.error(import_ansi_colors5.default.red(`\u2718 Failed to update register.router.ts: ${error.message}`));
1925
1943
  }
1926
1944
  }
1927
1945
  };
@@ -2045,14 +2063,14 @@ var init_fullCleanComponent_template = __esm({
2045
2063
  });
2046
2064
 
2047
2065
  // src/templates/cleanComponentByStep/cleanComponentByStep.template.ts
2048
- var import_path5, import_ansi_colors8, import_prompts3, cleanComponentByStepTemplate;
2066
+ var import_path5, import_ansi_colors8, import_prompts4, cleanComponentByStepTemplate;
2049
2067
  var init_cleanComponentByStep_template = __esm({
2050
2068
  "src/templates/cleanComponentByStep/cleanComponentByStep.template.ts"() {
2051
2069
  "use strict";
2052
2070
  init_cjs_shims();
2053
2071
  import_path5 = __toESM(require("path"), 1);
2054
2072
  import_ansi_colors8 = __toESM(require("ansi-colors"), 1);
2055
- import_prompts3 = require("@clack/prompts");
2073
+ import_prompts4 = require("@clack/prompts");
2056
2074
  init_fsModule_utils();
2057
2075
  init_prompt_utils();
2058
2076
  init_featureComponentGenerator_utils();
@@ -2062,7 +2080,7 @@ var init_cleanComponentByStep_template = __esm({
2062
2080
  let controller = { controllerName: "", methods: [] };
2063
2081
  const ask = async (label) => {
2064
2082
  const answer = await UPrompt.confirm(label, false);
2065
- if ((0, import_prompts3.isCancel)(answer)) {
2083
+ if ((0, import_prompts4.isCancel)(answer)) {
2066
2084
  UFsModule.removeDir(base, true, true);
2067
2085
  process.exit(0);
2068
2086
  }
@@ -2071,7 +2089,7 @@ var init_cleanComponentByStep_template = __esm({
2071
2089
  const track = () => {
2072
2090
  created++;
2073
2091
  };
2074
- console.log(import_ansi_colors8.default.bold(import_ansi_colors8.default.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")));
2092
+ console.log(import_ansi_colors8.default.bold(import_ansi_colors8.default.cyan("\n Domain ")));
2075
2093
  const mkDir = (dir) => {
2076
2094
  UFsModule.createDirectoryRecursively(dir);
2077
2095
  return dir;
@@ -2088,7 +2106,7 @@ var init_cleanComponentByStep_template = __esm({
2088
2106
  await FeatureComponentGeneratorUtils.createException(featureName, mkDir(import_path5.default.join(base, "domain", "exceptions")));
2089
2107
  track();
2090
2108
  }
2091
- console.log(import_ansi_colors8.default.bold(import_ansi_colors8.default.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")));
2109
+ console.log(import_ansi_colors8.default.bold(import_ansi_colors8.default.cyan("\n Application ")));
2092
2110
  if (await ask(`Repo Interface - ${featureName}.repository.interface.ts`)) {
2093
2111
  await FeatureComponentGeneratorUtils.createRepositoryInterface(featureName, mkDir(import_path5.default.join(base, "application", "ports", "repositories")));
2094
2112
  track();
@@ -2109,7 +2127,7 @@ var init_cleanComponentByStep_template = __esm({
2109
2127
  await FeatureComponentGeneratorUtils.createUseCase(featureName, mkDir(import_path5.default.join(base, "application", "use-cases")));
2110
2128
  track();
2111
2129
  }
2112
- console.log(import_ansi_colors8.default.bold(import_ansi_colors8.default.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")));
2130
+ console.log(import_ansi_colors8.default.bold(import_ansi_colors8.default.cyan("\n Infrastructure ")));
2113
2131
  if (await ask(`Repo Impl - ${featureName}.repository.ts`)) {
2114
2132
  await FeatureComponentGeneratorUtils.createRepositoryImpl(featureName, mkDir(import_path5.default.join(base, "infrastructure", "adapters", "repositories")));
2115
2133
  track();
@@ -2132,7 +2150,7 @@ var init_cleanComponentByStep_template = __esm({
2132
2150
  }
2133
2151
  if (created === 0) {
2134
2152
  console.log(import_ansi_colors8.default.yellow(`
2135
- \u26A0\uFE0F No files were created for feature "${featureName}".`));
2153
+ \u26A0 No files were created for feature "${featureName}".`));
2136
2154
  } else {
2137
2155
  console.log(
2138
2156
  import_ansi_colors8.default.bgGreen(import_ansi_colors8.default.white(`
@@ -2145,13 +2163,13 @@ var init_cleanComponentByStep_template = __esm({
2145
2163
  });
2146
2164
 
2147
2165
  // src/core/components/application/createController.application.ts
2148
- var import_prompts4, createComponentApplication;
2166
+ var import_prompts5, createComponentApplication;
2149
2167
  var init_createController_application = __esm({
2150
2168
  "src/core/components/application/createController.application.ts"() {
2151
2169
  "use strict";
2152
2170
  init_cjs_shims();
2153
2171
  init_controllerType_service();
2154
- import_prompts4 = require("@clack/prompts");
2172
+ import_prompts5 = require("@clack/prompts");
2155
2173
  init_base_service();
2156
2174
  init_cleanType_constant();
2157
2175
  init_simpleComponent_template();
@@ -2167,7 +2185,7 @@ var init_createController_application = __esm({
2167
2185
  { label: "Full CLEAN Architecture component", value: [CCleanType.full_clean_component] }
2168
2186
  ]
2169
2187
  );
2170
- if ((0, import_prompts4.isCancel)(askComponentType) === true || askComponentType === void 0) {
2188
+ if ((0, import_prompts5.isCancel)(askComponentType) === true || askComponentType === void 0) {
2171
2189
  BaseService._cancelOperation(featureDirectory);
2172
2190
  } else {
2173
2191
  switch (askComponentType) {
@@ -2204,397 +2222,340 @@ var init_resolveRoute_constant = __esm({
2204
2222
  }
2205
2223
  });
2206
2224
 
2207
- // src/templates/customModule/customModule.template.ts
2208
- var capitalize17, generateCustomControllerTemplate, generateMethod3, methodFindAll, methodFindById, methodCreate, methodUpdate, methodDelete, generateCustomServiceTemplate, generateCustomRepositoryTemplate, generateCustomModelTemplate, generateCustomTypesTemplate, generateCustomMiddlewareTemplate, generateCustomUtilsTemplate, generateCustomErrorsTemplate, generateCustomConstantsTemplate, generateCustomRouterHandlerTemplate, generateCustomRouterTemplate;
2209
- var init_customModule_template = __esm({
2210
- "src/templates/customModule/customModule.template.ts"() {
2225
+ // src/templates/customModule/buildYourOwnArchitecture.template.ts
2226
+ var capitalize17, generateBuildYourOwnControllerTemplate, generateBuildYourOwnServiceClassTemplate, generateBuildYourOwnServiceFunctionTemplate, generateBuildYourOwnDtoTemplate, generateBuildYourOwnEntityTemplate, generateBuildYourOwnRepositoryTemplate, generateBuildYourOwnRouteTemplate;
2227
+ var init_buildYourOwnArchitecture_template = __esm({
2228
+ "src/templates/customModule/buildYourOwnArchitecture.template.ts"() {
2211
2229
  "use strict";
2212
2230
  init_cjs_shims();
2213
2231
  init_resolveRoute_constant();
2214
- capitalize17 = (s) => s.charAt(0).toUpperCase() + s.slice(1);
2215
- generateCustomControllerTemplate = (controllerName, moduleName, methods) => {
2216
- const cap = capitalize17(moduleName);
2217
- const serviceName = `${cap}Service`;
2218
- const body = methods.length === 0 ? ` // TODO: add your handler methods here` : methods.map((m) => generateMethod3(m, cap, serviceName)).join("\n");
2219
- const serviceImport = methods.length === 0 ? `` : `import { ${serviceName} } from "./${moduleName}.service";
2220
- `;
2221
- return `import { Request, Response } from "opticore-express";
2222
- import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
2223
- ${serviceImport}
2224
- export class ${controllerName} {${methods.length > 0 ? `
2225
- private static buildService(): ${serviceName} {
2226
- return new ${serviceName}();
2227
- }
2228
- ` : ""}
2229
- ${body}
2230
- private static handleError(error: unknown) {
2231
- const message = error instanceof Error ? error.message : "Internal server error";
2232
- return ResponseHandler.error(message, HttpStatusCode.INTERNAL_SERVER_ERROR);
2233
- }
2234
- }`.trimEnd();
2235
- };
2236
- generateMethod3 = (method, cap, serviceName) => {
2237
- const lower = method.toLowerCase();
2238
- if (lower.includes("findall") || lower.includes("getall")) return methodFindAll(method, cap);
2239
- if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return methodFindById(method, cap);
2240
- if (lower.includes("create") || lower.includes("add")) return methodCreate(method, cap);
2241
- if (lower.includes("update") || lower.includes("edit")) return methodUpdate(method, cap);
2242
- if (lower.includes("delete") || lower.includes("remove")) return methodDelete(method, cap);
2243
- return `
2232
+ capitalize17 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2233
+ generateBuildYourOwnControllerTemplate = (fileName, methods) => {
2234
+ const controllerName = `${capitalize17(fileName)}Controller`;
2235
+ const body = methods.length === 0 ? ` // TODO: add your handler methods here` : methods.map((method) => `
2244
2236
  static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2245
2237
  try {
2246
- const service = ${cap}Controller.buildService();
2247
2238
  // TODO: implement ${method}
2248
2239
  return ResponseHandler.success({}, "success", HttpStatusCode.OK);
2249
2240
  } catch (error) {
2250
- return ${cap}Controller.handleError(error);
2251
- }
2252
- }`;
2253
- };
2254
- methodFindAll = (m, cap) => `
2255
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2256
- try {
2257
- const service = ${cap}Controller.buildService();
2258
- const results = await service.findAll();
2259
- return ResponseHandler.success(results, "success", HttpStatusCode.OK);
2260
- } catch (error) {
2261
- return ${cap}Controller.handleError(error);
2262
- }
2263
- }`;
2264
- methodFindById = (m, cap) => `
2265
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2266
- try {
2267
- const { id } = req.params;
2268
- const service = ${cap}Controller.buildService();
2269
- const result = await service.findById(id);
2270
- if (!result) return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
2271
- return ResponseHandler.success(result, "success", HttpStatusCode.OK);
2272
- } catch (error) {
2273
- return ${cap}Controller.handleError(error);
2241
+ const message = error instanceof Error ? error.message : "Internal server error";
2242
+ return ResponseHandler.error(message, HttpStatusCode.INTERNAL_SERVER_ERROR);
2274
2243
  }
2275
- }`;
2276
- methodCreate = (m, cap) => `
2277
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2278
- try {
2279
- const service = ${cap}Controller.buildService();
2280
- const result = await service.create(req.body);
2281
- return ResponseHandler.success(result, "created", HttpStatusCode.CREATED);
2282
- } catch (error) {
2283
- return ${cap}Controller.handleError(error);
2284
- }
2285
- }`;
2286
- methodUpdate = (m, cap) => `
2287
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2288
- try {
2289
- const { id } = req.params;
2290
- const service = ${cap}Controller.buildService();
2291
- const result = await service.update(id, req.body);
2292
- if (!result) return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
2293
- return ResponseHandler.success(result, "success", HttpStatusCode.OK);
2294
- } catch (error) {
2295
- return ${cap}Controller.handleError(error);
2296
- }
2297
- }`;
2298
- methodDelete = (m, cap) => `
2299
- static async ${m}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2300
- try {
2301
- const { id } = req.params;
2302
- const service = ${cap}Controller.buildService();
2303
- const deleted = await service.delete(id);
2304
- if (!deleted) return ResponseHandler.error(\`Not found: \${id}\`, HttpStatusCode.NOT_FOUND);
2305
- return ResponseHandler.success(null, "deleted", HttpStatusCode.NO_CONTENT);
2306
- } catch (error) {
2307
- return ${cap}Controller.handleError(error);
2308
- }
2309
- }`;
2310
- generateCustomServiceTemplate = (moduleName) => {
2311
- const cap = capitalize17(moduleName);
2312
- return `export class ${cap}Service {
2313
- async findAll(): Promise<unknown[]> {
2314
- // TODO: implement
2315
- return [];
2316
- }
2317
- async findById(id: string): Promise<unknown | null> {
2318
- // TODO: implement
2319
- return null;
2320
- }
2321
- async create(data: Record<string, unknown>): Promise<unknown> {
2322
- // TODO: implement
2323
- return data;
2324
- }
2325
- async update(id: string, data: Record<string, unknown>): Promise<unknown | null> {
2326
- // TODO: implement
2327
- return null;
2328
- }
2329
- async delete(id: string): Promise<boolean> {
2330
- // TODO: implement
2331
- return false;
2332
- }
2333
- }`.trimEnd();
2244
+ }`).join("\n");
2245
+ return `import { Request, Response } from "opticore-express";
2246
+ import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
2247
+
2248
+ export class ${controllerName} {
2249
+ ${body}
2250
+ }`.trimEnd() + "\n";
2251
+ };
2252
+ generateBuildYourOwnServiceClassTemplate = (fileName, methods) => {
2253
+ const serviceName = `${capitalize17(fileName)}Service`;
2254
+ const body = methods.length === 0 ? ` // TODO: add your service methods here` : methods.map((method) => `
2255
+ async ${method}(): Promise<unknown> {
2256
+ // TODO: implement ${method}
2257
+ throw new Error("Not implemented");
2258
+ }`).join("\n");
2259
+ return `export class ${serviceName} {
2260
+ ${body}
2261
+ }`.trimEnd() + "\n";
2262
+ };
2263
+ generateBuildYourOwnServiceFunctionTemplate = (fileName) => {
2264
+ const functionName = `${fileName}Service`;
2265
+ return `export async function ${functionName}(): Promise<unknown> {
2266
+ // TODO: implement ${functionName}
2267
+ throw new Error("Not implemented");
2268
+ }`.trimEnd() + "\n";
2269
+ };
2270
+ generateBuildYourOwnDtoTemplate = (fileName, fields) => {
2271
+ const dtoName = `${capitalize17(fileName)}Dto`;
2272
+ const body = fields.length === 0 ? ` // TODO: define the fields of this DTO` : fields.map((field) => ` ${field.name}: ${field.type};`).join("\n");
2273
+ return `export interface ${dtoName} {
2274
+ ${body}
2275
+ }`.trimEnd() + "\n";
2334
2276
  };
2335
- generateCustomRepositoryTemplate = (moduleName) => {
2336
- const cap = capitalize17(moduleName);
2337
- const name = moduleName.toLowerCase();
2338
- 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");
2339
- if (isAuthRelated) {
2340
- return `export class ${cap}Repository {
2341
- // TODO: inject your data source (ORM, DB client, etc.)
2342
-
2343
- async findByEmail(email: string): Promise<User | null> {
2344
- throw new Error("Not implemented");
2345
- }
2346
-
2347
- async findByUsernameOrEmail(identity: string): Promise<User | null> {
2348
- throw new Error("Not implemented");
2349
- }
2350
-
2351
- async updateLastLogin(userId: string, date: Date): Promise<void> {
2352
- throw new Error("Not implemented");
2353
- }
2354
-
2355
- async incrementLoginAttempts(userId: string): Promise<number> {
2356
- throw new Error("Not implemented");
2357
- }
2358
-
2359
- async resetLoginAttempts(userId: string): Promise<void> {
2360
- throw new Error("Not implemented");
2361
- }
2362
-
2363
- async saveToken(userId: string, token: string): Promise<void> {
2364
- throw new Error("Not implemented");
2365
- }
2366
- }`.trimEnd();
2367
- }
2368
- return `export class ${cap}Repository {
2369
- // TODO: inject your data source (ORM, DB client, etc.)
2370
- async findAll(): Promise<unknown[]> { throw new Error("Not implemented"); }
2371
- async findById(id: string): Promise<unknown | null> { throw new Error("Not implemented"); }
2372
- async create(data: Record<string, unknown>): Promise<unknown> { throw new Error("Not implemented"); }
2373
- async update(id: string, data: Record<string, unknown>): Promise<unknown | null> { throw new Error("Not implemented"); }
2374
- async delete(id: string): Promise<boolean> { throw new Error("Not implemented"); }
2375
- }`.trimEnd();
2376
- };
2377
- generateCustomModelTemplate = (moduleName) => {
2378
- const cap = capitalize17(moduleName);
2379
- return `export class ${cap}Model {
2277
+ generateBuildYourOwnEntityTemplate = (fileName, properties) => {
2278
+ const entityName = `${capitalize17(fileName)}Entity`;
2279
+ const ctorParams = properties.length === 0 ? ` // TODO: define the properties of this entity` : properties.map((prop) => ` public readonly ${prop.name}: ${prop.type},`).join("\n");
2280
+ return `export class ${entityName} {
2380
2281
  constructor(
2381
- public readonly id: string,
2382
- // TODO: add your fields here
2282
+ ${ctorParams}
2383
2283
  ) {}
2384
- }`.trimEnd();
2385
- };
2386
- generateCustomTypesTemplate = (moduleName) => `// ${moduleName} types
2387
- export type ${capitalize17(moduleName)}Id = string;
2388
- // TODO: add your domain types here`.trimEnd();
2389
- generateCustomMiddlewareTemplate = (moduleName) => {
2390
- const cap = capitalize17(moduleName);
2391
- return `import { Request, Response, NextFunction } from "opticore-express";
2392
-
2393
- export function ${moduleName}Middleware(req: Request, res: Response, next: NextFunction): void {
2394
- // TODO: implement ${cap} middleware logic
2395
- next();
2396
- }`.trimEnd();
2397
- };
2398
- generateCustomUtilsTemplate = (moduleName) => `// ${moduleName} utilities
2399
- // TODO: add helper functions here`.trimEnd();
2400
- generateCustomErrorsTemplate = (moduleName) => {
2401
- const cap = capitalize17(moduleName);
2402
- return `export class ${cap}NotFoundError extends Error {
2403
- constructor(id: string) {
2404
- super(\`${cap} not found: \${id}\`);
2405
- this.name = "${cap}NotFoundError";
2406
- }
2407
- }
2408
- export class ${cap}ValidationError extends Error {
2409
- constructor(message: string) {
2410
- super(message);
2411
- this.name = "${cap}ValidationError";
2412
- }
2413
- }`.trimEnd();
2284
+ }`.trimEnd() + "\n";
2414
2285
  };
2415
- generateCustomConstantsTemplate = (moduleName) => `// ${moduleName} constants
2416
- export const ${moduleName.toUpperCase()}_PREFIX = "/${moduleName}";
2417
- // TODO: add your constants here`.trimEnd();
2418
- generateCustomRouterHandlerTemplate = (moduleName, controllerMethods) => {
2419
- const cap = capitalize17(moduleName);
2420
- const handlerName = `${cap}HandlerRouter`;
2421
- const controllerName = `${cap}Controller`;
2422
- const routesCode = (controllerMethods || []).map((method) => {
2423
- const { httpMethod, path: path10 } = CResolveRoute(method, moduleName);
2424
- return `{
2425
- path: \`${path10}\`,
2426
- method: "${httpMethod}",
2286
+ generateBuildYourOwnRepositoryTemplate = (fileName, methods) => {
2287
+ const repositoryName = `${capitalize17(fileName)}Repository`;
2288
+ 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");
2289
+ return `export class ${repositoryName} {
2290
+ // TODO: inject your data source (ORM, DB client, etc.)
2291
+ ${body}
2292
+ }`.trimEnd() + "\n";
2293
+ };
2294
+ generateBuildYourOwnRouteTemplate = (fileName, actions) => {
2295
+ const capitalized = capitalize17(fileName);
2296
+ const handlerName = `${capitalized}HandlerRouter`;
2297
+ const controllerName = `${capitalized}Controller`;
2298
+ const routes = actions.map((action) => {
2299
+ const { httpMethod, path: path10 } = CResolveRoute(action, fileName);
2300
+ return { httpMethod, path: path10, action };
2301
+ });
2302
+ const body = routes.length === 0 ? ` // TODO: define the routes for this module` : routes.map((route) => `{
2303
+ path: "${route.path}",
2304
+ method: "${route.httpMethod}",
2427
2305
  middlewares: [],
2428
- handler: async (ctx: ICustomContext) => await ${controllerName}.${method}(ctx.req, ctx.res)
2429
- }`;
2430
- }).join(",\n");
2306
+ handler: async (ctx: ICustomContext) => await ${controllerName}.${route.action}(ctx.req, ctx.res)
2307
+ }`).join(",\n").replace(/\n/g, "\n ");
2431
2308
  return `import { OpticoreRoutingFactory, ICustomContext, IMultipleRouteDefinition } from "opticore-router";
2432
- import { ${controllerName} } from "../../app/${moduleName}.controller";
2309
+ // TODO: adjust this import if "${controllerName}" lives in a different folder
2310
+ import { ${controllerName} } from "./${fileName}.controller";
2433
2311
 
2434
2312
  export const ${handlerName}: () => IMultipleRouteDefinition = () => {
2435
2313
  return OpticoreRoutingFactory.routes(
2436
2314
  ${controllerName},
2437
2315
  [
2438
- ${routesCode ? routesCode.replace(/\n/g, "\n ") : ""}
2316
+ ${body}
2439
2317
  ]
2440
2318
  );
2441
- };`.trimEnd();
2442
- };
2443
- generateCustomRouterTemplate = (moduleName) => {
2444
- const cap = capitalize17(moduleName);
2445
- const handlerName = `${cap}HandlerRouter`;
2446
- const routerName = `${cap}Router`;
2447
- return `import { ${handlerName} } from "./core/handler/${moduleName}.router.handler";
2448
- import { TFeatureRoutes } from "opticore-router";
2449
-
2450
- export const ${routerName}: TFeatureRoutes = {
2451
- routes: [
2452
- {
2453
- path: ${handlerName}().path,
2454
- handler: ${handlerName}().handler
2455
- }
2456
- ]
2457
- };`.trimEnd();
2319
+ };`.trimEnd() + "\n";
2458
2320
  };
2459
2321
  }
2460
2322
  });
2461
2323
 
2462
- // src/templates/customModule/customModuleScaffold.template.ts
2463
- async function askFile(label) {
2464
- const answer = await UPrompt.confirm(`Create ${label}?`, false);
2465
- return answer === true;
2466
- }
2467
- async function askMethods() {
2468
- const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
2469
- if (!wantsMethods) return [];
2470
- const raw = await UPrompt.text(
2471
- "Enter the method names (comma separated):",
2472
- "create, findAll, findById, update, delete",
2473
- (v) => v ? void 0 : "Enter at least one method name."
2324
+ // src/templates/customModule/buildYourOwnArchitectureScaffold.template.ts
2325
+ async function handleFileCreation(dirPath) {
2326
+ const fileType = await UPrompt.select(
2327
+ "What type of file do you want to create?",
2328
+ ["controller"],
2329
+ [
2330
+ { label: "Controller", value: ["controller"] },
2331
+ { label: "Service", value: ["service"] },
2332
+ { label: "DTO", value: ["dto"] },
2333
+ { label: "Entity", value: ["entity"] },
2334
+ { label: "Repository", value: ["repository"] },
2335
+ { label: "Route", value: ["route"] }
2336
+ ]
2474
2337
  );
2475
- if ((0, import_prompts5.isCancel)(raw)) return [];
2476
- return raw.split(",").map((m) => m.trim()).filter(Boolean);
2338
+ if ((0, import_prompts6.isCancel)(fileType)) return void 0;
2339
+ const baseName = await askName(`Enter the name of this ${fileType} (without extension):`, "user");
2340
+ if (!baseName) return void 0;
2341
+ let fileName;
2342
+ let content;
2343
+ switch (fileType) {
2344
+ case "controller": {
2345
+ const wantsMethods = await UPrompt.confirm("Do you want to create methods for this controller?");
2346
+ let methods = [];
2347
+ if (wantsMethods === true) {
2348
+ methods = await askCommaSeparatedList(
2349
+ "Enter the method names (comma separated):",
2350
+ "create, findAll, findById, update, delete"
2351
+ );
2352
+ }
2353
+ fileName = `${baseName}.controller.ts`;
2354
+ content = generateBuildYourOwnControllerTemplate(baseName, methods);
2355
+ break;
2356
+ }
2357
+ case "service": {
2358
+ const kind = await UPrompt.select(
2359
+ "Do you want a class with methods, or a service that is just a function?",
2360
+ ["class"],
2361
+ [
2362
+ { label: "Class with methods", value: ["class"] },
2363
+ { label: "Single function", value: ["function"] }
2364
+ ]
2365
+ );
2366
+ if ((0, import_prompts6.isCancel)(kind)) return void 0;
2367
+ fileName = `${baseName}.service.ts`;
2368
+ if (kind === "class") {
2369
+ const methods = await askCommaSeparatedList(
2370
+ "Enter the method names (comma separated):",
2371
+ "findAll, findById, create, update, delete"
2372
+ );
2373
+ content = generateBuildYourOwnServiceClassTemplate(baseName, methods);
2374
+ } else {
2375
+ content = generateBuildYourOwnServiceFunctionTemplate(baseName);
2376
+ }
2377
+ break;
2378
+ }
2379
+ case "dto": {
2380
+ const raw = await askCommaSeparatedList(
2381
+ "Enter the DTO fields as name:type pairs, comma separated:",
2382
+ "name:string, email:string"
2383
+ );
2384
+ fileName = `${baseName}.dto.ts`;
2385
+ content = generateBuildYourOwnDtoTemplate(baseName, parseFieldDefinitions(raw));
2386
+ break;
2387
+ }
2388
+ case "entity": {
2389
+ const raw = await askCommaSeparatedList(
2390
+ "Enter the entity properties as name:type pairs, comma separated:",
2391
+ "id:string, name:string, createdAt:Date"
2392
+ );
2393
+ fileName = `${baseName}.entity.ts`;
2394
+ content = generateBuildYourOwnEntityTemplate(baseName, parseFieldDefinitions(raw));
2395
+ break;
2396
+ }
2397
+ case "repository": {
2398
+ const methods = await askCommaSeparatedList(
2399
+ "Enter the actions this repository should perform (comma separated):",
2400
+ "findAll, findById, save, update, delete"
2401
+ );
2402
+ fileName = `${baseName}.repository.ts`;
2403
+ content = generateBuildYourOwnRepositoryTemplate(baseName, methods);
2404
+ break;
2405
+ }
2406
+ case "route": {
2407
+ const actions = await askCommaSeparatedList(
2408
+ "Enter the actions to expose as routes (comma separated):",
2409
+ "findAll, findById, create, update, delete"
2410
+ );
2411
+ fileName = `${baseName}.route.ts`;
2412
+ content = generateBuildYourOwnRouteTemplate(baseName, actions);
2413
+ break;
2414
+ }
2415
+ }
2416
+ const filePath = import_path6.default.join(dirPath, fileName);
2417
+ UFsModule.createFile(filePath, content);
2418
+ ok(fileName);
2419
+ return { name: fileName, type: "file" };
2477
2420
  }
2478
- var import_path6, import_fs3, import_ansi_colors9, import_prompts5, ok, tip, capitalize18, customModuleScaffoldTemplate;
2479
- var init_customModuleScaffold_template = __esm({
2480
- "src/templates/customModule/customModuleScaffold.template.ts"() {
2421
+ async function handleDirectory(dirPath, node) {
2422
+ let keepGoing = true;
2423
+ while (keepGoing) {
2424
+ const choice = await UPrompt.select(
2425
+ `Inside "${node.name}", do you want to create a file or a folder?`,
2426
+ ["file"],
2427
+ [
2428
+ { label: "File", value: ["file"] },
2429
+ { label: "Folder", value: ["folder"] }
2430
+ ]
2431
+ );
2432
+ if ((0, import_prompts6.isCancel)(choice)) return;
2433
+ if (choice === "folder") {
2434
+ const folderName = await askName("Enter the folder name:", "core");
2435
+ if (!folderName) return;
2436
+ const subDir = import_path6.default.join(dirPath, folderName);
2437
+ UFsModule.createDirectoryRecursively(subDir);
2438
+ const subNode = { name: folderName, type: "dir", children: [] };
2439
+ node.children.push(subNode);
2440
+ ok(`${folderName}/`);
2441
+ await handleDirectory(subDir, subNode);
2442
+ } else {
2443
+ const fileNode = await handleFileCreation(dirPath);
2444
+ if (fileNode) {
2445
+ node.children.push(fileNode);
2446
+ }
2447
+ }
2448
+ info(`Current structure of "${node.name}":`);
2449
+ printTree(node);
2450
+ const wantsContinue = await UPrompt.confirm(`Continue creating files/folders inside "${node.name}"?`);
2451
+ if ((0, import_prompts6.isCancel)(wantsContinue) || wantsContinue !== true) {
2452
+ keepGoing = false;
2453
+ }
2454
+ }
2455
+ }
2456
+ var import_path6, import_fs3, import_ansi_colors9, import_prompts6, ok, info, NAME_PATTERN, askName, askCommaSeparatedList, parseFieldDefinitions, renderTree, printTree, buildYourOwnArchitectureScaffoldTemplate;
2457
+ var init_buildYourOwnArchitectureScaffold_template = __esm({
2458
+ "src/templates/customModule/buildYourOwnArchitectureScaffold.template.ts"() {
2481
2459
  "use strict";
2482
2460
  init_cjs_shims();
2483
2461
  import_path6 = __toESM(require("path"), 1);
2484
2462
  import_fs3 = __toESM(require("fs"), 1);
2485
2463
  import_ansi_colors9 = __toESM(require("ansi-colors"), 1);
2486
- import_prompts5 = require("@clack/prompts");
2464
+ import_prompts6 = require("@clack/prompts");
2487
2465
  init_fsModule_utils();
2488
2466
  init_prompt_utils();
2489
- init_featureName_service();
2490
- init_customModule_template();
2491
- init_featureComponentGenerator_utils();
2467
+ init_buildYourOwnArchitecture_template();
2492
2468
  ok = (msg) => {
2493
- console.log(import_ansi_colors9.default.green(`\u2705 ${msg}`));
2469
+ console.log(import_ansi_colors9.default.green(`\u2714 ${msg}`));
2494
2470
  };
2495
- tip = (msg) => {
2496
- console.log(import_ansi_colors9.default.yellow(` ${msg}`));
2471
+ info = (msg) => {
2472
+ console.log(import_ansi_colors9.default.cyan(`\u2139 ${msg}`));
2497
2473
  };
2498
- capitalize18 = (s) => s.charAt(0).toUpperCase() + s.slice(1);
2499
- customModuleScaffoldTemplate = async () => {
2500
- const rawName = await _featureName();
2501
- if ((0, import_prompts5.isCancel)(rawName)) {
2502
- console.log(import_ansi_colors9.default.bgRed(import_ansi_colors9.default.white("Operation cancelled.")));
2503
- process.exit(0);
2504
- }
2505
- const moduleName = rawName.toString();
2506
- const moduleDir = import_path6.default.join(process.cwd(), "src", "features", moduleName);
2507
- if (import_fs3.default.existsSync(moduleDir)) {
2508
- console.log(import_ansi_colors9.default.bgCyan(import_ansi_colors9.default.white(`Module "${moduleName}" already exists.`)));
2509
- process.exit(0);
2510
- }
2511
- const appDir = import_path6.default.join(moduleDir, "app");
2512
- const coreMiddlewaresDir = import_path6.default.join(moduleDir, "core", "middlewares");
2513
- const coreHandlerDir = import_path6.default.join(moduleDir, "core", "handler");
2514
- const sharedUtilsDir = import_path6.default.join(moduleDir, "shared", "utils");
2515
- const sharedErrorsDir = import_path6.default.join(moduleDir, "shared", "errors");
2516
- const sharedConstantsDir = import_path6.default.join(moduleDir, "shared", "constants");
2517
- UFsModule.createDirectoryRecursively(appDir);
2518
- UFsModule.createDirectoryRecursively(coreHandlerDir);
2519
- UFsModule.createDirectoryRecursively(sharedUtilsDir);
2520
- UFsModule.createDirectoryRecursively(sharedErrorsDir);
2521
- UFsModule.createDirectoryRecursively(sharedConstantsDir);
2522
- let controllerMethods = [];
2523
- if (await askFile(`${moduleName}.controller.ts`)) {
2524
- controllerMethods = await askMethods();
2525
- UFsModule.createFile(
2526
- import_path6.default.join(appDir, `${moduleName}.controller.ts`),
2527
- generateCustomControllerTemplate(`${capitalize18(moduleName)}Controller`, moduleName, controllerMethods)
2528
- );
2529
- ok(`app/${moduleName}.controller.ts`);
2530
- }
2531
- if (await askFile(`${moduleName}.service.ts`)) {
2532
- UFsModule.createFile(import_path6.default.join(appDir, `${moduleName}.service.ts`), generateCustomServiceTemplate(moduleName));
2533
- ok(`app/${moduleName}.service.ts`);
2534
- }
2535
- if (await askFile(`${moduleName}.repository.ts`)) {
2536
- UFsModule.createFile(import_path6.default.join(appDir, `${moduleName}.repository.ts`), generateCustomRepositoryTemplate(moduleName));
2537
- ok(`app/${moduleName}.repository.ts`);
2538
- }
2539
- if (await askFile(`${moduleName}.model.ts`)) {
2540
- UFsModule.createFile(import_path6.default.join(appDir, `${moduleName}.model.ts`), generateCustomModelTemplate(moduleName));
2541
- ok(`app/${moduleName}.model.ts`);
2542
- }
2543
- if (await askFile(`${moduleName}.types.ts`)) {
2544
- UFsModule.createFile(import_path6.default.join(appDir, `${moduleName}.types.ts`), generateCustomTypesTemplate(moduleName));
2545
- ok(`app/${moduleName}.types.ts`);
2546
- }
2547
- const wantsMiddleware = await UPrompt.confirm("Does your module need a middleware?", false);
2548
- if (wantsMiddleware === true) {
2549
- UFsModule.createDirectoryRecursively(coreMiddlewaresDir);
2550
- UFsModule.createFile(
2551
- import_path6.default.join(coreMiddlewaresDir, `${moduleName}.middleware.ts`),
2552
- generateCustomMiddlewareTemplate(moduleName)
2474
+ NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
2475
+ askName = async (message, placeholder) => {
2476
+ const raw = await UPrompt.text(message, placeholder, (value) => {
2477
+ if (!value) {
2478
+ return "Please enter a name.";
2479
+ }
2480
+ if (!NAME_PATTERN.test(value)) {
2481
+ return "Use letters, numbers, - or _, starting with a letter.";
2482
+ }
2483
+ });
2484
+ if ((0, import_prompts6.isCancel)(raw)) {
2485
+ return void 0;
2486
+ }
2487
+ return raw;
2488
+ };
2489
+ askCommaSeparatedList = async (message, placeholder) => {
2490
+ const raw = await UPrompt.text(message, placeholder, () => void 0);
2491
+ if ((0, import_prompts6.isCancel)(raw) || !raw) return [];
2492
+ return raw.split(",").map((v) => v.trim()).filter(Boolean);
2493
+ };
2494
+ parseFieldDefinitions = (raw) => raw.map((entry) => {
2495
+ const [name, type] = entry.split(":").map((v) => v.trim());
2496
+ return { name: name || entry, type: type || "string" };
2497
+ });
2498
+ renderTree = (node, prefix = "") => {
2499
+ const lines = [];
2500
+ const children = node.children ?? [];
2501
+ children.forEach((child, index) => {
2502
+ const isLast = index === children.length - 1;
2503
+ const branch = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
2504
+ lines.push(`${prefix}${branch}${child.name}${child.type === "dir" ? "/" : ""}`);
2505
+ if (child.type === "dir") {
2506
+ const nextPrefix = prefix + (isLast ? " " : "\u2502 ");
2507
+ lines.push(...renderTree(child, nextPrefix));
2508
+ }
2509
+ });
2510
+ return lines;
2511
+ };
2512
+ printTree = (root) => {
2513
+ console.log(import_ansi_colors9.default.yellow(`${root.name}/`));
2514
+ renderTree(root).forEach((line) => console.log(import_ansi_colors9.default.yellow(line)));
2515
+ };
2516
+ buildYourOwnArchitectureScaffoldTemplate = async () => {
2517
+ const featuresDir = import_path6.default.join(process.cwd(), "src", "features");
2518
+ const forest = [];
2519
+ let creatingNewRoot = true;
2520
+ while (creatingNewRoot) {
2521
+ const rootName = await askName("Enter the name of the root folder for your architecture:", "myArchitecture");
2522
+ if (!rootName) {
2523
+ console.log(import_ansi_colors9.default.bgRed(import_ansi_colors9.default.white("Operation cancelled.")));
2524
+ process.exit(0);
2525
+ }
2526
+ const rootDir = import_path6.default.join(featuresDir, rootName);
2527
+ if (import_fs3.default.existsSync(rootDir)) {
2528
+ info(`Folder "${rootName}" already exists, new files/folders will be added inside it.`);
2529
+ }
2530
+ UFsModule.createDirectoryRecursively(rootDir);
2531
+ const rootNode = { name: rootName, type: "dir", children: [] };
2532
+ forest.push(rootNode);
2533
+ await handleDirectory(rootDir, rootNode);
2534
+ const wantsNewRoot = await UPrompt.confirm(
2535
+ "Do you want to create a new folder at the root of your architecture?",
2536
+ false
2553
2537
  );
2554
- ok(`core/middlewares/${moduleName}.middleware.ts`);
2538
+ if ((0, import_prompts6.isCancel)(wantsNewRoot) || wantsNewRoot !== true) {
2539
+ console.log(import_ansi_colors9.default.cyan("En disant non, ce sera la fin de la cr\xE9ation de votre propre architecture."));
2540
+ creatingNewRoot = false;
2541
+ }
2555
2542
  }
2556
- UFsModule.createFile(
2557
- import_path6.default.join(coreHandlerDir, `${moduleName}.router.handler.ts`),
2558
- generateCustomRouterHandlerTemplate(moduleName, controllerMethods)
2559
- );
2560
- ok(`core/handler/${moduleName}.router.handler.ts`);
2561
- UFsModule.createFile(import_path6.default.join(sharedUtilsDir, `${moduleName}.utils.ts`), generateCustomUtilsTemplate(moduleName));
2562
- UFsModule.createFile(import_path6.default.join(sharedErrorsDir, `${moduleName}.errors.ts`), generateCustomErrorsTemplate(moduleName));
2563
- UFsModule.createFile(import_path6.default.join(sharedConstantsDir, `${moduleName}.constants.ts`), generateCustomConstantsTemplate(moduleName));
2564
- ok(`shared/utils/${moduleName}.utils.ts`);
2565
- ok(`shared/errors/${moduleName}.errors.ts`);
2566
- ok(`shared/constants/${moduleName}.constants.ts`);
2567
- UFsModule.createFile(import_path6.default.join(moduleDir, `${moduleName}.router.ts`), generateCustomRouterTemplate(moduleName));
2568
- ok(`${moduleName}.router.ts`);
2569
- FeatureComponentGeneratorUtils.setStructure("custom");
2570
- await FeatureComponentGeneratorUtils.registerModuleRouter(moduleName);
2571
- tip(`src/features/${moduleName}/`);
2572
- tip(`\u251C\u2500\u2500 app/`);
2573
- tip(`\u251C\u2500\u2500 core/`);
2574
- tip(`\u2502 \u251C\u2500\u2500 middlewares/`);
2575
- tip(`\u2502 \u2514\u2500\u2500 handler/`);
2576
- tip(`\u251C\u2500\u2500 shared/`);
2577
- tip(`\u2502 \u251C\u2500\u2500 utils/`);
2578
- tip(`\u2502 \u251C\u2500\u2500 errors/`);
2579
- tip(`\u2502 \u2514\u2500\u2500 constants/`);
2580
- tip(`\u2514\u2500\u2500 ${moduleName}.router.ts`);
2581
2543
  console.log(`
2582
- ${import_ansi_colors9.default.bgGreen(import_ansi_colors9.default.white(`
2583
- \u{1F389} Custom module "${moduleName}" scaffolded successfully!
2584
- `))}`);
2544
+ ${import_ansi_colors9.default.bgGreen(import_ansi_colors9.default.white("\n\u{1F389} Your custom architecture has been created!\n"))}`);
2545
+ forest.forEach((root) => printTree(root));
2585
2546
  };
2586
2547
  }
2587
2548
  });
2588
2549
 
2589
2550
  // src/templates/mvcModule/mvcModule.template.ts
2590
- var capitalize19, generateMvcModelTemplate, generateMvcViewTemplate, generateMvcControllerTemplate, generateMethod4, generateFindAllMethod3, generateFindByIdMethod3, generateCreateMethod3, generateUpdateMethod3, generateDeleteMethod3, generateMvcRouterHandlerTemplate, generateMvcRouterTemplate, resolveRoute3;
2551
+ var capitalize18, generateMvcModelTemplate, generateMvcViewTemplate, generateMvcControllerTemplate, generateMethod3, generateFindAllMethod3, generateFindByIdMethod3, generateCreateMethod3, generateUpdateMethod3, generateDeleteMethod3, generateMvcRouterHandlerTemplate, generateMvcRouterTemplate, resolveRoute3;
2591
2552
  var init_mvcModule_template = __esm({
2592
2553
  "src/templates/mvcModule/mvcModule.template.ts"() {
2593
2554
  "use strict";
2594
2555
  init_cjs_shims();
2595
- capitalize19 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2556
+ capitalize18 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2596
2557
  generateMvcModelTemplate = (featureName) => {
2597
- const capitalized = capitalize19(featureName);
2558
+ const capitalized = capitalize18(featureName);
2598
2559
  const modelName = `${capitalized}Model`;
2599
2560
  return `/**
2600
2561
  * ${modelName} \u2014 Model
@@ -2652,7 +2613,7 @@ export class ${modelName} {
2652
2613
  `;
2653
2614
  };
2654
2615
  generateMvcViewTemplate = (featureName) => {
2655
- const capitalized = capitalize19(featureName);
2616
+ const capitalized = capitalize18(featureName);
2656
2617
  const modelName = `${capitalized}Model`;
2657
2618
  const viewName = `${capitalized}View`;
2658
2619
  return `import { ${modelName} } from "../models/${featureName}.model";
@@ -2678,10 +2639,10 @@ export class ${viewName} {
2678
2639
  `;
2679
2640
  };
2680
2641
  generateMvcControllerTemplate = (controllerName, featureName, methods) => {
2681
- const capitalized = capitalize19(featureName);
2642
+ const capitalized = capitalize18(featureName);
2682
2643
  const modelName = `${capitalized}Model`;
2683
2644
  const viewName = `${capitalized}View`;
2684
- const methodsCode = methods.map((method) => generateMethod4(method, capitalized, modelName, viewName)).join("\n");
2645
+ const methodsCode = methods.map((method) => generateMethod3(method, capitalized, modelName, viewName)).join("\n");
2685
2646
  return `import { Request, Response } from "opticore-express";
2686
2647
  import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
2687
2648
  import { ${modelName} } from "../models/${featureName}.model";
@@ -2696,13 +2657,23 @@ ${methodsCode}
2696
2657
  }
2697
2658
  `;
2698
2659
  };
2699
- generateMethod4 = (method, capitalized, modelName, viewName) => {
2660
+ generateMethod3 = (method, capitalized, modelName, viewName) => {
2700
2661
  const lower = method.toLowerCase();
2701
- if (lower.includes("findall") || lower.includes("getall")) return generateFindAllMethod3(method, capitalized, modelName, viewName);
2702
- if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return generateFindByIdMethod3(method, capitalized, modelName, viewName);
2703
- if (lower.includes("create") || lower.includes("add")) return generateCreateMethod3(method, capitalized, modelName, viewName);
2704
- if (lower.includes("update") || lower.includes("edit")) return generateUpdateMethod3(method, capitalized, modelName, viewName);
2705
- if (lower.includes("delete") || lower.includes("remove")) return generateDeleteMethod3(method, capitalized, modelName);
2662
+ if (lower.includes("findall") || lower.includes("getall")) {
2663
+ return generateFindAllMethod3(method, capitalized, modelName, viewName);
2664
+ }
2665
+ if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) {
2666
+ return generateFindByIdMethod3(method, capitalized, modelName, viewName);
2667
+ }
2668
+ if (lower.includes("create") || lower.includes("add")) {
2669
+ return generateCreateMethod3(method, capitalized, modelName, viewName);
2670
+ }
2671
+ if (lower.includes("update") || lower.includes("edit")) {
2672
+ return generateUpdateMethod3(method, capitalized, modelName, viewName);
2673
+ }
2674
+ if (lower.includes("delete") || lower.includes("remove")) {
2675
+ return generateDeleteMethod3(method, capitalized, modelName);
2676
+ }
2706
2677
  return `
2707
2678
  static async ${method}(req: Request, res: Response): Promise<IResponseHandlerSuccessData | ReturnType<typeof ResponseHandler.error>> {
2708
2679
  try {
@@ -2777,7 +2748,7 @@ ${methodsCode}
2777
2748
  }
2778
2749
  `;
2779
2750
  generateMvcRouterHandlerTemplate = (featureName, controllerMethods) => {
2780
- const capitalized = capitalize19(featureName);
2751
+ const capitalized = capitalize18(featureName);
2781
2752
  const handlerName = `${capitalized}HandlerRouter`;
2782
2753
  const controllerName = `${capitalized}Controller`;
2783
2754
  const routesCode = (controllerMethods || []).map((method) => {
@@ -2803,7 +2774,7 @@ export const ${handlerName}: () => IMultipleRouteDefinition = () => {
2803
2774
  `;
2804
2775
  };
2805
2776
  generateMvcRouterTemplate = (featureName) => {
2806
- const capitalized = capitalize19(featureName);
2777
+ const capitalized = capitalize18(featureName);
2807
2778
  const handlerName = `${capitalized}HandlerRouter`;
2808
2779
  const routerName = `${capitalized}Router`;
2809
2780
  return `import { ${handlerName} } from "./${featureName}.router.handler";
@@ -2821,30 +2792,40 @@ export const ${routerName}: TFeatureRoutes = {
2821
2792
  };
2822
2793
  resolveRoute3 = (methodName, featureName) => {
2823
2794
  const lower = methodName.toLowerCase();
2824
- if (lower.includes("findall") || lower.includes("getall")) return { httpMethod: "get", path: `/${featureName}` };
2825
- if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return { httpMethod: "get", path: `/${featureName}/:id` };
2826
- if (lower.includes("create") || lower.includes("add")) return { httpMethod: "post", path: `/${featureName}` };
2827
- if (lower.includes("update") || lower.includes("edit")) return { httpMethod: "put", path: `/${featureName}/:id` };
2828
- if (lower.includes("delete") || lower.includes("remove")) return { httpMethod: "delete", path: `/${featureName}/:id` };
2795
+ if (lower.includes("findall") || lower.includes("getall")) {
2796
+ return { httpMethod: "get", path: `/${featureName}` };
2797
+ }
2798
+ if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) {
2799
+ return { httpMethod: "get", path: `/${featureName}/:id` };
2800
+ }
2801
+ if (lower.includes("create") || lower.includes("add")) {
2802
+ return { httpMethod: "post", path: `/${featureName}` };
2803
+ }
2804
+ if (lower.includes("update") || lower.includes("edit")) {
2805
+ return { httpMethod: "put", path: `/${featureName}/:id` };
2806
+ }
2807
+ if (lower.includes("delete") || lower.includes("remove")) {
2808
+ return { httpMethod: "delete", path: `/${featureName}/:id` };
2809
+ }
2829
2810
  return { httpMethod: "get", path: `/${featureName}/${lower}` };
2830
2811
  };
2831
2812
  }
2832
2813
  });
2833
2814
 
2834
2815
  // src/templates/mvcModule/mvcModuleScaffold.template.ts
2835
- var import_path7, import_ansi_colors10, import_prompts6, capitalize20, mvcModuleTemplate;
2816
+ var import_path7, import_ansi_colors10, import_prompts7, capitalize19, mvcModuleTemplate;
2836
2817
  var init_mvcModuleScaffold_template = __esm({
2837
2818
  "src/templates/mvcModule/mvcModuleScaffold.template.ts"() {
2838
2819
  "use strict";
2839
2820
  init_cjs_shims();
2840
2821
  import_path7 = __toESM(require("path"), 1);
2841
2822
  import_ansi_colors10 = __toESM(require("ansi-colors"), 1);
2842
- import_prompts6 = require("@clack/prompts");
2823
+ import_prompts7 = require("@clack/prompts");
2843
2824
  init_prompt_utils();
2844
2825
  init_fsModule_utils();
2845
2826
  init_featureComponentGenerator_utils();
2846
2827
  init_mvcModule_template();
2847
- capitalize20 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2828
+ capitalize19 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2848
2829
  mvcModuleTemplate = async (featureName) => {
2849
2830
  FeatureComponentGeneratorUtils.setStructure("mvc");
2850
2831
  const basePath = import_path7.default.join("src", "features", featureName);
@@ -2855,21 +2836,23 @@ var init_mvcModuleScaffold_template = __esm({
2855
2836
  routesDir: import_path7.default.join(basePath, "routes")
2856
2837
  };
2857
2838
  Object.values(paths).forEach((dir) => UFsModule.createDirectoryRecursively(dir));
2858
- const controllerName = `${capitalize20(featureName)}Controller`;
2839
+ const controllerName = `${capitalize19(featureName)}Controller`;
2859
2840
  UFsModule.createFile(import_path7.default.join(paths.modelsDir, `${featureName}.model.ts`), generateMvcModelTemplate(featureName));
2860
- console.log(import_ansi_colors10.default.green(`\u2705 Model created: ${import_path7.default.join(paths.modelsDir, `${featureName}.model.ts`)}`));
2841
+ console.log(import_ansi_colors10.default.green(`\u2714 Model created: ${import_path7.default.join(paths.modelsDir, `${featureName}.model.ts`)}`));
2861
2842
  UFsModule.createFile(import_path7.default.join(paths.viewsDir, `${featureName}.view.ts`), generateMvcViewTemplate(featureName));
2862
- console.log(import_ansi_colors10.default.green(`\u2705 View created: ${import_path7.default.join(paths.viewsDir, `${featureName}.view.ts`)}`));
2843
+ console.log(import_ansi_colors10.default.green(`\u2714 View created: ${import_path7.default.join(paths.viewsDir, `${featureName}.view.ts`)}`));
2863
2844
  const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
2864
2845
  let methods = [];
2865
2846
  let controllerContent;
2866
- if (wantsMethods && !(0, import_prompts6.isCancel)(wantsMethods)) {
2847
+ if (wantsMethods && !(0, import_prompts7.isCancel)(wantsMethods)) {
2867
2848
  const methodsText = await UPrompt.text(
2868
2849
  "Enter the method names (comma separated):",
2869
2850
  "create, findAll, findById, update, delete",
2870
2851
  (v) => v ? void 0 : "You must enter at least one method."
2871
2852
  );
2872
- methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
2853
+ if (!(0, import_prompts7.isCancel)(methodsText)) {
2854
+ methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
2855
+ }
2873
2856
  controllerContent = generateMvcControllerTemplate(controllerName, featureName, methods);
2874
2857
  } else {
2875
2858
  controllerContent = `import { Request, Response } from "opticore-express";
@@ -2879,18 +2862,18 @@ export class ${controllerName} {}
2879
2862
  }
2880
2863
  const controllerPath = import_path7.default.join(paths.controllersDir, `${featureName}.controller.ts`);
2881
2864
  UFsModule.createFile(controllerPath, controllerContent);
2882
- console.log(import_ansi_colors10.default.green(`\u2705 Controller created: ${controllerPath}`));
2865
+ console.log(import_ansi_colors10.default.green(`\u2714 Controller created: ${controllerPath}`));
2883
2866
  UFsModule.createFile(
2884
2867
  import_path7.default.join(paths.routesDir, `${featureName}.router.handler.ts`),
2885
2868
  generateMvcRouterHandlerTemplate(featureName, methods)
2886
2869
  );
2887
- console.log(import_ansi_colors10.default.green(`\u2705 Router Handler created: ${import_path7.default.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
2870
+ console.log(import_ansi_colors10.default.green(`\u2714 Router Handler created: ${import_path7.default.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
2888
2871
  UFsModule.createFile(
2889
2872
  import_path7.default.join(paths.routesDir, `${featureName}.router.ts`),
2890
2873
  generateMvcRouterTemplate(featureName)
2891
2874
  );
2892
2875
  await FeatureComponentGeneratorUtils.registerModuleRouter(featureName);
2893
- console.log(import_ansi_colors10.default.green(`\u2705 Router created: ${import_path7.default.join(paths.routesDir, `${featureName}.router.ts`)}`));
2876
+ console.log(import_ansi_colors10.default.green(`\u2714 Router created: ${import_path7.default.join(paths.routesDir, `${featureName}.router.ts`)}`));
2894
2877
  console.log(
2895
2878
  import_ansi_colors10.default.bgGreen(
2896
2879
  import_ansi_colors10.default.white(`
@@ -2903,14 +2886,14 @@ export class ${controllerName} {}
2903
2886
  });
2904
2887
 
2905
2888
  // src/templates/layeredModule/layeredModule.template.ts
2906
- var capitalize21, generateLayeredEntityTemplate, generateLayeredDtoTemplate, generateLayeredRepositoryTemplate, generateLayeredServiceTemplate, generateLayeredControllerTemplate, generateMethod5, generateFindAllMethod4, generateFindByIdMethod4, generateCreateMethod4, generateUpdateMethod4, generateDeleteMethod4, generateLayeredRouterHandlerTemplate, generateLayeredRouterTemplate, resolveRoute4;
2889
+ var capitalize20, generateLayeredEntityTemplate, generateLayeredDtoTemplate, generateLayeredRepositoryTemplate, generateLayeredServiceTemplate, generateLayeredControllerTemplate, generateMethod4, generateFindAllMethod4, generateFindByIdMethod4, generateCreateMethod4, generateUpdateMethod4, generateDeleteMethod4, generateLayeredRouterHandlerTemplate, generateLayeredRouterTemplate, resolveRoute4;
2907
2890
  var init_layeredModule_template = __esm({
2908
2891
  "src/templates/layeredModule/layeredModule.template.ts"() {
2909
2892
  "use strict";
2910
2893
  init_cjs_shims();
2911
- capitalize21 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2894
+ capitalize20 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
2912
2895
  generateLayeredEntityTemplate = (featureName) => {
2913
- const capitalized = capitalize21(featureName);
2896
+ const capitalized = capitalize20(featureName);
2914
2897
  const entityName = `${capitalized}Entity`;
2915
2898
  return `/**
2916
2899
  * ${entityName} \u2014 Entity
@@ -2927,7 +2910,7 @@ export class ${entityName} {
2927
2910
  `;
2928
2911
  };
2929
2912
  generateLayeredDtoTemplate = (featureName) => {
2930
- const capitalized = capitalize21(featureName);
2913
+ const capitalized = capitalize20(featureName);
2931
2914
  const entityName = `${capitalized}Entity`;
2932
2915
  return `import { ${entityName} } from "../entities/${featureName}.entity";
2933
2916
 
@@ -2954,7 +2937,7 @@ export const to${capitalized}ResponseDto = (entity: ${entityName}): ${capitalize
2954
2937
  `;
2955
2938
  };
2956
2939
  generateLayeredRepositoryTemplate = (featureName) => {
2957
- const capitalized = capitalize21(featureName);
2940
+ const capitalized = capitalize20(featureName);
2958
2941
  const entityName = `${capitalized}Entity`;
2959
2942
  const repoName = `${capitalized}Repository`;
2960
2943
  return `import { ${entityName} } from "../entities/${featureName}.entity";
@@ -2993,7 +2976,7 @@ export class ${repoName} {
2993
2976
  `;
2994
2977
  };
2995
2978
  generateLayeredServiceTemplate = (featureName) => {
2996
- const capitalized = capitalize21(featureName);
2979
+ const capitalized = capitalize20(featureName);
2997
2980
  const entityName = `${capitalized}Entity`;
2998
2981
  const repoName = `${capitalized}Repository`;
2999
2982
  const serviceName = `${capitalized}Service`;
@@ -3042,9 +3025,9 @@ export class ${serviceName} {
3042
3025
  `;
3043
3026
  };
3044
3027
  generateLayeredControllerTemplate = (controllerName, featureName, methods) => {
3045
- const capitalized = capitalize21(featureName);
3028
+ const capitalized = capitalize20(featureName);
3046
3029
  const serviceName = `${capitalized}Service`;
3047
- const methodsCode = methods.map((method) => generateMethod5(method, capitalized, serviceName)).join("\n");
3030
+ const methodsCode = methods.map((method) => generateMethod4(method, capitalized, serviceName)).join("\n");
3048
3031
  return `import { Request, Response } from "opticore-express";
3049
3032
  import { ResponseHandler, HttpStatusCode, IResponseHandlerSuccessData } from "opticore-http-response";
3050
3033
  import { ${serviceName} } from "../services/${featureName}.service";
@@ -3062,7 +3045,7 @@ ${methodsCode}
3062
3045
  }
3063
3046
  `;
3064
3047
  };
3065
- generateMethod5 = (method, capitalized, serviceName) => {
3048
+ generateMethod4 = (method, capitalized, serviceName) => {
3066
3049
  const lower = method.toLowerCase();
3067
3050
  if (lower.includes("findall") || lower.includes("getall")) return generateFindAllMethod4(method, capitalized);
3068
3051
  if (lower.includes("findbyid") || lower.includes("getbyid") || lower.includes("getone")) return generateFindByIdMethod4(method, capitalized);
@@ -3149,7 +3132,7 @@ ${methodsCode}
3149
3132
  }
3150
3133
  `;
3151
3134
  generateLayeredRouterHandlerTemplate = (featureName, controllerMethods) => {
3152
- const capitalized = capitalize21(featureName);
3135
+ const capitalized = capitalize20(featureName);
3153
3136
  const handlerName = `${capitalized}HandlerRouter`;
3154
3137
  const controllerName = `${capitalized}Controller`;
3155
3138
  const routesCode = (controllerMethods || []).map((method) => {
@@ -3175,7 +3158,7 @@ export const ${handlerName}: () => IMultipleRouteDefinition = () => {
3175
3158
  `;
3176
3159
  };
3177
3160
  generateLayeredRouterTemplate = (featureName) => {
3178
- const capitalized = capitalize21(featureName);
3161
+ const capitalized = capitalize20(featureName);
3179
3162
  const handlerName = `${capitalized}HandlerRouter`;
3180
3163
  const routerName = `${capitalized}Router`;
3181
3164
  return `import { ${handlerName} } from "./${featureName}.router.handler";
@@ -3204,19 +3187,19 @@ export const ${routerName}: TFeatureRoutes = {
3204
3187
  });
3205
3188
 
3206
3189
  // src/templates/layeredModule/layeredModuleScaffold.template.ts
3207
- var import_path8, import_ansi_colors11, import_prompts7, capitalize22, layeredModuleTemplate;
3190
+ var import_path8, import_ansi_colors11, import_prompts8, capitalize21, layeredModuleTemplate;
3208
3191
  var init_layeredModuleScaffold_template = __esm({
3209
3192
  "src/templates/layeredModule/layeredModuleScaffold.template.ts"() {
3210
3193
  "use strict";
3211
3194
  init_cjs_shims();
3212
3195
  import_path8 = __toESM(require("path"), 1);
3213
3196
  import_ansi_colors11 = __toESM(require("ansi-colors"), 1);
3214
- import_prompts7 = require("@clack/prompts");
3197
+ import_prompts8 = require("@clack/prompts");
3215
3198
  init_prompt_utils();
3216
3199
  init_fsModule_utils();
3217
3200
  init_featureComponentGenerator_utils();
3218
3201
  init_layeredModule_template();
3219
- capitalize22 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
3202
+ capitalize21 = (str) => str.charAt(0).toUpperCase() + str.slice(1);
3220
3203
  layeredModuleTemplate = async (featureName) => {
3221
3204
  FeatureComponentGeneratorUtils.setStructure("layered");
3222
3205
  const basePath = import_path8.default.join("src", "features", featureName);
@@ -3229,25 +3212,27 @@ var init_layeredModuleScaffold_template = __esm({
3229
3212
  routesDir: import_path8.default.join(basePath, "routes")
3230
3213
  };
3231
3214
  Object.values(paths).forEach((dir) => UFsModule.createDirectoryRecursively(dir));
3232
- const controllerName = `${capitalize22(featureName)}Controller`;
3215
+ const controllerName = `${capitalize21(featureName)}Controller`;
3233
3216
  UFsModule.createFile(import_path8.default.join(paths.entitiesDir, `${featureName}.entity.ts`), generateLayeredEntityTemplate(featureName));
3234
- console.log(import_ansi_colors11.default.green(`\u2705 Entity created: ${import_path8.default.join(paths.entitiesDir, `${featureName}.entity.ts`)}`));
3217
+ console.log(import_ansi_colors11.default.green(`\u2714 Entity created: ${import_path8.default.join(paths.entitiesDir, `${featureName}.entity.ts`)}`));
3235
3218
  UFsModule.createFile(import_path8.default.join(paths.dtoDir, `${featureName}.dto.ts`), generateLayeredDtoTemplate(featureName));
3236
- console.log(import_ansi_colors11.default.green(`\u2705 DTO created: ${import_path8.default.join(paths.dtoDir, `${featureName}.dto.ts`)}`));
3219
+ console.log(import_ansi_colors11.default.green(`\u2714 DTO created: ${import_path8.default.join(paths.dtoDir, `${featureName}.dto.ts`)}`));
3237
3220
  UFsModule.createFile(import_path8.default.join(paths.repositoriesDir, `${featureName}.repository.ts`), generateLayeredRepositoryTemplate(featureName));
3238
- console.log(import_ansi_colors11.default.green(`\u2705 Repository created: ${import_path8.default.join(paths.repositoriesDir, `${featureName}.repository.ts`)}`));
3221
+ console.log(import_ansi_colors11.default.green(`\u2714 Repository created: ${import_path8.default.join(paths.repositoriesDir, `${featureName}.repository.ts`)}`));
3239
3222
  UFsModule.createFile(import_path8.default.join(paths.servicesDir, `${featureName}.service.ts`), generateLayeredServiceTemplate(featureName));
3240
- console.log(import_ansi_colors11.default.green(`\u2705 Service created: ${import_path8.default.join(paths.servicesDir, `${featureName}.service.ts`)}`));
3223
+ console.log(import_ansi_colors11.default.green(`\u2714 Service created: ${import_path8.default.join(paths.servicesDir, `${featureName}.service.ts`)}`));
3241
3224
  const wantsMethods = await UPrompt.confirm("Do you want to add methods to the controller?");
3242
3225
  let methods = [];
3243
3226
  let controllerContent;
3244
- if (wantsMethods && !(0, import_prompts7.isCancel)(wantsMethods)) {
3227
+ if (wantsMethods && !(0, import_prompts8.isCancel)(wantsMethods)) {
3245
3228
  const methodsText = await UPrompt.text(
3246
3229
  "Enter the method names (comma separated):",
3247
3230
  "create, findAll, findById, update, delete",
3248
3231
  (v) => v ? void 0 : "You must enter at least one method."
3249
3232
  );
3250
- methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
3233
+ if (!(0, import_prompts8.isCancel)(methodsText)) {
3234
+ methods = methodsText.split(",").map((m) => m.trim()).filter(Boolean);
3235
+ }
3251
3236
  controllerContent = generateLayeredControllerTemplate(controllerName, featureName, methods);
3252
3237
  } else {
3253
3238
  controllerContent = `import { Request, Response } from "opticore-express";
@@ -3257,18 +3242,18 @@ export class ${controllerName} {}
3257
3242
  }
3258
3243
  const controllerPath = import_path8.default.join(paths.controllersDir, `${featureName}.controller.ts`);
3259
3244
  UFsModule.createFile(controllerPath, controllerContent);
3260
- console.log(import_ansi_colors11.default.green(`\u2705 Controller created: ${controllerPath}`));
3245
+ console.log(import_ansi_colors11.default.green(`\u2714 Controller created: ${controllerPath}`));
3261
3246
  UFsModule.createFile(
3262
3247
  import_path8.default.join(paths.routesDir, `${featureName}.router.handler.ts`),
3263
3248
  generateLayeredRouterHandlerTemplate(featureName, methods)
3264
3249
  );
3265
- console.log(import_ansi_colors11.default.green(`\u2705 Router Handler created: ${import_path8.default.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
3250
+ console.log(import_ansi_colors11.default.green(`\u2714 Router Handler created: ${import_path8.default.join(paths.routesDir, `${featureName}.router.handler.ts`)}`));
3266
3251
  UFsModule.createFile(
3267
3252
  import_path8.default.join(paths.routesDir, `${featureName}.router.ts`),
3268
3253
  generateLayeredRouterTemplate(featureName)
3269
3254
  );
3270
3255
  await FeatureComponentGeneratorUtils.registerModuleRouter(featureName);
3271
- console.log(import_ansi_colors11.default.green(`\u2705 Router created: ${import_path8.default.join(paths.routesDir, `${featureName}.router.ts`)}`));
3256
+ console.log(import_ansi_colors11.default.green(`\u2714 Router created: ${import_path8.default.join(paths.routesDir, `${featureName}.router.ts`)}`));
3272
3257
  console.log(
3273
3258
  import_ansi_colors11.default.bgGreen(
3274
3259
  import_ansi_colors11.default.white(`
@@ -3282,7 +3267,7 @@ export class ${controllerName} {}
3282
3267
 
3283
3268
  // src/core/core.ts
3284
3269
  var core_exports = {};
3285
- var import_process2, import_node_fs2, import_path9, import_prompts8;
3270
+ var import_process2, import_node_fs2, import_path9, import_prompts9;
3286
3271
  var init_core = __esm({
3287
3272
  "src/core/core.ts"() {
3288
3273
  "use strict";
@@ -3290,21 +3275,21 @@ var init_core = __esm({
3290
3275
  import_process2 = __toESM(require("process"), 1);
3291
3276
  import_node_fs2 = __toESM(require("fs"), 1);
3292
3277
  import_path9 = __toESM(require("path"), 1);
3293
- import_prompts8 = require("@clack/prompts");
3278
+ import_prompts9 = require("@clack/prompts");
3294
3279
  init_welcomeMessage_utils();
3295
3280
  init_choiceFeatureCleanModule();
3296
3281
  init_customFeatureInfo_utils();
3297
3282
  init_featureName_service();
3298
3283
  init_base_service();
3299
3284
  init_createController_application();
3300
- init_customModuleScaffold_template();
3285
+ init_buildYourOwnArchitectureScaffold_template();
3301
3286
  init_mvcModuleScaffold_template();
3302
3287
  init_layeredModuleScaffold_template();
3303
3288
  (async () => {
3304
3289
  UWelcomeMessage();
3305
3290
  const featureChoice = await choiceFeatureCleanModule();
3306
3291
  if (featureChoice === "custom_feature") {
3307
- await customModuleScaffoldTemplate();
3292
+ await buildYourOwnArchitectureScaffoldTemplate();
3308
3293
  return;
3309
3294
  }
3310
3295
  if (featureChoice === "mvc_architecture" || featureChoice === "layered_architecture") {
@@ -3314,7 +3299,7 @@ var init_core = __esm({
3314
3299
  if (BaseService._isSubdirectoryExists(featureName2)) {
3315
3300
  BaseService._featureFounded(featureName2);
3316
3301
  }
3317
- if ((0, import_prompts8.isCancel)(featureName2)) {
3302
+ if ((0, import_prompts9.isCancel)(featureName2)) {
3318
3303
  BaseService._cancelOperation(featureDirectory2);
3319
3304
  return;
3320
3305
  }
@@ -3340,7 +3325,7 @@ var init_core = __esm({
3340
3325
  if (featureCleanModule) {
3341
3326
  BaseService._featureFounded(featureName);
3342
3327
  }
3343
- if ((0, import_prompts8.isCancel)(featureName)) {
3328
+ if ((0, import_prompts9.isCancel)(featureName)) {
3344
3329
  BaseService._cancelOperation(featureDirectory);
3345
3330
  } else {
3346
3331
  try {