@devbro/pashmak 0.1.55 → 0.1.57

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.
Files changed (64) hide show
  1. package/dist/cjs/app/console/DefaultCommand.js +52 -0
  2. package/dist/cjs/app/console/KeyGenerateCommand.js +52 -0
  3. package/dist/cjs/app/console/StartCommand.js +52 -0
  4. package/dist/cjs/app/console/generate/GenerateApiDocsCommand.js +52 -0
  5. package/dist/cjs/app/console/generate/GenerateControllerCommand.js +52 -0
  6. package/dist/cjs/app/console/generate/index.js +52 -0
  7. package/dist/cjs/app/console/index.js +320 -70
  8. package/dist/cjs/app/console/migrate/GenerateMigrateCommand.js +52 -0
  9. package/dist/cjs/app/console/migrate/MigrateCommand.js +52 -0
  10. package/dist/cjs/app/console/migrate/MigrateRollbackCommand.js +52 -0
  11. package/dist/cjs/app/console/migrate/index.js +52 -0
  12. package/dist/cjs/app/console/project/CreateProjectCommand.js +263 -65
  13. package/dist/cjs/app/console/project/base_project/src/config/caches.ts.tpl +11 -1
  14. package/dist/cjs/app/console/project/base_project/src/config/databases.ts.tpl +8 -6
  15. package/dist/cjs/app/console/project/base_project/src/config/default.mts.tpl +13 -20
  16. package/dist/cjs/app/console/project/base_project/src/config/loggers.ts.tpl +13 -3
  17. package/dist/cjs/app/console/project/base_project/src/config/storages.ts.tpl +1 -2
  18. package/dist/cjs/app/console/project/base_project/src/initialize.ts.tpl +48 -16
  19. package/dist/cjs/app/console/project/base_project/src/routes.ts.tpl +2 -2
  20. package/dist/cjs/app/console/queue/GenerateQueueMigrateCommand.js +52 -0
  21. package/dist/cjs/bin/pashmak_cli.js +265 -66
  22. package/dist/cjs/cache/MultiCache.js +71 -0
  23. package/dist/cjs/{cache.js → cache/cache.js} +54 -2
  24. package/dist/cjs/facades.js +52 -0
  25. package/dist/cjs/factories.js +52 -0
  26. package/dist/cjs/http.js +52 -0
  27. package/dist/cjs/index.js +1900 -2056
  28. package/dist/cjs/middlewares.js +112 -2
  29. package/dist/cjs/queue.js +52 -0
  30. package/dist/esm/app/console/project/CreateProjectCommand.d.mts +15 -2
  31. package/dist/esm/app/console/project/CreateProjectCommand.mjs +265 -67
  32. package/dist/esm/app/console/project/CreateProjectCommand.mjs.map +1 -1
  33. package/dist/esm/app/console/project/base_project/src/config/caches.ts.tpl +11 -1
  34. package/dist/esm/app/console/project/base_project/src/config/databases.ts.tpl +8 -6
  35. package/dist/esm/app/console/project/base_project/src/config/default.mts.tpl +13 -20
  36. package/dist/esm/app/console/project/base_project/src/config/loggers.ts.tpl +13 -3
  37. package/dist/esm/app/console/project/base_project/src/config/storages.ts.tpl +1 -2
  38. package/dist/esm/app/console/project/base_project/src/initialize.ts.tpl +48 -16
  39. package/dist/esm/app/console/project/base_project/src/routes.ts.tpl +2 -2
  40. package/dist/esm/bin/pashmak_cli.mjs +2 -1
  41. package/dist/esm/bin/pashmak_cli.mjs.map +1 -1
  42. package/dist/esm/cache/MultiCache.d.mts +14 -0
  43. package/dist/esm/cache/MultiCache.mjs +47 -0
  44. package/dist/esm/cache/MultiCache.mjs.map +1 -0
  45. package/dist/esm/{cache.mjs → cache/cache.mjs} +1 -1
  46. package/dist/esm/cache/cache.mjs.map +1 -0
  47. package/dist/esm/config.mjs.map +1 -1
  48. package/dist/esm/factories.mjs +9 -0
  49. package/dist/esm/factories.mjs.map +1 -1
  50. package/dist/esm/index.d.mts +1 -7
  51. package/dist/esm/index.mjs +1 -32
  52. package/dist/esm/index.mjs.map +1 -1
  53. package/dist/esm/middlewares.d.mts +12 -1
  54. package/dist/esm/middlewares.mjs +52 -0
  55. package/dist/esm/middlewares.mjs.map +1 -1
  56. package/package.json +4 -2
  57. package/dist/cjs/app/console/project/base_project/package.json.tpl +0 -74
  58. package/dist/cjs/app/console/project/base_project/src/config/test.ts.tpl +0 -1
  59. package/dist/esm/app/console/project/base_project/package.json.tpl +0 -74
  60. package/dist/esm/app/console/project/base_project/src/config/test.ts.tpl +0 -1
  61. package/dist/esm/cache.mjs.map +0 -1
  62. /package/dist/cjs/app/console/project/base_project/src/config/{mailer.ts.tpl → mailers.ts.tpl} +0 -0
  63. /package/dist/esm/app/console/project/base_project/src/config/{mailer.ts.tpl → mailers.ts.tpl} +0 -0
  64. /package/dist/esm/{cache.d.mts → cache/cache.d.mts} +0 -0
