@venizia/ignis 0.4.1 → 0.4.3
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/base/applications/base.d.ts +1 -1
- package/dist/base/applications/base.js +1 -1
- package/dist/base/applications/base.js.map +1 -1
- package/dist/base/applications/common/types.d.ts +9 -0
- package/dist/base/applications/common/types.d.ts.map +1 -1
- package/dist/base/applications/common/types.js.map +1 -1
- package/dist/base/applications/server.d.ts +15 -1
- package/dist/base/applications/server.d.ts.map +1 -1
- package/dist/base/applications/server.js +62 -0
- package/dist/base/applications/server.js.map +1 -1
- package/dist/components/auth/authenticate/controllers/factory.d.ts +1 -1
- package/dist/components/auth/authenticate/controllers/factory.d.ts.map +1 -1
- package/dist/components/auth/models/entities/permission.model.d.ts +2 -1
- package/dist/components/auth/models/entities/permission.model.d.ts.map +1 -1
- package/dist/components/auth/models/entities/permission.model.js.map +1 -1
- package/dist/components/auth/models/entities/policy-definition.model.d.ts +2 -2
- package/dist/components/auth/models/entities/policy-definition.model.d.ts.map +1 -1
- package/dist/components/auth/models/entities/policy-definition.model.js.map +1 -1
- package/dist/components/auth/models/entities/user.model.d.ts +2 -1
- package/dist/components/auth/models/entities/user.model.d.ts.map +1 -1
- package/dist/components/auth/models/entities/user.model.js.map +1 -1
- package/dist/components/mail/common/constants.d.ts +9 -0
- package/dist/components/mail/common/constants.d.ts.map +1 -1
- package/dist/components/mail/common/constants.js +11 -1
- package/dist/components/mail/common/constants.js.map +1 -1
- package/dist/components/mail/common/types/queue.d.ts +2 -1
- package/dist/components/mail/common/types/queue.d.ts.map +1 -1
- package/dist/components/mail/common/types/queue.js.map +1 -1
- package/dist/components/mail/helpers/executors/bull-mq-executor.helper.d.ts.map +1 -1
- package/dist/components/mail/helpers/executors/bull-mq-executor.helper.js +1 -1
- package/dist/components/mail/helpers/executors/bull-mq-executor.helper.js.map +1 -1
- package/dist/components/mail/helpers/executors/internal-queue-executor.helper.js +1 -1
- package/dist/components/mail/helpers/executors/internal-queue-executor.helper.js.map +1 -1
- package/dist/components/static-asset/common/types.d.ts +2 -1
- package/dist/components/static-asset/common/types.d.ts.map +1 -1
- package/dist/components/static-asset/common/types.js.map +1 -1
- package/dist/components/static-asset/controller/factory.d.ts +1 -1
- package/dist/components/static-asset/controller/factory.d.ts.map +1 -1
- package/dist/components/static-asset/models/base.model.js +1 -1
- package/dist/components/static-asset/models/base.model.js.map +1 -1
- package/dist/presets/app/preset.json +4 -4
- package/dist/presets/lib/preset.json +3 -3
- package/package.json +8 -8
|
@@ -41,4 +41,13 @@ export declare class MailProviders {
|
|
|
41
41
|
static readonly AMAZON_SES = "amazon-ses";
|
|
42
42
|
}
|
|
43
43
|
export type TMailProvider = TConstValue<typeof MailProviders>;
|
|
44
|
+
/** How the delay between two attempts to send a queued mail grows: FIXED stays the same, EXPONENTIAL doubles. */
|
|
45
|
+
export declare class MailBackoffTypes {
|
|
46
|
+
static readonly FIXED = "fixed";
|
|
47
|
+
static readonly EXPONENTIAL = "exponential";
|
|
48
|
+
static readonly SCHEME_SET: Set<string>;
|
|
49
|
+
static isValid(value: string): boolean;
|
|
50
|
+
}
|
|
51
|
+
/** Valid mail backoff type values. */
|
|
52
|
+
export type TMailBackoffType = TConstValue<typeof MailBackoffTypes>;
|
|
44
53
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/components/mail/common/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAGjE,qBAAa,YAAY;IACvB,MAAM,CAAC,QAAQ,CAAC,iBAAiB,KAAK;IACtC,MAAM,CAAC,QAAQ,CAAC,aAAa,yBAAyB;IACtD,mFAAmF;IACnF,MAAM,CAAC,QAAQ,CAAC,oBAAoB,SAAoB;CACzD;AAED,yKAAyK;AACzK,qBAAa,cAAc;IACzB,MAAM,CAAC,QAAQ,CAAC,qBAAqB,SAElC;IACH,MAAM,CAAC,QAAQ,CAAC,WAAW,SAAiE;IAC5F,MAAM,CAAC,QAAQ,CAAC,mBAAmB,SAEhC;IACH,MAAM,CAAC,QAAQ,CAAC,iBAAiB,SAE9B;IACH,MAAM,CAAC,QAAQ,CAAC,iBAAiB,SAE9B;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,SAE/B;IACH,MAAM,CAAC,QAAQ,CAAC,uBAAuB,SAEpC;IACH,MAAM,CAAC,QAAQ,CAAC,oBAAoB,SAEjC;IACH,MAAM,CAAC,QAAQ,CAAC,mBAAmB,SAEhC;CACJ;AAED,qBAAa,kBAAkB;IAC7B,MAAM,CAAC,QAAQ,CAAC,iBAAiB,mDAAmD;CACrF;AAED,qBAAa,sBAAsB;IACjC,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAClC,MAAM,CAAC,QAAQ,CAAC,cAAc,oBAAoB;IAClD,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAElC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAAoE;IAC9F,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAGvC;AAED,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAgB;IAC1C,MAAM,CAAC,QAAQ,CAAC,WAAW,iBAAiB;IAC5C,MAAM,CAAC,QAAQ,CAAC,IAAI,UAAU;IAE9B,MAAM,CAAC,QAAQ,CAAC,QAAQ,cAAmE;IAC3F,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAGvC;AAED,qBAAa,aAAa;IACxB,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAgB;IAC1C,MAAM,CAAC,QAAQ,CAAC,OAAO,aAAa;IACpC,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAElC,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAgB;CAC3C;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,aAAa,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/components/mail/common/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAGjE,qBAAa,YAAY;IACvB,MAAM,CAAC,QAAQ,CAAC,iBAAiB,KAAK;IACtC,MAAM,CAAC,QAAQ,CAAC,aAAa,yBAAyB;IACtD,mFAAmF;IACnF,MAAM,CAAC,QAAQ,CAAC,oBAAoB,SAAoB;CACzD;AAED,yKAAyK;AACzK,qBAAa,cAAc;IACzB,MAAM,CAAC,QAAQ,CAAC,qBAAqB,SAElC;IACH,MAAM,CAAC,QAAQ,CAAC,WAAW,SAAiE;IAC5F,MAAM,CAAC,QAAQ,CAAC,mBAAmB,SAEhC;IACH,MAAM,CAAC,QAAQ,CAAC,iBAAiB,SAE9B;IACH,MAAM,CAAC,QAAQ,CAAC,iBAAiB,SAE9B;IACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,SAE/B;IACH,MAAM,CAAC,QAAQ,CAAC,uBAAuB,SAEpC;IACH,MAAM,CAAC,QAAQ,CAAC,oBAAoB,SAEjC;IACH,MAAM,CAAC,QAAQ,CAAC,mBAAmB,SAEhC;CACJ;AAED,qBAAa,kBAAkB;IAC7B,MAAM,CAAC,QAAQ,CAAC,iBAAiB,mDAAmD;CACrF;AAED,qBAAa,sBAAsB;IACjC,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAClC,MAAM,CAAC,QAAQ,CAAC,cAAc,oBAAoB;IAClD,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAElC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAAoE;IAC9F,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAGvC;AAED,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAgB;IAC1C,MAAM,CAAC,QAAQ,CAAC,WAAW,iBAAiB;IAC5C,MAAM,CAAC,QAAQ,CAAC,IAAI,UAAU;IAE9B,MAAM,CAAC,QAAQ,CAAC,QAAQ,cAAmE;IAC3F,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAGvC;AAED,qBAAa,aAAa;IACxB,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAgB;IAC1C,MAAM,CAAC,QAAQ,CAAC,OAAO,aAAa;IACpC,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAElC,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAgB;CAC3C;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,aAAa,CAAC,CAAC;AAE9D,iHAAiH;AACjH,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAChC,MAAM,CAAC,QAAQ,CAAC,WAAW,iBAAiB;IAE5C,MAAM,CAAC,QAAQ,CAAC,UAAU,cAAmD;IAE7E,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAGvC;AAED,sCAAsC;AACtC,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MailProviders = exports.BullMQExecutorModes = exports.MailQueueExecutorTypes = exports.MailExecutorErrors = exports.MailErrorCodes = exports.MailDefaults = void 0;
|
|
3
|
+
exports.MailBackoffTypes = exports.MailProviders = exports.BullMQExecutorModes = exports.MailQueueExecutorTypes = exports.MailExecutorErrors = exports.MailErrorCodes = exports.MailDefaults = void 0;
|
|
4
4
|
const core_1 = require("@venizia/ignis-helpers/core");
|
|
5
5
|
class MailDefaults {
|
|
6
6
|
static { this.BATCH_CONCURRENCY = 5; }
|
|
@@ -70,4 +70,14 @@ class MailProviders {
|
|
|
70
70
|
static { this.AMAZON_SES = 'amazon-ses'; }
|
|
71
71
|
}
|
|
72
72
|
exports.MailProviders = MailProviders;
|
|
73
|
+
/** How the delay between two attempts to send a queued mail grows: FIXED stays the same, EXPONENTIAL doubles. */
|
|
74
|
+
class MailBackoffTypes {
|
|
75
|
+
static { this.FIXED = 'fixed'; }
|
|
76
|
+
static { this.EXPONENTIAL = 'exponential'; }
|
|
77
|
+
static { this.SCHEME_SET = new Set([this.FIXED, this.EXPONENTIAL]); }
|
|
78
|
+
static isValid(value) {
|
|
79
|
+
return this.SCHEME_SET.has(value);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.MailBackoffTypes = MailBackoffTypes;
|
|
73
83
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/components/mail/common/constants.ts"],"names":[],"mappings":";;;AACA,sDAA0D;AAE1D,MAAa,YAAY;aACP,sBAAiB,GAAG,CAAC,CAAC;aACtB,kBAAa,GAAG,qBAAqB,CAAC;IACtD,mFAAmF;aACnE,yBAAoB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;;AAJ1D,oCAKC;AAED,yKAAyK;AACzK,MAAa,cAAc;aACT,0BAAqB,GAAG,kBAAW,CAAC,KAAK,CAAC;QACxD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,uBAAuB,CAAC;KACjD,CAAC,CAAC;aACa,gBAAW,GAAG,kBAAW,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;aAC5E,wBAAmB,GAAG,kBAAW,CAAC,KAAK,CAAC;QACtD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,qBAAqB,CAAC;KAC/C,CAAC,CAAC;aACa,sBAAiB,GAAG,kBAAW,CAAC,KAAK,CAAC;QACpD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,mBAAmB,CAAC;KAC7C,CAAC,CAAC;aACa,sBAAiB,GAAG,kBAAW,CAAC,KAAK,CAAC;QACpD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,mBAAmB,CAAC;KAC7C,CAAC,CAAC;aACa,uBAAkB,GAAG,kBAAW,CAAC,KAAK,CAAC;QACrD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,oBAAoB,CAAC;KAC9C,CAAC,CAAC;aACa,4BAAuB,GAAG,kBAAW,CAAC,KAAK,CAAC;QAC1D,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,yBAAyB,CAAC;KACnD,CAAC,CAAC;aACa,yBAAoB,GAAG,kBAAW,CAAC,KAAK,CAAC;QACvD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,sBAAsB,CAAC;KAChD,CAAC,CAAC;aACa,wBAAmB,GAAG,kBAAW,CAAC,KAAK,CAAC;QACtD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,qBAAqB,CAAC;KAC/C,CAAC,CAAC;;AAzBL,wCA0BC;AAED,MAAa,kBAAkB;aACb,sBAAiB,GAAG,+CAA+C,CAAC;;AADtF,gDAEC;AAED,MAAa,sBAAsB;aACjB,WAAM,GAAG,QAAQ,CAAC;aAClB,mBAAc,GAAG,gBAAgB,CAAC;aAClC,WAAM,GAAG,QAAQ,CAAC;aAElB,eAAU,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9F,MAAM,CAAC,OAAO,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;;AARH,wDASC;AAED,MAAa,mBAAmB;aACd,eAAU,GAAG,YAAY,CAAC;aAC1B,gBAAW,GAAG,aAAa,CAAC;aAC5B,SAAI,GAAG,MAAM,CAAC;aAEd,aAAQ,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3F,MAAM,CAAC,OAAO,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;;AARH,kDASC;AAED,MAAa,aAAa;aACR,eAAU,GAAG,YAAY,CAAC;aAC1B,YAAO,GAAG,SAAS,CAAC;aACpB,WAAM,GAAG,QAAQ,CAAC;IAClC,uHAAuH;aACvG,eAAU,GAAG,YAAY,CAAC;;AAL5C,sCAMC","sourcesContent":["import type { TConstValue } from '@venizia/ignis-helpers/common';\nimport { MessageCode } from '@venizia/ignis-helpers/core';\n\nexport class MailDefaults {\n static readonly BATCH_CONCURRENCY = 5;\n static readonly FALLBACK_FROM = 'noreply@example.com';\n /** Bytes of attachment content one message may carry, all attachments together. */\n static readonly MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;\n}\n\n/** Built via {@link MessageCode.build}: `ApplicationError` lower-cases codes, so a SCREAMING_CASE literal would reach the client in a spelling no const here matches. */\nexport class MailErrorCodes {\n static readonly INVALID_CONFIGURATION = MessageCode.build({\n parts: ['core', 'mail', 'invalid_configuration'],\n });\n static readonly SEND_FAILED = MessageCode.build({ parts: ['core', 'mail', 'send_failed'] });\n static readonly VERIFICATION_FAILED = MessageCode.build({\n parts: ['core', 'mail', 'verification_failed'],\n });\n static readonly INVALID_RECIPIENT = MessageCode.build({\n parts: ['core', 'mail', 'invalid_recipient'],\n });\n static readonly BATCH_SEND_FAILED = MessageCode.build({\n parts: ['core', 'mail', 'batch_send_failed'],\n });\n static readonly TEMPLATE_NOT_FOUND = MessageCode.build({\n parts: ['core', 'mail', 'template_not_found'],\n });\n static readonly ATTACHMENT_PATH_REFUSED = MessageCode.build({\n parts: ['core', 'mail', 'attachment_path_refused'],\n });\n static readonly ATTACHMENT_TOO_LARGE = MessageCode.build({\n parts: ['core', 'mail', 'attachment_too_large'],\n });\n static readonly BODY_SOURCE_REFUSED = MessageCode.build({\n parts: ['core', 'mail', 'body_source_refused'],\n });\n}\n\nexport class MailExecutorErrors {\n static readonly PROCESSOR_NOT_SET = 'Processor not set. Call setProcessor() first.';\n}\n\nexport class MailQueueExecutorTypes {\n static readonly DIRECT = 'direct';\n static readonly INTERNAL_QUEUE = 'internal-queue';\n static readonly BULLMQ = 'bullmq';\n\n static readonly SCHEME_SET = new Set<string>([this.DIRECT, this.INTERNAL_QUEUE, this.BULLMQ]);\n static isValid(value: string): boolean {\n return this.SCHEME_SET.has(value);\n }\n}\n\nexport class BullMQExecutorModes {\n static readonly QUEUE_ONLY = 'queue-only';\n static readonly WORKER_ONLY = 'worker-only';\n static readonly BOTH = 'both';\n\n static readonly MODE_SET = new Set<string>([this.QUEUE_ONLY, this.WORKER_ONLY, this.BOTH]);\n static isValid(value: string): boolean {\n return this.MODE_SET.has(value);\n }\n}\n\nexport class MailProviders {\n static readonly NODEMAILER = 'nodemailer';\n static readonly MAILGUN = 'mailgun';\n static readonly CUSTOM = 'custom';\n // Amazon SES supports both SMTP and HTTPS - this provider is the HTTPS API path; SMTP goes through NODEMAILER instead.\n static readonly AMAZON_SES = 'amazon-ses';\n}\n\nexport type TMailProvider = TConstValue<typeof MailProviders>;\n"]}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/components/mail/common/constants.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TConstValue } from '@venizia/ignis-helpers/common';\nimport { MessageCode } from '@venizia/ignis-helpers/core';\n\nexport class MailDefaults {\n static readonly BATCH_CONCURRENCY = 5;\n static readonly FALLBACK_FROM = 'noreply@example.com';\n /** Bytes of attachment content one message may carry, all attachments together. */\n static readonly MAX_ATTACHMENT_BYTES = 25 * 1024 * 1024;\n}\n\n/** Built via {@link MessageCode.build}: `ApplicationError` lower-cases codes, so a SCREAMING_CASE literal would reach the client in a spelling no const here matches. */\nexport class MailErrorCodes {\n static readonly INVALID_CONFIGURATION = MessageCode.build({\n parts: ['core', 'mail', 'invalid_configuration'],\n });\n static readonly SEND_FAILED = MessageCode.build({ parts: ['core', 'mail', 'send_failed'] });\n static readonly VERIFICATION_FAILED = MessageCode.build({\n parts: ['core', 'mail', 'verification_failed'],\n });\n static readonly INVALID_RECIPIENT = MessageCode.build({\n parts: ['core', 'mail', 'invalid_recipient'],\n });\n static readonly BATCH_SEND_FAILED = MessageCode.build({\n parts: ['core', 'mail', 'batch_send_failed'],\n });\n static readonly TEMPLATE_NOT_FOUND = MessageCode.build({\n parts: ['core', 'mail', 'template_not_found'],\n });\n static readonly ATTACHMENT_PATH_REFUSED = MessageCode.build({\n parts: ['core', 'mail', 'attachment_path_refused'],\n });\n static readonly ATTACHMENT_TOO_LARGE = MessageCode.build({\n parts: ['core', 'mail', 'attachment_too_large'],\n });\n static readonly BODY_SOURCE_REFUSED = MessageCode.build({\n parts: ['core', 'mail', 'body_source_refused'],\n });\n}\n\nexport class MailExecutorErrors {\n static readonly PROCESSOR_NOT_SET = 'Processor not set. Call setProcessor() first.';\n}\n\nexport class MailQueueExecutorTypes {\n static readonly DIRECT = 'direct';\n static readonly INTERNAL_QUEUE = 'internal-queue';\n static readonly BULLMQ = 'bullmq';\n\n static readonly SCHEME_SET = new Set<string>([this.DIRECT, this.INTERNAL_QUEUE, this.BULLMQ]);\n static isValid(value: string): boolean {\n return this.SCHEME_SET.has(value);\n }\n}\n\nexport class BullMQExecutorModes {\n static readonly QUEUE_ONLY = 'queue-only';\n static readonly WORKER_ONLY = 'worker-only';\n static readonly BOTH = 'both';\n\n static readonly MODE_SET = new Set<string>([this.QUEUE_ONLY, this.WORKER_ONLY, this.BOTH]);\n static isValid(value: string): boolean {\n return this.MODE_SET.has(value);\n }\n}\n\nexport class MailProviders {\n static readonly NODEMAILER = 'nodemailer';\n static readonly MAILGUN = 'mailgun';\n static readonly CUSTOM = 'custom';\n // Amazon SES supports both SMTP and HTTPS - this provider is the HTTPS API path; SMTP goes through NODEMAILER instead.\n static readonly AMAZON_SES = 'amazon-ses';\n}\n\nexport type TMailProvider = TConstValue<typeof MailProviders>;\n\n/** How the delay between two attempts to send a queued mail grows: FIXED stays the same, EXPONENTIAL doubles. */\nexport class MailBackoffTypes {\n static readonly FIXED = 'fixed';\n static readonly EXPONENTIAL = 'exponential';\n\n static readonly SCHEME_SET = new Set<string>([this.FIXED, this.EXPONENTIAL]);\n\n static isValid(value: string): boolean {\n return this.SCHEME_SET.has(value);\n }\n}\n\n/** Valid mail backoff type values. */\nexport type TMailBackoffType = TConstValue<typeof MailBackoffTypes>;\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TMailBackoffType } from '../constants';
|
|
1
2
|
import type { TConstValue } from '@venizia/ignis-helpers/common';
|
|
2
3
|
import type { IRedisSingleHelperOptions } from '@venizia/ignis-helpers';
|
|
3
4
|
import type { BullMQExecutorModes, MailQueueExecutorTypes } from '../constants';
|
|
@@ -6,7 +7,7 @@ export interface IMailQueueOptions {
|
|
|
6
7
|
delay?: number;
|
|
7
8
|
attempts?: number;
|
|
8
9
|
backoff?: {
|
|
9
|
-
type:
|
|
10
|
+
type: TMailBackoffType;
|
|
10
11
|
delay: number;
|
|
11
12
|
};
|
|
12
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../../../src/components/mail/common/types/queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEhF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../../../src/components/mail/common/types/queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEhF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,gBAAgB,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAChG,YAAY,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC;CACjF;AAED,sFAAsF;AACtF,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,8BAA8B;IAC7C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,2EAA2E;IAC3E,KAAK,EAAE,yBAAyB,CAAC;IACjC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,IAAI,EAAE,WAAW,CAAC,OAAO,mBAAmB,CAAC,CAAC;IAC9C,sGAAsG;IACtG,MAAM,CAAC,EAAE,cAAc,QAAQ,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,WAAW,CAAC,OAAO,sBAAsB,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,8BAA8B,CAAC;IAC/C,MAAM,CAAC,EAAE,uBAAuB,CAAC;CAClC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../../../src/components/mail/common/types/queue.ts"],"names":[],"mappings":"","sourcesContent":["import type { TConstValue } from '@venizia/ignis-helpers/common';\nimport type { IRedisSingleHelperOptions } from '@venizia/ignis-helpers';\nimport type { BullMQExecutorModes, MailQueueExecutorTypes } from '../constants';\n\nexport interface IMailQueueOptions {\n priority?: number;\n delay?: number;\n attempts?: number;\n backoff?: {\n type:
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../../../src/components/mail/common/types/queue.ts"],"names":[],"mappings":"","sourcesContent":["import type { TMailBackoffType } from '../constants';\nimport type { TConstValue } from '@venizia/ignis-helpers/common';\nimport type { IRedisSingleHelperOptions } from '@venizia/ignis-helpers';\nimport type { BullMQExecutorModes, MailQueueExecutorTypes } from '../constants';\n\nexport interface IMailQueueOptions {\n priority?: number;\n delay?: number;\n attempts?: number;\n backoff?: {\n type: TMailBackoffType;\n delay: number;\n };\n}\n\nexport interface IMailProcessorResult {\n success: boolean;\n message: string;\n expiresInMinutes: number;\n nextResendAt?: string;\n}\n\nexport interface IMailQueueResult {\n jobId?: string;\n queued: boolean;\n message: string;\n result?: IMailProcessorResult;\n}\n\nexport interface IMailQueueExecutor {\n enqueueVerificationEmail(email: string, options?: IMailQueueOptions): Promise<IMailQueueResult>;\n setProcessor(processor: (email: string) => Promise<IMailProcessorResult>): void;\n}\n\n/** Envelope every queue-backed executor stores for one pending verification email. */\nexport interface IQueueJobPayload {\n id: string;\n email: string;\n options?: IMailQueueOptions;\n attempts: number;\n scheduledAt: number;\n}\n\nexport interface IInternalQueueMailExecutorOpts {\n identifier: string;\n}\n\nexport interface IBullMQMailExecutorOpts {\n /** `redis.module` passes `ioredis` itself - see `module` below for why. */\n redis: IRedisSingleHelperOptions;\n queue: { identifier: string; name: string };\n mode: TConstValue<typeof BullMQExecutorModes>;\n /** `bullmq` itself, for a `bun build --compile` binary that has no `node_modules` to load it from. */\n module?: typeof import('bullmq');\n}\n\nexport interface IMailQueueExecutorConfig {\n type: TConstValue<typeof MailQueueExecutorTypes>;\n internalQueue?: IInternalQueueMailExecutorOpts;\n bullmq?: IBullMQMailExecutorOpts;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bull-mq-executor.helper.d.ts","sourceRoot":"","sources":["../../../../../src/components/mail/helpers/executors/bull-mq-executor.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAY,MAAM,6BAA6B,CAAC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAEjB,MAAM,cAAc,CAAC;AACtB,OAAO,
|
|
1
|
+
{"version":3,"file":"bull-mq-executor.helper.d.ts","sourceRoot":"","sources":["../../../../../src/components/mail/helpers/executors/bull-mq-executor.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAY,MAAM,6BAA6B,CAAC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAEjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,mBAAmB,EAIpB,MAAM,cAAc,CAAC;AAGtB,qBAAa,wBAAyB,SAAQ,UAAW,YAAW,kBAAkB;IACpF,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,IAAI,CAA0C;IAEtD,OAAO,CAAC,WAAW,CAAC,CAAmD;IACvE,OAAO,CAAC,aAAa,CAA8D;IACnF,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAA0B;IACxD,OAAO,CAAC,YAAY,CAAK;IAEzB,OAAO,CAAC,SAAS,CAAC,CAAmD;gBAEzD,IAAI,EAAE,uBAAuB;IAiBzC,SAAS,CAAC,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAmC/C,YAAY,CAChB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,EAC3D,IAAI,CAAC,EAAE;QACL,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GACA,OAAO,CAAC,IAAI,CAAC;IAkChB,SAAS,CAAC,IAAI,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAsG1F,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBnD,6JAA6J;YAC/I,YAAY;IA2BpB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC,sLAAsL;IAChL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC5B,cAAc,IAAI,MAAM;IAIxB,OAAO,IAAI,WAAW,CAAC,OAAO,mBAAmB,CAAC;IAI5C,wBAAwB,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC;CAqD7B"}
|
|
@@ -232,7 +232,7 @@ class BullMQMailExecutorHelper extends core_1.BaseHelper {
|
|
|
232
232
|
delay: options?.delay,
|
|
233
233
|
attempts: options?.attempts ?? 3,
|
|
234
234
|
backoff: {
|
|
235
|
-
type: options?.backoff?.type ??
|
|
235
|
+
type: options?.backoff?.type ?? common_1.MailBackoffTypes.EXPONENTIAL,
|
|
236
236
|
delay: options?.backoff?.delay ?? 1000,
|
|
237
237
|
},
|
|
238
238
|
removeOnComplete: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bull-mq-executor.helper.js","sourceRoot":"","sources":["../../../../../src/components/mail/helpers/executors/bull-mq-executor.helper.ts"],"names":[],"mappings":";;;AAAA,sDAAmE;AACnE,0DAA2D;AAE3D,0DAA6D;AAS7D,yCAAuF;AAGvF,MAAa,wBAAyB,SAAQ,iBAAU;IAatD,YAAY,IAA6B;QACvC,KAAK,CAAC,EAAE,KAAK,EAAE,wBAAwB,CAAC,IAAI,EAAE,CAAC,CAAC;QAR1C,kBAAa,GAA2D,EAAE,CAAC;QAG3E,iBAAY,GAAG,CAAC,CAAC;QAOvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAEtB,IAAI,CAAC,eAAe,GAAG,IAAI,iCAAiB,CAAC;YAC3C,GAAG,IAAI,CAAC,KAAK;YACb,QAAQ,EAAE,SAAS;SACpB,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;QAC7C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAEjC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,SAAS,CAAC,KAA2C;QACnD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,4BAAmB,CAAC,UAAU,CAAC;YACpC,KAAK,4BAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,qBAAY,CAAqC;oBACtE,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,SAAS,EAAE,KAAK,CAAC,IAAI;oBACrB,eAAe,EAAE,IAAI,CAAC,eAAe;oBACrC,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE,IAAI,CAAC,YAAY;iBAC1B,CAAC,CAAC;gBAEH,IAAI,CAAC,MAAM;qBACR,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;qBAC1B,IAAI,CACH,+EAA+E,EAC/E,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,IAAI,CACV,CAAC;gBACJ,MAAM;YACR,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,IAAI,CAAC,MAAM;qBACR,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;qBAC1B,IAAI,CACH,kFAAkF,EAClF,IAAI,CAAC,eAAe,EACpB,IAAI,CAAC,IAAI,CACV,CAAC;gBAEJ,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,SAA2D,EAC3D,IAIC;QAED,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAE3B,IAAI,IAAI,CAAC,IAAI,KAAK,4BAAmB,CAAC,UAAU,EAAE,CAAC;YACjD,IAAI,CAAC,MAAM;iBACR,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;iBAC3B,IAAI,CAAC,2EAA2E,CAAC,CAAC;YACrF,OAAO;QACT,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,EAAE,eAAe,IAAI,CAAC,CAAC;QACnD,MAAM,oBAAoB,GAAG,IAAI,EAAE,oBAAoB,IAAI,CAAC,CAAC;QAC7D,MAAM,YAAY,GAAG,IAAI,EAAE,YAAY,IAAI,KAAK,CAAC;QAEjD,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAE1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC,SAAS,CAAC;gBACb,gBAAgB,EAAE,GAAG,IAAI,CAAC,eAAe,WAAW,CAAC,EAAE;gBACvD,WAAW,EAAE,oBAAoB;gBACjC,YAAY;aACb,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM;aACR,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;aAC3B,IAAI,CACH,4EAA4E,EAC5E,IAAI,CAAC,IAAI,EACT,eAAe,EACf,oBAAoB,CACrB,CAAC;IACN,CAAC;IAED,SAAS,CAAC,IAA+E;QACvF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,IAAA,eAAQ,EAAC,EAAE,OAAO,EAAE,2BAAkB,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC/C,MAAM,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,IAAI,EAAE,YAAY,IAAI,KAAK,CAAC;QAEjD,MAAM,YAAY,GAAG,IAAI,qBAAY,CAAyC;YAC5E,UAAU,EAAE,gBAAgB;YAC5B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,IAAI,CAAC,YAAY;YACzB,cAAc,EAAE,WAAW;YAC3B,YAAY;YACZ,YAAY,EAAE,KAAK,EAAE,GAAgD,EAAE,EAAE;gBACvE,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,IAAI,CAAC,CAAC;gBAEpD,IAAI,CAAC,MAAM;qBACR,GAAG,CAAC,cAAc,CAAC;qBACnB,IAAI,CACH,sEAAsE,EACtE,gBAAgB,EAChB,GAAG,CAAC,IAAI,CAAC,EAAE,EACX,GAAG,CAAC,IAAI,CAAC,KAAK,EACd,GAAG,CAAC,YAAY,GAAG,CAAC,EACpB,WAAW,CACZ,CAAC;gBAEJ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpB,6HAA6H;oBAC7H,MAAM,IAAA,eAAQ,EAAC;wBACb,WAAW,EAAE,uBAAc,CAAC,WAAW;wBACvC,OAAO,EAAE,kBAAkB,2BAAkB,CAAC,iBAAiB,aAAa,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE;qBAC1F,CAAC,CAAC;gBACL,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAEpD,sKAAsK;gBACtK,IAAI,MAAM,EAAE,OAAO,KAAK,KAAK,EAAE,CAAC;oBAC9B,MAAM,IAAA,eAAQ,EAAC;wBACb,WAAW,EAAE,uBAAc,CAAC,WAAW;wBACvC,OAAO,EAAE,sDAAsD,GAAG,CAAC,IAAI,CAAC,EAAE,cAAc,MAAM,CAAC,OAAO,EAAE;qBACzG,CAAC,CAAC;gBACL,CAAC;gBAED,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,qBAAqB,EAAE,KAAK,EAAE,GAAgD,EAAE,EAAE;gBAChF,IAAI,CAAC,MAAM;qBACR,GAAG,CAAC,uBAAuB,CAAC;qBAC5B,IAAI,CACH,oDAAoD,EACpD,gBAAgB,EAChB,GAAG,CAAC,IAAI,CAAC,EAAE,EACX,GAAG,CAAC,IAAI,CAAC,KAAK,CACf,CAAC;YACN,CAAC;YACD,gBAAgB,EAAE,KAAK,EACrB,GAA4D,EAC5D,KAAY,EACZ,EAAE;gBACF,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,IAAI,CAAC,CAAC;oBACpD,IAAI,CAAC,MAAM;yBACR,GAAG,CAAC,kBAAkB,CAAC;yBACvB,KAAK,CACJ,8EAA8E,EAC9E,gBAAgB,EAChB,GAAG,CAAC,IAAI,CAAC,EAAE,EACX,GAAG,CAAC,IAAI,CAAC,KAAK,EACd,GAAG,CAAC,YAAY,EAChB,WAAW,EACX,KAAK,CAAC,OAAO,CACd,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM;yBACR,GAAG,CAAC,kBAAkB,CAAC;yBACvB,KAAK,CACJ,gDAAgD,EAChD,gBAAgB,EAChB,KAAK,CAAC,OAAO,CACd,CAAC;gBACN,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAEtC,IAAI,CAAC,MAAM;aACR,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aACxB,IAAI,CACH,qEAAqE,EACrE,gBAAgB,EAChB,WAAW,EACX,IAAI,CAAC,aAAa,CAAC,MAAM,CAC1B,CAAC;IACN,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAa;QAC9B,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YACpD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;YAChF,OAAO,KAAK,CAAC;QACf,CAAC;QAED,gJAAgJ;QAChJ,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAElC,IAAI,CAAC,MAAM;aACR,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;aAC3B,IAAI,CAAC,oDAAoD,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAEhG,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6JAA6J;IACrJ,KAAK,CAAC,YAAY;QACxB,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACzC,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QAExB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CACjE,CAAC;QAEF,MAAM,QAAQ,GAAY,EAAE,CAAC;QAE7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;gBACjC,SAAS;YACX,CAAC;YAED,MAAM,KAAK,GACT,MAAM,CAAC,MAAM,YAAY,KAAK;gBAC5B,CAAC,CAAC,MAAM,CAAC,MAAM;gBACf,CAAC,CAAC,IAAA,eAAQ,EAAC,EAAE,OAAO,EAAE,iCAAiC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;YAEtF,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7F,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QACxC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAE1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;IACzF,CAAC;IAED,sLAAsL;IACtL,KAAK,CAAC,KAAK;QACT,MAAM,QAAQ,GAAY,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QAE3D,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACvC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,UAAU,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,eAAQ,EAAC,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACzF,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,mCAAmC,EAAE,UAAU,CAAC,CAAC;YAC1F,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,eAAe,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAA,eAAQ,EAAC,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9F,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC/B,IAAI,CAAC,MAAM;iBACR,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;iBACpB,KAAK,CAAC,wCAAwC,EAAE,eAAe,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAA,eAAQ,EAAC;gBACb,OAAO,EAAE,gEAAgE,QAAQ;qBAC9E,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;qBACjC,IAAI,CAAC,KAAK,CAAC,EAAE;aACjB,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,wCAAwC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7F,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;IACnC,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,wBAAwB,CAC5B,KAAa,EACb,OAA2B;QAE3B,IAAI,IAAI,CAAC,IAAI,KAAK,4BAAmB,CAAC,WAAW,EAAE,CAAC;YAClD,MAAM,IAAA,eAAQ,EAAC;gBACb,OAAO,EAAE,8EAA8E;aACxF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAA,eAAQ,EAAC;gBACb,OAAO,EAAE,6EAA6E;aACvF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,4BAAmB,CAAC,UAAU,EAAE,CAAC;YACpE,MAAM,IAAA,eAAQ,EAAC,EAAE,OAAO,EAAE,2BAAkB,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACzD,MAAM,GAAG,GAAqB;YAC5B,EAAE,EAAE,KAAK;YACT,KAAK;YACL,OAAO;YACP,QAAQ,EAAE,CAAC;YACX,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC;SAChD,CAAC;QAEF,IAAI,CAAC,MAAM;aACR,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC;aACvC,IAAI,CACH,kEAAkE,EAClE,KAAK,EACL,KAAK,EACL,IAAI,CAAC,IAAI,CACV,CAAC;QAEJ,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,EAAE,GAAG,EAAE;YAC/E,QAAQ,EAAE,OAAO,EAAE,QAAQ;YAC3B,KAAK,EAAE,OAAO,EAAE,KAAK;YACrB,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAC;YAChC,OAAO,EAAE;gBACP,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,IAAI,aAAa;gBAC7C,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,IAAI,IAAI;aACvC;YACD,gBAAgB,EAAE,IAAI;YACtB,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;QAEH,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,EAAE,IAAI,KAAK;YAC1B,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,0CAA0C;SACpD,CAAC;IACJ,CAAC;CACF;AAvWD,4DAuWC","sourcesContent":["import { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { RedisSingleHelper } from '@venizia/ignis-helpers';\nimport type { TConstValue } from '@/helpers';\nimport { BullMQHelper } from '@venizia/ignis-helpers/bullmq';\nimport type {\n IBullMQMailExecutorOpts,\n IMailProcessorResult,\n IMailQueueExecutor,\n IMailQueueOptions,\n IMailQueueResult,\n IQueueJobPayload,\n} from '../../common';\nimport { BullMQExecutorModes, MailErrorCodes, MailExecutorErrors } from '../../common';\nimport type { Job } from 'bullmq';\n\nexport class BullMQMailExecutorHelper extends BaseHelper implements IMailQueueExecutor {\n private queueIdentifier: string;\n private queueName: string;\n private mode: TConstValue<typeof BullMQExecutorModes>;\n\n private queueHelper?: BullMQHelper<IQueueJobPayload, IMailQueueResult>;\n private workerHelpers: BullMQHelper<IQueueJobPayload, IMailProcessorResult>[] = [];\n private redisConnection: RedisSingleHelper;\n private readonly bullmqModule?: typeof import('bullmq');\n private jobIdCounter = 0;\n\n private processor?: (email: string) => Promise<IMailProcessorResult>;\n\n constructor(opts: IBullMQMailExecutorOpts) {\n super({ scope: BullMQMailExecutorHelper.name });\n\n this.mode = opts.mode;\n\n this.redisConnection = new RedisSingleHelper({\n ...opts.redis,\n maxRetry: undefined,\n });\n\n this.bullmqModule = opts.module;\n this.queueIdentifier = opts.queue.identifier;\n this.queueName = opts.queue.name;\n\n this.initQueue(opts.queue);\n }\n\n initQueue(queue: { identifier: string; name: string }) {\n switch (this.mode) {\n case BullMQExecutorModes.QUEUE_ONLY:\n case BullMQExecutorModes.BOTH: {\n this.queueHelper = new BullMQHelper<IQueueJobPayload, IMailQueueResult>({\n identifier: queue.identifier,\n queueName: queue.name,\n redisConnection: this.redisConnection,\n role: 'queue',\n module: this.bullmqModule,\n });\n\n this.logger\n .for(this.constructor.name)\n .info(\n 'BullMQ queue executor initialized (queue enabled) | Identifier: %s | Mode: %s',\n this.queueIdentifier,\n this.mode,\n );\n break;\n }\n default: {\n this.logger\n .for(this.constructor.name)\n .info(\n 'BullMQ queue executor initialized (worker-only mode) | Identifier: %s | Mode: %s',\n this.queueIdentifier,\n this.mode,\n );\n\n break;\n }\n }\n }\n\n async setProcessor(\n processor: (email: string) => Promise<IMailProcessorResult>,\n opts?: {\n numberOfWorkers?: number;\n concurrencyPerWorker?: number;\n lockDuration?: number;\n },\n ): Promise<void> {\n this.processor = processor;\n\n if (this.mode === BullMQExecutorModes.QUEUE_ONLY) {\n this.logger\n .for(this.setProcessor.name)\n .warn('Skipping worker creation in queue-only mode. Workers will not be started.');\n return;\n }\n\n const numberOfWorkers = opts?.numberOfWorkers ?? 1;\n const concurrencyPerWorker = opts?.concurrencyPerWorker ?? 5;\n const lockDuration = opts?.lockDuration ?? 30000;\n\n await this.clearWorkers();\n\n for (let i = 0; i < numberOfWorkers; i++) {\n this.addWorker({\n workerIdentifier: `${this.queueIdentifier}-worker-${i}`,\n concurrency: concurrencyPerWorker,\n lockDuration,\n });\n }\n\n this.logger\n .for(this.setProcessor.name)\n .info(\n 'Processor registered | Mode: %s | Workers: %d | Concurrency per worker: %d',\n this.mode,\n numberOfWorkers,\n concurrencyPerWorker,\n );\n }\n\n addWorker(opts: { workerIdentifier: string; concurrency?: number; lockDuration?: number }): void {\n if (!this.processor) {\n throw getError({ message: MailExecutorErrors.PROCESSOR_NOT_SET });\n }\n\n const workerIdentifier = opts.workerIdentifier;\n const concurrency = opts?.concurrency ?? 5;\n const lockDuration = opts?.lockDuration ?? 30000;\n\n const workerHelper = new BullMQHelper<IQueueJobPayload, IMailProcessorResult>({\n identifier: workerIdentifier,\n queueName: this.queueName,\n redisConnection: this.redisConnection,\n role: 'worker',\n module: this.bullmqModule,\n numberOfWorker: concurrency,\n lockDuration,\n onWorkerData: async (job: Job<IQueueJobPayload, IMailProcessorResult>) => {\n const maxAttempts = job.data.options?.attempts ?? 3;\n\n this.logger\n .for('onWorkerData')\n .info(\n 'Processing job | Worker: %s | jobId: %s | email: %s | attempt: %d/%d',\n workerIdentifier,\n job.data.id,\n job.data.email,\n job.attemptsMade + 1,\n maxAttempts,\n );\n\n if (!this.processor) {\n // Returning undefined would let BullMQ mark the job COMPLETED and (with removeOnComplete) delete it - mail silently dropped.\n throw getError({\n messageCode: MailErrorCodes.SEND_FAILED,\n message: `[onWorkerData] ${MailExecutorErrors.PROCESSOR_NOT_SET} | jobId: ${job.data.id}`,\n });\n }\n\n const result = await this.processor(job.data.email);\n\n // A processor reports SMTP rejection by RETURNING `{ success: false }`; BullMQ only treats a REJECTION as failure, so resolving completes the job - no retry, no DLQ.\n if (result?.success === false) {\n throw getError({\n messageCode: MailErrorCodes.SEND_FAILED,\n message: `[onWorkerData] Processor reported failure | jobId: ${job.data.id} | reason: ${result.message}`,\n });\n }\n\n return result;\n },\n onWorkerDataCompleted: async (job: Job<IQueueJobPayload, IMailProcessorResult>) => {\n this.logger\n .for('onWorkerDataCompleted')\n .info(\n 'Job completed | Worker: %s | jobId: %s | email: %s',\n workerIdentifier,\n job.data.id,\n job.data.email,\n );\n },\n onWorkerDataFail: async (\n job: Job<IQueueJobPayload, IMailProcessorResult> | undefined,\n error: Error,\n ) => {\n if (job) {\n const maxAttempts = job.data.options?.attempts ?? 3;\n this.logger\n .for('onWorkerDataFail')\n .error(\n 'Job failed | Worker: %s | jobId: %s | email: %s | attempt: %d/%d | error: %s',\n workerIdentifier,\n job.data.id,\n job.data.email,\n job.attemptsMade,\n maxAttempts,\n error.message,\n );\n } else {\n this.logger\n .for('onWorkerDataFail')\n .error(\n 'Worker error (no job) | Worker: %s | error: %s',\n workerIdentifier,\n error.message,\n );\n }\n },\n });\n\n this.workerHelpers.push(workerHelper);\n\n this.logger\n .for(this.addWorker.name)\n .info(\n 'Worker added | Identifier: %s | Concurrency: %d | Total workers: %d',\n workerIdentifier,\n concurrency,\n this.workerHelpers.length,\n );\n }\n\n async removeWorker(index: number): Promise<boolean> {\n if (index < 0 || index >= this.workerHelpers.length) {\n this.logger.for(this.removeWorker.name).warn('Invalid worker index: %d', index);\n return false;\n }\n\n // Dropped from the list BEFORE the close is awaited: a rejecting close must not leave a half-closed worker still counted and still handed jobs.\n const [workerHelper] = this.workerHelpers.splice(index, 1);\n await workerHelper.worker.close();\n\n this.logger\n .for(this.removeWorker.name)\n .info('Worker removed | Index: %d | Remaining workers: %d', index, this.workerHelpers.length);\n\n return true;\n }\n\n /** Closes every worker without stopping at the first failure, always empties the list, and returns failures instead of throwing so teardown can continue. */\n private async closeWorkers(): Promise<Error[]> {\n const workerHelpers = this.workerHelpers;\n this.workerHelpers = [];\n\n const results = await Promise.allSettled(\n workerHelpers.map((workerHelper) => workerHelper.worker.close()),\n );\n\n const failures: Error[] = [];\n\n for (const result of results) {\n if (result.status !== 'rejected') {\n continue;\n }\n\n const error =\n result.reason instanceof Error\n ? result.reason\n : getError({ message: `Worker close failed | reason: ${String(result.reason)}` });\n\n failures.push(error);\n this.logger.for('closeWorkers').error('Failed to close worker | error: %s', error.message);\n }\n\n return failures;\n }\n\n async clearWorkers(): Promise<void> {\n const count = this.workerHelpers.length;\n await this.closeWorkers();\n\n this.logger.for(this.clearWorkers.name).info('All workers cleared | Count: %d', count);\n }\n\n /** Full teardown: workers -> queue -> Redis. Every step runs even if an earlier one failed (skipping leaks a queue client + Redis socket); failures are reported once, at the end. */\n async close(): Promise<void> {\n const failures: Error[] = [...(await this.closeWorkers())];\n\n if (this.queueHelper) {\n try {\n await this.queueHelper.queue.close();\n } catch (error) {\n const closeError = error instanceof Error ? error : getError({ message: String(error) });\n failures.push(closeError);\n this.logger.for(this.close.name).error('Failed to close queue | error: %s', closeError);\n }\n }\n\n try {\n await this.redisConnection.disconnect();\n } catch (error) {\n const disconnectError = error instanceof Error ? error : getError({ message: String(error) });\n failures.push(disconnectError);\n this.logger\n .for(this.close.name)\n .error('Failed to disconnect redis | error: %s', disconnectError);\n }\n\n if (failures.length > 0) {\n throw getError({\n message: `[close] Incomplete BullMQ mail executor teardown | failures: ${failures\n .map((failure) => failure.message)\n .join(' | ')}`,\n });\n }\n\n this.logger.for(this.close.name).info('BullMQ mail executor closed | Mode: %s', this.mode);\n }\n\n getWorkerCount(): number {\n return this.workerHelpers.length;\n }\n\n getMode(): TConstValue<typeof BullMQExecutorModes> {\n return this.mode;\n }\n\n async enqueueVerificationEmail(\n email: string,\n options?: IMailQueueOptions,\n ): Promise<IMailQueueResult> {\n if (this.mode === BullMQExecutorModes.WORKER_ONLY) {\n throw getError({\n message: 'Cannot enqueue jobs in worker-only mode. Set mode to \"queue-only\" or \"both\".',\n });\n }\n\n if (!this.queueHelper) {\n throw getError({\n message: 'Queue helper not initialized. This should not happen in queue-enabled mode.',\n });\n }\n\n if (!this.processor && this.mode !== BullMQExecutorModes.QUEUE_ONLY) {\n throw getError({ message: MailExecutorErrors.PROCESSOR_NOT_SET });\n }\n\n const jobId = `job_${++this.jobIdCounter}_${Date.now()}`;\n const job: IQueueJobPayload = {\n id: jobId,\n email,\n options,\n attempts: 0,\n scheduledAt: Date.now() + (options?.delay ?? 0),\n };\n\n this.logger\n .for(this.enqueueVerificationEmail.name)\n .info(\n 'Queuing email to BullMQ/Redis | jobId: %s | email: %s | mode: %s',\n jobId,\n email,\n this.mode,\n );\n\n const bullJob = await this.queueHelper.queue.add('send-verification-email', job, {\n priority: options?.priority,\n delay: options?.delay,\n attempts: options?.attempts ?? 3,\n backoff: {\n type: options?.backoff?.type ?? 'exponential',\n delay: options?.backoff?.delay ?? 1000,\n },\n removeOnComplete: true,\n removeOnFail: false,\n });\n\n return {\n jobId: bullJob.id ?? jobId,\n queued: true,\n message: 'Email queued successfully (BullMQ/Redis)',\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bull-mq-executor.helper.js","sourceRoot":"","sources":["../../../../../src/components/mail/helpers/executors/bull-mq-executor.helper.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { RedisSingleHelper } from '@venizia/ignis-helpers';\nimport type { TConstValue } from '@/helpers';\nimport { BullMQHelper } from '@venizia/ignis-helpers/bullmq';\nimport type {\n IBullMQMailExecutorOpts,\n IMailProcessorResult,\n IMailQueueExecutor,\n IMailQueueOptions,\n IMailQueueResult,\n IQueueJobPayload,\n} from '../../common';\nimport {\n BullMQExecutorModes,\n MailBackoffTypes,\n MailErrorCodes,\n MailExecutorErrors,\n} from '../../common';\nimport type { Job } from 'bullmq';\n\nexport class BullMQMailExecutorHelper extends BaseHelper implements IMailQueueExecutor {\n private queueIdentifier: string;\n private queueName: string;\n private mode: TConstValue<typeof BullMQExecutorModes>;\n\n private queueHelper?: BullMQHelper<IQueueJobPayload, IMailQueueResult>;\n private workerHelpers: BullMQHelper<IQueueJobPayload, IMailProcessorResult>[] = [];\n private redisConnection: RedisSingleHelper;\n private readonly bullmqModule?: typeof import('bullmq');\n private jobIdCounter = 0;\n\n private processor?: (email: string) => Promise<IMailProcessorResult>;\n\n constructor(opts: IBullMQMailExecutorOpts) {\n super({ scope: BullMQMailExecutorHelper.name });\n\n this.mode = opts.mode;\n\n this.redisConnection = new RedisSingleHelper({\n ...opts.redis,\n maxRetry: undefined,\n });\n\n this.bullmqModule = opts.module;\n this.queueIdentifier = opts.queue.identifier;\n this.queueName = opts.queue.name;\n\n this.initQueue(opts.queue);\n }\n\n initQueue(queue: { identifier: string; name: string }) {\n switch (this.mode) {\n case BullMQExecutorModes.QUEUE_ONLY:\n case BullMQExecutorModes.BOTH: {\n this.queueHelper = new BullMQHelper<IQueueJobPayload, IMailQueueResult>({\n identifier: queue.identifier,\n queueName: queue.name,\n redisConnection: this.redisConnection,\n role: 'queue',\n module: this.bullmqModule,\n });\n\n this.logger\n .for(this.constructor.name)\n .info(\n 'BullMQ queue executor initialized (queue enabled) | Identifier: %s | Mode: %s',\n this.queueIdentifier,\n this.mode,\n );\n break;\n }\n default: {\n this.logger\n .for(this.constructor.name)\n .info(\n 'BullMQ queue executor initialized (worker-only mode) | Identifier: %s | Mode: %s',\n this.queueIdentifier,\n this.mode,\n );\n\n break;\n }\n }\n }\n\n async setProcessor(\n processor: (email: string) => Promise<IMailProcessorResult>,\n opts?: {\n numberOfWorkers?: number;\n concurrencyPerWorker?: number;\n lockDuration?: number;\n },\n ): Promise<void> {\n this.processor = processor;\n\n if (this.mode === BullMQExecutorModes.QUEUE_ONLY) {\n this.logger\n .for(this.setProcessor.name)\n .warn('Skipping worker creation in queue-only mode. Workers will not be started.');\n return;\n }\n\n const numberOfWorkers = opts?.numberOfWorkers ?? 1;\n const concurrencyPerWorker = opts?.concurrencyPerWorker ?? 5;\n const lockDuration = opts?.lockDuration ?? 30000;\n\n await this.clearWorkers();\n\n for (let i = 0; i < numberOfWorkers; i++) {\n this.addWorker({\n workerIdentifier: `${this.queueIdentifier}-worker-${i}`,\n concurrency: concurrencyPerWorker,\n lockDuration,\n });\n }\n\n this.logger\n .for(this.setProcessor.name)\n .info(\n 'Processor registered | Mode: %s | Workers: %d | Concurrency per worker: %d',\n this.mode,\n numberOfWorkers,\n concurrencyPerWorker,\n );\n }\n\n addWorker(opts: { workerIdentifier: string; concurrency?: number; lockDuration?: number }): void {\n if (!this.processor) {\n throw getError({ message: MailExecutorErrors.PROCESSOR_NOT_SET });\n }\n\n const workerIdentifier = opts.workerIdentifier;\n const concurrency = opts?.concurrency ?? 5;\n const lockDuration = opts?.lockDuration ?? 30000;\n\n const workerHelper = new BullMQHelper<IQueueJobPayload, IMailProcessorResult>({\n identifier: workerIdentifier,\n queueName: this.queueName,\n redisConnection: this.redisConnection,\n role: 'worker',\n module: this.bullmqModule,\n numberOfWorker: concurrency,\n lockDuration,\n onWorkerData: async (job: Job<IQueueJobPayload, IMailProcessorResult>) => {\n const maxAttempts = job.data.options?.attempts ?? 3;\n\n this.logger\n .for('onWorkerData')\n .info(\n 'Processing job | Worker: %s | jobId: %s | email: %s | attempt: %d/%d',\n workerIdentifier,\n job.data.id,\n job.data.email,\n job.attemptsMade + 1,\n maxAttempts,\n );\n\n if (!this.processor) {\n // Returning undefined would let BullMQ mark the job COMPLETED and (with removeOnComplete) delete it - mail silently dropped.\n throw getError({\n messageCode: MailErrorCodes.SEND_FAILED,\n message: `[onWorkerData] ${MailExecutorErrors.PROCESSOR_NOT_SET} | jobId: ${job.data.id}`,\n });\n }\n\n const result = await this.processor(job.data.email);\n\n // A processor reports SMTP rejection by RETURNING `{ success: false }`; BullMQ only treats a REJECTION as failure, so resolving completes the job - no retry, no DLQ.\n if (result?.success === false) {\n throw getError({\n messageCode: MailErrorCodes.SEND_FAILED,\n message: `[onWorkerData] Processor reported failure | jobId: ${job.data.id} | reason: ${result.message}`,\n });\n }\n\n return result;\n },\n onWorkerDataCompleted: async (job: Job<IQueueJobPayload, IMailProcessorResult>) => {\n this.logger\n .for('onWorkerDataCompleted')\n .info(\n 'Job completed | Worker: %s | jobId: %s | email: %s',\n workerIdentifier,\n job.data.id,\n job.data.email,\n );\n },\n onWorkerDataFail: async (\n job: Job<IQueueJobPayload, IMailProcessorResult> | undefined,\n error: Error,\n ) => {\n if (job) {\n const maxAttempts = job.data.options?.attempts ?? 3;\n this.logger\n .for('onWorkerDataFail')\n .error(\n 'Job failed | Worker: %s | jobId: %s | email: %s | attempt: %d/%d | error: %s',\n workerIdentifier,\n job.data.id,\n job.data.email,\n job.attemptsMade,\n maxAttempts,\n error.message,\n );\n } else {\n this.logger\n .for('onWorkerDataFail')\n .error(\n 'Worker error (no job) | Worker: %s | error: %s',\n workerIdentifier,\n error.message,\n );\n }\n },\n });\n\n this.workerHelpers.push(workerHelper);\n\n this.logger\n .for(this.addWorker.name)\n .info(\n 'Worker added | Identifier: %s | Concurrency: %d | Total workers: %d',\n workerIdentifier,\n concurrency,\n this.workerHelpers.length,\n );\n }\n\n async removeWorker(index: number): Promise<boolean> {\n if (index < 0 || index >= this.workerHelpers.length) {\n this.logger.for(this.removeWorker.name).warn('Invalid worker index: %d', index);\n return false;\n }\n\n // Dropped from the list BEFORE the close is awaited: a rejecting close must not leave a half-closed worker still counted and still handed jobs.\n const [workerHelper] = this.workerHelpers.splice(index, 1);\n await workerHelper.worker.close();\n\n this.logger\n .for(this.removeWorker.name)\n .info('Worker removed | Index: %d | Remaining workers: %d', index, this.workerHelpers.length);\n\n return true;\n }\n\n /** Closes every worker without stopping at the first failure, always empties the list, and returns failures instead of throwing so teardown can continue. */\n private async closeWorkers(): Promise<Error[]> {\n const workerHelpers = this.workerHelpers;\n this.workerHelpers = [];\n\n const results = await Promise.allSettled(\n workerHelpers.map((workerHelper) => workerHelper.worker.close()),\n );\n\n const failures: Error[] = [];\n\n for (const result of results) {\n if (result.status !== 'rejected') {\n continue;\n }\n\n const error =\n result.reason instanceof Error\n ? result.reason\n : getError({ message: `Worker close failed | reason: ${String(result.reason)}` });\n\n failures.push(error);\n this.logger.for('closeWorkers').error('Failed to close worker | error: %s', error.message);\n }\n\n return failures;\n }\n\n async clearWorkers(): Promise<void> {\n const count = this.workerHelpers.length;\n await this.closeWorkers();\n\n this.logger.for(this.clearWorkers.name).info('All workers cleared | Count: %d', count);\n }\n\n /** Full teardown: workers -> queue -> Redis. Every step runs even if an earlier one failed (skipping leaks a queue client + Redis socket); failures are reported once, at the end. */\n async close(): Promise<void> {\n const failures: Error[] = [...(await this.closeWorkers())];\n\n if (this.queueHelper) {\n try {\n await this.queueHelper.queue.close();\n } catch (error) {\n const closeError = error instanceof Error ? error : getError({ message: String(error) });\n failures.push(closeError);\n this.logger.for(this.close.name).error('Failed to close queue | error: %s', closeError);\n }\n }\n\n try {\n await this.redisConnection.disconnect();\n } catch (error) {\n const disconnectError = error instanceof Error ? error : getError({ message: String(error) });\n failures.push(disconnectError);\n this.logger\n .for(this.close.name)\n .error('Failed to disconnect redis | error: %s', disconnectError);\n }\n\n if (failures.length > 0) {\n throw getError({\n message: `[close] Incomplete BullMQ mail executor teardown | failures: ${failures\n .map((failure) => failure.message)\n .join(' | ')}`,\n });\n }\n\n this.logger.for(this.close.name).info('BullMQ mail executor closed | Mode: %s', this.mode);\n }\n\n getWorkerCount(): number {\n return this.workerHelpers.length;\n }\n\n getMode(): TConstValue<typeof BullMQExecutorModes> {\n return this.mode;\n }\n\n async enqueueVerificationEmail(\n email: string,\n options?: IMailQueueOptions,\n ): Promise<IMailQueueResult> {\n if (this.mode === BullMQExecutorModes.WORKER_ONLY) {\n throw getError({\n message: 'Cannot enqueue jobs in worker-only mode. Set mode to \"queue-only\" or \"both\".',\n });\n }\n\n if (!this.queueHelper) {\n throw getError({\n message: 'Queue helper not initialized. This should not happen in queue-enabled mode.',\n });\n }\n\n if (!this.processor && this.mode !== BullMQExecutorModes.QUEUE_ONLY) {\n throw getError({ message: MailExecutorErrors.PROCESSOR_NOT_SET });\n }\n\n const jobId = `job_${++this.jobIdCounter}_${Date.now()}`;\n const job: IQueueJobPayload = {\n id: jobId,\n email,\n options,\n attempts: 0,\n scheduledAt: Date.now() + (options?.delay ?? 0),\n };\n\n this.logger\n .for(this.enqueueVerificationEmail.name)\n .info(\n 'Queuing email to BullMQ/Redis | jobId: %s | email: %s | mode: %s',\n jobId,\n email,\n this.mode,\n );\n\n const bullJob = await this.queueHelper.queue.add('send-verification-email', job, {\n priority: options?.priority,\n delay: options?.delay,\n attempts: options?.attempts ?? 3,\n backoff: {\n type: options?.backoff?.type ?? MailBackoffTypes.EXPONENTIAL,\n delay: options?.backoff?.delay ?? 1000,\n },\n removeOnComplete: true,\n removeOnFail: false,\n });\n\n return {\n jobId: bullJob.id ?? jobId,\n queued: true,\n message: 'Email queued successfully (BullMQ/Redis)',\n };\n }\n}\n"]}
|
|
@@ -128,7 +128,7 @@ class InternalQueueMailExecutorHelper extends core_1.BaseHelper {
|
|
|
128
128
|
if (!backoff) {
|
|
129
129
|
return 1000;
|
|
130
130
|
}
|
|
131
|
-
if (backoff.type ===
|
|
131
|
+
if (backoff.type === common_1.MailBackoffTypes.EXPONENTIAL) {
|
|
132
132
|
return backoff.delay * Math.pow(2, job.attempts - 1);
|
|
133
133
|
}
|
|
134
134
|
return backoff.delay;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-queue-executor.helper.js","sourceRoot":"","sources":["../../../../../src/components/mail/helpers/executors/internal-queue-executor.helper.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { SequentialQueueHelper } from '@venizia/ignis-helpers';\nimport type {\n IMailQueueOptions,\n IMailQueueExecutor,\n IMailProcessorResult,\n IInternalQueueMailExecutorOpts,\n IMailQueueResult,\n IQueueJobPayload,\n} from '../../common';\nimport { MailErrorCodes, MailExecutorErrors } from '../../common';\n\nexport class InternalQueueMailExecutorHelper extends BaseHelper implements IMailQueueExecutor {\n private queue: SequentialQueueHelper<IQueueJobPayload>;\n private jobIdCounter = 0;\n private delayedJobs: Map<string, NodeJS.Timeout> = new Map();\n\n private processor?: (email: string) => Promise<IMailProcessorResult>;\n\n constructor(opts: IInternalQueueMailExecutorOpts) {\n super({ scope: InternalQueueMailExecutorHelper.name });\n\n this.queue = new SequentialQueueHelper<IQueueJobPayload>({\n identifier: opts.identifier,\n autoDispatch: true,\n onMessage: async ({ queueElement }) => {\n await this.processJob(queueElement.payload);\n },\n onDataEnqueue: ({ queueElement }) => {\n this.logger\n .for('onDataEnqueue')\n .info(\n 'Job enqueued | jobId: %s | email: %s',\n queueElement.payload.id,\n queueElement.payload.email,\n );\n },\n onStateChange: ({ from, to }) => {\n this.logger.for('onStateChange').debug('Queue state changed | from: %s | to: %s', from, to);\n },\n });\n\n this.logger.for(this.constructor.name).info('Internal queue executor initialized');\n }\n\n setProcessor(processor: (email: string) => Promise<IMailProcessorResult>): void {\n this.processor = processor;\n this.logger.for(this.setProcessor.name).info('Processor registered');\n }\n\n async enqueueVerificationEmail(\n email: string,\n options?: IMailQueueOptions,\n ): Promise<IMailQueueResult> {\n if (!this.processor) {\n throw getError({ message: MailExecutorErrors.PROCESSOR_NOT_SET });\n }\n\n const jobId = `job_${++this.jobIdCounter}_${Date.now()}`;\n const job: IQueueJobPayload = {\n id: jobId,\n email,\n options,\n attempts: 0,\n scheduledAt: Date.now() + (options?.delay ?? 0),\n };\n\n this.logger\n .for(this.enqueueVerificationEmail.name)\n .info('Queuing email | jobId: %s | email: %s', jobId, email);\n\n if (options?.delay && options.delay > 0) {\n const timeout = setTimeout(() => {\n this.queue.enqueue(job).catch((error) => {\n this.logger\n .for(this.enqueueVerificationEmail.name)\n .error('Failed to enqueue delayed job | jobId: %s | error: %s', jobId, error);\n });\n this.delayedJobs.delete(jobId);\n }, options.delay);\n\n this.delayedJobs.set(jobId, timeout);\n\n this.logger\n .for(this.enqueueVerificationEmail.name)\n .info('Job scheduled with delay | jobId: %s | delay: %dms', jobId, options.delay);\n } else {\n await this.queue.enqueue(job);\n }\n\n return {\n jobId,\n queued: true,\n message: 'Email queued successfully (internal queue)',\n };\n }\n\n /** Releases every pending delayed/backoff timer - a live `setTimeout` holds the event loop open past the executor. */\n async close(): Promise<void> {\n const pendingCount = this.delayedJobs.size;\n\n const delayedJobsValues = this.delayedJobs.values();\n for (const timeout of delayedJobsValues) {\n clearTimeout(timeout);\n }\n\n this.delayedJobs.clear();\n\n this.logger.for(this.close.name).info('Executor closed | Cleared timers: %d', pendingCount);\n }\n\n private async processJob(job: IQueueJobPayload): Promise<void> {\n if (!this.processor) {\n this.logger.for(this.processJob.name).error('Processor not set | jobId: %s', job.id);\n return;\n }\n\n const maxAttempts = job.options?.attempts ?? 3;\n\n this.logger\n .for(this.processJob.name)\n .info(\n 'Processing job | jobId: %s | email: %s | attempt: %d/%d',\n job.id,\n job.email,\n job.attempts + 1,\n maxAttempts,\n );\n\n try {\n const result = await this.processor(job.email);\n\n // A processor reports SMTP rejection by RETURNING `{ success: false }`; watching only for throws completes the job and drops the mail.\n if (result?.success === false) {\n throw getError({\n messageCode: MailErrorCodes.SEND_FAILED,\n message: `[processJob] Processor reported failure | jobId: ${job.id} | reason: ${result.message}`,\n });\n }\n\n this.logger.for(this.processJob.name).info('Job completed successfully | jobId: %s', job.id);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : error;\n job.attempts++;\n\n if (job.attempts < maxAttempts) {\n const backoffDelay = this.calculateBackoff(job);\n\n this.logger\n .for(this.processJob.name)\n .warn(\n 'Job failed, retrying | jobId: %s | attempt: %d/%d | retryIn: %dms | error: %s',\n job.id,\n job.attempts,\n maxAttempts,\n backoffDelay,\n errorMsg,\n );\n\n const timeout = setTimeout(() => {\n this.queue.enqueue(job).catch((reenqueueError) => {\n this.logger\n .for(this.processJob.name)\n .error('Failed to re-enqueue job | jobId: %s | error: %s', job.id, reenqueueError);\n });\n this.delayedJobs.delete(job.id);\n }, backoffDelay);\n\n this.delayedJobs.set(job.id, timeout);\n } else {\n this.logger\n .for(this.processJob.name)\n .error(\n 'Job failed permanently after %d attempts | jobId: %s | error: %s',\n maxAttempts,\n job.id,\n errorMsg,\n );\n }\n }\n }\n\n private calculateBackoff(job: IQueueJobPayload): number {\n const backoff = job.options?.backoff;\n\n if (!backoff) {\n return 1000;\n }\n\n if (backoff.type === 'exponential') {\n return backoff.delay * Math.pow(2, job.attempts - 1);\n }\n\n return backoff.delay;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"internal-queue-executor.helper.js","sourceRoot":"","sources":["../../../../../src/components/mail/helpers/executors/internal-queue-executor.helper.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseHelper, getError } from '@venizia/ignis-helpers/core';\nimport { SequentialQueueHelper } from '@venizia/ignis-helpers';\nimport type {\n IMailQueueOptions,\n IMailQueueExecutor,\n IMailProcessorResult,\n IInternalQueueMailExecutorOpts,\n IMailQueueResult,\n IQueueJobPayload,\n} from '../../common';\nimport { MailBackoffTypes, MailErrorCodes, MailExecutorErrors } from '../../common';\n\nexport class InternalQueueMailExecutorHelper extends BaseHelper implements IMailQueueExecutor {\n private queue: SequentialQueueHelper<IQueueJobPayload>;\n private jobIdCounter = 0;\n private delayedJobs: Map<string, NodeJS.Timeout> = new Map();\n\n private processor?: (email: string) => Promise<IMailProcessorResult>;\n\n constructor(opts: IInternalQueueMailExecutorOpts) {\n super({ scope: InternalQueueMailExecutorHelper.name });\n\n this.queue = new SequentialQueueHelper<IQueueJobPayload>({\n identifier: opts.identifier,\n autoDispatch: true,\n onMessage: async ({ queueElement }) => {\n await this.processJob(queueElement.payload);\n },\n onDataEnqueue: ({ queueElement }) => {\n this.logger\n .for('onDataEnqueue')\n .info(\n 'Job enqueued | jobId: %s | email: %s',\n queueElement.payload.id,\n queueElement.payload.email,\n );\n },\n onStateChange: ({ from, to }) => {\n this.logger.for('onStateChange').debug('Queue state changed | from: %s | to: %s', from, to);\n },\n });\n\n this.logger.for(this.constructor.name).info('Internal queue executor initialized');\n }\n\n setProcessor(processor: (email: string) => Promise<IMailProcessorResult>): void {\n this.processor = processor;\n this.logger.for(this.setProcessor.name).info('Processor registered');\n }\n\n async enqueueVerificationEmail(\n email: string,\n options?: IMailQueueOptions,\n ): Promise<IMailQueueResult> {\n if (!this.processor) {\n throw getError({ message: MailExecutorErrors.PROCESSOR_NOT_SET });\n }\n\n const jobId = `job_${++this.jobIdCounter}_${Date.now()}`;\n const job: IQueueJobPayload = {\n id: jobId,\n email,\n options,\n attempts: 0,\n scheduledAt: Date.now() + (options?.delay ?? 0),\n };\n\n this.logger\n .for(this.enqueueVerificationEmail.name)\n .info('Queuing email | jobId: %s | email: %s', jobId, email);\n\n if (options?.delay && options.delay > 0) {\n const timeout = setTimeout(() => {\n this.queue.enqueue(job).catch((error) => {\n this.logger\n .for(this.enqueueVerificationEmail.name)\n .error('Failed to enqueue delayed job | jobId: %s | error: %s', jobId, error);\n });\n this.delayedJobs.delete(jobId);\n }, options.delay);\n\n this.delayedJobs.set(jobId, timeout);\n\n this.logger\n .for(this.enqueueVerificationEmail.name)\n .info('Job scheduled with delay | jobId: %s | delay: %dms', jobId, options.delay);\n } else {\n await this.queue.enqueue(job);\n }\n\n return {\n jobId,\n queued: true,\n message: 'Email queued successfully (internal queue)',\n };\n }\n\n /** Releases every pending delayed/backoff timer - a live `setTimeout` holds the event loop open past the executor. */\n async close(): Promise<void> {\n const pendingCount = this.delayedJobs.size;\n\n const delayedJobsValues = this.delayedJobs.values();\n for (const timeout of delayedJobsValues) {\n clearTimeout(timeout);\n }\n\n this.delayedJobs.clear();\n\n this.logger.for(this.close.name).info('Executor closed | Cleared timers: %d', pendingCount);\n }\n\n private async processJob(job: IQueueJobPayload): Promise<void> {\n if (!this.processor) {\n this.logger.for(this.processJob.name).error('Processor not set | jobId: %s', job.id);\n return;\n }\n\n const maxAttempts = job.options?.attempts ?? 3;\n\n this.logger\n .for(this.processJob.name)\n .info(\n 'Processing job | jobId: %s | email: %s | attempt: %d/%d',\n job.id,\n job.email,\n job.attempts + 1,\n maxAttempts,\n );\n\n try {\n const result = await this.processor(job.email);\n\n // A processor reports SMTP rejection by RETURNING `{ success: false }`; watching only for throws completes the job and drops the mail.\n if (result?.success === false) {\n throw getError({\n messageCode: MailErrorCodes.SEND_FAILED,\n message: `[processJob] Processor reported failure | jobId: ${job.id} | reason: ${result.message}`,\n });\n }\n\n this.logger.for(this.processJob.name).info('Job completed successfully | jobId: %s', job.id);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : error;\n job.attempts++;\n\n if (job.attempts < maxAttempts) {\n const backoffDelay = this.calculateBackoff(job);\n\n this.logger\n .for(this.processJob.name)\n .warn(\n 'Job failed, retrying | jobId: %s | attempt: %d/%d | retryIn: %dms | error: %s',\n job.id,\n job.attempts,\n maxAttempts,\n backoffDelay,\n errorMsg,\n );\n\n const timeout = setTimeout(() => {\n this.queue.enqueue(job).catch((reenqueueError) => {\n this.logger\n .for(this.processJob.name)\n .error('Failed to re-enqueue job | jobId: %s | error: %s', job.id, reenqueueError);\n });\n this.delayedJobs.delete(job.id);\n }, backoffDelay);\n\n this.delayedJobs.set(job.id, timeout);\n } else {\n this.logger\n .for(this.processJob.name)\n .error(\n 'Job failed permanently after %d attempts | jobId: %s | error: %s',\n maxAttempts,\n job.id,\n errorMsg,\n );\n }\n }\n }\n\n private calculateBackoff(job: IQueueJobPayload): number {\n const backoff = job.options?.backoff;\n\n if (!backoff) {\n return 1000;\n }\n\n if (backoff.type === MailBackoffTypes.EXPONENTIAL) {\n return backoff.delay * Math.pow(2, job.attempts - 1);\n }\n\n return backoff.delay;\n }\n}\n"]}
|
|
@@ -4,12 +4,13 @@ import type { BaseRelationalEntity, DefaultCRUDRepository, TTableObject } from '
|
|
|
4
4
|
import type { DiskHelper, IBucketRef, IFileStat, IObjectLocation, IObjectRef, IStorageHelper, IUploadResult, TUploadNaming } from '@venizia/ignis-helpers';
|
|
5
5
|
import type { BunS3Helper } from '@venizia/ignis-helpers/bun-s3';
|
|
6
6
|
import type { AnyType, TValueOrAsyncResolver, ValueOrPromise } from '@venizia/ignis-helpers/common';
|
|
7
|
+
import type { TMultipartStorage } from '@venizia/ignis-helpers';
|
|
7
8
|
import type { MinioHelper } from '@venizia/ignis-helpers/minio';
|
|
8
9
|
import type { TMetaLinkCompatibleSchema, TMetaLinkSchema } from '../models';
|
|
9
10
|
import type { StaticAssetStorageTypes } from './constants';
|
|
10
11
|
export type TStaticAssetExtraOptions = {
|
|
11
12
|
parseMultipartBody?: {
|
|
12
|
-
storage?:
|
|
13
|
+
storage?: TMultipartStorage;
|
|
13
14
|
uploadDir?: string;
|
|
14
15
|
};
|
|
15
16
|
/** `folderPath` carries the upload query's target folder - dropping it flattens nested uploads. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/static-asset/common/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAClF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACb,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,SAAS,EACT,eAAe,EACf,UAAU,EACV,cAAc,EACd,aAAa,EACb,aAAa,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,MAAM,wBAAwB,GAAG;IACrC,kBAAkB,CAAC,EAAE;QACnB,OAAO,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/static-asset/common/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/components/static-asset/common/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { BaseRestController, IAuthRouteConfig, TRouteContext } from '@/base';\nimport type { IDuration } from '@venizia/ignis-helpers/common';\nimport type {\n BaseRelationalEntity,\n DefaultCRUDRepository,\n TTableObject,\n} from '@venizia/ignis-connectors/postgres';\nimport type {\n DiskHelper,\n IBucketRef,\n IFileStat,\n IObjectLocation,\n IObjectRef,\n IStorageHelper,\n IUploadResult,\n TUploadNaming,\n} from '@venizia/ignis-helpers';\nimport type { BunS3Helper } from '@venizia/ignis-helpers/bun-s3';\nimport type { AnyType, TValueOrAsyncResolver, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport type { MinioHelper } from '@venizia/ignis-helpers/minio';\nimport type { TMetaLinkCompatibleSchema, TMetaLinkSchema } from '../models';\nimport type { StaticAssetStorageTypes } from './constants';\n\nexport type TStaticAssetExtraOptions = {\n parseMultipartBody?: {\n storage?:
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/components/static-asset/common/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { BaseRestController, IAuthRouteConfig, TRouteContext } from '@/base';\nimport type { IDuration } from '@venizia/ignis-helpers/common';\nimport type {\n BaseRelationalEntity,\n DefaultCRUDRepository,\n TTableObject,\n} from '@venizia/ignis-connectors/postgres';\nimport type {\n DiskHelper,\n IBucketRef,\n IFileStat,\n IObjectLocation,\n IObjectRef,\n IStorageHelper,\n IUploadResult,\n TUploadNaming,\n} from '@venizia/ignis-helpers';\nimport type { BunS3Helper } from '@venizia/ignis-helpers/bun-s3';\nimport type { AnyType, TValueOrAsyncResolver, ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport type { TMultipartStorage } from '@venizia/ignis-helpers';\nimport type { MinioHelper } from '@venizia/ignis-helpers/minio';\nimport type { TMetaLinkCompatibleSchema, TMetaLinkSchema } from '../models';\nimport type { StaticAssetStorageTypes } from './constants';\n\nexport type TStaticAssetExtraOptions = {\n parseMultipartBody?: {\n storage?: TMultipartStorage;\n uploadDir?: string;\n };\n\n /** `folderPath` carries the upload query's target folder - dropping it flattens nested uploads. */\n normalizeNameFn?: (opts: { file: TUploadNaming }) => string;\n normalizeLinkFn?: (opts: IObjectLocation) => string;\n\n /** Maximum folder nesting depth allowed in object paths. Default: 2 */\n maxFolderDepth?: number;\n\n /** Largest file the UPLOAD route accepts. Absent means no ceiling. Checked against `content-length` before spooling, then per file after parsing. */\n maxBytes?: number;\n [key: string]: AnyType;\n};\n\n/** Decides the key one uploaded file is stored under. `defaultKey` is what IGNIS would have written. */\nexport type TObjectNameResolver = (opts: {\n bucket: IBucketRef;\n file: TUploadNaming;\n defaultKey: string;\n}) => string;\n\n/** Adds routes of the application's own to a generated asset controller. Runs after every built-in route, so a built-in route always wins a path collision. `basePath` is the mount path with exactly one leading slash. */\n/** Adds routes of the application's own. Registration order decides a path collision, so the same shape serves both the before and the after hook. */\nexport type TDefineExtraRoutes = (opts: {\n controller: BaseRestController;\n helper: IStorageHelper;\n basePath: string;\n}) => void;\n\n// Declared by hand rather than inferred: RouteHandler inference here is heavy.\nexport type TBucketParams = { bucketName: string };\nexport type TObjectParams = { bucketName: string; objectName: string };\nexport type TUploadQuery = {\n principalType?: string;\n principalId?: string;\n variant?: string;\n /** Display order within the principal. Caller-supplied: deriving it would be a non-atomic read of `max(sequence)` then a write of `max + 1`. */\n sequence?: number;\n folderPath?: string;\n};\nexport type TListQuery = { prefix?: string; recursive?: string; maxKeys?: string };\n\nexport type TDirectUploadOptions = {\n /** Who may ask for a policy. REQUIRED, not defaulted: this route hands out a write credential, and there is no safe default for that. */\n authorize: (opts: { context: TRouteContext }) => ValueOrPromise<boolean>;\n\n /** Signs the commit token. Keep it out of the repository and out of the client. */\n secretKey: string;\n\n /** The ceiling the policy carries as `content-length-range`. A signed PUT cannot express this at all, which is why this is a POST policy. */\n maxBytes: number;\n\n /** Where a policy may write. The final key is NEVER in a policy, so content cannot be replaced after the commit. Default: `pending/`. */\n pendingPrefix?: string;\n\n /** How long a policy and its commit token stay good. Default: the helper's POST default. */\n expiresIn?: IDuration;\n\n /** Runs BEFORE the copy to the final key, so a hook that throws leaves the object under the pending prefix for a lifecycle rule to collect, rather than stranding it at the final key. */\n onCommit?: (opts: {\n bucket: IBucketRef;\n pendingObject: IObjectRef;\n object: IObjectRef;\n }) => ValueOrPromise<void>;\n};\n\nexport type TUploadPolicyRequest = {\n files: Array<{ fileName: string; contentType?: string; size?: number }>;\n};\n\n/** The MetaLink table belongs to the application. `Schema` defaults to the table IGNIS ships, and widens to any table whose row carries the same fields. */\nexport type TMetaLinkConfig<Schema extends TMetaLinkCompatibleSchema = TMetaLinkSchema> = {\n model: TValueOrAsyncResolver<typeof BaseRelationalEntity<Schema>>;\n repository: TValueOrAsyncResolver<DefaultCRUDRepository<Schema>>;\n createMetaLink?: (opts: {\n uploadResult: IUploadResult;\n fileStat: IFileStat;\n /** The caller's labels. Named for where they used to travel - they arrive in the request BODY now, as form fields on an upload and beside the commit token on a direct one. */\n query: TUploadQuery;\n }) => ValueOrPromise<{ count: number; data: TTableObject<Schema> }>;\n};\n\n/** The part of a built-in route an application may change. */\nexport type TStaticAssetRouteConfig = Partial<\n Omit<IAuthRouteConfig, 'method' | 'request' | 'responses'>\n> & {\n /** Whether this route is registered. Defaults to true. */\n enabled?: boolean;\n};\n\nexport type TStaticAssetRoutes = {\n getBuckets?: TStaticAssetRouteConfig;\n getBucketByName?: TStaticAssetRouteConfig;\n createBucket?: TStaticAssetRouteConfig;\n deleteBucket?: TStaticAssetRouteConfig;\n\n upload?: TStaticAssetRouteConfig;\n listObjects?: TStaticAssetRouteConfig;\n deleteObject?: TStaticAssetRouteConfig;\n getObjectByName?: TStaticAssetRouteConfig;\n downloadObjectByName?: TStaticAssetRouteConfig;\n\n uploadPolicy?: TStaticAssetRouteConfig;\n uploadCommit?: TStaticAssetRouteConfig;\n\n recreateMetaLink?: TStaticAssetRouteConfig;\n};\n\nexport type TStaticAssetsComponentOptions<\n Schema extends TMetaLinkCompatibleSchema = TMetaLinkSchema,\n> = {\n [key: string]: {\n controller: {\n name: string;\n basePath: string;\n isStrict?: boolean;\n\n /** `true` serves a raw nested object path (`/objects/photos/2024/f.jpg`) - a URL shape change; a percent-encoded path keeps working either way. Default: `false`. */\n rawObjectPath?: boolean;\n\n /** The single bucket every object route uses. It leaves the URL (`/objects/{objectName}`) and the four bucket-management routes are not registered. The function form is read per request, so an environment variable can be read lazily. */\n bucket?: TValueOrAsyncResolver<string>;\n\n /**\n * The key scope this controller owns, e.g. `inventory/`. Every route refuses a key outside it\n * as a 404 without calling the storage, `listObjects` lists only inside it, and an upload key\n * must land inside it: the default name is placed there, a `resolveObjectName` or\n * `extra.normalizeNameFn` key outside it is refused. `maxFolderDepth` counts the folders below\n * it. Absent: every key in the bucket.\n */\n keyPrefix?: string;\n\n routes?: TStaticAssetRoutes;\n\n /** Direct upload: the browser posts the bytes to the storage and IGNIS only signs the permission. Absent leaves both routes unregistered. Requires `bucket` - a policy names one bucket, and a bucket in the URL is a bucket the caller chooses. */\n directUpload?: TDirectUploadOptions;\n };\n extra?: TStaticAssetExtraOptions;\n\n /** Decides the stored object name of each uploaded file; absent keeps the storage helper's own naming. */\n resolveObjectName?: TObjectNameResolver;\n\n /** Registers the application's own routes BEFORE every built-in one, so a literal path wins over the catch-all `rawObjectPath` produces. Hono matches in registration order. */\n defineRoutesBefore?: TDefineExtraRoutes;\n\n /** Registers the application's own routes on the generated controller, after every built-in one. */\n defineExtraRoutes?: TDefineExtraRoutes;\n } & (\n | { storage: typeof StaticAssetStorageTypes.BUN_S3; helper: BunS3Helper }\n | { storage: typeof StaticAssetStorageTypes.DISK; helper: DiskHelper }\n | { storage: typeof StaticAssetStorageTypes.MINIO; helper: MinioHelper }\n ) &\n (\n | { useMetaLink?: false | undefined }\n | { useMetaLink: true; metaLink: TMetaLinkConfig<Schema> }\n );\n};\n"]}
|
|
@@ -168,7 +168,7 @@ export declare class AssetControllerFactory extends BaseHelper {
|
|
|
168
168
|
definitions: Record<string, import("../../../base/controllers").IAuthRouteConfig>;
|
|
169
169
|
getRouter(): import("@hono/zod-openapi").OpenAPIHono<Env, {}, "/">;
|
|
170
170
|
registerRoutesFromRegistry(opts?: {
|
|
171
|
-
paths?: "
|
|
171
|
+
paths?: import("../../../base/controllers").TRoutePathScope;
|
|
172
172
|
}): void;
|
|
173
173
|
configure(opts?: {} | undefined): Promise<import("@hono/zod-openapi").OpenAPIHono<Env, {}, "/">>;
|
|
174
174
|
buildRouteMiddlewares<RouteConfig extends import("../../../base/controllers").IAuthRouteConfig>(opts: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/components/static-asset/controller/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAGL,KAAK,eAAe,EAEpB,KAAK,UAAU,EAEf,KAAK,cAAc,EAMpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAE,UAAU,EAAwB,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,OAAO,EAIL,KAAK,kBAAkB,EAEvB,KAAK,eAAe,EAKpB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAG7B,MAAM,WAAW,CAAC;AAYnB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,6BAA6B,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAChE,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iRAAiR;IACjR,QAAQ,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,wBAAwB,CAAC;IAEnC,qHAAqH;IACrH,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IAExC,oGAAoG;IACpG,4IAA4I;IAC5I,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;CACxC;AAED,6OAA6O;AAC7O,mIAAmI;AACnI,0EAA0E;AAC1E,QAAA,MAAM,kBAAkB,gFAMd,CAAC;AAEX,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,GAAI,MAAM;IACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC,OAAO,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5D,KAAG,MAAM,EAAyF,CAAC;AA8DpG,qJAAqJ;AACrJ,eAAO,MAAM,eAAe,GAC1B,MAAM,eAAe,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,KACA,MAQF,CAAC;AAcF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAI,MAAM;IAC7C,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;CACpB,KAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAS/C,CAAC;AAyDF,qBAAa,sBAAuB,SAAQ,UAAU;;IAKpD,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,uBAAuB;;YAwDtD,6FAA6F;2CAC9D;gBAAE,KAAK,EAAE,MAAM,EAAE,CAAA;aAAE,GAAG,IAAI;uBAYrC,cAAc,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/components/static-asset/controller/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAGL,KAAK,eAAe,EAEpB,KAAK,UAAU,EAEf,KAAK,cAAc,EAMpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAE,UAAU,EAAwB,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,OAAO,EAIL,KAAK,kBAAkB,EAEvB,KAAK,eAAe,EAKpB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAG7B,MAAM,WAAW,CAAC;AAYnB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,6BAA6B,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAChE,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iRAAiR;IACjR,QAAQ,CAAC,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,wBAAwB,CAAC;IAEnC,qHAAqH;IACrH,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IAExC,oGAAoG;IACpG,4IAA4I;IAC5I,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;CACxC;AAED,6OAA6O;AAC7O,mIAAmI;AACnI,0EAA0E;AAC1E,QAAA,MAAM,kBAAkB,gFAMd,CAAC;AAEX,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,GAAI,MAAM;IACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC,OAAO,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5D,KAAG,MAAM,EAAyF,CAAC;AA8DpG,qJAAqJ;AACrJ,eAAO,MAAM,eAAe,GAC1B,MAAM,eAAe,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,KACA,MAQF,CAAC;AAcF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAI,MAAM;IAC7C,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;CACpB,KAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAS/C,CAAC;AAyDF,qBAAa,sBAAuB,SAAQ,UAAU;;IAKpD,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,uBAAuB;;YAwDtD,6FAA6F;2CAC9D;gBAAE,KAAK,EAAE,MAAM,EAAE,CAAA;aAAE,GAAG,IAAI;uBAYrC,cAAc,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBArRjC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsmCb"}
|
|
@@ -43,6 +43,6 @@ let BaseMetaLinkModel = class BaseMetaLinkModel extends postgres_1.BaseRelationa
|
|
|
43
43
|
};
|
|
44
44
|
exports.BaseMetaLinkModel = BaseMetaLinkModel;
|
|
45
45
|
exports.BaseMetaLinkModel = BaseMetaLinkModel = __decorate([
|
|
46
|
-
(0, metadata_1.model)({
|
|
46
|
+
(0, metadata_1.model)({ migration: { use: false } })
|
|
47
47
|
], BaseMetaLinkModel);
|
|
48
48
|
//# sourceMappingURL=base.model.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.model.js","sourceRoot":"","sources":["../../../../src/components/static-asset/models/base.model.ts"],"names":[],"mappings":";;;;;;;;;AAAA,8CAAwC;AACxC,iEAM4C;AAC5C,iDAAoF;AAEpF,mNAAmN;AAE5M,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,+BAAqD;aAC1E,WAAM,GAAG,IAAA,iBAAO,EAC9B,UAAU,EACV;QACE,GAAG,IAAA,+BAAoB,EAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC;QACvD,GAAG,IAAA,+BAAoB,GAAE;QACzB,UAAU,EAAE,IAAA,cAAI,EAAC,aAAa,CAAC,CAAC,OAAO,EAAE;QACzC,UAAU,EAAE,IAAA,cAAI,EAAC,aAAa,CAAC,CAAC,OAAO,EAAE;QACzC,IAAI,EAAE,IAAA,cAAI,GAAE,CAAC,OAAO,EAAE;QACtB,QAAQ,EAAE,IAAA,cAAI,GAAE,CAAC,OAAO,EAAE;QAC1B,IAAI,EAAE,IAAA,iBAAO,GAAE,CAAC,OAAO,EAAE;QACzB,IAAI,EAAE,IAAA,cAAI,GAAE;QACZ,QAAQ,EAAE,IAAA,eAAK,GAAE,CAAC,KAAK,EAAuB;QAC9C,WAAW,EAAE,IAAA,cAAI,EAAC,cAAc,CAAC,CAAC,OAAO,EAAE;QAC3C,QAAQ,EAAE,IAAA,iBAAO,EAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;QAEvD,+IAA+I;QAC/I,OAAO,EAAE,IAAA,cAAI,GAAE;QAEf,qJAAqJ;QACrJ,QAAQ,EAAE,IAAA,iBAAO,GAAE,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAExC,uKAAuK;QACvK,aAAa,EAAE,IAAA,cAAI,EAAC,gBAAgB,CAAC;QACrC,WAAW,EAAE,IAAA,cAAI,EAAC,cAAc,CAAC;KAClC,EACD,CAAC,GAAG,EAAE,EAAE,CAAC;QACP,IAAA,eAAK,EAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;QACnD,IAAA,eAAK,EAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;QACnD,IAAA,eAAK,EAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC;QACrD,IAAA,eAAK,EAAC,uBAAuB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC/C,8FAA8F;QAC9F,IAAA,eAAK,EAAC,iCAAiC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC;KAC9F,CACF,AAjCqB,CAiCpB;aAEc,cAAS,GAAG,GAAG,EAAE,CAAC,EAAE,AAAX,CAAY;;AApC1B,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,gBAAK,EAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"base.model.js","sourceRoot":"","sources":["../../../../src/components/static-asset/models/base.model.ts"],"names":[],"mappings":";;;;;;;;;AAAA,8CAAwC;AACxC,iEAM4C;AAC5C,iDAAoF;AAEpF,mNAAmN;AAE5M,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,+BAAqD;aAC1E,WAAM,GAAG,IAAA,iBAAO,EAC9B,UAAU,EACV;QACE,GAAG,IAAA,+BAAoB,EAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC;QACvD,GAAG,IAAA,+BAAoB,GAAE;QACzB,UAAU,EAAE,IAAA,cAAI,EAAC,aAAa,CAAC,CAAC,OAAO,EAAE;QACzC,UAAU,EAAE,IAAA,cAAI,EAAC,aAAa,CAAC,CAAC,OAAO,EAAE;QACzC,IAAI,EAAE,IAAA,cAAI,GAAE,CAAC,OAAO,EAAE;QACtB,QAAQ,EAAE,IAAA,cAAI,GAAE,CAAC,OAAO,EAAE;QAC1B,IAAI,EAAE,IAAA,iBAAO,GAAE,CAAC,OAAO,EAAE;QACzB,IAAI,EAAE,IAAA,cAAI,GAAE;QACZ,QAAQ,EAAE,IAAA,eAAK,GAAE,CAAC,KAAK,EAAuB;QAC9C,WAAW,EAAE,IAAA,cAAI,EAAC,cAAc,CAAC,CAAC,OAAO,EAAE;QAC3C,QAAQ,EAAE,IAAA,iBAAO,EAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;QAEvD,+IAA+I;QAC/I,OAAO,EAAE,IAAA,cAAI,GAAE;QAEf,qJAAqJ;QACrJ,QAAQ,EAAE,IAAA,iBAAO,GAAE,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAExC,uKAAuK;QACvK,aAAa,EAAE,IAAA,cAAI,EAAC,gBAAgB,CAAC;QACrC,WAAW,EAAE,IAAA,cAAI,EAAC,cAAc,CAAC;KAClC,EACD,CAAC,GAAG,EAAE,EAAE,CAAC;QACP,IAAA,eAAK,EAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;QACnD,IAAA,eAAK,EAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;QACnD,IAAA,eAAK,EAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC;QACrD,IAAA,eAAK,EAAC,uBAAuB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC/C,8FAA8F;QAC9F,IAAA,eAAK,EAAC,iCAAiC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC;KAC9F,CACF,AAjCqB,CAiCpB;aAEc,cAAS,GAAG,GAAG,EAAE,CAAC,EAAE,AAAX,CAAY;;AApC1B,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,gBAAK,EAAC,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;GACxB,iBAAiB,CAqC7B","sourcesContent":["import { model } from '@/base/metadata';\nimport {\n BaseRelationalEntity,\n generateIdColumnDefs,\n generateTzColumnDefs,\n type TTableObject,\n type TTableSchemaWithId,\n} from '@venizia/ignis-connectors/postgres';\nimport { boolean, index, integer, jsonb, pgTable, text } from 'drizzle-orm/pg-core';\n\n/** One row per (object, owner) pairing, NOT per object: one product image attached to the product and to each variant is the common case, so `(bucketName, objectName)` is indexed and deliberately NOT unique. */\n@model({ migration: { use: false } })\nexport class BaseMetaLinkModel extends BaseRelationalEntity<typeof BaseMetaLinkModel.schema> {\n static override schema = pgTable(\n 'MetaLink',\n {\n ...generateIdColumnDefs({ id: { dataType: 'string' } }),\n ...generateTzColumnDefs(),\n bucketName: text('bucket_name').notNull(),\n objectName: text('object_name').notNull(),\n link: text().notNull(),\n mimetype: text().notNull(),\n size: integer().notNull(),\n etag: text(),\n metadata: jsonb().$type<Record<string, any>>(),\n storageType: text('storage_type').notNull(),\n isSynced: boolean('is_synced').notNull().default(false),\n\n /** An opaque label the caller chooses - a size, a role, a rendition name. The component stores and returns it and reads no meaning into it. */\n variant: text(),\n\n /** Display order within ONE principal. Defaults to 0 so legacy rows tie and `ORDER BY sequence, createdAt` reproduces the order they already had. */\n sequence: integer().notNull().default(0),\n\n /** A polymorphic owner: the type names the table, the id the row. Both nullable - an object may belong to nothing yet, which is how `recreate-metalink` writes one. */\n principalType: text('principal_type'),\n principalId: text('principal_id'),\n },\n (def) => [\n index(`IDX_MetaLink_bucketName`).on(def.bucketName),\n index(`IDX_MetaLink_objectName`).on(def.objectName),\n index(`IDX_MetaLink_storageType`).on(def.storageType),\n index(`IDX_MetaLink_isSynced`).on(def.isSynced),\n // Ordering runs inside a principal filter, so filter columns lead and the sort column trails.\n index(`IDX_MetaLink_principal_sequence`).on(def.principalType, def.principalId, def.sequence),\n ],\n );\n\n static override relations = () => [];\n}\n\nexport type TMetaLinkSchema = typeof BaseMetaLinkModel.schema;\nexport type TMetaLink = TTableObject<TMetaLinkSchema>;\n\n/** Any table whose row carries the MetaLink fields. The component reads and writes the ROW, so the table is free to carry another name or to live in another Postgres schema. */\nexport type TMetaLinkCompatibleSchema = TTableSchemaWithId & { $inferSelect: TMetaLink };\n"]}
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@hono/zod-openapi": "^1.6.3",
|
|
16
16
|
"@scalar/hono-api-reference": "^0.12.13",
|
|
17
|
-
"@venizia/ignis": "0.4.
|
|
18
|
-
"@venizia/ignis-boot": "0.4.
|
|
19
|
-
"@venizia/ignis-helpers": "0.4.
|
|
17
|
+
"@venizia/ignis": "0.4.3",
|
|
18
|
+
"@venizia/ignis-boot": "0.4.3",
|
|
19
|
+
"@venizia/ignis-helpers": "0.4.3",
|
|
20
20
|
"hono": "^4.13.13",
|
|
21
21
|
"winston": "^3.19.0",
|
|
22
22
|
"winston-daily-rotate-file": "^5.0.0",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/bun": "^1.4.3",
|
|
27
|
-
"@venizia/dev-configs": "0.4.
|
|
27
|
+
"@venizia/dev-configs": "0.4.3",
|
|
28
28
|
"eslint": "^10.13.0",
|
|
29
29
|
"oxlint": "1.89.0",
|
|
30
30
|
"oxlint-tsgolint": "7.0.2004",
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
"dependencies": {},
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@types/bun": "^1.4.3",
|
|
7
|
-
"@venizia/dev-configs": "0.4.
|
|
8
|
-
"@venizia/ignis": "0.4.
|
|
7
|
+
"@venizia/dev-configs": "0.4.3",
|
|
8
|
+
"@venizia/ignis": "0.4.3",
|
|
9
9
|
"eslint": "^10.13.0",
|
|
10
10
|
"oxlint": "1.89.0",
|
|
11
11
|
"oxlint-tsgolint": "7.0.2004",
|
|
12
12
|
"typescript": "^6.0.3"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@venizia/ignis": "0.4.
|
|
15
|
+
"@venizia/ignis": "0.4.3"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
18
|
"typecheck": "bun check",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/ignis",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "High-performance TypeScript server infrastructure combining LoopBack 4 enterprise architecture (decorator-based DI, repository pattern, component system) with Hono speed (~140k req/s). Features auto-generated OpenAPI docs, Drizzle ORM type-safe SQL, JWT/Basic authentication, Casbin authorization, convention-based bootstrapping, and pluggable components for health checks, Swagger UI, mail, Socket.IO, and static assets. Built for Bun and Node.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"access-control",
|
|
@@ -191,11 +191,11 @@
|
|
|
191
191
|
"prepublishOnly": "make rebuild"
|
|
192
192
|
},
|
|
193
193
|
"dependencies": {
|
|
194
|
-
"@venizia/ignis-connectors": "0.4.
|
|
195
|
-
"@venizia/ignis-filter": "0.4.
|
|
196
|
-
"@venizia/ignis-helpers": "0.4.
|
|
197
|
-
"@venizia/ignis-inversion": "0.4.
|
|
198
|
-
"@venizia/ignis-kernel": "0.4.
|
|
194
|
+
"@venizia/ignis-connectors": "0.4.3",
|
|
195
|
+
"@venizia/ignis-filter": "0.4.3",
|
|
196
|
+
"@venizia/ignis-helpers": "0.4.3",
|
|
197
|
+
"@venizia/ignis-inversion": "0.4.3",
|
|
198
|
+
"@venizia/ignis-kernel": "0.4.3",
|
|
199
199
|
"reflect-metadata": "^0.2.2"
|
|
200
200
|
},
|
|
201
201
|
"devDependencies": {
|
|
@@ -209,8 +209,8 @@
|
|
|
209
209
|
"@types/bun": "^1.4.3",
|
|
210
210
|
"@types/nodemailer": "^8.0.2",
|
|
211
211
|
"@types/pg": "^8.23.1",
|
|
212
|
-
"@venizia/dev-configs": "0.4.
|
|
213
|
-
"@venizia/ignis-boot": "0.4.
|
|
212
|
+
"@venizia/dev-configs": "0.4.3",
|
|
213
|
+
"@venizia/ignis-boot": "0.4.3",
|
|
214
214
|
"casbin": "^5.51.1",
|
|
215
215
|
"eslint": "^10.13.0",
|
|
216
216
|
"meilisearch": "^0.62.0",
|