@tinycloud/operations 0.3.0-beta.0 → 0.3.1-beta.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/dist/artifacts.cjs +210 -0
- package/dist/artifacts.cjs.map +1 -1
- package/dist/artifacts.js +210 -0
- package/dist/artifacts.js.map +1 -1
- package/dist/cli-runtime.cjs +211 -1
- package/dist/cli-runtime.cjs.map +1 -1
- package/dist/cli-runtime.js +211 -1
- package/dist/cli-runtime.js.map +1 -1
- package/dist/index.cjs +211 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +211 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/cli-runtime.js
CHANGED
|
@@ -2396,7 +2396,7 @@ function encOk(data) {
|
|
|
2396
2396
|
function encErr(error) {
|
|
2397
2397
|
return { ok: false, error };
|
|
2398
2398
|
}
|
|
2399
|
-
var import_decrypt_transport_response_error, import_decrypt_transport_response_error2, import_decrypt_transport_response_error3, ErrorCodes, defaultRetryPolicy, TelemetryEvents, REDACTED, SAFE_NUMBER_FIELDS, SAFE_BOOLEAN_FIELDS, DEBUG_FLAG, MAX_EVENTS, TinyCloudDebugLogger, tinyCloudDebugLogger, ServiceErrorSchema, GenericResultSchema, KVResponseHeadersSchema, GenericKVResponseSchema, KVListResponseSchema, KVListResultSchema, ServiceRequestEventSchema, ServiceResponseEventSchema, ServiceErrorEventSchema, ServiceRetryEventSchema, TelemetrySpanEventSchema, RetryPolicySchema, ServiceSessionSchema, BaseService, PrefixedKVService, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, KVAction, KVService, SQLMigrations, DatabaseHandle, SQLAction, DDL_TOKENS, MIGRATIONS_TABLE, MIGRATIONS_SCHEMA, MIGRATIONS_META_NAMESPACE, MIGRATIONS_META_ID, SQLService, DuckDbDatabaseHandle, DuckDbAction, DuckDbService, AsyncQueue, HooksService, VaultVersionConfig, CURRENT_VAULT_VERSION, VaultHeaders, DB_NAME, DB_VERSION, STORE_NAME, WRAP_KEY_ID, DataVaultService, HEX, URN_PREFIX, NETWORK_NAME_RE, PKH_EIP155_DID_RE, NetworkIdError, DEFAULT_ENCRYPTION_ALG, ENVELOPE_VERSION, DEFAULT_KEY_VERSION, DECRYPT_FACT_TYPE, DECRYPT_RESULT_TYPE, EncryptionService;
|
|
2399
|
+
var import_decrypt_transport_response_error, import_decrypt_transport_response_error2, import_decrypt_transport_response_error3, ErrorCodes, defaultRetryPolicy, TelemetryEvents, REDACTED, SAFE_NUMBER_FIELDS, SAFE_BOOLEAN_FIELDS, DEBUG_FLAG, MAX_EVENTS, TinyCloudDebugLogger, tinyCloudDebugLogger, ServiceErrorSchema, GenericResultSchema, KVResponseHeadersSchema, GenericKVResponseSchema, KVListResponseSchema, KVListResultSchema, ServiceRequestEventSchema, ServiceResponseEventSchema, ServiceErrorEventSchema, ServiceRetryEventSchema, TelemetrySpanEventSchema, RetryPolicySchema, ServiceSessionSchema, BaseService, PrefixedKVService, DEFAULT_SIGNED_READ_URL_EXPIRY_MS, KVAction, MAX_KV_BATCH_READ_ITEMS, KVService, SQLMigrations, DatabaseHandle, SQLAction, DDL_TOKENS, MIGRATIONS_TABLE, MIGRATIONS_SCHEMA, MIGRATIONS_META_NAMESPACE, MIGRATIONS_META_ID, SQLService, DuckDbDatabaseHandle, DuckDbAction, DuckDbService, AsyncQueue, HooksService, VaultVersionConfig, CURRENT_VAULT_VERSION, VaultHeaders, DB_NAME, DB_VERSION, STORE_NAME, WRAP_KEY_ID, DataVaultService, HEX, URN_PREFIX, NETWORK_NAME_RE, PKH_EIP155_DID_RE, NetworkIdError, DEFAULT_ENCRYPTION_ALG, ENVELOPE_VERSION, DEFAULT_KEY_VERSION, DECRYPT_FACT_TYPE, DECRYPT_RESULT_TYPE, EncryptionService;
|
|
2400
2400
|
var init_dist2 = __esm({
|
|
2401
2401
|
"../sdk-services/dist/index.js"() {
|
|
2402
2402
|
"use strict";
|
|
@@ -2913,6 +2913,20 @@ var init_dist2 = __esm({
|
|
|
2913
2913
|
const fullKey = this.getFullKey(key);
|
|
2914
2914
|
return this._kv.get(fullKey, { ...options, prefix: "" });
|
|
2915
2915
|
}
|
|
2916
|
+
async batchGet(keys, options) {
|
|
2917
|
+
const response = await this._kv.batchGet(
|
|
2918
|
+
keys.map((key) => this.getFullKey(key)),
|
|
2919
|
+
{ ...options, prefix: "" }
|
|
2920
|
+
);
|
|
2921
|
+
if (!response.ok) return response;
|
|
2922
|
+
return ok({
|
|
2923
|
+
...response.data,
|
|
2924
|
+
results: response.data.results.map((item, index) => ({
|
|
2925
|
+
...item,
|
|
2926
|
+
key: keys[index]
|
|
2927
|
+
}))
|
|
2928
|
+
});
|
|
2929
|
+
}
|
|
2916
2930
|
/**
|
|
2917
2931
|
* Store a value at a key.
|
|
2918
2932
|
*/
|
|
@@ -2957,6 +2971,20 @@ var init_dist2 = __esm({
|
|
|
2957
2971
|
const fullKey = this.getFullKey(key);
|
|
2958
2972
|
return this._kv.head(fullKey, { ...options, prefix: "" });
|
|
2959
2973
|
}
|
|
2974
|
+
async batchHead(keys, options) {
|
|
2975
|
+
const response = await this._kv.batchHead(
|
|
2976
|
+
keys.map((key) => this.getFullKey(key)),
|
|
2977
|
+
{ ...options, prefix: "" }
|
|
2978
|
+
);
|
|
2979
|
+
if (!response.ok) return response;
|
|
2980
|
+
return ok({
|
|
2981
|
+
...response.data,
|
|
2982
|
+
results: response.data.results.map((item, index) => ({
|
|
2983
|
+
...item,
|
|
2984
|
+
key: keys[index]
|
|
2985
|
+
}))
|
|
2986
|
+
});
|
|
2987
|
+
}
|
|
2960
2988
|
/**
|
|
2961
2989
|
* Create a short-lived signed URL for reading a KV object.
|
|
2962
2990
|
*/
|
|
@@ -2981,6 +3009,7 @@ var init_dist2 = __esm({
|
|
|
2981
3009
|
DELETE: "tinycloud.kv/del",
|
|
2982
3010
|
HEAD: "tinycloud.kv/metadata"
|
|
2983
3011
|
};
|
|
3012
|
+
MAX_KV_BATCH_READ_ITEMS = 100;
|
|
2984
3013
|
KVService = class extends BaseService {
|
|
2985
3014
|
/**
|
|
2986
3015
|
* Create a new KVService instance.
|
|
@@ -3209,6 +3238,173 @@ var init_dist2 = __esm({
|
|
|
3209
3238
|
get: (name) => headers.get(name)
|
|
3210
3239
|
};
|
|
3211
3240
|
}
|
|
3241
|
+
createBatchResponseHeaders(values) {
|
|
3242
|
+
const normalized = new Map(
|
|
3243
|
+
Object.entries(values).map(([name, value]) => [name.toLowerCase(), value])
|
|
3244
|
+
);
|
|
3245
|
+
return this.createResponseHeaders({
|
|
3246
|
+
get: (name) => normalized.get(name.toLowerCase()) ?? null
|
|
3247
|
+
});
|
|
3248
|
+
}
|
|
3249
|
+
parseBatchValue(dataBase64, headers, raw = false, binary = false) {
|
|
3250
|
+
const encoded = globalThis.atob(dataBase64);
|
|
3251
|
+
const bytes = Uint8Array.from(encoded, (character) => character.charCodeAt(0));
|
|
3252
|
+
if (binary) return bytes;
|
|
3253
|
+
const text = new TextDecoder().decode(bytes);
|
|
3254
|
+
if (raw) return text;
|
|
3255
|
+
const contentType = Object.entries(headers).find(
|
|
3256
|
+
([name]) => name.toLowerCase() === "content-type"
|
|
3257
|
+
)?.[1];
|
|
3258
|
+
return contentType?.includes("application/json") ? JSON.parse(text) : text;
|
|
3259
|
+
}
|
|
3260
|
+
normalizeBatchReadResponse(data, paths, requireData) {
|
|
3261
|
+
if (!data || typeof data !== "object") return void 0;
|
|
3262
|
+
const response = data;
|
|
3263
|
+
if (!Array.isArray(response.results) || response.results.length !== paths.length) {
|
|
3264
|
+
return void 0;
|
|
3265
|
+
}
|
|
3266
|
+
for (let index = 0; index < response.results.length; index++) {
|
|
3267
|
+
const item = response.results[index];
|
|
3268
|
+
if (!item || typeof item !== "object" || item.key !== paths[index] || typeof item.ok !== "boolean") {
|
|
3269
|
+
return void 0;
|
|
3270
|
+
}
|
|
3271
|
+
if (item.ok && (!item.headers || typeof item.headers !== "object" || Object.values(item.headers).some((value) => typeof value !== "string") || requireData && typeof item.dataBase64 !== "string")) {
|
|
3272
|
+
return void 0;
|
|
3273
|
+
}
|
|
3274
|
+
if (!item.ok && (!item.error || typeof item.error.code !== "string" || typeof item.error.message !== "string")) {
|
|
3275
|
+
return void 0;
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
return response;
|
|
3279
|
+
}
|
|
3280
|
+
async batchRead(keys, action, options) {
|
|
3281
|
+
if (!this.requireAuth()) return err(authRequiredError("kv"));
|
|
3282
|
+
if (keys.length === 0) return ok({ results: [], count: 0 });
|
|
3283
|
+
if (keys.length > MAX_KV_BATCH_READ_ITEMS) {
|
|
3284
|
+
return err(serviceError(
|
|
3285
|
+
ErrorCodes.INVALID_INPUT,
|
|
3286
|
+
`KV batch reads accept at most ${MAX_KV_BATCH_READ_ITEMS} keys`,
|
|
3287
|
+
"kv"
|
|
3288
|
+
));
|
|
3289
|
+
}
|
|
3290
|
+
if (keys.length === 1) {
|
|
3291
|
+
const key = keys[0];
|
|
3292
|
+
const result = action === KVAction.GET ? await this.get(key, options) : await this.head(key, options);
|
|
3293
|
+
return ok({
|
|
3294
|
+
results: [{ key, result }],
|
|
3295
|
+
count: 1
|
|
3296
|
+
});
|
|
3297
|
+
}
|
|
3298
|
+
if (!this.context.invokeAny) {
|
|
3299
|
+
return err(serviceError(
|
|
3300
|
+
ErrorCodes.INVALID_INPUT,
|
|
3301
|
+
"KV batch reads require SDK runtime support for multi-resource invocations",
|
|
3302
|
+
"kv"
|
|
3303
|
+
));
|
|
3304
|
+
}
|
|
3305
|
+
const getOptions = action === KVAction.GET ? options : void 0;
|
|
3306
|
+
if (getOptions?.maxResponseBytes !== void 0 && (!Number.isSafeInteger(getOptions.maxResponseBytes) || getOptions.maxResponseBytes <= 0)) {
|
|
3307
|
+
return err(serviceError(
|
|
3308
|
+
ErrorCodes.INVALID_INPUT,
|
|
3309
|
+
"KV maxResponseBytes must be a positive safe integer",
|
|
3310
|
+
"kv"
|
|
3311
|
+
));
|
|
3312
|
+
}
|
|
3313
|
+
const paths = keys.map((key) => this.getFullPath(key, options?.prefix));
|
|
3314
|
+
if (new Set(paths).size !== paths.length) {
|
|
3315
|
+
return err(serviceError(
|
|
3316
|
+
ErrorCodes.INVALID_INPUT,
|
|
3317
|
+
"KV batch read received duplicate keys after prefix resolution",
|
|
3318
|
+
"kv"
|
|
3319
|
+
));
|
|
3320
|
+
}
|
|
3321
|
+
try {
|
|
3322
|
+
const session = this.context.session;
|
|
3323
|
+
const invocationHeaders = this.context.invokeAny(
|
|
3324
|
+
session,
|
|
3325
|
+
paths.map((path) => ({
|
|
3326
|
+
spaceId: session.spaceId,
|
|
3327
|
+
service: "kv",
|
|
3328
|
+
path,
|
|
3329
|
+
action
|
|
3330
|
+
}))
|
|
3331
|
+
);
|
|
3332
|
+
const limitHeaders = {};
|
|
3333
|
+
if (getOptions?.maxResponseBytes !== void 0) {
|
|
3334
|
+
limitHeaders["x-tinycloud-max-response-bytes"] = String(
|
|
3335
|
+
getOptions.maxResponseBytes
|
|
3336
|
+
);
|
|
3337
|
+
}
|
|
3338
|
+
const headers = Array.isArray(invocationHeaders) ? [...invocationHeaders, ...Object.entries(limitHeaders)] : { ...invocationHeaders, ...limitHeaders };
|
|
3339
|
+
const response = await this.context.fetch(`${this.host}/invoke`, {
|
|
3340
|
+
method: "POST",
|
|
3341
|
+
headers,
|
|
3342
|
+
signal: this.combineSignals(options?.signal)
|
|
3343
|
+
});
|
|
3344
|
+
if (!response.ok) {
|
|
3345
|
+
const errorText = await response.text();
|
|
3346
|
+
if (response.status === 401 || response.status === 403) {
|
|
3347
|
+
const { resource, action: requiredAction } = parseAuthError(errorText);
|
|
3348
|
+
return err(authUnauthorizedError("kv", errorText, {
|
|
3349
|
+
status: response.status,
|
|
3350
|
+
...requiredAction && { requiredAction },
|
|
3351
|
+
...resource && { resource }
|
|
3352
|
+
}));
|
|
3353
|
+
}
|
|
3354
|
+
if (response.status === 413) {
|
|
3355
|
+
return err(serviceError(
|
|
3356
|
+
ErrorCodes.KV_RESPONSE_TOO_LARGE,
|
|
3357
|
+
"A KV batch value exceeds the requested response limit",
|
|
3358
|
+
"kv",
|
|
3359
|
+
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3360
|
+
));
|
|
3361
|
+
}
|
|
3362
|
+
return err(serviceError(
|
|
3363
|
+
ErrorCodes.NETWORK_ERROR,
|
|
3364
|
+
`Failed to batch read ${keys.length} key(s): ${response.status} - ${errorText}`,
|
|
3365
|
+
"kv",
|
|
3366
|
+
{ meta: { status: response.status, statusText: response.statusText } }
|
|
3367
|
+
));
|
|
3368
|
+
}
|
|
3369
|
+
const payload = this.normalizeBatchReadResponse(
|
|
3370
|
+
await response.json(),
|
|
3371
|
+
paths,
|
|
3372
|
+
action === KVAction.GET
|
|
3373
|
+
);
|
|
3374
|
+
if (!payload) {
|
|
3375
|
+
return err(serviceError(
|
|
3376
|
+
ErrorCodes.NETWORK_ERROR,
|
|
3377
|
+
"KV batch read response did not match the requested keys",
|
|
3378
|
+
"kv"
|
|
3379
|
+
));
|
|
3380
|
+
}
|
|
3381
|
+
const results = payload.results.map((item, index) => {
|
|
3382
|
+
if (!item.ok) {
|
|
3383
|
+
return {
|
|
3384
|
+
key: keys[index],
|
|
3385
|
+
result: err(serviceError(item.error.code, item.error.message, "kv"))
|
|
3386
|
+
};
|
|
3387
|
+
}
|
|
3388
|
+
const headers2 = item.headers;
|
|
3389
|
+
const data = action === KVAction.HEAD ? void 0 : this.parseBatchValue(
|
|
3390
|
+
item.dataBase64,
|
|
3391
|
+
headers2,
|
|
3392
|
+
getOptions?.raw,
|
|
3393
|
+
getOptions?.binary
|
|
3394
|
+
);
|
|
3395
|
+
return {
|
|
3396
|
+
key: keys[index],
|
|
3397
|
+
result: ok({
|
|
3398
|
+
data,
|
|
3399
|
+
headers: this.createBatchResponseHeaders(headers2)
|
|
3400
|
+
})
|
|
3401
|
+
};
|
|
3402
|
+
});
|
|
3403
|
+
return ok({ results, count: results.length });
|
|
3404
|
+
} catch (error) {
|
|
3405
|
+
return err(wrapError("kv", error));
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3212
3408
|
/**
|
|
3213
3409
|
* Parse response body based on content type.
|
|
3214
3410
|
*
|
|
@@ -3355,6 +3551,13 @@ var init_dist2 = __esm({
|
|
|
3355
3551
|
}
|
|
3356
3552
|
});
|
|
3357
3553
|
}
|
|
3554
|
+
async batchGet(keys, options) {
|
|
3555
|
+
return this.withTelemetry(
|
|
3556
|
+
"batchGet",
|
|
3557
|
+
String(keys.length),
|
|
3558
|
+
() => this.batchRead(keys, KVAction.GET, options)
|
|
3559
|
+
);
|
|
3560
|
+
}
|
|
3358
3561
|
/**
|
|
3359
3562
|
* Store a value at a key.
|
|
3360
3563
|
*/
|
|
@@ -3714,6 +3917,13 @@ var init_dist2 = __esm({
|
|
|
3714
3917
|
}
|
|
3715
3918
|
});
|
|
3716
3919
|
}
|
|
3920
|
+
async batchHead(keys, options) {
|
|
3921
|
+
return this.withTelemetry(
|
|
3922
|
+
"batchHead",
|
|
3923
|
+
String(keys.length),
|
|
3924
|
+
() => this.batchRead(keys, KVAction.HEAD, options)
|
|
3925
|
+
);
|
|
3926
|
+
}
|
|
3717
3927
|
/**
|
|
3718
3928
|
* Create a short-lived signed URL for reading a KV object.
|
|
3719
3929
|
*/
|