@goatlab/node-backend 0.0.16 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +54 -38
  2. package/dist/container/Container.d.ts +441 -0
  3. package/dist/container/Container.js +895 -0
  4. package/dist/container/Container.js.map +1 -0
  5. package/dist/container/DistributedCacheInvalidator.d.ts +84 -0
  6. package/dist/container/DistributedCacheInvalidator.js +213 -0
  7. package/dist/container/DistributedCacheInvalidator.js.map +1 -0
  8. package/dist/container/LruCache.d.ts +14 -0
  9. package/dist/container/LruCache.js +23 -0
  10. package/dist/container/LruCache.js.map +1 -0
  11. package/dist/container/types.d.ts +128 -0
  12. package/dist/container/types.js +6 -0
  13. package/dist/container/types.js.map +1 -0
  14. package/dist/index.d.ts +31 -0
  15. package/dist/index.js +53 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/server/bootstraps/getExpressTrpcApp.d.ts +17 -0
  18. package/dist/server/bootstraps/getExpressTrpcApp.js +98 -0
  19. package/dist/server/bootstraps/getExpressTrpcApp.js.map +1 -0
  20. package/dist/server/consts.d.ts +35 -0
  21. package/dist/server/consts.js +33 -0
  22. package/dist/server/consts.js.map +1 -0
  23. package/dist/server/context/context.model.d.ts +13 -0
  24. package/dist/server/context/context.model.js +3 -0
  25. package/dist/server/context/context.model.js.map +1 -0
  26. package/dist/server/context/request.context.d.ts +40 -0
  27. package/dist/server/context/request.context.js +91 -0
  28. package/dist/server/context/request.context.js.map +1 -0
  29. package/dist/server/context/trpc.context.d.ts +11 -0
  30. package/dist/server/context/trpc.context.js +67 -0
  31. package/dist/server/context/trpc.context.js.map +1 -0
  32. package/dist/server/initOpenApiDocs.d.ts +9 -0
  33. package/dist/server/initOpenApiDocs.js +18 -0
  34. package/dist/server/initOpenApiDocs.js.map +1 -0
  35. package/dist/server/middleware/cloudTaskDecrypt.middleware.d.ts +6 -0
  36. package/dist/server/middleware/cloudTaskDecrypt.middleware.js +44 -0
  37. package/dist/server/middleware/cloudTaskDecrypt.middleware.js.map +1 -0
  38. package/dist/server/middleware/error.middleware.d.ts +17 -0
  39. package/dist/server/middleware/error.middleware.js +66 -0
  40. package/dist/server/middleware/error.middleware.js.map +1 -0
  41. package/dist/server/middleware/handleRequest.middleware.d.ts +7 -0
  42. package/dist/server/middleware/handleRequest.middleware.js +40 -0
  43. package/dist/server/middleware/handleRequest.middleware.js.map +1 -0
  44. package/dist/server/middleware/logger/cloudRun.logger.d.ts +27 -0
  45. package/dist/server/middleware/logger/cloudRun.logger.js +87 -0
  46. package/dist/server/middleware/logger/cloudRun.logger.js.map +1 -0
  47. package/dist/server/middleware/logger/logger.service.d.ts +6 -0
  48. package/dist/server/middleware/logger/logger.service.js +17 -0
  49. package/dist/server/middleware/logger/logger.service.js.map +1 -0
  50. package/dist/server/middleware/logs.middleware.d.ts +7 -0
  51. package/dist/server/middleware/logs.middleware.js +130 -0
  52. package/dist/server/middleware/logs.middleware.js.map +1 -0
  53. package/dist/server/middleware/requireAuthenticated.d.ts +2 -0
  54. package/dist/server/middleware/requireAuthenticated.js +13 -0
  55. package/dist/server/middleware/requireAuthenticated.js.map +1 -0
  56. package/dist/server/middleware/trpcError.middleware.d.ts +4 -0
  57. package/dist/server/middleware/trpcError.middleware.js +38 -0
  58. package/dist/server/middleware/trpcError.middleware.js.map +1 -0
  59. package/dist/server/schemas/user.schema.d.ts +109 -0
  60. package/dist/server/schemas/user.schema.js +28 -0
  61. package/dist/server/schemas/user.schema.js.map +1 -0
  62. package/dist/server/sentry/getSentry.d.ts +6 -0
  63. package/dist/server/sentry/getSentry.js +45 -0
  64. package/dist/server/sentry/getSentry.js.map +1 -0
  65. package/dist/server/sentry/sentry.service.d.ts +34 -0
  66. package/dist/server/sentry/sentry.service.js +110 -0
  67. package/dist/server/sentry/sentry.service.js.map +1 -0
  68. package/dist/server/services/email/email.model.d.ts +84 -0
  69. package/dist/server/services/email/email.model.js +62 -0
  70. package/dist/server/services/email/email.model.js.map +1 -0
  71. package/dist/server/services/email/email.service.d.ts +23 -0
  72. package/dist/server/services/email/email.service.js +139 -0
  73. package/dist/server/services/email/email.service.js.map +1 -0
  74. package/dist/server/services/gcp/getGcpServiceAccountFromBase64.d.ts +15 -0
  75. package/dist/server/services/gcp/getGcpServiceAccountFromBase64.js +9 -0
  76. package/dist/server/services/gcp/getGcpServiceAccountFromBase64.js.map +1 -0
  77. package/dist/server/services/secrets/secret.service.d.ts +32 -0
  78. package/dist/server/services/secrets/secret.service.js +220 -0
  79. package/dist/server/services/secrets/secret.service.js.map +1 -0
  80. package/dist/server/services/sendgrid/sendgrid.model.d.ts +118 -0
  81. package/dist/server/services/sendgrid/sendgrid.model.js +3 -0
  82. package/dist/server/services/sendgrid/sendgrid.model.js.map +1 -0
  83. package/dist/server/services/sendgrid/sendgridApi.service.d.ts +13 -0
  84. package/dist/server/services/sendgrid/sendgridApi.service.js +79 -0
  85. package/dist/server/services/sendgrid/sendgridApi.service.js.map +1 -0
  86. package/dist/server/services/sendgrid/sendgridHooks.model.d.ts +27 -0
  87. package/dist/server/services/sendgrid/sendgridHooks.model.js +19 -0
  88. package/dist/server/services/sendgrid/sendgridHooks.model.js.map +1 -0
  89. package/dist/server/services/translations/template.util.d.ts +7 -0
  90. package/dist/server/services/translations/template.util.js +11 -0
  91. package/dist/server/services/translations/template.util.js.map +1 -0
  92. package/dist/server/services/translations/translation.model.d.ts +4 -0
  93. package/dist/server/services/translations/translation.model.js +6 -0
  94. package/dist/server/services/translations/translation.model.js.map +1 -0
  95. package/dist/server/services/translations/translation.service.d.ts +25 -0
  96. package/dist/server/services/translations/translation.service.js +97 -0
  97. package/dist/server/services/translations/translation.service.js.map +1 -0
  98. package/dist/server/services/util/benchmarker.d.ts +13 -0
  99. package/dist/server/services/util/benchmarker.js +34 -0
  100. package/dist/server/services/util/benchmarker.js.map +1 -0
  101. package/dist/server/services/util/pagination.d.ts +50 -0
  102. package/dist/server/services/util/pagination.js +57 -0
  103. package/dist/server/services/util/pagination.js.map +1 -0
  104. package/dist/server/services/util/url.service.d.ts +75 -0
  105. package/dist/server/services/util/url.service.js +139 -0
  106. package/dist/server/services/util/url.service.js.map +1 -0
  107. package/dist/server/test/express.mock.d.ts +6 -0
  108. package/dist/server/test/express.mock.js +49 -0
  109. package/dist/server/test/express.mock.js.map +1 -0
  110. package/dist/server/test/firebase.mock.d.ts +4 -0
  111. package/dist/server/test/firebase.mock.js +30 -0
  112. package/dist/server/test/firebase.mock.js.map +1 -0
  113. package/dist/server/test/mock.model.d.ts +5 -0
  114. package/dist/server/test/mock.model.js +3 -0
  115. package/dist/server/test/mock.model.js.map +1 -0
  116. package/dist/server/test/trpc.mock.d.ts +6 -0
  117. package/dist/server/test/trpc.mock.js +14 -0
  118. package/dist/server/test/trpc.mock.js.map +1 -0
  119. package/dist/server/trpc.d.ts +364 -0
  120. package/dist/server/trpc.js +87 -0
  121. package/dist/server/trpc.js.map +1 -0
  122. package/dist/server/types/Envinronment.d.ts +1 -0
  123. package/dist/server/types/Envinronment.js +3 -0
  124. package/dist/server/types/Envinronment.js.map +1 -0
  125. package/dist/test/const.d.ts +4 -0
  126. package/dist/test/const.js +11 -1
  127. package/dist/test/const.js.map +1 -1
  128. package/dist/tsconfig.tsbuildinfo +1 -1
  129. package/package.json +34 -3
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SecretService = void 0;
4
+ const fs = require("fs");
5
+ const undici_1 = require("undici");
6
+ const node_utils_1 = require("@goatlab/node-utils");
7
+ const colors_1 = require("kleur/colors");
8
+ const memoryCache = {};
9
+ class SecretService {
10
+ provider;
11
+ location;
12
+ encryptionKey;
13
+ vaultConfig;
14
+ constructor({ provider, location, encryptionKey, vaultConfig }) {
15
+ this.provider = provider;
16
+ this.location = location;
17
+ this.encryptionKey = encryptionKey;
18
+ this.vaultConfig = vaultConfig;
19
+ }
20
+ // We should cache this call
21
+ loadSecretsFromFile() {
22
+ if (memoryCache[this.location]) {
23
+ return memoryCache[this.location];
24
+ }
25
+ if (!fs.existsSync(this.location)) {
26
+ throw new Error(`Secret file "${this.location}" does not exist`);
27
+ }
28
+ const start = process.hrtime.bigint();
29
+ const fileContents = fs.readFileSync(this.location, 'utf-8');
30
+ const secretEncryptedObject = JSON.parse(fileContents);
31
+ console.log(`🔐 Secrets loaded: ${(0, colors_1.magenta)(this.location.split('/').slice(-2).join('/'))}`);
32
+ try {
33
+ const decripted = node_utils_1.Security.decryptObject(secretEncryptedObject, this.encryptionKey);
34
+ memoryCache[this.location] = decripted;
35
+ const durationMs = Number(process.hrtime.bigint() - start) / 1_000_000;
36
+ console.log(`⏱️ loadSecrets(${this.location}) took ${durationMs.toFixed(3)}ms`);
37
+ return memoryCache[this.location];
38
+ }
39
+ catch (err) {
40
+ console.error(err);
41
+ throw new Error(`loadSecrets failed to decrypt: ${this.location}`);
42
+ }
43
+ }
44
+ loadSecretsFromGCP() {
45
+ return {};
46
+ }
47
+ loadEncryptionKeyFromGCP() {
48
+ return '';
49
+ }
50
+ loadSecretsFromEnv() {
51
+ const cacheKey = `env_${this.location}`;
52
+ if (memoryCache[cacheKey]) {
53
+ return memoryCache[cacheKey];
54
+ }
55
+ const start = process.hrtime.bigint();
56
+ try {
57
+ // For ENV provider, location is used as a prefix for environment variables
58
+ // For example, if location is "APP", it will look for APP_API_KEY, APP_DB_PASSWORD, etc.
59
+ const prefix = this.location ? `${this.location.toUpperCase()}_` : '';
60
+ const secrets = {};
61
+ // Get all environment variables that start with the prefix
62
+ for (const [key, value] of Object.entries(process.env)) {
63
+ if (value !== undefined) {
64
+ if (prefix && key.startsWith(prefix)) {
65
+ // Remove the prefix from the key
66
+ const secretKey = key.slice(prefix.length);
67
+ secrets[secretKey] = value;
68
+ }
69
+ else if (!prefix) {
70
+ // No prefix, include all environment variables
71
+ secrets[key] = value;
72
+ }
73
+ }
74
+ }
75
+ // Log warning if no prefix is specified
76
+ if (!this.location) {
77
+ console.warn('ENV provider without location prefix - this will expose all environment variables');
78
+ }
79
+ memoryCache[cacheKey] = secrets;
80
+ const durationMs = Number(process.hrtime.bigint() - start) / 1_000_000;
81
+ console.log(`🔐 Secrets loaded from ENV: ${(0, colors_1.magenta)(this.location || 'all')} (${durationMs.toFixed(3)}ms)`);
82
+ return secrets;
83
+ }
84
+ catch (error) {
85
+ console.error('Failed to load secrets from ENV:', error.message);
86
+ throw new Error(`loadSecretsFromEnv failed: ${error.message}`);
87
+ }
88
+ }
89
+ async loadSecretsFromVault() {
90
+ if (!this.vaultConfig) {
91
+ throw new Error('Vault configuration is required for VAULT provider');
92
+ }
93
+ const cacheKey = `vault_${this.vaultConfig.endpoint}_${this.location}`;
94
+ if (memoryCache[cacheKey]) {
95
+ return memoryCache[cacheKey];
96
+ }
97
+ const start = process.hrtime.bigint();
98
+ try {
99
+ const vaultUrl = `${this.vaultConfig.endpoint}/v1/${this.vaultConfig.mount || 'secret'}/data/${this.location}`;
100
+ const headers = {
101
+ 'Content-Type': 'application/json'
102
+ };
103
+ // Add token authentication
104
+ if (this.vaultConfig.token) {
105
+ headers['X-Vault-Token'] = this.vaultConfig.token;
106
+ }
107
+ // Add namespace if specified
108
+ if (this.vaultConfig.namespace) {
109
+ headers['X-Vault-Namespace'] = this.vaultConfig.namespace;
110
+ }
111
+ const response = await (0, undici_1.fetch)(vaultUrl, {
112
+ method: 'GET',
113
+ headers
114
+ });
115
+ if (!response.ok) {
116
+ throw new Error(`Vault request failed: ${response.status} ${response.statusText}`);
117
+ }
118
+ const data = (await response.json());
119
+ // Vault KV v2 stores data in data.data
120
+ const secrets = data.data?.data || data.data || {};
121
+ memoryCache[cacheKey] = secrets;
122
+ const durationMs = Number(process.hrtime.bigint() - start) / 1_000_000;
123
+ console.log(`🔐 Secrets loaded from Vault: ${(0, colors_1.magenta)(this.location)} (${durationMs.toFixed(3)}ms)`);
124
+ return secrets;
125
+ }
126
+ catch (error) {
127
+ console.error('Failed to load secrets from Vault:', error.message);
128
+ throw new Error(`loadSecretsFromVault failed: ${error.message}`);
129
+ }
130
+ }
131
+ async storeSecretsToVault(secrets) {
132
+ if (!this.vaultConfig) {
133
+ throw new Error('Vault configuration is required for VAULT provider');
134
+ }
135
+ try {
136
+ const vaultUrl = `${this.vaultConfig.endpoint}/v1/${this.vaultConfig.mount || 'secret'}/data/${this.location}`;
137
+ const headers = {
138
+ 'Content-Type': 'application/json'
139
+ };
140
+ // Add token authentication
141
+ if (this.vaultConfig.token) {
142
+ headers['X-Vault-Token'] = this.vaultConfig.token;
143
+ }
144
+ // Add namespace if specified
145
+ if (this.vaultConfig.namespace) {
146
+ headers['X-Vault-Namespace'] = this.vaultConfig.namespace;
147
+ }
148
+ // For Vault KV v2, data needs to be wrapped in a data object
149
+ const payload = {
150
+ data: secrets
151
+ };
152
+ const response = await (0, undici_1.fetch)(vaultUrl, {
153
+ method: 'POST',
154
+ headers,
155
+ body: JSON.stringify(payload)
156
+ });
157
+ if (!response.ok) {
158
+ throw new Error(`Vault store request failed: ${response.status} ${response.statusText}`);
159
+ }
160
+ // Clear cache to force reload on next access
161
+ const cacheKey = `vault_${this.vaultConfig.endpoint}_${this.location}`;
162
+ delete memoryCache[cacheKey];
163
+ console.log(`🔐 Secrets stored to Vault: ${(0, colors_1.magenta)(this.location)}`);
164
+ }
165
+ catch (error) {
166
+ console.error('Failed to store secrets to Vault:', error.message);
167
+ throw new Error(`storeSecretsToVault failed: ${error.message}`);
168
+ }
169
+ }
170
+ loadSecrets() {
171
+ if (this.provider === 'GCP') {
172
+ return this.loadSecretsFromGCP();
173
+ }
174
+ if (this.provider === 'VAULT') {
175
+ return this.loadSecretsFromVault();
176
+ }
177
+ if (this.provider === 'ENV') {
178
+ return this.loadSecretsFromEnv();
179
+ }
180
+ return this.loadSecretsFromFile();
181
+ }
182
+ loadEncryptionKey() {
183
+ return this.encryptionKey;
184
+ }
185
+ async getSecret(secretName) {
186
+ const secrets = await this.loadSecrets();
187
+ const secret = secrets[secretName];
188
+ if (!secret) {
189
+ throw new Error(`Secret ${secretName.toString()} does not exist in ${this.location} env`);
190
+ }
191
+ return secret;
192
+ }
193
+ async getSecretJson(secretName) {
194
+ const secretValue = await this.getSecret(secretName);
195
+ return JSON.parse(secretValue);
196
+ }
197
+ // Synchronous versions for backward compatibility (FILE and ENV providers only)
198
+ getSecretSync(secretName) {
199
+ if (this.provider === 'VAULT') {
200
+ throw new Error('Use async getSecret() method for Vault provider');
201
+ }
202
+ const secrets = this.loadSecrets();
203
+ const secret = secrets[secretName];
204
+ if (!secret) {
205
+ throw new Error(`Secret ${secretName.toString()} does not exist in ${this.location} env`);
206
+ }
207
+ return secret;
208
+ }
209
+ getSecretJsonSync(secretName) {
210
+ return JSON.parse(this.getSecretSync(secretName));
211
+ }
212
+ // Utility method to clear cache for testing
213
+ static clearCache() {
214
+ Object.keys(memoryCache).forEach(key => {
215
+ delete memoryCache[key];
216
+ });
217
+ }
218
+ }
219
+ exports.SecretService = SecretService;
220
+ //# sourceMappingURL=secret.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret.service.js","sourceRoot":"","sources":["../../../../src/server/services/secrets/secret.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ import type { EmailAddress, EmailAttachment } from '../email/email.model';
2
+ export interface SendgridHTMLEmailRequest {
3
+ fromEmail: string;
4
+ fromName: string;
5
+ replyTo: string;
6
+ subject: string;
7
+ html: string;
8
+ categories: string[];
9
+ recipients: [
10
+ {
11
+ email: string;
12
+ name?: string;
13
+ }
14
+ ];
15
+ bcc?: EmailAddress[];
16
+ attachments?: EmailAttachment[];
17
+ }
18
+ export interface SendGridEmailResponse {
19
+ isSuccess: boolean;
20
+ statusCode: number;
21
+ body: string | Record<string, string>;
22
+ headers: Record<string, string>;
23
+ }
24
+ export interface TrackingSettingsJSON {
25
+ click_tracking?: {
26
+ enable?: boolean;
27
+ enable_text?: boolean;
28
+ };
29
+ open_tracking?: {
30
+ enable?: boolean;
31
+ substitution_tag?: string;
32
+ };
33
+ subscription_tracking?: {
34
+ enable?: boolean;
35
+ text?: string;
36
+ html?: string;
37
+ substitution_tag?: string;
38
+ };
39
+ ganalytics?: {
40
+ enable?: boolean;
41
+ utm_source?: string;
42
+ utm_medium?: string;
43
+ utm_term?: string;
44
+ utm_content?: string;
45
+ utm_campaign?: string;
46
+ };
47
+ }
48
+ export interface MailSettingsJSON {
49
+ bcc?: {
50
+ enable?: boolean;
51
+ email?: string;
52
+ };
53
+ bypass_list_management?: {
54
+ enable?: boolean;
55
+ };
56
+ footer?: {
57
+ enable?: boolean;
58
+ text?: string;
59
+ html?: string;
60
+ };
61
+ sandbox_mode?: {
62
+ enable?: boolean;
63
+ };
64
+ spam_check?: {
65
+ enable?: boolean;
66
+ threshold?: number;
67
+ post_to_url?: string;
68
+ };
69
+ }
70
+ export interface ASMOptionsJSON {
71
+ group_id: number;
72
+ groups_to_display?: number[];
73
+ }
74
+ export interface MailContent {
75
+ type: string;
76
+ value: string;
77
+ }
78
+ export interface AttachmentJSON {
79
+ content: string;
80
+ filename: string;
81
+ type?: string;
82
+ disposition?: string;
83
+ content_id?: string;
84
+ }
85
+ export interface EmailJSON {
86
+ name?: string;
87
+ email: string;
88
+ }
89
+ export interface PersonalizationJSON {
90
+ to: EmailJSON | EmailJSON[];
91
+ cc?: EmailJSON[];
92
+ bcc?: EmailJSON[];
93
+ headers?: Record<string, string>;
94
+ substitutions?: Record<string, string>;
95
+ dynamic_template_data?: Record<string, string>;
96
+ custom_args?: Record<string, string>;
97
+ subject?: string;
98
+ send_at?: number;
99
+ }
100
+ export interface MailJSON {
101
+ from: EmailJSON;
102
+ subject: string;
103
+ content: MailContent[];
104
+ personalizations: PersonalizationJSON[];
105
+ attachments?: AttachmentJSON[] | EmailAttachment[];
106
+ categories?: string[];
107
+ headers?: Record<string, string>;
108
+ mail_settings?: MailSettingsJSON;
109
+ tracking_settings?: TrackingSettingsJSON;
110
+ custom_args?: Record<string, string>;
111
+ sections?: Record<string, string>;
112
+ asm?: ASMOptionsJSON;
113
+ reply_to?: EmailJSON;
114
+ send_at?: number;
115
+ batch_id?: string;
116
+ template_id?: string;
117
+ ip_pool_name?: string;
118
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=sendgrid.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendgrid.model.js","sourceRoot":"","sources":["../../../../src/server/services/sendgrid/sendgrid.model.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import { KyInstance } from '@goatlab/js-utils';
2
+ import type { SendGridEmailResponse, SendgridHTMLEmailRequest } from './sendgrid.model';
3
+ export declare class SendgridService {
4
+ sendgridApi: KyInstance | undefined;
5
+ shouldSendEmail: boolean;
6
+ fromEmail: string;
7
+ constructor({ token, shouldSendEmail, fromEmail, }: {
8
+ token: string;
9
+ shouldSendEmail?: boolean;
10
+ fromEmail: string;
11
+ });
12
+ sendFinalizedEmail(request: SendgridHTMLEmailRequest): Promise<SendGridEmailResponse>;
13
+ }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SendgridService = void 0;
4
+ const js_utils_1 = require("@goatlab/js-utils");
5
+ class SendgridService {
6
+ sendgridApi = undefined;
7
+ shouldSendEmail = true;
8
+ fromEmail = 'test@example.com';
9
+ constructor({ token, shouldSendEmail = true, fromEmail, }) {
10
+ this.sendgridApi = js_utils_1.Http.getClient({
11
+ prefixUrl: 'https://api.sendgrid.com/v3/',
12
+ headers: {
13
+ Authorization: `Bearer ${token}`,
14
+ },
15
+ retry: {
16
+ limit: 3,
17
+ // Sendgrid uses POST
18
+ methods: ['POST'],
19
+ },
20
+ });
21
+ this.shouldSendEmail = shouldSendEmail;
22
+ this.fromEmail = fromEmail;
23
+ }
24
+ // https://docs.sendgrid.com/api-reference/mail-send/mail-send
25
+ async sendFinalizedEmail(request) {
26
+ if (this.shouldSendEmail) {
27
+ console.log('NOT SENDING EMAILS - shouldSendEmail=false');
28
+ return {
29
+ isSuccess: false,
30
+ statusCode: 1,
31
+ body: {},
32
+ headers: {},
33
+ };
34
+ }
35
+ const json = {
36
+ personalizations: [
37
+ {
38
+ to: request.recipients,
39
+ bcc: request.bcc?.length ? request.bcc : undefined,
40
+ },
41
+ ],
42
+ subject: request.subject,
43
+ categories: request.categories,
44
+ content: [{ type: 'text/html', value: request.html }],
45
+ from: {
46
+ email: this.fromEmail,
47
+ name: request.fromName,
48
+ },
49
+ reply_to: { email: request.replyTo },
50
+ tracking_settings: {
51
+ click_tracking: {
52
+ enable: true,
53
+ enable_text: true,
54
+ },
55
+ open_tracking: {
56
+ enable: true,
57
+ },
58
+ },
59
+ attachments: request.attachments?.length
60
+ ? request.attachments
61
+ : undefined,
62
+ };
63
+ if (!this.sendgridApi) {
64
+ return {
65
+ isSuccess: false,
66
+ statusCode: 1,
67
+ body: {},
68
+ headers: {},
69
+ };
70
+ }
71
+ return await this.sendgridApi
72
+ .post('mail/send', {
73
+ json,
74
+ })
75
+ .json();
76
+ }
77
+ }
78
+ exports.SendgridService = SendgridService;
79
+ //# sourceMappingURL=sendgridApi.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendgridApi.service.js","sourceRoot":"","sources":["../../../../src/server/services/sendgrid/sendgridApi.service.ts"],"names":[],"mappings":";;;AAAA,gDAAoD;AAOpD,MAAa,eAAe;IAC1B,WAAW,GAA2B,SAAS,CAAA;IAC/C,eAAe,GAAY,IAAI,CAAA;IAC/B,SAAS,GAAW,kBAAkB,CAAA;IAEtC,YAAY,EACV,KAAK,EACL,eAAe,GAAG,IAAI,EACtB,SAAS,GAKV;QACC,IAAI,CAAC,WAAW,GAAG,eAAI,CAAC,SAAS,CAAC;YAChC,SAAS,EAAE,8BAA8B;YACzC,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;aACjC;YACD,KAAK,EAAE;gBACL,KAAK,EAAE,CAAC;gBACR,qBAAqB;gBACrB,OAAO,EAAE,CAAC,MAAM,CAAC;aAClB;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,eAAe,GAAG,eAAe,CAAA;QACtC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,8DAA8D;IAC9D,KAAK,CAAC,kBAAkB,CACtB,OAAiC;QAEjC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAA;YACzD,OAAO;gBACL,SAAS,EAAE,KAAK;gBAChB,UAAU,EAAE,CAAC;gBACb,IAAI,EAAE,EAAE;gBACR,OAAO,EAAE,EAAE;aACZ,CAAA;QACH,CAAC;QAED,MAAM,IAAI,GAAa;YACrB,gBAAgB,EAAE;gBAChB;oBACE,EAAE,EAAE,OAAO,CAAC,UAAU;oBACtB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;iBACnD;aACF;YACD,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;YACrD,IAAI,EAAE;gBACJ,KAAK,EAAE,IAAI,CAAC,SAAS;gBACrB,IAAI,EAAE,OAAO,CAAC,QAAQ;aACvB;YACD,QAAQ,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE;YACpC,iBAAiB,EAAE;gBACjB,cAAc,EAAE;oBACd,MAAM,EAAE,IAAI;oBACZ,WAAW,EAAE,IAAI;iBAClB;gBACD,aAAa,EAAE;oBACb,MAAM,EAAE,IAAI;iBACb;aACF;YACD,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,MAAM;gBACtC,CAAC,CAAC,OAAO,CAAC,WAAW;gBACrB,CAAC,CAAC,SAAS;SACd,CAAA;QAED,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO;gBACL,SAAS,EAAE,KAAK;gBAChB,UAAU,EAAE,CAAC;gBACb,IAAI,EAAE,EAAE;gBACR,OAAO,EAAE,EAAE;aACZ,CAAA;QACH,CAAC;QAED,OAAO,MAAM,IAAI,CAAC,WAAW;aAC1B,IAAI,CAAC,WAAW,EAAE;YACjB,IAAI;SACL,CAAC;aACD,IAAI,EAAyB,CAAA;IAClC,CAAC;CACF;AAxFD,0CAwFC"}
@@ -0,0 +1,27 @@
1
+ import type { EmailCategory } from '../email/email.model';
2
+ export declare enum SendgridEventType {
3
+ processed = "processed",
4
+ dropped = "dropped",
5
+ bounce = "bounce",
6
+ deferred = "deferred",
7
+ delivered = "delivered",
8
+ open = "open",
9
+ click = "click",
10
+ unsubscribe = "unsubscribe",
11
+ spamreport = "spamreport"
12
+ }
13
+ export interface SendgridEvent {
14
+ email: string;
15
+ category?: EmailCategory[];
16
+ 'smtp-id'?: string;
17
+ sg_event_id: string;
18
+ sg_message_id?: string;
19
+ timestamp: number;
20
+ event: SendgridEventType;
21
+ ip?: string;
22
+ url?: string;
23
+ useragent?: string;
24
+ response?: string;
25
+ reason?: string;
26
+ status?: string;
27
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SendgridEventType = void 0;
4
+ var SendgridEventType;
5
+ (function (SendgridEventType) {
6
+ // Process events
7
+ SendgridEventType["processed"] = "processed";
8
+ SendgridEventType["dropped"] = "dropped";
9
+ // Deliver events
10
+ SendgridEventType["bounce"] = "bounce";
11
+ SendgridEventType["deferred"] = "deferred";
12
+ SendgridEventType["delivered"] = "delivered";
13
+ // Read events
14
+ SendgridEventType["open"] = "open";
15
+ SendgridEventType["click"] = "click";
16
+ SendgridEventType["unsubscribe"] = "unsubscribe";
17
+ SendgridEventType["spamreport"] = "spamreport";
18
+ })(SendgridEventType || (exports.SendgridEventType = SendgridEventType = {}));
19
+ //# sourceMappingURL=sendgridHooks.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendgridHooks.model.js","sourceRoot":"","sources":["../../../../src/server/services/sendgrid/sendgridHooks.model.ts"],"names":[],"mappings":";;;AAEA,IAAY,iBAeX;AAfD,WAAY,iBAAiB;IAC3B,iBAAiB;IACjB,4CAAuB,CAAA;IACvB,wCAAmB,CAAA;IAEnB,iBAAiB;IACjB,sCAAiB,CAAA;IACjB,0CAAqB,CAAA;IACrB,4CAAuB,CAAA;IAEvB,cAAc;IACd,kCAAa,CAAA;IACb,oCAAe,CAAA;IACf,gDAA2B,CAAA;IAC3B,8CAAyB,CAAA;AAC3B,CAAC,EAfW,iBAAiB,iCAAjB,iBAAiB,QAe5B"}
@@ -0,0 +1,7 @@
1
+ import type { AnyObject } from '@goatlab/js-utils';
2
+ import type { PupaOptions } from '@goatlab/js-utils/dist/Strings/pupa';
3
+ declare class TemplateUtil {
4
+ renderString(tmpl: string, params?: AnyObject, opt?: PupaOptions): string;
5
+ }
6
+ export declare const templateUtil: TemplateUtil;
7
+ export {};
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.templateUtil = void 0;
4
+ const js_utils_1 = require("@goatlab/js-utils");
5
+ class TemplateUtil {
6
+ renderString(tmpl, params = {}, opt = {}) {
7
+ return js_utils_1.Strings.pupa(tmpl, params, opt);
8
+ }
9
+ }
10
+ exports.templateUtil = new TemplateUtil();
11
+ //# sourceMappingURL=template.util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.util.js","sourceRoot":"","sources":["../../../../src/server/services/translations/template.util.ts"],"names":[],"mappings":";;;AAEA,gDAA2C;AAE3C,MAAM,YAAY;IAChB,YAAY,CACV,IAAY,EACZ,SAAoB,EAAE,EACtB,MAAmB,EAAE;QAErB,OAAO,kBAAO,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;IACxC,CAAC;CACF;AAEY,QAAA,YAAY,GAAG,IAAI,YAAY,EAAE,CAAA"}
@@ -0,0 +1,4 @@
1
+ export type LANG = 'en_us' | 'en_gb' | 'es_us' | 'es_cl' | 'es_mx';
2
+ export declare const SUPPORTED_LANGUAGES: LANG[];
3
+ export declare const LANG_DEFAULT = "en_us";
4
+ export declare const missingTranslationExcludeList: Set<string>;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.missingTranslationExcludeList = exports.LANG_DEFAULT = void 0;
4
+ exports.LANG_DEFAULT = 'en_us';
5
+ exports.missingTranslationExcludeList = new Set([]);
6
+ //# sourceMappingURL=translation.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translation.model.js","sourceRoot":"","sources":["../../../../src/server/services/translations/translation.model.ts"],"names":[],"mappings":";;;AAGa,QAAA,YAAY,GAAG,OAAO,CAAA;AAEtB,QAAA,6BAA6B,GAAG,IAAI,GAAG,CAAS,EAAE,CAAC,CAAA"}
@@ -0,0 +1,25 @@
1
+ import type { StringMap } from '@goatlab/js-utils';
2
+ import { LANG } from './translation.model';
3
+ export interface UserLanguageOptions {
4
+ language: LANG | null;
5
+ }
6
+ declare class TranslationService {
7
+ getLocale(lang: LANG | null): StringMap;
8
+ getLocaleMap(): Record<LANG, StringMap>;
9
+ missingKey(key: string): string;
10
+ translate(key: string, acc: UserLanguageOptions, args?: any): string;
11
+ /**
12
+ * Implementation based on static ./src/lang/*.json files
13
+ */
14
+ translateIfExists(key: string, user: UserLanguageOptions, args?: {}): string | undefined;
15
+ formatResult(key: string, text: string, args?: {}): string;
16
+ reportMissing(key: string, opt: UserLanguageOptions): void;
17
+ /**
18
+ * Based on: https://nodejs.org/api/intl.html#intl_detecting_internationalization_support
19
+ */
20
+ hasFullICU(): boolean;
21
+ }
22
+ export declare const translationService: TranslationService;
23
+ export declare function tr(key: string, user: UserLanguageOptions, args?: {}): string;
24
+ export declare function trIfExists(key: string, user: UserLanguageOptions, args?: {}): string | undefined;
25
+ export {};