@devbro/pashmak 0.1.18 → 0.1.20
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/app/console/project/base_project/package.json.tpl +1 -1
- package/dist/app/console/project/base_project/src/app/models/index.ts.tpl +1 -0
- package/dist/app/console/project/base_project/src/config/caches.ts.tpl +7 -0
- package/dist/app/console/project/base_project/src/config/databases.ts.tpl +10 -6
- package/dist/app/console/project/base_project/src/config/default.mts.tpl +35 -0
- package/dist/app/console/project/base_project/src/config/loggers.ts.tpl +11 -7
- package/dist/app/console/project/base_project/src/config/mailer.ts.tpl +21 -1
- package/dist/app/console/project/base_project/src/config/queues.ts.tpl +7 -0
- package/dist/app/console/project/base_project/src/config/storages.ts.tpl +8 -4
- package/dist/app/console/project/base_project/tsconfig.json.tpl +7 -4
- package/dist/app/console/queue/queue_migration.tpl +2 -1
- package/dist/bin/app/console/DefaultCommand.cjs +53 -34
- package/dist/bin/app/console/KeyGenerateCommand.cjs +53 -34
- package/dist/bin/app/console/StartCommand.cjs +55 -36
- package/dist/bin/app/console/generate/GenerateControllerCommand.cjs +53 -34
- package/dist/bin/app/console/generate/index.cjs +53 -34
- package/dist/bin/app/console/index.cjs +54 -36
- package/dist/bin/app/console/migrate/GenerateMigrateCommand.cjs +53 -34
- package/dist/bin/app/console/migrate/MigrateCommand.cjs +52 -34
- package/dist/bin/app/console/migrate/MigrateRollbackCommand.cjs +52 -34
- package/dist/bin/app/console/migrate/index.cjs +52 -34
- package/dist/bin/app/console/queue/GenerateQueueMigrateCommand.cjs +53 -34
- package/dist/bin/cache.cjs +53 -34
- package/dist/bin/facades.cjs +52 -34
- package/dist/bin/factories.cjs +58 -39
- package/dist/bin/index.cjs +62 -43
- package/dist/bin/middlewares.cjs +52 -34
- package/dist/bin/queue.cjs +675 -18
- package/dist/facades.d.mts +2 -1
- package/dist/facades.mjs +12 -8
- package/dist/facades.mjs.map +1 -1
- package/dist/factories.d.mts +5 -5
- package/dist/factories.mjs +17 -10
- package/dist/factories.mjs.map +1 -1
- package/dist/queue.d.mts +8 -4
- package/dist/queue.mjs +26 -18
- package/dist/queue.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/app/console/project/base_project/src/app/models/README.md.tpl +0 -1
- package/dist/app/console/project/base_project/src/config/default.ts.tpl +0 -42
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"prepare": "husky",
|
|
20
20
|
"prettier": "prettier --write .",
|
|
21
21
|
"dev": "nodemon --watch src --ext ts,tsx,json --signal SIGTERM --exec \"clear && tsx -r tsconfig-paths/register src/index.ts start --all | npx pino-pretty\"",
|
|
22
|
-
"
|
|
22
|
+
"pdev": "tsx -r tsconfig-paths/register src/index.ts",
|
|
23
23
|
"clean": "rm -rf dist"
|
|
24
24
|
},
|
|
25
25
|
"author": "???",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// export all models from here
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
databases: {
|
|
3
|
+
default: {
|
|
4
|
+
host: process.env.DB_HOST,
|
|
5
|
+
database: process.env.DB_NAME || 'test_db',
|
|
6
|
+
user: process.env.DB_USER,
|
|
7
|
+
password: process.env.DB_PASSWORD,
|
|
8
|
+
port: parseInt(process.env.DB_PORT || '5432'),
|
|
9
|
+
name: 'db',
|
|
10
|
+
},
|
|
11
|
+
},
|
|
8
12
|
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import { getEnv } from '@devbro/pashmak/helper';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
|
|
10
|
+
const extends_list = ['databases', 'storages', 'mailer', 'loggers', 'queues', 'caches'];
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
extends: [...extends_list.map((i) => `./${i}.js`), ...extends_list.map((i) => `./${i}.ts`)],
|
|
14
|
+
port: getEnv('PORT', 3000),
|
|
15
|
+
file_upload_path: path.join(os.tmpdir(), ''),
|
|
16
|
+
migration: {
|
|
17
|
+
path: path.join(__dirname, '..', 'database/migrations'),
|
|
18
|
+
},
|
|
19
|
+
jwt: {
|
|
20
|
+
options: {
|
|
21
|
+
algorithm: 'RS256',
|
|
22
|
+
expiresIn: 8 * 3600,
|
|
23
|
+
},
|
|
24
|
+
refresh_options: {
|
|
25
|
+
algorithm: 'RS256',
|
|
26
|
+
expiresIn: 3 * 24 * 3600,
|
|
27
|
+
},
|
|
28
|
+
secret: '-----BEGIN PRIVATE KEY-----\n' + process.env.jwt_secret_private + '\n-----END PRIVATE KEY-----\n',
|
|
29
|
+
public: '-----BEGIN PUBLIC KEY-----\n' + process.env.jwt_secret_public + '\n-----END PUBLIC KEY-----\n',
|
|
30
|
+
public_retired:
|
|
31
|
+
'-----BEGIN PUBLIC KEY-----\n' + process.env.jwt_secret_public_retired + '\n-----END PUBLIC KEY-----\n',
|
|
32
|
+
},
|
|
33
|
+
public_path: path.join(__dirname, '../..', 'public'),
|
|
34
|
+
debug_mode: getEnv('APP_DEBUG', false),
|
|
35
|
+
};
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import { ctxSafe } from
|
|
2
|
-
import { LogMessage } from
|
|
1
|
+
import { ctxSafe } from '@devbro/pashmak/context';
|
|
2
|
+
import { LogMessage } from '@devbro/pashmak/logger';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
loggers: {
|
|
6
|
+
default: {
|
|
7
|
+
level: process.env.NODE_ENV === 'test' ? 'silent' : 'info',
|
|
8
|
+
extrasFunction: (message: LogMessage) => {
|
|
9
|
+
let requestId = ctxSafe()?.get('requestId');
|
|
10
|
+
requestId && (message.requestId = requestId);
|
|
11
|
+
return message;
|
|
12
|
+
},
|
|
13
|
+
},
|
|
10
14
|
},
|
|
11
15
|
};
|
|
@@ -1,3 +1,23 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
|
|
2
|
+
mailer: {
|
|
3
|
+
default: {
|
|
4
|
+
provider: 'MEMORY',
|
|
5
|
+
default_from: 'no-reply@devbro.com',
|
|
6
|
+
},
|
|
7
|
+
},
|
|
8
|
+
$prod: {
|
|
9
|
+
mailer: {
|
|
10
|
+
default: {
|
|
11
|
+
provider: 'SES',
|
|
12
|
+
// credentials are loaded as env vars
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
$test: {
|
|
17
|
+
mailer: {
|
|
18
|
+
default: {
|
|
19
|
+
provider: 'MEMORY',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
3
23
|
};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import os from
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import os from 'os';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
storages: {
|
|
6
|
+
default: {
|
|
7
|
+
engine: 'local',
|
|
8
|
+
basePath: path.join(os.tmpdir(), '/app-storage/'),
|
|
9
|
+
},
|
|
10
|
+
},
|
|
7
11
|
};
|
|
@@ -8,9 +8,7 @@
|
|
|
8
8
|
"module": "esnext" /* Specify what module code is generated. */,
|
|
9
9
|
"rootDir": "./src" /* Specify the root folder within your source files. */,
|
|
10
10
|
"moduleResolution": "bundler" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
|
11
|
-
"
|
|
12
|
-
"paths": {} /* Specify a set of entries that re-map imports to additional lookup locations. */,
|
|
13
|
-
"allowImportingTsExtensions": true /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */,
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
14
12
|
"allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */,
|
|
15
13
|
"emitDeclarationOnly": true /* Only output d.ts files and not JavaScript files. */,
|
|
16
14
|
"declaration": true,
|
|
@@ -18,6 +16,11 @@
|
|
|
18
16
|
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
|
19
17
|
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
|
20
18
|
"strict": true /* Enable all strict type-checking options. */,
|
|
21
|
-
"skipLibCheck": true
|
|
19
|
+
"skipLibCheck": true,
|
|
20
|
+
"baseUrl": "./src",
|
|
21
|
+
"paths": {
|
|
22
|
+
"app/*": ["./app/*"],
|
|
23
|
+
"@/*": ["./*"]
|
|
24
|
+
}
|
|
22
25
|
}
|
|
23
26
|
}
|
|
@@ -10,7 +10,8 @@ export default class {{className}} extends Migration {
|
|
|
10
10
|
table.text('message');
|
|
11
11
|
table.datetimeTz('last_tried_at').nullable(true);
|
|
12
12
|
table.text('process_message').default('');
|
|
13
|
-
table.
|
|
13
|
+
table.string('status').default('pending');
|
|
14
|
+
table.number('retried_count').default(0);
|
|
14
15
|
});
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -457,7 +457,7 @@ var Router = class {
|
|
|
457
457
|
var import_neko_scheduler = require("@devbro/neko-scheduler");
|
|
458
458
|
var import_neko_helper = require("@devbro/neko-helper");
|
|
459
459
|
var import_neko_context2 = require("@devbro/neko-context");
|
|
460
|
-
var
|
|
460
|
+
var import_neko_storage2 = require("@devbro/neko-storage");
|
|
461
461
|
var import_neko_mailer2 = require("@devbro/neko-mailer");
|
|
462
462
|
var import_neko_config = require("@devbro/neko-config");
|
|
463
463
|
var import_clipanion = require("clipanion");
|
|
@@ -481,31 +481,38 @@ __export(queue_exports, {
|
|
|
481
481
|
DatabaseTransport: () => DatabaseTransport
|
|
482
482
|
});
|
|
483
483
|
__reExport(queue_exports, require("@devbro/neko-queue"));
|
|
484
|
-
var import_neko_sql = require("@devbro/neko-sql");
|
|
485
484
|
var DatabaseTransport = class {
|
|
486
|
-
constructor(db_config) {
|
|
487
|
-
this.db_config = db_config;
|
|
488
|
-
}
|
|
489
485
|
static {
|
|
490
486
|
__name(this, "DatabaseTransport");
|
|
491
487
|
}
|
|
492
|
-
listenInterval = 6e4;
|
|
493
|
-
// default to 1 minute
|
|
494
|
-
messageLimit = 100;
|
|
495
|
-
// default to 100 messages per fetch
|
|
496
488
|
activeIntervals = /* @__PURE__ */ new Set();
|
|
489
|
+
config = {
|
|
490
|
+
queue_table: "queue_messages",
|
|
491
|
+
db_connection: "default",
|
|
492
|
+
listen_interval: 60,
|
|
493
|
+
// seconds
|
|
494
|
+
message_limit: 10
|
|
495
|
+
// messages per each fetch
|
|
496
|
+
};
|
|
497
|
+
constructor(config2) {
|
|
498
|
+
this.config = { ...this.config, ...config2 };
|
|
499
|
+
}
|
|
497
500
|
setListenInterval(interval) {
|
|
498
|
-
this.
|
|
501
|
+
this.config.listen_interval = interval;
|
|
499
502
|
}
|
|
500
503
|
setMessageLimit(limit) {
|
|
501
|
-
this.
|
|
504
|
+
this.config.message_limit = limit;
|
|
502
505
|
}
|
|
503
506
|
async dispatch(channel, message) {
|
|
504
|
-
const conn =
|
|
507
|
+
const conn = db(this.config.db_connection);
|
|
505
508
|
try {
|
|
506
509
|
await conn.connect();
|
|
510
|
+
let schema = conn.getSchema();
|
|
511
|
+
if (await schema.tableExists(this.config.queue_table) === false) {
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
507
514
|
let q = conn.getQuery();
|
|
508
|
-
await q.table(
|
|
515
|
+
await q.table(this.config.queue_table).insert({
|
|
509
516
|
channel,
|
|
510
517
|
message,
|
|
511
518
|
processed: false,
|
|
@@ -521,20 +528,20 @@ var DatabaseTransport = class {
|
|
|
521
528
|
async listen(channel, callback) {
|
|
522
529
|
return new Promise(async (resolve, reject) => {
|
|
523
530
|
const intervalId = setInterval(async () => {
|
|
524
|
-
const conn =
|
|
531
|
+
const conn = db(this.config.db_connection);
|
|
525
532
|
try {
|
|
526
533
|
await conn.connect();
|
|
527
534
|
let q = conn.getQuery();
|
|
528
|
-
let messages = await q.table(
|
|
535
|
+
let messages = await q.table(this.config.queue_table).whereOp("channel", "=", channel).whereOp("processed", "=", false).limit(this.config.message_limit).orderBy("last_tried_at", "asc").get();
|
|
529
536
|
for (let msg of messages) {
|
|
530
537
|
try {
|
|
531
538
|
await callback(msg.message);
|
|
532
|
-
await q.table(
|
|
539
|
+
await q.table(this.config.queue_table).whereOp("id", "=", msg.id).update({
|
|
533
540
|
processed: true,
|
|
534
541
|
updated_at: /* @__PURE__ */ new Date()
|
|
535
542
|
});
|
|
536
543
|
} catch (error) {
|
|
537
|
-
await q.table(
|
|
544
|
+
await q.table(this.config.queue_table).whereOp("id", "=", msg.id).update({
|
|
538
545
|
processed: false,
|
|
539
546
|
last_tried_at: /* @__PURE__ */ new Date(),
|
|
540
547
|
process_message: error.message || "Error processing message"
|
|
@@ -543,11 +550,11 @@ var DatabaseTransport = class {
|
|
|
543
550
|
}
|
|
544
551
|
} catch (error) {
|
|
545
552
|
this.activeIntervals.delete(intervalId);
|
|
546
|
-
|
|
553
|
+
logger().error("Error in DatabaseTransport listen interval:", { error });
|
|
547
554
|
} finally {
|
|
548
555
|
await conn.disconnect();
|
|
549
556
|
}
|
|
550
|
-
}, this.
|
|
557
|
+
}, this.config.listen_interval * 1e3);
|
|
551
558
|
this.activeIntervals.add(intervalId);
|
|
552
559
|
});
|
|
553
560
|
}
|
|
@@ -561,6 +568,7 @@ var DatabaseTransport = class {
|
|
|
561
568
|
|
|
562
569
|
// src/factories.mts
|
|
563
570
|
var import_neko_cache = require("@devbro/neko-cache");
|
|
571
|
+
var import_neko_storage = require("@devbro/neko-storage");
|
|
564
572
|
var FlexibleFactory = class {
|
|
565
573
|
static {
|
|
566
574
|
__name(this, "FlexibleFactory");
|
|
@@ -597,32 +605,32 @@ MailerFactory.register("logger", (opt) => {
|
|
|
597
605
|
});
|
|
598
606
|
});
|
|
599
607
|
});
|
|
600
|
-
MailerFactory.register("
|
|
608
|
+
MailerFactory.register("ses", (opt) => {
|
|
601
609
|
return new import_neko_mailer.SESProvider(opt);
|
|
602
610
|
});
|
|
603
|
-
MailerFactory.register("
|
|
611
|
+
MailerFactory.register("smtp", (opt) => {
|
|
604
612
|
return new import_neko_mailer.SMTPProvider(opt);
|
|
605
613
|
});
|
|
606
|
-
MailerFactory.register("
|
|
614
|
+
MailerFactory.register("memory", (opt) => {
|
|
607
615
|
return new import_neko_mailer.MemoryProvider();
|
|
608
616
|
});
|
|
609
|
-
var
|
|
617
|
+
var QueueTransportFactory = class _QueueTransportFactory {
|
|
610
618
|
static {
|
|
611
|
-
__name(this, "
|
|
619
|
+
__name(this, "QueueTransportFactory");
|
|
612
620
|
}
|
|
613
621
|
static instance = new FlexibleFactory();
|
|
614
622
|
static register(key, factory) {
|
|
615
|
-
|
|
623
|
+
_QueueTransportFactory.instance.register(key, factory);
|
|
616
624
|
}
|
|
617
625
|
static create(key, ...args) {
|
|
618
|
-
return
|
|
626
|
+
return _QueueTransportFactory.instance.create(key, ...args);
|
|
619
627
|
}
|
|
620
628
|
};
|
|
621
|
-
|
|
629
|
+
QueueTransportFactory.register("database", (opt) => {
|
|
622
630
|
let transport = new DatabaseTransport(opt);
|
|
623
631
|
return new import_neko_queue.QueueConnection(transport);
|
|
624
632
|
});
|
|
625
|
-
|
|
633
|
+
QueueTransportFactory.register("memory", (opt) => {
|
|
626
634
|
let transport = new import_neko_queue2.MemoryTransport(opt);
|
|
627
635
|
return new import_neko_queue.QueueConnection(transport);
|
|
628
636
|
});
|
|
@@ -650,9 +658,16 @@ CacheProviderFactory.register("file", (opt) => {
|
|
|
650
658
|
CacheProviderFactory.register("disabled", (opt) => {
|
|
651
659
|
return new import_neko_cache.DisabledCacheProvider();
|
|
652
660
|
});
|
|
661
|
+
import_neko_storage.StorageProviderFactory.register("local", (opt) => {
|
|
662
|
+
return new import_neko_storage.LocalStorageProvider(opt);
|
|
663
|
+
});
|
|
664
|
+
import_neko_storage.StorageProviderFactory.register("s3", (opt) => {
|
|
665
|
+
return new import_neko_storage.AWSS3StorageProvider(opt);
|
|
666
|
+
});
|
|
653
667
|
|
|
654
668
|
// src/facades.mts
|
|
655
669
|
var import_neko_cache2 = require("@devbro/neko-cache");
|
|
670
|
+
var import_neko_queue3 = require("@devbro/neko-queue");
|
|
656
671
|
var router = (0, import_neko_helper.createSingleton)(() => new Router());
|
|
657
672
|
var scheduler = (0, import_neko_helper.createSingleton)(() => {
|
|
658
673
|
const rc = new import_neko_scheduler.Scheduler();
|
|
@@ -665,9 +680,12 @@ var scheduler = (0, import_neko_helper.createSingleton)(() => {
|
|
|
665
680
|
});
|
|
666
681
|
return rc;
|
|
667
682
|
});
|
|
668
|
-
var
|
|
669
|
-
|
|
670
|
-
);
|
|
683
|
+
var db = /* @__PURE__ */ __name((label = "default") => (0, import_neko_context2.ctx)().getOrThrow(["database", label]), "db");
|
|
684
|
+
var storage = (0, import_neko_helper.createSingleton)((label = "default") => {
|
|
685
|
+
let storage_config = import_neko_config.config.get(["storages", label].join("."));
|
|
686
|
+
const provider = import_neko_storage2.StorageProviderFactory.create(storage_config.provider, storage_config.config);
|
|
687
|
+
return new import_neko_storage2.Storage(provider);
|
|
688
|
+
});
|
|
671
689
|
var cli = (0, import_neko_helper.createSingleton)(() => {
|
|
672
690
|
const [node, app, ...args] = process.argv;
|
|
673
691
|
return new import_clipanion.Cli({
|
|
@@ -722,7 +740,7 @@ var logger = (0, import_neko_helper.createSingleton)((label) => {
|
|
|
722
740
|
});
|
|
723
741
|
var mailer = (0, import_neko_helper.createSingleton)((label) => {
|
|
724
742
|
const mailer_config = import_neko_config.config.get(["mailer", label].join("."));
|
|
725
|
-
|
|
743
|
+
const provider = MailerFactory.create(
|
|
726
744
|
mailer_config.provider,
|
|
727
745
|
mailer_config.config
|
|
728
746
|
);
|
|
@@ -734,7 +752,8 @@ var queue = (0, import_neko_helper.createSingleton)((label) => {
|
|
|
734
752
|
if (!queue_config) {
|
|
735
753
|
throw new Error(`Queue configuration for '${label}' not found`);
|
|
736
754
|
}
|
|
737
|
-
const
|
|
755
|
+
const provider = QueueTransportFactory.create(queue_config.provider, queue_config.config);
|
|
756
|
+
const rc = new import_neko_queue3.QueueConnection(provider);
|
|
738
757
|
return rc;
|
|
739
758
|
});
|
|
740
759
|
var cache = (0, import_neko_helper.createSingleton)((label) => {
|
|
@@ -743,7 +762,7 @@ var cache = (0, import_neko_helper.createSingleton)((label) => {
|
|
|
743
762
|
throw new Error(`Cache configuration for '${label}' not found`);
|
|
744
763
|
}
|
|
745
764
|
const provider = CacheProviderFactory.create(
|
|
746
|
-
cache_config.
|
|
765
|
+
cache_config.provider,
|
|
747
766
|
cache_config.config
|
|
748
767
|
);
|
|
749
768
|
return new import_neko_cache2.Cache(provider);
|
|
@@ -460,7 +460,7 @@ var Router = class {
|
|
|
460
460
|
var import_neko_scheduler = require("@devbro/neko-scheduler");
|
|
461
461
|
var import_neko_helper = require("@devbro/neko-helper");
|
|
462
462
|
var import_neko_context2 = require("@devbro/neko-context");
|
|
463
|
-
var
|
|
463
|
+
var import_neko_storage2 = require("@devbro/neko-storage");
|
|
464
464
|
var import_neko_mailer2 = require("@devbro/neko-mailer");
|
|
465
465
|
var import_neko_config = require("@devbro/neko-config");
|
|
466
466
|
var import_clipanion = require("clipanion");
|
|
@@ -484,31 +484,38 @@ __export(queue_exports, {
|
|
|
484
484
|
DatabaseTransport: () => DatabaseTransport
|
|
485
485
|
});
|
|
486
486
|
__reExport(queue_exports, require("@devbro/neko-queue"));
|
|
487
|
-
var import_neko_sql = require("@devbro/neko-sql");
|
|
488
487
|
var DatabaseTransport = class {
|
|
489
|
-
constructor(db_config) {
|
|
490
|
-
this.db_config = db_config;
|
|
491
|
-
}
|
|
492
488
|
static {
|
|
493
489
|
__name(this, "DatabaseTransport");
|
|
494
490
|
}
|
|
495
|
-
listenInterval = 6e4;
|
|
496
|
-
// default to 1 minute
|
|
497
|
-
messageLimit = 100;
|
|
498
|
-
// default to 100 messages per fetch
|
|
499
491
|
activeIntervals = /* @__PURE__ */ new Set();
|
|
492
|
+
config = {
|
|
493
|
+
queue_table: "queue_messages",
|
|
494
|
+
db_connection: "default",
|
|
495
|
+
listen_interval: 60,
|
|
496
|
+
// seconds
|
|
497
|
+
message_limit: 10
|
|
498
|
+
// messages per each fetch
|
|
499
|
+
};
|
|
500
|
+
constructor(config2) {
|
|
501
|
+
this.config = { ...this.config, ...config2 };
|
|
502
|
+
}
|
|
500
503
|
setListenInterval(interval) {
|
|
501
|
-
this.
|
|
504
|
+
this.config.listen_interval = interval;
|
|
502
505
|
}
|
|
503
506
|
setMessageLimit(limit) {
|
|
504
|
-
this.
|
|
507
|
+
this.config.message_limit = limit;
|
|
505
508
|
}
|
|
506
509
|
async dispatch(channel, message) {
|
|
507
|
-
const conn =
|
|
510
|
+
const conn = db(this.config.db_connection);
|
|
508
511
|
try {
|
|
509
512
|
await conn.connect();
|
|
513
|
+
let schema = conn.getSchema();
|
|
514
|
+
if (await schema.tableExists(this.config.queue_table) === false) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
510
517
|
let q = conn.getQuery();
|
|
511
|
-
await q.table(
|
|
518
|
+
await q.table(this.config.queue_table).insert({
|
|
512
519
|
channel,
|
|
513
520
|
message,
|
|
514
521
|
processed: false,
|
|
@@ -524,20 +531,20 @@ var DatabaseTransport = class {
|
|
|
524
531
|
async listen(channel, callback) {
|
|
525
532
|
return new Promise(async (resolve, reject) => {
|
|
526
533
|
const intervalId = setInterval(async () => {
|
|
527
|
-
const conn =
|
|
534
|
+
const conn = db(this.config.db_connection);
|
|
528
535
|
try {
|
|
529
536
|
await conn.connect();
|
|
530
537
|
let q = conn.getQuery();
|
|
531
|
-
let messages = await q.table(
|
|
538
|
+
let messages = await q.table(this.config.queue_table).whereOp("channel", "=", channel).whereOp("processed", "=", false).limit(this.config.message_limit).orderBy("last_tried_at", "asc").get();
|
|
532
539
|
for (let msg of messages) {
|
|
533
540
|
try {
|
|
534
541
|
await callback(msg.message);
|
|
535
|
-
await q.table(
|
|
542
|
+
await q.table(this.config.queue_table).whereOp("id", "=", msg.id).update({
|
|
536
543
|
processed: true,
|
|
537
544
|
updated_at: /* @__PURE__ */ new Date()
|
|
538
545
|
});
|
|
539
546
|
} catch (error) {
|
|
540
|
-
await q.table(
|
|
547
|
+
await q.table(this.config.queue_table).whereOp("id", "=", msg.id).update({
|
|
541
548
|
processed: false,
|
|
542
549
|
last_tried_at: /* @__PURE__ */ new Date(),
|
|
543
550
|
process_message: error.message || "Error processing message"
|
|
@@ -546,11 +553,11 @@ var DatabaseTransport = class {
|
|
|
546
553
|
}
|
|
547
554
|
} catch (error) {
|
|
548
555
|
this.activeIntervals.delete(intervalId);
|
|
549
|
-
|
|
556
|
+
logger().error("Error in DatabaseTransport listen interval:", { error });
|
|
550
557
|
} finally {
|
|
551
558
|
await conn.disconnect();
|
|
552
559
|
}
|
|
553
|
-
}, this.
|
|
560
|
+
}, this.config.listen_interval * 1e3);
|
|
554
561
|
this.activeIntervals.add(intervalId);
|
|
555
562
|
});
|
|
556
563
|
}
|
|
@@ -564,6 +571,7 @@ var DatabaseTransport = class {
|
|
|
564
571
|
|
|
565
572
|
// src/factories.mts
|
|
566
573
|
var import_neko_cache = require("@devbro/neko-cache");
|
|
574
|
+
var import_neko_storage = require("@devbro/neko-storage");
|
|
567
575
|
var FlexibleFactory = class {
|
|
568
576
|
static {
|
|
569
577
|
__name(this, "FlexibleFactory");
|
|
@@ -600,32 +608,32 @@ MailerFactory.register("logger", (opt) => {
|
|
|
600
608
|
});
|
|
601
609
|
});
|
|
602
610
|
});
|
|
603
|
-
MailerFactory.register("
|
|
611
|
+
MailerFactory.register("ses", (opt) => {
|
|
604
612
|
return new import_neko_mailer.SESProvider(opt);
|
|
605
613
|
});
|
|
606
|
-
MailerFactory.register("
|
|
614
|
+
MailerFactory.register("smtp", (opt) => {
|
|
607
615
|
return new import_neko_mailer.SMTPProvider(opt);
|
|
608
616
|
});
|
|
609
|
-
MailerFactory.register("
|
|
617
|
+
MailerFactory.register("memory", (opt) => {
|
|
610
618
|
return new import_neko_mailer.MemoryProvider();
|
|
611
619
|
});
|
|
612
|
-
var
|
|
620
|
+
var QueueTransportFactory = class _QueueTransportFactory {
|
|
613
621
|
static {
|
|
614
|
-
__name(this, "
|
|
622
|
+
__name(this, "QueueTransportFactory");
|
|
615
623
|
}
|
|
616
624
|
static instance = new FlexibleFactory();
|
|
617
625
|
static register(key, factory) {
|
|
618
|
-
|
|
626
|
+
_QueueTransportFactory.instance.register(key, factory);
|
|
619
627
|
}
|
|
620
628
|
static create(key, ...args) {
|
|
621
|
-
return
|
|
629
|
+
return _QueueTransportFactory.instance.create(key, ...args);
|
|
622
630
|
}
|
|
623
631
|
};
|
|
624
|
-
|
|
632
|
+
QueueTransportFactory.register("database", (opt) => {
|
|
625
633
|
let transport = new DatabaseTransport(opt);
|
|
626
634
|
return new import_neko_queue.QueueConnection(transport);
|
|
627
635
|
});
|
|
628
|
-
|
|
636
|
+
QueueTransportFactory.register("memory", (opt) => {
|
|
629
637
|
let transport = new import_neko_queue2.MemoryTransport(opt);
|
|
630
638
|
return new import_neko_queue.QueueConnection(transport);
|
|
631
639
|
});
|
|
@@ -653,9 +661,16 @@ CacheProviderFactory.register("file", (opt) => {
|
|
|
653
661
|
CacheProviderFactory.register("disabled", (opt) => {
|
|
654
662
|
return new import_neko_cache.DisabledCacheProvider();
|
|
655
663
|
});
|
|
664
|
+
import_neko_storage.StorageProviderFactory.register("local", (opt) => {
|
|
665
|
+
return new import_neko_storage.LocalStorageProvider(opt);
|
|
666
|
+
});
|
|
667
|
+
import_neko_storage.StorageProviderFactory.register("s3", (opt) => {
|
|
668
|
+
return new import_neko_storage.AWSS3StorageProvider(opt);
|
|
669
|
+
});
|
|
656
670
|
|
|
657
671
|
// src/facades.mts
|
|
658
672
|
var import_neko_cache2 = require("@devbro/neko-cache");
|
|
673
|
+
var import_neko_queue3 = require("@devbro/neko-queue");
|
|
659
674
|
var router = (0, import_neko_helper.createSingleton)(() => new Router());
|
|
660
675
|
var scheduler = (0, import_neko_helper.createSingleton)(() => {
|
|
661
676
|
const rc = new import_neko_scheduler.Scheduler();
|
|
@@ -668,9 +683,12 @@ var scheduler = (0, import_neko_helper.createSingleton)(() => {
|
|
|
668
683
|
});
|
|
669
684
|
return rc;
|
|
670
685
|
});
|
|
671
|
-
var
|
|
672
|
-
|
|
673
|
-
);
|
|
686
|
+
var db = /* @__PURE__ */ __name((label = "default") => (0, import_neko_context2.ctx)().getOrThrow(["database", label]), "db");
|
|
687
|
+
var storage = (0, import_neko_helper.createSingleton)((label = "default") => {
|
|
688
|
+
let storage_config = import_neko_config.config.get(["storages", label].join("."));
|
|
689
|
+
const provider = import_neko_storage2.StorageProviderFactory.create(storage_config.provider, storage_config.config);
|
|
690
|
+
return new import_neko_storage2.Storage(provider);
|
|
691
|
+
});
|
|
674
692
|
var cli = (0, import_neko_helper.createSingleton)(() => {
|
|
675
693
|
const [node, app, ...args] = process.argv;
|
|
676
694
|
return new import_clipanion.Cli({
|
|
@@ -725,7 +743,7 @@ var logger = (0, import_neko_helper.createSingleton)((label) => {
|
|
|
725
743
|
});
|
|
726
744
|
var mailer = (0, import_neko_helper.createSingleton)((label) => {
|
|
727
745
|
const mailer_config = import_neko_config.config.get(["mailer", label].join("."));
|
|
728
|
-
|
|
746
|
+
const provider = MailerFactory.create(
|
|
729
747
|
mailer_config.provider,
|
|
730
748
|
mailer_config.config
|
|
731
749
|
);
|
|
@@ -737,7 +755,8 @@ var queue = (0, import_neko_helper.createSingleton)((label) => {
|
|
|
737
755
|
if (!queue_config) {
|
|
738
756
|
throw new Error(`Queue configuration for '${label}' not found`);
|
|
739
757
|
}
|
|
740
|
-
const
|
|
758
|
+
const provider = QueueTransportFactory.create(queue_config.provider, queue_config.config);
|
|
759
|
+
const rc = new import_neko_queue3.QueueConnection(provider);
|
|
741
760
|
return rc;
|
|
742
761
|
});
|
|
743
762
|
var cache = (0, import_neko_helper.createSingleton)((label) => {
|
|
@@ -746,7 +765,7 @@ var cache = (0, import_neko_helper.createSingleton)((label) => {
|
|
|
746
765
|
throw new Error(`Cache configuration for '${label}' not found`);
|
|
747
766
|
}
|
|
748
767
|
const provider = CacheProviderFactory.create(
|
|
749
|
-
cache_config.
|
|
768
|
+
cache_config.provider,
|
|
750
769
|
cache_config.config
|
|
751
770
|
);
|
|
752
771
|
return new import_neko_cache2.Cache(provider);
|