@serve.zone/interfaces 27.3.0 → 27.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.
@@ -0,0 +1,862 @@
1
+ import * as plugins from './plugins.runtime.js';
2
+
3
+ import {
4
+ canonicalizeStrictJson,
5
+ deepFreezeValue,
6
+ } from './private/canonicaljson.js';
7
+ import type {
8
+ ICorestoreDatabaseAllocationReference,
9
+ ICorestoreDatabaseBackupReceipt,
10
+ } from './runtime.corestore.js';
11
+ import {
12
+ corestoreDatabaseBackupRuntimeLimits,
13
+ encodeCorestoreDatabaseBackupReceipt,
14
+ normalizeCorestoreDatabaseAllocationReference,
15
+ normalizeCorestoreDatabaseBackupReceipt,
16
+ } from './runtime.corestore.js';
17
+
18
+ export const corestoreDatabaseExportPackageRuntimeLimits = Object.freeze({
19
+ maximumControlBytes: corestoreDatabaseBackupRuntimeLimits.maximumControlBytes,
20
+ maximumInputBytes: corestoreDatabaseBackupRuntimeLimits.maximumSnapshotOriginalBytes,
21
+ maximumClosureBytes: corestoreDatabaseBackupRuntimeLimits.maximumClosureBytes,
22
+ maximumPackageAttemptIdLength: 128,
23
+ } as const);
24
+
25
+ export type TCorestoreDatabaseExportPackageCodecErrorCode =
26
+ | 'INVALID_DATA'
27
+ | 'INVALID_SCHEMA'
28
+ | 'INVALID_VALUE'
29
+ | 'LIMIT_EXCEEDED'
30
+ | 'CROSS_FIELD_MISMATCH'
31
+ | 'ATTEMPT_CONFLICT';
32
+
33
+ export class CorestoreDatabaseExportPackageCodecError extends Error {
34
+ public readonly code: TCorestoreDatabaseExportPackageCodecErrorCode;
35
+ public readonly path: string;
36
+
37
+ public constructor(
38
+ codeArg: TCorestoreDatabaseExportPackageCodecErrorCode,
39
+ pathArg: string,
40
+ ) {
41
+ super(`${codeArg}:${pathArg}`);
42
+ this.name = 'CorestoreDatabaseExportPackageCodecError';
43
+ this.code = codeArg;
44
+ this.path = pathArg;
45
+ }
46
+ }
47
+
48
+ export interface ICorestoreDatabaseExportPackageInputIdentityV1 {
49
+ format: 'smartdb.database.export.v1';
50
+ databaseName: string;
51
+ byteLength: number;
52
+ sha256: string;
53
+ lineFeedTerminator: 'single-lf';
54
+ }
55
+
56
+ export interface ICorestoreDatabaseExportPackageApprovedBackupIdentityV1 {
57
+ backupId: string;
58
+ sourceServiceId: string;
59
+ snapshotId: string;
60
+ backupReceiptSha256: string;
61
+ }
62
+
63
+ export interface ICorestoreDatabaseExportPackageAllocationAbsentExpectationV1 {
64
+ expectation: 'absent';
65
+ }
66
+
67
+ export interface ICorestoreDatabaseExportPackageAllocationExactExpectationV1 {
68
+ expectation: 'exact';
69
+ allocation: ICorestoreDatabaseAllocationReference;
70
+ }
71
+
72
+ export type TCorestoreDatabaseExportPackageAllocationExpectationV1 =
73
+ | ICorestoreDatabaseExportPackageAllocationAbsentExpectationV1
74
+ | ICorestoreDatabaseExportPackageAllocationExactExpectationV1;
75
+
76
+ export interface ICorestoreDatabaseExportPackageRequestV1 {
77
+ schemaVersion: 1;
78
+ kind: 'corestore-database-export-package-request';
79
+ packageAttemptId: string;
80
+ packageBackupId: string;
81
+ input: ICorestoreDatabaseExportPackageInputIdentityV1;
82
+ approvedSourceBackup: ICorestoreDatabaseExportPackageApprovedBackupIdentityV1;
83
+ completeOutputReceiptSha256: string;
84
+ allocationExpectation: TCorestoreDatabaseExportPackageAllocationExpectationV1;
85
+ }
86
+
87
+ export interface ICorestoreDatabaseExportPackageCompletionV1 {
88
+ schemaVersion: 1;
89
+ kind: 'corestore-database-export-package-completion';
90
+ packageAttemptId: string;
91
+ requestSha256: string;
92
+ completedAt: number;
93
+ receipt: ICorestoreDatabaseBackupReceipt;
94
+ receiptSha256: string;
95
+ closureByteLength: number;
96
+ closureSha256: string;
97
+ }
98
+
99
+ export interface ICorestoreDatabaseExportPackageResponseV1 {
100
+ schemaVersion: 1;
101
+ kind: 'corestore-database-export-package-response';
102
+ completion: ICorestoreDatabaseExportPackageCompletionV1;
103
+ replayed: boolean;
104
+ }
105
+
106
+ export interface ICorestoreDatabaseExportPackageReleaseRequestV1 {
107
+ schemaVersion: 1;
108
+ kind: 'corestore-database-export-package-release-request';
109
+ packageAttemptId: string;
110
+ requestSha256: string;
111
+ completionSha256: string;
112
+ callerFsyncedClosureByteLength: number;
113
+ callerFsyncedClosureSha256: string;
114
+ callerFsyncedReceiptByteLength: number;
115
+ callerFsyncedReceiptSha256: string;
116
+ callerFsyncedAt: number;
117
+ }
118
+
119
+ export interface ICorestoreDatabaseExportPackageReleaseCompletionV1 {
120
+ schemaVersion: 1;
121
+ kind: 'corestore-database-export-package-release-completion';
122
+ packageAttemptId: string;
123
+ requestSha256: string;
124
+ completionSha256: string;
125
+ releaseRequestSha256: string;
126
+ releasedAt: number;
127
+ }
128
+
129
+ export interface ICorestoreDatabaseExportPackageReleaseResponseV1 {
130
+ schemaVersion: 1;
131
+ kind: 'corestore-database-export-package-release-response';
132
+ release: ICorestoreDatabaseExportPackageReleaseCompletionV1;
133
+ replayed: boolean;
134
+ }
135
+
136
+ export type TCorestoreDatabaseExportPackageRequestReuse =
137
+ | 'different-attempt'
138
+ | 'exact-replay';
139
+
140
+ const inputIdentityKeys = [
141
+ 'format',
142
+ 'databaseName',
143
+ 'byteLength',
144
+ 'sha256',
145
+ 'lineFeedTerminator',
146
+ ] as const;
147
+ const approvedBackupIdentityKeys = [
148
+ 'backupId',
149
+ 'sourceServiceId',
150
+ 'snapshotId',
151
+ 'backupReceiptSha256',
152
+ ] as const;
153
+ const requestKeys = [
154
+ 'schemaVersion',
155
+ 'kind',
156
+ 'packageAttemptId',
157
+ 'packageBackupId',
158
+ 'input',
159
+ 'approvedSourceBackup',
160
+ 'completeOutputReceiptSha256',
161
+ 'allocationExpectation',
162
+ ] as const;
163
+ const completionKeys = [
164
+ 'schemaVersion',
165
+ 'kind',
166
+ 'packageAttemptId',
167
+ 'requestSha256',
168
+ 'completedAt',
169
+ 'receipt',
170
+ 'receiptSha256',
171
+ 'closureByteLength',
172
+ 'closureSha256',
173
+ ] as const;
174
+ const responseKeys = ['schemaVersion', 'kind', 'completion', 'replayed'] as const;
175
+ const releaseRequestKeys = [
176
+ 'schemaVersion',
177
+ 'kind',
178
+ 'packageAttemptId',
179
+ 'requestSha256',
180
+ 'completionSha256',
181
+ 'callerFsyncedClosureByteLength',
182
+ 'callerFsyncedClosureSha256',
183
+ 'callerFsyncedReceiptByteLength',
184
+ 'callerFsyncedReceiptSha256',
185
+ 'callerFsyncedAt',
186
+ ] as const;
187
+ const releaseCompletionKeys = [
188
+ 'schemaVersion',
189
+ 'kind',
190
+ 'packageAttemptId',
191
+ 'requestSha256',
192
+ 'completionSha256',
193
+ 'releaseRequestSha256',
194
+ 'releasedAt',
195
+ ] as const;
196
+ const releaseResponseKeys = ['schemaVersion', 'kind', 'release', 'replayed'] as const;
197
+
198
+ const identifierPattern = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,255}$/;
199
+ const packageAttemptIdPattern = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
200
+ const sha256Pattern = /^[a-f0-9]{64}$/;
201
+
202
+ const fail = (
203
+ codeArg: TCorestoreDatabaseExportPackageCodecErrorCode,
204
+ pathArg: string,
205
+ ): never => {
206
+ throw new CorestoreDatabaseExportPackageCodecError(codeArg, pathArg);
207
+ };
208
+
209
+ const normalizeAllocationReference = (
210
+ valueArg: unknown,
211
+ pathArg: string,
212
+ ): ICorestoreDatabaseAllocationReference => {
213
+ try {
214
+ return normalizeCorestoreDatabaseAllocationReference(
215
+ valueArg,
216
+ ) as ICorestoreDatabaseAllocationReference;
217
+ } catch {
218
+ return fail('INVALID_VALUE', pathArg);
219
+ }
220
+ };
221
+
222
+ const normalizeBackupReceipt = (
223
+ valueArg: unknown,
224
+ pathArg: string,
225
+ ): ICorestoreDatabaseBackupReceipt => {
226
+ try {
227
+ return normalizeCorestoreDatabaseBackupReceipt(valueArg) as ICorestoreDatabaseBackupReceipt;
228
+ } catch {
229
+ return fail('INVALID_VALUE', pathArg);
230
+ }
231
+ };
232
+
233
+ const readRecord = (valueArg: unknown, pathArg: string): Record<string, unknown> => {
234
+ if (!valueArg || typeof valueArg !== 'object' || Array.isArray(valueArg)) {
235
+ return fail('INVALID_DATA', pathArg);
236
+ }
237
+ const prototype = Object.getPrototypeOf(valueArg);
238
+ if (prototype !== Object.prototype && prototype !== null) {
239
+ return fail('INVALID_DATA', pathArg);
240
+ }
241
+ const value = valueArg as Record<string, unknown>;
242
+ for (const key of Reflect.ownKeys(value)) {
243
+ if (typeof key !== 'string') return fail('INVALID_DATA', pathArg);
244
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
245
+ if (!descriptor || !descriptor.enumerable || !Object.hasOwn(descriptor, 'value')) {
246
+ return fail('INVALID_DATA', pathArg);
247
+ }
248
+ }
249
+ return value;
250
+ };
251
+
252
+ const assertExactKeys = (
253
+ valueArg: Record<string, unknown>,
254
+ keysArg: readonly string[],
255
+ pathArg: string,
256
+ ): void => {
257
+ const actual = Object.keys(valueArg).sort();
258
+ const expected = [...keysArg].sort();
259
+ if (actual.length !== expected.length
260
+ || actual.some((keyArg, indexArg) => keyArg !== expected[indexArg])) {
261
+ fail('INVALID_SCHEMA', pathArg);
262
+ }
263
+ };
264
+
265
+ const readIdentifier = (valueArg: unknown, pathArg: string): string => {
266
+ if (typeof valueArg !== 'string' || !identifierPattern.test(valueArg)) {
267
+ return fail('INVALID_VALUE', pathArg);
268
+ }
269
+ return valueArg;
270
+ };
271
+
272
+ const readPackageAttemptId = (valueArg: unknown, pathArg: string): string => {
273
+ if (typeof valueArg !== 'string' || !packageAttemptIdPattern.test(valueArg)) {
274
+ return fail('INVALID_VALUE', pathArg);
275
+ }
276
+ return valueArg;
277
+ };
278
+
279
+ const readSha256 = (valueArg: unknown, pathArg: string): string => {
280
+ if (typeof valueArg !== 'string' || !sha256Pattern.test(valueArg)) {
281
+ return fail('INVALID_VALUE', pathArg);
282
+ }
283
+ return valueArg;
284
+ };
285
+
286
+ const readInteger = (
287
+ valueArg: unknown,
288
+ pathArg: string,
289
+ minimumArg: number,
290
+ maximumArg = Number.MAX_SAFE_INTEGER,
291
+ ): number => {
292
+ if (typeof valueArg !== 'number'
293
+ || !Number.isSafeInteger(valueArg)
294
+ || Object.is(valueArg, -0)
295
+ || valueArg < minimumArg
296
+ || valueArg > maximumArg) {
297
+ return fail('INVALID_VALUE', pathArg);
298
+ }
299
+ return valueArg;
300
+ };
301
+
302
+ const readBoolean = (valueArg: unknown, pathArg: string): boolean => {
303
+ if (typeof valueArg !== 'boolean') return fail('INVALID_VALUE', pathArg);
304
+ return valueArg;
305
+ };
306
+
307
+ const canonicalize = (valueArg: unknown, pathArg: string): string => canonicalizeStrictJson(
308
+ valueArg,
309
+ () => fail('INVALID_DATA', pathArg),
310
+ pathArg,
311
+ );
312
+
313
+ const finalize = <T>(valueArg: T, pathArg: string): Readonly<T> => {
314
+ const canonical = canonicalize(valueArg, pathArg);
315
+ if (Buffer.byteLength(canonical, 'utf8')
316
+ > corestoreDatabaseExportPackageRuntimeLimits.maximumControlBytes) {
317
+ return fail('LIMIT_EXCEEDED', pathArg);
318
+ }
319
+ return deepFreezeValue(valueArg);
320
+ };
321
+
322
+ const encodeNormalized = (valueArg: unknown, pathArg: string): Uint8Array => (
323
+ Buffer.from(canonicalize(valueArg, pathArg), 'utf8')
324
+ );
325
+
326
+ const digestBytes = (valueArg: Uint8Array): string => plugins.crypto
327
+ .createHash('sha256')
328
+ .update(new Uint8Array(valueArg))
329
+ .digest('hex');
330
+
331
+ const canonicalEqual = (leftArg: unknown, rightArg: unknown, pathArg: string): boolean => (
332
+ canonicalize(leftArg, `${pathArg}.left`) === canonicalize(rightArg, `${pathArg}.right`)
333
+ );
334
+
335
+ const normalizeInputIdentityInternal = (
336
+ valueArg: unknown,
337
+ pathArg: string,
338
+ ): ICorestoreDatabaseExportPackageInputIdentityV1 => {
339
+ const value = readRecord(valueArg, pathArg);
340
+ assertExactKeys(value, inputIdentityKeys, pathArg);
341
+ if (value.format !== 'smartdb.database.export.v1'
342
+ || value.lineFeedTerminator !== 'single-lf') {
343
+ fail('INVALID_VALUE', `${pathArg}.format`);
344
+ }
345
+ return {
346
+ format: 'smartdb.database.export.v1',
347
+ databaseName: readIdentifier(value.databaseName, `${pathArg}.databaseName`),
348
+ byteLength: readInteger(
349
+ value.byteLength,
350
+ `${pathArg}.byteLength`,
351
+ 1,
352
+ corestoreDatabaseExportPackageRuntimeLimits.maximumInputBytes,
353
+ ),
354
+ sha256: readSha256(value.sha256, `${pathArg}.sha256`),
355
+ lineFeedTerminator: 'single-lf',
356
+ };
357
+ };
358
+
359
+ export const normalizeCorestoreDatabaseExportPackageInputIdentity = (
360
+ valueArg: unknown,
361
+ ): Readonly<ICorestoreDatabaseExportPackageInputIdentityV1> => finalize(
362
+ normalizeInputIdentityInternal(valueArg, 'databaseExportPackageInput'),
363
+ 'databaseExportPackageInput',
364
+ );
365
+
366
+ const normalizeApprovedBackupIdentityInternal = (
367
+ valueArg: unknown,
368
+ pathArg: string,
369
+ ): ICorestoreDatabaseExportPackageApprovedBackupIdentityV1 => {
370
+ const value = readRecord(valueArg, pathArg);
371
+ assertExactKeys(value, approvedBackupIdentityKeys, pathArg);
372
+ return {
373
+ backupId: readIdentifier(value.backupId, `${pathArg}.backupId`),
374
+ sourceServiceId: readIdentifier(value.sourceServiceId, `${pathArg}.sourceServiceId`),
375
+ snapshotId: readIdentifier(value.snapshotId, `${pathArg}.snapshotId`),
376
+ backupReceiptSha256: readSha256(
377
+ value.backupReceiptSha256,
378
+ `${pathArg}.backupReceiptSha256`,
379
+ ),
380
+ };
381
+ };
382
+
383
+ export const normalizeCorestoreDatabaseExportPackageApprovedBackupIdentity = (
384
+ valueArg: unknown,
385
+ ): Readonly<ICorestoreDatabaseExportPackageApprovedBackupIdentityV1> => finalize(
386
+ normalizeApprovedBackupIdentityInternal(valueArg, 'databaseExportPackageApprovedBackup'),
387
+ 'databaseExportPackageApprovedBackup',
388
+ );
389
+
390
+ const normalizeAllocationExpectationInternal = (
391
+ valueArg: unknown,
392
+ pathArg: string,
393
+ ): TCorestoreDatabaseExportPackageAllocationExpectationV1 => {
394
+ const value = readRecord(valueArg, pathArg);
395
+ if (value.expectation === 'absent') {
396
+ assertExactKeys(value, ['expectation'], pathArg);
397
+ return { expectation: 'absent' };
398
+ }
399
+ if (value.expectation !== 'exact') {
400
+ fail('INVALID_VALUE', `${pathArg}.expectation`);
401
+ }
402
+ assertExactKeys(value, ['expectation', 'allocation'], pathArg);
403
+ return {
404
+ expectation: 'exact',
405
+ allocation: normalizeAllocationReference(
406
+ value.allocation,
407
+ `${pathArg}.allocation`,
408
+ ),
409
+ };
410
+ };
411
+
412
+ export const normalizeCorestoreDatabaseExportPackageAllocationExpectation = (
413
+ valueArg: unknown,
414
+ ): Readonly<TCorestoreDatabaseExportPackageAllocationExpectationV1> => finalize(
415
+ normalizeAllocationExpectationInternal(valueArg, 'databaseExportPackageAllocationExpectation'),
416
+ 'databaseExportPackageAllocationExpectation',
417
+ );
418
+
419
+ export const normalizeCorestoreDatabaseExportPackageRequest = (
420
+ valueArg: unknown,
421
+ ): Readonly<ICorestoreDatabaseExportPackageRequestV1> => {
422
+ const value = readRecord(valueArg, 'databaseExportPackageRequest');
423
+ assertExactKeys(value, requestKeys, 'databaseExportPackageRequest');
424
+ if (value.schemaVersion !== 1
425
+ || value.kind !== 'corestore-database-export-package-request') {
426
+ fail('INVALID_VALUE', 'databaseExportPackageRequest.kind');
427
+ }
428
+ return finalize({
429
+ schemaVersion: 1,
430
+ kind: 'corestore-database-export-package-request',
431
+ packageAttemptId: readPackageAttemptId(
432
+ value.packageAttemptId,
433
+ 'databaseExportPackageRequest.packageAttemptId',
434
+ ),
435
+ packageBackupId: readIdentifier(
436
+ value.packageBackupId,
437
+ 'databaseExportPackageRequest.packageBackupId',
438
+ ),
439
+ input: normalizeInputIdentityInternal(value.input, 'databaseExportPackageRequest.input'),
440
+ approvedSourceBackup: normalizeApprovedBackupIdentityInternal(
441
+ value.approvedSourceBackup,
442
+ 'databaseExportPackageRequest.approvedSourceBackup',
443
+ ),
444
+ completeOutputReceiptSha256: readSha256(
445
+ value.completeOutputReceiptSha256,
446
+ 'databaseExportPackageRequest.completeOutputReceiptSha256',
447
+ ),
448
+ allocationExpectation: normalizeAllocationExpectationInternal(
449
+ value.allocationExpectation,
450
+ 'databaseExportPackageRequest.allocationExpectation',
451
+ ),
452
+ } satisfies ICorestoreDatabaseExportPackageRequestV1, 'databaseExportPackageRequest');
453
+ };
454
+
455
+ export const encodeCorestoreDatabaseExportPackageRequest = (
456
+ valueArg: unknown,
457
+ ): Uint8Array => encodeNormalized(
458
+ normalizeCorestoreDatabaseExportPackageRequest(valueArg),
459
+ 'databaseExportPackageRequest',
460
+ );
461
+
462
+ export const computeCorestoreDatabaseExportPackageRequestSha256 = async (
463
+ valueArg: unknown,
464
+ ): Promise<string> => digestBytes(encodeCorestoreDatabaseExportPackageRequest(valueArg));
465
+
466
+ const digestCorestoreDatabaseExportPackageRequest = (valueArg: unknown): string => digestBytes(
467
+ encodeCorestoreDatabaseExportPackageRequest(valueArg),
468
+ );
469
+
470
+ export const classifyCorestoreDatabaseExportPackageRequestReuse = (
471
+ persistedRequestArg: unknown,
472
+ candidateRequestArg: unknown,
473
+ ): TCorestoreDatabaseExportPackageRequestReuse => {
474
+ const persisted = normalizeCorestoreDatabaseExportPackageRequest(persistedRequestArg);
475
+ const candidate = normalizeCorestoreDatabaseExportPackageRequest(candidateRequestArg);
476
+ if (persisted.packageAttemptId !== candidate.packageAttemptId) return 'different-attempt';
477
+ if (!canonicalEqual(persisted, candidate, 'databaseExportPackageRequest.reuse')) {
478
+ fail('ATTEMPT_CONFLICT', 'databaseExportPackageRequest.packageAttemptId');
479
+ }
480
+ return 'exact-replay';
481
+ };
482
+
483
+ export const normalizeCorestoreDatabaseExportPackageCompletion = (
484
+ valueArg: unknown,
485
+ ): Readonly<ICorestoreDatabaseExportPackageCompletionV1> => {
486
+ const value = readRecord(valueArg, 'databaseExportPackageCompletion');
487
+ assertExactKeys(value, completionKeys, 'databaseExportPackageCompletion');
488
+ if (value.schemaVersion !== 1
489
+ || value.kind !== 'corestore-database-export-package-completion') {
490
+ fail('INVALID_VALUE', 'databaseExportPackageCompletion.kind');
491
+ }
492
+ const receipt = normalizeBackupReceipt(
493
+ value.receipt,
494
+ 'databaseExportPackageCompletion.receipt',
495
+ );
496
+ const receiptSha256 = readSha256(
497
+ value.receiptSha256,
498
+ 'databaseExportPackageCompletion.receiptSha256',
499
+ );
500
+ const closureByteLength = readInteger(
501
+ value.closureByteLength,
502
+ 'databaseExportPackageCompletion.closureByteLength',
503
+ 1,
504
+ corestoreDatabaseExportPackageRuntimeLimits.maximumClosureBytes,
505
+ );
506
+ const closureSha256 = readSha256(
507
+ value.closureSha256,
508
+ 'databaseExportPackageCompletion.closureSha256',
509
+ );
510
+ if (receiptSha256 !== digestBytes(encodeCorestoreDatabaseBackupReceipt(receipt))
511
+ || closureByteLength !== receipt.closure.archiveBytes
512
+ || closureSha256 !== receipt.closure.sha256) {
513
+ fail('CROSS_FIELD_MISMATCH', 'databaseExportPackageCompletion.receipt');
514
+ }
515
+ const completedAt = readInteger(
516
+ value.completedAt,
517
+ 'databaseExportPackageCompletion.completedAt',
518
+ receipt.createdAt,
519
+ );
520
+ return finalize({
521
+ schemaVersion: 1,
522
+ kind: 'corestore-database-export-package-completion',
523
+ packageAttemptId: readPackageAttemptId(
524
+ value.packageAttemptId,
525
+ 'databaseExportPackageCompletion.packageAttemptId',
526
+ ),
527
+ requestSha256: readSha256(
528
+ value.requestSha256,
529
+ 'databaseExportPackageCompletion.requestSha256',
530
+ ),
531
+ completedAt,
532
+ receipt,
533
+ receiptSha256,
534
+ closureByteLength,
535
+ closureSha256,
536
+ } satisfies ICorestoreDatabaseExportPackageCompletionV1, 'databaseExportPackageCompletion');
537
+ };
538
+
539
+ export const normalizeCorestoreDatabaseExportPackageCompletionForRequest = (
540
+ completionArg: unknown,
541
+ requestArg: unknown,
542
+ ): Readonly<ICorestoreDatabaseExportPackageCompletionV1> => {
543
+ const request = normalizeCorestoreDatabaseExportPackageRequest(requestArg);
544
+ const completion = normalizeCorestoreDatabaseExportPackageCompletion(completionArg);
545
+ const receiptAllocation = completion.receipt.snapshot.databaseAllocation;
546
+ const allocationMatches = request.allocationExpectation.expectation === 'absent'
547
+ ? receiptAllocation === undefined
548
+ : receiptAllocation !== undefined
549
+ && canonicalEqual(
550
+ receiptAllocation,
551
+ request.allocationExpectation.allocation,
552
+ 'databaseExportPackageCompletion.receipt.snapshot.databaseAllocation',
553
+ );
554
+ if (completion.packageAttemptId !== request.packageAttemptId
555
+ || completion.requestSha256 !== digestCorestoreDatabaseExportPackageRequest(request)
556
+ || completion.receipt.backupId !== request.packageBackupId
557
+ || completion.receipt.sourceServiceId !== request.approvedSourceBackup.sourceServiceId
558
+ || completion.receipt.snapshot.databaseName !== request.input.databaseName
559
+ || completion.receipt.snapshot.originalSize !== request.input.byteLength
560
+ || !allocationMatches) {
561
+ fail('CROSS_FIELD_MISMATCH', 'databaseExportPackageCompletion.request');
562
+ }
563
+ return completion;
564
+ };
565
+
566
+ export const encodeCorestoreDatabaseExportPackageCompletion = (
567
+ valueArg: unknown,
568
+ ): Uint8Array => encodeNormalized(
569
+ normalizeCorestoreDatabaseExportPackageCompletion(valueArg),
570
+ 'databaseExportPackageCompletion',
571
+ );
572
+
573
+ export const computeCorestoreDatabaseExportPackageCompletionSha256 = async (
574
+ valueArg: unknown,
575
+ ): Promise<string> => digestBytes(encodeCorestoreDatabaseExportPackageCompletion(valueArg));
576
+
577
+ const digestCorestoreDatabaseExportPackageCompletion = (valueArg: unknown): string => digestBytes(
578
+ encodeCorestoreDatabaseExportPackageCompletion(valueArg),
579
+ );
580
+
581
+ export const normalizeCorestoreDatabaseExportPackageResponse = (
582
+ valueArg: unknown,
583
+ ): Readonly<ICorestoreDatabaseExportPackageResponseV1> => {
584
+ const value = readRecord(valueArg, 'databaseExportPackageResponse');
585
+ assertExactKeys(value, responseKeys, 'databaseExportPackageResponse');
586
+ if (value.schemaVersion !== 1
587
+ || value.kind !== 'corestore-database-export-package-response') {
588
+ fail('INVALID_VALUE', 'databaseExportPackageResponse.kind');
589
+ }
590
+ return finalize({
591
+ schemaVersion: 1,
592
+ kind: 'corestore-database-export-package-response',
593
+ completion: normalizeCorestoreDatabaseExportPackageCompletion(
594
+ value.completion,
595
+ ) as ICorestoreDatabaseExportPackageCompletionV1,
596
+ replayed: readBoolean(value.replayed, 'databaseExportPackageResponse.replayed'),
597
+ } satisfies ICorestoreDatabaseExportPackageResponseV1, 'databaseExportPackageResponse');
598
+ };
599
+
600
+ export const normalizeCorestoreDatabaseExportPackageResponseForRequest = (
601
+ responseArg: unknown,
602
+ requestArg: unknown,
603
+ ): Readonly<ICorestoreDatabaseExportPackageResponseV1> => {
604
+ const response = normalizeCorestoreDatabaseExportPackageResponse(responseArg);
605
+ normalizeCorestoreDatabaseExportPackageCompletionForRequest(
606
+ response.completion,
607
+ requestArg,
608
+ );
609
+ return response;
610
+ };
611
+
612
+ export const encodeCorestoreDatabaseExportPackageResponse = (
613
+ valueArg: unknown,
614
+ ): Uint8Array => encodeNormalized(
615
+ normalizeCorestoreDatabaseExportPackageResponse(valueArg),
616
+ 'databaseExportPackageResponse',
617
+ );
618
+
619
+ export const computeCorestoreDatabaseExportPackageResponseSha256 = async (
620
+ valueArg: unknown,
621
+ ): Promise<string> => digestBytes(encodeCorestoreDatabaseExportPackageResponse(valueArg));
622
+
623
+ export const normalizeCorestoreDatabaseExportPackageReleaseRequest = (
624
+ valueArg: unknown,
625
+ ): Readonly<ICorestoreDatabaseExportPackageReleaseRequestV1> => {
626
+ const value = readRecord(valueArg, 'databaseExportPackageReleaseRequest');
627
+ assertExactKeys(value, releaseRequestKeys, 'databaseExportPackageReleaseRequest');
628
+ if (value.schemaVersion !== 1
629
+ || value.kind !== 'corestore-database-export-package-release-request') {
630
+ fail('INVALID_VALUE', 'databaseExportPackageReleaseRequest.kind');
631
+ }
632
+ return finalize({
633
+ schemaVersion: 1,
634
+ kind: 'corestore-database-export-package-release-request',
635
+ packageAttemptId: readPackageAttemptId(
636
+ value.packageAttemptId,
637
+ 'databaseExportPackageReleaseRequest.packageAttemptId',
638
+ ),
639
+ requestSha256: readSha256(
640
+ value.requestSha256,
641
+ 'databaseExportPackageReleaseRequest.requestSha256',
642
+ ),
643
+ completionSha256: readSha256(
644
+ value.completionSha256,
645
+ 'databaseExportPackageReleaseRequest.completionSha256',
646
+ ),
647
+ callerFsyncedClosureByteLength: readInteger(
648
+ value.callerFsyncedClosureByteLength,
649
+ 'databaseExportPackageReleaseRequest.callerFsyncedClosureByteLength',
650
+ 1,
651
+ corestoreDatabaseExportPackageRuntimeLimits.maximumClosureBytes,
652
+ ),
653
+ callerFsyncedClosureSha256: readSha256(
654
+ value.callerFsyncedClosureSha256,
655
+ 'databaseExportPackageReleaseRequest.callerFsyncedClosureSha256',
656
+ ),
657
+ callerFsyncedReceiptByteLength: readInteger(
658
+ value.callerFsyncedReceiptByteLength,
659
+ 'databaseExportPackageReleaseRequest.callerFsyncedReceiptByteLength',
660
+ 1,
661
+ corestoreDatabaseExportPackageRuntimeLimits.maximumControlBytes,
662
+ ),
663
+ callerFsyncedReceiptSha256: readSha256(
664
+ value.callerFsyncedReceiptSha256,
665
+ 'databaseExportPackageReleaseRequest.callerFsyncedReceiptSha256',
666
+ ),
667
+ callerFsyncedAt: readInteger(
668
+ value.callerFsyncedAt,
669
+ 'databaseExportPackageReleaseRequest.callerFsyncedAt',
670
+ 1,
671
+ ),
672
+ } satisfies ICorestoreDatabaseExportPackageReleaseRequestV1,
673
+ 'databaseExportPackageReleaseRequest');
674
+ };
675
+
676
+ export const normalizeCorestoreDatabaseExportPackageReleaseRequestForCompletion = (
677
+ releaseRequestArg: unknown,
678
+ requestArg: unknown,
679
+ completionArg: unknown,
680
+ ): Readonly<ICorestoreDatabaseExportPackageReleaseRequestV1> => {
681
+ const request = normalizeCorestoreDatabaseExportPackageRequest(requestArg);
682
+ const completion = normalizeCorestoreDatabaseExportPackageCompletionForRequest(
683
+ completionArg,
684
+ request,
685
+ );
686
+ const releaseRequest = normalizeCorestoreDatabaseExportPackageReleaseRequest(
687
+ releaseRequestArg,
688
+ );
689
+ const receiptBytes = encodeCorestoreDatabaseBackupReceipt(completion.receipt);
690
+ if (releaseRequest.packageAttemptId !== request.packageAttemptId
691
+ || releaseRequest.requestSha256 !== digestCorestoreDatabaseExportPackageRequest(request)
692
+ || releaseRequest.completionSha256
693
+ !== digestCorestoreDatabaseExportPackageCompletion(completion)
694
+ || releaseRequest.callerFsyncedClosureByteLength !== completion.closureByteLength
695
+ || releaseRequest.callerFsyncedClosureSha256 !== completion.closureSha256
696
+ || releaseRequest.callerFsyncedReceiptByteLength !== receiptBytes.byteLength
697
+ || releaseRequest.callerFsyncedReceiptSha256 !== completion.receiptSha256
698
+ || releaseRequest.callerFsyncedAt < completion.completedAt) {
699
+ fail('CROSS_FIELD_MISMATCH', 'databaseExportPackageReleaseRequest.completion');
700
+ }
701
+ return releaseRequest;
702
+ };
703
+
704
+ export const encodeCorestoreDatabaseExportPackageReleaseRequest = (
705
+ valueArg: unknown,
706
+ ): Uint8Array => encodeNormalized(
707
+ normalizeCorestoreDatabaseExportPackageReleaseRequest(valueArg),
708
+ 'databaseExportPackageReleaseRequest',
709
+ );
710
+
711
+ export const computeCorestoreDatabaseExportPackageReleaseRequestSha256 = async (
712
+ valueArg: unknown,
713
+ ): Promise<string> => digestBytes(encodeCorestoreDatabaseExportPackageReleaseRequest(valueArg));
714
+
715
+ const digestCorestoreDatabaseExportPackageReleaseRequest = (valueArg: unknown): string => (
716
+ digestBytes(encodeCorestoreDatabaseExportPackageReleaseRequest(valueArg))
717
+ );
718
+
719
+ export const classifyCorestoreDatabaseExportPackageReleaseRequestReuse = (
720
+ persistedRequestArg: unknown,
721
+ candidateRequestArg: unknown,
722
+ ): TCorestoreDatabaseExportPackageRequestReuse => {
723
+ const persisted = normalizeCorestoreDatabaseExportPackageReleaseRequest(persistedRequestArg);
724
+ const candidate = normalizeCorestoreDatabaseExportPackageReleaseRequest(candidateRequestArg);
725
+ if (persisted.packageAttemptId !== candidate.packageAttemptId) return 'different-attempt';
726
+ if (!canonicalEqual(persisted, candidate, 'databaseExportPackageReleaseRequest.reuse')) {
727
+ fail('ATTEMPT_CONFLICT', 'databaseExportPackageReleaseRequest.packageAttemptId');
728
+ }
729
+ return 'exact-replay';
730
+ };
731
+
732
+ export const normalizeCorestoreDatabaseExportPackageReleaseCompletion = (
733
+ valueArg: unknown,
734
+ ): Readonly<ICorestoreDatabaseExportPackageReleaseCompletionV1> => {
735
+ const value = readRecord(valueArg, 'databaseExportPackageReleaseCompletion');
736
+ assertExactKeys(value, releaseCompletionKeys, 'databaseExportPackageReleaseCompletion');
737
+ if (value.schemaVersion !== 1
738
+ || value.kind !== 'corestore-database-export-package-release-completion') {
739
+ fail('INVALID_VALUE', 'databaseExportPackageReleaseCompletion.kind');
740
+ }
741
+ return finalize({
742
+ schemaVersion: 1,
743
+ kind: 'corestore-database-export-package-release-completion',
744
+ packageAttemptId: readPackageAttemptId(
745
+ value.packageAttemptId,
746
+ 'databaseExportPackageReleaseCompletion.packageAttemptId',
747
+ ),
748
+ requestSha256: readSha256(
749
+ value.requestSha256,
750
+ 'databaseExportPackageReleaseCompletion.requestSha256',
751
+ ),
752
+ completionSha256: readSha256(
753
+ value.completionSha256,
754
+ 'databaseExportPackageReleaseCompletion.completionSha256',
755
+ ),
756
+ releaseRequestSha256: readSha256(
757
+ value.releaseRequestSha256,
758
+ 'databaseExportPackageReleaseCompletion.releaseRequestSha256',
759
+ ),
760
+ releasedAt: readInteger(
761
+ value.releasedAt,
762
+ 'databaseExportPackageReleaseCompletion.releasedAt',
763
+ 1,
764
+ ),
765
+ } satisfies ICorestoreDatabaseExportPackageReleaseCompletionV1,
766
+ 'databaseExportPackageReleaseCompletion');
767
+ };
768
+
769
+ export const normalizeCorestoreDatabaseExportPackageReleaseCompletionForRequest = (
770
+ releaseCompletionArg: unknown,
771
+ releaseRequestArg: unknown,
772
+ requestArg: unknown,
773
+ completionArg: unknown,
774
+ ): Readonly<ICorestoreDatabaseExportPackageReleaseCompletionV1> => {
775
+ const request = normalizeCorestoreDatabaseExportPackageRequest(requestArg);
776
+ const completion = normalizeCorestoreDatabaseExportPackageCompletionForRequest(
777
+ completionArg,
778
+ request,
779
+ );
780
+ const releaseRequest = normalizeCorestoreDatabaseExportPackageReleaseRequestForCompletion(
781
+ releaseRequestArg,
782
+ request,
783
+ completion,
784
+ );
785
+ const releaseCompletion = normalizeCorestoreDatabaseExportPackageReleaseCompletion(
786
+ releaseCompletionArg,
787
+ );
788
+ if (releaseCompletion.packageAttemptId !== request.packageAttemptId
789
+ || releaseCompletion.requestSha256 !== digestCorestoreDatabaseExportPackageRequest(request)
790
+ || releaseCompletion.completionSha256
791
+ !== digestCorestoreDatabaseExportPackageCompletion(completion)
792
+ || releaseCompletion.releaseRequestSha256
793
+ !== digestCorestoreDatabaseExportPackageReleaseRequest(releaseRequest)
794
+ || releaseCompletion.releasedAt < releaseRequest.callerFsyncedAt) {
795
+ fail('CROSS_FIELD_MISMATCH', 'databaseExportPackageReleaseCompletion.request');
796
+ }
797
+ return releaseCompletion;
798
+ };
799
+
800
+ export const encodeCorestoreDatabaseExportPackageReleaseCompletion = (
801
+ valueArg: unknown,
802
+ ): Uint8Array => encodeNormalized(
803
+ normalizeCorestoreDatabaseExportPackageReleaseCompletion(valueArg),
804
+ 'databaseExportPackageReleaseCompletion',
805
+ );
806
+
807
+ export const computeCorestoreDatabaseExportPackageReleaseCompletionSha256 = async (
808
+ valueArg: unknown,
809
+ ): Promise<string> => digestBytes(
810
+ encodeCorestoreDatabaseExportPackageReleaseCompletion(valueArg),
811
+ );
812
+
813
+ export const normalizeCorestoreDatabaseExportPackageReleaseResponse = (
814
+ valueArg: unknown,
815
+ ): Readonly<ICorestoreDatabaseExportPackageReleaseResponseV1> => {
816
+ const value = readRecord(valueArg, 'databaseExportPackageReleaseResponse');
817
+ assertExactKeys(value, releaseResponseKeys, 'databaseExportPackageReleaseResponse');
818
+ if (value.schemaVersion !== 1
819
+ || value.kind !== 'corestore-database-export-package-release-response') {
820
+ fail('INVALID_VALUE', 'databaseExportPackageReleaseResponse.kind');
821
+ }
822
+ return finalize({
823
+ schemaVersion: 1,
824
+ kind: 'corestore-database-export-package-release-response',
825
+ release: normalizeCorestoreDatabaseExportPackageReleaseCompletion(
826
+ value.release,
827
+ ) as ICorestoreDatabaseExportPackageReleaseCompletionV1,
828
+ replayed: readBoolean(value.replayed, 'databaseExportPackageReleaseResponse.replayed'),
829
+ } satisfies ICorestoreDatabaseExportPackageReleaseResponseV1,
830
+ 'databaseExportPackageReleaseResponse');
831
+ };
832
+
833
+ export const normalizeCorestoreDatabaseExportPackageReleaseResponseForRequest = (
834
+ responseArg: unknown,
835
+ releaseRequestArg: unknown,
836
+ requestArg: unknown,
837
+ completionArg: unknown,
838
+ ): Readonly<ICorestoreDatabaseExportPackageReleaseResponseV1> => {
839
+ const response = normalizeCorestoreDatabaseExportPackageReleaseResponse(responseArg);
840
+ normalizeCorestoreDatabaseExportPackageReleaseCompletionForRequest(
841
+ response.release,
842
+ releaseRequestArg,
843
+ requestArg,
844
+ completionArg,
845
+ );
846
+ return response;
847
+ };
848
+
849
+ export const encodeCorestoreDatabaseExportPackageReleaseResponse = (
850
+ valueArg: unknown,
851
+ ): Uint8Array => encodeNormalized(
852
+ normalizeCorestoreDatabaseExportPackageReleaseResponse(valueArg),
853
+ 'databaseExportPackageReleaseResponse',
854
+ );
855
+
856
+ export const computeCorestoreDatabaseExportPackageReleaseResponseSha256 = async (
857
+ valueArg: unknown,
858
+ ): Promise<string> => digestBytes(encodeCorestoreDatabaseExportPackageReleaseResponse(valueArg));
859
+
860
+ export {
861
+ corestoreDatabaseExportPackageGoldenVectors,
862
+ } from './runtime.corestore.databaseexportpackage.golden.js';