@devbro/pashmak 0.1.10 → 0.1.12
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/migrate/MigrateCommand.d.mts +1 -0
- package/dist/app/console/migrate/MigrateCommand.mjs +33 -16
- package/dist/app/console/migrate/MigrateCommand.mjs.map +1 -1
- package/dist/app/console/migrate/MigrateRollbackCommand.d.mts +1 -1
- package/dist/app/console/migrate/MigrateRollbackCommand.mjs +5 -6
- package/dist/app/console/migrate/MigrateRollbackCommand.mjs.map +1 -1
- package/dist/app/console/migrate/make_migration.tpl +5 -5
- package/dist/app/console/queue/GenerateMigrateCommand.d.mts +9 -0
- package/dist/app/console/queue/GenerateMigrateCommand.mjs +51 -0
- package/dist/app/console/queue/GenerateMigrateCommand.mjs.map +1 -0
- package/dist/app/console/queue/queue_migration.tpl +19 -0
- package/dist/bin/app/console/DefaultCommand.cjs +254 -25
- package/dist/bin/app/console/KeyGenerateCommand.cjs +254 -25
- package/dist/bin/app/console/StartCommand.cjs +257 -28
- package/dist/bin/app/console/generate/GenerateControllerCommand.cjs +254 -25
- package/dist/bin/app/console/generate/index.cjs +254 -25
- package/dist/bin/app/console/index.cjs +293 -48
- package/dist/bin/app/console/migrate/GenerateMigrateCommand.cjs +254 -25
- package/dist/bin/app/console/migrate/MigrateCommand.cjs +288 -42
- package/dist/bin/app/console/migrate/MigrateRollbackCommand.cjs +258 -30
- package/dist/bin/app/console/migrate/index.cjs +291 -46
- package/dist/bin/app/console/queue/GenerateMigrateCommand.cjs +752 -0
- package/dist/bin/facades.cjs +257 -26
- package/dist/bin/factories.cjs +707 -0
- package/dist/bin/index.cjs +312 -54
- package/dist/bin/middlewares.cjs +255 -26
- package/dist/bin/queue.cjs +99 -0
- package/dist/bin/router.cjs +95 -5
- package/dist/facades.d.mts +3 -1
- package/dist/facades.mjs +15 -27
- package/dist/facades.mjs.map +1 -1
- package/dist/factories.d.mts +20 -0
- package/dist/factories.mjs +83 -0
- package/dist/factories.mjs.map +1 -0
- package/dist/queue.d.mts +15 -0
- package/dist/queue.mjs +73 -0
- package/dist/queue.mjs.map +1 -0
- package/dist/router.mjs +1 -1
- package/dist/router.mjs.map +1 -1
- package/package.json +10 -3
|
@@ -44,6 +44,9 @@ var import_path2 = __toESM(require("path"), 1);
|
|
|
44
44
|
var import_neko_context = require("@devbro/neko-context");
|
|
45
45
|
var import_errors = require("@devbro/neko-http/errors");
|
|
46
46
|
|
|
47
|
+
// ../neko-router/dist/CompiledRoute.mjs
|
|
48
|
+
var import_stream = require("stream");
|
|
49
|
+
|
|
47
50
|
// ../neko-router/dist/Middleware.mjs
|
|
48
51
|
var Middleware = class {
|
|
49
52
|
static {
|
|
@@ -121,6 +124,9 @@ var CompiledRoute = class {
|
|
|
121
124
|
if (typeof value.toJson === "function") {
|
|
122
125
|
return traverse(value.toJson());
|
|
123
126
|
}
|
|
127
|
+
if (typeof value.toJSON === "function") {
|
|
128
|
+
return traverse(value.toJSON());
|
|
129
|
+
}
|
|
124
130
|
if (Array.isArray(value)) {
|
|
125
131
|
return value.map(traverse);
|
|
126
132
|
}
|
|
@@ -145,7 +151,7 @@ var CompiledRoute = class {
|
|
|
145
151
|
}
|
|
146
152
|
return String(obj);
|
|
147
153
|
}
|
|
148
|
-
processResponseBody(res, controller_rc) {
|
|
154
|
+
async processResponseBody(res, controller_rc) {
|
|
149
155
|
if (controller_rc && res.writableEnded) {
|
|
150
156
|
throw new Error("cannot write to response, response has already ended");
|
|
151
157
|
}
|
|
@@ -154,18 +160,36 @@ var CompiledRoute = class {
|
|
|
154
160
|
}
|
|
155
161
|
if (controller_rc) {
|
|
156
162
|
const header_content_type = res.getHeader("Content-Type");
|
|
157
|
-
if (
|
|
163
|
+
if (controller_rc instanceof import_stream.Stream || Buffer.isBuffer(controller_rc)) {
|
|
164
|
+
await this.writeAsync(res, controller_rc);
|
|
165
|
+
res.end();
|
|
166
|
+
} else if (!header_content_type && typeof controller_rc === "object") {
|
|
158
167
|
res.setHeader("Content-Type", "application/json");
|
|
168
|
+
res.end(this.convertToString(controller_rc));
|
|
159
169
|
} else if (!header_content_type) {
|
|
160
170
|
res.setHeader("Content-Type", "text/plain");
|
|
171
|
+
res.end(this.convertToString(controller_rc));
|
|
172
|
+
} else {
|
|
173
|
+
res.end(this.convertToString(controller_rc));
|
|
161
174
|
}
|
|
162
|
-
res.end(this.convertToString(controller_rc));
|
|
163
175
|
return;
|
|
164
176
|
} else {
|
|
165
177
|
res.statusCode = [200].includes(res.statusCode) ? 204 : res.statusCode;
|
|
166
178
|
res.end();
|
|
167
179
|
}
|
|
168
180
|
}
|
|
181
|
+
async writeAsync(res, chunk) {
|
|
182
|
+
return new Promise((resolve, reject) => {
|
|
183
|
+
const ok = res.write(chunk, (err) => {
|
|
184
|
+
if (err) reject(err);
|
|
185
|
+
});
|
|
186
|
+
if (ok) {
|
|
187
|
+
resolve(0);
|
|
188
|
+
} else {
|
|
189
|
+
res.once("drain", resolve);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
169
193
|
async runMiddlewares(middlewares, req, res) {
|
|
170
194
|
let index = 0;
|
|
171
195
|
const me = this;
|
|
@@ -223,7 +247,7 @@ var Route = class {
|
|
|
223
247
|
i = start;
|
|
224
248
|
} else if (char === "*") {
|
|
225
249
|
let start = i + 1;
|
|
226
|
-
while (start < path3.length && /[a-zA-Z0-9_]/.test(path3[start])) {
|
|
250
|
+
while (start < path3.length && /[a-zA-Z0-9_\.]/.test(path3[start])) {
|
|
227
251
|
start++;
|
|
228
252
|
}
|
|
229
253
|
tokens.push({ type: "WILDCARD", value: path3.slice(i + 1, start) });
|
|
@@ -293,6 +317,10 @@ var Route = class {
|
|
|
293
317
|
params: r.groups || {}
|
|
294
318
|
};
|
|
295
319
|
}
|
|
320
|
+
prependMiddleware(middlewares) {
|
|
321
|
+
this.middlewares = [].concat(middlewares, this.middlewares);
|
|
322
|
+
return this;
|
|
323
|
+
}
|
|
296
324
|
addMiddleware(middlewares) {
|
|
297
325
|
this.middlewares = this.middlewares.concat(middlewares);
|
|
298
326
|
return this;
|
|
@@ -307,6 +335,62 @@ var Route = class {
|
|
|
307
335
|
|
|
308
336
|
// ../neko-router/dist/Router.mjs
|
|
309
337
|
var import_path = __toESM(require("path"), 1);
|
|
338
|
+
|
|
339
|
+
// ../node_modules/url-join/lib/url-join.js
|
|
340
|
+
function normalize(strArray) {
|
|
341
|
+
var resultArray = [];
|
|
342
|
+
if (strArray.length === 0) {
|
|
343
|
+
return "";
|
|
344
|
+
}
|
|
345
|
+
if (typeof strArray[0] !== "string") {
|
|
346
|
+
throw new TypeError("Url must be a string. Received " + strArray[0]);
|
|
347
|
+
}
|
|
348
|
+
if (strArray[0].match(/^[^/:]+:\/*$/) && strArray.length > 1) {
|
|
349
|
+
var first = strArray.shift();
|
|
350
|
+
strArray[0] = first + strArray[0];
|
|
351
|
+
}
|
|
352
|
+
if (strArray[0].match(/^file:\/\/\//)) {
|
|
353
|
+
strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, "$1:///");
|
|
354
|
+
} else {
|
|
355
|
+
strArray[0] = strArray[0].replace(/^([^/:]+):\/*/, "$1://");
|
|
356
|
+
}
|
|
357
|
+
for (var i = 0; i < strArray.length; i++) {
|
|
358
|
+
var component = strArray[i];
|
|
359
|
+
if (typeof component !== "string") {
|
|
360
|
+
throw new TypeError("Url must be a string. Received " + component);
|
|
361
|
+
}
|
|
362
|
+
if (component === "") {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (i > 0) {
|
|
366
|
+
component = component.replace(/^[\/]+/, "");
|
|
367
|
+
}
|
|
368
|
+
if (i < strArray.length - 1) {
|
|
369
|
+
component = component.replace(/[\/]+$/, "");
|
|
370
|
+
} else {
|
|
371
|
+
component = component.replace(/[\/]+$/, "/");
|
|
372
|
+
}
|
|
373
|
+
resultArray.push(component);
|
|
374
|
+
}
|
|
375
|
+
var str = resultArray.join("/");
|
|
376
|
+
str = str.replace(/\/(\?|&|#[^!])/g, "$1");
|
|
377
|
+
var parts = str.split("?");
|
|
378
|
+
str = parts.shift() + (parts.length > 0 ? "?" : "") + parts.join("&");
|
|
379
|
+
return str;
|
|
380
|
+
}
|
|
381
|
+
__name(normalize, "normalize");
|
|
382
|
+
function urlJoin() {
|
|
383
|
+
var input;
|
|
384
|
+
if (typeof arguments[0] === "object") {
|
|
385
|
+
input = arguments[0];
|
|
386
|
+
} else {
|
|
387
|
+
input = [].slice.call(arguments);
|
|
388
|
+
}
|
|
389
|
+
return normalize(input);
|
|
390
|
+
}
|
|
391
|
+
__name(urlJoin, "urlJoin");
|
|
392
|
+
|
|
393
|
+
// ../neko-router/dist/Router.mjs
|
|
310
394
|
var Router = class {
|
|
311
395
|
static {
|
|
312
396
|
__name(this, "Router");
|
|
@@ -331,6 +415,12 @@ var Router = class {
|
|
|
331
415
|
}).addMiddleware([...controller.baseMiddlewares, ...route.middlewares]);
|
|
332
416
|
}
|
|
333
417
|
}
|
|
418
|
+
addRouter(path22, router2) {
|
|
419
|
+
for (const route of router2.routes) {
|
|
420
|
+
let path222 = urlJoin("/", path22, route.path);
|
|
421
|
+
this.addRoute(route.methods, path222, route.handler).addMiddleware(router2.getMiddlewares()).addMiddleware(route.getMiddlewares());
|
|
422
|
+
}
|
|
423
|
+
}
|
|
334
424
|
addGlobalMiddleware(middlewares) {
|
|
335
425
|
this.middlewares = this.middlewares.concat(middlewares);
|
|
336
426
|
}
|
|
@@ -371,7 +461,7 @@ var import_neko_scheduler = require("@devbro/neko-scheduler");
|
|
|
371
461
|
var import_neko_helper = require("@devbro/neko-helper");
|
|
372
462
|
var import_neko_context2 = require("@devbro/neko-context");
|
|
373
463
|
var import_neko_storage = require("@devbro/neko-storage");
|
|
374
|
-
var
|
|
464
|
+
var import_neko_mailer2 = require("@devbro/neko-mailer");
|
|
375
465
|
var import_neko_config = require("@devbro/neko-config");
|
|
376
466
|
var import_clipanion = require("clipanion");
|
|
377
467
|
|
|
@@ -382,6 +472,153 @@ __reExport(http_exports, require("@devbro/neko-http"));
|
|
|
382
472
|
// src/facades.mts
|
|
383
473
|
var yup = __toESM(require("yup"), 1);
|
|
384
474
|
var import_neko_logger = require("@devbro/neko-logger");
|
|
475
|
+
|
|
476
|
+
// src/factories.mts
|
|
477
|
+
var import_neko_mailer = require("@devbro/neko-mailer");
|
|
478
|
+
var import_neko_queue = require("@devbro/neko-queue");
|
|
479
|
+
var import_neko_queue2 = require("@devbro/neko-queue");
|
|
480
|
+
|
|
481
|
+
// src/queue.mts
|
|
482
|
+
var queue_exports = {};
|
|
483
|
+
__export(queue_exports, {
|
|
484
|
+
DatabaseTransport: () => DatabaseTransport
|
|
485
|
+
});
|
|
486
|
+
__reExport(queue_exports, require("@devbro/neko-queue"));
|
|
487
|
+
var import_neko_sql = require("@devbro/neko-sql");
|
|
488
|
+
var DatabaseTransport = class {
|
|
489
|
+
// default to 100 messages per fetch
|
|
490
|
+
constructor(db_config) {
|
|
491
|
+
this.db_config = db_config;
|
|
492
|
+
}
|
|
493
|
+
static {
|
|
494
|
+
__name(this, "DatabaseTransport");
|
|
495
|
+
}
|
|
496
|
+
listenInterval = 6e4;
|
|
497
|
+
// default to 1 minute
|
|
498
|
+
messageLimit = 100;
|
|
499
|
+
setListenInterval(interval) {
|
|
500
|
+
this.listenInterval = interval;
|
|
501
|
+
}
|
|
502
|
+
setMessageLimit(limit) {
|
|
503
|
+
this.messageLimit = limit;
|
|
504
|
+
}
|
|
505
|
+
async dispatch(channel, message) {
|
|
506
|
+
const conn = new import_neko_sql.PostgresqlConnection(this.db_config);
|
|
507
|
+
try {
|
|
508
|
+
await conn.connect();
|
|
509
|
+
let q = conn.getQuery();
|
|
510
|
+
await q.table("queue_messages").insert({
|
|
511
|
+
channel,
|
|
512
|
+
message,
|
|
513
|
+
processed: false,
|
|
514
|
+
created_at: /* @__PURE__ */ new Date(),
|
|
515
|
+
updated_at: /* @__PURE__ */ new Date(),
|
|
516
|
+
last_tried_at: null,
|
|
517
|
+
process_message: ""
|
|
518
|
+
});
|
|
519
|
+
} finally {
|
|
520
|
+
await conn.disconnect();
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
async listen(channel, callback) {
|
|
524
|
+
return new Promise(async (resolve, reject) => {
|
|
525
|
+
setInterval(async () => {
|
|
526
|
+
const conn = new import_neko_sql.PostgresqlConnection(this.db_config);
|
|
527
|
+
try {
|
|
528
|
+
await conn.connect();
|
|
529
|
+
let q = conn.getQuery();
|
|
530
|
+
let messages = await q.table("queue_messages").whereOp("channel", "=", channel).whereOp("processed", "=", false).limit(this.messageLimit).orderBy("last_tried_at", "asc").get();
|
|
531
|
+
for (let msg of messages) {
|
|
532
|
+
try {
|
|
533
|
+
await callback(msg.message);
|
|
534
|
+
await q.table("queue_messages").whereOp("id", "=", msg.id).update({
|
|
535
|
+
processed: true,
|
|
536
|
+
updated_at: /* @__PURE__ */ new Date()
|
|
537
|
+
});
|
|
538
|
+
} catch (error) {
|
|
539
|
+
await q.table("queue_messages").whereOp("id", "=", msg.id).update({
|
|
540
|
+
processed: false,
|
|
541
|
+
last_tried_at: /* @__PURE__ */ new Date(),
|
|
542
|
+
process_message: error.message || "Error processing message"
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
} finally {
|
|
547
|
+
await conn.disconnect();
|
|
548
|
+
}
|
|
549
|
+
}, this.listenInterval);
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
// src/factories.mts
|
|
555
|
+
var FlexibleFactory = class {
|
|
556
|
+
static {
|
|
557
|
+
__name(this, "FlexibleFactory");
|
|
558
|
+
}
|
|
559
|
+
registry = /* @__PURE__ */ new Map();
|
|
560
|
+
register(key, ctor) {
|
|
561
|
+
this.registry.set(key, ctor);
|
|
562
|
+
}
|
|
563
|
+
create(key, ...args) {
|
|
564
|
+
const ctor = this.registry.get(key);
|
|
565
|
+
if (!ctor) {
|
|
566
|
+
throw new Error(`No factory registered for key: ${key}`);
|
|
567
|
+
}
|
|
568
|
+
return new ctor(...args);
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
var MailerFactory = class _MailerFactory {
|
|
572
|
+
static {
|
|
573
|
+
__name(this, "MailerFactory");
|
|
574
|
+
}
|
|
575
|
+
static instance = new FlexibleFactory();
|
|
576
|
+
static register(key, factory) {
|
|
577
|
+
_MailerFactory.instance.register(key, factory);
|
|
578
|
+
}
|
|
579
|
+
static create(key, ...args) {
|
|
580
|
+
return _MailerFactory.instance.create(key, ...args);
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
MailerFactory.register("logger", (opt) => {
|
|
584
|
+
return new import_neko_mailer.FunctionProvider((mail) => {
|
|
585
|
+
logger().info({
|
|
586
|
+
msg: "Sending email",
|
|
587
|
+
mail
|
|
588
|
+
});
|
|
589
|
+
});
|
|
590
|
+
});
|
|
591
|
+
MailerFactory.register("SES", (opt) => {
|
|
592
|
+
return new import_neko_mailer.SESProvider(opt);
|
|
593
|
+
});
|
|
594
|
+
MailerFactory.register("SMTP", (opt) => {
|
|
595
|
+
return new import_neko_mailer.SMTPProvider(opt);
|
|
596
|
+
});
|
|
597
|
+
MailerFactory.register("MEMORY", (opt) => {
|
|
598
|
+
return new import_neko_mailer.MemoryProvider();
|
|
599
|
+
});
|
|
600
|
+
var QueueFactory = class _QueueFactory {
|
|
601
|
+
static {
|
|
602
|
+
__name(this, "QueueFactory");
|
|
603
|
+
}
|
|
604
|
+
static instance = new FlexibleFactory();
|
|
605
|
+
static register(key, factory) {
|
|
606
|
+
_QueueFactory.instance.register(key, factory);
|
|
607
|
+
}
|
|
608
|
+
static create(key, ...args) {
|
|
609
|
+
return _QueueFactory.instance.create(key, ...args);
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
QueueFactory.register("database", (opt) => {
|
|
613
|
+
let transport = new DatabaseTransport(opt);
|
|
614
|
+
return new import_neko_queue.QueueConnection(transport);
|
|
615
|
+
});
|
|
616
|
+
QueueFactory.register("memory", (opt) => {
|
|
617
|
+
let transport = new import_neko_queue2.MemoryTransport(opt);
|
|
618
|
+
return new import_neko_queue.QueueConnection(transport);
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
// src/facades.mts
|
|
385
622
|
var router = (0, import_neko_helper.createSingleton)(() => new Router());
|
|
386
623
|
var scheduler = (0, import_neko_helper.createSingleton)(() => {
|
|
387
624
|
const rc = new import_neko_scheduler.Scheduler();
|
|
@@ -451,27 +688,19 @@ var logger = (0, import_neko_helper.createSingleton)((label) => {
|
|
|
451
688
|
});
|
|
452
689
|
var mailer = (0, import_neko_helper.createSingleton)((label) => {
|
|
453
690
|
const mailer_config = import_neko_config.config.get(["mailer", label].join("."));
|
|
454
|
-
let provider
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
provider = new import_neko_mailer.SMTPProvider(mailer_config.config);
|
|
466
|
-
} else if (mailer_config.provider === "MEMORY") {
|
|
467
|
-
provider = new import_neko_mailer.MemoryProvider();
|
|
468
|
-
}
|
|
469
|
-
if (!provider) {
|
|
470
|
-
throw new Error(
|
|
471
|
-
`cannot initiate mailer provider: ${mailer_config?.provider}`
|
|
472
|
-
);
|
|
691
|
+
let provider = MailerFactory.create(
|
|
692
|
+
mailer_config.provider,
|
|
693
|
+
mailer_config.config
|
|
694
|
+
);
|
|
695
|
+
const rc = new import_neko_mailer2.Mailer(provider);
|
|
696
|
+
return rc;
|
|
697
|
+
});
|
|
698
|
+
var queue = (0, import_neko_helper.createSingleton)(async (label) => {
|
|
699
|
+
const queue_config = import_neko_config.config.get(["queues", label].join("."));
|
|
700
|
+
if (!queue_config) {
|
|
701
|
+
throw new Error(`Queue configuration for '${label}' not found`);
|
|
473
702
|
}
|
|
474
|
-
const rc =
|
|
703
|
+
const rc = await QueueFactory.create(queue_config.type, queue_config);
|
|
475
704
|
return rc;
|
|
476
705
|
});
|
|
477
706
|
|