From f2366910f35fbf3ad403f219a83dd630eb6b9df8 Mon Sep 17 00:00:00 2001 From: Yusuke Sakurai Date: Thu, 26 Sep 2019 22:31:19 +0900 Subject: [PATCH] v0.4.0 (#20) * bump: deno@v0.19.0, deno_std@v0.18.0 * fmt --- .circleci/config.yml | 4 +- .gitignore | 3 +- Makefile | 4 +- README.md | 14 +++-- modules-lock.json | 11 ++++ modules.json | 9 ++- pipeline.ts | 4 +- pipeline_test.ts | 6 +- pubsub.ts | 2 +- pubsub_test.ts | 5 +- redis.ts | 59 +++++++++++++++++-- redis_test.ts | 26 +++++++- test.ts | 5 -- tsconfig.json | 14 +++++ vendor/https/deno.land/std/fmt/colors.ts | 1 + vendor/https/deno.land/std/io/bufio.ts | 2 +- vendor/https/deno.land/std/testing/asserts.ts | 2 +- vendor/https/deno.land/std/testing/mod.ts | 2 +- 18 files changed, 140 insertions(+), 33 deletions(-) create mode 100644 modules-lock.json delete mode 100644 test.ts create mode 100644 tsconfig.json create mode 100644 vendor/https/deno.land/std/fmt/colors.ts diff --git a/.circleci/config.yml b/.circleci/config.yml index 31ce27e3..354628e0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,9 +8,9 @@ jobs: - checkout - run: name: Install Deno - command: curl -fsSL https://deno.land/x/install/install.sh | sh -s -- v0.17.0 + command: curl -fsSL https://deno.land/x/install/install.sh | sh -s -- v0.19.0 - run: name: Run Tests command: | export PATH=$HOME/.deno/bin:$PATH - deno -A test.ts \ No newline at end of file + deno -A test \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6e2b7650..44f92335 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ deno.d.ts .idea -commands -tsconfig.json +commands \ No newline at end of file diff --git a/Makefile b/Makefile index 637f36c3..4b61c3fa 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,2 @@ redis: - docker run -p 6379:6379 -d -t redis:5 -test: - deno --allow-net test.ts \ No newline at end of file + docker run -p 6379:6379 -d -t redis:5 \ No newline at end of file diff --git a/README.md b/README.md index 3c1dde4e..c448ec0a 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ [![CircleCI](https://circleci.com/gh/keroxp/deno-redis.svg?style=svg)](https://circleci.com/gh/keroxp/deno-redis) ![https://img.shields.io/github/tag/keroxp/deno-redis.svg](https://img.shields.io/github/tag/keroxp/deno-redis.svg) [![license](https://img.shields.io/github/license/keroxp/deno-redis.svg)](https://github.com/keroxp/deno-redis) -[![tag](https://img.shields.io/badge/deno__std-v0.17.0-green.svg)](https://github.com/denoland/deno_std) -[![tag](https://img.shields.io/badge/deno-v0.17.0-green.svg)](https://github.com/denoland/deno) +[![tag](https://img.shields.io/badge/deno__std-v0.18.0-green.svg)](https://github.com/denoland/deno_std) +[![tag](https://img.shields.io/badge/deno-v0.19.0-green.svg)](https://github.com/denoland/deno) An experimental implementation of redis client for deno @@ -16,7 +16,10 @@ needs `--allow-net` privilege ```ts import { connect } from "https://denopkg.com/keroxp/deno-redis/redis.ts"; -const redis = await connect("127.0.0.1:6379"); +const redis = await connect({ + hostname: "127.0.0.1", + port: 6379 +}); const ok = await redis.set("hoge", "fuga"); const fuga = await redis.get("hoge"); ``` @@ -39,7 +42,10 @@ const sub = await redis.subscribe("channel"); https://redis.io/topics/pipelining ```ts -const redis = await connect("127.0.0.1:6379"); +const redis = await connect({ + hostname: "127.0.0.1", + port: 6379 +}); const pl = redis.pipeline(); await Promise.all([ pl.ping(), diff --git a/modules-lock.json b/modules-lock.json new file mode 100644 index 00000000..0da27902 --- /dev/null +++ b/modules-lock.json @@ -0,0 +1,11 @@ +{ + "https://deno.land/std": { + "version": "@v0.18.0", + "modules": [ + "/testing/mod.ts", + "/testing/asserts.ts", + "/io/bufio.ts", + "/fmt/colors.ts" + ] + } +} diff --git a/modules.json b/modules.json index af8d2bda..0da27902 100644 --- a/modules.json +++ b/modules.json @@ -1,6 +1,11 @@ { "https://deno.land/std": { - "version": "@v0.17.0", - "modules": ["/testing/mod.ts", "/testing/asserts.ts", "/io/bufio.ts"] + "version": "@v0.18.0", + "modules": [ + "/testing/mod.ts", + "/testing/asserts.ts", + "/io/bufio.ts", + "/fmt/colors.ts" + ] } } diff --git a/pipeline.ts b/pipeline.ts index c495c4c2..9a32fdcf 100644 --- a/pipeline.ts +++ b/pipeline.ts @@ -14,7 +14,7 @@ export function createRedisPipeline( reader: BufReader, opts?: { tx: true } ): RedisPipeline { - let queue = []; + let queue: string[] = []; const executor = { enqueue(command: string, ...args) { const msg = createRequest(command, ...args); @@ -29,7 +29,7 @@ export function createRedisPipeline( const msg = queue.join(""); await writer.write(encoder.encode(msg)); await writer.flush(); - const ret = []; + const ret: RedisRawReply[] = []; for (let i = 0; i < queue.length; i++) { try { const rep = await readReply(reader); diff --git a/pipeline_test.ts b/pipeline_test.ts index 8a902a05..15bacaa4 100644 --- a/pipeline_test.ts +++ b/pipeline_test.ts @@ -2,7 +2,11 @@ import { test } from "./vendor/https/deno.land/std/testing/mod.ts"; import { assertEquals } from "./vendor/https/deno.land/std/testing/asserts.ts"; import { connect } from "./redis.ts"; -const addr = "127.0.0.1:6379"; +const addr = { + hostname: "127.0.0.1", + port: 6379 +}; + test(async function testPipeline() { const redis = await connect(addr); const pl = redis.pipeline(); diff --git a/pubsub.ts b/pubsub.ts index f80ffef9..9fa71fe3 100644 --- a/pubsub.ts +++ b/pubsub.ts @@ -1,5 +1,5 @@ import { BufReader, BufWriter } from "./vendor/https/deno.land/std/io/bufio.ts"; -import { createRequest, readArrayReply, sendCommand } from "./io.ts"; +import { readArrayReply, sendCommand } from "./io.ts"; export type RedisSubscription = { readonly isClosed: boolean; diff --git a/pubsub_test.ts b/pubsub_test.ts index f234e19d..7f3601e4 100644 --- a/pubsub_test.ts +++ b/pubsub_test.ts @@ -3,7 +3,10 @@ import { assertEquals } from "./vendor/https/deno.land/std/testing/asserts.ts"; import { connect } from "./redis.ts"; import { RedisPubSubMessage } from "./pubsub.ts"; -const addr = "127.0.0.1:6379"; +const addr = { + hostname: "127.0.0.1", + port: 6379 +}; async function wait(duration) { return new Promise(resolve => { diff --git a/redis.ts b/redis.ts index 303055f9..be347a76 100644 --- a/redis.ts +++ b/redis.ts @@ -1,7 +1,10 @@ +import DialOptions = Deno.DialOptions; + type Reader = Deno.Reader; type Writer = Deno.Writer; type Closer = Deno.Closer; import { BufReader, BufWriter } from "./vendor/https/deno.land/std/io/bufio.ts"; +import { yellow } from "./vendor/https/deno.land/std/fmt/colors.ts"; import { ConnectionClosedError } from "./errors.ts"; import { psubscribe, RedisSubscription, subscribe } from "./pubsub.ts"; import { RedisRawReply, sendCommand } from "./io.ts"; @@ -445,12 +448,12 @@ class RedisImpl implements Redis, CommandExecutor { get isClosed() { return this._isClosed; } - + private executor: CommandExecutor; constructor( private closer: Closer, private writer: BufWriter, private reader: BufReader, - private executor?: CommandExecutor + executor?: CommandExecutor ) { this.executor = executor || this; } @@ -1502,8 +1505,56 @@ class RedisImpl implements Redis, CommandExecutor { } } -export async function connect(addr: string): Promise { - const conn = await Deno.dial("tcp", addr); +export type RedisConnectOptions = { + hostname: string; + port?: number | string; + tls?: boolean; +}; + +/** + * Connect to Redis server + * @param opts redis server's url http/https url with port number + * Examples: + * const conn = connect({hostname: "127.0.0.1", port: 6379})// -> tcp, 127.0.0.1:6379 + * const conn = connect({hostname: "redis.proxy", port: 443, tls: true}) // -> TLS, redis.proxy:443 + */ +export async function connect( + opts: string | RedisConnectOptions +): Promise { + let conn: Deno.Conn; + if (typeof opts === "string") { + console.warn( + yellow( + "deno-redis: connect(addr) is now deprecated and will be removed in v0.5.0 (now v0.4.x)" + ) + ); + const [h, p] = opts.split(":"); + if (!p) { + throw new Error("redis: port must be specified"); + } + const dialOptions: DialOptions = { port: parseInt(p) }; + if (h) { + dialOptions.hostname = h; + } + conn = await Deno.dial(dialOptions); + } else { + const { hostname } = opts; + const port = parseInt(`${opts.port}`); + if (!Number.isSafeInteger(port)) { + throw new Error("deno-redis: opts.port is invalid"); + } + if (opts.tls) { + conn = await Deno.dialTLS({ + hostname, + port + }); + } else { + conn = await Deno.dial({ + hostname, + port + }); + } + } return create(conn, conn, conn); } diff --git a/redis_test.ts b/redis_test.ts index 4c241fc9..f1518fb7 100644 --- a/redis_test.ts +++ b/redis_test.ts @@ -1,8 +1,14 @@ import { connect } from "./redis.ts"; -import { test } from "./vendor/https/deno.land/std/testing/mod.ts"; -import { assertEquals } from "./vendor/https/deno.land/std/testing/asserts.ts"; +import { runIfMain, test } from "./vendor/https/deno.land/std/testing/mod.ts"; +import { + assertEquals, + assertThrowsAsync +} from "./vendor/https/deno.land/std/testing/asserts.ts"; // can be substituted with env variable -const addr = "127.0.0.1:6379"; +const addr = { + hostname: "127.0.0.1", + port: 6379 +}; test(async function beforeAll() { const redis = await connect(addr); @@ -101,3 +107,17 @@ test(async function testDecrby() { assertEquals(await redis.get("decryby"), "-101"); redis.close(); }); + +[Infinity, NaN, "", "port"].forEach(v => { + test(`invalid port: ${v}`, () => { + assertThrowsAsync( + async () => { + await connect({ hostname: "127.0.0.1", port: v }); + }, + Error, + "invalid" + ); + }); +}); + +runIfMain(import.meta); diff --git a/test.ts b/test.ts deleted file mode 100644 index e8d53fe7..00000000 --- a/test.ts +++ /dev/null @@ -1,5 +0,0 @@ -import "./redis_test.ts"; -import "./pubsub_test.ts"; -import "./pipeline_test.ts"; -import { runIfMain } from "./vendor/https/deno.land/std/testing/mod.ts"; -runIfMain(import.meta); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..d47b7843 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "noResolve": true, + "baseUrl": "/Users/keroxp/Library/Caches", + "strictNullChecks": true, + "paths": { + "deno": ["./deno.d.ts"], + "https://*": ["./deno/deps/https/*"], + "http://*": ["./deno/deps/http/*"] + } + } +} diff --git a/vendor/https/deno.land/std/fmt/colors.ts b/vendor/https/deno.land/std/fmt/colors.ts new file mode 100644 index 00000000..f5177377 --- /dev/null +++ b/vendor/https/deno.land/std/fmt/colors.ts @@ -0,0 +1 @@ +export * from "https://deno.land/std@v0.18.0/fmt/colors.ts"; diff --git a/vendor/https/deno.land/std/io/bufio.ts b/vendor/https/deno.land/std/io/bufio.ts index 46982d6a..6fedff00 100644 --- a/vendor/https/deno.land/std/io/bufio.ts +++ b/vendor/https/deno.land/std/io/bufio.ts @@ -1 +1 @@ -export * from "https://deno.land/std@v0.17.0/io/bufio.ts"; +export * from "https://deno.land/std@v0.18.0/io/bufio.ts"; diff --git a/vendor/https/deno.land/std/testing/asserts.ts b/vendor/https/deno.land/std/testing/asserts.ts index b9591202..43a65eb3 100644 --- a/vendor/https/deno.land/std/testing/asserts.ts +++ b/vendor/https/deno.land/std/testing/asserts.ts @@ -1 +1 @@ -export * from "https://deno.land/std@v0.17.0/testing/asserts.ts"; +export * from "https://deno.land/std@v0.18.0/testing/asserts.ts"; diff --git a/vendor/https/deno.land/std/testing/mod.ts b/vendor/https/deno.land/std/testing/mod.ts index adf3ebec..f0cacae2 100644 --- a/vendor/https/deno.land/std/testing/mod.ts +++ b/vendor/https/deno.land/std/testing/mod.ts @@ -1 +1 @@ -export * from "https://deno.land/std@v0.17.0/testing/mod.ts"; +export * from "https://deno.land/std@v0.18.0/testing/mod.ts";