@develit-services/bank 0.3.60 → 0.4.0

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 (45) hide show
  1. package/dist/database/schema.cjs +9 -9
  2. package/dist/database/schema.d.cts +4 -5
  3. package/dist/database/schema.d.mts +4 -5
  4. package/dist/database/schema.d.ts +4 -5
  5. package/dist/database/schema.mjs +3 -3
  6. package/dist/export/worker.cjs +91 -85
  7. package/dist/export/worker.d.cts +23 -766
  8. package/dist/export/worker.d.mts +23 -766
  9. package/dist/export/worker.d.ts +23 -766
  10. package/dist/export/worker.mjs +72 -66
  11. package/dist/export/workflows.cjs +215 -211
  12. package/dist/export/workflows.d.cts +4 -4
  13. package/dist/export/workflows.d.mts +4 -4
  14. package/dist/export/workflows.d.ts +4 -4
  15. package/dist/export/workflows.mjs +210 -206
  16. package/dist/export/wrangler.d.cts +3 -1
  17. package/dist/export/wrangler.d.mts +3 -1
  18. package/dist/export/wrangler.d.ts +3 -1
  19. package/dist/shared/bank.B51e8oDT.mjs +104 -0
  20. package/dist/shared/{bank.Dh_H_5rC.d.cts → bank.BJvgLwyZ.d.cts} +2 -0
  21. package/dist/shared/{bank.Dh_H_5rC.d.mts → bank.BJvgLwyZ.d.mts} +2 -0
  22. package/dist/shared/{bank.Dh_H_5rC.d.ts → bank.BJvgLwyZ.d.ts} +2 -0
  23. package/dist/shared/bank.BUSlmr6r.mjs +13 -0
  24. package/dist/shared/{bank.CMbfx0u7.cjs → bank.BeIpkWR-.cjs} +3 -14
  25. package/dist/shared/bank.Bg3Pdwm4.cjs +44 -0
  26. package/dist/shared/bank.CDoYUKBx.d.cts +748 -0
  27. package/dist/shared/bank.CDoYUKBx.d.mts +748 -0
  28. package/dist/shared/bank.CDoYUKBx.d.ts +748 -0
  29. package/dist/shared/{bank.CNEv3Rac.cjs → bank.CfSZTfWS.cjs} +634 -179
  30. package/dist/shared/{bank.XJJV8p4b.d.cts → bank.CsJuzqZH.d.cts} +2401 -2117
  31. package/dist/shared/{bank.XJJV8p4b.d.mts → bank.CsJuzqZH.d.mts} +2401 -2117
  32. package/dist/shared/{bank.XJJV8p4b.d.ts → bank.CsJuzqZH.d.ts} +2401 -2117
  33. package/dist/shared/bank.DEvSNsEs.cjs +114 -0
  34. package/dist/shared/{bank.DgGcjhmM.mjs → bank.DinCwx0P.mjs} +627 -179
  35. package/dist/shared/bank.Dpx6PvkA.mjs +33 -0
  36. package/dist/shared/bank.c38V_FCq.cjs +15 -0
  37. package/dist/shared/{bank.BqGzJNC6.mjs → bank.qc8ALZwm.mjs} +4 -14
  38. package/dist/types.cjs +51 -33
  39. package/dist/types.d.cts +164 -39
  40. package/dist/types.d.mts +164 -39
  41. package/dist/types.d.ts +164 -39
  42. package/dist/types.mjs +4 -3
  43. package/package.json +7 -10
  44. package/dist/shared/bank.CXpc8168.cjs +0 -212
  45. package/dist/shared/bank.DSsVeR3F.mjs +0 -202
@@ -1,16 +1,16 @@
1
1
  import { WorkflowEntrypoint, WorkflowEvent, WorkflowStep } from 'cloudflare:workers';
2
2
 
3
3
  type Params$1 = {
4
- accountId: string;
4
+ batchId: string;
5
5
  };
