@upstash/redis 0.0.0-ci.babdc47f97e036e2863dfed16300cda2b97bf6ad-20240322001434 → 0.0.0-ci.bb93ac2803c2e927dc8bf1a1b3c5aa2a14034eb6-20240930061920
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/.env.example +2 -0
- package/.github/workflows/release.yml +53 -0
- package/.github/workflows/tests.yaml +609 -0
- package/.gitignore +175 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +2 -0
- package/.husky/pre-push +1 -0
- package/.prettierignore +1 -0
- package/.vscode/extensions.json +3 -0
- package/.vscode/settings.json +20 -0
- package/README.md +1 -2
- package/bun.lockb +0 -0
- package/commitlint.config.js +46 -0
- package/dist/LICENSE +21 -0
- package/dist/README.md +136 -0
- package/dist/chunk-TEVCO3ZO.mjs +3797 -0
- package/dist/cloudflare.d.mts +55 -0
- package/dist/cloudflare.d.ts +55 -0
- package/dist/cloudflare.js +3907 -0
- package/dist/cloudflare.mjs +91 -0
- package/dist/fastly.d.mts +48 -0
- package/dist/fastly.d.ts +48 -0
- package/dist/fastly.js +3880 -0
- package/dist/fastly.mjs +64 -0
- package/dist/nodejs.d.mts +73 -0
- package/dist/nodejs.d.ts +73 -0
- package/dist/nodejs.js +3926 -0
- package/dist/nodejs.mjs +110 -0
- package/dist/package.json +1 -0
- package/{zmscore-5d82e632.d.ts → dist/zmscore-BhX8yEQc.d.mts} +249 -184
- package/dist/zmscore-BhX8yEQc.d.ts +3486 -0
- package/eslint.config.mjs +102 -0
- package/examples/auto-pipeline/.eslintrc.json +3 -0
- package/examples/auto-pipeline/README.md +77 -0
- package/examples/auto-pipeline/app/components/DataComponent.tsx +49 -0
- package/examples/auto-pipeline/app/data/getEvents.ts +18 -0
- package/examples/auto-pipeline/app/data/getUsers.ts +18 -0
- package/examples/auto-pipeline/app/data/redis.ts +12 -0
- package/examples/auto-pipeline/app/favicon.ico +0 -0
- package/examples/auto-pipeline/app/globals.css +0 -0
- package/examples/auto-pipeline/app/layout.tsx +22 -0
- package/examples/auto-pipeline/app/page.tsx +15 -0
- package/examples/auto-pipeline/next.config.mjs +4 -0
- package/examples/auto-pipeline/package.json +27 -0
- package/examples/auto-pipeline/postcss.config.mjs +8 -0
- package/examples/auto-pipeline/public/next.svg +1 -0
- package/examples/auto-pipeline/public/vercel.svg +1 -0
- package/examples/auto-pipeline/tailwind.config.ts +20 -0
- package/examples/auto-pipeline/tsconfig.json +26 -0
- package/examples/aws-cdk-python/README.md +36 -0
- package/examples/aws-cdk-python/cdk.json +72 -0
- package/examples/aws-cdk-python/jest.config.js +8 -0
- package/examples/aws-cdk-python/lib/api/index.py +10 -0
- package/examples/aws-cdk-python/lib/api/requirements.txt +1 -0
- package/examples/aws-cdk-python/package-lock.json +4470 -0
- package/examples/aws-cdk-python/package.json +27 -0
- package/examples/aws-cdk-python/tsconfig.json +31 -0
- package/examples/aws-cdk-typescript/README.md +36 -0
- package/examples/aws-cdk-typescript/cdk.json +72 -0
- package/examples/aws-cdk-typescript/jest.config.js +8 -0
- package/examples/aws-cdk-typescript/package-lock.json +4548 -0
- package/examples/aws-cdk-typescript/package.json +28 -0
- package/examples/aws-cdk-typescript/tsconfig.json +31 -0
- package/examples/aws-lambda/README.md +39 -0
- package/examples/aws-lambda/index.js +11 -0
- package/examples/aws-lambda/package-lock.json +27 -0
- package/examples/aws-lambda/package.json +6 -0
- package/examples/aws-sam/README.md +34 -0
- package/examples/aws-sam/__init__.py +0 -0
- package/examples/aws-sam/events/event.json +62 -0
- package/examples/aws-sam/hello_world/__init__.py +0 -0
- package/examples/aws-sam/hello_world/app.py +10 -0
- package/examples/aws-sam/hello_world/requirements.txt +2 -0
- package/examples/aws-sam/samconfig.toml +34 -0
- package/examples/aws-sam/template.yaml +52 -0
- package/examples/aws-sam/tests/__init__.py +0 -0
- package/examples/aws-sam/tests/integration/__init__.py +0 -0
- package/examples/aws-sam/tests/integration/test_api_gateway.py +45 -0
- package/examples/aws-sam/tests/requirements.txt +3 -0
- package/examples/aws-sam/tests/unit/__init__.py +0 -0
- package/examples/aws-sam/tests/unit/test_handler.py +72 -0
- package/examples/azure-functions/.funcignore +10 -0
- package/examples/azure-functions/.vscode/extensions.json +5 -0
- package/examples/azure-functions/README.md +67 -0
- package/examples/azure-functions/host.json +15 -0
- package/examples/azure-functions/package-lock.json +1019 -0
- package/examples/azure-functions/package.json +24 -0
- package/examples/azure-functions/src/functions/CounterFunction.ts +19 -0
- package/examples/azure-functions/tsconfig.json +10 -0
- package/examples/cloudflare-workers/README.md +26 -0
- package/examples/cloudflare-workers/bun.lockb +0 -0
- package/examples/cloudflare-workers/ci.test.ts +18 -0
- package/examples/cloudflare-workers/index.js +11 -0
- package/examples/cloudflare-workers/package.json +17 -0
- package/examples/cloudflare-workers/wrangler.toml +11 -0
- package/examples/cloudflare-workers-with-typescript/README.md +26 -0
- package/examples/cloudflare-workers-with-typescript/ci.test.ts +17 -0
- package/examples/cloudflare-workers-with-typescript/package.json +17 -0
- package/examples/cloudflare-workers-with-typescript/src/index.ts +16 -0
- package/examples/cloudflare-workers-with-typescript/tsconfig.json +105 -0
- package/examples/cloudflare-workers-with-typescript/wrangler.toml +9 -0
- package/examples/deno/main.test.ts +16 -0
- package/examples/deno/main.ts +9 -0
- package/examples/fastapi/README.md +23 -0
- package/examples/fastapi/main.py +12 -0
- package/examples/fastapi/requirements.txt +2 -0
- package/examples/fastly/README.md +7 -0
- package/examples/fastly/fastly.toml +12 -0
- package/examples/fastly/package.json +23 -0
- package/examples/fastly/src/index.js +19 -0
- package/examples/fastly/webpack.config.js +28 -0
- package/examples/google-cloud-functions/README.md +37 -0
- package/examples/google-cloud-functions/index.js +12 -0
- package/examples/google-cloud-functions/package.json +7 -0
- package/examples/ion/.env.example +2 -0
- package/examples/ion/.eslintrc.json +3 -0
- package/examples/ion/README.md +49 -0
- package/examples/ion/app/favicon.ico +0 -0
- package/examples/ion/app/globals.css +33 -0
- package/examples/ion/app/layout.tsx +22 -0
- package/examples/ion/app/page.tsx +12 -0
- package/examples/ion/next.config.mjs +4 -0
- package/examples/ion/package-lock.json +6709 -0
- package/examples/ion/package.json +28 -0
- package/examples/ion/postcss.config.mjs +8 -0
- package/examples/ion/public/next.svg +1 -0
- package/examples/ion/public/vercel.svg +1 -0
- package/examples/ion/sst-env.d.ts +12 -0
- package/examples/ion/sst.config.ts +19 -0
- package/examples/ion/tailwind.config.ts +20 -0
- package/examples/ion/tsconfig.json +26 -0
- package/examples/nextjs-app-router/.env.example +2 -0
- package/examples/nextjs-app-router/.eslintrc.json +3 -0
- package/examples/nextjs-app-router/README.md +26 -0
- package/examples/nextjs-app-router/app/globals.css +3 -0
- package/examples/nextjs-app-router/app/layout.tsx +22 -0
- package/examples/nextjs-app-router/app/page.tsx +12 -0
- package/examples/nextjs-app-router/next.config.mjs +4 -0
- package/examples/nextjs-app-router/package.json +27 -0
- package/examples/nextjs-app-router/postcss.config.mjs +8 -0
- package/examples/nextjs-app-router/tailwind.config.ts +20 -0
- package/examples/nextjs-app-router/tsconfig.json +26 -0
- package/examples/nextjs-pages-router/.env.example +2 -0
- package/examples/nextjs-pages-router/.eslintrc.json +3 -0
- package/examples/nextjs-pages-router/README.md +26 -0
- package/examples/nextjs-pages-router/next.config.mjs +6 -0
- package/examples/nextjs-pages-router/package.json +27 -0
- package/examples/nextjs-pages-router/pages/_app.tsx +6 -0
- package/examples/nextjs-pages-router/pages/_document.tsx +13 -0
- package/examples/nextjs-pages-router/pages/api/hello.ts +13 -0
- package/examples/nextjs-pages-router/pages/index.tsx +19 -0
- package/examples/nextjs-pages-router/postcss.config.mjs +8 -0
- package/examples/nextjs-pages-router/styles/globals.css +3 -0
- package/examples/nextjs-pages-router/tailwind.config.ts +20 -0
- package/examples/nextjs-pages-router/tsconfig.json +21 -0
- package/examples/nodejs/.env.example +2 -0
- package/examples/nodejs/README.md +24 -0
- package/examples/nodejs/index.js +10 -0
- package/examples/nodejs/package.json +10 -0
- package/examples/serverless-framework/counter/.env.example +2 -0
- package/examples/serverless-framework/counter/README.md +38 -0
- package/examples/serverless-framework/counter/handler.js +12 -0
- package/examples/serverless-framework/counter/package-lock.json +27 -0
- package/examples/serverless-framework/counter/package.json +6 -0
- package/examples/serverless-framework/counter/serverless.yml +16 -0
- package/examples/sst-v2/.vscode/launch.json +15 -0
- package/examples/sst-v2/.vscode/settings.json +5 -0
- package/examples/sst-v2/README.md +62 -0
- package/examples/sst-v2/package.json +27 -0
- package/examples/sst-v2/packages/core/package.json +14 -0
- package/examples/sst-v2/packages/core/sst-env.d.ts +1 -0
- package/examples/sst-v2/packages/core/tsconfig.json +7 -0
- package/examples/sst-v2/packages/functions/package.json +15 -0
- package/examples/sst-v2/packages/functions/sst-env.d.ts +1 -0
- package/examples/sst-v2/packages/functions/tsconfig.json +11 -0
- package/examples/sst-v2/packages/web/README.md +40 -0
- package/examples/sst-v2/packages/web/next.config.mjs +6 -0
- package/examples/sst-v2/packages/web/package.json +23 -0
- package/examples/sst-v2/packages/web/pages/_app.tsx +6 -0
- package/examples/sst-v2/packages/web/pages/_document.tsx +13 -0
- package/examples/sst-v2/packages/web/pages/api/hello.ts +16 -0
- package/examples/sst-v2/packages/web/pages/index.tsx +114 -0
- package/examples/sst-v2/packages/web/public/favicon.ico +0 -0
- package/examples/sst-v2/packages/web/public/next.svg +1 -0
- package/examples/sst-v2/packages/web/public/vercel.svg +1 -0
- package/examples/sst-v2/packages/web/sst-env.d.ts +1 -0
- package/examples/sst-v2/packages/web/styles/Home.module.css +229 -0
- package/examples/sst-v2/packages/web/styles/globals.css +107 -0
- package/examples/sst-v2/packages/web/tsconfig.json +36 -0
- package/examples/sst-v2/pnpm-workspace.yaml +2 -0
- package/examples/sst-v2/sst.config.ts +14 -0
- package/examples/sst-v2/stacks/Default.ts +13 -0
- package/examples/sst-v2/tsconfig.json +8 -0
- package/examples/terraform/README.md +38 -0
- package/examples/terraform/counter/counter.js +11 -0
- package/examples/terraform/counter/package.json +6 -0
- package/examples/terraform/main.tf +166 -0
- package/examples/terraform/outputs.tf +17 -0
- package/examples/terraform/terraform.tf +18 -0
- package/examples/terraform/variables.tf +6 -0
- package/examples/vercel-functions-app-router/.env.example +2 -0
- package/examples/vercel-functions-app-router/.eslintrc.json +3 -0
- package/examples/vercel-functions-app-router/README.md +26 -0
- package/examples/vercel-functions-app-router/app/api/hello/route.ts +11 -0
- package/examples/vercel-functions-app-router/app/globals.css +3 -0
- package/examples/vercel-functions-app-router/app/layout.tsx +22 -0
- package/examples/vercel-functions-app-router/ci.test.ts +14 -0
- package/examples/vercel-functions-app-router/next.config.mjs +4 -0
- package/examples/vercel-functions-app-router/package.json +27 -0
- package/examples/vercel-functions-app-router/postcss.config.mjs +8 -0
- package/examples/vercel-functions-app-router/tailwind.config.ts +20 -0
- package/examples/vercel-functions-app-router/tsconfig.json +26 -0
- package/examples/vercel-functions-pages-router/.env.example +2 -0
- package/examples/vercel-functions-pages-router/.eslintrc.json +3 -0
- package/examples/vercel-functions-pages-router/README.md +26 -0
- package/examples/vercel-functions-pages-router/ci.test.ts +14 -0
- package/examples/vercel-functions-pages-router/next.config.mjs +6 -0
- package/examples/vercel-functions-pages-router/package.json +27 -0
- package/examples/vercel-functions-pages-router/pages/_app.tsx +6 -0
- package/examples/vercel-functions-pages-router/pages/_document.tsx +13 -0
- package/examples/vercel-functions-pages-router/pages/api/hello.ts +12 -0
- package/examples/vercel-functions-pages-router/postcss.config.mjs +8 -0
- package/examples/vercel-functions-pages-router/styles/globals.css +3 -0
- package/examples/vercel-functions-pages-router/tailwind.config.ts +20 -0
- package/examples/vercel-functions-pages-router/tsconfig.json +21 -0
- package/examples/vercel-python-runtime-django/.env.example +2 -0
- package/examples/vercel-python-runtime-django/README.md +34 -0
- package/examples/vercel-python-runtime-django/api/__init__.py +0 -0
- package/examples/vercel-python-runtime-django/api/asgi.py +16 -0
- package/examples/vercel-python-runtime-django/api/settings.py +121 -0
- package/examples/vercel-python-runtime-django/api/urls.py +22 -0
- package/examples/vercel-python-runtime-django/api/wsgi.py +16 -0
- package/examples/vercel-python-runtime-django/example/__init__.py +0 -0
- package/examples/vercel-python-runtime-django/example/admin.py +3 -0
- package/examples/vercel-python-runtime-django/example/apps.py +6 -0
- package/examples/vercel-python-runtime-django/example/urls.py +9 -0
- package/examples/vercel-python-runtime-django/example/views.py +18 -0
- package/examples/vercel-python-runtime-django/manage.py +22 -0
- package/examples/vercel-python-runtime-django/package.json +5 -0
- package/examples/vercel-python-runtime-django/requirements.txt +2 -0
- package/examples/vercel-python-runtime-django/vercel.json +8 -0
- package/examples/with-sentry/index.ts +36 -0
- package/examples/with-sentry/package.json +17 -0
- package/package.json +1 -1
- package/pkg/auto-pipeline.test.ts +321 -0
- package/pkg/auto-pipeline.ts +107 -0
- package/pkg/commands/append.test.ts +28 -0
- package/pkg/commands/append.ts +11 -0
- package/pkg/commands/bitcount.test.ts +37 -0
- package/pkg/commands/bitcount.ts +29 -0
- package/pkg/commands/bitfield.test.ts +51 -0
- package/pkg/commands/bitfield.ts +50 -0
- package/pkg/commands/bitop.test.ts +45 -0
- package/pkg/commands/bitop.ts +22 -0
- package/pkg/commands/bitpos.test.ts +47 -0
- package/pkg/commands/bitpos.ts +14 -0
- package/pkg/commands/command.test.ts +22 -0
- package/pkg/commands/command.ts +98 -0
- package/pkg/commands/copy.test.ts +65 -0
- package/pkg/commands/copy.ts +22 -0
- package/pkg/commands/dbsize.test.ts +18 -0
- package/pkg/commands/dbsize.ts +11 -0
- package/pkg/commands/decr.test.ts +23 -0
- package/pkg/commands/decr.ts +11 -0
- package/pkg/commands/decrby.test.ts +24 -0
- package/pkg/commands/decrby.ts +11 -0
- package/pkg/commands/del.test.ts +38 -0
- package/pkg/commands/del.ts +11 -0
- package/pkg/commands/echo.test.ts +11 -0
- package/pkg/commands/echo.ts +11 -0
- package/pkg/commands/eval.test.ts +30 -0
- package/pkg/commands/eval.ts +14 -0
- package/pkg/commands/evalsha.test.ts +19 -0
- package/pkg/commands/evalsha.ts +14 -0
- package/pkg/commands/exists.test.ts +38 -0
- package/pkg/commands/exists.ts +11 -0
- package/pkg/commands/expire.test.ts +119 -0
- package/pkg/commands/expire.ts +12 -0
- package/pkg/commands/expireat.test.ts +25 -0
- package/pkg/commands/expireat.ts +11 -0
- package/pkg/commands/flushall.test.ts +18 -0
- package/pkg/commands/flushall.ts +14 -0
- package/pkg/commands/flushdb.test.ts +17 -0
- package/pkg/commands/flushdb.ts +14 -0
- package/pkg/commands/geo_add.test.ts +202 -0
- package/pkg/commands/geo_add.ts +54 -0
- package/pkg/commands/geo_dist.test.ts +79 -0
- package/pkg/commands/geo_dist.ts +19 -0
- package/pkg/commands/geo_hash.test.ts +49 -0
- package/pkg/commands/geo_hash.ts +23 -0
- package/pkg/commands/geo_pos.test.ts +60 -0
- package/pkg/commands/geo_pos.ts +39 -0
- package/pkg/commands/geo_search.test.ts +197 -0
- package/pkg/commands/geo_search.ts +139 -0
- package/pkg/commands/geo_search_store.test.ts +153 -0
- package/pkg/commands/geo_search_store.ts +69 -0
- package/pkg/commands/get.test.ts +35 -0
- package/pkg/commands/get.ts +11 -0
- package/pkg/commands/getbit.test.ts +17 -0
- package/pkg/commands/getbit.ts +11 -0
- package/pkg/commands/getdel.test.ts +39 -0
- package/pkg/commands/getdel.ts +11 -0
- package/pkg/commands/getrange.test.ts +25 -0
- package/pkg/commands/getrange.ts +14 -0
- package/pkg/commands/getset.test.ts +33 -0
- package/pkg/commands/getset.ts +14 -0
- package/pkg/commands/hdel.test.ts +45 -0
- package/pkg/commands/hdel.ts +11 -0
- package/pkg/commands/hexists.test.ts +36 -0
- package/pkg/commands/hexists.ts +11 -0
- package/pkg/commands/hget.test.ts +52 -0
- package/pkg/commands/hget.ts +14 -0
- package/pkg/commands/hgetall.test.ts +45 -0
- package/pkg/commands/hgetall.ts +37 -0
- package/pkg/commands/hincrby.test.ts +28 -0
- package/pkg/commands/hincrby.ts +14 -0
- package/pkg/commands/hincrbyfloat.test.ts +28 -0
- package/pkg/commands/hincrbyfloat.ts +14 -0
- package/pkg/commands/hkeys.test.ts +23 -0
- package/pkg/commands/hkeys.ts +11 -0
- package/pkg/commands/hlen.test.ts +25 -0
- package/pkg/commands/hlen.ts +11 -0
- package/pkg/commands/hmget.test.ts +44 -0
- package/pkg/commands/hmget.ts +46 -0
- package/pkg/commands/hmset.test.ts +23 -0
- package/pkg/commands/hmset.ts +14 -0
- package/pkg/commands/hrandfield.test.ts +59 -0
- package/pkg/commands/hrandfield.ts +50 -0
- package/pkg/commands/hscan.test.ts +44 -0
- package/pkg/commands/hscan.ts +30 -0
- package/pkg/commands/hset.test.ts +21 -0
- package/pkg/commands/hset.ts +14 -0
- package/pkg/commands/hsetnx.test.ts +37 -0
- package/pkg/commands/hsetnx.ts +14 -0
- package/pkg/commands/hstrlen.test.ts +24 -0
- package/pkg/commands/hstrlen.ts +11 -0
- package/pkg/commands/hvals.test.ts +24 -0
- package/pkg/commands/hvals.ts +11 -0
- package/pkg/commands/incr.test.ts +24 -0
- package/pkg/commands/incr.ts +11 -0
- package/pkg/commands/incrby.test.ts +24 -0
- package/pkg/commands/incrby.ts +11 -0
- package/pkg/commands/incrbyfloat.test.ts +25 -0
- package/pkg/commands/incrbyfloat.ts +11 -0
- package/pkg/commands/json_arrappend.test.ts +40 -0
- package/pkg/commands/json_arrappend.ts +17 -0
- package/pkg/commands/json_arrindex.test.ts +54 -0
- package/pkg/commands/json_arrindex.ts +14 -0
- package/pkg/commands/json_arrinsert.test.ts +49 -0
- package/pkg/commands/json_arrinsert.ts +17 -0
- package/pkg/commands/json_arrlen.test.ts +31 -0
- package/pkg/commands/json_arrlen.ts +14 -0
- package/pkg/commands/json_arrpop.test.ts +30 -0
- package/pkg/commands/json_arrpop.ts +14 -0
- package/pkg/commands/json_arrtrim.test.ts +31 -0
- package/pkg/commands/json_arrtrim.ts +18 -0
- package/pkg/commands/json_clear.test.ts +35 -0
- package/pkg/commands/json_clear.ts +11 -0
- package/pkg/commands/json_del.test.ts +29 -0
- package/pkg/commands/json_del.ts +11 -0
- package/pkg/commands/json_forget.test.ts +29 -0
- package/pkg/commands/json_forget.ts +11 -0
- package/pkg/commands/json_get.test.ts +28 -0
- package/pkg/commands/json_get.ts +44 -0
- package/pkg/commands/json_mget.test.ts +43 -0
- package/pkg/commands/json_mget.ts +11 -0
- package/pkg/commands/json_mset.test.ts +50 -0
- package/pkg/commands/json_mset.ts +26 -0
- package/pkg/commands/json_numincrby.test.ts +28 -0
- package/pkg/commands/json_numincrby.ts +14 -0
- package/pkg/commands/json_nummultby.test.ts +28 -0
- package/pkg/commands/json_nummultby.ts +14 -0
- package/pkg/commands/json_objkeys.test.ts +32 -0
- package/pkg/commands/json_objkeys.ts +14 -0
- package/pkg/commands/json_objlen.test.ts +26 -0
- package/pkg/commands/json_objlen.ts +14 -0
- package/pkg/commands/json_resp.test.ts +31 -0
- package/pkg/commands/json_resp.ts +11 -0
- package/pkg/commands/json_set.test.ts +48 -0
- package/pkg/commands/json_set.ts +34 -0
- package/pkg/commands/json_strappend.test.ts +34 -0
- package/pkg/commands/json_strappend.ts +14 -0
- package/pkg/commands/json_strlen.test.ts +27 -0
- package/pkg/commands/json_strlen.ts +14 -0
- package/pkg/commands/json_toggle.test.ts +26 -0
- package/pkg/commands/json_toggle.ts +11 -0
- package/pkg/commands/json_type.test.ts +29 -0
- package/pkg/commands/json_type.ts +11 -0
- package/pkg/commands/keys.test.ts +18 -0
- package/pkg/commands/keys.ts +11 -0
- package/pkg/commands/lindex.test.ts +33 -0
- package/pkg/commands/lindex.ts +11 -0
- package/pkg/commands/linsert.test.ts +24 -0
- package/pkg/commands/linsert.ts +10 -0
- package/pkg/commands/llen.test.ts +27 -0
- package/pkg/commands/llen.ts +11 -0
- package/pkg/commands/lmove.test.ts +48 -0
- package/pkg/commands/lmove.ts +19 -0
- package/pkg/commands/lmpop.test.ts +86 -0
- package/pkg/commands/lmpop.ts +19 -0
- package/pkg/commands/lpop.test.ts +40 -0
- package/pkg/commands/lpop.ts +14 -0
- package/pkg/commands/lpos.test.ts +56 -0
- package/pkg/commands/lpos.ts +25 -0
- package/pkg/commands/lpush.test.ts +18 -0
- package/pkg/commands/lpush.ts +11 -0
- package/pkg/commands/lpushx.test.ts +30 -0
- package/pkg/commands/lpushx.ts +11 -0
- package/pkg/commands/lrange.test.ts +21 -0
- package/pkg/commands/lrange.ts +11 -0
- package/pkg/commands/lrem.test.ts +19 -0
- package/pkg/commands/lrem.ts +10 -0
- package/pkg/commands/lset.test.ts +43 -0
- package/pkg/commands/lset.ts +8 -0
- package/pkg/commands/ltrim.test.ts +30 -0
- package/pkg/commands/ltrim.ts +8 -0
- package/pkg/commands/mget.test.ts +44 -0
- package/pkg/commands/mget.ts +11 -0
- package/pkg/commands/mod.ts +168 -0
- package/pkg/commands/mset.test.ts +24 -0
- package/pkg/commands/mset.ts +11 -0
- package/pkg/commands/msetnx.test.ts +46 -0
- package/pkg/commands/msetnx.ts +11 -0
- package/pkg/commands/persist.test.ts +22 -0
- package/pkg/commands/persist.ts +11 -0
- package/pkg/commands/pexpire.test.ts +24 -0
- package/pkg/commands/pexpire.ts +11 -0
- package/pkg/commands/pexpireat.test.ts +31 -0
- package/pkg/commands/pexpireat.ts +11 -0
- package/pkg/commands/pfadd.test.ts +80 -0
- package/pkg/commands/pfadd.ts +11 -0
- package/pkg/commands/pfcount.test.ts +55 -0
- package/pkg/commands/pfcount.ts +11 -0
- package/pkg/commands/pfmerge.test.ts +67 -0
- package/pkg/commands/pfmerge.ts +11 -0
- package/pkg/commands/ping.test.ts +19 -0
- package/pkg/commands/ping.ts +14 -0
- package/pkg/commands/psetex.test.ts +23 -0
- package/pkg/commands/psetex.ts +14 -0
- package/pkg/commands/pttl.test.ts +18 -0
- package/pkg/commands/pttl.ts +11 -0
- package/pkg/commands/publish.test.ts +12 -0
- package/pkg/commands/publish.ts +11 -0
- package/pkg/commands/randomkey.test.ts +16 -0
- package/pkg/commands/randomkey.ts +11 -0
- package/pkg/commands/rename.test.ts +19 -0
- package/pkg/commands/rename.ts +11 -0
- package/pkg/commands/renamenx.test.ts +33 -0
- package/pkg/commands/renamenx.ts +11 -0
- package/pkg/commands/rpop.test.ts +40 -0
- package/pkg/commands/rpop.ts +17 -0
- package/pkg/commands/rpush.test.ts +17 -0
- package/pkg/commands/rpush.ts +11 -0
- package/pkg/commands/rpushx.test.ts +30 -0
- package/pkg/commands/rpushx.ts +11 -0
- package/pkg/commands/sadd.test.ts +22 -0
- package/pkg/commands/sadd.ts +14 -0
- package/pkg/commands/scan.test.ts +91 -0
- package/pkg/commands/scan.ts +33 -0
- package/pkg/commands/scard.test.ts +16 -0
- package/pkg/commands/scard.ts +10 -0
- package/pkg/commands/script_exists.test.ts +34 -0
- package/pkg/commands/script_exists.ts +14 -0
- package/pkg/commands/script_flush.ts +21 -0
- package/pkg/commands/script_load.test.ts +11 -0
- package/pkg/commands/script_load.ts +11 -0
- package/pkg/commands/sdiff.test.ts +20 -0
- package/pkg/commands/sdiff.ts +10 -0
- package/pkg/commands/sdiffstore.test.ts +22 -0
- package/pkg/commands/sdiffstore.ts +13 -0
- package/pkg/commands/set.test.ts +168 -0
- package/pkg/commands/set.ts +51 -0
- package/pkg/commands/setbit.test.ts +17 -0
- package/pkg/commands/setbit.ts +14 -0
- package/pkg/commands/setex.test.ts +22 -0
- package/pkg/commands/setex.ts +11 -0
- package/pkg/commands/setnx.test.ts +27 -0
- package/pkg/commands/setnx.ts +11 -0
- package/pkg/commands/setrange.test.ts +25 -0
- package/pkg/commands/setrange.ts +14 -0
- package/pkg/commands/sinter.test.ts +37 -0
- package/pkg/commands/sinter.ts +10 -0
- package/pkg/commands/sinterstore.test.ts +22 -0
- package/pkg/commands/sinterstore.ts +13 -0
- package/pkg/commands/sismember.test.ts +31 -0
- package/pkg/commands/sismember.ts +10 -0
- package/pkg/commands/smembers.test.ts +22 -0
- package/pkg/commands/smembers.ts +11 -0
- package/pkg/commands/smismember.test.ts +22 -0
- package/pkg/commands/smismember.ts +16 -0
- package/pkg/commands/smove.test.ts +18 -0
- package/pkg/commands/smove.ts +13 -0
- package/pkg/commands/spop.test.ts +36 -0
- package/pkg/commands/spop.ts +17 -0
- package/pkg/commands/srandmember.test.ts +31 -0
- package/pkg/commands/srandmember.ts +17 -0
- package/pkg/commands/srem.test.ts +19 -0
- package/pkg/commands/srem.ts +10 -0
- package/pkg/commands/sscan.test.ts +48 -0
- package/pkg/commands/sscan.ts +30 -0
- package/pkg/commands/strlen.test.ts +17 -0
- package/pkg/commands/strlen.ts +11 -0
- package/pkg/commands/sunion.test.ts +22 -0
- package/pkg/commands/sunion.ts +11 -0
- package/pkg/commands/sunionstore.test.ts +30 -0
- package/pkg/commands/sunionstore.ts +14 -0
- package/pkg/commands/time.test.ts +12 -0
- package/pkg/commands/time.ts +10 -0
- package/pkg/commands/touch.test.ts +21 -0
- package/pkg/commands/touch.ts +11 -0
- package/pkg/commands/ttl.test.ts +17 -0
- package/pkg/commands/ttl.ts +11 -0
- package/pkg/commands/type.test.ts +72 -0
- package/pkg/commands/type.ts +12 -0
- package/pkg/commands/types.ts +150 -0
- package/pkg/commands/unlink.test.ts +22 -0
- package/pkg/commands/unlink.ts +11 -0
- package/pkg/commands/xack.test.ts +53 -0
- package/pkg/commands/xack.ts +15 -0
- package/pkg/commands/xadd.test.ts +128 -0
- package/pkg/commands/xadd.ts +64 -0
- package/pkg/commands/xautoclaim.test.ts +105 -0
- package/pkg/commands/xautoclaim.ts +30 -0
- package/pkg/commands/xclaim.test.ts +70 -0
- package/pkg/commands/xclaim.ts +55 -0
- package/pkg/commands/xdel.test.ts +50 -0
- package/pkg/commands/xdel.ts +15 -0
- package/pkg/commands/xgroup.test.ts +202 -0
- package/pkg/commands/xgroup.ts +100 -0
- package/pkg/commands/xinfo.test.ts +82 -0
- package/pkg/commands/xinfo.ts +27 -0
- package/pkg/commands/xlen.test.ts +29 -0
- package/pkg/commands/xlen.ts +11 -0
- package/pkg/commands/xpending.test.ts +94 -0
- package/pkg/commands/xpending.ts +43 -0
- package/pkg/commands/xrange.test.ts +69 -0
- package/pkg/commands/xrange.ts +48 -0
- package/pkg/commands/xread.test.ts +117 -0
- package/pkg/commands/xread.ts +51 -0
- package/pkg/commands/xreadgroup.test.ts +166 -0
- package/pkg/commands/xreadgroup.ts +66 -0
- package/pkg/commands/xrevrange.test.ts +48 -0
- package/pkg/commands/xrevrange.ts +47 -0
- package/pkg/commands/xtrim.test.ts +65 -0
- package/pkg/commands/xtrim.ts +24 -0
- package/pkg/commands/zadd.test.ts +242 -0
- package/pkg/commands/zadd.ts +53 -0
- package/pkg/commands/zcard.test.ts +16 -0
- package/pkg/commands/zcard.ts +11 -0
- package/pkg/commands/zcount.test.ts +16 -0
- package/pkg/commands/zcount.ts +13 -0
- package/pkg/commands/zdiffstore.test.ts +42 -0
- package/pkg/commands/zdiffstore.ts +14 -0
- package/pkg/commands/zincrby.test.ts +19 -0
- package/pkg/commands/zincrby.ts +13 -0
- package/pkg/commands/zinterstore.test.ts +297 -0
- package/pkg/commands/zinterstore.ts +51 -0
- package/pkg/commands/zlexcount.test.ts +23 -0
- package/pkg/commands/zlexcount.ts +10 -0
- package/pkg/commands/zmscore.test.ts +39 -0
- package/pkg/commands/zmscore.ts +15 -0
- package/pkg/commands/zpopmax.test.ts +46 -0
- package/pkg/commands/zpopmax.ts +17 -0
- package/pkg/commands/zpopmin.test.ts +50 -0
- package/pkg/commands/zpopmin.ts +17 -0
- package/pkg/commands/zrange.test.ts +188 -0
- package/pkg/commands/zrange.ts +68 -0
- package/pkg/commands/zrank.test.ts +23 -0
- package/pkg/commands/zrank.ts +14 -0
- package/pkg/commands/zrem.test.ts +21 -0
- package/pkg/commands/zrem.ts +10 -0
- package/pkg/commands/zremrangebylex.test.ts +24 -0
- package/pkg/commands/zremrangebylex.ts +10 -0
- package/pkg/commands/zremrangebyrank.test.ts +27 -0
- package/pkg/commands/zremrangebyrank.ts +13 -0
- package/pkg/commands/zremrangebyscore.test.ts +24 -0
- package/pkg/commands/zremrangebyscore.ts +10 -0
- package/pkg/commands/zrevrank.test.ts +23 -0
- package/pkg/commands/zrevrank.ts +14 -0
- package/pkg/commands/zscan.test.ts +48 -0
- package/pkg/commands/zscan.ts +30 -0
- package/pkg/commands/zscore.test.ts +18 -0
- package/pkg/commands/zscore.ts +14 -0
- package/pkg/commands/zunion.test.ts +251 -0
- package/pkg/commands/zunion.ts +54 -0
- package/pkg/commands/zunionstore.test.ts +274 -0
- package/pkg/commands/zunionstore.ts +51 -0
- package/pkg/error.ts +18 -0
- package/pkg/http.ts +349 -0
- package/pkg/index.ts +1 -0
- package/pkg/pipeline.test.ts +254 -0
- package/pkg/pipeline.ts +1401 -0
- package/pkg/read-your-writes.test.ts +115 -0
- package/pkg/redis.test.ts +250 -0
- package/pkg/redis.ts +1367 -0
- package/pkg/script.test.ts +58 -0
- package/pkg/script.ts +67 -0
- package/pkg/test-utils.test.ts +17 -0
- package/pkg/test-utils.ts +72 -0
- package/pkg/types.ts +35 -0
- package/pkg/util.ts +42 -0
- package/platforms/cloudflare.ts +144 -0
- package/platforms/fastly.ts +100 -0
- package/platforms/nodejs.ts +196 -0
- package/prettier.config.mjs +13 -0
- package/tsconfig.json +21 -0
- package/tsup.config.ts +8 -0
- package/version.ts +1 -0
- package/chunk-JD7AT2OK.js +0 -1
- package/chunk-XCPX3L6C.mjs +0 -1
- package/cloudflare.d.mts +0 -50
- package/cloudflare.d.ts +0 -50
- package/cloudflare.js +0 -1
- package/cloudflare.mjs +0 -1
- package/fastly.d.mts +0 -43
- package/fastly.d.ts +0 -43
- package/fastly.js +0 -1
- package/fastly.mjs +0 -1
- package/nodejs.d.mts +0 -85
- package/nodejs.d.ts +0 -85
- package/nodejs.js +0 -1
- package/nodejs.mjs +0 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { Redis } from "./redis";
|
|
3
|
+
import { keygen, newHttpClient, randomID } from "./test-utils";
|
|
4
|
+
const client = newHttpClient();
|
|
5
|
+
|
|
6
|
+
const { cleanup } = keygen();
|
|
7
|
+
afterEach(cleanup);
|
|
8
|
+
|
|
9
|
+
describe("create a new script", () => {
|
|
10
|
+
test(
|
|
11
|
+
"creates a new script",
|
|
12
|
+
async () => {
|
|
13
|
+
const redis = new Redis(client);
|
|
14
|
+
const script = redis.createScript("return ARGV[1];");
|
|
15
|
+
|
|
16
|
+
const res = await script.eval([], ["Hello World"]);
|
|
17
|
+
expect(res).toEqual("Hello World");
|
|
18
|
+
},
|
|
19
|
+
{ timeout: 15_000 }
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe("sha1", () => {
|
|
24
|
+
test("calculates the correct sha1", () => {
|
|
25
|
+
const redis = new Redis(client);
|
|
26
|
+
const script = redis.createScript("The quick brown fox jumps over the lazy dog");
|
|
27
|
+
|
|
28
|
+
expect(script.sha1).toEqual("2fd4e1c67a2d28fced849ee1bb76e7391b93eb12");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("calculates the correct sha1 for empty string", () => {
|
|
32
|
+
const redis = new Redis(client);
|
|
33
|
+
const script = redis.createScript("");
|
|
34
|
+
|
|
35
|
+
expect(script.sha1).toEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709");
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe("script gets loaded", () => {
|
|
40
|
+
test("following evalsha command is a hit", async () => {
|
|
41
|
+
const id = randomID();
|
|
42
|
+
const s = `return "${id}";`;
|
|
43
|
+
const redis = new Redis(client);
|
|
44
|
+
const script = redis.createScript(s);
|
|
45
|
+
|
|
46
|
+
let hasThrown = false;
|
|
47
|
+
|
|
48
|
+
await script.evalsha([], []).catch(() => {
|
|
49
|
+
hasThrown = true;
|
|
50
|
+
});
|
|
51
|
+
expect(hasThrown).toBeTrue();
|
|
52
|
+
const res = await script.exec([], []);
|
|
53
|
+
expect(res).toEqual(id);
|
|
54
|
+
|
|
55
|
+
const res2 = await script.evalsha([], []);
|
|
56
|
+
expect(res2).toEqual(id);
|
|
57
|
+
});
|
|
58
|
+
});
|
package/pkg/script.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import Hex from "crypto-js/enc-hex.js";
|
|
2
|
+
import sha1 from "crypto-js/sha1.js";
|
|
3
|
+
import type { Redis } from "./redis";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a new script.
|
|
6
|
+
*
|
|
7
|
+
* Scripts offer the ability to optimistically try to execute a script without having to send the
|
|
8
|
+
* entire script to the server. If the script is loaded on the server, it tries again by sending
|
|
9
|
+
* the entire script. Afterwards, the script is cached on the server.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const redis = new Redis({...})
|
|
14
|
+
*
|
|
15
|
+
* const script = redis.createScript<string>("return ARGV[1];")
|
|
16
|
+
* const arg1 = await script.eval([], ["Hello World"])
|
|
17
|
+
* expect(arg1, "Hello World")
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export class Script<TResult = unknown> {
|
|
21
|
+
public readonly script: string;
|
|
22
|
+
public readonly sha1: string;
|
|
23
|
+
private readonly redis: Redis;
|
|
24
|
+
|
|
25
|
+
constructor(redis: Redis, script: string) {
|
|
26
|
+
this.redis = redis;
|
|
27
|
+
this.sha1 = this.digest(script);
|
|
28
|
+
this.script = script;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Send an `EVAL` command to redis.
|
|
33
|
+
*/
|
|
34
|
+
public async eval(keys: string[], args: string[]): Promise<TResult> {
|
|
35
|
+
return await this.redis.eval(this.script, keys, args);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Calculates the sha1 hash of the script and then calls `EVALSHA`.
|
|
40
|
+
*/
|
|
41
|
+
public async evalsha(keys: string[], args: string[]): Promise<TResult> {
|
|
42
|
+
return await this.redis.evalsha(this.sha1, keys, args);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Optimistically try to run `EVALSHA` first.
|
|
47
|
+
* If the script is not loaded in redis, it will fall back and try again with `EVAL`.
|
|
48
|
+
*
|
|
49
|
+
* Following calls will be able to use the cached script
|
|
50
|
+
*/
|
|
51
|
+
public async exec(keys: string[], args: string[]): Promise<TResult> {
|
|
52
|
+
const res = await this.redis.evalsha(this.sha1, keys, args).catch(async (error) => {
|
|
53
|
+
if (error instanceof Error && error.message.toLowerCase().includes("noscript")) {
|
|
54
|
+
return await this.redis.eval(this.script, keys, args);
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
});
|
|
58
|
+
return res as TResult;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Compute the sha1 hash of the script and return its hex representation.
|
|
63
|
+
*/
|
|
64
|
+
private digest(s: string): string {
|
|
65
|
+
return Hex.stringify(sha1(s));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { randomUnsafeIntegerString } from "./test-utils";
|
|
4
|
+
|
|
5
|
+
test("randomUnsafeIntegerString() should return a string", () => {
|
|
6
|
+
const result = randomUnsafeIntegerString();
|
|
7
|
+
expect(typeof result).toEqual("string");
|
|
8
|
+
});
|
|
9
|
+
test("randomUnsafeIntegerString() should return different values", () => {
|
|
10
|
+
const result1 = randomUnsafeIntegerString();
|
|
11
|
+
const result2 = randomUnsafeIntegerString();
|
|
12
|
+
expect(result1).not.toEqual(result2);
|
|
13
|
+
});
|
|
14
|
+
test("randomUnsafeIntegerString() should return a string with unsafe integer", () => {
|
|
15
|
+
const result = randomUnsafeIntegerString();
|
|
16
|
+
expect(Number.isSafeInteger(Number(result))).toBeFalse();
|
|
17
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { DelCommand } from "./commands/del";
|
|
2
|
+
import { XAddCommand } from "./commands/xadd";
|
|
3
|
+
import { HttpClient } from "./http";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* crypto.randomUUID() is not available in dnt crypto shim
|
|
7
|
+
*/
|
|
8
|
+
export function randomID(): string {
|
|
9
|
+
const bytes = new Uint8Array(32);
|
|
10
|
+
crypto.getRandomValues(bytes);
|
|
11
|
+
|
|
12
|
+
const s: string[] = [];
|
|
13
|
+
for (let i = 0; i < bytes.byteLength; i++) {
|
|
14
|
+
s.push(String.fromCodePoint(bytes[i]));
|
|
15
|
+
}
|
|
16
|
+
return btoa(s.join(""));
|
|
17
|
+
}
|
|
18
|
+
export const randomUnsafeIntegerString = (): string => {
|
|
19
|
+
const buffer = new Uint8Array(8);
|
|
20
|
+
crypto.getRandomValues(buffer);
|
|
21
|
+
const dataView = new DataView(buffer.buffer);
|
|
22
|
+
const unsafeInteger = dataView.getBigInt64(0, true); // true for little-endian
|
|
23
|
+
return unsafeInteger.toString();
|
|
24
|
+
};
|
|
25
|
+
export const newHttpClient = () => {
|
|
26
|
+
const url = process.env.UPSTASH_REDIS_REST_URL;
|
|
27
|
+
if (!url) {
|
|
28
|
+
throw new Error("Could not find url");
|
|
29
|
+
}
|
|
30
|
+
const token = process.env.UPSTASH_REDIS_REST_TOKEN;
|
|
31
|
+
if (!token) {
|
|
32
|
+
throw new Error("Could not find token");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return new HttpClient({
|
|
36
|
+
baseUrl: url,
|
|
37
|
+
headers: { authorization: `Bearer ${token}` },
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export function keygen(): {
|
|
42
|
+
newKey: () => string;
|
|
43
|
+
cleanup: () => Promise<void>;
|
|
44
|
+
} {
|
|
45
|
+
const keys: string[] = [];
|
|
46
|
+
return {
|
|
47
|
+
newKey: () => {
|
|
48
|
+
const key = randomID();
|
|
49
|
+
keys.push(key);
|
|
50
|
+
return key;
|
|
51
|
+
},
|
|
52
|
+
cleanup: async () => {
|
|
53
|
+
if (keys.length > 0) {
|
|
54
|
+
await new DelCommand(keys).exec(newHttpClient());
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export async function addNewItemToStream(streamKey: string, client: HttpClient) {
|
|
61
|
+
const field1 = "field1";
|
|
62
|
+
const member1 = randomID();
|
|
63
|
+
const field2 = "field2";
|
|
64
|
+
const member2 = randomID();
|
|
65
|
+
|
|
66
|
+
const res = await new XAddCommand([
|
|
67
|
+
streamKey,
|
|
68
|
+
"*",
|
|
69
|
+
{ [field1]: member1, [field2]: member2 },
|
|
70
|
+
]).exec(client);
|
|
71
|
+
return { member1, member2, streamId: res };
|
|
72
|
+
}
|
package/pkg/types.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type CommandArgs<TCommand extends new (..._args: any) => any> =
|
|
2
|
+
ConstructorParameters<TCommand>[0];
|
|
3
|
+
|
|
4
|
+
export type Telemetry = {
|
|
5
|
+
/**
|
|
6
|
+
* Upstash-Telemetry-Sdk
|
|
7
|
+
* @example @upstash/redis@v1.1.1
|
|
8
|
+
*/
|
|
9
|
+
sdk?: string;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Upstash-Telemetry-Platform
|
|
13
|
+
* @example cloudflare
|
|
14
|
+
*/
|
|
15
|
+
platform?: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Upstash-Telemetry-Runtime
|
|
19
|
+
* @example node@v18
|
|
20
|
+
*/
|
|
21
|
+
runtime?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type RedisOptions = {
|
|
25
|
+
/**
|
|
26
|
+
* Automatically try to deserialize the returned data from upstash using `JSON.deserialize`
|
|
27
|
+
*
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
automaticDeserialization?: boolean;
|
|
31
|
+
latencyLogging?: boolean;
|
|
32
|
+
enableTelemetry?: boolean;
|
|
33
|
+
enableAutoPipelining?: boolean;
|
|
34
|
+
readYourWrites?: boolean;
|
|
35
|
+
};
|
package/pkg/util.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
function parseRecursive(obj: unknown): unknown {
|
|
2
|
+
const parsed = Array.isArray(obj)
|
|
3
|
+
? obj.map((o) => {
|
|
4
|
+
try {
|
|
5
|
+
return parseRecursive(o);
|
|
6
|
+
} catch {
|
|
7
|
+
return o;
|
|
8
|
+
}
|
|
9
|
+
})
|
|
10
|
+
: JSON.parse(obj as string);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Parsing very large numbers can result in MAX_SAFE_INTEGER
|
|
14
|
+
* overflow. In that case we return the number as string instead.
|
|
15
|
+
*/
|
|
16
|
+
if (typeof parsed === "number" && parsed.toString() !== obj) {
|
|
17
|
+
return obj;
|
|
18
|
+
}
|
|
19
|
+
return parsed;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function parseResponse<TResult>(result: unknown): TResult {
|
|
23
|
+
try {
|
|
24
|
+
/**
|
|
25
|
+
* Try to parse the response if possible
|
|
26
|
+
*/
|
|
27
|
+
return parseRecursive(result) as TResult;
|
|
28
|
+
} catch {
|
|
29
|
+
return result as TResult;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Deserializes a scan result, excluding the cursor
|
|
35
|
+
* which can be string "0" or a big number string.
|
|
36
|
+
* Either way, we want it to stay as a string.
|
|
37
|
+
*
|
|
38
|
+
* @param result
|
|
39
|
+
*/
|
|
40
|
+
export function deserializeScanResponse<TResult>(result: [string, ...any]): TResult {
|
|
41
|
+
return [result[0], ...parseResponse<any[]>(result.slice(1))] as TResult;
|
|
42
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
|
+
import type { RequesterConfig } from "../pkg/http";
|
|
3
|
+
import { HttpClient } from "../pkg/http";
|
|
4
|
+
import * as core from "../pkg/redis";
|
|
5
|
+
import { VERSION } from "../version";
|
|
6
|
+
|
|
7
|
+
type Env = {
|
|
8
|
+
UPSTASH_DISABLE_TELEMETRY?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export * as errors from "../pkg/error";
|
|
12
|
+
export type * from "../pkg/commands/types";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Connection credentials for upstash redis.
|
|
16
|
+
* Get them from https://console.upstash.com/redis/<uuid>
|
|
17
|
+
*/
|
|
18
|
+
export type RedisConfigCloudflare = {
|
|
19
|
+
/**
|
|
20
|
+
* UPSTASH_REDIS_REST_URL
|
|
21
|
+
*/
|
|
22
|
+
url: string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* UPSTASH_REDIS_REST_TOKEN
|
|
25
|
+
*/
|
|
26
|
+
token: string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* The signal will allow aborting requests on the fly.
|
|
29
|
+
* For more check: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
|
|
30
|
+
*/
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
keepAlive?: boolean;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* When this flag is enabled, any subsequent commands issued by this client are guaranteed to observe the effects of all earlier writes submitted by the same client.
|
|
36
|
+
*/
|
|
37
|
+
readYourWrites?: boolean;
|
|
38
|
+
} & core.RedisOptions &
|
|
39
|
+
RequesterConfig &
|
|
40
|
+
Env;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Serverless redis client for upstash.
|
|
44
|
+
*/
|
|
45
|
+
export class Redis extends core.Redis {
|
|
46
|
+
/**
|
|
47
|
+
* Create a new redis client
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const redis = new Redis({
|
|
52
|
+
* url: "<UPSTASH_REDIS_REST_URL>",
|
|
53
|
+
* token: "<UPSTASH_REDIS_REST_TOKEN>",
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
constructor(config: RedisConfigCloudflare, env?: Env) {
|
|
58
|
+
if (!config.url) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`[Upstash Redis] The 'url' property is missing or undefined in your Redis config.`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!config.token) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`[Upstash Redis] The 'token' property is missing or undefined in your Redis config.`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (config.url.startsWith(" ") || config.url.endsWith(" ") || /\r|\n/.test(config.url)) {
|
|
71
|
+
console.warn("The redis url contains whitespace or newline, which can cause errors!");
|
|
72
|
+
}
|
|
73
|
+
if (config.token.startsWith(" ") || config.token.endsWith(" ") || /\r|\n/.test(config.token)) {
|
|
74
|
+
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const client = new HttpClient({
|
|
78
|
+
retry: config.retry,
|
|
79
|
+
baseUrl: config.url,
|
|
80
|
+
headers: { authorization: `Bearer ${config.token}` },
|
|
81
|
+
responseEncoding: config.responseEncoding,
|
|
82
|
+
signal: config.signal,
|
|
83
|
+
keepAlive: config.keepAlive,
|
|
84
|
+
readYourWrites: config.readYourWrites,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
super(client, {
|
|
88
|
+
enableTelemetry: !env?.UPSTASH_DISABLE_TELEMETRY,
|
|
89
|
+
automaticDeserialization: config.automaticDeserialization,
|
|
90
|
+
latencyLogging: config.latencyLogging,
|
|
91
|
+
enableAutoPipelining: config.enableAutoPipelining,
|
|
92
|
+
});
|
|
93
|
+
// This is only added of the user has not disabled telemetry
|
|
94
|
+
this.addTelemetry({
|
|
95
|
+
platform: "cloudflare",
|
|
96
|
+
sdk: `@upstash/redis@${VERSION}`,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
if (this.enableAutoPipelining) {
|
|
100
|
+
return this.autoPipeline();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/*
|
|
105
|
+
* Create a new Upstash Redis instance from environment variables on cloudflare.
|
|
106
|
+
*
|
|
107
|
+
* This tries to load `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` from
|
|
108
|
+
* the global namespace
|
|
109
|
+
*
|
|
110
|
+
* If you are using a module worker, please pass in the `env` object.
|
|
111
|
+
* ```ts
|
|
112
|
+
* const redis = Redis.fromEnv(env)
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
static fromEnv(
|
|
116
|
+
env?: {
|
|
117
|
+
UPSTASH_REDIS_REST_URL: string;
|
|
118
|
+
UPSTASH_REDIS_REST_TOKEN: string;
|
|
119
|
+
UPSTASH_DISABLE_TELEMETRY?: string;
|
|
120
|
+
},
|
|
121
|
+
opts?: Omit<RedisConfigCloudflare, "url" | "token">
|
|
122
|
+
): Redis {
|
|
123
|
+
// @ts-expect-error These will be defined by cloudflare
|
|
124
|
+
const url = env?.UPSTASH_REDIS_REST_URL ?? UPSTASH_REDIS_REST_URL;
|
|
125
|
+
|
|
126
|
+
// @ts-expect-error These will be defined by cloudflare
|
|
127
|
+
const token = env?.UPSTASH_REDIS_REST_TOKEN ?? UPSTASH_REDIS_REST_TOKEN;
|
|
128
|
+
|
|
129
|
+
if (!url) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
"Unable to find environment variable: `UPSTASH_REDIS_REST_URL`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_URL`"
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
if (!token) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
"Unable to find environment variable: `UPSTASH_REDIS_REST_TOKEN`. Please add it via `wrangler secret put UPSTASH_REDIS_REST_TOKEN`"
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return new Redis({ ...opts, url, token }, env);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export { type Requester, type UpstashRequest, type UpstashResponse } from "../pkg/http";
|
|
144
|
+
export { type Pipeline } from "../pkg/pipeline";
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { RequesterConfig } from "../pkg/http";
|
|
2
|
+
|
|
3
|
+
import { HttpClient } from "../pkg/http";
|
|
4
|
+
import * as core from "../pkg/redis";
|
|
5
|
+
import { VERSION } from "../version";
|
|
6
|
+
|
|
7
|
+
export * as errors from "../pkg/error";
|
|
8
|
+
export type * from "../pkg/commands/types";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Connection credentials for upstash redis.
|
|
12
|
+
* Get them from https://console.upstash.com/redis/<uuid>
|
|
13
|
+
*/
|
|
14
|
+
export type RedisConfigFastly = {
|
|
15
|
+
/**
|
|
16
|
+
* UPSTASH_REDIS_REST_URL
|
|
17
|
+
*/
|
|
18
|
+
url: string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* UPSTASH_REDIS_REST_TOKEN
|
|
21
|
+
*/
|
|
22
|
+
token: string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* A Request can be forwarded to any backend defined on your service. Backends
|
|
25
|
+
* can be created via the Fastly CLI, API, or web interface, and are
|
|
26
|
+
* referenced by name.
|
|
27
|
+
*/
|
|
28
|
+
backend: string;
|
|
29
|
+
keepAlive?: boolean;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* When this flag is enabled, any subsequent commands issued by this client are guaranteed to observe the effects of all earlier writes submitted by the same client.
|
|
33
|
+
*/
|
|
34
|
+
readYourWrites?: boolean;
|
|
35
|
+
} & core.RedisOptions &
|
|
36
|
+
RequesterConfig;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Serverless redis client for upstash.
|
|
40
|
+
*/
|
|
41
|
+
export class Redis extends core.Redis {
|
|
42
|
+
/**
|
|
43
|
+
* Create a new redis client
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const redis = new Redis({
|
|
48
|
+
* url: "<UPSTASH_REDIS_REST_URL>",
|
|
49
|
+
* token: "<UPSTASH_REDIS_REST_TOKEN>",
|
|
50
|
+
* backend: "upstash-db",
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
constructor(config: RedisConfigFastly) {
|
|
55
|
+
if (!config.url) {
|
|
56
|
+
throw new Error(
|
|
57
|
+
`[Upstash Redis] The 'url' property is missing or undefined in your Redis config.`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!config.token) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`[Upstash Redis] The 'token' property is missing or undefined in your Redis config.`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (config.url.startsWith(" ") || config.url.endsWith(" ") || /\r|\n/.test(config.url)) {
|
|
68
|
+
console.warn("The redis url contains whitespace or newline, which can cause errors!");
|
|
69
|
+
}
|
|
70
|
+
if (config.token.startsWith(" ") || config.token.endsWith(" ") || /\r|\n/.test(config.token)) {
|
|
71
|
+
console.warn("The redis token contains whitespace or newline, which can cause errors!");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const client = new HttpClient({
|
|
75
|
+
baseUrl: config.url,
|
|
76
|
+
retry: config.retry,
|
|
77
|
+
headers: { authorization: `Bearer ${config.token}` },
|
|
78
|
+
options: { backend: config.backend },
|
|
79
|
+
responseEncoding: config.responseEncoding,
|
|
80
|
+
keepAlive: config.keepAlive,
|
|
81
|
+
readYourWrites: config.readYourWrites,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
super(client, {
|
|
85
|
+
automaticDeserialization: config.automaticDeserialization,
|
|
86
|
+
enableAutoPipelining: config.enableAutoPipelining,
|
|
87
|
+
});
|
|
88
|
+
this.addTelemetry({
|
|
89
|
+
sdk: `@upstash/redis@${VERSION}`,
|
|
90
|
+
platform: "fastly",
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (this.enableAutoPipelining) {
|
|
94
|
+
return this.autoPipeline();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { type Requester, type UpstashRequest, type UpstashResponse } from "../pkg/http";
|
|
100
|
+
export { type Pipeline } from "../pkg/pipeline";
|