11import "@aws-sdk/signature-v4a" ;
22
33import { Sha256 } from "@aws-crypto/sha256-js" ;
4- import { CloudFrontClient , CreateKeyValueStoreCommand , DeleteKeyValueStoreCommand } from "@aws-sdk/client-cloudfront" ;
5- import { CloudFrontKeyValueStoreClient , DescribeKeyValueStoreCommand } from "@aws-sdk/client-cloudfront-keyvaluestore" ;
6- import { GetCallerIdentityCommand , STSClient } from "@aws-sdk/client-sts" ;
4+ import { CloudFrontClient , CreateKeyValueStoreCommand , DescribeKeyValueStoreCommand } from "@aws-sdk/client-cloudfront" ;
5+ import {
6+ CloudFrontKeyValueStoreClient ,
7+ DescribeKeyValueStoreCommand as KVSDescribeCommand ,
8+ } from "@aws-sdk/client-cloudfront-keyvaluestore" ;
79import { defaultProvider } from "@aws-sdk/credential-provider-node" ;
810import { SignatureV4MultiRegion } from "@aws-sdk/signature-v4-multi-region" ;
911import { HttpRequest } from "@smithy/protocol-http" ;
1012import { afterAll , beforeAll , describe , expect , it , vi } from "vitest" ;
1113
1214const LONG_TIMEOUT = 300000 ;
1315
16+ // Long-lived resource name
17+ const KEY_VALUE_STORE_NAME = "jsv3-e2e-cfkvs-sigv4a" ;
18+
1419const wait = ( ms : number ) => new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
1520
1621// Helper util to poll until KVS is ready
@@ -23,13 +28,9 @@ async function waitForKeyValueStoreReady(
2328 const startTime = Date . now ( ) ;
2429 while ( Date . now ( ) - startTime < timeoutMs ) {
2530 try {
26- const response = await client . send ( new DescribeKeyValueStoreCommand ( { KvsARN : arn } ) ) ;
31+ const response = await client . send ( new KVSDescribeCommand ( { KvsARN : arn } ) ) ;
2732 // if describe doesn't throw ResourceNotFound, it's ready enough for the test
2833 if ( response . KvsARN === arn ) {
29- // Optionally wait for 'Deployed' status if needed, but findable is often enough
30- // if (response.Status === "Deployed") {
31- // return;
32- // }
3334 return ;
3435 }
3536 } catch ( error : any ) {
@@ -49,19 +50,13 @@ async function waitForKeyValueStoreReady(
4950describe ( "CloudFront KeyValue Store with SignatureV4a (JS Implementation)" , ( ) => {
5051 let cfClient : CloudFrontClient ;
5152 let kvsClient : CloudFrontKeyValueStoreClient ;
52- let keyValueStoreName : string ;
5353 let keyValueStoreARN : string ;
54- let keyValueStoreETag : string ;
5554 let signer : SignatureV4MultiRegion ;
55+ let keyValueStoreETag : string ;
5656
5757 beforeAll ( async ( ) => {
5858 vi . setConfig ( { testTimeout : LONG_TIMEOUT , hookTimeout : LONG_TIMEOUT } ) ;
5959
60- const stsClient = new STSClient ( { region : "us-west-2" } ) ;
61- const { Account } = await stsClient . send ( new GetCallerIdentityCommand ( { } ) ) ;
62- const timestamp = Date . now ( ) ;
63- keyValueStoreName = `test-store-${ Account } -${ timestamp } ` ;
64-
6560 signer = new SignatureV4MultiRegion ( {
6661 service : "cloudfront-keyvaluestore" ,
6762 region : "*" ,
@@ -80,30 +75,43 @@ describe("CloudFront KeyValue Store with SignatureV4a (JS Implementation)", () =
8075 disableHostPrefix : true ,
8176 } ) ;
8277
83- const createResponse = await cfClient . send (
84- new CreateKeyValueStoreCommand ( {
85- Name : keyValueStoreName ,
86- } )
87- ) ;
88- keyValueStoreARN = createResponse . KeyValueStore ! . ARN ! ;
89- keyValueStoreETag = createResponse . ETag ! ;
78+ // Try to get the existing key value store
79+ try {
80+ const describeResponse = await cfClient . send (
81+ new DescribeKeyValueStoreCommand ( {
82+ Name : KEY_VALUE_STORE_NAME ,
83+ } )
84+ ) ;
85+ keyValueStoreARN = describeResponse . KeyValueStore ! . ARN ! ;
86+ keyValueStoreETag = describeResponse . ETag ! ;
87+ console . log ( `Using existing KeyValueStore: ${ keyValueStoreARN } ` ) ;
88+ } catch ( error : any ) {
89+ if ( error . name === "EntityNotFound" ) {
90+ console . log ( `KeyValueStore ${ KEY_VALUE_STORE_NAME } does not exist. Creating it now...` ) ;
91+ // Create the key value store if it doesn't exist
92+ const createResponse = await cfClient . send (
93+ new CreateKeyValueStoreCommand ( {
94+ Name : KEY_VALUE_STORE_NAME ,
95+ } )
96+ ) ;
97+ keyValueStoreARN = createResponse . KeyValueStore ! . ARN ! ;
98+ keyValueStoreETag = createResponse . ETag ! ;
99+ console . log ( `Created new KeyValueStore: ${ keyValueStoreARN } ` ) ;
100+ } else {
101+ throw error ;
102+ }
103+ }
90104
105+ // Make sure the key-value store is ready
91106 await waitForKeyValueStoreReady ( kvsClient , keyValueStoreARN ) ;
92107 } , LONG_TIMEOUT ) ;
93108
94109 afterAll ( async ( ) => {
95110 vi . setConfig ( { testTimeout : LONG_TIMEOUT } ) ;
96111
97- try {
98- await cfClient . send (
99- new DeleteKeyValueStoreCommand ( {
100- Name : keyValueStoreName ,
101- IfMatch : keyValueStoreETag ,
102- } )
103- ) ;
104- } catch ( error ) {
105- console . error ( "Failed to delete key-value store:" , error ) ;
106- }
112+ // key-value store is a long-lived resource, so we don't delete it
113+ cfClient ?. destroy ?.( ) ;
114+ kvsClient ?. destroy ?.( ) ;
107115 } ) ;
108116
109117 it ( "should use SignatureV4a JS implementation for CFKVS (mocked)" , async ( ) => {
@@ -129,7 +137,7 @@ describe("CloudFront KeyValue Store with SignatureV4a (JS Implementation)", () =
129137 } ) ;
130138
131139 it ( "should describe the key-value store using SignatureV4a" , async ( ) => {
132- const response = await kvsClient . send ( new DescribeKeyValueStoreCommand ( { KvsARN : keyValueStoreARN } ) ) ;
140+ const response = await kvsClient . send ( new KVSDescribeCommand ( { KvsARN : keyValueStoreARN } ) ) ;
133141 expect ( response . KvsARN ) . toBe ( keyValueStoreARN ) ;
134142 expect ( [ "READY" , "Deployed" ] ) . toContain ( response . Status ) ;
135143 } ) ;
0 commit comments