Skip to content

thomasgauvin/testing-workers-kv-sdk-typescript

Repository files navigation

KV Metadata Testing

This project tests the Cloudflare KV metadata issue where:

  1. Metadata is supposedly optional but required in TypeScript types
  2. Passing empty metadata {} causes values to be stored as {value: XYZ, metadata: {}}
  3. Manual multipart headers may be needed as a workaround

Setup

  1. Copy .env.example to .env and fill in your Cloudflare credentials:

    cp .env.example .env
  2. Get your credentials:

    • API Token: Create one in Cloudflare dashboard with KV permissions
    • Account ID: Found in right sidebar of Cloudflare dashboard
    • KV Namespace ID: Create a KV namespace and copy its ID
  3. Install dependencies:

    npm install

Running Tests

TypeScript Version

npm run test:ts

Just Compile TypeScript

npm run compile

What This Tests

  1. Writing without metadata - Should work fine
  2. Writing with empty metadata {} - The problematic case that wraps values
  3. Writing with actual metadata - Should work but also wraps values
  4. Writing via REST API with multipart/form-data - Direct API call with metadata
  5. Reading values back - To see what actually got stored

Findings

TypeScript Types Analysis ✅

  • metadata is actually optional in the TypeScript types
  • The issue is NOT with TypeScript compilation
  • You can successfully omit metadata in the value parameter

The Real Issue 🚨

The problem occurs when using the TypeScript SDK - metadata is not being saved:

  1. No metadata: Value stored as plain string ✅

    { value: "hello", account_id: "..." }  // Stores: "hello", no metadata
  2. Empty metadata: Value stored, but metadata is lost ❌

    { value: "hello", metadata: {}, account_id: "..." }  // Stores: "hello", metadata: null/undefined
  3. With metadata: Value stored, but metadata is lost ❌

    { value: "hello", metadata: {...}, account_id: "..." }  // Stores: "hello", metadata: null/undefined

The TypeScript SDK appears to ignore the metadata parameter entirely, while the REST API properly stores metadata when using multipart/form-data.

REST API Direct Access

Test 4 demonstrates using the Cloudflare KV REST API directly with proper multipart/form-data:

const formData = new FormData();
formData.append('value', 'your-value');
formData.append('metadata', JSON.stringify({
  author: 'test-user',
  timestamp: new Date().toISOString()
}));

const response = await fetch(
  `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/storage/kv/namespaces/${NAMESPACE_ID}/values/your-key?expiration_ttl=3600`,
  {
    method: 'PUT',
    headers: {
      'Authorization': `Bearer ${API_TOKEN}`
    },
    body: formData
  }
);

This bypasses the TypeScript SDK's wrapping behavior and stores metadata properly according to the official API specification.

Solutions

✅ Recommended Option 1: Just omit metadata

// Good - stores as plain value
await cf.kv.namespaces.values.update(namespaceId, key, {
  value: "your-data",
  account_id: accountId
  // Don't include metadata property at all
});

✅ Recommended Option 2: Use REST API directly

// Good - stores metadata properly without wrapping
const formData = new FormData();
formData.append('value', 'your-data');
formData.append('metadata', JSON.stringify({ author: 'user' }));

await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}`, {
  method: 'PUT',
  headers: { 'Authorization': `Bearer ${apiToken}` },
  body: formData
});

❌ Don't do this

// Bad - causes wrapping  
await cf.kv.namespaces.values.update(namespaceId, key, {
  value: "your-data", 
  account_id: accountId,
  metadata: {} // This forces multipart and wraps your value!
});

🤔 Alternative: Handle wrapped responses

If you must use the TypeScript SDK with metadata, handle the wrapper in your reads:

const result = await cf.kv.namespaces.values.get(namespaceId, key, {account_id});
const actualValue = typeof result === 'object' && result.value ? result.value : result;

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published