@devbro/pashmak 0.1.48 → 0.1.49

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 (38) hide show
  1. package/dist/DatabaseServiceProvider.d.mts +4 -1
  2. package/dist/DatabaseServiceProvider.mjs +5 -2
  3. package/dist/DatabaseServiceProvider.mjs.map +1 -1
  4. package/dist/app/console/StartCommand.d.mts +1 -0
  5. package/dist/app/console/StartCommand.mjs +5 -2
  6. package/dist/app/console/StartCommand.mjs.map +1 -1
  7. package/dist/app/console/generate/GenerateApiDocsCommand.d.mts +34 -2
  8. package/dist/app/console/generate/GenerateApiDocsCommand.mjs +183 -100
  9. package/dist/app/console/generate/GenerateApiDocsCommand.mjs.map +1 -1
  10. package/dist/app/console/project/base_project/src/config/storages.ts.tpl +2 -2
  11. package/dist/bin/DatabaseServiceProvider.cjs +8 -2
  12. package/dist/bin/app/console/DefaultCommand.cjs +45 -17
  13. package/dist/bin/app/console/KeyGenerateCommand.cjs +45 -17
  14. package/dist/bin/app/console/StartCommand.cjs +50 -19
  15. package/dist/bin/app/console/generate/GenerateApiDocsCommand.cjs +229 -118
  16. package/dist/bin/app/console/generate/GenerateControllerCommand.cjs +45 -17
  17. package/dist/bin/app/console/generate/index.cjs +229 -118
  18. package/dist/bin/app/console/index.cjs +234 -120
  19. package/dist/bin/app/console/migrate/GenerateMigrateCommand.cjs +45 -17
  20. package/dist/bin/app/console/migrate/MigrateCommand.cjs +45 -17
  21. package/dist/bin/app/console/migrate/MigrateRollbackCommand.cjs +45 -17
  22. package/dist/bin/app/console/migrate/index.cjs +45 -17
  23. package/dist/bin/app/console/queue/GenerateQueueMigrateCommand.cjs +45 -17
  24. package/dist/bin/cache.cjs +45 -17
  25. package/dist/bin/facades.cjs +45 -17
  26. package/dist/bin/factories.cjs +45 -17
  27. package/dist/bin/http.cjs +45 -17
  28. package/dist/bin/index.cjs +243 -126
  29. package/dist/bin/middlewares.cjs +45 -17
  30. package/dist/bin/queue.cjs +45 -17
  31. package/dist/bin/router.cjs +3 -5
  32. package/dist/factories.mjs +45 -2
  33. package/dist/factories.mjs.map +1 -1
  34. package/dist/http.mjs +1 -1
  35. package/dist/http.mjs.map +1 -1
  36. package/dist/queue.d.mts +1 -1
  37. package/dist/queue.mjs.map +1 -1
  38. package/package.json +1 -1
@@ -78,6 +78,7 @@ var MiddlewareFactory = class {
78
78
  };
79
79
 
80
80
  // ../neko-router/dist/CompiledRoute.mjs