6
- declare class BankSyncAccountPayments extends WorkflowEntrypoint<BankEnv, Params$1> {
6
+ declare class BankProcessBatch extends WorkflowEntrypoint<BankEnv, Params$1> {
7
7
  run(event: WorkflowEvent<Params$1>, step: WorkflowStep): Promise<void>;
8
8
  }
9
9
 
10
10
  type Params = {
11
- batchId: string;
11
+ accountId: string;
12
12
  };
13
- declare class BankProcessBatch extends WorkflowEntrypoint<BankEnv, Params> {
13
+ declare class BankSyncAccountPayments extends WorkflowEntrypoint<BankEnv, Params> {
14
14
  run(event: WorkflowEvent<Params>, step: WorkflowStep): Promise<void>;
15
15
  }
16
16
 
@@ -1,16 +1,16 @@
1
1
  import { WorkflowEntrypoint, WorkflowEvent, WorkflowStep } from 'cloudflare:workers';
2
2
 
3
3
  type Params$1 = {
4
- accountId: string;
4
+ batchId: string;
5
5
  };
6
- declare class BankSyncAccountPayments extends WorkflowEntrypoint<BankEnv, Params$1> {
6
+ declare class BankProcessBatch extends WorkflowEntrypoint<BankEnv, Params$1> {
7
7
  run(event: WorkflowEvent<Params$1>, step: WorkflowStep): Promise<void>;
8
8
  }
9
9
 
10
10
  type Params = {
11
- batchId: string;
11
+ accountId: string;
12
12
  };
13
- declare class BankProcessBatch extends WorkflowEntrypoint<BankEnv, Params> {
13
+ declare class BankSyncAccountPayments extends WorkflowEntrypoint<BankEnv, Params> {
14
14
  run(event: WorkflowEvent<Params>, step: WorkflowStep): Promise<void>;
15
15
  }
16
16
 
@@ -1,16 +1,16 @@
1
1
  import { WorkflowEntrypoint, WorkflowEvent, WorkflowStep } from 'cloudflare:workers';
2
2
 
3
3
  type Params$1 = {
4
- accountId: string;
4
+ batchId: string;
5
5
  };
6
- declare class BankSyncAccountPayments extends WorkflowEntrypoint<BankEnv, Params$1> {
6
+ declare class BankProcessBatch extends WorkflowEntrypoint<BankEnv, Params$1> {
7
7
  run(event: WorkflowEvent<Params$1>, step: WorkflowStep): Promise<void>;
8
8
  }
9
9
 
10
10
  type Params = {
11
- batchId: string;
11
+ accountId: string;
12
12
  };
13
- declare class BankProcessBatch extends WorkflowEntrypoint<BankEnv, Params> {
13
+ declare class BankSyncAccountPayments extends WorkflowEntrypoint<BankEnv, Params> {
14
14
  run(event: WorkflowEvent<Params>, step: WorkflowStep): Promise<void>;
15
15
  }
16
16
 
@@ -1,14 +1,16 @@
1
+ import { first, uuidv4, asNonEmpty } from '@develit-io/backend-sdk';
1
2
  import { WorkflowEntrypoint } from 'cloudflare:workers';
2
3
  import { NonRetryableError } from 'cloudflare:workflows';
3
4
  import { drizzle } from 'drizzle-orm/d1';
4
- import { t as tables } from '../shared/bank.DgGcjhmM.mjs';
5
- import { asNonEmpty, first } from '@develit-io/backend-sdk';
6
- import { g as getAccountByIdQuery, i as importAesKey, a as getCredentialsByAccountId, b as initiateConnector, c as createPaymentCommand, d as getBatchByIdQuery, e as checksum, u as upsertBatchCommand } from '../shared/bank.DSsVeR3F.mjs';
5
+ import { t as tables, g as getBatchByIdQuery, c as checksum, u as upsertBatchCommand, a as getAccountByIdQuery, i as importAesKey, b as getCredentialsByAccountId, d as createPaymentCommand } from '../shared/bank.B51e8oDT.mjs';
6
+ import { d as isBatchSigned, j as isBatchFailed, g as isBatchOpen, a as isPaymentCompleted } from '../shared/bank.Dpx6PvkA.mjs';
7
+ import { f as toPreparedPayment, i as initiateConnector, g as toCompletedPayment } from '../shared/bank.DinCwx0P.mjs';
7
8
  import { eq } from 'drizzle-orm';
8
- import 'date-fns';
9
- import '../shared/bank.BqGzJNC6.mjs';
10
- import 'drizzle-orm/sqlite-core';
9
+ import '../shared/bank.BUSlmr6r.mjs';
10
+ import '../shared/bank.qc8ALZwm.mjs';
11
11
  import 'drizzle-orm/relations';
12
+ import 'drizzle-orm/sqlite-core';
13
+ import 'date-fns';
12
14
  import '@develit-io/general-codes';
13
15
  import 'jose';
14
16
  import 'node:crypto';
@@ -37,6 +39,206 @@ function pushToQueue$1(queue, message) {
37
39
  }))
38
40
  );
39
41
  }
42
+ class BankProcessBatch extends WorkflowEntrypoint {
43
+ async run(event, step) {
44
+ const { batchId } = event.payload;
45
+ const db = drizzle(this.env.BANK_D1, { schema: tables });
46
+ const batch = await step.do("load batch", async () => {
47
+ const batch2 = await getBatchByIdQuery(db, { batchId });
48
+ if (!batch2) {
49
+ throw new NonRetryableError(`Batch not found`);
50
+ }
51
+ if (isBatchSigned(batch2))
52
+ throw new NonRetryableError(`Batch already signed`);
53
+ return batch2;
54
+ });
55
+ await step.do("lock batch", async () => {
56
+ const paymentsChecksum = checksum(batch.payments);
57
+ if (batch.paymentsChecksum && batch.paymentsChecksum !== paymentsChecksum)
58
+ throw new NonRetryableError(
59
+ `Batch payments have been modified externally, manual review needed`
60
+ );
61
+ if (isBatchFailed(batch))
62
+ throw new NonRetryableError(
63
+ `Batch is in FAILED status and cannot be processed, manual review needed`
64
+ );
65
+ if (isBatchOpen(batch)) {
66
+ const updatedBatch = await upsertBatchCommand(db, {
67
+ batch: {
68
+ ...batch,
69
+ status: "PROCESSING",
70
+ paymentsChecksum
71
+ }
72
+ }).command.execute().then(first);
73
+ return { status: updatedBatch.status };
74
+ }
75
+ return { status: batch.status };
76
+ });
77
+ const batchResult = await step.do(
78
+ "initiate batch with payments",
79
+ {
80
+ retries: { limit: 5, delay: 2e3, backoff: "constant" },
81
+ timeout: "30 seconds"
82
+ },
83
+ async () => {
84
+ if (batch.batchPaymentInitiatedAt) {
85
+ return {
86
+ authorizationUrls: batch.authorizationUrls,
87
+ preparedPayments: batch.payments.map(
88
+ (p) => toPreparedPayment(p, void 0, batch.batchPaymentInitiatedAt)
89
+ ),
90
+ metadata: batch.metadata
91
+ };
92
+ }
93
+ const account = await getAccountByIdQuery(db, {
94
+ accountId: batch.accountId
95
+ });
96
+ if (!account) {
97
+ throw new NonRetryableError(`Account not found: ${batch.accountId}`);
98
+ }
99
+ const encryptionKey = await importAesKey(this.env.ENCRYPTION_KEY);
100
+ const credentials = await getCredentialsByAccountId(db, encryptionKey, {
101
+ accountId: account.id
102
+ });
103
+ if (!credentials) {
104
+ throw new NonRetryableError(
105
+ `No credentials found for account: ${account.id}`
106
+ );
107
+ }
108
+ if (credentials.expiresAt < /* @__PURE__ */ new Date()) {
109
+ throw new NonRetryableError(
110
+ `Credentials have expired for account: ${account.id}`
111
+ );
112
+ }
113
+ const connector = initiateConnector({
114
+ env: this.env,
115
+ bank: account.connectorKey,
116
+ connectedAccounts: [
117
+ {
118
+ ...account,
119
+ iban: account.iban,
120
+ token: credentials.value
121
+ }
122
+ ]
123
+ });
124
+ const result = await connector.initiateBatch({
125
+ batchId: batch.id,
126
+ payments: batch.payments
127
+ });
128
+ const {
129
+ authorizationUrls,
130
+ payments: preparedPayments,
131
+ metadata
132
+ } = result;
133
+ if (!authorizationUrls || authorizationUrls.length === 0) {
134
+ throw new Error("Failed to retrieve authorization URLs");
135
+ }
136
+ return {
137
+ authorizationUrls,
138
+ preparedPayments,
139
+ metadata
140
+ };
141
+ }
142
+ );
143
+ await step.do("update batch to ready to sign", async () => {
144
+ const upsertBatch = upsertBatchCommand(db, {
145
+ batch: {
146
+ ...batch,
147
+ authorizationUrls: batchResult.authorizationUrls,
148
+ metadata: batchResult.metadata,
149
+ status: "READY_TO_SIGN",
150
+ batchPaymentInitiatedAt: /* @__PURE__ */ new Date()
151
+ }
152
+ }).command;
153
+ await upsertBatch.execute();
154
+ return {
155
+ status: "READY_TO_SIGN",
156
+ paymentsPrepared: batchResult.preparedPayments.length
157
+ };
158
+ });
159
+ const isMockConnector = batchResult.preparedPayments.some(
160
+ (p) => p.connectorKey === "MOCK"
161
+ );
162
+ if (isMockConnector) {
163
+ await step.do(
164
+ "mock: create completed payments and update batch",
165
+ async () => {
166
+ const processedAt = /* @__PURE__ */ new Date();
167
+ const completedPayments = batchResult.preparedPayments.map(
168
+ (p) => toCompletedPayment(p, "COMPLETED", `MOCK-${uuidv4()}`, processedAt)
169
+ );
170
+ const createCommands = completedPayments.map(
171
+ (payment) => createPaymentCommand(db, { payment }).command
172
+ );
173
+ const updateBatchCommand = upsertBatchCommand(db, {
174
+ batch: {
175
+ ...batch,
176
+ status: "SIGNED",
177
+ authorizationUrls: batchResult.authorizationUrls,
178
+ metadata: batchResult.metadata,
179
+ batchPaymentInitiatedAt: /* @__PURE__ */ new Date()
180
+ }
181
+ }).command;
182
+ if (createCommands.length > 0) {
183
+ await db.batch([updateBatchCommand, ...createCommands]);
184
+ } else {
185
+ await updateBatchCommand.execute();
186
+ }
187
+ const eventsToEmit = completedPayments.map(
188
+ (payment) => ({
189
+ eventType: "BANK_PAYMENT",
190
+ eventSignal: "paymentCompleted",
191
+ bankPayment: payment,
192
+ metadata: {
193
+ correlationId: uuidv4(),
194
+ entityId: payment.id,
195
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
196
+ }
197
+ })
198
+ );
199
+ await pushToQueue$1(
200
+ this.env.QUEUE_BUS_QUEUE,
201
+ eventsToEmit
202
+ );
203
+ return {
204
+ paymentsCreated: completedPayments.length,
205
+ eventsEmitted: completedPayments.length
206
+ };
207
+ }
208
+ );
209
+ }
210
+ if (!isMockConnector) {
211
+ await step.do("enqueue authorization email", async () => {
212
+ await pushToQueue$1(this.env.NOTIFICATIONS_QUEUE, {
213
+ type: "email",
214
+ payload: {
215
+ email: {
216
+ to: [this.env.BANK_AUTH_RECIPIENT],
217
+ subject: "Payment Authorization",
218
+ text: Array.isArray(batchResult.authorizationUrls) ? batchResult.authorizationUrls[0] || "No Authorization URL" : batchResult.authorizationUrls || "No Authorization URL"
219
+ }
220
+ },
221
+ metadata: {
222
+ initiator: {
223
+ service: "bank"
224
+ }
225
+ }
226
+ });
227
+ return { emailSent: true };
228
+ });
229
+ }
230
+ }
231
+ }
232
+
233
+ function pushToQueue(queue, message) {
234
+ if (!Array.isArray(message)) return queue.send(message, { contentType: "v8" });
235
+ return queue.sendBatch(
236
+ message.map((m) => ({
237
+ body: m,
238
+ contentType: "v8"
239
+ }))
240
+ );
241
+ }
40
242
  class BankSyncAccountPayments extends WorkflowEntrypoint {
41
243
  async run(event, step) {
42
244
  const { accountId } = event.payload;
@@ -89,15 +291,13 @@ class BankSyncAccountPayments extends WorkflowEntrypoint {
89
291
  ]
90
292
  });
91
293
  return await connector.getAllAccountPayments({
92
- environment: this.env.ENVIRONMENT,
93
- db,
94
294
  account,
95
295
  filter: { dateFrom: account.lastSyncAt }
96
296
  });
97
297
  }
98
298
  );
