@tinycloud/cli 0.8.1-beta.0 → 0.8.2-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/index.js +211 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -12067,7 +12067,7 @@ function encOk(data) {
|
|
|
12067
12067
|
function encErr(error) {
|
|
12068
12068
|
return { ok: false, error };
|
|
12069
12069
|
}
|
|
12070
|
-
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, SECRET_NAME_RE, SECRET_PREFIX, SCOPED_SECRET_PREFIX, RESERVED_SECRET_SCOPES, 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;
|
|
12070
|
+
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, SECRET_NAME_RE, SECRET_PREFIX, SCOPED_SECRET_PREFIX, RESERVED_SECRET_SCOPES, 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;
|
|
12071
12071
|
var init_dist2 = __esm({
|
|
12072
12072
|
"../sdk-services/dist/index.js"() {
|
|
12073
12073
|
"use strict";
|
|
@@ -12585,6 +12585,20 @@ var init_dist2 = __esm({
|
|
|
12585
12585
|
const fullKey = this.getFullKey(key);
|
|
12586
12586
|
return this._kv.get(fullKey, { ...options, prefix: "" });
|
|
12587
12587
|
}
|
|
12588
|
+
async batchGet(keys, options) {
|
|
12589
|
+
const response = await this._kv.batchGet(
|
|
12590
|
+
keys.map((key) => this.getFullKey(key)),
|
|
12591
|
+
{ ...options, prefix: "" }
|
|
12592
|
+
);
|
|
12593
|
+
if (!response.ok) return response;
|
|
12594
|
+
return ok({
|
|
12595
|
+
...response.data,
|
|
12596
|
+
results: response.data.results.map((item, index) => ({
|
|
12597
|
+
...item,
|
|
12598
|
+
key: keys[index]
|
|
12599
|
+
}))
|
|
12600
|
+
});
|
|
12601
|
+
}
|
|
12588
12602
|
/**
|
|
12589
12603
|
* Store a value at a key.
|
|
12590
12604
|
*/
|
|
@@ -12629,6 +12643,20 @@ var init_dist2 = __esm({
|
|
|
12629
12643
|
const fullKey = this.getFullKey(key);
|
|
12630
12644
|
return this._kv.head(fullKey, { ...options, prefix: "" });
|
|
12631
12645
|
}
|
|
12646
|
+
async batchHead(keys, options) {
|
|
12647
|
+
const response = await this._kv.batchHead(
|
|
12648
|
+
keys.map((key) => this.getFullKey(key)),
|
|
12649
|
+
{ ...options, prefix: "" }
|
|
12650
|
+
);
|
|
12651
|
+
if (!response.ok) return response;
|
|
12652
|
+
return ok({
|
|
12653
|
+
...response.data,
|
|
12654
|
+
results: response.data.results.map((item, index) => ({
|
|
12655
|
+
...item,
|
|
12656
|
+
key: keys[index]
|
|
12657
|
+
}))
|
|
12658
|
+
});
|
|
12659
|
+
}
|
|
12632
12660
|
/**
|
|
12633
12661
|
* Create a short-lived signed URL for reading a KV object.
|
|
12634
12662
|
*/
|
|
@@ -12653,6 +12681,7 @@ var init_dist2 = __esm({
|
|
|
12653
12681
|
DELETE: "tinycloud.kv/del",
|
|
12654
12682
|
HEAD: "tinycloud.kv/metadata"
|
|
12655
12683
|
};
|
|
12684
|
+
MAX_KV_BATCH_READ_ITEMS = 100;
|
|
12656
12685
|
KVService = class extends BaseService {
|
|
12657
12686
|
/**
|
|
12658
12687
|
* Create a new KVService instance.
|
|
@@ -12881,6 +12910,173 @@ var init_dist2 = __esm({
|
|
|
12881
12910
|
get: (name2) => headers.get(name2)
|
|
12882
12911
|
};
|
|
12883
12912
|
}
|
|
12913
|
+
createBatchResponseHeaders(values) {
|
|
12914
|
+
const normalized = new Map(
|
|
12915
|
+
Object.entries(values).map(([name2, value]) => [name2.toLowerCase(), value])
|
|
12916
|
+
);
|
|
12917
|
+
return this.createResponseHeaders({
|
|
12918
|
+
get: (name2) => normalized.get(name2.toLowerCase()) ?? null
|
|
12919
|
+
});
|
|
12920
|
+
}
|
|
12921
|
+
parseBatchValue(dataBase64, headers, raw = false, binary = false) {
|
|
12922
|
+
const encoded = globalThis.atob(dataBase64);
|
|
12923
|
+
const bytes = Uint8Array.from(encoded, (character) => character.charCodeAt(0));
|
|
12924
|
+
if (binary) return bytes;
|
|
12925
|
+
const text = new TextDecoder().decode(bytes);
|
|
12926
|
+
if (raw) return text;
|
|
12927
|
+
const contentType = Object.entries(headers).find(
|
|
12928
|
+
([name2]) => name2.toLowerCase() === "content-type"
|
|
12929
|
+
)?.[1];
|
|
12930
|
+
return contentType?.includes("application/json") ? JSON.parse(text) : text;
|
|
12931
|
+
}
|
|
12932
|
+
normalizeBatchReadResponse(data, paths, requireData) {
|
|
12933
|
+
if (!data || typeof data !== "object") return void 0;
|
|
12934
|
+
const response = data;
|
|
12935
|
+
if (!Array.isArray(response.results) || response.results.length !== paths.length) {
|
|
12936
|
+
return void 0;
|
|
12937
|
+
}
|
|
12938
|
+
for (let index = 0; index < response.results.length; index++) {
|
|
12939
|
+
const item = response.results[index];
|
|
12940
|
+
if (!item || typeof item !== "object" || item.key !== paths[index] || typeof item.ok !== "boolean") {
|
|
12941
|
+
return void 0;
|
|
12942
|
+
}
|
|
12943
|
+
if (item.ok && (!item.headers || typeof item.headers !== "object" || Object.values(item.headers).some((value) => typeof value !== "string") || requireData && typeof item.dataBase64 !== "string")) {
|
|
12944
|
+
return void 0;
|
|
12945
|
+
}
|
|
12946
|
+
if (!item.ok && (!item.error || typeof item.error.code !== "string" || typeof item.error.message !== "string")) {
|
|
12947
|
+
return void 0;
|
|
12948
|
+
}
|
|
12949
|
+
}
|
|
12950
|
+
return response;
|
|
12951
|
+
}
|
|
12952
|
+
async batchRead(keys, action, options) {
|
|
12953
|
+
if (!this.requireAuth()) return err(authRequiredError("kv"));
|
|
12954
|
+
if (keys.length === 0) return ok({ results: [], count: 0 });
|
|
12955
|
+
if (keys.length > MAX_KV_BATCH_READ_ITEMS) {
|
|
12956
|
+
return err(serviceError(
|
|
12957
|
+
ErrorCodes.INVALID_INPUT,
|
|
12958
|
+
`KV batch reads accept at most ${MAX_KV_BATCH_READ_ITEMS} keys`,
|
|
12959
|
+
"kv"
|
|
12960
|
+
));
|
|
12961
|
+
}
|
|
12962
|
+
if (keys.length === 1) {
|
|
12963
|
+
const key = keys[0];
|
|
12964
|
+
const result = action === KVAction.GET ? await this.get(key, options) : await this.head(key, options);
|
|
12965
|
+
return ok({
|
|
12966
|
+
results: [{ key, result }],
|
|
12967
|
+
count: 1
|
|
12968
|
+
});
|
|
12969
|
+
}
|
|
12970
|
+
if (!this.context.invokeAny) {
|
|
12971
|
+
return err(serviceError(
|
|
12972
|
+
ErrorCodes.INVALID_INPUT,
|
|
12973
|
+
"KV batch reads require SDK runtime support for multi-resource invocations",
|
|
12974
|
+
"kv"
|
|
12975
|
+
));
|
|
12976
|
+
}
|
|
12977
|
+
const getOptions = action === KVAction.GET ? options : void 0;
|
|
12978
|
+
if (getOptions?.maxResponseBytes !== void 0 && (!Number.isSafeInteger(getOptions.maxResponseBytes) || getOptions.maxResponseBytes <= 0)) {
|
|
12979
|
+
return err(serviceError(
|
|
12980
|
+
ErrorCodes.INVALID_INPUT,
|
|
12981
|
+
"KV maxResponseBytes must be a positive safe integer",
|
|
12982
|
+
"kv"
|
|
12983
|
+
));
|
|
12984
|
+
}
|
|
12985
|
+
const paths = keys.map((key) => this.getFullPath(key, options?.prefix));
|
|
12986
|
+
if (new Set(paths).size !== paths.length) {
|
|
12987
|
+
return err(serviceError(
|
|
12988
|
+
ErrorCodes.INVALID_INPUT,
|
|
12989
|
+
"KV batch read received duplicate keys after prefix resolution",
|
|
12990
|
+
"kv"
|
|
12991
|
+
));
|
|
12992
|
+
}
|
|
12993
|
+
try {
|
|
12994
|
+
const session = this.context.session;
|
|
12995
|
+
const invocationHeaders = this.context.invokeAny(
|
|
12996
|
+
session,
|
|
12997
|
+
paths.map((path) => ({
|
|
12998
|
+
spaceId: session.spaceId,
|
|
12999
|
+
service: "kv",
|
|
13000
|
+
path,
|
|
13001
|
+
action
|
|
13002
|
+
}))
|
|
13003
|
+
);
|
|
13004
|
+
const limitHeaders = {};
|
|
13005
|
+
if (getOptions?.maxResponseBytes !== void 0) {
|
|
13006
|
+
limitHeaders["x-tinycloud-max-response-bytes"] = String(
|
|
13007
|
+
getOptions.maxResponseBytes
|
|
13008
|
+
);
|
|
13009
|
+
}
|
|
13010
|
+
const headers = Array.isArray(invocationHeaders) ? [...invocationHeaders, ...Object.entries(limitHeaders)] : { ...invocationHeaders, ...limitHeaders };
|
|
13011
|
+
const response = await this.context.fetch(`${this.host}/invoke`, {
|
|
13012
|
+
method: "POST",
|
|
13013
|
+
headers,
|
|
13014
|
+
signal: this.combineSignals(options?.signal)
|
|
13015
|
+
});
|
|
13016
|
+
if (!response.ok) {
|
|
13017
|
+
const errorText = await response.text();
|
|
13018
|
+
if (response.status === 401 || response.status === 403) {
|
|
13019
|
+
const { resource, action: requiredAction } = parseAuthError(errorText);
|
|
13020
|
+
return err(authUnauthorizedError("kv", errorText, {
|
|
13021
|
+
status: response.status,
|
|
13022
|
+
...requiredAction && { requiredAction },
|
|
13023
|
+
...resource && { resource }
|
|
13024
|
+
}));
|
|
13025
|
+
}
|
|
13026
|
+
if (response.status === 413) {
|
|
13027
|
+
return err(serviceError(
|
|
13028
|
+
ErrorCodes.KV_RESPONSE_TOO_LARGE,
|
|
13029
|
+
"A KV batch value exceeds the requested response limit",
|
|
13030
|
+
"kv",
|
|
13031
|
+
{ meta: { status: response.status, statusText: response.statusText } }
|
|
13032
|
+
));
|
|
13033
|
+
}
|
|
13034
|
+
return err(serviceError(
|
|
13035
|
+
ErrorCodes.NETWORK_ERROR,
|
|
13036
|
+
`Failed to batch read ${keys.length} key(s): ${response.status} - ${errorText}`,
|
|
13037
|
+
"kv",
|
|
13038
|
+
{ meta: { status: response.status, statusText: response.statusText } }
|
|
13039
|
+
));
|
|
13040
|
+
}
|
|
13041
|
+
const payload = this.normalizeBatchReadResponse(
|
|
13042
|
+
await response.json(),
|
|
13043
|
+
paths,
|
|
13044
|
+
action === KVAction.GET
|
|
13045
|
+
);
|
|
13046
|
+
if (!payload) {
|
|
13047
|
+
return err(serviceError(
|
|
13048
|
+
ErrorCodes.NETWORK_ERROR,
|
|
13049
|
+
"KV batch read response did not match the requested keys",
|
|
13050
|
+
"kv"
|
|
13051
|
+
));
|
|
13052
|
+
}
|
|
13053
|
+
const results = payload.results.map((item, index) => {
|
|
13054
|
+
if (!item.ok) {
|
|
13055
|
+
return {
|
|
13056
|
+
key: keys[index],
|
|
13057
|
+
result: err(serviceError(item.error.code, item.error.message, "kv"))
|
|
13058
|
+
};
|
|
13059
|
+
}
|
|
13060
|
+
const headers2 = item.headers;
|
|
13061
|
+
const data = action === KVAction.HEAD ? void 0 : this.parseBatchValue(
|
|
13062
|
+
item.dataBase64,
|
|
13063
|
+
headers2,
|
|
13064
|
+
getOptions?.raw,
|
|
13065
|
+
getOptions?.binary
|
|
13066
|
+
);
|
|
13067
|
+
return {
|
|
13068
|
+
key: keys[index],
|
|
13069
|
+
result: ok({
|
|
13070
|
+
data,
|
|
13071
|
+
headers: this.createBatchResponseHeaders(headers2)
|
|
13072
|
+
})
|
|
13073
|
+
};
|
|
13074
|
+
});
|
|
13075
|
+
return ok({ results, count: results.length });
|
|
13076
|
+
} catch (error) {
|
|
13077
|
+
return err(wrapError2("kv", error));
|
|
13078
|
+
}
|
|
13079
|
+
}
|
|
12884
13080
|
/**
|
|
12885
13081
|
* Parse response body based on content type.
|
|
12886
13082
|
*
|
|
@@ -13027,6 +13223,13 @@ var init_dist2 = __esm({
|
|
|
13027
13223
|
}
|
|
13028
13224
|
});
|
|
13029
13225
|
}
|
|
13226
|
+
async batchGet(keys, options) {
|
|
13227
|
+
return this.withTelemetry(
|
|
13228
|
+
"batchGet",
|
|
13229
|
+
String(keys.length),
|
|
13230
|
+
() => this.batchRead(keys, KVAction.GET, options)
|
|
13231
|
+
);
|
|
13232
|
+
}
|
|
13030
13233
|
/**
|
|
13031
13234
|
* Store a value at a key.
|
|
13032
13235
|
*/
|
|
@@ -13386,6 +13589,13 @@ var init_dist2 = __esm({
|
|
|
13386
13589
|
}
|
|
13387
13590
|
});
|
|
13388
13591
|
}
|
|
13592
|
+
async batchHead(keys, options) {
|
|
13593
|
+
return this.withTelemetry(
|
|
13594
|
+
"batchHead",
|
|
13595
|
+
String(keys.length),
|
|
13596
|
+
() => this.batchRead(keys, KVAction.HEAD, options)
|
|
13597
|
+
);
|
|
13598
|
+
}
|
|
13389
13599
|
/**
|
|
13390
13600
|
* Create a short-lived signed URL for reading a KV object.
|
|
13391
13601
|
*/
|