@tinycloud/sdk-services 2.1.0 → 2.2.0-beta.12
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.cjs +245 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -2
- package/dist/index.d.ts +53 -2
- package/dist/index.js +240 -0
- package/dist/index.js.map +1 -1
- package/dist/kv/index.cjs +116 -0
- package/dist/kv/index.cjs.map +1 -1
- package/dist/kv/index.d.cts +99 -1
- package/dist/kv/index.d.ts +99 -1
- package/dist/kv/index.js +115 -0
- package/dist/kv/index.js.map +1 -1
- package/package.json +3 -3
package/dist/kv/index.d.cts
CHANGED
|
@@ -140,6 +140,47 @@ interface KVHeadOptions {
|
|
|
140
140
|
*/
|
|
141
141
|
signal?: AbortSignal;
|
|
142
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Default lifetime for signed KV read URLs when a caller omits expiresInSeconds.
|
|
145
|
+
* SDK duration defaults are stored in milliseconds; createSignedReadUrl converts
|
|
146
|
+
* this to the node endpoint's ttl_seconds field.
|
|
147
|
+
*
|
|
148
|
+
* Keep this in sync with EXPIRY.SIGNED_READ_URL_MS in @tinycloud/sdk-core.
|
|
149
|
+
* sdk-services cannot import sdk-core because sdk-core depends on sdk-services.
|
|
150
|
+
*/
|
|
151
|
+
declare const DEFAULT_SIGNED_READ_URL_EXPIRY_MS: number;
|
|
152
|
+
/**
|
|
153
|
+
* Options for creating a signed KV read URL.
|
|
154
|
+
*/
|
|
155
|
+
interface KVCreateSignedReadUrlOptions {
|
|
156
|
+
/**
|
|
157
|
+
* Override the default prefix for this operation.
|
|
158
|
+
*/
|
|
159
|
+
prefix?: string;
|
|
160
|
+
/**
|
|
161
|
+
* Requested URL lifetime in seconds.
|
|
162
|
+
* Defaults to {@link DEFAULT_SIGNED_READ_URL_EXPIRY_MS} converted to seconds.
|
|
163
|
+
* The node may cap this by its configured maximum, the invocation expiry,
|
|
164
|
+
* or the parent delegation expiry.
|
|
165
|
+
*/
|
|
166
|
+
expiresInSeconds?: number;
|
|
167
|
+
/**
|
|
168
|
+
* Optional blake3 content hash to bind the signed URL to a specific object.
|
|
169
|
+
*/
|
|
170
|
+
contentHash?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Optional ETag to bind the signed URL to a specific object version.
|
|
173
|
+
*/
|
|
174
|
+
etag?: string;
|
|
175
|
+
/**
|
|
176
|
+
* Custom timeout for this operation in milliseconds.
|
|
177
|
+
*/
|
|
178
|
+
timeout?: number;
|
|
179
|
+
/**
|
|
180
|
+
* Custom abort signal for this operation.
|
|
181
|
+
*/
|
|
182
|
+
signal?: AbortSignal;
|
|
183
|
+
}
|
|
143
184
|
/**
|
|
144
185
|
* Response headers from KV operations.
|
|
145
186
|
*/
|
|
@@ -192,6 +233,27 @@ interface KVListResponse {
|
|
|
192
233
|
*/
|
|
193
234
|
keys: string[];
|
|
194
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Response from signed KV read URL creation.
|
|
238
|
+
*/
|
|
239
|
+
interface KVSignedReadUrlResponse {
|
|
240
|
+
/**
|
|
241
|
+
* Absolute URL suitable for passing to external readers.
|
|
242
|
+
*/
|
|
243
|
+
url: string;
|
|
244
|
+
/**
|
|
245
|
+
* Opaque URL returned by tinycloud-node, usually relative to the node host.
|
|
246
|
+
*/
|
|
247
|
+
relativeUrl: string;
|
|
248
|
+
/**
|
|
249
|
+
* Opaque signed KV ticket identifier.
|
|
250
|
+
*/
|
|
251
|
+
ticketId: string;
|
|
252
|
+
/**
|
|
253
|
+
* Expiry timestamp as returned by tinycloud-node.
|
|
254
|
+
*/
|
|
255
|
+
expiresAt: string;
|
|
256
|
+
}
|
|
195
257
|
/**
|
|
196
258
|
* KV service action types.
|
|
197
259
|
*/
|
|
@@ -333,6 +395,16 @@ interface IPrefixedKVService {
|
|
|
333
395
|
* ```
|
|
334
396
|
*/
|
|
335
397
|
head(key: string, options?: Omit<KVHeadOptions, 'prefix'>): Promise<Result<KVResponse<void>>>;
|
|
398
|
+
/**
|
|
399
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
400
|
+
*
|
|
401
|
+
* The key is automatically prefixed with this service's prefix.
|
|
402
|
+
*
|
|
403
|
+
* @param key - The key to expose via a signed read URL (will be prefixed)
|
|
404
|
+
* @param options - Optional signed URL configuration
|
|
405
|
+
* @returns Result with URL and expiry metadata
|
|
406
|
+
*/
|
|
407
|
+
createSignedReadUrl(key: string, options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>): Promise<Result<KVSignedReadUrlResponse>>;
|
|
336
408
|
/**
|
|
337
409
|
* Create a nested prefix-scoped view.
|
|
338
410
|
*
|
|
@@ -362,6 +434,7 @@ interface IKVServiceLike {
|
|
|
362
434
|
list(options?: KVListOptions): Promise<Result<KVListResponse>>;
|
|
363
435
|
delete(key: string, options?: KVDeleteOptions): Promise<Result<void>>;
|
|
364
436
|
head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
|
|
437
|
+
createSignedReadUrl(key: string, options?: KVCreateSignedReadUrlOptions): Promise<Result<KVSignedReadUrlResponse>>;
|
|
365
438
|
}
|
|
366
439
|
/**
|
|
367
440
|
* PrefixedKVService - Implementation of prefix-scoped KV operations.
|
|
@@ -442,6 +515,10 @@ declare class PrefixedKVService implements IPrefixedKVService {
|
|
|
442
515
|
* Get metadata for a key without retrieving the value.
|
|
443
516
|
*/
|
|
444
517
|
head(key: string, options?: Omit<KVHeadOptions, 'prefix'>): Promise<Result<KVResponse<void>>>;
|
|
518
|
+
/**
|
|
519
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
520
|
+
*/
|
|
521
|
+
createSignedReadUrl(key: string, options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>): Promise<Result<KVSignedReadUrlResponse>>;
|
|
445
522
|
/**
|
|
446
523
|
* Create a nested prefix-scoped view.
|
|
447
524
|
*/
|
|
@@ -564,6 +641,20 @@ interface IKVService extends IService {
|
|
|
564
641
|
* ```
|
|
565
642
|
*/
|
|
566
643
|
head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
|
|
644
|
+
/**
|
|
645
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
646
|
+
*
|
|
647
|
+
* The request is authorized with the current session's `tinycloud.kv/get`
|
|
648
|
+
* capability for the resolved key path. The returned `url` is absolute and
|
|
649
|
+
* can be passed to external services that need bearer read access.
|
|
650
|
+
*
|
|
651
|
+
* Requires tinycloud-node with the `/signed/kv` endpoint from TC-1368.
|
|
652
|
+
*
|
|
653
|
+
* @param key - The key to expose via a signed read URL
|
|
654
|
+
* @param options - Optional signed URL configuration
|
|
655
|
+
* @returns Result with URL and expiry metadata
|
|
656
|
+
*/
|
|
657
|
+
createSignedReadUrl(key: string, options?: KVCreateSignedReadUrlOptions): Promise<Result<KVSignedReadUrlResponse>>;
|
|
567
658
|
/**
|
|
568
659
|
* Create a prefix-scoped view of this KV service.
|
|
569
660
|
*
|
|
@@ -655,6 +746,7 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
655
746
|
* Get the host URL.
|
|
656
747
|
*/
|
|
657
748
|
private get host();
|
|
749
|
+
private withJsonContentType;
|
|
658
750
|
/**
|
|
659
751
|
* Execute an invoke operation.
|
|
660
752
|
*
|
|
@@ -680,6 +772,8 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
680
772
|
* @returns Parsed data
|
|
681
773
|
*/
|
|
682
774
|
private parseResponse;
|
|
775
|
+
private createSignedReadUrlError;
|
|
776
|
+
private normalizeSignedReadUrlResponse;
|
|
683
777
|
/**
|
|
684
778
|
* Get a value by key.
|
|
685
779
|
*/
|
|
@@ -700,6 +794,10 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
700
794
|
* Get metadata for a key without retrieving the value.
|
|
701
795
|
*/
|
|
702
796
|
head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
|
|
797
|
+
/**
|
|
798
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
799
|
+
*/
|
|
800
|
+
createSignedReadUrl(key: string, options?: KVCreateSignedReadUrlOptions): Promise<Result<KVSignedReadUrlResponse>>;
|
|
703
801
|
/**
|
|
704
802
|
* Create a prefix-scoped view of this KV service.
|
|
705
803
|
*
|
|
@@ -745,4 +843,4 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
745
843
|
withPrefix(prefix: string): IPrefixedKVService;
|
|
746
844
|
}
|
|
747
845
|
|
|
748
|
-
export { type IKVService, type IPrefixedKVService, KVAction, type KVActionType, type KVDeleteOptions, type KVGetOptions, type KVHeadOptions, type KVListOptions, type KVListResponse, type KVPutOptions, type KVResponse, type KVResponseHeaders, KVService, type KVServiceConfig, PrefixedKVService };
|
|
846
|
+
export { DEFAULT_SIGNED_READ_URL_EXPIRY_MS, type IKVService, type IPrefixedKVService, KVAction, type KVActionType, type KVCreateSignedReadUrlOptions, type KVDeleteOptions, type KVGetOptions, type KVHeadOptions, type KVListOptions, type KVListResponse, type KVPutOptions, type KVResponse, type KVResponseHeaders, KVService, type KVServiceConfig, type KVSignedReadUrlResponse, PrefixedKVService };
|
package/dist/kv/index.d.ts
CHANGED
|
@@ -140,6 +140,47 @@ interface KVHeadOptions {
|
|
|
140
140
|
*/
|
|
141
141
|
signal?: AbortSignal;
|
|
142
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Default lifetime for signed KV read URLs when a caller omits expiresInSeconds.
|
|
145
|
+
* SDK duration defaults are stored in milliseconds; createSignedReadUrl converts
|
|
146
|
+
* this to the node endpoint's ttl_seconds field.
|
|
147
|
+
*
|
|
148
|
+
* Keep this in sync with EXPIRY.SIGNED_READ_URL_MS in @tinycloud/sdk-core.
|
|
149
|
+
* sdk-services cannot import sdk-core because sdk-core depends on sdk-services.
|
|
150
|
+
*/
|
|
151
|
+
declare const DEFAULT_SIGNED_READ_URL_EXPIRY_MS: number;
|
|
152
|
+
/**
|
|
153
|
+
* Options for creating a signed KV read URL.
|
|
154
|
+
*/
|
|
155
|
+
interface KVCreateSignedReadUrlOptions {
|
|
156
|
+
/**
|
|
157
|
+
* Override the default prefix for this operation.
|
|
158
|
+
*/
|
|
159
|
+
prefix?: string;
|
|
160
|
+
/**
|
|
161
|
+
* Requested URL lifetime in seconds.
|
|
162
|
+
* Defaults to {@link DEFAULT_SIGNED_READ_URL_EXPIRY_MS} converted to seconds.
|
|
163
|
+
* The node may cap this by its configured maximum, the invocation expiry,
|
|
164
|
+
* or the parent delegation expiry.
|
|
165
|
+
*/
|
|
166
|
+
expiresInSeconds?: number;
|
|
167
|
+
/**
|
|
168
|
+
* Optional blake3 content hash to bind the signed URL to a specific object.
|
|
169
|
+
*/
|
|
170
|
+
contentHash?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Optional ETag to bind the signed URL to a specific object version.
|
|
173
|
+
*/
|
|
174
|
+
etag?: string;
|
|
175
|
+
/**
|
|
176
|
+
* Custom timeout for this operation in milliseconds.
|
|
177
|
+
*/
|
|
178
|
+
timeout?: number;
|
|
179
|
+
/**
|
|
180
|
+
* Custom abort signal for this operation.
|
|
181
|
+
*/
|
|
182
|
+
signal?: AbortSignal;
|
|
183
|
+
}
|
|
143
184
|
/**
|
|
144
185
|
* Response headers from KV operations.
|
|
145
186
|
*/
|
|
@@ -192,6 +233,27 @@ interface KVListResponse {
|
|
|
192
233
|
*/
|
|
193
234
|
keys: string[];
|
|
194
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Response from signed KV read URL creation.
|
|
238
|
+
*/
|
|
239
|
+
interface KVSignedReadUrlResponse {
|
|
240
|
+
/**
|
|
241
|
+
* Absolute URL suitable for passing to external readers.
|
|
242
|
+
*/
|
|
243
|
+
url: string;
|
|
244
|
+
/**
|
|
245
|
+
* Opaque URL returned by tinycloud-node, usually relative to the node host.
|
|
246
|
+
*/
|
|
247
|
+
relativeUrl: string;
|
|
248
|
+
/**
|
|
249
|
+
* Opaque signed KV ticket identifier.
|
|
250
|
+
*/
|
|
251
|
+
ticketId: string;
|
|
252
|
+
/**
|
|
253
|
+
* Expiry timestamp as returned by tinycloud-node.
|
|
254
|
+
*/
|
|
255
|
+
expiresAt: string;
|
|
256
|
+
}
|
|
195
257
|
/**
|
|
196
258
|
* KV service action types.
|
|
197
259
|
*/
|
|
@@ -333,6 +395,16 @@ interface IPrefixedKVService {
|
|
|
333
395
|
* ```
|
|
334
396
|
*/
|
|
335
397
|
head(key: string, options?: Omit<KVHeadOptions, 'prefix'>): Promise<Result<KVResponse<void>>>;
|
|
398
|
+
/**
|
|
399
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
400
|
+
*
|
|
401
|
+
* The key is automatically prefixed with this service's prefix.
|
|
402
|
+
*
|
|
403
|
+
* @param key - The key to expose via a signed read URL (will be prefixed)
|
|
404
|
+
* @param options - Optional signed URL configuration
|
|
405
|
+
* @returns Result with URL and expiry metadata
|
|
406
|
+
*/
|
|
407
|
+
createSignedReadUrl(key: string, options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>): Promise<Result<KVSignedReadUrlResponse>>;
|
|
336
408
|
/**
|
|
337
409
|
* Create a nested prefix-scoped view.
|
|
338
410
|
*
|
|
@@ -362,6 +434,7 @@ interface IKVServiceLike {
|
|
|
362
434
|
list(options?: KVListOptions): Promise<Result<KVListResponse>>;
|
|
363
435
|
delete(key: string, options?: KVDeleteOptions): Promise<Result<void>>;
|
|
364
436
|
head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
|
|
437
|
+
createSignedReadUrl(key: string, options?: KVCreateSignedReadUrlOptions): Promise<Result<KVSignedReadUrlResponse>>;
|
|
365
438
|
}
|
|
366
439
|
/**
|
|
367
440
|
* PrefixedKVService - Implementation of prefix-scoped KV operations.
|
|
@@ -442,6 +515,10 @@ declare class PrefixedKVService implements IPrefixedKVService {
|
|
|
442
515
|
* Get metadata for a key without retrieving the value.
|
|
443
516
|
*/
|
|
444
517
|
head(key: string, options?: Omit<KVHeadOptions, 'prefix'>): Promise<Result<KVResponse<void>>>;
|
|
518
|
+
/**
|
|
519
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
520
|
+
*/
|
|
521
|
+
createSignedReadUrl(key: string, options?: Omit<KVCreateSignedReadUrlOptions, 'prefix'>): Promise<Result<KVSignedReadUrlResponse>>;
|
|
445
522
|
/**
|
|
446
523
|
* Create a nested prefix-scoped view.
|
|
447
524
|
*/
|
|
@@ -564,6 +641,20 @@ interface IKVService extends IService {
|
|
|
564
641
|
* ```
|
|
565
642
|
*/
|
|
566
643
|
head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
|
|
644
|
+
/**
|
|
645
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
646
|
+
*
|
|
647
|
+
* The request is authorized with the current session's `tinycloud.kv/get`
|
|
648
|
+
* capability for the resolved key path. The returned `url` is absolute and
|
|
649
|
+
* can be passed to external services that need bearer read access.
|
|
650
|
+
*
|
|
651
|
+
* Requires tinycloud-node with the `/signed/kv` endpoint from TC-1368.
|
|
652
|
+
*
|
|
653
|
+
* @param key - The key to expose via a signed read URL
|
|
654
|
+
* @param options - Optional signed URL configuration
|
|
655
|
+
* @returns Result with URL and expiry metadata
|
|
656
|
+
*/
|
|
657
|
+
createSignedReadUrl(key: string, options?: KVCreateSignedReadUrlOptions): Promise<Result<KVSignedReadUrlResponse>>;
|
|
567
658
|
/**
|
|
568
659
|
* Create a prefix-scoped view of this KV service.
|
|
569
660
|
*
|
|
@@ -655,6 +746,7 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
655
746
|
* Get the host URL.
|
|
656
747
|
*/
|
|
657
748
|
private get host();
|
|
749
|
+
private withJsonContentType;
|
|
658
750
|
/**
|
|
659
751
|
* Execute an invoke operation.
|
|
660
752
|
*
|
|
@@ -680,6 +772,8 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
680
772
|
* @returns Parsed data
|
|
681
773
|
*/
|
|
682
774
|
private parseResponse;
|
|
775
|
+
private createSignedReadUrlError;
|
|
776
|
+
private normalizeSignedReadUrlResponse;
|
|
683
777
|
/**
|
|
684
778
|
* Get a value by key.
|
|
685
779
|
*/
|
|
@@ -700,6 +794,10 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
700
794
|
* Get metadata for a key without retrieving the value.
|
|
701
795
|
*/
|
|
702
796
|
head(key: string, options?: KVHeadOptions): Promise<Result<KVResponse<void>>>;
|
|
797
|
+
/**
|
|
798
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
799
|
+
*/
|
|
800
|
+
createSignedReadUrl(key: string, options?: KVCreateSignedReadUrlOptions): Promise<Result<KVSignedReadUrlResponse>>;
|
|
703
801
|
/**
|
|
704
802
|
* Create a prefix-scoped view of this KV service.
|
|
705
803
|
*
|
|
@@ -745,4 +843,4 @@ declare class KVService extends BaseService implements IKVService {
|
|
|
745
843
|
withPrefix(prefix: string): IPrefixedKVService;
|
|
746
844
|
}
|
|
747
845
|
|
|
748
|
-
export { type IKVService, type IPrefixedKVService, KVAction, type KVActionType, type KVDeleteOptions, type KVGetOptions, type KVHeadOptions, type KVListOptions, type KVListResponse, type KVPutOptions, type KVResponse, type KVResponseHeaders, KVService, type KVServiceConfig, PrefixedKVService };
|
|
846
|
+
export { DEFAULT_SIGNED_READ_URL_EXPIRY_MS, type IKVService, type IPrefixedKVService, KVAction, type KVActionType, type KVCreateSignedReadUrlOptions, type KVDeleteOptions, type KVGetOptions, type KVHeadOptions, type KVListOptions, type KVListResponse, type KVPutOptions, type KVResponse, type KVResponseHeaders, KVService, type KVServiceConfig, type KVSignedReadUrlResponse, PrefixedKVService };
|
package/dist/kv/index.js
CHANGED
|
@@ -386,6 +386,13 @@ var PrefixedKVService = class _PrefixedKVService {
|
|
|
386
386
|
const fullKey = this.getFullKey(key);
|
|
387
387
|
return this._kv.head(fullKey, { ...options, prefix: "" });
|
|
388
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
391
|
+
*/
|
|
392
|
+
async createSignedReadUrl(key, options) {
|
|
393
|
+
const fullKey = this.getFullKey(key);
|
|
394
|
+
return this._kv.createSignedReadUrl(fullKey, { ...options, prefix: "" });
|
|
395
|
+
}
|
|
389
396
|
/**
|
|
390
397
|
* Create a nested prefix-scoped view.
|
|
391
398
|
*/
|
|
@@ -397,6 +404,7 @@ var PrefixedKVService = class _PrefixedKVService {
|
|
|
397
404
|
};
|
|
398
405
|
|
|
399
406
|
// src/kv/types.ts
|
|
407
|
+
var DEFAULT_SIGNED_READ_URL_EXPIRY_MS = 5 * 60 * 1e3;
|
|
400
408
|
var KVAction = {
|
|
401
409
|
GET: "tinycloud.kv/get",
|
|
402
410
|
PUT: "tinycloud.kv/put",
|
|
@@ -481,6 +489,15 @@ var KVService = class extends BaseService {
|
|
|
481
489
|
get host() {
|
|
482
490
|
return this.context.hosts[0];
|
|
483
491
|
}
|
|
492
|
+
withJsonContentType(headers) {
|
|
493
|
+
if (Array.isArray(headers)) {
|
|
494
|
+
return [...headers, ["content-type", "application/json"]];
|
|
495
|
+
}
|
|
496
|
+
return {
|
|
497
|
+
...headers,
|
|
498
|
+
"content-type": "application/json"
|
|
499
|
+
};
|
|
500
|
+
}
|
|
484
501
|
/**
|
|
485
502
|
* Execute an invoke operation.
|
|
486
503
|
*
|
|
@@ -550,6 +567,48 @@ var KVService = class extends BaseService {
|
|
|
550
567
|
return text;
|
|
551
568
|
}
|
|
552
569
|
}
|
|
570
|
+
async createSignedReadUrlError(response, key) {
|
|
571
|
+
let errorText = response.statusText;
|
|
572
|
+
try {
|
|
573
|
+
const text = await response.text();
|
|
574
|
+
if (text) {
|
|
575
|
+
errorText = text;
|
|
576
|
+
}
|
|
577
|
+
} catch {
|
|
578
|
+
}
|
|
579
|
+
if (response.status === 401 || response.status === 403) {
|
|
580
|
+
const { resource, action } = parseAuthError(errorText);
|
|
581
|
+
return err(authUnauthorizedError("kv", errorText, {
|
|
582
|
+
status: response.status,
|
|
583
|
+
...action && { requiredAction: action },
|
|
584
|
+
...resource && { resource }
|
|
585
|
+
}));
|
|
586
|
+
}
|
|
587
|
+
const code = response.status === 400 ? ErrorCodes.INVALID_INPUT : ErrorCodes.NETWORK_ERROR;
|
|
588
|
+
return err(
|
|
589
|
+
serviceError(
|
|
590
|
+
code,
|
|
591
|
+
`Failed to create signed read URL for key "${key}": ${response.status} - ${errorText}`,
|
|
592
|
+
"kv",
|
|
593
|
+
{ meta: { status: response.status, statusText: response.statusText } }
|
|
594
|
+
)
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
normalizeSignedReadUrlResponse(data) {
|
|
598
|
+
if (!data || typeof data !== "object") {
|
|
599
|
+
return void 0;
|
|
600
|
+
}
|
|
601
|
+
const response = data;
|
|
602
|
+
if (typeof response.url !== "string" || typeof response.ticketId !== "string" || typeof response.expiresAt !== "string") {
|
|
603
|
+
return void 0;
|
|
604
|
+
}
|
|
605
|
+
return {
|
|
606
|
+
url: new URL(response.url, this.host).toString(),
|
|
607
|
+
relativeUrl: response.url,
|
|
608
|
+
ticketId: response.ticketId,
|
|
609
|
+
expiresAt: response.expiresAt
|
|
610
|
+
};
|
|
611
|
+
}
|
|
553
612
|
/**
|
|
554
613
|
* Get a value by key.
|
|
555
614
|
*/
|
|
@@ -822,6 +881,61 @@ var KVService = class extends BaseService {
|
|
|
822
881
|
}
|
|
823
882
|
});
|
|
824
883
|
}
|
|
884
|
+
/**
|
|
885
|
+
* Create a short-lived signed URL for reading a KV object.
|
|
886
|
+
*/
|
|
887
|
+
async createSignedReadUrl(key, options) {
|
|
888
|
+
return this.withTelemetry("createSignedReadUrl", key, async () => {
|
|
889
|
+
if (!this.requireAuth()) {
|
|
890
|
+
return err(authRequiredError("kv"));
|
|
891
|
+
}
|
|
892
|
+
const path = this.getFullPath(key, options?.prefix);
|
|
893
|
+
const session = this.context.session;
|
|
894
|
+
const headers = this.context.invoke(
|
|
895
|
+
session,
|
|
896
|
+
"kv",
|
|
897
|
+
path,
|
|
898
|
+
KVAction.GET
|
|
899
|
+
);
|
|
900
|
+
const body = {
|
|
901
|
+
space: session.spaceId,
|
|
902
|
+
path,
|
|
903
|
+
ttl_seconds: options?.expiresInSeconds ?? Math.ceil(DEFAULT_SIGNED_READ_URL_EXPIRY_MS / 1e3)
|
|
904
|
+
};
|
|
905
|
+
if (options?.contentHash !== void 0) {
|
|
906
|
+
body.content_hash = options.contentHash;
|
|
907
|
+
}
|
|
908
|
+
if (options?.etag !== void 0) {
|
|
909
|
+
body.etag = options.etag;
|
|
910
|
+
}
|
|
911
|
+
try {
|
|
912
|
+
const response = await this.context.fetch(`${this.host}/signed/kv`, {
|
|
913
|
+
method: "POST",
|
|
914
|
+
headers: this.withJsonContentType(headers),
|
|
915
|
+
body: JSON.stringify(body),
|
|
916
|
+
signal: this.combineSignals(options?.signal)
|
|
917
|
+
});
|
|
918
|
+
if (!response.ok) {
|
|
919
|
+
return this.createSignedReadUrlError(response, key);
|
|
920
|
+
}
|
|
921
|
+
const signedUrl = this.normalizeSignedReadUrlResponse(
|
|
922
|
+
await response.json()
|
|
923
|
+
);
|
|
924
|
+
if (!signedUrl) {
|
|
925
|
+
return err(
|
|
926
|
+
serviceError(
|
|
927
|
+
ErrorCodes.NETWORK_ERROR,
|
|
928
|
+
"Signed read URL response did not include url, ticketId, and expiresAt",
|
|
929
|
+
"kv"
|
|
930
|
+
)
|
|
931
|
+
);
|
|
932
|
+
}
|
|
933
|
+
return ok(signedUrl);
|
|
934
|
+
} catch (error) {
|
|
935
|
+
return err(wrapError("kv", error));
|
|
936
|
+
}
|
|
937
|
+
});
|
|
938
|
+
}
|
|
825
939
|
/**
|
|
826
940
|
* Create a prefix-scoped view of this KV service.
|
|
827
941
|
*
|
|
@@ -873,6 +987,7 @@ var KVService = class extends BaseService {
|
|
|
873
987
|
*/
|
|
874
988
|
KVService.serviceName = "kv";
|
|
875
989
|
export {
|
|
990
|
+
DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
|
|
876
991
|
KVAction,
|
|
877
992
|
KVService,
|
|
878
993
|
PrefixedKVService
|