@serve.zone/coremail 1.0.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 (75) hide show
  1. package/.smartconfig.json +50 -0
  2. package/changelog.md +10 -0
  3. package/cli.js +4 -0
  4. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  5. package/dist_ts/00_commitinfo_data.js +9 -0
  6. package/dist_ts/classes.auth.d.ts +45 -0
  7. package/dist_ts/classes.auth.js +204 -0
  8. package/dist_ts/classes.config.d.ts +2 -0
  9. package/dist_ts/classes.config.js +72 -0
  10. package/dist_ts/classes.coremail.d.ts +41 -0
  11. package/dist_ts/classes.coremail.js +155 -0
  12. package/dist_ts/classes.desiredstate.d.ts +40 -0
  13. package/dist_ts/classes.desiredstate.js +382 -0
  14. package/dist_ts/classes.gateway.d.ts +62 -0
  15. package/dist_ts/classes.gateway.js +669 -0
  16. package/dist_ts/classes.inbound.d.ts +49 -0
  17. package/dist_ts/classes.inbound.js +702 -0
  18. package/dist_ts/classes.maintenance.d.ts +16 -0
  19. package/dist_ts/classes.maintenance.js +339 -0
  20. package/dist_ts/classes.models.d.ts +161 -0
  21. package/dist_ts/classes.models.js +595 -0
  22. package/dist_ts/classes.server.d.ts +40 -0
  23. package/dist_ts/classes.server.js +309 -0
  24. package/dist_ts/classes.storage.d.ts +32 -0
  25. package/dist_ts/classes.storage.js +317 -0
  26. package/dist_ts/classes.submissions.d.ts +33 -0
  27. package/dist_ts/classes.submissions.js +385 -0
  28. package/dist_ts/classes.transfer.d.ts +41 -0
  29. package/dist_ts/classes.transfer.js +289 -0
  30. package/dist_ts/coremail.cursor.d.ts +20 -0
  31. package/dist_ts/coremail.cursor.js +191 -0
  32. package/dist_ts/coremail.log.d.ts +3 -0
  33. package/dist_ts/coremail.log.js +11 -0
  34. package/dist_ts/coremail.mime.d.ts +8 -0
  35. package/dist_ts/coremail.mime.js +63 -0
  36. package/dist_ts/coremail.persistence.d.ts +148 -0
  37. package/dist_ts/coremail.persistence.js +695 -0
  38. package/dist_ts/coremail.quota.d.ts +29 -0
  39. package/dist_ts/coremail.quota.js +149 -0
  40. package/dist_ts/coremail.selectors.d.ts +3 -0
  41. package/dist_ts/coremail.selectors.js +21 -0
  42. package/dist_ts/coremail.validation.d.ts +9 -0
  43. package/dist_ts/coremail.validation.js +325 -0
  44. package/dist_ts/index.d.ts +4 -0
  45. package/dist_ts/index.js +39 -0
  46. package/dist_ts/interfaces.d.ts +92 -0
  47. package/dist_ts/interfaces.js +2 -0
  48. package/dist_ts/plugins.d.ts +11 -0
  49. package/dist_ts/plugins.js +12 -0
  50. package/license.md +19 -0
  51. package/package.json +48 -0
  52. package/readme.md +199 -0
  53. package/ts/00_commitinfo_data.ts +8 -0
  54. package/ts/classes.auth.ts +321 -0
  55. package/ts/classes.config.ts +104 -0
  56. package/ts/classes.coremail.ts +249 -0
  57. package/ts/classes.desiredstate.ts +508 -0
  58. package/ts/classes.gateway.ts +811 -0
  59. package/ts/classes.inbound.ts +898 -0
  60. package/ts/classes.maintenance.ts +335 -0
  61. package/ts/classes.models.ts +530 -0
  62. package/ts/classes.server.ts +444 -0
  63. package/ts/classes.storage.ts +448 -0
  64. package/ts/classes.submissions.ts +554 -0
  65. package/ts/classes.transfer.ts +379 -0
  66. package/ts/coremail.cursor.ts +328 -0
  67. package/ts/coremail.log.ts +21 -0
  68. package/ts/coremail.mime.ts +94 -0
  69. package/ts/coremail.persistence.ts +1156 -0
  70. package/ts/coremail.quota.ts +214 -0
  71. package/ts/coremail.selectors.ts +35 -0
  72. package/ts/coremail.validation.ts +446 -0
  73. package/ts/index.ts +38 -0
  74. package/ts/interfaces.ts +109 -0
  75. package/ts/plugins.ts +11 -0
