diff --git a/.changeset/eighty-starfishes-laugh.md b/.changeset/eighty-starfishes-laugh.md new file mode 100644 index 000000000..f89b00cc8 --- /dev/null +++ b/.changeset/eighty-starfishes-laugh.md @@ -0,0 +1,5 @@ +--- +'@vercel/kv': minor +--- + +move default export to named kv export diff --git a/packages/kv/README.md b/packages/kv/README.md index 723edb0a7..719c907a3 100644 --- a/packages/kv/README.md +++ b/packages/kv/README.md @@ -12,7 +12,7 @@ npm install @vercel/kv ## Usage ```js -import kv from '@vercel/kv'; +import { kv } from '@vercel/kv'; // string await kv.set('key', 'value'); diff --git a/packages/kv/src/index.test.ts b/packages/kv/src/index.test.ts index df7512c5f..6e93973f6 100644 --- a/packages/kv/src/index.test.ts +++ b/packages/kv/src/index.test.ts @@ -1,4 +1,4 @@ -import kv, { VercelKV, createClient } from '.'; +import defaultKv, { kv, VercelKV, createClient } from '.'; let scanReturnValues: [number, string[]][] = [[0, []]]; jest.mock('@upstash/redis', () => ({ @@ -15,10 +15,11 @@ jest.mock('@upstash/redis', () => ({ describe('@vercel/kv', () => { beforeEach(() => { scanReturnValues = [[0, []]]; + jest.clearAllMocks(); }); describe('kv export', () => { - it('exports a default client', async () => { + it('exports "kv" client', async () => { process.env.KV_REST_API_URL = 'https://foobar-6739.redis.vercel-storage.com'; process.env.KV_REST_API_TOKEN = 'tok_foobar'; @@ -28,6 +29,30 @@ describe('@vercel/kv', () => { process.env.KV_REST_API_URL = undefined; process.env.KV_REST_API_TOKEN = undefined; }); + + it('exports default legacy client', async () => { + process.env.KV_REST_API_URL = + 'https://foobar-6739.redis.vercel-storage.com'; + process.env.KV_REST_API_TOKEN = 'tok_foobar'; + + expect(await defaultKv.get('foo')).toEqual('bar'); + + process.env.KV_REST_API_URL = undefined; + process.env.KV_REST_API_TOKEN = undefined; + }); + + it('should load awaited default module (Vite use case', async () => { + const kvModule = await import('.').then((m) => m.default); + + process.env.KV_REST_API_URL = + 'https://foobar-6739.redis.vercel-storage.com'; + process.env.KV_REST_API_TOKEN = 'tok_foobar'; + + expect(await kvModule.get('foo')).toEqual('bar'); + + process.env.KV_REST_API_URL = undefined; + process.env.KV_REST_API_TOKEN = undefined; + }); }); describe('createClient', () => { diff --git a/packages/kv/src/index.ts b/packages/kv/src/index.ts index 53ecd14c4..acb5b8899 100644 --- a/packages/kv/src/index.ts +++ b/packages/kv/src/index.ts @@ -82,6 +82,39 @@ export function createClient(config: RedisConfigNodejs): VercelKV { // eslint-disable-next-line import/no-default-export export default new Proxy( + {}, + { + // eslint-disable-next-line @typescript-eslint/explicit-function-return-type + get(target, prop, receiver) { + if (prop === 'then' || prop === 'parse') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return Reflect.get(target, prop, receiver); + } + + if (!_kv) { + if (!process.env.KV_REST_API_URL || !process.env.KV_REST_API_TOKEN) { + throw new Error( + '@vercel/kv: Missing required environment variables KV_REST_API_URL and KV_REST_API_TOKEN', + ); + } + // eslint-disable-next-line no-console + console.warn( + '\x1b[33m"The default export has been moved to a named export and it will be removed in version 1, change to import { kv }\x1b[0m"', + ); + + _kv = createClient({ + url: process.env.KV_REST_API_URL, + token: process.env.KV_REST_API_TOKEN, + }); + } + + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return Reflect.get(_kv, prop); + }, + }, +) as VercelKV; + +export const kv = new Proxy( {}, { // eslint-disable-next-line @typescript-eslint/explicit-function-return-type diff --git a/test/next/README.md b/test/next/README.md index 8017998fb..f027d05ec 100644 --- a/test/next/README.md +++ b/test/next/README.md @@ -1,6 +1,6 @@ Instructions: -- `cd packages/integration` +- `cd test/next` - `vc link` => link to `Curated Tests` => `vercel-storage-next-integration-test-suite` - `vc env pull` - `pnpm i`