@lossless.org/nosqldb 8.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.
- package/.smartconfig.json +107 -0
- package/dist_rust/rustdb_linux_amd64 +0 -0
- package/dist_rust/rustdb_linux_amd64.tsrust-build.json +14 -0
- package/dist_rust/rustdb_linux_arm64 +0 -0
- package/dist_rust/rustdb_linux_arm64.tsrust-build.json +14 -0
- package/dist_rust/rustdb_macos_amd64 +0 -0
- package/dist_rust/rustdb_macos_amd64.tsrust-build.json +14 -0
- package/dist_rust/rustdb_macos_arm64 +0 -0
- package/dist_rust/rustdb_macos_arm64.tsrust-build.json +14 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/index.d.ts +8 -0
- package/dist_ts/index.js +10 -0
- package/dist_ts/ts_local/classes.localnosqldb.d.ts +119 -0
- package/dist_ts/ts_local/classes.localnosqldb.js +386 -0
- package/dist_ts/ts_local/index.d.ts +5 -0
- package/dist_ts/ts_local/index.js +3 -0
- package/dist_ts/ts_local/plugins.d.ts +1 -0
- package/dist_ts/ts_local/plugins.js +3 -0
- package/dist_ts/ts_nosqldb/classes.storagerehearsal.d.ts +19 -0
- package/dist_ts/ts_nosqldb/classes.storagerehearsal.js +122 -0
- package/dist_ts/ts_nosqldb/file-storage-options.d.ts +13 -0
- package/dist_ts/ts_nosqldb/file-storage-options.js +24 -0
- package/dist_ts/ts_nosqldb/file-storage-startup.d.ts +3 -0
- package/dist_ts/ts_nosqldb/file-storage-startup.js +6 -0
- package/dist_ts/ts_nosqldb/index.d.ts +14 -0
- package/dist_ts/ts_nosqldb/index.js +11 -0
- package/dist_ts/ts_nosqldb/offline-inspection.d.ts +72 -0
- package/dist_ts/ts_nosqldb/offline-inspection.js +282 -0
- package/dist_ts/ts_nosqldb/plugins.d.ts +7 -0
- package/dist_ts/ts_nosqldb/plugins.js +10 -0
- package/dist_ts/ts_nosqldb/resource-fencing.d.ts +39 -0
- package/dist_ts/ts_nosqldb/resource-fencing.js +271 -0
- package/dist_ts/ts_nosqldb/rust-db-bridge.d.ts +213 -0
- package/dist_ts/ts_nosqldb/rust-db-bridge.js +439 -0
- package/dist_ts/ts_nosqldb/server/classes.nosqldbserver.d.ts +204 -0
- package/dist_ts/ts_nosqldb/server/classes.nosqldbserver.js +456 -0
- package/dist_ts/ts_nosqldb/server/index.d.ts +3 -0
- package/dist_ts/ts_nosqldb/server/index.js +3 -0
- package/dist_ts/ts_nosqldb/service-types.d.ts +341 -0
- package/dist_ts/ts_nosqldb/service-types.js +62 -0
- package/dist_ts/ts_nosqldb/storage-rehearsal.d.ts +103 -0
- package/dist_ts/ts_nosqldb/storage-rehearsal.js +131 -0
- package/dist_ts/ts_nosqldb/storage-root-relocation.d.ts +27 -0
- package/dist_ts/ts_nosqldb/storage-root-relocation.js +211 -0
- package/dist_ts_debugserver/bundled.d.ts +4 -0
- package/dist_ts_debugserver/bundled.js +16 -0
- package/dist_ts_debugserver/classes.debugserver.d.ts +36 -0
- package/dist_ts_debugserver/classes.debugserver.js +95 -0
- package/dist_ts_debugserver/index.d.ts +2 -0
- package/dist_ts_debugserver/index.js +2 -0
- package/dist_ts_debugserver/plugins.d.ts +2 -0
- package/dist_ts_debugserver/plugins.js +3 -0
- package/dist_ts_debugui/index.d.ts +2 -0
- package/dist_ts_debugui/index.js +2 -0
- package/dist_ts_debugui/nosqldb-debugui.d.ts +62 -0
- package/dist_ts_debugui/nosqldb-debugui.js +1132 -0
- package/dist_ts_debugui/plugins.d.ts +1 -0
- package/dist_ts_debugui/plugins.js +2 -0
- package/license +21 -0
- package/package.json +82 -0
- package/readme.md +1733 -0
- package/third-party-notices.md +925 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/index.ts +85 -0
- package/ts/ts_local/classes.localnosqldb.ts +500 -0
- package/ts/ts_local/index.ts +19 -0
- package/ts/ts_local/plugins.ts +1 -0
- package/ts/ts_nosqldb/classes.storagerehearsal.ts +109 -0
- package/ts/ts_nosqldb/file-storage-options.ts +33 -0
- package/ts/ts_nosqldb/file-storage-startup.ts +9 -0
- package/ts/ts_nosqldb/index.ts +104 -0
- package/ts/ts_nosqldb/offline-inspection.ts +375 -0
- package/ts/ts_nosqldb/plugins.ts +12 -0
- package/ts/ts_nosqldb/resource-fencing.ts +368 -0
- package/ts/ts_nosqldb/rust-db-bridge.ts +964 -0
- package/ts/ts_nosqldb/server/classes.nosqldbserver.ts +696 -0
- package/ts/ts_nosqldb/server/index.ts +4 -0
- package/ts/ts_nosqldb/service-types.ts +484 -0
- package/ts/ts_nosqldb/storage-rehearsal.ts +215 -0
- package/ts/ts_nosqldb/storage-root-relocation.ts +277 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
export interface INoSqlDbHealth {
|
|
2
|
+
running: boolean;
|
|
3
|
+
storage?: 'memory' | 'file';
|
|
4
|
+
fileStorageEngine?: 'mvcc';
|
|
5
|
+
storagePurpose?: 'production' | 'rehearsal';
|
|
6
|
+
storageRehearsalId?: string | null;
|
|
7
|
+
storagePath?: string;
|
|
8
|
+
resourceFencingVersion?: 1;
|
|
9
|
+
resourceFencingSupported?: boolean;
|
|
10
|
+
resourceFencingRequiresDrain?: true;
|
|
11
|
+
allocationFencingVersion?: 1;
|
|
12
|
+
allocationFencingSupported?: boolean;
|
|
13
|
+
allocationFencingRequiresDrain?: true;
|
|
14
|
+
databaseAllocationReadAccessGrantVersion?: 1;
|
|
15
|
+
databaseAllocationReadAccessGrantSupported?: true;
|
|
16
|
+
publicationHoldVersion: 1;
|
|
17
|
+
publicationHoldSupported: boolean;
|
|
18
|
+
publicationHoldRequiresExternalDrain: boolean;
|
|
19
|
+
authEnabled?: boolean;
|
|
20
|
+
authUsers?: number;
|
|
21
|
+
usersPathConfigured?: boolean;
|
|
22
|
+
databaseCount: number;
|
|
23
|
+
collectionCount: number;
|
|
24
|
+
uptimeSeconds?: number;
|
|
25
|
+
}
|
|
26
|
+
/** Per-operation admission bounds for read-only stopped native storage inspection. */
|
|
27
|
+
export interface ILocalNoSqlDbOfflineInspectionLimits {
|
|
28
|
+
maximumEntries: number;
|
|
29
|
+
maximumTotalFileBytes: number;
|
|
30
|
+
maximumRecords: number;
|
|
31
|
+
maximumRecordBytes: number;
|
|
32
|
+
maximumResultBytes: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ILocalNoSqlDbOfflineStringValueInspection {
|
|
35
|
+
folderPath: string;
|
|
36
|
+
databaseName: string;
|
|
37
|
+
collectionName: string;
|
|
38
|
+
match: {
|
|
39
|
+
field: string;
|
|
40
|
+
value: string;
|
|
41
|
+
};
|
|
42
|
+
valueField: string;
|
|
43
|
+
limits: ILocalNoSqlDbOfflineInspectionLimits;
|
|
44
|
+
}
|
|
45
|
+
export type TLocalNoSqlDbOfflineStringValueInspectionResult = {
|
|
46
|
+
status: 'not-found';
|
|
47
|
+
} | {
|
|
48
|
+
status: 'found';
|
|
49
|
+
value: string;
|
|
50
|
+
};
|
|
51
|
+
export interface ILocalNoSqlDbOfflinePhysicalNamespaceInspectionLimits {
|
|
52
|
+
maximumEntries: number;
|
|
53
|
+
maximumDatabases: number;
|
|
54
|
+
maximumCollections: number;
|
|
55
|
+
maximumIndexes: number;
|
|
56
|
+
maximumTotalFileBytes: number;
|
|
57
|
+
maximumRecordsPerCollection: number;
|
|
58
|
+
maximumRecordBytes: number;
|
|
59
|
+
maximumResultBytes: number;
|
|
60
|
+
}
|
|
61
|
+
export interface ILocalNoSqlDbOfflinePhysicalNamespaceInspection {
|
|
62
|
+
folderPath: string;
|
|
63
|
+
limits: ILocalNoSqlDbOfflinePhysicalNamespaceInspectionLimits;
|
|
64
|
+
}
|
|
65
|
+
export interface ILocalNoSqlDbOfflinePhysicalNamespaceInspectionResult {
|
|
66
|
+
schemaVersion: 1;
|
|
67
|
+
databases: Array<{
|
|
68
|
+
name: string;
|
|
69
|
+
collections: string[];
|
|
70
|
+
}>;
|
|
71
|
+
}
|
|
72
|
+
export declare const noSqlDbResourceFenceErrorCodes: readonly ["EFENCE_REQUIRED", "EFENCE_STALE", "EFENCE_SCOPE_MISMATCH", "EFENCE_UNSUPPORTED", "EFENCE_MUTATION_MISMATCH", "EFENCE_OWNERSHIP_MISMATCH", "EFENCE_STATE_CORRUPT", "EFENCE_RECEIPT_LIMIT", "EFENCE_BUSY", "EFENCE_PUBLICATION_HELD", "EFENCE_CAPABILITY_MISMATCH", "EFENCE_NOT_HELD", "EALLOCATION_EXPECTED_ABSENT_CONFLICT", "EALLOCATION_REQUIRED", "EALLOCATION_MISMATCH", "EALLOCATION_GENERATION_EXHAUSTED", "EALLOCATION_DEPROVISIONED"];
|
|
73
|
+
export type TNoSqlDbResourceFenceErrorCode = (typeof noSqlDbResourceFenceErrorCodes)[number];
|
|
74
|
+
export interface INoSqlDbResourceFence {
|
|
75
|
+
version: 1;
|
|
76
|
+
scopeId: string;
|
|
77
|
+
token: number;
|
|
78
|
+
mutationId: string;
|
|
79
|
+
payloadSha256: string;
|
|
80
|
+
}
|
|
81
|
+
export interface INoSqlDbResourceFenceReceipt extends INoSqlDbResourceFence {
|
|
82
|
+
kind: 'smartdb.database.replace.v1' | 'smartdb.database.delete.v1' | 'smartdb.database.ensure.v1' | 'smartdb.database.allocate.v1';
|
|
83
|
+
/** Digest of the canonical payload interpretation derived by NoSQLDB. */
|
|
84
|
+
effectivePayloadSha256: string;
|
|
85
|
+
provider?: 'smartdb';
|
|
86
|
+
resourceIdSha256?: string;
|
|
87
|
+
holdPublication?: true;
|
|
88
|
+
publicationState?: 'held' | 'released';
|
|
89
|
+
bindingSha256?: string;
|
|
90
|
+
resultSha256?: string;
|
|
91
|
+
receiptSha256?: string;
|
|
92
|
+
publicationCapabilitySha256?: string;
|
|
93
|
+
/** Present only while publication is held; never returned after release. */
|
|
94
|
+
publicationCapability?: string;
|
|
95
|
+
allocation?: INoSqlDbDatabaseAllocationIdentity;
|
|
96
|
+
}
|
|
97
|
+
export interface INoSqlDbDatabaseAllocationIdentity {
|
|
98
|
+
version: 1;
|
|
99
|
+
provider: 'smartdb';
|
|
100
|
+
state: 'active';
|
|
101
|
+
databaseName: string;
|
|
102
|
+
username: string;
|
|
103
|
+
allocationId: string;
|
|
104
|
+
generation: number;
|
|
105
|
+
principalId: string;
|
|
106
|
+
resourceIdSha256: string;
|
|
107
|
+
bindingSha256: string;
|
|
108
|
+
receiptSha256: string;
|
|
109
|
+
}
|
|
110
|
+
export interface INoSqlDbDatabaseAllocationLifecycle {
|
|
111
|
+
version: 1;
|
|
112
|
+
provider: 'smartdb';
|
|
113
|
+
state: 'allocating' | 'active' | 'deprovisioning' | 'deprovisioned';
|
|
114
|
+
databaseName: string;
|
|
115
|
+
username: string;
|
|
116
|
+
allocationId: string;
|
|
117
|
+
generation: number;
|
|
118
|
+
principalId: string;
|
|
119
|
+
resourceIdSha256: string;
|
|
120
|
+
bindingSha256: string;
|
|
121
|
+
receiptSha256: string;
|
|
122
|
+
}
|
|
123
|
+
export interface INoSqlDbDatabaseAllocationReadAccessGrantIdentity {
|
|
124
|
+
version: 1;
|
|
125
|
+
grantId: string;
|
|
126
|
+
principalId: string;
|
|
127
|
+
generation: number;
|
|
128
|
+
}
|
|
129
|
+
export interface INoSqlDbIssueDatabaseAllocationReadAccessGrantInput {
|
|
130
|
+
databaseName: string;
|
|
131
|
+
grantId: string;
|
|
132
|
+
username: string;
|
|
133
|
+
password: string;
|
|
134
|
+
allocation: INoSqlDbDatabaseAllocationIdentity;
|
|
135
|
+
}
|
|
136
|
+
export interface INoSqlDbIssueDatabaseAllocationReadAccessGrantResult {
|
|
137
|
+
databaseName: string;
|
|
138
|
+
username: string;
|
|
139
|
+
roles: ['read'];
|
|
140
|
+
authSource: string;
|
|
141
|
+
mongodbUri?: string;
|
|
142
|
+
allocation: INoSqlDbDatabaseAllocationIdentity;
|
|
143
|
+
grant: INoSqlDbDatabaseAllocationReadAccessGrantIdentity;
|
|
144
|
+
issuedAt: number;
|
|
145
|
+
expiresAt: number;
|
|
146
|
+
}
|
|
147
|
+
export interface INoSqlDbRevokeDatabaseAllocationReadAccessGrantInput {
|
|
148
|
+
databaseName: string;
|
|
149
|
+
grantId: string;
|
|
150
|
+
allocation: INoSqlDbDatabaseAllocationIdentity;
|
|
151
|
+
}
|
|
152
|
+
export interface INoSqlDbRevokeDatabaseAllocationReadAccessGrantResult {
|
|
153
|
+
databaseName: string;
|
|
154
|
+
grantId: string;
|
|
155
|
+
allocation: INoSqlDbDatabaseAllocationIdentity;
|
|
156
|
+
revoked: true;
|
|
157
|
+
}
|
|
158
|
+
export declare const noSqlDbAllocationReadAccessGrantErrorCodes: readonly ["EGRANT_INVALID_REQUEST", "EGRANT_CREDENTIAL_MISMATCH", "EGRANT_CONFLICT", "EGRANT_REPLAY_CAPACITY", "EGRANT_STATE_UNAVAILABLE"];
|
|
159
|
+
export type TNoSqlDbAllocationReadAccessGrantErrorCode = (typeof noSqlDbAllocationReadAccessGrantErrorCodes)[number];
|
|
160
|
+
export declare class NoSqlDbAllocationReadAccessGrantError extends Error {
|
|
161
|
+
readonly code: TNoSqlDbAllocationReadAccessGrantErrorCode;
|
|
162
|
+
constructor(codeArg: TNoSqlDbAllocationReadAccessGrantErrorCode, messageArg: string, causeArg?: unknown);
|
|
163
|
+
}
|
|
164
|
+
export declare const normalizeNoSqlDbAllocationReadAccessGrantError: (errorArg: unknown, codeArg?: unknown) => Error;
|
|
165
|
+
export interface INoSqlDbHeldPublicationReceipt extends INoSqlDbResourceFenceReceipt {
|
|
166
|
+
provider: 'smartdb';
|
|
167
|
+
resourceIdSha256: string;
|
|
168
|
+
holdPublication: true;
|
|
169
|
+
publicationState: 'held';
|
|
170
|
+
bindingSha256: string;
|
|
171
|
+
resultSha256: string;
|
|
172
|
+
receiptSha256: string;
|
|
173
|
+
publicationCapabilitySha256: string;
|
|
174
|
+
publicationCapability: string;
|
|
175
|
+
}
|
|
176
|
+
export interface INoSqlDbCommitDatabasePublicationInput {
|
|
177
|
+
databaseName: string;
|
|
178
|
+
resourceFence: INoSqlDbHeldPublicationReceipt;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Cancellation and deadline ownership for one durable database-management
|
|
182
|
+
* operation. Aborting or timing out is fail-stop: NoSQLDB terminates the Rust
|
|
183
|
+
* engine so the operation cannot continue after the caller has released it.
|
|
184
|
+
*/
|
|
185
|
+
export interface INoSqlDbManagementOperationOptions {
|
|
186
|
+
signal?: AbortSignal;
|
|
187
|
+
timeoutMs?: number;
|
|
188
|
+
}
|
|
189
|
+
export interface INoSqlDbDatabaseResourceFenceState {
|
|
190
|
+
version: 1;
|
|
191
|
+
databaseName: string;
|
|
192
|
+
resourceIdSha256: string;
|
|
193
|
+
scopeId: string;
|
|
194
|
+
highestToken: number;
|
|
195
|
+
publicationState: 'requested' | 'publishing' | 'held' | 'released';
|
|
196
|
+
allocation?: INoSqlDbDatabaseAllocationLifecycle;
|
|
197
|
+
}
|
|
198
|
+
export declare class NoSqlDbResourceFenceError extends Error {
|
|
199
|
+
readonly code: TNoSqlDbResourceFenceErrorCode;
|
|
200
|
+
constructor(codeArg: TNoSqlDbResourceFenceErrorCode, messageArg: string, causeArg?: unknown);
|
|
201
|
+
}
|
|
202
|
+
export declare const normalizeNoSqlDbResourceFenceError: (errorArg: unknown) => Error;
|
|
203
|
+
export interface INoSqlDbDatabaseTenantInput {
|
|
204
|
+
databaseName: string;
|
|
205
|
+
username: string;
|
|
206
|
+
password: string;
|
|
207
|
+
roles?: string[];
|
|
208
|
+
}
|
|
209
|
+
export interface INoSqlDbEnsureDatabaseTenantInput extends INoSqlDbDatabaseTenantInput {
|
|
210
|
+
fence: INoSqlDbResourceFence;
|
|
211
|
+
allocation?: INoSqlDbDatabaseAllocationIdentity;
|
|
212
|
+
}
|
|
213
|
+
export interface INoSqlDbAttestDatabaseTenantInput {
|
|
214
|
+
databaseName: string;
|
|
215
|
+
username: string;
|
|
216
|
+
roles: string[];
|
|
217
|
+
password: string;
|
|
218
|
+
}
|
|
219
|
+
export interface INoSqlDbAttestDatabaseTenantResult {
|
|
220
|
+
matches: boolean;
|
|
221
|
+
}
|
|
222
|
+
export interface INoSqlDbAllocateDatabaseTenantInput extends INoSqlDbDatabaseTenantInput {
|
|
223
|
+
expectedAbsent: true;
|
|
224
|
+
fence: INoSqlDbResourceFence;
|
|
225
|
+
}
|
|
226
|
+
export interface INoSqlDbDeleteDatabaseTenantInput {
|
|
227
|
+
databaseName: string;
|
|
228
|
+
/**
|
|
229
|
+
* Exact tenant user to revoke. For a fenced deletion this identity is
|
|
230
|
+
* included in the durable mutation and is removed idempotently after the
|
|
231
|
+
* database deletion is durable. Omitting it from a fenced deletion
|
|
232
|
+
* preserves auth users; an unfenced omission retains the legacy behavior
|
|
233
|
+
* of deleting every user for the database. If the database exists, a
|
|
234
|
+
* fenced deletion fails closed unless this exact user currently owns it.
|
|
235
|
+
*/
|
|
236
|
+
username?: string;
|
|
237
|
+
fence?: INoSqlDbResourceFence;
|
|
238
|
+
allocation?: INoSqlDbDatabaseAllocationIdentity;
|
|
239
|
+
/** Keep the database data plane closed until commitDatabasePublication. */
|
|
240
|
+
holdPublication?: boolean;
|
|
241
|
+
}
|
|
242
|
+
export interface INoSqlDbRotateDatabaseTenantPasswordInput {
|
|
243
|
+
username: string;
|
|
244
|
+
password: string;
|
|
245
|
+
}
|
|
246
|
+
export interface INoSqlDbDatabaseTenantDescriptor {
|
|
247
|
+
databaseName: string;
|
|
248
|
+
username: string;
|
|
249
|
+
roles: string[];
|
|
250
|
+
authSource: string;
|
|
251
|
+
mongodbUri?: string;
|
|
252
|
+
resourceFence?: INoSqlDbResourceFenceReceipt;
|
|
253
|
+
allocation?: INoSqlDbDatabaseAllocationIdentity;
|
|
254
|
+
}
|
|
255
|
+
export interface INoSqlDbEnsureDatabaseTenantResult extends INoSqlDbDatabaseTenantDescriptor {
|
|
256
|
+
resourceFence: INoSqlDbResourceFenceReceipt;
|
|
257
|
+
}
|
|
258
|
+
export interface INoSqlDbAllocateDatabaseTenantResult extends INoSqlDbDatabaseTenantDescriptor {
|
|
259
|
+
resourceFence: INoSqlDbResourceFenceReceipt;
|
|
260
|
+
allocation: INoSqlDbDatabaseAllocationIdentity;
|
|
261
|
+
}
|
|
262
|
+
export interface INoSqlDbDeleteDatabaseTenantResult {
|
|
263
|
+
databaseName: string;
|
|
264
|
+
/**
|
|
265
|
+
* Users removed during the completing attempt. This can be zero after
|
|
266
|
+
* crash recovery when the exact user was durably removed by the prior
|
|
267
|
+
* attempt.
|
|
268
|
+
*/
|
|
269
|
+
deletedUsers: number;
|
|
270
|
+
databaseDropped: boolean;
|
|
271
|
+
/**
|
|
272
|
+
* Present for fenced calls. False means the bound exact username is now
|
|
273
|
+
* absent; true means no username was supplied and auth users were preserved.
|
|
274
|
+
*/
|
|
275
|
+
usersPreserved?: boolean;
|
|
276
|
+
resourceFence?: INoSqlDbResourceFenceReceipt;
|
|
277
|
+
allocation?: INoSqlDbDatabaseAllocationIdentity;
|
|
278
|
+
}
|
|
279
|
+
export interface INoSqlDbDatabaseExportCollection {
|
|
280
|
+
name: string;
|
|
281
|
+
documents: Record<string, any>[];
|
|
282
|
+
indexes: Record<string, any>[];
|
|
283
|
+
}
|
|
284
|
+
export interface INoSqlDbDatabaseExportLimits {
|
|
285
|
+
maxEncodedBytes?: number;
|
|
286
|
+
maxCollections?: number;
|
|
287
|
+
maxDocuments?: number;
|
|
288
|
+
maxIndexes?: number;
|
|
289
|
+
}
|
|
290
|
+
export interface INoSqlDbExportDatabaseInput {
|
|
291
|
+
databaseName: string;
|
|
292
|
+
limits?: INoSqlDbDatabaseExportLimits;
|
|
293
|
+
}
|
|
294
|
+
export interface INoSqlDbDatabaseContentDigestLimits {
|
|
295
|
+
maxScannedBsonBytes?: number;
|
|
296
|
+
maxCollections?: number;
|
|
297
|
+
maxDocuments?: number;
|
|
298
|
+
maxIndexes?: number;
|
|
299
|
+
}
|
|
300
|
+
export interface INoSqlDbGetDatabaseContentDigestInput {
|
|
301
|
+
databaseName: string;
|
|
302
|
+
limits?: INoSqlDbDatabaseContentDigestLimits;
|
|
303
|
+
}
|
|
304
|
+
export interface INoSqlDbDatabaseContentDigest {
|
|
305
|
+
format: 'smartdb.database.content-digest.v1';
|
|
306
|
+
algorithm: 'sha256';
|
|
307
|
+
databaseName: string;
|
|
308
|
+
sha256: string;
|
|
309
|
+
scannedBsonBytes: number;
|
|
310
|
+
collections: number;
|
|
311
|
+
documents: number;
|
|
312
|
+
indexes: number;
|
|
313
|
+
}
|
|
314
|
+
export interface INoSqlDbDatabaseExport {
|
|
315
|
+
format: 'smartdb.database.export.v1';
|
|
316
|
+
databaseName: string;
|
|
317
|
+
exportedAtMs: number;
|
|
318
|
+
collections: INoSqlDbDatabaseExportCollection[];
|
|
319
|
+
}
|
|
320
|
+
export interface INoSqlDbImportDatabaseInput {
|
|
321
|
+
databaseName: string;
|
|
322
|
+
source: INoSqlDbDatabaseExport;
|
|
323
|
+
/**
|
|
324
|
+
* Exact exclusive tenant owner required for this replacement. When used
|
|
325
|
+
* with a fence, the username is included in the provider-derived mutation
|
|
326
|
+
* identity. Omission preserves the original version 1 replacement profile.
|
|
327
|
+
*/
|
|
328
|
+
username?: string;
|
|
329
|
+
fence?: INoSqlDbResourceFence;
|
|
330
|
+
allocation?: INoSqlDbDatabaseAllocationIdentity;
|
|
331
|
+
/** Keep the database data plane closed until commitDatabasePublication. */
|
|
332
|
+
holdPublication?: boolean;
|
|
333
|
+
}
|
|
334
|
+
export interface INoSqlDbImportDatabaseResult {
|
|
335
|
+
databaseName: string;
|
|
336
|
+
collections: number;
|
|
337
|
+
documents: number;
|
|
338
|
+
resourceFence?: INoSqlDbResourceFenceReceipt;
|
|
339
|
+
allocation?: INoSqlDbDatabaseAllocationIdentity;
|
|
340
|
+
}
|
|
341
|
+
export type TNoSqlDbCommitDatabasePublicationResult = INoSqlDbImportDatabaseResult | INoSqlDbDeleteDatabaseTenantResult;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const noSqlDbResourceFenceErrorCodes = [
|
|
2
|
+
'EFENCE_REQUIRED',
|
|
3
|
+
'EFENCE_STALE',
|
|
4
|
+
'EFENCE_SCOPE_MISMATCH',
|
|
5
|
+
'EFENCE_UNSUPPORTED',
|
|
6
|
+
'EFENCE_MUTATION_MISMATCH',
|
|
7
|
+
'EFENCE_OWNERSHIP_MISMATCH',
|
|
8
|
+
'EFENCE_STATE_CORRUPT',
|
|
9
|
+
'EFENCE_RECEIPT_LIMIT',
|
|
10
|
+
'EFENCE_BUSY',
|
|
11
|
+
'EFENCE_PUBLICATION_HELD',
|
|
12
|
+
'EFENCE_CAPABILITY_MISMATCH',
|
|
13
|
+
'EFENCE_NOT_HELD',
|
|
14
|
+
'EALLOCATION_EXPECTED_ABSENT_CONFLICT',
|
|
15
|
+
'EALLOCATION_REQUIRED',
|
|
16
|
+
'EALLOCATION_MISMATCH',
|
|
17
|
+
'EALLOCATION_GENERATION_EXHAUSTED',
|
|
18
|
+
'EALLOCATION_DEPROVISIONED',
|
|
19
|
+
];
|
|
20
|
+
export const noSqlDbAllocationReadAccessGrantErrorCodes = [
|
|
21
|
+
'EGRANT_INVALID_REQUEST',
|
|
22
|
+
'EGRANT_CREDENTIAL_MISMATCH',
|
|
23
|
+
'EGRANT_CONFLICT',
|
|
24
|
+
'EGRANT_REPLAY_CAPACITY',
|
|
25
|
+
'EGRANT_STATE_UNAVAILABLE',
|
|
26
|
+
];
|
|
27
|
+
export class NoSqlDbAllocationReadAccessGrantError extends Error {
|
|
28
|
+
constructor(codeArg, messageArg, causeArg) {
|
|
29
|
+
super(`${codeArg}: ${messageArg}`, { cause: causeArg });
|
|
30
|
+
this.name = 'NoSqlDbAllocationReadAccessGrantError';
|
|
31
|
+
this.code = codeArg;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export const normalizeNoSqlDbAllocationReadAccessGrantError = (errorArg, codeArg) => {
|
|
35
|
+
const error = errorArg instanceof Error
|
|
36
|
+
? errorArg
|
|
37
|
+
: new Error(String(errorArg));
|
|
38
|
+
if (typeof codeArg !== 'string'
|
|
39
|
+
|| !noSqlDbAllocationReadAccessGrantErrorCodes.includes(codeArg)) {
|
|
40
|
+
return error;
|
|
41
|
+
}
|
|
42
|
+
return new NoSqlDbAllocationReadAccessGrantError(codeArg, error.message, error);
|
|
43
|
+
};
|
|
44
|
+
export class NoSqlDbResourceFenceError extends Error {
|
|
45
|
+
constructor(codeArg, messageArg, causeArg) {
|
|
46
|
+
super(`${codeArg}: ${messageArg}`, { cause: causeArg });
|
|
47
|
+
this.name = 'NoSqlDbResourceFenceError';
|
|
48
|
+
this.code = codeArg;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export const normalizeNoSqlDbResourceFenceError = (errorArg) => {
|
|
52
|
+
const error = errorArg instanceof Error
|
|
53
|
+
? errorArg
|
|
54
|
+
: new Error(String(errorArg));
|
|
55
|
+
const match = /^((?:EFENCE|EALLOCATION)_[A-Z_]+):\s*(.*)$/s.exec(error.message);
|
|
56
|
+
if (!match ||
|
|
57
|
+
!noSqlDbResourceFenceErrorCodes.includes(match[1])) {
|
|
58
|
+
return error;
|
|
59
|
+
}
|
|
60
|
+
return new NoSqlDbResourceFenceError(match[1], match[2], error);
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS10eXBlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3RzX25vc3FsZGIvc2VydmljZS10eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUEyRUEsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQUc7SUFDNUMsaUJBQWlCO0lBQ2pCLGNBQWM7SUFDZCx1QkFBdUI7SUFDdkIsb0JBQW9CO0lBQ3BCLDBCQUEwQjtJQUMxQiwyQkFBMkI7SUFDM0Isc0JBQXNCO0lBQ3RCLHNCQUFzQjtJQUN0QixhQUFhO0lBQ2IseUJBQXlCO0lBQ3pCLDRCQUE0QjtJQUM1QixpQkFBaUI7SUFDakIsc0NBQXNDO0lBQ3RDLHNCQUFzQjtJQUN0QixzQkFBc0I7SUFDdEIsa0NBQWtDO0lBQ2xDLDJCQUEyQjtDQUNuQixDQUFDO0FBdUdYLE1BQU0sQ0FBQyxNQUFNLDBDQUEwQyxHQUFHO0lBQ3hELHdCQUF3QjtJQUN4Qiw0QkFBNEI7SUFDNUIsaUJBQWlCO0lBQ2pCLHdCQUF3QjtJQUN4QiwwQkFBMEI7Q0FDbEIsQ0FBQztBQUtYLE1BQU0sT0FBTyxxQ0FBc0MsU0FBUSxLQUFLO0lBRzlELFlBQ0UsT0FBbUQsRUFDbkQsVUFBa0IsRUFDbEIsUUFBa0I7UUFFbEIsS0FBSyxDQUFDLEdBQUcsT0FBTyxLQUFLLFVBQVUsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLElBQUksR0FBRyx1Q0FBdUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztJQUN0QixDQUFDO0NBQ0Y7QUFFRCxNQUFNLENBQUMsTUFBTSw4Q0FBOEMsR0FBRyxDQUM1RCxRQUFpQixFQUNqQixPQUFpQixFQUNWLEVBQUU7SUFDVCxNQUFNLEtBQUssR0FDVCxRQUFRLFlBQVksS0FBSztRQUN2QixDQUFDLENBQUMsUUFBUTtRQUNWLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNsQyxJQUNFLE9BQU8sT0FBTyxLQUFLLFFBQVE7V0FDeEIsQ0FBQywwQ0FBMEMsQ0FBQyxRQUFRLENBQ3JELE9BQXFELENBQ3RELEVBQ0QsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE9BQU8sSUFBSSxxQ0FBcUMsQ0FDOUMsT0FBcUQsRUFDckQsS0FBSyxDQUFDLE9BQU8sRUFDYixLQUFLLENBQ04sQ0FBQztBQUNKLENBQUMsQ0FBQztBQXdDRixNQUFNLE9BQU8seUJBQTBCLFNBQVEsS0FBSztJQUdsRCxZQUNFLE9BQXVDLEVBQ3ZDLFVBQWtCLEVBQ2xCLFFBQWtCO1FBRWxCLEtBQUssQ0FBQyxHQUFHLE9BQU8sS0FBSyxVQUFVLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxJQUFJLEdBQUcsMkJBQTJCLENBQUM7UUFDeEMsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7SUFDdEIsQ0FBQztDQUNGO0FBRUQsTUFBTSxDQUFDLE1BQU0sa0NBQWtDLEdBQUcsQ0FDaEQsUUFBaUIsRUFDVixFQUFFO0lBQ1QsTUFBTSxLQUFLLEdBQ1QsUUFBUSxZQUFZLEtBQUs7UUFDdkIsQ0FBQyxDQUFDLFFBQVE7UUFDVixDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbEMsTUFBTSxLQUFLLEdBQUcsNkNBQTZDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoRixJQUNFLENBQUMsS0FBSztRQUNOLENBQUMsOEJBQThCLENBQUMsUUFBUSxDQUN0QyxLQUFLLENBQUMsQ0FBQyxDQUFtQyxDQUMzQyxFQUNELENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxPQUFPLElBQUkseUJBQXlCLENBQ2xDLEtBQUssQ0FBQyxDQUFDLENBQW1DLEVBQzFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFDUixLQUFLLENBQ04sQ0FBQztBQUNKLENBQUMsQ0FBQyJ9
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { INoSqlDbServerOptions } from './server/classes.nosqldbserver.js';
|
|
2
|
+
export declare const noSqlDbStorageRehearsalErrorCodes: readonly ["INVALID_REQUEST", "UNSUPPORTED", "BUSY", "NOT_FOUND", "DESTINATION_CONFLICT", "IDENTITY_MISMATCH", "STATE_CORRUPT", "SOURCE_CHANGED", "CAPACITY", "CANCELLED", "IO", "RECOVERY_REQUIRED", "BINARY_UNAVAILABLE"];
|
|
3
|
+
export type TNoSqlDbStorageRehearsalErrorCode = typeof noSqlDbStorageRehearsalErrorCodes[number];
|
|
4
|
+
/** Errors deliberately contain neither persisted values nor nested engine errors. */
|
|
5
|
+
export declare class NoSqlDbStorageRehearsalError extends Error {
|
|
6
|
+
readonly code: TNoSqlDbStorageRehearsalErrorCode;
|
|
7
|
+
constructor(code: TNoSqlDbStorageRehearsalErrorCode);
|
|
8
|
+
}
|
|
9
|
+
export interface INoSqlDbStorageRehearsalOptions {
|
|
10
|
+
/** Exact executable, with SmartRust's exclusive non-mutating selection contract. */
|
|
11
|
+
binaryPath?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface INoSqlDbStorageRehearsalInput {
|
|
14
|
+
/** Absolute canonical path of an already initialized, stopped source. */
|
|
15
|
+
sourceFolderPath: string;
|
|
16
|
+
/** Absent destination; its existing parent must be private and on the source filesystem. */
|
|
17
|
+
destinationFolderPath: string;
|
|
18
|
+
/** Optional previously attested provider identity. The engine always verifies source ownership and bindings. */
|
|
19
|
+
expectedSourceProviderRootId?: string;
|
|
20
|
+
/** Stable caller operation ID. Every retry must retain the same request. */
|
|
21
|
+
operationId: string;
|
|
22
|
+
limits?: {
|
|
23
|
+
/** Source files plus directories, including the root. Default/maximum: 100,000. */
|
|
24
|
+
maximumEntries: number;
|
|
25
|
+
/** Total source file bytes. Default/maximum: 1 TiB. */
|
|
26
|
+
maximumBytes: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** Counts include retained historical records separately from live contents. */
|
|
30
|
+
export interface INoSqlDbStorageRehearsalPreservation {
|
|
31
|
+
files: number;
|
|
32
|
+
bytes: number;
|
|
33
|
+
databases: number;
|
|
34
|
+
collections: number;
|
|
35
|
+
documents: number;
|
|
36
|
+
indexes: number;
|
|
37
|
+
indexAliases: number;
|
|
38
|
+
users: number;
|
|
39
|
+
principalIdentities: number;
|
|
40
|
+
retiredDatabases: number;
|
|
41
|
+
retiredCollections: number;
|
|
42
|
+
retiredDocuments: number;
|
|
43
|
+
retiredIndexes: number;
|
|
44
|
+
retiredPrincipals: number;
|
|
45
|
+
allocationReplays: number;
|
|
46
|
+
resources: number;
|
|
47
|
+
receipts: number;
|
|
48
|
+
maximumFencingToken: string;
|
|
49
|
+
publicationHolds: number;
|
|
50
|
+
activeAllocations: number;
|
|
51
|
+
retiredAllocations: number;
|
|
52
|
+
sessions: number;
|
|
53
|
+
retiringSessions: number;
|
|
54
|
+
retryOutcomes: number;
|
|
55
|
+
transactionOutcomes: number;
|
|
56
|
+
obsoleteOutcomes: number;
|
|
57
|
+
records: number;
|
|
58
|
+
encodedRecordBytes: number;
|
|
59
|
+
}
|
|
60
|
+
/** Immutable creation evidence. Completed retries replay this receipt even after isolated writes. */
|
|
61
|
+
export interface INoSqlDbStorageRehearsalReceipt {
|
|
62
|
+
format: 'smartdb.storage-rehearsal.receipt.v2';
|
|
63
|
+
operationId: string;
|
|
64
|
+
requestSha256: string;
|
|
65
|
+
storageProfile: 'native-mvcc-authenticated-v1';
|
|
66
|
+
sourceFolderPath: string;
|
|
67
|
+
destinationFolderPath: string;
|
|
68
|
+
sourceProviderRootId: string;
|
|
69
|
+
destinationProviderRootId: string;
|
|
70
|
+
sourceStorageRootSha256: string;
|
|
71
|
+
sourceSnapshotSha256: string;
|
|
72
|
+
destinationDevice: string;
|
|
73
|
+
destinationInode: string;
|
|
74
|
+
groupId: string;
|
|
75
|
+
timelineId: string;
|
|
76
|
+
sourceLsn: string;
|
|
77
|
+
destinationLsn: string;
|
|
78
|
+
sourceRecordsSha256: string;
|
|
79
|
+
preservedRecordsSha256: string;
|
|
80
|
+
scramIterations: number;
|
|
81
|
+
preservation: INoSqlDbStorageRehearsalPreservation;
|
|
82
|
+
sourceUnchanged: true;
|
|
83
|
+
contentsAndIndexesPreserved: true;
|
|
84
|
+
namespacesPreserved: true;
|
|
85
|
+
authenticationPreserved: true;
|
|
86
|
+
historicalFencingPreserved: true;
|
|
87
|
+
outcomesPreserved: true;
|
|
88
|
+
filesystemBindingsVerified: true;
|
|
89
|
+
productionAuthority: false;
|
|
90
|
+
promotionSupported: false;
|
|
91
|
+
receiptSha256: string;
|
|
92
|
+
}
|
|
93
|
+
export type TNormalizedNoSqlDbStorageRehearsalInput = INoSqlDbStorageRehearsalInput & {
|
|
94
|
+
limits: NonNullable<INoSqlDbStorageRehearsalInput['limits']>;
|
|
95
|
+
};
|
|
96
|
+
export declare const normalizeNoSqlDbStorageRehearsalOptions: (value: unknown) => INoSqlDbStorageRehearsalOptions;
|
|
97
|
+
export declare const normalizeNoSqlDbStorageRehearsalOperationOptions: (value: unknown) => {
|
|
98
|
+
timeoutMs: number;
|
|
99
|
+
signal?: AbortSignal;
|
|
100
|
+
};
|
|
101
|
+
export declare const normalizeNoSqlDbStorageRehearsalInput: (value: unknown) => TNormalizedNoSqlDbStorageRehearsalInput;
|
|
102
|
+
export declare const normalizeNoSqlDbStorageRehearsalReceipt: (value: unknown, input: TNormalizedNoSqlDbStorageRehearsalInput) => INoSqlDbStorageRehearsalReceipt;
|
|
103
|
+
export declare const validateNoSqlDbStorageRehearsalStartup: (options: INoSqlDbServerOptions) => void;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
export const noSqlDbStorageRehearsalErrorCodes = [
|
|
3
|
+
'INVALID_REQUEST', 'UNSUPPORTED', 'BUSY', 'NOT_FOUND', 'DESTINATION_CONFLICT',
|
|
4
|
+
'IDENTITY_MISMATCH', 'STATE_CORRUPT', 'SOURCE_CHANGED', 'CAPACITY', 'CANCELLED',
|
|
5
|
+
'IO', 'RECOVERY_REQUIRED', 'BINARY_UNAVAILABLE',
|
|
6
|
+
];
|
|
7
|
+
/** Errors deliberately contain neither persisted values nor nested engine errors. */
|
|
8
|
+
export class NoSqlDbStorageRehearsalError extends Error {
|
|
9
|
+
constructor(code) {
|
|
10
|
+
super(`NoSQLDB storage rehearsal failed with code ${code}`);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.name = 'NoSqlDbStorageRehearsalError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const fail = (code = 'INVALID_REQUEST') => {
|
|
16
|
+
throw new NoSqlDbStorageRehearsalError(code);
|
|
17
|
+
};
|
|
18
|
+
const object = (value) => {
|
|
19
|
+
try {
|
|
20
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)
|
|
21
|
+
|| ![Object.prototype, null].includes(Object.getPrototypeOf(value)))
|
|
22
|
+
return false;
|
|
23
|
+
return Reflect.ownKeys(value).every((key) => {
|
|
24
|
+
const property = Object.getOwnPropertyDescriptor(value, key);
|
|
25
|
+
return typeof key === 'string' && property?.enumerable === true && Object.hasOwn(property, 'value');
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const digest = (value) => typeof value === 'string' && /^[0-9a-f]{64}$/.test(value);
|
|
33
|
+
const identifier = (value) => typeof value === 'string'
|
|
34
|
+
&& /^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/.test(value);
|
|
35
|
+
const canonicalPath = (value) => typeof value === 'string'
|
|
36
|
+
&& value.startsWith('/') && value !== '/' && plugins.buffer.Buffer.byteLength(value) <= 4095
|
|
37
|
+
&& !/[\p{Cc}\p{Cs}]/u.test(value) && !value.endsWith('/') && !value.includes('//')
|
|
38
|
+
&& value.split('/').every((part) => part !== '.' && part !== '..' && !part.startsWith('.smartdb-rehearsal-'));
|
|
39
|
+
const integer = (value, minimum, maximum) => typeof value === 'number' && Number.isSafeInteger(value) && value >= minimum && value <= maximum;
|
|
40
|
+
const exactKeys = (value, required, optional = []) => required.every((key) => Object.hasOwn(value, key)) && Object.keys(value).every((key) => required.includes(key) || optional.includes(key));
|
|
41
|
+
const sha256 = (domain, value) => plugins.crypto.createHash('sha256').update(domain).update(JSON.stringify(value)).digest('hex');
|
|
42
|
+
export const normalizeNoSqlDbStorageRehearsalOptions = (value) => {
|
|
43
|
+
try {
|
|
44
|
+
if (!object(value) || !exactKeys(value, [], ['binaryPath'])
|
|
45
|
+
|| (value.binaryPath !== undefined && (typeof value.binaryPath !== 'string' || value.binaryPath.length === 0)))
|
|
46
|
+
return fail();
|
|
47
|
+
return { binaryPath: value.binaryPath };
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return fail();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
export const normalizeNoSqlDbStorageRehearsalOperationOptions = (value) => {
|
|
54
|
+
try {
|
|
55
|
+
if (value === undefined)
|
|
56
|
+
return { timeoutMs: 3_600_000 };
|
|
57
|
+
if (!object(value) || !exactKeys(value, [], ['timeoutMs', 'signal'])
|
|
58
|
+
|| (value.timeoutMs !== undefined && !integer(value.timeoutMs, 1, 86_400_000))
|
|
59
|
+
|| (value.signal !== undefined && !(value.signal instanceof AbortSignal)))
|
|
60
|
+
return fail();
|
|
61
|
+
return { timeoutMs: value.timeoutMs ?? 3_600_000, signal: value.signal };
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return fail();
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
export const normalizeNoSqlDbStorageRehearsalInput = (value) => {
|
|
68
|
+
if (!object(value) || !exactKeys(value, ['sourceFolderPath', 'destinationFolderPath', 'operationId'], ['expectedSourceProviderRootId', 'limits'])
|
|
69
|
+
|| !canonicalPath(value.sourceFolderPath) || !canonicalPath(value.destinationFolderPath)
|
|
70
|
+
|| value.sourceFolderPath === value.destinationFolderPath
|
|
71
|
+
|| value.sourceFolderPath.startsWith(`${value.destinationFolderPath}/`)
|
|
72
|
+
|| value.destinationFolderPath.startsWith(`${value.sourceFolderPath}/`)
|
|
73
|
+
|| (value.expectedSourceProviderRootId !== undefined && !digest(value.expectedSourceProviderRootId))
|
|
74
|
+
|| !identifier(value.operationId))
|
|
75
|
+
return fail();
|
|
76
|
+
const limits = value.limits === undefined ? { maximumEntries: 100_000, maximumBytes: 1024 ** 4 } : value.limits;
|
|
77
|
+
if (!object(limits) || !exactKeys(limits, ['maximumEntries', 'maximumBytes'])
|
|
78
|
+
|| !integer(limits.maximumEntries, 1, 100_000) || !integer(limits.maximumBytes, 1, 1024 ** 4))
|
|
79
|
+
return fail();
|
|
80
|
+
return {
|
|
81
|
+
sourceFolderPath: value.sourceFolderPath,
|
|
82
|
+
destinationFolderPath: value.destinationFolderPath,
|
|
83
|
+
...(value.expectedSourceProviderRootId === undefined ? {} : { expectedSourceProviderRootId: value.expectedSourceProviderRootId }),
|
|
84
|
+
operationId: value.operationId,
|
|
85
|
+
limits: { maximumEntries: limits.maximumEntries, maximumBytes: limits.maximumBytes },
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
const preservationKeys = ['files', 'bytes', 'databases', 'collections', 'documents', 'indexes', 'indexAliases', 'users', 'principalIdentities', 'retiredDatabases', 'retiredCollections', 'retiredDocuments', 'retiredIndexes', 'retiredPrincipals', 'allocationReplays', 'resources', 'receipts', 'maximumFencingToken', 'publicationHolds', 'activeAllocations', 'retiredAllocations', 'sessions', 'retiringSessions', 'retryOutcomes', 'transactionOutcomes', 'obsoleteOutcomes', 'records', 'encodedRecordBytes'];
|
|
89
|
+
const receiptKeys = ['format', 'operationId', 'requestSha256', 'storageProfile', 'sourceFolderPath', 'destinationFolderPath', 'sourceProviderRootId', 'destinationProviderRootId', 'sourceStorageRootSha256', 'sourceSnapshotSha256', 'destinationDevice', 'destinationInode', 'groupId', 'timelineId', 'sourceLsn', 'destinationLsn', 'sourceRecordsSha256', 'preservedRecordsSha256', 'scramIterations', 'preservation', 'sourceUnchanged', 'contentsAndIndexesPreserved', 'namespacesPreserved', 'authenticationPreserved', 'historicalFencingPreserved', 'outcomesPreserved', 'filesystemBindingsVerified', 'productionAuthority', 'promotionSupported', 'receiptSha256'];
|
|
90
|
+
const unsigned = (value) => typeof value === 'string'
|
|
91
|
+
&& /^(0|[1-9][0-9]{0,19})$/.test(value) && BigInt(value) <= 0xffffffffffffffffn;
|
|
92
|
+
export const normalizeNoSqlDbStorageRehearsalReceipt = (value, input) => {
|
|
93
|
+
if (!object(value) || !exactKeys(value, receiptKeys) || !object(value.preservation)
|
|
94
|
+
|| !exactKeys(value.preservation, preservationKeys)
|
|
95
|
+
|| !preservationKeys.every((key) => key === 'maximumFencingToken'
|
|
96
|
+
? unsigned(value.preservation[key])
|
|
97
|
+
: integer(value.preservation[key], 0, Number.MAX_SAFE_INTEGER))
|
|
98
|
+
|| value.format !== 'smartdb.storage-rehearsal.receipt.v2' || value.storageProfile !== 'native-mvcc-authenticated-v1'
|
|
99
|
+
|| value.operationId !== input.operationId || value.sourceFolderPath !== input.sourceFolderPath
|
|
100
|
+
|| value.destinationFolderPath !== input.destinationFolderPath
|
|
101
|
+
|| (input.expectedSourceProviderRootId !== undefined && value.sourceProviderRootId !== input.expectedSourceProviderRootId)
|
|
102
|
+
|| !['sourceProviderRootId', 'destinationProviderRootId', 'sourceSnapshotSha256', 'sourceRecordsSha256', 'preservedRecordsSha256', 'receiptSha256'].every((key) => digest(value[key]))
|
|
103
|
+
|| value.sourceProviderRootId === value.destinationProviderRootId
|
|
104
|
+
|| value.sourceStorageRootSha256 !== plugins.crypto.createHash('sha256').update(`${input.sourceFolderPath}/.__rustdb_mvcc/data`).digest('hex')
|
|
105
|
+
|| value.requestSha256 !== sha256('smartdb.storage-rehearsal.request.v2\0', input)
|
|
106
|
+
|| !integer(value.scramIterations, 4096, 0xffff_ffff)
|
|
107
|
+
|| ![value.destinationDevice, value.destinationInode, value.sourceLsn, value.destinationLsn].every(unsigned)
|
|
108
|
+
|| BigInt(value.sourceLsn) < 1n || BigInt(value.sourceLsn) + 1n !== BigInt(value.destinationLsn)
|
|
109
|
+
|| !identifier(value.groupId) || !identifier(value.timelineId)
|
|
110
|
+
|| !['sourceUnchanged', 'contentsAndIndexesPreserved', 'namespacesPreserved', 'authenticationPreserved', 'historicalFencingPreserved', 'outcomesPreserved', 'filesystemBindingsVerified'].every((key) => value[key] === true)
|
|
111
|
+
|| value.productionAuthority !== false || value.promotionSupported !== false)
|
|
112
|
+
return fail('STATE_CORRUPT');
|
|
113
|
+
const preservation = Object.fromEntries(preservationKeys.map((key) => [key, value.preservation[key]]));
|
|
114
|
+
const normalized = Object.fromEntries(receiptKeys.map((key) => [key,
|
|
115
|
+
key === 'preservation' ? preservation : key === 'receiptSha256' ? '' : value[key]]));
|
|
116
|
+
if (sha256('smartdb.storage-rehearsal.receipt.v2\0', normalized) !== value.receiptSha256)
|
|
117
|
+
return fail('STATE_CORRUPT');
|
|
118
|
+
normalized.receiptSha256 = value.receiptSha256;
|
|
119
|
+
return normalized;
|
|
120
|
+
};
|
|
121
|
+
export const validateNoSqlDbStorageRehearsalStartup = (options) => {
|
|
122
|
+
if (options.storageRehearsalId === undefined)
|
|
123
|
+
return;
|
|
124
|
+
if (!identifier(options.storageRehearsalId) || options.storage !== 'file'
|
|
125
|
+
|| (options.fileStorageStartup !== undefined && options.fileStorageStartup !== 'current-format-only') || !canonicalPath(options.storagePath)
|
|
126
|
+
|| !canonicalPath(options.socketPath) || options.socketPath.startsWith(`${options.storagePath}/`)
|
|
127
|
+
|| options.auth?.enabled !== true || (options.auth.users?.length ?? 0) !== 0
|
|
128
|
+
|| !integer(options.auth.scramIterations, 4096, 0xffff_ffff))
|
|
129
|
+
return fail();
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZS1yZWhlYXJzYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy90c19ub3NxbGRiL3N0b3JhZ2UtcmVoZWFyc2FsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBR3hDLE1BQU0sQ0FBQyxNQUFNLGlDQUFpQyxHQUFHO0lBQy9DLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLHNCQUFzQjtJQUM3RSxtQkFBbUIsRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLFdBQVc7SUFDL0UsSUFBSSxFQUFFLG1CQUFtQixFQUFFLG9CQUFvQjtDQUN2QyxDQUFDO0FBR1gscUZBQXFGO0FBQ3JGLE1BQU0sT0FBTyw0QkFBNkIsU0FBUSxLQUFLO0lBQ3JELFlBQW1DLElBQXVDO1FBQ3hFLEtBQUssQ0FBQyw4Q0FBOEMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUQzQixTQUFJLEdBQUosSUFBSSxDQUFtQztRQUV4RSxJQUFJLENBQUMsSUFBSSxHQUFHLDhCQUE4QixDQUFDO0lBQzdDLENBQUM7Q0FDRjtBQThGRCxNQUFNLElBQUksR0FBRyxDQUFDLE9BQTBDLGlCQUFpQixFQUFTLEVBQUU7SUFDbEYsTUFBTSxJQUFJLDRCQUE0QixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQy9DLENBQUMsQ0FBQztBQUNGLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBYyxFQUFvQyxFQUFFO0lBQ2xFLElBQUksQ0FBQztRQUNILElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7ZUFDbEUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7WUFBRSxP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
|