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