81
+ var import_neko_helper = require("@devbro/neko-helper");
81
82
  var CompiledRoute = class {
82
83
  static {
83
84
  __name(this, "CompiledRoute");
@@ -98,7 +99,7 @@ var CompiledRoute = class {
98
99
  for (const middleware of [...this.globalMiddlewares, ...this.route.getMiddlewares()]) {
99
100
  if (middleware instanceof Middleware) {
100
101
  this.middlewares.push(middleware);
101
- } else if (this.isClass(middleware)) {
102
+ } else if ((0, import_neko_helper.isClass)(middleware)) {
102
103
  this.middlewares.push(middleware.getInstance({}));
103
104
  } else if (typeof middleware === "function") {
104
105
  this.middlewares.push(MiddlewareFactory.create(middleware));
@@ -107,9 +108,6 @@ var CompiledRoute = class {
107
108
  }
108
109
  }
109
110
  }
110
- isClass(func) {
111
- return typeof func === "function" && /^class\s/.test(Function.prototype.toString.call(func));
112
- }
113
111
  async run() {
114
112
  return await this.runMiddlewares(this.middlewares, this.request, this.response);
115
113
  }
@@ -245,7 +243,7 @@ var Route = class {
245
243
  i = start;
246
244
  } else if (char === "*") {
247
245
  let start = i + 1;
248
- while (start < path4.length && /[a-zA-Z0-9_\.]/.test(path4[start])) {
246
+ while (start < path4.length && /[a-zA-Z0-9_]/.test(path4[start])) {
249
247
  start++;
250
248
  }
251
249
  tokens.push({ type: "WILDCARD", value: path4.slice(i + 1, start) });
@@ -456,7 +454,7 @@ var Router = class {
456
454
 
457
455
  // src/facades.mts
458
456
  var import_neko_scheduler = require("@devbro/neko-scheduler");
459
- var import_neko_helper2 = require("@devbro/neko-helper");
457
+ var import_neko_helper3 = require("@devbro/neko-helper");
460
458
  var import_neko_context3 = require("@devbro/neko-context");
461
459
  var import_neko_storage2 = require("@devbro/neko-storage");
462
460
  var import_neko_mailer2 = require("@devbro/neko-mailer");
@@ -497,7 +495,7 @@ __export(queue_exports, {
497
495
  DatabaseTransport: () => DatabaseTransport
498
496
  });
499
497
  __reExport(queue_exports, require("@devbro/neko-queue"));
500
- var import_neko_helper = require("@devbro/neko-helper");
498
+ var import_neko_helper2 = require("@devbro/neko-helper");
501
499
  var import_neko_context2 = require("@devbro/neko-context");
502
500
  var DatabaseTransport = class {
503
501
  static {
@@ -558,7 +556,7 @@ var DatabaseTransport = class {
558
556
  }, "processMessage");
559
557
  constructor(config4 = {}) {
560
558
  this.config = { ...this.config, ...config4 };
561
- this.repeater = (0, import_neko_helper.createRepeater)(
559
+ this.repeater = (0, import_neko_helper2.createRepeater)(
562
560
  this.processMessage,
563
561
  this.config.listen_interval * 1e3
564
562
  );
@@ -626,6 +624,24 @@ import_neko_queue.QueueTransportFactory.register("database", (opt) => {
626
624
  import_neko_queue.QueueTransportFactory.register("memory", (opt) => {
627
625
  return new import_neko_queue.MemoryTransport(opt);
628
626
  });
627
+ import_neko_queue.QueueTransportFactory.register("sqs", (opt) => {
628
+ return new import_neko_queue.AwsSqsTransport(opt);
629
+ });
630
+ import_neko_queue.QueueTransportFactory.register("amqp", (opt) => {
631
+ return new import_neko_queue.AmqpTransport(opt);
632
+ });
633
+ import_neko_queue.QueueTransportFactory.register("redis", (opt) => {
634
+ return new import_neko_queue.RedisTransport(opt);
635
+ });
636
+ import_neko_queue.QueueTransportFactory.register("async", (opt) => {
637
+ return new import_neko_queue.AsyncTransport();
638
+ });
639
+ import_neko_queue.QueueTransportFactory.register("azure_service_bus", (opt) => {
640
+ return new import_neko_queue.AzureServiceBusTransport(opt);
641
+ });
642
+ import_neko_queue.QueueTransportFactory.register("google_pubsub", (opt) => {
643
+ return new import_neko_queue.GooglePubSubTransport(opt);
644
+ });
629
645
  var CacheProviderFactory = class _CacheProviderFactory {
630
646
  static {
631
647
  __name(this, "CacheProviderFactory");
@@ -656,12 +672,24 @@ import_neko_storage.StorageProviderFactory.register("local", (opt) => {
656
672
  import_neko_storage.StorageProviderFactory.register("s3", (opt) => {
657
673
  return new import_neko_storage.AWSS3StorageProvider(opt);
658
674
  });
675
+ import_neko_storage.StorageProviderFactory.register("gcp", (opt) => {
676
+ return new import_neko_storage.GCPStorageProvider(opt);
677
+ });
678
+ import_neko_storage.StorageProviderFactory.register("azure", (opt) => {
679
+ return new import_neko_storage.AzureBlobStorageProvider(opt);
680
+ });
681
+ import_neko_storage.StorageProviderFactory.register("ftp", (opt) => {
682
+ return new import_neko_storage.FTPStorageProvider(opt);
683
+ });
684
+ import_neko_storage.StorageProviderFactory.register("sftp", (opt) => {
685
+ return new import_neko_storage.SFTPStorageProvider(opt);
686
+ });
659
687
 
660
688
  // src/facades.mts
661
689
  var import_neko_cache2 = require("@devbro/neko-cache");
662
690
  var import_neko_queue2 = require("@devbro/neko-queue");
663
- var router = (0, import_neko_helper2.createSingleton)(() => new Router());
664
- var scheduler = (0, import_neko_helper2.createSingleton)(() => {
691
+ var router = (0, import_neko_helper3.createSingleton)(() => new Router());
692
+ var scheduler = (0, import_neko_helper3.createSingleton)(() => {
665
693
  const rc = new import_neko_scheduler.Scheduler();
666
694
  rc.setErrorHandler((err, job) => {
667
695
  logger().error({
@@ -673,7 +701,7 @@ var scheduler = (0, import_neko_helper2.createSingleton)(() => {
673
701
  return rc;
674
702
  });
675
703
  var db = /* @__PURE__ */ __name((label = "default") => (0, import_neko_context3.ctx)().getOrThrow(["database", label]), "db");
676
- var storage = (0, import_neko_helper2.createSingleton)((label = "default") => {
704
+ var storage = (0, import_neko_helper3.createSingleton)((label = "default") => {
677
705
  let storage_config = import_neko_config.config.get(["storages", label].join("."));
678
706
  const provider = import_neko_storage2.StorageProviderFactory.create(
679
707
  storage_config.provider,
@@ -681,7 +709,7 @@ var storage = (0, import_neko_helper2.createSingleton)((label = "default") => {
681
709
  );
682
710
  return new import_neko_storage2.Storage(provider);
683
711
  });
684
- var cli = (0, import_neko_helper2.createSingleton)(() => {
712
+ var cli = (0, import_neko_helper3.createSingleton)(() => {
685
713
  const [node, app, ...args] = process.argv;
686
714
  return new import_clipanion.Cli({
687
715
  binaryLabel: `My Application`,
@@ -689,13 +717,13 @@ var cli = (0, import_neko_helper2.createSingleton)(() => {
689
717
  binaryVersion: `1.0.0`
690
718
  });
691
719
  });
692
- var httpServer = (0, import_neko_helper2.createSingleton)(() => {
720
+ var httpServer = (0, import_neko_helper3.createSingleton)(() => {
693
721
  const server = new http_exports.HttpServer();
694
722
  server.setErrorHandler(handleHttpErrors);
695
723
  server.setRouter(router());
696
724
  return server;
697
725
  });
698
- var logger = (0, import_neko_helper2.createSingleton)((label) => {
726
+ var logger = (0, import_neko_helper3.createSingleton)((label) => {
699
727
  const logger_config = import_neko_config.config.get(["loggers", label].join("."));
700
728
  const rc = new import_neko_logger.Logger(logger_config);
701
729
  rc.setExtrasFunction((message) => {
@@ -704,7 +732,7 @@ var logger = (0, import_neko_helper2.createSingleton)((label) => {
704
732
  });
705
733
  return rc;
706
734
  });
707
- var mailer = (0, import_neko_helper2.createSingleton)((label) => {
735
+ var mailer = (0, import_neko_helper3.createSingleton)((label) => {
708
736
  const mailer_config = import_neko_config.config.get(["mailer", label].join("."));
709
737
  const provider = import_neko_mailer2.MailerProviderFactory.create(
710
738
  mailer_config.provider,
@@ -713,7 +741,7 @@ var mailer = (0, import_neko_helper2.createSingleton)((label) => {
713
741
  const rc = new import_neko_mailer2.Mailer(provider);
714
742
  return rc;
715
743
  });
716
- var queue = (0, import_neko_helper2.createSingleton)((label) => {
744
+ var queue = (0, import_neko_helper3.createSingleton)((label) => {
717
745
  const queue_config = import_neko_config.config.get(["queues", label].join("."));
718
746
  if (!queue_config) {
719
747
  throw new Error(`Queue configuration for '${label}' not found`);
@@ -724,7 +752,7 @@ var queue = (0, import_neko_helper2.createSingleton)((label) => {
724
752
  );
725
753
  return new import_neko_queue2.QueueConnection(provider);
726
754
  });
727
- var cache = (0, import_neko_helper2.createSingleton)((label) => {
755
+ var cache = (0, import_neko_helper3.createSingleton)((label) => {
728
756
  const cache_config = import_neko_config.config.get(["caches", label].join("."));
729
757
  if (!cache_config) {
730
758
  throw new Error(`Cache configuration for '${label}' not found`);
@@ -799,144 +827,155 @@ var config_exports = {};
799
827
  __reExport(config_exports, require("@devbro/neko-config"));
800
828
 
801
829
  // src/app/console/generate/GenerateApiDocsCommand.mts
802
- var import_neko_helper3 = require("@devbro/neko-helper");
830
+ var import_neko_helper4 = require("@devbro/neko-helper");
803
831
  var GenerateApiDocsCommand = class extends import_clipanion3.Command {
804
832
  static {
805
833
  __name(this, "GenerateApiDocsCommand");
806
834
  }
807
- static paths = [
808
- [`make`, `apidocs`],
809
- [`generate`, `apidocs`]
810
- ];
835
+ static paths = [[`generate`, `apidocsv2`]];
811
836
  static usage = import_clipanion3.Command.Usage({
812
837
  category: `Generate`,
813
838
  description: `Generate OpenAPI documentation from routes`,
814
839
  details: `
815
- This command generates OpenAPI 3.0 specification documentation by analyzing
840
+ This command utility generates OpenAPI 3.0 specification documentation by analyzing
816
841
  your application's routes and merging with example files.
817
842
 
818
- The generated documentation includes:
819
- - All registered routes with their HTTP methods
820
- - Path parameters extracted from route definitions
821
- - Request body schemas for POST, PUT, and PATCH methods
822
- - Response schemas
823
-
824
- The command will merge files specified in config.api_docs.merge_files
825
- and output the final documentation to config.api_docs.output.
843
+ Subcommands:
844
+ - generate-from-routes: Generate OpenAPI spec from registered routes
845
+ - generate-base: Generate base OpenAPI specification structure
846
+ - merge-files: Merge multiple OpenAPI files into final documentation
826
847
 
848
+
827
849
  This command depends on config data. make sure your default config contains the following:
828
- api_docs: {
829
- merge_files: [
830
- path.join(__dirname, '../..', 'private', 'openapi_examples.json'),
831
- path.join(__dirname, '../..', 'private', 'openapi_base.json'),
832
- path.join(__dirname, '../..', 'private', 'openapi_user_changes.json'),
833
- ],
834
- output: path.join(__dirname, '../..', 'private', 'openapi.json'),
835
- }
850
+
851
+ \`\`\`
852
+ api_docs: {
853
+
854
+ merge_files: [
855
+
856
+ path.join(__dirname, '../..', 'private', 'openapi_base.json'),
857
+
858
+ path.join(__dirname, '../..', 'private', 'openapi_from_routes.json'),
859
+
860
+ path.join(__dirname, '../..', 'private', 'openapi_from_tests.json'),
861
+
862
+ path.join(__dirname, '../..', 'private', 'openapi_other_user_changes.json'),
863
+
864
+ ],
865
+
866
+ output: path.join(__dirname, '../..', 'public', 'openapi.json'),
867
+
868
+ }
869
+
870
+ \`\`\`
836
871
  `,
837
- examples: [[`Generate API documentation`, `$0 generate apidocs`]]
872
+ examples: [
873
+ [
874
+ `Generate from routes`,
875
+ `$0 generate apidocsv2 generate-from-routes --output path/to/output.json`
876
+ ],
877
+ [
878
+ `Generate base spec`,
879
+ `$0 generate apidocsv2 generate-base --output path/to/output.json`
880
+ ],
881
+ [`Merge files`, `$0 generate apidocsv2 merge-files`],
882
+ [`Show help`, `$0 generate apidocsv2 --help`]
883
+ ]
884
+ });
885
+ subcommand = import_clipanion3.Option.String({ required: false });
886
+ output = import_clipanion3.Option.String(`--output,-o`, {
887
+ description: `Output file path for generated documentation`
838
888
  });
839
- help = import_clipanion3.Option.Boolean(`--help,-h`, false, {
840
- description: `Show help message for this command`
889
+ config = import_clipanion3.Option.String(`--config,-c`, {
890
+ description: `Path in config to get details from (default: api_docs)`,
891
+ required: false
841
892
  });
842
893
  async execute() {
843
- if (this.help) {
894
+ if (!this.subcommand) {
844
895
  this.context.stdout.write(
845
896
  this.constructor.usage?.toString() || "No help available\n"
846
897
  );
847
898
  return 0;
848
899
  }
849
- const rootDir = process.cwd();
850
- this.context.stdout.write(`Generating OpenAPI documentation...
900
+ switch (this.subcommand) {
901
+ case "generate-from-routes":
902
+ return await this.executeGenerateFromRoutes();
903
+ case "generate-base":
904
+ return await this.executeGenerateBase();
905
+ case "merge-files":
906
+ return await this.executeMergeFiles();
907
+ default:
908
+ this.context.stderr.write(`Unknown subcommand: ${this.subcommand}
851
909
  `);
852
- const routes = router().routes;
853
- const openApiSpec = {
854
- openapi: "3.0.0",
855
- info: {
856
- title: "API Documentation",
857
- version: "1.0.0",
858
- description: "Auto-generated API documentation"
859
- },
860
- servers: [
861
- {
862
- url: "/",
863
- description: "Local server"
864
- }
865
- ],
866
- paths: {}
867
- };
868
- for (const route of routes) {
869
- const routePath = route.path;
870
- const openApiPath = routePath.replace(/:([a-zA-Z0-9_]+)/g, "{$1}");
871
- if (!openApiSpec.paths[openApiPath]) {
872
- openApiSpec.paths[openApiPath] = {};
873
- }
874
- for (const method of route.methods) {
875
- const lowerMethod = method.toLowerCase();
876
- if (lowerMethod === "head") {
877
- continue;
878
- }
879
- openApiSpec.paths[openApiPath][lowerMethod] = {
880
- summary: `${method} ${routePath}`,
881
- description: `Endpoint for ${method} ${routePath}`,
882
- parameters: this.extractParameters(routePath),
883
- responses: {
884
- "200": {
885
- description: "Successful response",
886
- content: {
887
- "application/json": {
888
- schema: {
889
- type: "object"
890
- }
891
- }
892
- }
893
- },
894
- "500": {
895
- description: "Internal server error"
896
- }
897
- }
898
- };
899
- if (["post", "put", "patch"].includes(lowerMethod)) {
900
- openApiSpec.paths[openApiPath][lowerMethod].requestBody = {
901
- required: true,
902
- content: {
903
- "application/json": {
904
- schema: {
905
- type: "object"
906
- }
907
- }
908
- }
909
- };
910
- }
911
- }
910
+ this.context.stdout.write(
911
+ this.constructor.usage?.toString() || "No help available\n"
912
+ );
913
+ return 1;
912
914
  }
913
- await fs2.mkdir(config_exports.config.get("private_path"), { recursive: true });
914
- const outputPath = import_path3.default.join(config_exports.config.get("private_path"), "openapi.json");
915
+ }
916
+ async executeGenerateFromRoutes() {
917
+ this.context.stdout.write(
918
+ `Generating OpenAPI documentation from routes...
919
+ `
920
+ );
921
+ const openApiSpec = this.generateFromRoutes();
922
+ const outputPath = this.output || import_path3.default.join(config_exports.config.get("private_path"), "openapi_from_routes.json");
923
+ await fs2.mkdir(import_path3.default.dirname(outputPath), { recursive: true });
915
924
  await fs2.writeFile(
916
925
  outputPath,
917
926
  JSON.stringify(openApiSpec, null, 2),
918
927
  "utf-8"
919
928
  );
920
929
  this.context.stdout.write(
921
- `OpenAPI documentation generated at: ${outputPath}
930
+ `OpenAPI routes documentation generated at: ${outputPath}
931
+ `
932
+ );
933
+ this.context.stdout.write(
934
+ `Total routes documented: ${Object.keys(openApiSpec.paths).length}
935
+ `
936
+ );
937
+ return 0;
938
+ }
939
+ async executeGenerateBase() {
940
+ this.context.stdout.write(`Generating base OpenAPI specification...
941
+ `);
942
+ const baseSpec = this.getBaseOpenApiSpec();
943
+ const outputPath = this.output || import_path3.default.join(config_exports.config.get("private_path"), "openapi_base.json");
944
+ await fs2.mkdir(import_path3.default.dirname(outputPath), { recursive: true });
945
+ await fs2.writeFile(outputPath, JSON.stringify(baseSpec, null, 2), "utf-8");
946
+ this.context.stdout.write(
947
+ `Base OpenAPI specification generated at: ${outputPath}
922
948
  `
923
949
  );
924
- this.context.stdout.write(`Total routes documented: ${routes.length}
950
+ return 0;
951
+ }
952
+ async executeMergeFiles() {
953
+ this.context.stdout.write(`Merging OpenAPI files...
925
954
  `);
926
- let files_to_merge = config_exports.config.get("api_docs.merge_files");
955
+ let configPath = this.config || "api_docs";
956
+ const files_to_merge = config_exports.config.get(`${configPath}.merge_files`);
927
957
  let final_api_docs = {};
928
- for (let file_path of files_to_merge) {
929
- let file_json = JSON.parse(await fs2.readFile(file_path, "utf8"));
930
- final_api_docs = import_neko_helper3.Arr.deepMerge(final_api_docs, file_json);
958
+ for (const file_path of files_to_merge) {
959
+ try {
960
+ const file_json = JSON.parse(await fs2.readFile(file_path, "utf8"));
961
+ final_api_docs = import_neko_helper4.Arr.deepMerge(final_api_docs, file_json);
962
+ this.context.stdout.write(` Merged: ${file_path}
963
+ `);
964
+ } catch (error) {
965
+ this.context.stderr.write(
966
+ ` Warning: Could not read ${file_path}: ${error.message}
967
+ `
968
+ );
969
+ }
931
970
  }
932
- await fs2.writeFile(
933
- config_exports.config.get("api_docs.output"),
934
- JSON.stringify(final_api_docs, null, 2)
935
- );
971
+ const outputPath = this.output || config_exports.config.get(`${configPath}.output`);
972
+ await fs2.mkdir(import_path3.default.dirname(outputPath), { recursive: true });
973
+ await fs2.writeFile(outputPath, JSON.stringify(final_api_docs, null, 2));
936
974
  this.context.stdout.write(
937
- `wrote final open api document to : ${config_exports.config.get("api_docs.output")}
975
+ `Final OpenAPI document written to: ${outputPath}
938
976
  `
939
977
  );
978
+ return 0;
940
979
  }
941
980
  extractParameters(routePath) {
942
981
  const paramRegex = /:([a-zA-Z0-9_]+)/g;
@@ -955,6 +994,78 @@ var GenerateApiDocsCommand = class extends import_clipanion3.Command {
955
994
  }
956
995
  return parameters;
957
996
  }
997
+ generateFromRoutes() {
998
+ const openApiSpec = {
999
+ paths: {}
1000
+ };
1001
+ const routes = router().routes;
1002
+ for (const route of routes) {
1003
+ const routePath = route.path;
1004
+ const openApiPath = routePath.replace(/\/$/g, "");
1005
+ if (!openApiSpec.paths[openApiPath]) {
1006
+ openApiSpec.paths[openApiPath] = {};
1007
+ }
1008
+ for (const method of route.methods) {
1009
+ const lowerMethod = method.toLowerCase();
1010
+ if (lowerMethod === "head") {
1011
+ continue;
1012
+ }
1013
+ openApiSpec.paths[openApiPath][lowerMethod] = {
1014
+ summary: `${routePath}`,
1015
+ description: `Endpoint for ${method} ${routePath}`,
1016
+ security: [],
1017
+ parameters: this.extractParameters(routePath),
1018
+ responses: {}
1019
+ };
1020
+ if (["post", "put", "patch"].includes(lowerMethod)) {
1021
+ openApiSpec.paths[openApiPath][lowerMethod].requestBody = {
1022
+ required: true,
1023
+ content: {
1024
+ "application/json": {
1025
+ schema: {
1026
+ type: "object"
1027
+ }
1028
+ }
1029
+ }
1030
+ };
1031
+ }
1032
+ }
1033
+ }
1034
+ return openApiSpec;
1035
+ }
1036
+ getBaseOpenApiSpec() {
1037
+ const openApiSpec = {
1038
+ openapi: "3.0.0",
1039
+ info: {
1040
+ title: "API Documentation",
1041
+ version: "1.0.0",
1042
+ description: "Auto-generated API documentation"
1043
+ },
1044
+ servers: [
1045
+ {
1046
+ url: "/",
1047
+ description: "Local server"
1048
+ }
1049
+ ],
1050
+ components: {
1051
+ securitySchemes: {
1052
+ bearerAuth: {
1053
+ type: "http",
1054
+ scheme: "bearer",
1055
+ bearerFormat: "JWT",
1056
+ description: "JWT token authentication"
1057
+ }
1058
+ }
1059
+ },
1060
+ security: [
1061
+ {
1062
+ bearerAuth: []
1063
+ }
1064
+ ],
1065
+ paths: {}
1066
+ };
1067
+ return openApiSpec;
1068
+ }
958
1069
  };
959
1070
  cli().register(GenerateApiDocsCommand);
960
1071
  // Annotate the CommonJS export names for ESM import in node: