@lossless.org/nosqldb 10.11.0 → 11.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 +117 -0
- package/dist_rust/rustdb_linux_amd64 +0 -0
- package/dist_rust/rustdb_linux_amd64.tsrust-build.json +5 -5
- package/dist_rust/rustdb_linux_amd64_musl +0 -0
- package/dist_rust/rustdb_linux_amd64_musl.tsrust-build.json +5 -5
- package/dist_rust/rustdb_linux_arm64 +0 -0
- package/dist_rust/rustdb_linux_arm64.tsrust-build.json +5 -5
- package/dist_rust/rustdb_linux_arm64_musl +0 -0
- package/dist_rust/rustdb_linux_arm64_musl.tsrust-build.json +5 -5
- package/dist_rust/rustdb_macos_amd64 +0 -0
- package/dist_rust/rustdb_macos_amd64.tsrust-build.json +5 -5
- package/dist_rust/rustdb_macos_arm64 +0 -0
- package/dist_rust/rustdb_macos_arm64.tsrust-build.json +5 -5
- package/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/ts_local/classes.localnosqldb.d.ts +15 -4
- package/dist_ts/ts_local/classes.localnosqldb.js +31 -11
- package/dist_ts/ts_nosqldb/index.d.ts +3 -3
- package/dist_ts/ts_nosqldb/index.js +5 -4
- package/dist_ts/ts_nosqldb/rust-db-bridge.d.ts +125 -2
- package/dist_ts/ts_nosqldb/rust-db-bridge.js +261 -46
- package/dist_ts/ts_nosqldb/server/classes.nosqldbserver.d.ts +69 -3
- package/dist_ts/ts_nosqldb/server/classes.nosqldbserver.js +91 -12
- package/dist_ts/ts_nosqldb/server/index.d.ts +2 -2
- package/dist_ts/ts_nosqldb/server/index.js +2 -2
- package/dist_ts/ts_nosqldb/stopped-storage.d.ts +9 -1
- package/dist_ts/ts_nosqldb/stopped-storage.js +1 -1
- package/dist_ts/ts_nosqldb/storage-rehearsal.js +1 -1
- package/dist_ts/ts_nosqldb/storage-root-alignment.js +7 -3
- package/dist_ts/ts_nosqldb/storage-root-relocation.js +2 -2
- package/dist_ts_debugserver/bundled.js +6 -2
- package/package.json +28 -15
- package/readme.md +470 -730
- package/third-party-notices.md +40 -8
- package/third_party_licenses/inventory.json +6 -6
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/index.ts +85 -0
- package/ts/ts_local/classes.localnosqldb.ts +631 -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/committed-writes.ts +38 -0
- package/ts/ts_nosqldb/file-storage-options.ts +33 -0
- package/ts/ts_nosqldb/file-storage-startup.ts +10 -0
- package/ts/ts_nosqldb/index.ts +132 -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 +1309 -0
- package/ts/ts_nosqldb/server/classes.nosqldbserver.ts +874 -0
- package/ts/ts_nosqldb/server/index.ts +4 -0
- package/ts/ts_nosqldb/service-types.ts +499 -0
- package/ts/ts_nosqldb/stopped-storage.ts +116 -0
- package/ts/ts_nosqldb/storage-rehearsal.ts +215 -0
- package/ts/ts_nosqldb/storage-root-alignment.ts +180 -0
- package/ts/ts_nosqldb/storage-root-relocation.ts +279 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import type {
|
|
3
|
+
ILocalNoSqlDbOfflinePhysicalNamespaceInspection,
|
|
4
|
+
ILocalNoSqlDbOfflineStringValueInspection,
|
|
5
|
+
INoSqlDbManagementOperationOptions,
|
|
6
|
+
} from './service-types.js';
|
|
7
|
+
|
|
8
|
+
export const localNoSqlDbOfflineInspectionBounds = {
|
|
9
|
+
maximumFolderPathBytes: 4095,
|
|
10
|
+
maximumNamespaceComponentBytes: 255,
|
|
11
|
+
maximumFieldNameBytes: 255,
|
|
12
|
+
maximumMatchValueBytes: 1024 * 1024,
|
|
13
|
+
maximumRequestBytes: 2 * 1024 * 1024,
|
|
14
|
+
maximumTimeoutMs: 2_147_483_647,
|
|
15
|
+
limits: {
|
|
16
|
+
maximumEntries: { minimum: 1, maximum: 100_000 },
|
|
17
|
+
maximumTotalFileBytes: { minimum: 1, maximum: 1024 ** 4 },
|
|
18
|
+
maximumRecords: { minimum: 1, maximum: 1_000_000_000 },
|
|
19
|
+
maximumRecordBytes: { minimum: 5, maximum: 16 * 1024 * 1024 },
|
|
20
|
+
maximumResultBytes: { minimum: 1, maximum: 16 * 1024 * 1024 },
|
|
21
|
+
},
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
export const localNoSqlDbOfflinePhysicalNamespaceInspectionBounds = {
|
|
25
|
+
maximumFolderPathBytes: 4095,
|
|
26
|
+
maximumRequestBytes: 2 * 1024 * 1024,
|
|
27
|
+
limits: {
|
|
28
|
+
maximumDatabases: { minimum: 1, maximum: 1_000_000 },
|
|
29
|
+
maximumCollections: { minimum: 1, maximum: 1_000_000 },
|
|
30
|
+
maximumIndexes: { minimum: 1, maximum: 1_000_000 },
|
|
31
|
+
maximumEntries: { minimum: 1, maximum: 100_000 },
|
|
32
|
+
maximumTotalFileBytes: { minimum: 1, maximum: 1024 * 1024 * 1024 * 1024 },
|
|
33
|
+
maximumRecordsPerCollection: { minimum: 1, maximum: 1_000_000_000 },
|
|
34
|
+
maximumRecordBytes: { minimum: 5, maximum: 16 * 1024 * 1024 },
|
|
35
|
+
maximumResultBytes: { minimum: 32, maximum: 16 * 1024 * 1024 },
|
|
36
|
+
},
|
|
37
|
+
} as const;
|
|
38
|
+
|
|
39
|
+
const inputKeys = new Set([
|
|
40
|
+
'folderPath',
|
|
41
|
+
'databaseName',
|
|
42
|
+
'collectionName',
|
|
43
|
+
'match',
|
|
44
|
+
'valueField',
|
|
45
|
+
'limits',
|
|
46
|
+
]);
|
|
47
|
+
const matchKeys = new Set(['field', 'value']);
|
|
48
|
+
const limitKeys = [
|
|
49
|
+
'maximumEntries',
|
|
50
|
+
'maximumTotalFileBytes',
|
|
51
|
+
'maximumRecords',
|
|
52
|
+
'maximumRecordBytes',
|
|
53
|
+
'maximumResultBytes',
|
|
54
|
+
] as const;
|
|
55
|
+
const limitKeySet = new Set<string>(limitKeys);
|
|
56
|
+
const requestStructuralBytes = plugins.buffer.Buffer.byteLength(
|
|
57
|
+
'{"folderPath":,"databaseName":,"collectionName":,"match":{"field":,"value":},"valueField":,"limits":{"maximumEntries":,"maximumTotalFileBytes":,"maximumRecords":,"maximumRecordBytes":,"maximumResultBytes":}}',
|
|
58
|
+
'utf8',
|
|
59
|
+
);
|
|
60
|
+
const requestEnvelopeBytes = plugins.buffer.Buffer.byteLength(
|
|
61
|
+
'{"id":"req_9007199254740991","method":"inspectOfflineStringValue","params":}',
|
|
62
|
+
'utf8',
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const physicalNamespaceInputKeys = new Set(['folderPath', 'limits']);
|
|
66
|
+
const physicalNamespaceLimitKeys = [
|
|
67
|
+
'maximumDatabases',
|
|
68
|
+
'maximumCollections',
|
|
69
|
+
'maximumIndexes',
|
|
70
|
+
'maximumEntries',
|
|
71
|
+
'maximumTotalFileBytes',
|
|
72
|
+
'maximumRecordsPerCollection',
|
|
73
|
+
'maximumRecordBytes',
|
|
74
|
+
'maximumResultBytes',
|
|
75
|
+
] as const;
|
|
76
|
+
const physicalNamespaceLimitKeySet = new Set<string>(physicalNamespaceLimitKeys);
|
|
77
|
+
|
|
78
|
+
const isRecord = (valueArg: unknown): valueArg is Record<string, unknown> =>
|
|
79
|
+
typeof valueArg === 'object' && valueArg !== null && !Array.isArray(valueArg);
|
|
80
|
+
|
|
81
|
+
const requirePhysicalNamespacePlainObject = (
|
|
82
|
+
valueArg: unknown,
|
|
83
|
+
allowedKeysArg: Set<string>,
|
|
84
|
+
labelArg: string,
|
|
85
|
+
): Record<string, unknown> => {
|
|
86
|
+
if (!isRecord(valueArg)) {
|
|
87
|
+
throw new TypeError(
|
|
88
|
+
`LocalNoSqlDb offline physical namespace inspection ${labelArg} must be a plain object`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
for (const key in valueArg) {
|
|
92
|
+
if (!allowedKeysArg.has(key)) {
|
|
93
|
+
throw new TypeError(
|
|
94
|
+
`LocalNoSqlDb offline physical namespace inspection ${labelArg} contains unknown key '${key}'`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (Object.getPrototypeOf(valueArg) !== Object.prototype) {
|
|
99
|
+
throw new TypeError(
|
|
100
|
+
`LocalNoSqlDb offline physical namespace inspection ${labelArg} must be a plain object`,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
for (const key of allowedKeysArg) {
|
|
104
|
+
if (!Object.prototype.propertyIsEnumerable.call(valueArg, key)) {
|
|
105
|
+
throw new TypeError(
|
|
106
|
+
`LocalNoSqlDb offline physical namespace inspection ${labelArg} must contain own enumerable key '${key}'`,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return valueArg;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const rejectUnknownEnumerableKeys = (
|
|
114
|
+
valueArg: object,
|
|
115
|
+
allowedKeysArg: Set<string>,
|
|
116
|
+
labelArg: string,
|
|
117
|
+
): void => {
|
|
118
|
+
for (const key in valueArg) {
|
|
119
|
+
if (!allowedKeysArg.has(key)) {
|
|
120
|
+
throw new TypeError(`LocalNoSqlDb offline inspection ${labelArg} contains unknown key '${key}'`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const encodedJsonStringBytes = (valueArg: string): number => {
|
|
126
|
+
let bytes = 2;
|
|
127
|
+
for (let index = 0; index < valueArg.length; index++) {
|
|
128
|
+
const code = valueArg.charCodeAt(index);
|
|
129
|
+
if (
|
|
130
|
+
code === 0x22
|
|
131
|
+
|| code === 0x5c
|
|
132
|
+
|| code === 0x08
|
|
133
|
+
|| code === 0x09
|
|
134
|
+
|| code === 0x0a
|
|
135
|
+
|| code === 0x0c
|
|
136
|
+
|| code === 0x0d
|
|
137
|
+
) {
|
|
138
|
+
bytes += 2;
|
|
139
|
+
} else if (code <= 0x1f) {
|
|
140
|
+
bytes += 6;
|
|
141
|
+
} else if (code <= 0x7f) {
|
|
142
|
+
bytes += 1;
|
|
143
|
+
} else if (code <= 0x7ff) {
|
|
144
|
+
bytes += 2;
|
|
145
|
+
} else if (code >= 0xd800 && code <= 0xdbff) {
|
|
146
|
+
const next = valueArg.charCodeAt(index + 1);
|
|
147
|
+
if (next >= 0xdc00 && next <= 0xdfff) {
|
|
148
|
+
bytes += 4;
|
|
149
|
+
index++;
|
|
150
|
+
} else {
|
|
151
|
+
bytes += 6;
|
|
152
|
+
}
|
|
153
|
+
} else if (code >= 0xdc00 && code <= 0xdfff) {
|
|
154
|
+
bytes += 6;
|
|
155
|
+
} else {
|
|
156
|
+
bytes += 3;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return bytes;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const validateString = (
|
|
163
|
+
valueArg: unknown,
|
|
164
|
+
labelArg: string,
|
|
165
|
+
minimumBytesArg: number,
|
|
166
|
+
maximumBytesArg: number,
|
|
167
|
+
rejectControlsArg: boolean,
|
|
168
|
+
): void => {
|
|
169
|
+
if (typeof valueArg !== 'string') {
|
|
170
|
+
throw new TypeError(`LocalNoSqlDb offline inspection ${labelArg} must be a string`);
|
|
171
|
+
}
|
|
172
|
+
const bytes = plugins.buffer.Buffer.byteLength(valueArg, 'utf8');
|
|
173
|
+
if (bytes < minimumBytesArg || bytes > maximumBytesArg) {
|
|
174
|
+
throw new RangeError(
|
|
175
|
+
`LocalNoSqlDb offline inspection ${labelArg} must be between ${minimumBytesArg} and ${maximumBytesArg} UTF-8 bytes`,
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
if (rejectControlsArg) {
|
|
179
|
+
for (const character of valueArg) {
|
|
180
|
+
if (/\p{Cc}/u.test(character)) {
|
|
181
|
+
throw new TypeError(
|
|
182
|
+
`LocalNoSqlDb offline inspection ${labelArg} must not contain control characters`,
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
export const normalizeLocalNoSqlDbOfflineInspectionInput = (
|
|
190
|
+
inputArg: ILocalNoSqlDbOfflineStringValueInspection,
|
|
191
|
+
): ILocalNoSqlDbOfflineStringValueInspection => {
|
|
192
|
+
if (!isRecord(inputArg as unknown)) {
|
|
193
|
+
throw new TypeError('LocalNoSqlDb offline inspection input must be an object');
|
|
194
|
+
}
|
|
195
|
+
rejectUnknownEnumerableKeys(inputArg, inputKeys, 'input');
|
|
196
|
+
const inputRecord = inputArg as unknown as Record<string, unknown>;
|
|
197
|
+
const match = inputRecord.match;
|
|
198
|
+
if (!isRecord(match)) {
|
|
199
|
+
throw new TypeError('LocalNoSqlDb offline inspection match must be an object');
|
|
200
|
+
}
|
|
201
|
+
rejectUnknownEnumerableKeys(match, matchKeys, 'match');
|
|
202
|
+
const limits = inputRecord.limits;
|
|
203
|
+
if (!isRecord(limits)) {
|
|
204
|
+
throw new TypeError('LocalNoSqlDb offline inspection limits must be an object');
|
|
205
|
+
}
|
|
206
|
+
rejectUnknownEnumerableKeys(limits, limitKeySet, 'limits');
|
|
207
|
+
|
|
208
|
+
const normalized = {
|
|
209
|
+
folderPath: inputRecord.folderPath,
|
|
210
|
+
databaseName: inputRecord.databaseName,
|
|
211
|
+
collectionName: inputRecord.collectionName,
|
|
212
|
+
match: {
|
|
213
|
+
field: match.field,
|
|
214
|
+
value: match.value,
|
|
215
|
+
},
|
|
216
|
+
valueField: inputRecord.valueField,
|
|
217
|
+
limits: {
|
|
218
|
+
maximumEntries: limits.maximumEntries,
|
|
219
|
+
maximumTotalFileBytes: limits.maximumTotalFileBytes,
|
|
220
|
+
maximumRecords: limits.maximumRecords,
|
|
221
|
+
maximumRecordBytes: limits.maximumRecordBytes,
|
|
222
|
+
maximumResultBytes: limits.maximumResultBytes,
|
|
223
|
+
},
|
|
224
|
+
} as unknown as ILocalNoSqlDbOfflineStringValueInspection;
|
|
225
|
+
|
|
226
|
+
const bounds = localNoSqlDbOfflineInspectionBounds;
|
|
227
|
+
validateString(normalized.folderPath, 'folderPath', 1, bounds.maximumFolderPathBytes, true);
|
|
228
|
+
for (const [label, value] of [
|
|
229
|
+
['databaseName', normalized.databaseName],
|
|
230
|
+
['collectionName', normalized.collectionName],
|
|
231
|
+
] as const) {
|
|
232
|
+
validateString(value, label, 1, bounds.maximumNamespaceComponentBytes, true);
|
|
233
|
+
if (value === '.' || value === '..' || value.includes('/') || value.includes('\\')) {
|
|
234
|
+
throw new TypeError(
|
|
235
|
+
`LocalNoSqlDb offline inspection ${label} must be one canonical path component`,
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
validateString(normalized.match.field, 'match.field', 1, bounds.maximumFieldNameBytes, true);
|
|
240
|
+
validateString(normalized.valueField, 'valueField', 1, bounds.maximumFieldNameBytes, true);
|
|
241
|
+
validateString(
|
|
242
|
+
normalized.match.value,
|
|
243
|
+
'match.value',
|
|
244
|
+
0,
|
|
245
|
+
bounds.maximumMatchValueBytes,
|
|
246
|
+
false,
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
for (const key of limitKeys) {
|
|
250
|
+
const value = normalized.limits[key];
|
|
251
|
+
const range = bounds.limits[key as keyof typeof bounds.limits];
|
|
252
|
+
if (!Number.isSafeInteger(value) || value < range.minimum || value > range.maximum) {
|
|
253
|
+
throw new RangeError(
|
|
254
|
+
`LocalNoSqlDb offline inspection limits.${key} must be a safe integer between ${range.minimum} and ${range.maximum}`,
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (plugins.buffer.Buffer.byteLength(normalized.match.value, 'utf8') > normalized.limits.maximumRecordBytes) {
|
|
259
|
+
throw new RangeError(
|
|
260
|
+
'LocalNoSqlDb offline inspection match.value must not exceed limits.maximumRecordBytes',
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
let requestBytes = 32 // Reserve the optional native deadline field.
|
|
265
|
+
+ requestEnvelopeBytes
|
|
266
|
+
+ requestStructuralBytes
|
|
267
|
+
+ encodedJsonStringBytes(normalized.folderPath)
|
|
268
|
+
+ encodedJsonStringBytes(normalized.databaseName)
|
|
269
|
+
+ encodedJsonStringBytes(normalized.collectionName)
|
|
270
|
+
+ encodedJsonStringBytes(normalized.match.field)
|
|
271
|
+
+ encodedJsonStringBytes(normalized.match.value)
|
|
272
|
+
+ encodedJsonStringBytes(normalized.valueField);
|
|
273
|
+
for (const key of limitKeys) {
|
|
274
|
+
requestBytes += String(normalized.limits[key]).length;
|
|
275
|
+
}
|
|
276
|
+
if (requestBytes > bounds.maximumRequestBytes) {
|
|
277
|
+
throw new RangeError(
|
|
278
|
+
`LocalNoSqlDb offline inspection request exceeds the ${bounds.maximumRequestBytes}-byte serialized limit`,
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
return normalized;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
export const normalizeLocalNoSqlDbOfflinePhysicalNamespaceInspectionInput = (
|
|
285
|
+
inputArg: ILocalNoSqlDbOfflinePhysicalNamespaceInspection,
|
|
286
|
+
): ILocalNoSqlDbOfflinePhysicalNamespaceInspection => {
|
|
287
|
+
const inputRecord = requirePhysicalNamespacePlainObject(
|
|
288
|
+
inputArg,
|
|
289
|
+
physicalNamespaceInputKeys,
|
|
290
|
+
'input',
|
|
291
|
+
);
|
|
292
|
+
const limits = requirePhysicalNamespacePlainObject(
|
|
293
|
+
inputRecord.limits,
|
|
294
|
+
physicalNamespaceLimitKeySet,
|
|
295
|
+
'limits',
|
|
296
|
+
);
|
|
297
|
+
const normalized: ILocalNoSqlDbOfflinePhysicalNamespaceInspection = {
|
|
298
|
+
folderPath: inputRecord.folderPath as string,
|
|
299
|
+
limits: {
|
|
300
|
+
maximumDatabases: limits.maximumDatabases as number,
|
|
301
|
+
maximumCollections: limits.maximumCollections as number,
|
|
302
|
+
maximumIndexes: limits.maximumIndexes as number,
|
|
303
|
+
maximumEntries: limits.maximumEntries as number,
|
|
304
|
+
maximumTotalFileBytes: limits.maximumTotalFileBytes as number,
|
|
305
|
+
maximumRecordsPerCollection: limits.maximumRecordsPerCollection as number,
|
|
306
|
+
maximumRecordBytes: limits.maximumRecordBytes as number,
|
|
307
|
+
maximumResultBytes: limits.maximumResultBytes as number,
|
|
308
|
+
},
|
|
309
|
+
};
|
|
310
|
+
const bounds = localNoSqlDbOfflinePhysicalNamespaceInspectionBounds;
|
|
311
|
+
if (typeof normalized.folderPath !== 'string') {
|
|
312
|
+
throw new TypeError(
|
|
313
|
+
'LocalNoSqlDb offline physical namespace inspection folderPath must be a string',
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
const folderPathBytes = plugins.buffer.Buffer.byteLength(normalized.folderPath, 'utf8');
|
|
317
|
+
if (folderPathBytes < 1 || folderPathBytes > bounds.maximumFolderPathBytes) {
|
|
318
|
+
throw new RangeError(
|
|
319
|
+
`LocalNoSqlDb offline physical namespace inspection folderPath must be between 1 and ${bounds.maximumFolderPathBytes} UTF-8 bytes`,
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
for (const character of normalized.folderPath) {
|
|
323
|
+
if (/\p{Cc}/u.test(character)) {
|
|
324
|
+
throw new TypeError(
|
|
325
|
+
'LocalNoSqlDb offline physical namespace inspection folderPath must not contain control characters',
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
for (const key of physicalNamespaceLimitKeys) {
|
|
331
|
+
const value = normalized.limits[key];
|
|
332
|
+
const range = bounds.limits[key];
|
|
333
|
+
if (!Number.isSafeInteger(value) || value < range.minimum || value > range.maximum) {
|
|
334
|
+
throw new RangeError(
|
|
335
|
+
`LocalNoSqlDb offline physical namespace inspection limits.${key} must be a safe integer between ${range.minimum} and ${range.maximum}`,
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const requestBytes = plugins.buffer.Buffer.byteLength(JSON.stringify({
|
|
341
|
+
id: 'req_9007199254740991',
|
|
342
|
+
method: 'inspectOfflinePhysicalNamespaces',
|
|
343
|
+
params: {
|
|
344
|
+
folderPath: normalized.folderPath,
|
|
345
|
+
...normalized.limits,
|
|
346
|
+
},
|
|
347
|
+
}), 'utf8');
|
|
348
|
+
if (requestBytes > bounds.maximumRequestBytes) {
|
|
349
|
+
throw new RangeError(
|
|
350
|
+
`LocalNoSqlDb offline physical namespace inspection request exceeds the ${bounds.maximumRequestBytes}-byte serialized limit`,
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
return normalized;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
export const validateNoSqlDbManagementOperationOptions = (
|
|
357
|
+
optionsArg?: INoSqlDbManagementOperationOptions,
|
|
358
|
+
): void => {
|
|
359
|
+
if (optionsArg === undefined) return;
|
|
360
|
+
if (!isRecord(optionsArg as unknown)) {
|
|
361
|
+
throw new TypeError('NoSQLDB management operation options must be an object');
|
|
362
|
+
}
|
|
363
|
+
if (
|
|
364
|
+
optionsArg.timeoutMs !== undefined
|
|
365
|
+
&& (
|
|
366
|
+
!Number.isSafeInteger(optionsArg.timeoutMs)
|
|
367
|
+
|| optionsArg.timeoutMs <= 0
|
|
368
|
+
|| optionsArg.timeoutMs > localNoSqlDbOfflineInspectionBounds.maximumTimeoutMs
|
|
369
|
+
)
|
|
370
|
+
) {
|
|
371
|
+
throw new RangeError(
|
|
372
|
+
`NoSQLDB management operation timeoutMs must be an integer between 1 and ${localNoSqlDbOfflineInspectionBounds.maximumTimeoutMs}`,
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// node native scope
|
|
2
|
+
import * as buffer from 'node:buffer';
|
|
3
|
+
import * as crypto from 'node:crypto';
|
|
4
|
+
import * as fs from 'node:fs/promises';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
|
|
7
|
+
export { buffer, crypto, fs, path };
|
|
8
|
+
|
|
9
|
+
// @push.rocks scope
|
|
10
|
+
import * as smartrust from '@push.rocks/smartrust';
|
|
11
|
+
|
|
12
|
+
export { smartrust };
|