99
299
  const paymentsToProcess = payments.filter(
100
- (p) => p.parsed.status === "COMPLETED" || p.parsed.status === "FAILED"
300
+ (p) => isPaymentCompleted(p.parsed)
101
301
  );
102
302
  if (paymentsToProcess.length) {
103
303
  const lastSyncBankRefIds = account.lastSyncMetadata?.lastSyncBankRefIds || [];
@@ -142,7 +342,7 @@ class BankSyncAccountPayments extends WorkflowEntrypoint {
142
342
  await db.batch(
143
343
  asNonEmpty([updateLastSyncCommand, ...createCommands])
144
344
  );
145
- await pushToQueue$1(
345
+ await pushToQueue(
146
346
  this.env.QUEUE_BUS_QUEUE,
147
347
  eventsToEmit
148
348
  );
@@ -162,200 +362,4 @@ class BankSyncAccountPayments extends WorkflowEntrypoint {
162
362
  }
163
363
  }
164
364
 
165
- function pushToQueue(queue, message) {
166
- if (!Array.isArray(message)) return queue.send(message, { contentType: "v8" });
167
- return queue.sendBatch(
168
- message.map((m) => ({
169
- body: m,
170
- contentType: "v8"
171
- }))
172
- );
173
- }
174
- class BankProcessBatch extends WorkflowEntrypoint {
175
- async run(event, step) {
176
- const { batchId } = event.payload;
177
- const db = drizzle(this.env.BANK_D1, { schema: tables });
178
- const batch = await step.do("load batch", async () => {
179
- const batch2 = await getBatchByIdQuery(db, { batchId });
180
- if (!batch2) {
181
- throw new NonRetryableError(`Batch not found`);
182
- }
183
- if (batch2.status === "SIGNED")
184
- throw new NonRetryableError(`Batch already signed`);
185
- return batch2;
186
- });
187
- await step.do("lock batch", async () => {
188
- const paymentsChecksum = checksum(batch.payments);
189
- if (batch.paymentsChecksum && batch.paymentsChecksum !== paymentsChecksum)
190
- throw new NonRetryableError(
191
- `Batch payments have been modified externally, manual review needed`
192
- );
193
- if (batch.status === "FAILED")
194
- throw new NonRetryableError(
195
- `Batch is in FAILED status and cannot be processed, manual review needed`
196
- );
197
- if (batch.status === "OPEN") {
198
- const updatedBatch = await upsertBatchCommand(db, {
199
- batch: {
200
- ...batch,
201
- status: "PROCESSING",
202
- paymentsChecksum
203
- }
204
- }).command.execute().then(first);
205
- return { status: updatedBatch.status };
206
- }
207
- return { status: batch.status };
208
- });
209
- const preparedPayments = await step.do(
210
- "prepare payments",
211
- {
212
- retries: { limit: 5, delay: 2e3, backoff: "constant" },
213
- timeout: "30 seconds"
214
- },
215
- async () => {
216
- const account = await getAccountByIdQuery(db, {
217
- accountId: batch.accountId
218
- });
219
- if (!account) {
220
- throw new NonRetryableError(`Account not found: ${batch.accountId}`);
221
- }
222
- const encryptionKey = await importAesKey(this.env.ENCRYPTION_KEY);
223
- const credentials = await getCredentialsByAccountId(db, encryptionKey, {
224
- accountId: account.id
225
- });
226
- if (!credentials) {
227
- throw new NonRetryableError(
228
- `No credentials found for account: ${account.id}`
229
- );
230
- }
231
- if (credentials.expiresAt < /* @__PURE__ */ new Date()) {
232
- throw new NonRetryableError(
233
- `Credentials have expired for account: ${account.id}`
234
- );
235
- }
236
- const connector = initiateConnector({
237
- env: this.env,
238
- bank: account.connectorKey,
239
- connectedAccounts: [
240
- {
241
- ...account,
242
- iban: account.iban,
243
- token: credentials.value
244
- }
245
- ]
246
- });
247
- const preparedPayments2 = [];
248
- for (const payment of batch.payments) {
249
- const prepared = await connector.preparePayment(payment);
250
- if (prepared) {
251
- preparedPayments2.push(prepared);
252
- }
253
- }
254
- return preparedPayments2;
255
- }
256
- );
257
- const batchResult = await step.do(
258
- "initiate batch from payments",
259
- {
260
- retries: { limit: 5, delay: 2e3, backoff: "constant" },
261
- timeout: "30 seconds"
262
- },
263
- async () => {
264
- if (batch.batchPaymentInitiatedAt) {
265
- return {
266
- authorizationUrls: batch.authorizationUrls,
267
- initializedPayments: preparedPayments.map((p) => ({
268
- ...p,
269
- status: "INITIALIZED"
270
- })),
271
- metadata: batch.metadata
272
- };
273
- }
274
- const account = await getAccountByIdQuery(db, {
275
- accountId: batch.accountId
276
- });
277
- if (!account) {
278
- throw new NonRetryableError(`Account not found: ${batch.accountId}`);
279
- }
280
- const encryptionKey = await importAesKey(this.env.ENCRYPTION_KEY);
281
- const credentials = await getCredentialsByAccountId(db, encryptionKey, {
282
- accountId: account.id
283
- });
284
- if (!credentials) {
285
- throw new NonRetryableError(
286
- `No credentials found for account: ${account.id}`
287
- );
288
- }
289
- if (credentials.expiresAt < /* @__PURE__ */ new Date()) {
290
- throw new NonRetryableError(
291
- `Credentials have expired for account: ${account.id}`
292
- );
293
- }
294
- const connector = initiateConnector({
295
- env: this.env,
296
- bank: account.connectorKey,
297
- connectedAccounts: [
298
- {
299
- ...account,
300
- iban: account.iban,
301
- token: credentials.value
302
- }
303
- ]
304
- });
305
- const result = await connector.initiateBatchFromPayments({
306
- batchId: batch.id,
307
- payments: preparedPayments
308
- });
309
- const {
310
- authorizationUrls,
311
- payments: initializedPayments,
312
- metadata
313
- } = result;
314
- if (!authorizationUrls || authorizationUrls.length === 0) {
315
- throw new Error("Failed to retrieve authorization URLs");
316
- }
317
- return {
318
- authorizationUrls,
319
- initializedPayments,
320
- metadata
321
- };
322
- }
323
- );
324
- await step.do("update batch and payments to initialized", async () => {
325
- const upsertBatch = upsertBatchCommand(db, {
326
- batch: {
327
- ...batch,
328
- authorizationUrls: batchResult.authorizationUrls,
329
- metadata: batchResult.metadata,
330
- status: "READY_TO_SIGN",
331
- batchPaymentInitiatedAt: /* @__PURE__ */ new Date()
332
- }
333
- }).command;
334
- await upsertBatch.execute();
335
- return {
336
- status: "READY_TO_SIGN",
337
- paymentsInitialized: batchResult.initializedPayments.length
338
- };
339
- });
340
- await step.do("enqueue authorization email", async () => {
341
- await pushToQueue(this.env.NOTIFICATIONS_QUEUE, {
342
- type: "email",
343
- payload: {
344
- email: {
345
- to: [this.env.BANK_AUTH_RECIPIENT],
346
- subject: "Payment Authorization",
347
- text: Array.isArray(batchResult.authorizationUrls) ? batchResult.authorizationUrls[0] || "No Authorization URL" : batchResult.authorizationUrls || "No Authorization URL"
348
- }
349
- },
350
- metadata: {
351
- initiator: {
352
- service: "bank"
353
- }
354
- }
355
- });
356
- return { emailSent: true };
357
- });
358
- }
359
- }
360
-
361
365
  export { BankProcessBatch, BankSyncAccountPayments };
@@ -1,4 +1,4 @@
1
- import { B as BankServiceWranglerConfig } from '../shared/bank.Dh_H_5rC.cjs';
1
+ import { B as BankServiceWranglerConfig } from '../shared/bank.BJvgLwyZ.cjs';
2
2
 
3
3
  declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
4
4
  vars: {
@@ -11,6 +11,8 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
11
11
  CRON_BATCH_STATUSES: string;
12
12
  CRON_PAYMENTS_PROCESSING: string;
13
13
  BANK_AUTH_RECIPIENT: string;
14
+ DBUCS_BASE_URI: string;
15
+ DBUCS_USERNAME: string;
14
16
  REDIRECT_URI: string;
15
17
  ENCRYPTION_KEY: string;
16
18
  FINBRICKS_PRIVATE_KEY_PEM: string;
@@ -1,4 +1,4 @@
1
- import { B as BankServiceWranglerConfig } from '../shared/bank.Dh_H_5rC.mjs';
1
+ import { B as BankServiceWranglerConfig } from '../shared/bank.BJvgLwyZ.mjs';
2
2
 
3
3
  declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
4
4
  vars: {
@@ -11,6 +11,8 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
11
11
  CRON_BATCH_STATUSES: string;
12
12
  CRON_PAYMENTS_PROCESSING: string;
13
13
  BANK_AUTH_RECIPIENT: string;
14
+ DBUCS_BASE_URI: string;
15
+ DBUCS_USERNAME: string;
14
16
  REDIRECT_URI: string;
15
17
  ENCRYPTION_KEY: string;
16
18
  FINBRICKS_PRIVATE_KEY_PEM: string;
@@ -1,4 +1,4 @@
1
- import { B as BankServiceWranglerConfig } from '../shared/bank.Dh_H_5rC.js';
1
+ import { B as BankServiceWranglerConfig } from '../shared/bank.BJvgLwyZ.js';
2
2
 
3
3
  declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
4
4
  vars: {
@@ -11,6 +11,8 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
11
11
  CRON_BATCH_STATUSES: string;
12
12
  CRON_PAYMENTS_PROCESSING: string;
13
13
  BANK_AUTH_RECIPIENT: string;
14
+ DBUCS_BASE_URI: string;
15
+ DBUCS_USERNAME: string;
14
16
  REDIRECT_URI: string;
15
17
  ENCRYPTION_KEY: string;
16
18
  FINBRICKS_PRIVATE_KEY_PEM: string;
@@ -0,0 +1,104 @@
1
+ import { uuidv4 } from '@develit-io/backend-sdk';
2
+ import { eq } from 'drizzle-orm';
3
+ import { s as schema } from './bank.BUSlmr6r.mjs';
4
+ import 'date-fns';
5
+ import '@develit-io/general-codes';
6
+ import 'jose';
7
+ import './bank.qc8ALZwm.mjs';
8
+ import { createHash } from 'node:crypto';
9
+
10
+ const createPaymentCommand = (db, { payment }) => {
11
+ return {
12
+ command: db.insert(tables.payment).values({
13
+ ...payment,
14
+ creditorIban: payment.creditor.iban,
15
+ debtorIban: payment.debtor.iban
16
+ }).returning()
17
+ };
18
+ };
19
+
20
+ const upsertBatchCommand = (db, { batch }) => {
21
+ const id = batch.id || uuidv4();
22
+ const command = db.insert(tables.batch).values({
23
+ ...batch,
24
+ id
25
+ }).onConflictDoUpdate({
26
+ target: tables.batch.id,
27
+ set: {
28
+ ...batch
29
+ }
30
+ }).returning();
31
+ return {
32
+ id,
33
+ command
34
+ };
35
+ };
36
+
37
+ const getAccountByIdQuery = async (db, { accountId }) => {
38
+ return await db.select().from(tables.account).where(eq(tables.account.id, accountId)).get();
39
+ };
40
+
41
+ const getBatchByIdQuery = async (db, { batchId }) => {
42
+ return await db.select().from(tables.batch).where(eq(tables.batch.id, batchId)).get();
43
+ };
44
+
45
+ const getCredentialsByAccountId = async (db, encryptionKey, { accountId }) => {
46
+ const cred = await db.select().from(tables.accountCredentials).where(eq(tables.accountCredentials.accountId, accountId)).get();
47
+ return cred ? {
48
+ ...cred,
49
+ value: await decrypt(cred.value, encryptionKey)
50
+ } : void 0;
51
+ };
52
+
53
+ async function importAesKey(base64Key) {
54
+ const raw = Uint8Array.from(atob(base64Key), (c) => c.charCodeAt(0));
55
+ return await crypto.subtle.importKey("raw", raw, { name: "AES-GCM" }, false, [
56
+ "encrypt",
57
+ "decrypt"
58
+ ]);
59
+ }
60
+ async function encrypt(value, key) {
61
+ const encoder = new TextEncoder();
62
+ const iv = crypto.getRandomValues(new Uint8Array(12));
63
+ const ciphertext = await crypto.subtle.encrypt(
64
+ { name: "AES-GCM", iv },
65
+ key,
66
+ encoder.encode(value)
67
+ );
68
+ const combined = new Uint8Array(iv.length + ciphertext.byteLength);
69
+ combined.set(iv, 0);
70
+ combined.set(new Uint8Array(ciphertext), iv.length);
71
+ return btoa(String.fromCharCode(...combined));
72
+ }
73
+ async function decrypt(base64, key) {
74
+ const raw = Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
75
+ const iv = raw.slice(0, 12);
76
+ const ciphertext = raw.slice(12);
77
+ const decrypted = await crypto.subtle.decrypt(
78
+ { name: "AES-GCM", iv },
79
+ key,
80
+ ciphertext
81
+ );
82
+ return new TextDecoder().decode(decrypted);
83
+ }
84
+ function canonicalize(value) {
85
+ if (value === null || typeof value !== "object") return value;
86
+ if (Array.isArray(value)) {
87
+ return value.map(canonicalize);
88
+ }
89
+ const obj = value;
90
+ const sorted = Object.keys(obj).sort().reduce((acc, key) => {
91
+ acc[key] = canonicalize(obj[key]);
92
+ return acc;
93
+ }, {});
94
+ return sorted;
95
+ }
96
+ function checksum(input) {
97
+ const canonical = canonicalize(input);
98
+ const json = JSON.stringify(canonical);
99
+ return createHash("sha256").update(json).digest("hex");
100
+ }
101
+
102
+ const tables = schema;
103
+
104
+ export { getAccountByIdQuery as a, getCredentialsByAccountId as b, checksum as c, createPaymentCommand as d, encrypt as e, getBatchByIdQuery as g, importAesKey as i, tables as t, upsertBatchCommand as u };
@@ -21,6 +21,8 @@ interface BankServiceEnvironmentConfig {
21
21
  CRON_BATCH_STATUSES: string;
22
22
  CRON_PAYMENTS_PROCESSING: string;
23
23
  BANK_AUTH_RECIPIENT: string;
24
+ DBUCS_BASE_URI: string;
25
+ DBUCS_USERNAME: string;
24
26
  REDIRECT_URI: string;
25
27
  };
26
28
  }
@@ -21,6 +21,8 @@ interface BankServiceEnvironmentConfig {
21
21
  CRON_BATCH_STATUSES: string;
22
22
  CRON_PAYMENTS_PROCESSING: string;
23
23
  BANK_AUTH_RECIPIENT: string;
24
+ DBUCS_BASE_URI: string;
25
+ DBUCS_USERNAME: string;
24
26
  REDIRECT_URI: string;
25
27
  };
26
28
  }