@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
@@ -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 (!header_content_type && typeof controller_rc === "object") {
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 import_neko_mailer = require("@devbro/neko-mailer");
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
- if (mailer_config.provider === "logger") {
456
- provider = new import_neko_mailer.FunctionProvider((mail) => {
457
- logger().info({
458
- msg: "Sending email",
459
- mail
460
- });
461
- });
462
- } else if (mailer_config.provider === "SES") {
463
- provider = new import_neko_mailer.SESProvider(mailer_config.config);
464
- } else if (mailer_config.provider === "SMTP") {
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 = new import_neko_mailer.Mailer(provider);
703
+ const rc = await QueueFactory.create(queue_config.type, queue_config);
475
704
  return rc;
476
705
  });
477
706