@@ -0,0 +1,385 @@
1
+ import * as plugins from './plugins.js';
2
+ import {} from './classes.models.js';
3
+ import { CoreMailStorage, createSha256 } from './classes.storage.js';
4
+ import { CoreMailTransferService } from './classes.transfer.js';
5
+ import { createCoreMailSubmissionDigest, normalizeCoreMailOutboundMessage, } from './coremail.validation.js';
6
+ import { createCoreMailMime } from './coremail.mime.js';
7
+ import { createCoreMailOutboundQuotaDescriptors, ensureCoreMailQuotaCounter, incrementCoreMailQuotaCounter, withCoreMailTransaction, } from './coremail.quota.js';
8
+ import { requireCoreMailIdentifier, requireCoreMailUuid, } from './coremail.selectors.js';
9
+ const maximumPartBytes = plugins.serveZoneInterfaces.data.coreMailLimits.attachmentBytes;
10
+ const authorityFilter = (sessionArg, submissionIdArg) => ({
11
+ tenantId: requireCoreMailIdentifier(sessionArg.tenantId, 'session.tenantId'),
12
+ serviceId: requireCoreMailIdentifier(sessionArg.serviceId, 'session.serviceId'),
13
+ bindingId: requireCoreMailIdentifier(sessionArg.bindingId, 'session.bindingId'),
14
+ bindingRevision: sessionArg.bindingRevision,
15
+ ...(submissionIdArg === undefined
16
+ ? {}
17
+ : { submissionId: requireCoreMailUuid(submissionIdArg, 'submissionId') }),
18
+ });
19
+ const workloadAuthority = (sessionArg) => ({
20
+ kind: 'workload',
21
+ tenantId: sessionArg.tenantId,
22
+ serviceId: sessionArg.serviceId,
23
+ bindingId: sessionArg.bindingId,
24
+ });
25
+ const toPublicSubmission = (submissionArg) => plugins.serveZoneInterfaces.data.normalizeCoreMailSubmission({
26
+ submissionId: submissionArg.submissionId,
27
+ idempotencyKey: submissionArg.idempotencyKey,
28
+ submissionDigest: submissionArg.submissionDigest,
29
+ state: submissionArg.state,
30
+ parts: submissionArg.parts.map((partArg) => ({
31
+ partId: partArg.partId,
32
+ state: partArg.state,
33
+ sha256: partArg.sha256,
34
+ lengthBytes: partArg.lengthBytes,
35
+ })),
36
+ ...(submissionArg.transportMessageId
37
+ ? { transportMessageId: submissionArg.transportMessageId }
38
+ : {}),
39
+ attempts: submissionArg.attempts,
40
+ ...(submissionArg.nextAttemptAt === undefined
41
+ || submissionArg.state !== 'deferred'
42
+ ? {}
43
+ : { nextAttemptAt: submissionArg.nextAttemptAt }),
44
+ ...(submissionArg.error === undefined ? {} : { error: submissionArg.error }),
45
+ ...(submissionArg.acceptedAt === undefined
46
+ ? {}
47
+ : { acceptedAt: submissionArg.acceptedAt }),
48
+ ...(submissionArg.deliveredAt === undefined
49
+ ? {}
50
+ : { deliveredAt: submissionArg.deliveredAt }),
51
+ ...(submissionArg.terminalAt === undefined
52
+ ? {}
53
+ : { terminalAt: submissionArg.terminalAt }),
54
+ createdAt: submissionArg.createdAt,
55
+ updatedAt: submissionArg.updatedAt,
56
+ });
57
+ const isUniqueConflict = (errorArg) => errorArg instanceof plugins.smartdata.SmartdataExactPersistenceError
58
+ && errorArg.code === 'unique_conflict';
59
+ export class CoreMailSubmissionService {
60
+ database;
61
+ models;
62
+ storage;
63
+ transfers;
64
+ now;
65
+ constructor(database, models, storage, transfers, now = Date.now) {
66
+ this.database = database;
67
+ this.models = models;
68
+ this.storage = storage;
69
+ this.transfers = transfers;
70
+ this.now = now;
71
+ }
72
+ async prepare(sessionArg, bindingArg, requestArg) {
73
+ const message = normalizeCoreMailOutboundMessage(requestArg.message, bindingArg);
74
+ const submissionDigest = createCoreMailSubmissionDigest(requestArg.idempotencyKey, message);
75
+ const replay = await this.models.Submission.exact.findStoredOne({
76
+ ...authorityFilter(sessionArg, undefined),
77
+ idempotencyKey: requestArg.idempotencyKey,
78
+ });
79
+ if (replay) {
80
+ if (replay.submissionDigest !== submissionDigest) {
81
+ throw new Error('CoreMail idempotency key conflicts with persisted intent.');
82
+ }
83
+ return { submission: toPublicSubmission(replay), replayed: true };
84
+ }
85
+ const submissionId = plugins.nodeCrypto.randomUUID();
86
+ const createdAt = this.now();
87
+ const parts = message.parts.map((partArg) => ({
88
+ ...partArg,
89
+ objectKey: `outbound-parts/${submissionId}/${plugins.nodeCrypto.randomUUID()}`,
90
+ state: 'missing',
91
+ }));
92
+ const submission = {
93
+ submissionId,
94
+ tenantId: sessionArg.tenantId,
95
+ serviceId: sessionArg.serviceId,
96
+ bindingId: sessionArg.bindingId,
97
+ bindingRevision: sessionArg.bindingRevision,
98
+ revision: 0,
99
+ idempotencyKey: requestArg.idempotencyKey,
100
+ submissionDigest,
101
+ state: 'preparing',
102
+ message,
103
+ parts,
104
+ attempts: 0,
105
+ createdAt,
106
+ updatedAt: createdAt,
107
+ };
108
+ const quotaNow = this.now();
109
+ const quota = createCoreMailOutboundQuotaDescriptors({
110
+ tenantId: sessionArg.tenantId,
111
+ serviceId: sessionArg.serviceId,
112
+ bindingId: sessionArg.bindingId,
113
+ bindingRevision: sessionArg.bindingRevision,
114
+ }, quotaNow);
115
+ await ensureCoreMailQuotaCounter(this.models, quota.minute);
116
+ await ensureCoreMailQuotaCounter(this.models, quota.day);
117
+ try {
118
+ const transactionResult = await withCoreMailTransaction(this.database, async (transactionArg) => {
119
+ const transactionReplay = await this.models.Submission.exact.findStoredOne({
120
+ ...authorityFilter(sessionArg, undefined),
121
+ idempotencyKey: requestArg.idempotencyKey,
122
+ }, { session: transactionArg });
123
+ if (transactionReplay) {
124
+ if (transactionReplay.submissionDigest !== submissionDigest) {
125
+ throw new Error('CoreMail idempotency key conflicts with persisted intent.');
126
+ }
127
+ return { submissionId: transactionReplay.submissionId, replayed: true };
128
+ }
129
+ await incrementCoreMailQuotaCounter(this.models, quota.day, bindingArg.limits.messagesPerDay, quotaNow, transactionArg, quota.dayRetryAfterMs);
130
+ await incrementCoreMailQuotaCounter(this.models, quota.minute, bindingArg.limits.messagesPerMinute, quotaNow, transactionArg, quota.minuteRetryAfterMs);
131
+ const inserted = await this.models.Submission.exact.insert(submission, { session: transactionArg });
132
+ if (inserted.status === 'conflict') {
133
+ throw new Error('CoreMail submission identity conflicts with persisted intent.');
134
+ }
135
+ return { submissionId, replayed: inserted.status === 'already_committed' };
136
+ });
137
+ const committed = await this.models.Submission.exact.findStoredOne({
138
+ ...authorityFilter(sessionArg, transactionResult.submissionId),
139
+ });
140
+ if (!committed || committed.submissionDigest !== submissionDigest) {
141
+ throw new Error('CoreMail committed submission is unavailable.');
142
+ }
143
+ return {
144
+ submission: toPublicSubmission(committed),
145
+ replayed: transactionResult.replayed,
146
+ };
147
+ }
148
+ catch (error) {
149
+ if (!isUniqueConflict(error)) {
150
+ throw error;
151
+ }
152
+ const concurrent = await this.models.Submission.exact.findStoredOne({
153
+ ...authorityFilter(sessionArg, undefined),
154
+ idempotencyKey: requestArg.idempotencyKey,
155
+ });
156
+ if (!concurrent || concurrent.submissionDigest !== submissionDigest) {
157
+ throw new Error('CoreMail idempotency key conflicts with persisted intent.');
158
+ }
159
+ return { submission: toPublicSubmission(concurrent), replayed: true };
160
+ }
161
+ }
162
+ async preparePartUpload(sessionArg, requestArg) {
163
+ const submission = await this.requireSubmission(sessionArg, requestArg.submissionId);
164
+ if (submission.state !== 'preparing'
165
+ && submission.state !== 'uploading'
166
+ && submission.state !== 'ready') {
167
+ throw new Error('CoreMail submission no longer accepts part uploads.');
168
+ }
169
+ const partIndex = submission.parts.findIndex((partArg) => partArg.partId === requireCoreMailIdentifier(requestArg.partId, 'partId'));
170
+ if (partIndex < 0) {
171
+ throw new Error('CoreMail submission part is unavailable.');
172
+ }
173
+ const part = submission.parts[partIndex];
174
+ if (part.state === 'complete') {
175
+ throw new Error('CoreMail submission part is already complete.');
176
+ }
177
+ const grant = await this.transfers.issueGrant({
178
+ authority: workloadAuthority(sessionArg),
179
+ purpose: 'outbound-part-upload',
180
+ method: 'PUT',
181
+ expectedSha256: part.sha256,
182
+ lengthBytes: part.lengthBytes,
183
+ contentType: part.contentType,
184
+ objectKey: part.objectKey,
185
+ });
186
+ const parts = submission.parts.map((partArg, indexArg) => indexArg === partIndex
187
+ ? { ...partArg, state: 'uploading', grantId: grant.grantId }
188
+ : partArg);
189
+ const updatedAt = this.now();
190
+ const update = await this.models.Submission.exact.transition({
191
+ current: submission,
192
+ change: (modelArg) => {
193
+ modelArg.parts = parts;
194
+ modelArg.state = 'uploading';
195
+ modelArg.updatedAt = updatedAt;
196
+ modelArg.revision += 1;
197
+ },
198
+ });
199
+ if (update.status !== 'transitioned') {
200
+ throw new Error('CoreMail submission part upload fence changed.');
201
+ }
202
+ return {
203
+ grant: grant,
204
+ };
205
+ }
206
+ async completePartUpload(sessionArg, requestArg) {
207
+ const submission = await this.requireSubmission(sessionArg, requestArg.submissionId);
208
+ const partIndex = submission.parts.findIndex((partArg) => partArg.partId === requireCoreMailIdentifier(requestArg.partId, 'partId'));
209
+ if (partIndex < 0) {
210
+ throw new Error('CoreMail submission part is unavailable.');
211
+ }
212
+ const part = submission.parts[partIndex];
213
+ const sha256 = plugins.serveZoneInterfaces.data.normalizeCoreMailSha256(requestArg.sha256);
214
+ if ((part.state !== 'uploading' && part.state !== 'complete')
215
+ || part.sha256 !== sha256
216
+ || part.lengthBytes !== requestArg.lengthBytes) {
217
+ throw new Error('CoreMail submission part completion is invalid.');
218
+ }
219
+ await this.transfers.assertConsumed({
220
+ grantId: requestArg.grantId,
221
+ authority: workloadAuthority(sessionArg),
222
+ purpose: 'outbound-part-upload',
223
+ expectedSha256: part.sha256,
224
+ lengthBytes: part.lengthBytes,
225
+ objectKey: part.objectKey,
226
+ });
227
+ if (part.state === 'complete') {
228
+ return { submission: toPublicSubmission(submission) };
229
+ }
230
+ const parts = submission.parts.map((partArg, indexArg) => indexArg === partIndex
231
+ ? {
232
+ ...partArg,
233
+ state: 'complete',
234
+ grantId: requestArg.grantId,
235
+ }
236
+ : partArg);
237
+ const allComplete = parts.every((partArg) => partArg.state === 'complete');
238
+ const updatedAt = this.now();
239
+ const update = await this.models.Submission.exact.transition({
240
+ current: submission,
241
+ change: (modelArg) => {
242
+ modelArg.parts = parts;
243
+ modelArg.state = allComplete ? 'ready' : 'uploading';
244
+ modelArg.updatedAt = updatedAt;
245
+ modelArg.revision += 1;
246
+ },
247
+ });
248
+ if (update.status !== 'transitioned') {
249
+ throw new Error('CoreMail submission part completion fence changed.');
250
+ }
251
+ return {
252
+ submission: toPublicSubmission(update.document),
253
+ };
254
+ }
255
+ async finalize(sessionArg, requestArg) {
256
+ const submission = await this.requireSubmission(sessionArg, requestArg.submissionId);
257
+ if (submission.state === 'accepted'
258
+ || submission.state === 'queued'
259
+ || submission.state === 'delivering'
260
+ || submission.state === 'delivered'
261
+ || submission.state === 'deferred'
262
+ || submission.state === 'failed'
263
+ || submission.state === 'deadLettered') {
264
+ return { submission: toPublicSubmission(submission) };
265
+ }
266
+ if (submission.state !== 'ready'
267
+ || !submission.parts.every((partArg) => partArg.state === 'complete')) {
268
+ throw new Error('CoreMail submission is not ready for finalization.');
269
+ }
270
+ if (submission.mimeObjectKey
271
+ && submission.mimeSha256
272
+ && submission.mimeLengthBytes !== undefined
273
+ && submission.mimePublishedAt !== undefined
274
+ && (submission.workerRetryAt !== undefined
275
+ || (submission.leaseOwnerTaskId !== undefined
276
+ && submission.leaseOwnerTaskId !== 'submission-finalizer'
277
+ && submission.leaseExpiresAt !== undefined
278
+ && submission.leaseExpiresAt > this.now()))) {
279
+ return { submission: toPublicSubmission(submission) };
280
+ }
281
+ const content = await Promise.all(submission.parts.map(async (partArg) => ({
282
+ descriptor: partArg,
283
+ bytes: await this.storage.getVerifiedBytes(partArg.objectKey, partArg.lengthBytes, partArg.sha256, maximumPartBytes),
284
+ })));
285
+ const mimeBytes = createCoreMailMime(submission.submissionId, submission.submissionDigest, submission.createdAt, submission.message, content);
286
+ const mimeObjectKey = `outbound-mime/${submission.submissionId}/${submission.submissionDigest.slice(7)}`;
287
+ const mimeSha256 = createSha256(mimeBytes);
288
+ const mimeLengthBytes = mimeBytes.byteLength;
289
+ if (mimeLengthBytes > plugins.serveZoneInterfaces.data.coreMailLimits.serializedMimeBytes) {
290
+ throw new Error('CoreMail serialized MIME exceeds its byte budget.');
291
+ }
292
+ if (submission.mimeObjectKey !== undefined
293
+ && (submission.mimeObjectKey !== mimeObjectKey
294
+ || submission.mimeSha256 !== mimeSha256
295
+ || submission.mimeLengthBytes !== mimeLengthBytes)) {
296
+ throw new Error('CoreMail submission MIME ownership conflicts.');
297
+ }
298
+ if (submission.mimeObjectKey === mimeObjectKey
299
+ && submission.leaseExpiresAt !== undefined
300
+ && submission.leaseExpiresAt > this.now()) {
301
+ if (submission.leaseOwnerTaskId !== 'submission-finalizer') {
302
+ return { submission: toPublicSubmission(submission) };
303
+ }
304
+ throw new Error('CoreMail submission finalization is already in progress.');
305
+ }
306
+ const leaseToken = plugins.nodeCrypto.randomUUID();
307
+ const claimAt = this.now();
308
+ const claim = await this.models.Submission.exact.transition({
309
+ current: submission,
310
+ change: (modelArg) => {
311
+ modelArg.mimeObjectKey = mimeObjectKey;
312
+ modelArg.mimeSha256 = mimeSha256;
313
+ modelArg.mimeLengthBytes = mimeLengthBytes;
314
+ modelArg.leaseOwnerTaskId = 'submission-finalizer';
315
+ modelArg.leaseToken = leaseToken;
316
+ modelArg.leaseExpiresAt = claimAt
317
+ + plugins.serveZoneInterfaces.data.coreMailLimits.transferOverallTimeoutMs
318
+ + 2 * 60_000;
319
+ modelArg.updatedAt = claimAt;
320
+ modelArg.revision += 1;
321
+ delete modelArg.mimePublishedAt;
322
+ delete modelArg.workerRetryAt;
323
+ },
324
+ });
325
+ if (claim.status !== 'transitioned') {
326
+ const replay = await this.requireSubmission(sessionArg, submission.submissionId);
327
+ if (replay.submissionDigest === submission.submissionDigest
328
+ && replay.mimeObjectKey === mimeObjectKey
329
+ && replay.mimeSha256 === mimeSha256
330
+ && replay.mimeLengthBytes === mimeLengthBytes
331
+ && (replay.workerRetryAt !== undefined
332
+ || replay.leaseOwnerTaskId !== 'submission-finalizer')) {
333
+ return { submission: toPublicSubmission(replay) };
334
+ }
335
+ throw new Error('CoreMail submission finalization fence changed.');
336
+ }
337
+ const mime = await this.storage.putBytesExact(mimeObjectKey, mimeBytes, 'message/rfc822', plugins.serveZoneInterfaces.data.coreMailLimits.serializedMimeBytes, AbortSignal.timeout(plugins.serveZoneInterfaces.data.coreMailLimits.transferOverallTimeoutMs));
338
+ if (mime.sha256 !== mimeSha256 || mime.lengthBytes !== mimeLengthBytes) {
339
+ throw new Error('CoreMail published MIME integrity conflicts.');
340
+ }
341
+ const queuedAt = this.now();
342
+ const update = await this.models.Submission.exact.transition({
343
+ current: claim.document,
344
+ change: (modelArg) => {
345
+ modelArg.mimePublishedAt = queuedAt;
346
+ modelArg.workerRetryAt = queuedAt;
347
+ modelArg.updatedAt = queuedAt;
348
+ modelArg.revision += 1;
349
+ delete modelArg.leaseOwnerTaskId;
350
+ delete modelArg.leaseToken;
351
+ delete modelArg.leaseExpiresAt;
352
+ },
353
+ });
354
+ if (update.status !== 'transitioned') {
355
+ const replay = await this.requireSubmission(sessionArg, submission.submissionId).catch(() => undefined);
356
+ if (replay?.submissionDigest === submission.submissionDigest
357
+ && replay.mimeObjectKey === mimeObjectKey
358
+ && replay.mimeSha256 === mime.sha256
359
+ && replay.mimeLengthBytes === mime.lengthBytes
360
+ && (replay.workerRetryAt !== undefined
361
+ || replay.leaseOwnerTaskId !== 'submission-finalizer')) {
362
+ return { submission: toPublicSubmission(replay) };
363
+ }
364
+ throw new Error('CoreMail submission finalization fence changed.');
365
+ }
366
+ return {
367
+ submission: toPublicSubmission(update.document),
368
+ };
369
+ }
370
+ async get(sessionArg, requestArg) {
371
+ return {
372
+ submission: toPublicSubmission(await this.requireSubmission(sessionArg, requestArg.submissionId)),
373
+ };
374
+ }
375
+ async requireSubmission(sessionArg, submissionIdArg) {
376
+ const submission = await this.models.Submission.exact.findStoredOne({
377
+ ...authorityFilter(sessionArg, submissionIdArg),
378
+ });
379
+ if (!submission) {
380
+ throw new Error('CoreMail submission is unavailable.');
381
+ }
382
+ return submission;
383
+ }
384
+ }
385
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zdWJtaXNzaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuc3VibWlzc2lvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUF3QixNQUFNLHFCQUFxQixDQUFDO0FBQzNELE9BQU8sRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDckUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDaEUsT0FBTyxFQUNMLDhCQUE4QixFQUM5QixnQ0FBZ0MsR0FDakMsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN4RCxPQUFPLEVBQ0wsc0NBQXNDLEVBQ3RDLDBCQUEwQixFQUMxQiw2QkFBNkIsRUFDN0IsdUJBQXVCLEdBQ3hCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUNMLHlCQUF5QixFQUN6QixtQkFBbUIsR0FDcEIsTUFBTSx5QkFBeUIsQ0FBQztBQWFqQyxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQztBQUV6RixNQUFNLGVBQWUsR0FBRyxDQUN0QixVQUFvQyxFQUNwQyxlQUFtQyxFQUNuQyxFQUFFLENBQUMsQ0FBQztJQUNKLFFBQVEsRUFBRSx5QkFBeUIsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLGtCQUFrQixDQUFDO0lBQzVFLFNBQVMsRUFBRSx5QkFBeUIsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLG1CQUFtQixDQUFDO0lBQy9FLFNBQVMsRUFBRSx5QkFBeUIsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLG1CQUFtQixDQUFDO0lBQy9FLGVBQWUsRUFBRSxVQUFVLENBQUMsZUFBZTtJQUMzQyxH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
@@ -0,0 +1,41 @@
1
+ import * as plugins from './plugins.js';
2
+ import { type ICoreMailModels } from './classes.models.js';
3
+ import { CoreMailStorage } from './classes.storage.js';
4
+ import type { ITransferAuthority, TTransferGrantPurpose } from './interfaces.js';
5
+ import type { ICoreMailTransferGrantRecord } from './coremail.persistence.js';
6
+ type TCoreMailSha256 = plugins.serveZoneInterfaces.data.TCoreMailSha256;
7
+ type TStoredTransferGrant = plugins.smartdata.TStoredDocument<ICoreMailTransferGrantRecord>;
8
+ export declare class CoreMailTransferService {
9
+ private readonly models;
10
+ private readonly storage;
11
+ private readonly now;
12
+ private readonly completionTasks;
13
+ private readonly operationControllers;
14
+ private readonly stopController;
15
+ private stopping;
16
+ constructor(models: ICoreMailModels, storage: CoreMailStorage, now?: () => number);
17
+ stop(): Promise<void>;
18
+ private track;
19
+ issueGrant(optionsArg: {
20
+ authority: ITransferAuthority;
21
+ purpose: TTransferGrantPurpose;
22
+ method: 'PUT' | 'GET';
23
+ expectedSha256: TCoreMailSha256;
24
+ lengthBytes: number;
25
+ contentType: string;
26
+ objectKey: string;
27
+ }): Promise<plugins.serveZoneInterfaces.data.ICoreMailTransferGrant>;
28
+ assertConsumed(optionsArg: {
29
+ grantId: string;
30
+ authority: ITransferAuthority;
31
+ purpose: TTransferGrantPurpose;
32
+ expectedSha256: TCoreMailSha256;
33
+ lengthBytes: number;
34
+ objectKey?: string;
35
+ }): Promise<TStoredTransferGrant>;
36
+ handleHttp(contextArg: plugins.typedserver.IRequestContext): Promise<Response | null>;
37
+ private handleUpload;
38
+ private handleDownload;
39
+ private failGrant;
40
+ }
41
+ export {};