@devbro/pashmak 0.1.47 → 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.
- package/dist/DatabaseServiceProvider.d.mts +4 -1
- package/dist/DatabaseServiceProvider.mjs +5 -2
- package/dist/DatabaseServiceProvider.mjs.map +1 -1
- package/dist/app/console/StartCommand.d.mts +1 -0
- package/dist/app/console/StartCommand.mjs +5 -2
- package/dist/app/console/StartCommand.mjs.map +1 -1
- package/dist/app/console/generate/GenerateApiDocsCommand.d.mts +34 -2
- package/dist/app/console/generate/GenerateApiDocsCommand.mjs +183 -100
- package/dist/app/console/generate/GenerateApiDocsCommand.mjs.map +1 -1
- package/dist/app/console/project/base_project/src/config/storages.ts.tpl +2 -2
- package/dist/bin/DatabaseServiceProvider.cjs +8 -2
- package/dist/bin/app/console/DefaultCommand.cjs +64 -32
- package/dist/bin/app/console/KeyGenerateCommand.cjs +64 -32
- package/dist/bin/app/console/StartCommand.cjs +69 -34
- package/dist/bin/app/console/generate/GenerateApiDocsCommand.cjs +248 -133
- package/dist/bin/app/console/generate/GenerateControllerCommand.cjs +64 -32
- package/dist/bin/app/console/generate/index.cjs +248 -133
- package/dist/bin/app/console/index.cjs +253 -135
- package/dist/bin/app/console/migrate/GenerateMigrateCommand.cjs +64 -32
- package/dist/bin/app/console/migrate/MigrateCommand.cjs +64 -32
- package/dist/bin/app/console/migrate/MigrateRollbackCommand.cjs +64 -32
- package/dist/bin/app/console/migrate/index.cjs +64 -32
- package/dist/bin/app/console/queue/GenerateQueueMigrateCommand.cjs +64 -32
- package/dist/bin/cache.cjs +64 -32
- package/dist/bin/facades.cjs +64 -32
- package/dist/bin/factories.cjs +64 -32
- package/dist/bin/http.cjs +739 -0
- package/dist/bin/index.cjs +264 -141
- package/dist/bin/middlewares.cjs +66 -34
- package/dist/bin/queue.cjs +64 -32
- package/dist/bin/router.cjs +4 -8
- package/dist/config.d.mts +0 -1
- package/dist/facades.mjs +2 -13
- package/dist/facades.mjs.map +1 -1
- package/dist/factories.mjs +45 -2
- package/dist/factories.mjs.map +1 -1
- package/dist/http.d.mts +4 -0
- package/dist/http.mjs +20 -0
- package/dist/http.mjs.map +1 -1
- package/dist/queue.d.mts +1 -1
- package/dist/queue.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bin/index.cjs
CHANGED
|
@@ -89,13 +89,14 @@ var init_MiddlewareFactory = __esm({
|
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
// ../neko-router/dist/CompiledRoute.mjs
|
|
92
|
-
var import_stream, CompiledRoute;
|
|
92
|
+
var import_stream, import_neko_helper, CompiledRoute;
|
|
93
93
|
var init_CompiledRoute = __esm({
|
|
94
94
|
"../neko-router/dist/CompiledRoute.mjs"() {
|
|
95
95
|
"use strict";
|
|
96
96
|
import_stream = require("stream");
|
|
97
97
|
init_Middleware();
|
|
98
98
|
init_MiddlewareFactory();
|
|
99
|
+
import_neko_helper = require("@devbro/neko-helper");
|
|
99
100
|
CompiledRoute = class {
|
|
100
101
|
static {
|
|
101
102
|
__name(this, "CompiledRoute");
|
|
@@ -116,7 +117,7 @@ var init_CompiledRoute = __esm({
|
|
|
116
117
|
for (const middleware of [...this.globalMiddlewares, ...this.route.getMiddlewares()]) {
|
|
117
118
|
if (middleware instanceof Middleware) {
|
|
118
119
|
this.middlewares.push(middleware);
|
|
119
|
-
} else if (
|
|
120
|
+
} else if ((0, import_neko_helper.isClass)(middleware)) {
|
|
120
121
|
this.middlewares.push(middleware.getInstance({}));
|
|
121
122
|
} else if (typeof middleware === "function") {
|
|
122
123
|
this.middlewares.push(MiddlewareFactory.create(middleware));
|
|
@@ -125,13 +126,8 @@ var init_CompiledRoute = __esm({
|
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
}
|
|
128
|
-
isClass(func) {
|
|
129
|
-
return typeof func === "function" && /^class\s/.test(Function.prototype.toString.call(func));
|
|
130
|
-
}
|
|
131
129
|
async run() {
|
|
132
|
-
|
|
133
|
-
this.response.end();
|
|
134
|
-
return rc;
|
|
130
|
+
return await this.runMiddlewares(this.middlewares, this.request, this.response);
|
|
135
131
|
}
|
|
136
132
|
prepareOutputJsonFormat(obj) {
|
|
137
133
|
function traverse(value) {
|
|
@@ -278,7 +274,7 @@ var init_Route = __esm({
|
|
|
278
274
|
i = start;
|
|
279
275
|
} else if (char === "*") {
|
|
280
276
|
let start = i + 1;
|
|
281
|
-
while (start < path10.length && /[a-zA-Z0-9_
|
|
277
|
+
while (start < path10.length && /[a-zA-Z0-9_]/.test(path10[start])) {
|
|
282
278
|
start++;
|
|
283
279
|
}
|
|
284
280
|
tokens.push({ type: "WILDCARD", value: path10.slice(i + 1, start) });
|
|
@@ -557,10 +553,29 @@ var init_router = __esm({
|
|
|
557
553
|
|
|
558
554
|
// src/http.mts
|
|
559
555
|
var http_exports = {};
|
|
556
|
+
__export(http_exports, {
|
|
557
|
+
handleHttpErrors: () => handleHttpErrors
|
|
558
|
+
});
|
|
559
|
+
async function handleHttpErrors(err, req, res) {
|
|
560
|
+
if (err instanceof import_neko_http.HttpError) {
|
|
561
|
+
res.writeHead(err.statusCode, { "Content-Type": "application/json" });
|
|
562
|
+
res.write(JSON.stringify({ message: err.message, error: err.code }));
|
|
563
|
+
logger().warn({ msg: "HttpError: " + err.message, err });
|
|
564
|
+
return;
|
|
565
|
+
} else {
|
|
566
|
+
logger().error({ msg: "Error: " + err.message, err });
|
|
567
|
+
}
|
|
568
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
569
|
+
res.write(JSON.stringify({ error: "Internal Server Error" }));
|
|
570
|
+
}
|
|
571
|
+
var import_neko_http;
|
|
560
572
|
var init_http = __esm({
|
|
561
573
|
"src/http.mts"() {
|
|
562
574
|
"use strict";
|
|
575
|
+
import_neko_http = require("@devbro/neko-http");
|
|
576
|
+
init_facades();
|
|
563
577
|
__reExport(http_exports, require("@devbro/neko-http"));
|
|
578
|
+
__name(handleHttpErrors, "handleHttpErrors");
|
|
564
579
|
}
|
|
565
580
|
});
|
|
566
581
|
|
|
@@ -569,13 +584,13 @@ var queue_exports = {};
|
|
|
569
584
|
__export(queue_exports, {
|
|
570
585
|
DatabaseTransport: () => DatabaseTransport
|
|
571
586
|
});
|
|
572
|
-
var
|
|
587
|
+
var import_neko_helper2, import_neko_context2, DatabaseTransport;
|
|
573
588
|
var init_queue = __esm({
|
|
574
589
|
"src/queue.mts"() {
|
|
575
590
|
"use strict";
|
|
576
591
|
__reExport(queue_exports, require("@devbro/neko-queue"));
|
|
577
592
|
init_facades();
|
|
578
|
-
|
|
593
|
+
import_neko_helper2 = require("@devbro/neko-helper");
|
|
579
594
|
import_neko_context2 = require("@devbro/neko-context");
|
|
580
595
|
DatabaseTransport = class {
|
|
581
596
|
static {
|
|
@@ -636,7 +651,7 @@ var init_queue = __esm({
|
|
|
636
651
|
}, "processMessage");
|
|
637
652
|
constructor(config11 = {}) {
|
|
638
653
|
this.config = { ...this.config, ...config11 };
|
|
639
|
-
this.repeater = (0,
|
|
654
|
+
this.repeater = (0, import_neko_helper2.createRepeater)(
|
|
640
655
|
this.processMessage,
|
|
641
656
|
this.config.listen_interval * 1e3
|
|
642
657
|
);
|
|
@@ -713,6 +728,24 @@ var init_factories = __esm({
|
|
|
713
728
|
import_neko_queue.QueueTransportFactory.register("memory", (opt) => {
|
|
714
729
|
return new import_neko_queue.MemoryTransport(opt);
|
|
715
730
|
});
|
|
731
|
+
import_neko_queue.QueueTransportFactory.register("sqs", (opt) => {
|
|
732
|
+
return new import_neko_queue.AwsSqsTransport(opt);
|
|
733
|
+
});
|
|
734
|
+
import_neko_queue.QueueTransportFactory.register("amqp", (opt) => {
|
|
735
|
+
return new import_neko_queue.AmqpTransport(opt);
|
|
736
|
+
});
|
|
737
|
+
import_neko_queue.QueueTransportFactory.register("redis", (opt) => {
|
|
738
|
+
return new import_neko_queue.RedisTransport(opt);
|
|
739
|
+
});
|
|
740
|
+
import_neko_queue.QueueTransportFactory.register("async", (opt) => {
|
|
741
|
+
return new import_neko_queue.AsyncTransport();
|
|
742
|
+
});
|
|
743
|
+
import_neko_queue.QueueTransportFactory.register("azure_service_bus", (opt) => {
|
|
744
|
+
return new import_neko_queue.AzureServiceBusTransport(opt);
|
|
745
|
+
});
|
|
746
|
+
import_neko_queue.QueueTransportFactory.register("google_pubsub", (opt) => {
|
|
747
|
+
return new import_neko_queue.GooglePubSubTransport(opt);
|
|
748
|
+
});
|
|
716
749
|
CacheProviderFactory = class _CacheProviderFactory {
|
|
717
750
|
static {
|
|
718
751
|
__name(this, "CacheProviderFactory");
|
|
@@ -743,17 +776,29 @@ var init_factories = __esm({
|
|
|
743
776
|
import_neko_storage.StorageProviderFactory.register("s3", (opt) => {
|
|
744
777
|
return new import_neko_storage.AWSS3StorageProvider(opt);
|
|
745
778
|
});
|
|
779
|
+
import_neko_storage.StorageProviderFactory.register("gcp", (opt) => {
|
|
780
|
+
return new import_neko_storage.GCPStorageProvider(opt);
|
|
781
|
+
});
|
|
782
|
+
import_neko_storage.StorageProviderFactory.register("azure", (opt) => {
|
|
783
|
+
return new import_neko_storage.AzureBlobStorageProvider(opt);
|
|
784
|
+
});
|
|
785
|
+
import_neko_storage.StorageProviderFactory.register("ftp", (opt) => {
|
|
786
|
+
return new import_neko_storage.FTPStorageProvider(opt);
|
|
787
|
+
});
|
|
788
|
+
import_neko_storage.StorageProviderFactory.register("sftp", (opt) => {
|
|
789
|
+
return new import_neko_storage.SFTPStorageProvider(opt);
|
|
790
|
+
});
|
|
746
791
|
}
|
|
747
792
|
});
|
|
748
793
|
|
|
749
794
|
// src/facades.mts
|
|
750
|
-
var import_neko_scheduler,
|
|
795
|
+
var import_neko_scheduler, import_neko_helper3, import_neko_context3, import_neko_storage2, import_neko_mailer2, import_neko_config, import_clipanion, import_neko_logger, import_neko_cache2, import_neko_queue2, router, scheduler, db, storage, cli, httpServer, logger, mailer, queue, cache;
|
|
751
796
|
var init_facades = __esm({
|
|
752
797
|
"src/facades.mts"() {
|
|
753
798
|
"use strict";
|
|
754
799
|
init_router();
|
|
755
800
|
import_neko_scheduler = require("@devbro/neko-scheduler");
|
|
756
|
-
|
|
801
|
+
import_neko_helper3 = require("@devbro/neko-helper");
|
|
757
802
|
import_neko_context3 = require("@devbro/neko-context");
|
|
758
803
|
import_neko_storage2 = require("@devbro/neko-storage");
|
|
759
804
|
import_neko_mailer2 = require("@devbro/neko-mailer");
|
|
@@ -764,8 +809,8 @@ var init_facades = __esm({
|
|
|
764
809
|
init_factories();
|
|
765
810
|
import_neko_cache2 = require("@devbro/neko-cache");
|
|
766
811
|
import_neko_queue2 = require("@devbro/neko-queue");
|
|
767
|
-
router = (0,
|
|
768
|
-
scheduler = (0,
|
|
812
|
+
router = (0, import_neko_helper3.createSingleton)(() => new Router());
|
|
813
|
+
scheduler = (0, import_neko_helper3.createSingleton)(() => {
|
|
769
814
|
const rc = new import_neko_scheduler.Scheduler();
|
|
770
815
|
rc.setErrorHandler((err, job) => {
|
|
771
816
|
logger().error({
|
|
@@ -777,7 +822,7 @@ var init_facades = __esm({
|
|
|
777
822
|
return rc;
|
|
778
823
|
});
|
|
779
824
|
db = /* @__PURE__ */ __name((label = "default") => (0, import_neko_context3.ctx)().getOrThrow(["database", label]), "db");
|
|
780
|
-
storage = (0,
|
|
825
|
+
storage = (0, import_neko_helper3.createSingleton)((label = "default") => {
|
|
781
826
|
let storage_config = import_neko_config.config.get(["storages", label].join("."));
|
|
782
827
|
const provider = import_neko_storage2.StorageProviderFactory.create(
|
|
783
828
|
storage_config.provider,
|
|
@@ -785,7 +830,7 @@ var init_facades = __esm({
|
|
|
785
830
|
);
|
|
786
831
|
return new import_neko_storage2.Storage(provider);
|
|
787
832
|
});
|
|
788
|
-
cli = (0,
|
|
833
|
+
cli = (0, import_neko_helper3.createSingleton)(() => {
|
|
789
834
|
const [node, app, ...args] = process.argv;
|
|
790
835
|
return new import_clipanion.Cli({
|
|
791
836
|
binaryLabel: `My Application`,
|
|
@@ -793,24 +838,13 @@ var init_facades = __esm({
|
|
|
793
838
|
binaryVersion: `1.0.0`
|
|
794
839
|
});
|
|
795
840
|
});
|
|
796
|
-
httpServer = (0,
|
|
841
|
+
httpServer = (0, import_neko_helper3.createSingleton)(() => {
|
|
797
842
|
const server = new http_exports.HttpServer();
|
|
798
|
-
server.setErrorHandler(
|
|
799
|
-
if (err instanceof http_exports.HttpError) {
|
|
800
|
-
res.writeHead(err.statusCode, { "Content-Type": "application/json" });
|
|
801
|
-
res.end(JSON.stringify({ message: err.message, error: err.code }));
|
|
802
|
-
logger().warn({ msg: "HttpError: " + err.message, err });
|
|
803
|
-
return;
|
|
804
|
-
} else {
|
|
805
|
-
logger().error({ msg: "Error: " + err.message, err });
|
|
806
|
-
}
|
|
807
|
-
res.writeHead(500, { "Content-Type": "" });
|
|
808
|
-
res.end(JSON.stringify({ error: "Internal Server Error" }));
|
|
809
|
-
});
|
|
843
|
+
server.setErrorHandler(handleHttpErrors);
|
|
810
844
|
server.setRouter(router());
|
|
811
845
|
return server;
|
|
812
846
|
});
|
|
813
|
-
logger = (0,
|
|
847
|
+
logger = (0, import_neko_helper3.createSingleton)((label) => {
|
|
814
848
|
const logger_config = import_neko_config.config.get(["loggers", label].join("."));
|
|
815
849
|
const rc = new import_neko_logger.Logger(logger_config);
|
|
816
850
|
rc.setExtrasFunction((message) => {
|
|
@@ -819,7 +853,7 @@ var init_facades = __esm({
|
|
|
819
853
|
});
|
|
820
854
|
return rc;
|
|
821
855
|
});
|
|
822
|
-
mailer = (0,
|
|
856
|
+
mailer = (0, import_neko_helper3.createSingleton)((label) => {
|
|
823
857
|
const mailer_config = import_neko_config.config.get(["mailer", label].join("."));
|
|
824
858
|
const provider = import_neko_mailer2.MailerProviderFactory.create(
|
|
825
859
|
mailer_config.provider,
|
|
@@ -828,7 +862,7 @@ var init_facades = __esm({
|
|
|
828
862
|
const rc = new import_neko_mailer2.Mailer(provider);
|
|
829
863
|
return rc;
|
|
830
864
|
});
|
|
831
|
-
queue = (0,
|
|
865
|
+
queue = (0, import_neko_helper3.createSingleton)((label) => {
|
|
832
866
|
const queue_config = import_neko_config.config.get(["queues", label].join("."));
|
|
833
867
|
if (!queue_config) {
|
|
834
868
|
throw new Error(`Queue configuration for '${label}' not found`);
|
|
@@ -839,7 +873,7 @@ var init_facades = __esm({
|
|
|
839
873
|
);
|
|
840
874
|
return new import_neko_queue2.QueueConnection(provider);
|
|
841
875
|
});
|
|
842
|
-
cache = (0,
|
|
876
|
+
cache = (0, import_neko_helper3.createSingleton)((label) => {
|
|
843
877
|
const cache_config = import_neko_config.config.get(["caches", label].join("."));
|
|
844
878
|
if (!cache_config) {
|
|
845
879
|
throw new Error(`Cache configuration for '${label}' not found`);
|
|
@@ -2254,12 +2288,15 @@ var init_StartCommand = __esm({
|
|
|
2254
2288
|
__name(this, "StartCommand");
|
|
2255
2289
|
}
|
|
2256
2290
|
scheduler = import_clipanion5.Option.Boolean(`--scheduler`, false);
|
|
2291
|
+
cron = import_clipanion5.Option.Boolean(`--cron`, false);
|
|
2257
2292
|
http = import_clipanion5.Option.Boolean(`--http`, false);
|
|
2258
2293
|
queue = import_clipanion5.Option.Boolean(`--queue`, false);
|
|
2259
2294
|
all = import_clipanion5.Option.Boolean("--all", false);
|
|
2260
2295
|
static paths = [[`start`]];
|
|
2261
2296
|
async execute() {
|
|
2262
|
-
if ([this.all, this.http, this.scheduler, this.queue].filter(
|
|
2297
|
+
if ([this.all, this.http, this.scheduler || this.cron, this.queue].filter(
|
|
2298
|
+
(x) => x
|
|
2299
|
+
).length == 0) {
|
|
2263
2300
|
this.context.stdout.write(
|
|
2264
2301
|
`No service was selected. please check -h for details
|
|
2265
2302
|
`
|
|
@@ -2269,7 +2306,7 @@ var init_StartCommand = __esm({
|
|
|
2269
2306
|
logger().info(`Starting Server
|
|
2270
2307
|
`);
|
|
2271
2308
|
import_neko_sql.PostgresqlConnection.defaults.idleTimeoutMillis = 1e4;
|
|
2272
|
-
if (this.scheduler || this.all) {
|
|
2309
|
+
if (this.scheduler || this.cron || this.all) {
|
|
2273
2310
|
logger().info(`starting scheduler
|
|
2274
2311
|
`);
|
|
2275
2312
|
scheduler().start();
|
|
@@ -2490,7 +2527,7 @@ var init_config = __esm({
|
|
|
2490
2527
|
});
|
|
2491
2528
|
|
|
2492
2529
|
// src/app/console/generate/GenerateApiDocsCommand.mts
|
|
2493
|
-
var import_clipanion9, import_path7, fs6,
|
|
2530
|
+
var import_clipanion9, import_path7, fs6, import_neko_helper4, GenerateApiDocsCommand;
|
|
2494
2531
|
var init_GenerateApiDocsCommand = __esm({
|
|
2495
2532
|
"src/app/console/generate/GenerateApiDocsCommand.mts"() {
|
|
2496
2533
|
"use strict";
|
|
@@ -2499,144 +2536,155 @@ var init_GenerateApiDocsCommand = __esm({
|
|
|
2499
2536
|
import_path7 = __toESM(require("path"), 1);
|
|
2500
2537
|
fs6 = __toESM(require("fs/promises"), 1);
|
|
2501
2538
|
init_config();
|
|
2502
|
-
|
|
2539
|
+
import_neko_helper4 = require("@devbro/neko-helper");
|
|
2503
2540
|
GenerateApiDocsCommand = class extends import_clipanion9.Command {
|
|
2504
2541
|
static {
|
|
2505
2542
|
__name(this, "GenerateApiDocsCommand");
|
|
2506
2543
|
}
|
|
2507
|
-
static paths = [
|
|
2508
|
-
[`make`, `apidocs`],
|
|
2509
|
-
[`generate`, `apidocs`]
|
|
2510
|
-
];
|
|
2544
|
+
static paths = [[`generate`, `apidocsv2`]];
|
|
2511
2545
|
static usage = import_clipanion9.Command.Usage({
|
|
2512
2546
|
category: `Generate`,
|
|
2513
2547
|
description: `Generate OpenAPI documentation from routes`,
|
|
2514
2548
|
details: `
|
|
2515
|
-
This command generates OpenAPI 3.0 specification documentation by analyzing
|
|
2549
|
+
This command utility generates OpenAPI 3.0 specification documentation by analyzing
|
|
2516
2550
|
your application's routes and merging with example files.
|
|
2517
2551
|
|
|
2518
|
-
|
|
2519
|
-
-
|
|
2520
|
-
-
|
|
2521
|
-
-
|
|
2522
|
-
- Response schemas
|
|
2523
|
-
|
|
2524
|
-
The command will merge files specified in config.api_docs.merge_files
|
|
2525
|
-
and output the final documentation to config.api_docs.output.
|
|
2552
|
+
Subcommands:
|
|
2553
|
+
- generate-from-routes: Generate OpenAPI spec from registered routes
|
|
2554
|
+
- generate-base: Generate base OpenAPI specification structure
|
|
2555
|
+
- merge-files: Merge multiple OpenAPI files into final documentation
|
|
2526
2556
|
|
|
2557
|
+
|
|
2527
2558
|
This command depends on config data. make sure your default config contains the following:
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2559
|
+
|
|
2560
|
+
\`\`\`
|
|
2561
|
+
api_docs: {
|
|
2562
|
+
|
|
2563
|
+
merge_files: [
|
|
2564
|
+
|
|
2565
|
+
path.join(__dirname, '../..', 'private', 'openapi_base.json'),
|
|
2566
|
+
|
|
2567
|
+
path.join(__dirname, '../..', 'private', 'openapi_from_routes.json'),
|
|
2568
|
+
|
|
2569
|
+
path.join(__dirname, '../..', 'private', 'openapi_from_tests.json'),
|
|
2570
|
+
|
|
2571
|
+
path.join(__dirname, '../..', 'private', 'openapi_other_user_changes.json'),
|
|
2572
|
+
|
|
2573
|
+
],
|
|
2574
|
+
|
|
2575
|
+
output: path.join(__dirname, '../..', 'public', 'openapi.json'),
|
|
2576
|
+
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2579
|
+
\`\`\`
|
|
2536
2580
|
`,
|
|
2537
|
-
examples: [
|
|
2581
|
+
examples: [
|
|
2582
|
+
[
|
|
2583
|
+
`Generate from routes`,
|
|
2584
|
+
`$0 generate apidocsv2 generate-from-routes --output path/to/output.json`
|
|
2585
|
+
],
|
|
2586
|
+
[
|
|
2587
|
+
`Generate base spec`,
|
|
2588
|
+
`$0 generate apidocsv2 generate-base --output path/to/output.json`
|
|
2589
|
+
],
|
|
2590
|
+
[`Merge files`, `$0 generate apidocsv2 merge-files`],
|
|
2591
|
+
[`Show help`, `$0 generate apidocsv2 --help`]
|
|
2592
|
+
]
|
|
2593
|
+
});
|
|
2594
|
+
subcommand = import_clipanion9.Option.String({ required: false });
|
|
2595
|
+
output = import_clipanion9.Option.String(`--output,-o`, {
|
|
2596
|
+
description: `Output file path for generated documentation`
|
|
2538
2597
|
});
|
|
2539
|
-
|
|
2540
|
-
description: `
|
|
2598
|
+
config = import_clipanion9.Option.String(`--config,-c`, {
|
|
2599
|
+
description: `Path in config to get details from (default: api_docs)`,
|
|
2600
|
+
required: false
|
|
2541
2601
|
});
|
|
2542
2602
|
async execute() {
|
|
2543
|
-
if (this.
|
|
2603
|
+
if (!this.subcommand) {
|
|
2544
2604
|
this.context.stdout.write(
|
|
2545
2605
|
this.constructor.usage?.toString() || "No help available\n"
|
|
2546
2606
|
);
|
|
2547
2607
|
return 0;
|
|
2548
2608
|
}
|
|
2549
|
-
|
|
2550
|
-
|
|
2609
|
+
switch (this.subcommand) {
|
|
2610
|
+
case "generate-from-routes":
|
|
2611
|
+
return await this.executeGenerateFromRoutes();
|
|
2612
|
+
case "generate-base":
|
|
2613
|
+
return await this.executeGenerateBase();
|
|
2614
|
+
case "merge-files":
|
|
2615
|
+
return await this.executeMergeFiles();
|
|
2616
|
+
default:
|
|
2617
|
+
this.context.stderr.write(`Unknown subcommand: ${this.subcommand}
|
|
2551
2618
|
`);
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
title: "API Documentation",
|
|
2557
|
-
version: "1.0.0",
|
|
2558
|
-
description: "Auto-generated API documentation"
|
|
2559
|
-
},
|
|
2560
|
-
servers: [
|
|
2561
|
-
{
|
|
2562
|
-
url: "/",
|
|
2563
|
-
description: "Local server"
|
|
2564
|
-
}
|
|
2565
|
-
],
|
|
2566
|
-
paths: {}
|
|
2567
|
-
};
|
|
2568
|
-
for (const route of routes) {
|
|
2569
|
-
const routePath = route.path;
|
|
2570
|
-
const openApiPath = routePath.replace(/:([a-zA-Z0-9_]+)/g, "{$1}");
|
|
2571
|
-
if (!openApiSpec.paths[openApiPath]) {
|
|
2572
|
-
openApiSpec.paths[openApiPath] = {};
|
|
2573
|
-
}
|
|
2574
|
-
for (const method of route.methods) {
|
|
2575
|
-
const lowerMethod = method.toLowerCase();
|
|
2576
|
-
if (lowerMethod === "head") {
|
|
2577
|
-
continue;
|
|
2578
|
-
}
|
|
2579
|
-
openApiSpec.paths[openApiPath][lowerMethod] = {
|
|
2580
|
-
summary: `${method} ${routePath}`,
|
|
2581
|
-
description: `Endpoint for ${method} ${routePath}`,
|
|
2582
|
-
parameters: this.extractParameters(routePath),
|
|
2583
|
-
responses: {
|
|
2584
|
-
"200": {
|
|
2585
|
-
description: "Successful response",
|
|
2586
|
-
content: {
|
|
2587
|
-
"application/json": {
|
|
2588
|
-
schema: {
|
|
2589
|
-
type: "object"
|
|
2590
|
-
}
|
|
2591
|
-
}
|
|
2592
|
-
}
|
|
2593
|
-
},
|
|
2594
|
-
"500": {
|
|
2595
|
-
description: "Internal server error"
|
|
2596
|
-
}
|
|
2597
|
-
}
|
|
2598
|
-
};
|
|
2599
|
-
if (["post", "put", "patch"].includes(lowerMethod)) {
|
|
2600
|
-
openApiSpec.paths[openApiPath][lowerMethod].requestBody = {
|
|
2601
|
-
required: true,
|
|
2602
|
-
content: {
|
|
2603
|
-
"application/json": {
|
|
2604
|
-
schema: {
|
|
2605
|
-
type: "object"
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
2608
|
-
}
|
|
2609
|
-
};
|
|
2610
|
-
}
|
|
2611
|
-
}
|
|
2619
|
+
this.context.stdout.write(
|
|
2620
|
+
this.constructor.usage?.toString() || "No help available\n"
|
|
2621
|
+
);
|
|
2622
|
+
return 1;
|
|
2612
2623
|
}
|
|
2613
|
-
|
|
2614
|
-
|
|
2624
|
+
}
|
|
2625
|
+
async executeGenerateFromRoutes() {
|
|
2626
|
+
this.context.stdout.write(
|
|
2627
|
+
`Generating OpenAPI documentation from routes...
|
|
2628
|
+
`
|
|
2629
|
+
);
|
|
2630
|
+
const openApiSpec = this.generateFromRoutes();
|
|
2631
|
+
const outputPath = this.output || import_path7.default.join(config_exports.config.get("private_path"), "openapi_from_routes.json");
|
|
2632
|
+
await fs6.mkdir(import_path7.default.dirname(outputPath), { recursive: true });
|
|
2615
2633
|
await fs6.writeFile(
|
|
2616
2634
|
outputPath,
|
|
2617
2635
|
JSON.stringify(openApiSpec, null, 2),
|
|
2618
2636
|
"utf-8"
|
|
2619
2637
|
);
|
|
2620
2638
|
this.context.stdout.write(
|
|
2621
|
-
`OpenAPI documentation generated at: ${outputPath}
|
|
2639
|
+
`OpenAPI routes documentation generated at: ${outputPath}
|
|
2622
2640
|
`
|
|
2623
2641
|
);
|
|
2624
|
-
this.context.stdout.write(
|
|
2642
|
+
this.context.stdout.write(
|
|
2643
|
+
`Total routes documented: ${Object.keys(openApiSpec.paths).length}
|
|
2644
|
+
`
|
|
2645
|
+
);
|
|
2646
|
+
return 0;
|
|
2647
|
+
}
|
|
2648
|
+
async executeGenerateBase() {
|
|
2649
|
+
this.context.stdout.write(`Generating base OpenAPI specification...
|
|
2625
2650
|
`);
|
|
2626
|
-
|
|
2651
|
+
const baseSpec = this.getBaseOpenApiSpec();
|
|
2652
|
+
const outputPath = this.output || import_path7.default.join(config_exports.config.get("private_path"), "openapi_base.json");
|
|
2653
|
+
await fs6.mkdir(import_path7.default.dirname(outputPath), { recursive: true });
|
|
2654
|
+
await fs6.writeFile(outputPath, JSON.stringify(baseSpec, null, 2), "utf-8");
|
|
2655
|
+
this.context.stdout.write(
|
|
2656
|
+
`Base OpenAPI specification generated at: ${outputPath}
|
|
2657
|
+
`
|
|
2658
|
+
);
|
|
2659
|
+
return 0;
|
|
2660
|
+
}
|
|
2661
|
+
async executeMergeFiles() {
|
|
2662
|
+
this.context.stdout.write(`Merging OpenAPI files...
|
|
2663
|
+
`);
|
|
2664
|
+
let configPath = this.config || "api_docs";
|
|
2665
|
+
const files_to_merge = config_exports.config.get(`${configPath}.merge_files`);
|
|
2627
2666
|
let final_api_docs = {};
|
|
2628
|
-
for (
|
|
2629
|
-
|
|
2630
|
-
|
|
2667
|
+
for (const file_path of files_to_merge) {
|
|
2668
|
+
try {
|
|
2669
|
+
const file_json = JSON.parse(await fs6.readFile(file_path, "utf8"));
|
|
2670
|
+
final_api_docs = import_neko_helper4.Arr.deepMerge(final_api_docs, file_json);
|
|
2671
|
+
this.context.stdout.write(` Merged: ${file_path}
|
|
2672
|
+
`);
|
|
2673
|
+
} catch (error) {
|
|
2674
|
+
this.context.stderr.write(
|
|
2675
|
+
` Warning: Could not read ${file_path}: ${error.message}
|
|
2676
|
+
`
|
|
2677
|
+
);
|
|
2678
|
+
}
|
|
2631
2679
|
}
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
);
|
|
2680
|
+
const outputPath = this.output || config_exports.config.get(`${configPath}.output`);
|
|
2681
|
+
await fs6.mkdir(import_path7.default.dirname(outputPath), { recursive: true });
|
|
2682
|
+
await fs6.writeFile(outputPath, JSON.stringify(final_api_docs, null, 2));
|
|
2636
2683
|
this.context.stdout.write(
|
|
2637
|
-
`
|
|
2684
|
+
`Final OpenAPI document written to: ${outputPath}
|
|
2638
2685
|
`
|
|
2639
2686
|
);
|
|
2687
|
+
return 0;
|
|
2640
2688
|
}
|
|
2641
2689
|
extractParameters(routePath) {
|
|
2642
2690
|
const paramRegex = /:([a-zA-Z0-9_]+)/g;
|
|
@@ -2655,6 +2703,78 @@ var init_GenerateApiDocsCommand = __esm({
|
|
|
2655
2703
|
}
|
|
2656
2704
|
return parameters;
|
|
2657
2705
|
}
|
|
2706
|
+
generateFromRoutes() {
|
|
2707
|
+
const openApiSpec = {
|
|
2708
|
+
paths: {}
|
|
2709
|
+
};
|
|
2710
|
+
const routes = router().routes;
|
|
2711
|
+
for (const route of routes) {
|
|
2712
|
+
const routePath = route.path;
|
|
2713
|
+
const openApiPath = routePath.replace(/\/$/g, "");
|
|
2714
|
+
if (!openApiSpec.paths[openApiPath]) {
|
|
2715
|
+
openApiSpec.paths[openApiPath] = {};
|
|
2716
|
+
}
|
|
2717
|
+
for (const method of route.methods) {
|
|
2718
|
+
const lowerMethod = method.toLowerCase();
|
|
2719
|
+
if (lowerMethod === "head") {
|
|
2720
|
+
continue;
|
|
2721
|
+
}
|
|
2722
|
+
openApiSpec.paths[openApiPath][lowerMethod] = {
|
|
2723
|
+
summary: `${routePath}`,
|
|
2724
|
+
description: `Endpoint for ${method} ${routePath}`,
|
|
2725
|
+
security: [],
|
|
2726
|
+
parameters: this.extractParameters(routePath),
|
|
2727
|
+
responses: {}
|
|
2728
|
+
};
|
|
2729
|
+
if (["post", "put", "patch"].includes(lowerMethod)) {
|
|
2730
|
+
openApiSpec.paths[openApiPath][lowerMethod].requestBody = {
|
|
2731
|
+
required: true,
|
|
2732
|
+
content: {
|
|
2733
|
+
"application/json": {
|
|
2734
|
+
schema: {
|
|
2735
|
+
type: "object"
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
};
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
return openApiSpec;
|
|
2744
|
+
}
|
|
2745
|
+
getBaseOpenApiSpec() {
|
|
2746
|
+
const openApiSpec = {
|
|
2747
|
+
openapi: "3.0.0",
|
|
2748
|
+
info: {
|
|
2749
|
+
title: "API Documentation",
|
|
2750
|
+
version: "1.0.0",
|
|
2751
|
+
description: "Auto-generated API documentation"
|
|
2752
|
+
},
|
|
2753
|
+
servers: [
|
|
2754
|
+
{
|
|
2755
|
+
url: "/",
|
|
2756
|
+
description: "Local server"
|
|
2757
|
+
}
|
|
2758
|
+
],
|
|
2759
|
+
components: {
|
|
2760
|
+
securitySchemes: {
|
|
2761
|
+
bearerAuth: {
|
|
2762
|
+
type: "http",
|
|
2763
|
+
scheme: "bearer",
|
|
2764
|
+
bearerFormat: "JWT",
|
|
2765
|
+
description: "JWT token authentication"
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
},
|
|
2769
|
+
security: [
|
|
2770
|
+
{
|
|
2771
|
+
bearerAuth: []
|
|
2772
|
+
}
|
|
2773
|
+
],
|
|
2774
|
+
paths: {}
|
|
2775
|
+
};
|
|
2776
|
+
return openApiSpec;
|
|
2777
|
+
}
|
|
2658
2778
|
};
|
|
2659
2779
|
cli().register(GenerateApiDocsCommand);
|
|
2660
2780
|
}
|
|
@@ -3000,8 +3120,11 @@ var init_DatabaseServiceProvider = __esm({
|
|
|
3000
3120
|
return _DatabaseServiceProvider.instance;
|
|
3001
3121
|
}
|
|
3002
3122
|
getConnection(db_config) {
|
|
3003
|
-
|
|
3004
|
-
|
|
3123
|
+
if (db_config.provider === "postgresql") {
|
|
3124
|
+
const conn = new import_neko_sql2.PostgresqlConnection(db_config.config);
|
|
3125
|
+
return conn;
|
|
3126
|
+
}
|
|
3127
|
+
throw new Error(`Unsupported database provider: ${db_config.provider}`);
|
|
3005
3128
|
}
|
|
3006
3129
|
};
|
|
3007
3130
|
}
|