@@ -1539,13 +1539,13 @@ function normalize(strArray) {
1539
1539
  }
1540
1540
  __name(normalize, "normalize");
1541
1541
  function urlJoin() {
1542
- var input;
1542
+ var input2;
1543
1543
  if (typeof arguments[0] === "object") {
1544
- input = arguments[0];
1544
+ input2 = arguments[0];
1545
1545
  } else {
1546
- input = [].slice.call(arguments);
1546
+ input2 = [].slice.call(arguments);
1547
1547
  }
1548
- return normalize(input);
1548
+ return normalize(input2);
1549
1549
  }
1550
1550
  __name(urlJoin, "urlJoin");
1551
1551
 
@@ -1756,6 +1756,51 @@ var DatabaseTransport = class {
1756
1756
  // src/factories.mts
1757
1757
  var import_neko_cache = require("@devbro/neko-cache");
1758
1758
  var import_neko_storage = require("@devbro/neko-storage");
1759
+
1760
+ // src/cache/MultiCache.mts
1761
+ var MultiCache = class {
1762
+ constructor(caches) {
1763
+ this.caches = caches;
1764
+ }
1765
+ static {
1766
+ __name(this, "MultiCache");
1767
+ }
1768
+ async get(key) {
1769
+ for (const cache2 of this.caches) {
1770
+ const value = await cache2.get(key);
1771
+ if (value !== void 0) {
1772
+ return value;
1773
+ }
1774
+ }
1775
+ return void 0;
1776
+ }
1777
+ async put(key, value, ttl) {
1778
+ await Promise.all(this.caches.map((cache2) => cache2.put(key, value, ttl)));
1779
+ }
1780
+ async delete(key) {
1781
+ await Promise.all(this.caches.map((cache2) => cache2.delete(key)));
1782
+ }
1783
+ async has(key) {
1784
+ for (const cache2 of this.caches) {
1785
+ if (await cache2.has(key)) {
1786
+ return true;
1787
+ }
1788
+ }
1789
+ return false;
1790
+ }
1791
+ async increment(key, amount) {
1792
+ let rc = void 0;
1793
+ for (const cache2 of this.caches) {
1794
+ let rc2 = await cache2.increment(key, amount);
1795
+ if (rc === void 0) {
1796
+ rc = rc2;
1797
+ }
1798
+ }
1799
+ return rc;
1800
+ }
1801
+ };
1802
+
1803
+ // src/factories.mts
1759
1804
  var FlexibleFactory = class {
1760
1805
  static {
1761
1806
  __name(this, "FlexibleFactory");
@@ -1826,6 +1871,13 @@ CacheProviderFactory.register("redis", (opt) => {
1826
1871
  CacheProviderFactory.register("file", (opt) => {
1827
1872
  return new import_neko_cache.FileCacheProvider(opt);
1828
1873
  });
1874
+ CacheProviderFactory.register("multi", (opt) => {
1875
+ const caches = [];
1876
+ for (const c of opt.caches) {
1877
+ caches.push(cache(c));
1878
+ }
1879
+ return new MultiCache(caches);
1880
+ });
1829
1881
  CacheProviderFactory.register("disabled", (opt) => {
1830
1882
  return new import_neko_cache.DisabledCacheProvider();
1831
1883
  });
@@ -2656,24 +2708,17 @@ var CreateProjectCommand = class extends import_clipanion10.Command {
2656
2708
  category: `Project`,
2657
2709
  description: `Create a new project`,
2658
2710
  details: `
2659
- This command creates a new project with the specified name at the given path.
2660
- If no path is provided, the project will be created in the current directory.
2711
+ This command creates a new project interactively.
2712
+ You will be prompted for the project path and other configuration options.
2661
2713
  `,
2662
- examples: [
2663
- [
2664
- `Create a new project in specified directory`,
2665
- `create project --path /path/to/my-project --git`
2666
- ],
2667
- [
2668
- `Create a new project at a specific path with git initialized`,
2669
- `create project --path /path/to/my-project --git`
2670
- ]
2671
- ]
2672
- });
2673
- projectPath = import_clipanion10.Option.String("--path", { required: true });
2674
- git = import_clipanion10.Option.Boolean(`--git`, false, {
2675
- description: `Initialize a git repository in the new project`
2714
+ examples: [[`Create a new project`, `create project`]]
2676
2715
  });
2716
+ projectPath = "";
2717
+ executor = "";
2718
+ packageManager = "";
2719
+ linter = "";
2720
+ validation_library = "";
2721
+ database_type = "";
2677
2722
  async folderExists(folderPath) {
2678
2723
  try {
2679
2724
  const stats = await fs7.stat(folderPath);
@@ -2686,14 +2731,148 @@ var CreateProjectCommand = class extends import_clipanion10.Command {
2686
2731
  }
2687
2732
  }
2688
2733
  async execute() {
2689
- const projectPath = import_path8.default.join(this.projectPath);
2690
- try {
2691
- await fs7.access(projectPath);
2692
- console.error(`Error: Directory ${projectPath} already exists.`);
2693
- return 1;
2694
- } catch {
2734
+ await this.setupProjectPath();
2735
+ await this.setupGit();
2736
+ await this.setupExecutorAndPackageManager();
2737
+ await this.setupLinter();
2738
+ await this.setupGeneralPackages();
2739
+ await this.setupBaseProject();
2740
+ await this.installPackages();
2741
+ }
2742
+ async processTplFolder(src, dest, data = {}) {
2743
+ const files = await fs7.readdir(src, { withFileTypes: true });
2744
+ for (const file of files) {
2745
+ const srcPath = import_path8.default.join(src, file.name);
2746
+ const destPath = file.isFile() && file.name.endsWith(".tpl") ? import_path8.default.join(dest, file.name.substring(0, file.name.length - 4)) : import_path8.default.join(dest, file.name);
2747
+ if (file.isDirectory()) {
2748
+ await fs7.mkdir(destPath, { recursive: true });
2749
+ await this.processTplFolder(srcPath, destPath, data);
2750
+ } else if (file.name.endsWith(".tpl")) {
2751
+ await this.processTplFile(srcPath, destPath, data);
2752
+ } else {
2753
+ throw new Error(
2754
+ "unexpected non tpl file: " + srcPath + " " + file.name
2755
+ );
2756
+ }
2695
2757
  }
2696
- const validation_library = await (0, import_prompts.select)({
2758
+ }
2759
+ async processTplFile(src, dest, data = {}) {
2760
+ import_handlebars3.default.registerHelper("eq", (a, b) => a === b);
2761
+ const compiledTemplate = import_handlebars3.default.compile(
2762
+ (await fs7.readFile(src)).toString()
2763
+ );
2764
+ const template = await compiledTemplate(data);
2765
+ await fs7.writeFile(dest, template);
2766
+ }
2767
+ async setupProjectPath() {
2768
+ const pathInput = await (0, import_prompts.input)({
2769
+ message: "Enter project path (leave empty to use current directory):",
2770
+ default: ""
2771
+ });
2772
+ this.projectPath = pathInput.trim() ? import_path8.default.resolve(pathInput.trim()) : process.cwd();
2773
+ await fs7.mkdir(this.projectPath, { recursive: true });
2774
+ const files = await fs7.readdir(this.projectPath);
2775
+ if (files.length > 0) {
2776
+ throw new Error(
2777
+ `Directory ${this.projectPath} is not empty. Please use an empty directory.`
2778
+ );
2779
+ }
2780
+ }
2781
+ async setupExecutorAndPackageManager() {
2782
+ this.executor = await (0, import_prompts.select)({
2783
+ message: "Select a TypeScript executor",
2784
+ choices: [
2785
+ {
2786
+ name: "Bun",
2787
+ value: "bun",
2788
+ description: "Fast all-in-one JavaScript runtime"
2789
+ },
2790
+ {
2791
+ name: "TSX",
2792
+ value: "tsx",
2793
+ description: "TypeScript execute (tsx) - Node.js enhanced with esbuild"
2794
+ }
2795
+ ]
2796
+ });
2797
+ this.packageManager = this.executor === "bun" ? "bun" : await (0, import_prompts.select)({
2798
+ message: "Select a package manager",
2799
+ choices: [
2800
+ {
2801
+ name: "Yarn",
2802
+ value: "yarn",
2803
+ description: "Fast, reliable, and secure dependency management"
2804
+ },
2805
+ {
2806
+ name: "npm",
2807
+ value: "npm",
2808
+ description: "Node package manager (default)"
2809
+ },
2810
+ {
2811
+ name: "Bun",
2812
+ value: "bun",
2813
+ description: "Ultra-fast package manager built into Bun"
2814
+ }
2815
+ ],
2816
+ default: "yarn"
2817
+ });
2818
+ (0, import_child_process.execSync)(`${this.packageManager} init -y`, {
2819
+ stdio: "inherit",
2820
+ cwd: this.projectPath
2821
+ });
2822
+ const packageJsonPath = import_path8.default.join(this.projectPath, `package.json`);
2823
+ let packageJson = JSON.parse(await fs7.readFile(packageJsonPath, `utf-8`));
2824
+ packageJson.type = "module";
2825
+ packageJson.scripts = packageJson.scripts || {};
2826
+ packageJson.scripts.prepare = "husky init";
2827
+ packageJson.scripts.clean = "rm -rf dist";
2828
+ if (this.executor === "bun") {
2829
+ packageJson.scripts.dev = "bun run dev";
2830
+ packageJson.scripts.start = "bun run pdev";
2831
+ packageJson.scripts.build = "bun run build";
2832
+ packageJson.scripts.test = "vitest";
2833
+ packageJson.scripts["test:watch"] = "vitest --watch";
2834
+ packageJson.scripts["test:coverage"] = "vitest run --coverage";
2835
+ } else if (this.executor === "tsx") {
2836
+ packageJson.scripts.dev = "tsx --watch -r tsconfig-paths/register src/index.ts start --all | npx pino-pretty";
2837
+ packageJson.scripts.start = "tsx dist/index.js";
2838
+ packageJson.scripts.build = "tsc";
2839
+ packageJson.scripts.test = "vitest";
2840
+ packageJson.scripts["test:watch"] = "vitest --watch";
2841
+ packageJson.scripts["test:coverage"] = "vitest run --coverage";
2842
+ }
2843
+ await fs7.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
2844
+ }
2845
+ async setupLinter() {
2846
+ this.linter = await (0, import_prompts.select)({
2847
+ message: "Select a linter",
2848
+ choices: [
2849
+ {
2850
+ name: "Biome",
2851
+ value: "biome",
2852
+ description: "Fast formatter and linter for JavaScript, TypeScript, and more"
2853
+ },
2854
+ {
2855
+ name: "ESLint",
2856
+ value: "eslint",
2857
+ description: "Find and fix problems in your JavaScript code"
2858
+ }
2859
+ ]
2860
+ });
2861
+ const packageJsonPath = import_path8.default.join(this.projectPath, `package.json`);
2862
+ let packageJson = JSON.parse(await fs7.readFile(packageJsonPath, `utf-8`));
2863
+ if (this.linter === "biome") {
2864
+ packageJson.scripts.lint = "biome check . --ext .ts,.tsx";
2865
+ packageJson.scripts.format = "biome format . --ext .ts,.tsx --write";
2866
+ this.addPackage("@biomejs/biome", true);
2867
+ } else if (this.linter === "eslint") {
2868
+ packageJson.scripts.lint = "eslint . --ext .ts,.tsx";
2869
+ packageJson.scripts.format = "eslint . --ext .ts,.tsx --fix";
2870
+ this.addPackage("eslint", true);
2871
+ }
2872
+ await fs7.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
2873
+ }
2874
+ async setupGeneralPackages() {
2875
+ this.validation_library = await (0, import_prompts.select)({
2697
2876
  message: "Select a package you want for validation",
2698
2877
  choices: [
2699
2878
  {
@@ -2714,8 +2893,42 @@ var CreateProjectCommand = class extends import_clipanion10.Command {
2714
2893
  }
2715
2894
  ]
2716
2895
  });
2717
- await fs7.mkdir(projectPath, { recursive: true });
2718
- console.log(`Created project directory at: ${projectPath}`);
2896
+ this.validation_library === "none" || await this.addPackage(this.validation_library);
2897
+ this.database_type = await (0, import_prompts.select)({
2898
+ message: "Select a database type (you can add more databases later)",
2899
+ choices: [
2900
+ {
2901
+ name: "PostgreSQL",
2902
+ value: "postgresql",
2903
+ description: "A powerful, open source object-relational database system"
2904
+ },
2905
+ {
2906
+ name: "MySQL",
2907
+ value: "mysql",
2908
+ description: "The world's most popular open source database"
2909
+ },
2910
+ {
2911
+ name: "SQLite",
2912
+ value: "sqlite",
2913
+ description: "A C library that provides a lightweight disk-based database"
2914
+ }
2915
+ ]
2916
+ });
2917
+ if (this.database_type === "postgresql") {
2918
+ await this.addPackage("pg pg-cursor");
2919
+ } else if (this.database_type === "mysql") {
2920
+ await this.addPackage("mysql2");
2921
+ } else if (this.database_type === "sqlite") {
2922
+ await this.addPackage("sqlite3");
2923
+ }
2924
+ await this.addPackage("@devbro/pashmak tsconfig-paths dotenv ");
2925
+ await this.addPackage(
2926
+ "husky vitest supertest @types/supertest pino-pretty typescript tsx",
2927
+ true
2928
+ );
2929
+ }
2930
+ async setupBaseProject() {
2931
+ console.log(`Using project directory: ${this.projectPath}`);
2719
2932
  const dirname = typeof __dirname === "undefined" ? import_path8.default.dirname((0, import_url3.fileURLToPath)(import_meta3.url)) : __dirname;
2720
2933
  let basePath = import_path8.default.join(dirname, `./base_project`);
2721
2934
  if (await this.folderExists(basePath) === false) {
@@ -2723,53 +2936,90 @@ var CreateProjectCommand = class extends import_clipanion10.Command {
2723
2936
  }
2724
2937
  console.log(`Using base project path: ${basePath}`);
2725
2938
  const baseProjectPath = basePath;
2726
- await this.processTplFolder(baseProjectPath, projectPath, {
2727
- validation_library
2939
+ await this.processTplFolder(baseProjectPath, this.projectPath, {
2940
+ validation_library: this.validation_library,
2941
+ executor: this.executor,
2942
+ package_manager: this.packageManager,
2943
+ linter: this.linter,
2944
+ database_type: this.database_type
2728
2945
  });
2729
- console.log(`Copied base project files to: ${projectPath}`);
2730
- const packageJsonPath = import_path8.default.join(projectPath, `package.json`);
2731
- const packageJson = JSON.parse(await fs7.readFile(packageJsonPath, `utf-8`));
2732
- packageJson.name = import_change_case_all3.Case.snake(import_path8.default.basename(projectPath));
2946
+ console.log(`Copied base project files to: ${this.projectPath}`);
2947
+ const packageJsonPath = import_path8.default.join(this.projectPath, "package.json");
2948
+ let packageJson = JSON.parse(await fs7.readFile(packageJsonPath, `utf-8`));
2949
+ packageJson.name = import_change_case_all3.Case.snake(import_path8.default.basename(this.projectPath));
2733
2950
  await fs7.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
2734
2951
  console.log(`Updated package.json with project name: ${packageJson.name}`);
2735
- if (this.git) {
2736
- try {
2737
- (0, import_child_process.execSync)(
2738
- 'git init; git add --all; git commit --allow-empty -m "chore: first commit for pashmak"',
2739
- {
2740
- cwd: projectPath
2741
- }
2742
- );
2743
- } catch (error) {
2744
- console.error(`Failed to create project.`, error);
2745
- return 1;
2746
- }
2747
- }
2748
2952
  }
2749
- async processTplFolder(src, dest, data = {}) {
2750
- const files = await fs7.readdir(src, { withFileTypes: true });
2751
- for (const file of files) {
2752
- const srcPath = import_path8.default.join(src, file.name);
2753
- const destPath = file.isFile() && file.name.endsWith(".tpl") ? import_path8.default.join(dest, file.name.substring(0, file.name.length - 4)) : import_path8.default.join(dest, file.name);
2754
- if (file.isDirectory()) {
2755
- await fs7.mkdir(destPath, { recursive: true });
2756
- await this.processTplFolder(srcPath, destPath, data);
2757
- } else if (file.name.endsWith(".tpl")) {
2758
- await this.processTplFile(srcPath, destPath, data);
2759
- } else {
2760
- throw new Error(
2761
- "unexpected non tpl file: " + srcPath + " " + file.name
2762
- );
2763
- }
2953
+ async addPackage(packageName, dev = false) {
2954
+ let install_command = "";
2955
+ switch (this.packageManager) {
2956
+ case "bun":
2957
+ install_command = `bun add ${packageName}${dev ? " -d" : ""}`;
2958
+ break;
2959
+ case "yarn":
2960
+ install_command = `yarn add ${packageName}${dev ? " -D" : ""} --no-install`;
2961
+ break;
2962
+ case "npm":
2963
+ install_command = `npm install ${packageName}${dev ? " --save-dev" : ""} --package-lock-only`;
2964
+ break;
2965
+ }
2966
+ (0, import_child_process.execSync)(install_command, {
2967
+ stdio: "inherit",
2968
+ cwd: this.projectPath
2969
+ });
2970
+ }
2971
+ async installPackages() {
2972
+ const install_command = this.packageManager === "bun" ? `bun install` : this.packageManager === "yarn" ? `yarn` : `npm install`;
2973
+ (0, import_child_process.execSync)(install_command, {
2974
+ stdio: "inherit",
2975
+ cwd: this.projectPath
2976
+ });
2977
+ }
2978
+ async setupGit() {
2979
+ const initGit = await (0, import_prompts.select)({
2980
+ message: "Initialize a git repository?",
2981
+ choices: [
2982
+ {
2983
+ name: "Yes",
2984
+ value: true,
2985
+ description: "Initialize git and create first commit"
2986
+ },
2987
+ {
2988
+ name: "No",
2989
+ value: false,
2990
+ description: "Skip git initialization"
2991
+ }
2992
+ ]
2993
+ });
2994
+ if (initGit) {
2995
+ const gitignoreContent = [
2996
+ "node_modules/",
2997
+ "dist/",
2998
+ ".env",
2999
+ ".env.*",
3000
+ "!.env.example",
3001
+ "*.log",
3002
+ "coverage/",
3003
+ ".DS_Store"
3004
+ ].join("\n") + "\n";
3005
+ await fs7.writeFile(
3006
+ import_path8.default.join(this.projectPath, ".gitignore"),
3007
+ gitignoreContent
3008
+ );
3009
+ (0, import_child_process.execSync)(
3010
+ `git init; git add --all; git commit --allow-empty -m "chore: first commit"`,
3011
+ {
3012
+ cwd: this.projectPath
3013
+ }
3014
+ );
2764
3015
  }
2765
3016
  }
2766
- async processTplFile(src, dest, data = {}) {
2767
- import_handlebars3.default.registerHelper("eq", (a, b) => a === b);
2768
- const compiledTemplate = import_handlebars3.default.compile(
2769
- (await fs7.readFile(src)).toString()
2770
- );
2771
- const template = await compiledTemplate(data);
2772
- await fs7.writeFile(dest, template);
3017
+ async catch(error) {
3018
+ if (Error.isError(error)) {
3019
+ console.error(error.message);
3020
+ } else {
3021
+ console.error(error);
3022
+ }
2773
3023
  }
2774
3024
  };
2775
3025
 
@@ -592,6 +592,51 @@ var DatabaseTransport = class {
592
592
  // src/factories.mts
593
593
  var import_neko_cache = require("@devbro/neko-cache");
594
594
  var import_neko_storage = require("@devbro/neko-storage");
595
+
596
+ // src/cache/MultiCache.mts
597
+ var MultiCache = class {
598
+ constructor(caches) {
599
+ this.caches = caches;
600
+ }
601
+ static {
602
+ __name(this, "MultiCache");
603
+ }
604
+ async get(key) {
605
+ for (const cache2 of this.caches) {
606
+ const value = await cache2.get(key);
607
+ if (value !== void 0) {
608
+ return value;
609
+ }
610
+ }
611
+ return void 0;
612
+ }
613
+ async put(key, value, ttl) {
614
+ await Promise.all(this.caches.map((cache2) => cache2.put(key, value, ttl)));
615
+ }
616
+ async delete(key) {
617
+ await Promise.all(this.caches.map((cache2) => cache2.delete(key)));
618
+ }
619
+ async has(key) {
620
+ for (const cache2 of this.caches) {
621
+ if (await cache2.has(key)) {
622
+ return true;
623
+ }
624
+ }
625
+ return false;
626
+ }
627
+ async increment(key, amount) {
628
+ let rc = void 0;
629
+ for (const cache2 of this.caches) {
630
+ let rc2 = await cache2.increment(key, amount);
631
+ if (rc === void 0) {
632
+ rc = rc2;
633
+ }
634
+ }
635
+ return rc;
636
+ }
637
+ };
638
+
639
+ // src/factories.mts
595
640
  var FlexibleFactory = class {
596
641
  static {
597
642
  __name(this, "FlexibleFactory");
@@ -662,6 +707,13 @@ CacheProviderFactory.register("redis", (opt) => {
662
707
  CacheProviderFactory.register("file", (opt) => {
663
708
  return new import_neko_cache.FileCacheProvider(opt);
664
709
  });
710
+ CacheProviderFactory.register("multi", (opt) => {
711
+ const caches = [];
712
+ for (const c of opt.caches) {
713
+ caches.push(cache(c));
714
+ }
715
+ return new MultiCache(caches);
716
+ });
665
717
  CacheProviderFactory.register("disabled", (opt) => {
666
718
  return new import_neko_cache.DisabledCacheProvider();
667
719
  });
@@ -592,6 +592,51 @@ var DatabaseTransport = class {
592
592
  // src/factories.mts
593
593
  var import_neko_cache = require("@devbro/neko-cache");
594
594
  var import_neko_storage = require("@devbro/neko-storage");
595
+
596
+ // src/cache/MultiCache.mts
597
+ var MultiCache = class {
598
+ constructor(caches) {
599
+ this.caches = caches;
600
+ }
601
+ static {
602
+ __name(this, "MultiCache");
603
+ }
604
+ async get(key) {
605
+ for (const cache2 of this.caches) {
606
+ const value = await cache2.get(key);
607
+ if (value !== void 0) {
608
+ return value;
609
+ }
610
+ }
611
+ return void 0;
612
+ }
613
+ async put(key, value, ttl) {
614
+ await Promise.all(this.caches.map((cache2) => cache2.put(key, value, ttl)));
615
+ }
616
+ async delete(key) {
617
+ await Promise.all(this.caches.map((cache2) => cache2.delete(key)));
618
+ }
619
+ async has(key) {
620
+ for (const cache2 of this.caches) {
621
+ if (await cache2.has(key)) {
622
+ return true;
623
+ }
624
+ }
625
+ return false;
626
+ }
627
+ async increment(key, amount) {
628
+ let rc = void 0;
629
+ for (const cache2 of this.caches) {
630
+ let rc2 = await cache2.increment(key, amount);
631
+ if (rc === void 0) {
632
+ rc = rc2;
633
+ }
634
+ }
635
+ return rc;
636
+ }
637
+ };
638
+
639
+ // src/factories.mts
595
640
  var FlexibleFactory = class {
596
641
  static {
597
642
  __name(this, "FlexibleFactory");
@@ -662,6 +707,13 @@ CacheProviderFactory.register("redis", (opt) => {
662
707
  CacheProviderFactory.register("file", (opt) => {
663
708
  return new import_neko_cache.FileCacheProvider(opt);
664
709
  });
710
+ CacheProviderFactory.register("multi", (opt) => {
711
+ const caches = [];
712
+ for (const c of opt.caches) {
713
+ caches.push(cache(c));
714
+ }
715
+ return new MultiCache(caches);
716
+ });
665
717
  CacheProviderFactory.register("disabled", (opt) => {
666
718
  return new import_neko_cache.DisabledCacheProvider();
667
719
  });
@@ -1747,6 +1747,51 @@ var DatabaseTransport = class {
1747
1747
  // src/factories.mts
1748
1748
  var import_neko_cache = require("@devbro/neko-cache");
1749
1749
  var import_neko_storage = require("@devbro/neko-storage");
1750
+
1751
+ // src/cache/MultiCache.mts
1752
+ var MultiCache = class {
1753
+ constructor(caches) {
1754
+ this.caches = caches;
1755
+ }
1756
+ static {
1757
+ __name(this, "MultiCache");
1758
+ }
1759
+ async get(key) {
1760
+ for (const cache2 of this.caches) {
1761
+ const value = await cache2.get(key);
1762
+ if (value !== void 0) {
1763
+ return value;
1764
+ }
1765
+ }
1766
+ return void 0;
1767
+ }
1768
+ async put(key, value, ttl) {
1769
+ await Promise.all(this.caches.map((cache2) => cache2.put(key, value, ttl)));
1770
+ }
1771
+ async delete(key) {
1772
+ await Promise.all(this.caches.map((cache2) => cache2.delete(key)));
1773
+ }
1774
+ async has(key) {
1775
+ for (const cache2 of this.caches) {
1776
+ if (await cache2.has(key)) {
1777
+ return true;
1778
+ }
1779
+ }
1780
+ return false;
1781
+ }
1782
+ async increment(key, amount) {
1783
+ let rc = void 0;
1784
+ for (const cache2 of this.caches) {
1785
+ let rc2 = await cache2.increment(key, amount);
1786
+ if (rc === void 0) {
1787
+ rc = rc2;
1788
+ }
1789
+ }
1790
+ return rc;
1791
+ }
1792
+ };
1793
+
1794
+ // src/factories.mts
1750
1795
  var FlexibleFactory = class {
1751
1796
  static {
1752
1797
  __name(this, "FlexibleFactory");
@@ -1817,6 +1862,13 @@ CacheProviderFactory.register("redis", (opt) => {
1817
1862
  CacheProviderFactory.register("file", (opt) => {
1818
1863
  return new import_neko_cache.FileCacheProvider(opt);
1819
1864
  });
1865
+ CacheProviderFactory.register("multi", (opt) => {
1866
+ const caches = [];
1867
+ for (const c of opt.caches) {
1868
+ caches.push(cache(c));
1869
+ }
1870
+ return new MultiCache(caches);
1871
+ });
1820
1872
  CacheProviderFactory.register("disabled", (opt) => {
1821
1873
  return new import_neko_cache.DisabledCacheProvider();
1822
1874
  });