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