@serve.zone/interfaces 31.5.0 → 31.7.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.
- package/changelog.md +68 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/backup.d.ts +13 -0
- package/dist_ts/data/clusternode.d.ts +49 -0
- package/dist_ts/data/clusternode.js +47 -1
- package/dist_ts/data/corestore.d.ts +27 -0
- package/dist_ts/data/corestore.js +11 -0
- package/dist_ts/data/index.d.ts +1 -0
- package/dist_ts/data/index.js +2 -1
- package/dist_ts/data/isolatedrestore.js +42 -2
- package/dist_ts/requests/backup.d.ts +223 -0
- package/dist_ts/requests/corestore.d.ts +57 -0
- package/dist_ts/requests/corestore.js +102 -1
- package/dist_ts/requests/node.d.ts +31 -0
- package/dist_ts/requests/platform.d.ts +30 -0
- package/dist_ts/runtime.corestore.d.ts +7 -10
- package/dist_ts/runtime.corestore.js +1 -1
- package/dist_ts/runtime.corestore.relay.d.ts +47 -0
- package/dist_ts/runtime.corestore.relay.js +57 -0
- package/dist_ts/runtime.d.ts +1 -0
- package/dist_ts/runtime.js +2 -1
- package/package.json +1 -1
- package/readme.md +112 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/backup.ts +14 -0
- package/ts/data/clusternode.ts +93 -0
- package/ts/data/corestore.ts +28 -0
- package/ts/data/index.ts +1 -0
- package/ts/data/isolatedrestore.ts +53 -1
- package/ts/requests/backup.ts +253 -0
- package/ts/requests/corestore.ts +183 -0
- package/ts/requests/node.ts +35 -0
- package/ts/requests/platform.ts +36 -0
- package/ts/runtime.corestore.relay.ts +111 -0
- package/ts/runtime.corestore.ts +7 -8
- package/ts/runtime.ts +1 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { ICorestoreDatabaseBackupReceipt } from './runtime.corestore.js';
|
|
2
|
+
import {
|
|
3
|
+
corestoreDatabaseBackupRuntimeLimits,
|
|
4
|
+
normalizeCorestoreDatabaseBackupReceipt,
|
|
5
|
+
} from './runtime.corestore.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Carrying a Corestore database closure through the cluster relay.
|
|
9
|
+
*
|
|
10
|
+
* A cluster is outbound-only, so Cloudly never reads Corestore itself: the
|
|
11
|
+
* relay exports the closure from its cluster's Corestore and streams it to
|
|
12
|
+
* Cloudly, and streams it back for a restore. The bytes travel as a
|
|
13
|
+
* VirtualStream on the relay's own session; this descriptor is what the parent
|
|
14
|
+
* TypedRequest carries about them.
|
|
15
|
+
*
|
|
16
|
+
* No version suffix and no schema field: the protocol version is the installed
|
|
17
|
+
* `@serve.zone/interfaces` version.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* What a peer states about the closure it is about to send or serve.
|
|
22
|
+
*
|
|
23
|
+
* `size` is mandatory, and it is the reason this descriptor exists at all:
|
|
24
|
+
* Corestore's database backup restore requires one exact `Content-Length`,
|
|
25
|
+
* identity transfer encoding and no content encoding, and it refuses a body
|
|
26
|
+
* whose byte length differs from its receipt. A stream that only learned its
|
|
27
|
+
* length at EOF could therefore never be restored — the receiver has to open
|
|
28
|
+
* the Corestore request before the first byte arrives.
|
|
29
|
+
*
|
|
30
|
+
* `sha256` is the digest of those exact bytes, and `receipt` is Corestore's own
|
|
31
|
+
* closure receipt, which binds the backup, the source service, the snapshot and
|
|
32
|
+
* the closure's identity. The two are cross-checked here rather than trusted
|
|
33
|
+
* separately: a descriptor whose `size` or `sha256` disagrees with its receipt
|
|
34
|
+
* describes a closure nobody can restore.
|
|
35
|
+
*/
|
|
36
|
+
export interface ICorestoreDatabaseClosureDescriptor {
|
|
37
|
+
/** Exact byte length of the closure, as Corestore's `Content-Length` needs it. */
|
|
38
|
+
size: number;
|
|
39
|
+
/** Lowercase hex SHA-256 over those exact bytes. */
|
|
40
|
+
sha256: string;
|
|
41
|
+
/** Corestore's own receipt for this closure; its identity and integrity authority. */
|
|
42
|
+
receipt: ICorestoreDatabaseBackupReceipt;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const bareSha256Pattern = /^[a-f0-9]{64}$/;
|
|
46
|
+
|
|
47
|
+
const isRecord = (valueArg: unknown): valueArg is Record<string, unknown> => (
|
|
48
|
+
Boolean(valueArg)
|
|
49
|
+
&& typeof valueArg === 'object'
|
|
50
|
+
&& !Array.isArray(valueArg)
|
|
51
|
+
&& (Object.getPrototypeOf(valueArg) === Object.prototype
|
|
52
|
+
|| Object.getPrototypeOf(valueArg) === null)
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const hasExactKeys = (
|
|
56
|
+
valueArg: Record<string, unknown>,
|
|
57
|
+
keysArg: readonly string[],
|
|
58
|
+
): boolean => {
|
|
59
|
+
const actualKeys = Object.keys(valueArg).sort();
|
|
60
|
+
const expectedKeys = [...keysArg].sort();
|
|
61
|
+
return actualKeys.length === expectedKeys.length
|
|
62
|
+
&& actualKeys.every((keyArg, indexArg) => keyArg === expectedKeys[indexArg]);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Validates one closure descriptor and names every reason it is refused.
|
|
67
|
+
*
|
|
68
|
+
* Shape and self-consistency only: whether the closure exists, whether the
|
|
69
|
+
* backup is this cluster's and whether the target database may be replaced are
|
|
70
|
+
* decisions for the party that holds them. A descriptor that passes here has
|
|
71
|
+
* claimed none of them. No reason quotes closure bytes, because a reason
|
|
72
|
+
* travels into logs and the closure is tenant data.
|
|
73
|
+
*/
|
|
74
|
+
export const validateCorestoreDatabaseClosureDescriptor = (
|
|
75
|
+
valueArg: unknown,
|
|
76
|
+
pathArg = 'corestore database closure descriptor',
|
|
77
|
+
): string[] => {
|
|
78
|
+
if (!isRecord(valueArg) || !hasExactKeys(valueArg, ['size', 'sha256', 'receipt'])) {
|
|
79
|
+
return [`${pathArg} must use its exact schema`];
|
|
80
|
+
}
|
|
81
|
+
const errors: string[] = [];
|
|
82
|
+
const maximumBytes = corestoreDatabaseBackupRuntimeLimits.maximumClosureBytes;
|
|
83
|
+
if (!Number.isSafeInteger(valueArg.size)
|
|
84
|
+
|| (valueArg.size as number) < 1
|
|
85
|
+
|| (valueArg.size as number) > maximumBytes) {
|
|
86
|
+
errors.push(`${pathArg} size must be an integer from 1 to ${maximumBytes}`);
|
|
87
|
+
}
|
|
88
|
+
if (typeof valueArg.sha256 !== 'string' || !bareSha256Pattern.test(valueArg.sha256)) {
|
|
89
|
+
errors.push(`${pathArg} sha256 must be a lowercase hex SHA-256 digest`);
|
|
90
|
+
}
|
|
91
|
+
let receipt: ICorestoreDatabaseBackupReceipt | undefined;
|
|
92
|
+
try {
|
|
93
|
+
receipt = normalizeCorestoreDatabaseBackupReceipt(valueArg.receipt);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
// Corestore's own normalizer names the field it refused and never the
|
|
96
|
+
// material behind it, so its reason is worth more than its class.
|
|
97
|
+
errors.push(`${pathArg} receipt is not canonical: ${(error as Error).message}`);
|
|
98
|
+
}
|
|
99
|
+
if (!receipt || errors.length > 0) {
|
|
100
|
+
return errors;
|
|
101
|
+
}
|
|
102
|
+
if (valueArg.size !== receipt.closure.archiveBytes) {
|
|
103
|
+
errors.push(
|
|
104
|
+
`${pathArg} size must equal the ${receipt.closure.archiveBytes} bytes its receipt states`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (valueArg.sha256 !== receipt.closure.sha256) {
|
|
108
|
+
errors.push(`${pathArg} sha256 must equal the digest its receipt states`);
|
|
109
|
+
}
|
|
110
|
+
return errors;
|
|
111
|
+
};
|
package/ts/runtime.corestore.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import type {
|
|
3
3
|
IActiveSecretRecipientMetadata,
|
|
4
|
+
ICorestoreDatabaseAllocationReference,
|
|
4
5
|
IIdentityCredential,
|
|
5
6
|
ISecretVersionReference,
|
|
6
7
|
} from './data/index.js';
|
|
@@ -1281,14 +1282,12 @@ export const corestoreDatabaseBackupRuntimeLimits = Object.freeze({
|
|
|
1281
1282
|
maximumServiceNameBytes: 1024,
|
|
1282
1283
|
});
|
|
1283
1284
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
receiptSha256: string;
|
|
1291
|
-
}
|
|
1285
|
+
/**
|
|
1286
|
+
* Declared in the data tree, because an isolated restore's canonical resource
|
|
1287
|
+
* mappings bind the exact same reference and that tree carries no runtime
|
|
1288
|
+
* import. Re-exported here so this module's readers keep one import site.
|
|
1289
|
+
*/
|
|
1290
|
+
export type { ICorestoreDatabaseAllocationReference };
|
|
1292
1291
|
|
|
1293
1292
|
export interface ICorestoreDatabaseBackupSnapshotTags {
|
|
1294
1293
|
corestore: 'resource';
|
package/ts/runtime.ts
CHANGED
|
@@ -42,6 +42,7 @@ export * from './runtime.workloadinit.js';
|
|
|
42
42
|
export * from './runtime.networkprojection.js';
|
|
43
43
|
export * from './runtime.corestore.js';
|
|
44
44
|
export * from './runtime.corestore.databaseexportpackage.js';
|
|
45
|
+
export * from './runtime.corestore.relay.js';
|
|
45
46
|
export * from './runtime.cloudlylegacydeploymentsettlement.js';
|
|
46
47
|
export * from './runtime.cloudlylegacydeploymentsettlement.offlineexport.js';
|
|
47
48
|
|