From e067c2fcb9d47c8fed98b538c61b10289d068b4b Mon Sep 17 00:00:00 2001 From: thetutlage Date: Tue, 25 Jun 2019 10:54:31 +0530 Subject: [PATCH] feat: initiate new project --- .circleci/config.yml | 40 ++++ .github/COMMIT_CONVENTION.md | 70 ++++++ .github/PULL_REQUEST_TEMPLATE.md | 2 +- .npmrc | 1 + .travis.yml | 15 -- CHANGELOG.md | 100 --------- LICENSE.md | 2 +- README.md | 96 +++----- appveyor.yml | 16 -- config.json | 9 +- examples/listener.js | 24 -- examples/redis.js | 64 ------ instructions.js | 31 --- instructions.md | 38 ---- japaFile.js | 8 +- package.json | 120 +++++----- providers/RedisProvider.js | 29 --- src/Redis/index.js | 131 ----------- src/Redis/proxyHandler.js | 35 --- src/RedisFactory/index.js | 361 ------------------------------- src/RedisFactory/proxyHandler.js | 46 ---- test/redis-factory.spec.js | 266 ----------------------- test/redis.spec.js | 212 ------------------ tsconfig.json | 3 + tslint.json | 6 + 25 files changed, 216 insertions(+), 1509 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .github/COMMIT_CONVENTION.md create mode 100644 .npmrc delete mode 100644 .travis.yml delete mode 100644 CHANGELOG.md delete mode 100644 appveyor.yml delete mode 100644 examples/listener.js delete mode 100644 examples/redis.js delete mode 100644 instructions.js delete mode 100644 instructions.md delete mode 100644 providers/RedisProvider.js delete mode 100644 src/Redis/index.js delete mode 100644 src/Redis/proxyHandler.js delete mode 100644 src/RedisFactory/index.js delete mode 100644 src/RedisFactory/proxyHandler.js delete mode 100644 test/redis-factory.spec.js delete mode 100644 test/redis.spec.js create mode 100644 tsconfig.json create mode 100644 tslint.json diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..1b5ff3c --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,40 @@ +version: 2 +jobs: + build_10.15.3: + docker: + - image: 'circleci/node:10.15.3' + working_directory: ~/app + steps: + - checkout + - restore_cache: + keys: + - 'v1-dependencies-{{ checksum "package.json" }}' + - v1-dependencies- + - run: npm install + - save_cache: + paths: + - node_modules + key: 'v1-dependencies-{{ checksum "package.json" }}' + - run: npm test + build_latest: + docker: + - image: 'circleci/node:latest' + working_directory: ~/app + steps: + - checkout + - restore_cache: + keys: + - 'v1-dependencies-{{ checksum "package.json" }}' + - v1-dependencies- + - run: npm install + - save_cache: + paths: + - node_modules + key: 'v1-dependencies-{{ checksum "package.json" }}' + - run: npm test +workflows: + version: 2 + workflow: + jobs: + - build_10.15.3 + - build_latest diff --git a/.github/COMMIT_CONVENTION.md b/.github/COMMIT_CONVENTION.md new file mode 100644 index 0000000..33a78e6 --- /dev/null +++ b/.github/COMMIT_CONVENTION.md @@ -0,0 +1,70 @@ +## Git Commit Message Convention + +> This is adapted from [Angular's commit convention](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular). + +Using conventional commit messages, we can automate the process of generating the CHANGELOG file. All commits messages will automatically be validated against the following regex. + +``` js +/^(revert: )?(feat|fix|docs|style|refactor|perf|test|workflow|ci|chore|types|build)((.+))?: .{1,50}/ +``` + +## Commit Message Format +A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**: + +> The **scope** is optional + +``` +feat(router): add support for prefix + +Prefix makes it easier to append a path to a group of routes +``` + +1. `feat` is type. +2. `router` is scope and is optional +3. `add support for prefix` is the subject +4. The **body** is followed by a blank line. +5. The optional **footer** can be added after the body, followed by a blank line. + +## Types +Only one type can be used at a time and only following types are allowed. + +- feat +- fix +- docs +- style +- refactor +- perf +- test +- workflow +- ci +- chore +- types +- build + +If a type is `feat`, `fix` or `perf`, then the commit will appear in the CHANGELOG.md file. However if there is any BREAKING CHANGE, the commit will always appear in the changelog. + +### Revert +If the commit reverts a previous commit, it should begin with `revert:`, followed by the header of the reverted commit. In the body it should say: `This reverts commit `., where the hash is the SHA of the commit being reverted. + +## Scope +The scope could be anything specifying place of the commit change. For example: `router`, `view`, `querybuilder`, `database`, `model` and so on. + +## Subject +The subject contains succinct description of the change: + +- use the imperative, present tense: "change" not "changed" nor "changes". +- don't capitalize first letter +- no dot (.) at the end + +## Body + +Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes". +The body should include the motivation for the change and contrast this with previous behavior. + +## Footer + +The footer should contain any information about **Breaking Changes** and is also the place to +reference GitHub issues that this commit **Closes**. + +**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this. + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 42940f1..0aad71a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -18,7 +18,7 @@ _Put an `x` in the boxes that apply_ _Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code._ -- [ ] I have read the [CONTRIBUTING](https://github.com/adonisjs/adonis-redis/CONTRIBUTING.md) doc +- [ ] I have read the [CONTRIBUTING](https://github.com/adonisjs/adonis-redis/blob/master/CONTRIBUTING.md) doc - [ ] Lint and unit tests pass locally with my changes - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added necessary documentation (if appropriate) diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..a54c771 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +message="chore(release): %s" diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index caf8bea..0000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: node_js -node_js: - - node - - 8.0.0 -sudo: false -services: - - redis-server -install: - - npm install -after_script: - - npm run coverage -notifications: - slack: - secure: >- - m91zkX2cLVDRDMBAUnR1d+hbZqtSHXLkuPencHadhJ3C3wm53Box8U25co/goAmjnW5HNJ1SMSIg+DojtgDhqTbReSh5gSbU0uU8YaF8smbvmUv3b2Q8PRCA7f6hQiea+a8+jAb7BOvwh66dV4Al/1DJ2b4tCjPuVuxQ96Wll7Pnj1S7yW/Hb8fQlr9wc+INXUZOe8erFin+508r5h1L4Xv0N5ZmNw+Gqvn2kPJD8f/YBPpx0AeZdDssTL0IOcol1+cDtDzMw5PAkGnqwamtxhnsw+i8OW4avFt1GrRNlz3eci5Cb3NQGjHxJf+JIALvBeSqkOEFJIFGqwAXMctJ9q8/7XyXk7jVFUg5+0Z74HIkBwdtLwi/BTyXMZAgsnDjndmR9HsuBP7OSTJF5/V7HCJZAaO9shEgS8DwR78owv9Fr5er5m9IMI+EgSH3qtb8iuuQaPtflbk+cPD3nmYbDqmPwkSCXcXRfq3IxdcV9hkiaAw52AIqqhnAXJWZfL6+Ct32i2mtSaov9FYtp/G0xb4tjrUAsDUd/AGmMJNEBVoHtP7mKjrVQ35cEtFwJr/8SmZxGvOaJXPaLs43dhXKa2tAGl11wF02d+Rz1HhbOoq9pJvJuqkLAVvRdBHUJrB4/hnTta5B0W5pe3mIgLw3AmOpk+s/H4hAP4Hp0gOWlPA= diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index b3c4f10..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,100 +0,0 @@ - -## [2.0.8](https://github.com/adonisjs/adonis-redis/compare/v2.0.7...v2.0.8) (2018-07-17) - - - - -## [2.0.7](https://github.com/adonisjs/adonis-redis/compare/v2.0.6...v2.0.7) (2018-06-02) - - -### Bug Fixes - -* **redisfactory:** bind connection when proxy receives a function call ([10de858](https://github.com/adonisjs/adonis-redis/commit/10de858)) -* **tests:** improve tests connection/disconnection flow ([9ab980f](https://github.com/adonisjs/adonis-redis/commit/9ab980f)) - - - - -## [2.0.6](https://github.com/adonisjs/adonis-redis/compare/v2.0.5...v2.0.6) (2018-04-19) - - -### Bug Fixes - -* **redis:** improve connections pool flow ([9a891c5](https://github.com/adonisjs/adonis-redis/commit/9a891c5)) - - - - -## [2.0.5](https://github.com/adonisjs/adonis-redis/compare/v2.0.4...v2.0.5) (2018-04-19) - - -### Features - -* **Redis:** expose namedConnection method ([a2c527b](https://github.com/adonisjs/adonis-redis/commit/a2c527b)) - - - - -## [2.0.4](https://github.com/adonisjs/adonis-redis/compare/v2.0.3...v2.0.4) (2018-02-07) - - - - -## [2.0.3](https://github.com/adonisjs/adonis-redis/compare/v2.0.2...v2.0.3) (2017-10-29) - - - - -## [2.0.2](https://github.com/adonisjs/adonis-redis/compare/v2.0.1...v2.0.2) (2017-08-18) - - - - -## [2.0.1](https://github.com/adonisjs/adonis-redis/compare/v2.0.0...v2.0.1) (2017-08-02) - - -### Features - -* **exceptions:** use generic-exceptions package ([311e6b7](https://github.com/adonisjs/adonis-redis/commit/311e6b7)) -* **instructions:** implement instructions ([fa31bbc](https://github.com/adonisjs/adonis-redis/commit/fa31bbc)) - - - - -# 2.0.0 (2017-07-22) - - -### Bug Fixes - -* **package:** update node-exceptions to version 2.0.0 ([#5](https://github.com/adonisjs/adonis-redis/issues/5)) ([bfe6fbc](https://github.com/adonisjs/adonis-redis/commit/bfe6fbc)) -* **test:** fix test behavior ([75d74d8](https://github.com/adonisjs/adonis-redis/commit/75d74d8)) - - -### Features - -* cleanup for 4.0 ([ef14fd0](https://github.com/adonisjs/adonis-redis/commit/ef14fd0)) -* **exceptions:** add custom exceptions ([8046ba9](https://github.com/adonisjs/adonis-redis/commit/8046ba9)) - - - -## 1.0.1 (2016-09-26) - - - -# 1.0.0 (2016-07-11) - - -### Bug Fixes - -* **package:** install standard as a dev dependency([af46312](https://github.com/adonisjs/adonis-redis/commit/af46312)) -* **redis:** add redis class to access factory with lazy intialization([701e7f3](https://github.com/adonisjs/adonis-redis/commit/701e7f3)) -* **redis:** fix broken tests([671439b](https://github.com/adonisjs/adonis-redis/commit/671439b)) -* **redis:factory:** fix redis subscriber connection re-use issue([a493413](https://github.com/adonisjs/adonis-redis/commit/a493413)) - - -### Features - -* implement io-redis and add support for expressive pub/sub([3803407](https://github.com/adonisjs/adonis-redis/commit/3803407)) -* **providers:** add redis, redis-factory providers([3323dd3](https://github.com/adonisjs/adonis-redis/commit/3323dd3)) -* **redis:pubsub:** add support for ioc bindings([3198ce6](https://github.com/adonisjs/adonis-redis/commit/3198ce6)) - diff --git a/LICENSE.md b/LICENSE.md index f9333f2..7dd66b3 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # The MIT License -Copyright 2018 thetutlage, contributors +Copyright 2019 thetutlage, contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 9b6a73f..2033a49 100644 --- a/README.md +++ b/README.md @@ -1,85 +1,39 @@ -# AdonisJs Redis 🚀 -> Provider to run redis commands from your Adonis app + + +## Table of contents -[![NPM Version][npm-image]][npm-url] -[![Build Status][travis-image]][travis-url] -[![Appveyor][appveyor-image]][appveyor-url] -[![Coveralls][coveralls-image]][coveralls-url] +- [@adonisjs/redis](#adonisjsredis) + - [Change log](#change-log) + - [Contributing](#contributing) + - [Authors & License](#authors--license) -Adonis redis is a wrapper on top of [IoRedis](https://github.com/luin/ioredis) to run redis commands from your Adonisjs app. + - +# @adonisjs/redis -## Features +[![circleci-image]][circleci-url] +[![npm-image]][npm-url] +![](https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript) -1. Support for cluser. -2. Run redis commands using `async/await` syntax. -3. Intutive pub/sub API. +## Change log +The change log can be found in the [CHANGELOG.md](CHANGELOG.md) file. -## Node/OS Target +## Contributing -This repo/branch is supposed to run fine on all major OS platforms and targets `Node.js >=7.0` +Everyone is welcome to contribute. Please go through the following guides, before getting started. -## Development +1. [Contributing](https://adonisjs.com/contributing) +2. [Code of conduct](https://adonisjs.com/code-of-conduct) -Great! If you are planning to contribute to the framework, make sure to adhere to following conventions, since a consistent code-base is always joy to work with. -Run the following command to see list of available npm scripts. +## Authors & License +[thetutlage](https://github.com/thetutlage) and [contributors](https://github.com/adonisjs/adonis-redis/graphs/contributors). -``` -npm run -``` +MIT License, see the included [MIT](LICENSE.md) file. -### Tests & Linting +[circleci-image]: https://img.shields.io/circleci/project/github/adonisjs/adonis-redis/master.svg?style=for-the-badge&logo=circleci +[circleci-url]: https://circleci.com/gh/adonisjs/adonis-redis "circleci" -1. Lint your code using standardJs. Run `npm run lint` command to check if there are any linting errors. -2. Make sure you write tests for all the changes/bug fixes. -3. Also you can write **regression tests**, which shows that something is failing but doesn't breaks the build. Which is actually a nice way to show that something fails. Regression tests are written using `test.failing()` method. -4. Make sure all the tests are passing on `travis` and `appveyor`. - -### General Practices - -Since Es6 is in, you should strive to use latest features. For example: - -1. Use `Spread` over `arguments` keyword. -2. Never use `bind` or `call`. After calling these methods, we cannot guarantee the scope of any methods and in AdonisJs codebase we do not override the methods scope. -3. Make sure to write proper docblock. - -## Issues & PR - -It is always helpful if we try to follow certain practices when creating issues or PR's, since it will save everyone's time. - -1. Always try creating regression tests when you find a bug (if possible). -2. Share some context on what you are trying to do, with enough code to reproduce the issue. -3. For general questions, please create a forum thread. -4. When creating a PR for a feature, make sure to create a parallel PR for docs too. - - -## Regression Tests - -Regression tests are tests, which shows how a piece of code fails under certain circumstance, but the beauty is even after the failure, the test suite will never fail. Actually is a nice way to notify about bugs, but making sure everything is green. - -The regression tests are created using - -``` -test.failing('2 + 2 is always 4, but add method returns 6', (assert) => { - assert.true(add(2, 2), 4) -}) -``` - -Now since the `add` method has a bug, it will return `6` instead of `4`. But the build will pass. - -[appveyor-image]: https://img.shields.io/appveyor/ci/thetutlage/adonis-redis/master.svg?style=flat-square - -[appveyor-url]: https://ci.appveyor.com/project/thetutlage/adonis-redis - -[npm-image]: https://img.shields.io/npm/v/@adonisjs/redis.svg?style=flat-square -[npm-url]: https://npmjs.org/package/@adonisjs/redis - -[travis-image]: https://img.shields.io/travis/adonisjs/adonis-redis/master.svg?style=flat-square -[travis-url]: https://travis-ci.org/adonisjs/adonis-redis - -[coveralls-image]: https://img.shields.io/coveralls/adonisjs/adonis-redis/develop.svg?style=flat-square - -[coveralls-url]: https://coveralls.io/github/adonisjs/adonis-redis +[npm-image]: https://img.shields.io/npm/v/@adonisjs/redis.svg?style=for-the-badge&logo=npm +[npm-url]: https://npmjs.org/package/@adonisjs/redis "npm" diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index ac3340f..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,16 +0,0 @@ -environment: - matrix: - - nodejs_version: Stable - - nodejs_version: 8.0.0 -init: git config --global core.autocrlf true -install: - - ps: 'Install-Product node $env:nodejs_version' - - npm install -test_script: - - node --version - - npm --version - - 'npm run test:win' -build: 'off' -clone_depth: 1 -matrix: - fast_finish: true diff --git a/config.json b/config.json index d11827e..9568b97 100644 --- a/config.json +++ b/config.json @@ -1,12 +1,9 @@ { "core": true, - "ts": false, + "ts": true, "license": "MIT", "services": [ - "travis", - "appveyor", - "coveralls" + "circleci" ], - "appveyorUsername": "thetutlage", - "minNodeVersion": "8.0.0" + "minNodeVersion": "10.15.3" } diff --git a/examples/listener.js b/examples/listener.js deleted file mode 100644 index 98fae1f..0000000 --- a/examples/listener.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict' - -/* -|-------------------------------------------------------------------------- -| Redis Subscribers -|-------------------------------------------------------------------------- -| -| Here you can register the subscribers to redis channels. Adonis assumes -| your listeners are stored inside `app/Listeners` directory. -| -*/ - -// const Redis = use('Redis') - -/** - * Inline subscriber - */ -// Redis.subscribe('news', async () => { -// }) - -/** - * Binding method from a module saved inside `app/Listeners/News` - */ -// Redis.subcribe('news', 'News.onMessage') diff --git a/examples/redis.js b/examples/redis.js deleted file mode 100644 index 0dd8707..0000000 --- a/examples/redis.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict' - -/* -|-------------------------------------------------------------------------- -| Redis Configuaration -|-------------------------------------------------------------------------- -| -| Here we define the configuration for redis server. A single application -| can make use of multiple redis connections using the redis provider. -| -*/ - -const Env = use('Env') - -module.exports = { - /* - |-------------------------------------------------------------------------- - | connection - |-------------------------------------------------------------------------- - | - | Redis connection to be used by default. - | - */ - connection: Env.get('REDIS_CONNECTION', 'local'), - - /* - |-------------------------------------------------------------------------- - | local connection config - |-------------------------------------------------------------------------- - | - | Configuration for a named connection. - | - */ - local: { - host: '127.0.0.1', - port: 6379, - password: null, - db: 0, - keyPrefix: '' - }, - - /* - |-------------------------------------------------------------------------- - | cluster config - |-------------------------------------------------------------------------- - | - | Below is the configuration for the redis cluster. - | - */ - cluster: { - clusters: [{ - host: '127.0.0.1', - port: 6379, - password: null, - db: 0 - }, - { - host: '127.0.0.1', - port: 6380, - password: null, - db: 0 - }] - } -} diff --git a/instructions.js b/instructions.js deleted file mode 100644 index 8b10fa4..0000000 --- a/instructions.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict' - -/* - * adonis-redis - * - * (c) Harminder Virk - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. -*/ - -const path = require('path') - -async function createConfigFile (cli) { - try { - await cli.copy(path.join(__dirname, 'examples/redis.js'), path.join(cli.helpers.configPath(), 'redis.js')) - cli.command.completed('create', 'config/redis.js') - } catch (e) {} -} - -async function createListenerFile (cli) { - try { - await cli.copy(path.join(__dirname, 'examples/listener.js'), path.join(cli.helpers.appRoot(), 'start/redis.js')) - cli.command.completed('create', 'start/redis.js') - } catch (e) {} -} - -module.exports = async function (cli) { - createConfigFile(cli) - createListenerFile(cli) -} diff --git a/instructions.md b/instructions.md deleted file mode 100644 index 1479faf..0000000 --- a/instructions.md +++ /dev/null @@ -1,38 +0,0 @@ -## Registering provider - -Make sure you register the provider inside `start/app.js` file before making use redis. - -```js -const providers = [ - '@adonisjs/redis/providers/RedisProvider' -] -``` - -Once that done you can make use of Redis anywhere by importing the redis provider. - -```js -const Redis = use('Redis') -await Redis.get() -``` - -## Pub Sub -In order to make use of pub/sub you can subscribe to channels inside `start/redis.js` file. - -```js -const Redis = use('Redis') -Redis.subscribe('news', async () => { -}) - -// or bind listeners from `app/Listeners` directory -Redis.subcribe('news', 'News.onMessage') -``` - -## Config -The config file `config/redis.js` contains all the configuration. Feel free to tweak it as per your needs. - -## Environment variables -The configuration file makes use of **Environment variables**, make sure to define them for development and in production too - -``` -REDIS_CONNECTION=local -``` diff --git a/japaFile.js b/japaFile.js index 5fcde58..46b457c 100644 --- a/japaFile.js +++ b/japaFile.js @@ -1,2 +1,6 @@ -const cli = require('japa/cli') -cli.run('test/**/*.spec.js') +require('ts-node/register') + +const { configure } = require('japa') +configure({ + files: ['test/**/*.spec.ts'] +}) diff --git a/package.json b/package.json index ceba56e..97df83e 100644 --- a/package.json +++ b/package.json @@ -1,66 +1,18 @@ { "name": "@adonisjs/redis", "version": "2.0.8", - "description": "AdonisJs official redis provider to make working with redis fun and simple.", - "files": [ - "examples", - "providers", - "src", - "instructions.js", - "instructions.md" - ], - "dependencies": { - "@adonisjs/generic-exceptions": "^2.0.1", - "debug": "^3.1.0", - "ioredis": "^3.2.2", - "lodash": "^4.17.10" - }, - "devDependencies": { - "@adonisjs/fold": "^4.0.9", - "@adonisjs/mrm-preset": "^1.0.9", - "@adonisjs/sink": "^1.0.16", - "commitizen": "^2.10.1", - "coveralls": "^3.0.2", - "cz-conventional-changelog": "^2.1.0", - "japa": "^1.0.6", - "japa-cli": "^1.0.1", - "mrm": "^1.2.1", - "nyc": "^12.0.2", - "pkg-ok": "^2.2.0", - "semver": "^5.5.0", - "standard": "^11.0.1" - }, + "description": "AdonisJs addon for Redis", "scripts": { "mrm": "mrm --preset=@adonisjs/mrm-preset", "pretest": "npm run lint", - "test:local": "FORCE_COLOR=true node bin/index.js --local", - "test": "nyc japa", - "test:win": "node ./node_modules/japa-cli/index.js", - "coverage": "nyc report --reporter=text-lcov | coveralls", + "test": "node japaFile.js", + "lint": "tslint --project tsconfig.json", + "clean": "del build", + "compile": "npm run lint && npm run clean && tsc", + "build": "npm run compile", "commit": "git-cz", - "lint": "standard" - }, - "standard": { - "globals": [ - "use", - "make" - ] - }, - "author": "virk", - "license": "MIT", - "config": { - "commitizen": { - "path": "cz-conventional-changelog" - } - }, - "nyc": { - "exclude": [ - "test", - "japaFile.js" - ] - }, - "directories": { - "test": "test" + "release": "np", + "version": "npm run build" }, "repository": { "type": "git", @@ -68,13 +20,61 @@ }, "keywords": [ "redis", - "adonisjs", - "adonis", - "adonis-redis", "ioredis" ], + "author": "virk,adonisjs", + "license": "MIT", "bugs": { "url": "https://github.com/adonisjs/adonis-redis/issues" }, - "homepage": "https://github.com/adonisjs/adonis-redis#readme" + "homepage": "https://github.com/adonisjs/adonis-redis#readme", + "publishConfig": { + "access": "public", + "tag": "next" + }, + "devDependencies": { + "@adonisjs/mrm-preset": "^2.0.3", + "@types/node": "^12.0.10", + "commitizen": "^3.1.1", + "cz-conventional-changelog": "^2.1.0", + "del-cli": "^2.0.0", + "doctoc": "^1.4.0", + "husky": "^2.5.0", + "japa": "^2.0.10", + "mrm": "^1.2.2", + "np": "^5.0.3", + "ts-node": "^8.3.0", + "tslint": "^5.18.0", + "tslint-eslint-rules": "^5.4.0", + "typescript": "^3.5.2" + }, + "nyc": { + "exclude": [ + "test" + ], + "extension": [ + ".ts" + ] + }, + "main": "build/index.js", + "files": [ + "build/src", + "build/index.d.ts", + "build/index.js" + ], + "husky": { + "hooks": { + "pre-commit": "doctoc README.md --title='## Table of contents' && git add README.md", + "commit-msg": "node ./node_modules/@adonisjs/mrm-preset/validateCommit/conventional/validate.js" + } + }, + "config": { + "commitizen": { + "path": "cz-conventional-changelog" + } + }, + "np": { + "contents": ".", + "anyBranch": false + } } diff --git a/providers/RedisProvider.js b/providers/RedisProvider.js deleted file mode 100644 index e893781..0000000 --- a/providers/RedisProvider.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -/** - * adonis-redis - * - * (c) Harminder Virk - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. -*/ - -const { ServiceProvider } = require('@adonisjs/fold') - -class RedisProvider extends ServiceProvider { - register () { - this.app.bind('Adonis/Addons/RedisFactory', () => require('../src/RedisFactory')) - - this.app.singleton('Adonis/Addons/Redis', (app) => { - const RedisFactory = app.use('Adonis/Addons/RedisFactory') - const Config = app.use('Adonis/Src/Config') - const Redis = require('../src/Redis') - return new Redis(Config, RedisFactory) - }) - - this.app.alias('Adonis/Addons/Redis', 'Redis') - } -} - -module.exports = RedisProvider diff --git a/src/Redis/index.js b/src/Redis/index.js deleted file mode 100644 index be0d9a2..0000000 --- a/src/Redis/index.js +++ /dev/null @@ -1,131 +0,0 @@ -'use strict' - -/* - * adonis-redis - * - * (c) Harminder Virk - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. -*/ - -const GE = require('@adonisjs/generic-exceptions') -const _ = require('lodash') -const proxyHandler = require('./proxyHandler') - -/** - * Redis class is used to call methods on a redis server. - * This library creates a pool of connections and reuse - * them. - * - * @namespace Adonis/Addons/Redis - * @singleton - * @alias Redis - * - * @class Redis - * @constructor - */ -class Redis { - constructor (Config, Factory) { - this.Config = Config - this.Factory = Factory - this.connectionPools = {} - return new Proxy(this, proxyHandler) - } - - /** - * Looks at the config file and tells if a - * cluster connection to be created or - * not - * - * @param {Object} config - * - * @return {Boolean} - * - * @private - */ - _isCluster (config) { - return !!config.clusters - } - - /** - * Closes a given redis connection by quitting - * and removing it from the connectionsPool. - * - * @param {String} connection - * - * @private - */ - _closeConnection (connection) { - const redisConnection = this.connectionPools[connection] - if (!redisConnection) { - return - } - _.unset(this.connectionPools, connection) - return redisConnection.quit() - } - - /** - * Returns instance of a new factory instance for - * a given connection. - * - * @param {String} [connection=''] - * - * @return {RedisFactory} - */ - connection (connection = '') { - connection = connection || this.Config.get('redis.connection') - const config = this.Config.get(`redis.${connection}`) - - return this.namedConnection(connection, config) - } - - /** - * Creates a connection using raw config and adds it to the - * connection pool. - * - * @method namedConnection - * - * @param {String} name - * @param {Object} config - * - * @return {RedisFactory} - */ - namedConnection (name, config) { - if (this.connectionPools[name]) { - return this.connectionPools[name] - } - - if (!config || !_.size(config) === 0) { - throw GE.RuntimeException.missingConfig(name || 'configuration for redis', 'config/redis.js') - } - - this.connectionPools[name] = new this.Factory(config, this._isCluster(config)) - return this.connectionPools[name] - } - - /** - * Returns a hash of connection pools - * - * @return {Object} - * - * @public - */ - getConnections () { - return this.connectionPools - } - - /** - * Closes a single or number of redis connections - * - * @param {Spread} connections - * - * @public - */ - quit (...name) { - const connections = _.isArray(name) ? name : [name] - return Promise.all(_.map(connections, (connection) => this._closeConnection(connection))) - } -} - -module.exports = Redis diff --git a/src/Redis/proxyHandler.js b/src/Redis/proxyHandler.js deleted file mode 100644 index 7aad178..0000000 --- a/src/Redis/proxyHandler.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict' - -/** - * adonis-redis - * - * (c) Harminder Virk - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. -*/ - -const proxyHandler = exports = module.exports = {} - -proxyHandler.get = function (target, name) { - /** - * Node.js inspecting target - */ - if (typeof (name) === 'symbol' || name === 'inspect') { - return target[name] - } - - /** - * Property exists on target - */ - if (typeof (target[name]) !== 'undefined') { - return target[name] - } - - const connection = target.connection() - if (typeof (connection[name]) === 'function') { - return connection[name].bind(connection) - } - - return target.connection()[name] -} diff --git a/src/RedisFactory/index.js b/src/RedisFactory/index.js deleted file mode 100644 index cfaa597..0000000 --- a/src/RedisFactory/index.js +++ /dev/null @@ -1,361 +0,0 @@ -'use strict' - -/** - * adonis-redis - * - * (c) Harminder Virk - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. -*/ - -const _ = require('lodash') -const IoRedis = require('ioredis') -const debug = require('debug')('adonis:redis') -const { resolver } = require('@adonisjs/fold') -const GE = require('@adonisjs/generic-exceptions') - -const proxyHandler = require('./proxyHandler') - -class RedisFactory { - constructor (config, useCluster = false) { - this._config = config - this._useCluster = useCluster - - /** - * The main redis connection. - * - * @attribute connection - * - * @type {Object} - */ - this.connection = null - - /** - * The list of subscribers for different channels - * - * @type {Array} - */ - this.subscribers = {} - - /** - * The list of psubscribers for different channels - * - * @type {Array} - */ - this.psubscribers = {} - - /** - * The connection for subscribers, this connection is created - * automatically when you register a subscriber. - */ - this.subscriberConnection = null - - /** - * Connect to redis - */ - this.connect() - - return new Proxy(this, proxyHandler) - } - - /** - * Create a new redis connection - * - * @method _newConnection - * - * @return {Object} - * - * @example - * ```js - * { - * clusters: [{ - * port: 6380, - * host: '127.0.0.1' - * }], - * redisOptions: {} - * } - * ``` - * - * @private - */ - _newConnection () { - if (this._useCluster) { - debug('creating new redis cluster using config: %j', this._config) - return new IoRedis.Cluster(this._config.clusters, { redisOptions: this._config.redisOptions }) - } - debug('creating new redis connection using config: %j', this._config) - return new IoRedis(this._config) - } - - /** - * This method is invoked when redis pub/sub receives - * a new message, it's job is to call the registered - * subscribers - * - * @method _executeSubscribeListeners - * - * @param {String} channel - * @param {Mixed} message - * - * @return {void} - * - * @private - */ - _executeSubscribeListeners (channel, message) { - if (typeof (this.subscribers[channel]) === 'function') { - this.subscribers[channel](message, channel) - } - } - - /** - * This method is invoked when redis psubscribe receives - * a new message, it's job is to call the registered - * subscribers - * - * @method _executePSubscribeListeners - * - * @param {String} pattern - * @param {String} channel - * @param {Mixed} message - * - * @return {void} - * - * @private - */ - _executePSubscribeListeners (pattern, channel, message) { - if (typeof (this.psubscribers[pattern]) === 'function') { - this.psubscribers[pattern](pattern, message, channel) - } - } - - /** - * Closes the redis connection first by removing - * all attached listeners - * - * @method _closeConnection - * - * @param {Object} connection - * - * @return {Promise} - * - * @private - */ - _closeConnection (connection) { - debug('closing redis connection') - return new Promise((resolve, reject) => { - connection.quit((response) => { - connection.removeAllListeners() - return response - }).then(resolve).catch(reject) - }) - } - - /** - * Creates subscribe connection only if doesn't - * exists - * - * @method _setupSubscriberConnection - * - * @return {void} - * - * @private - */ - _setupSubscriberConnection () { - if (!this.subscriberConnection) { - debug('creating new subscription connection') - this.subscriberConnection = this._newConnection() - this.subscriberConnection.on('message', this._executeSubscribeListeners.bind(this)) - this.subscriberConnection.on('pmessage', this._executePSubscribeListeners.bind(this)) - } - } - - /** - * Creates a new redis connection - * - * @method connect - * - * @return {void} - */ - connect () { - this.connection = this._newConnection() - } - - /** - * Subscribe to a channel - * - * @method subscribe - * @async - * - * @param {String} channel - * @param {Function|String} handler - * - * @return {void} - */ - subscribe (channel, handler) { - return new Promise((resolve, reject) => { - if (typeof (handler) !== 'function' && typeof (handler) !== 'string') { - throw GE - .InvalidArgumentException - .invalidParameter('Redis.subscribe needs a callback function or ioc reference string', handler) - } - - const { method } = resolver.forDir('listeners').resolveFunc(handler) - this._setupSubscriberConnection() - - /** - * Cannot have multiple subscribers on a single channel - */ - if (this.subscribers[channel]) { - reject(GE.RuntimeException.invoke(`Cannot subscribe to ${channel} channel twice`)) - return - } - - /** - * Otherwise subscribe with redis - */ - debug('setting up subscriber for %s', channel) - this.subscriberConnection.subscribe(channel, (error, count) => { - if (error) { - reject(error) - return - } - this.subscribers[channel] = method - resolve() - }) - }) - } - - /** - * Subscribe to a pattern on redis - * - * @method psubscribe - * @async - * - * @param {String} pattern - * @param {Function|String} handler - * - * @return {void} - */ - psubscribe (pattern, handler) { - return new Promise((resolve, reject) => { - if (typeof (handler) !== 'function' && typeof (handler) !== 'string') { - throw GE - .InvalidArgumentException - .invalidParameter('Redis.psubscribe needs a callback function or ioc reference string', handler) - } - - const { method } = resolver.forDir('listeners').resolveFunc(handler) - this._setupSubscriberConnection() - - /** - * Cannot have multiple subscribers on a single channel - */ - if (this.psubscribers[pattern]) { - reject(new Error(`Cannot subscribe to ${pattern} pattern twice`)) - return - } - - /** - * Otherwise subscribe with redis - */ - debug('setting up psubscriber for %s', pattern) - this.subscriberConnection.psubscribe(pattern, (error, count) => { - if (error) { - reject(error) - return - } - this.psubscribers[pattern] = method - resolve() - }) - }) - } - - /** - * Unsubscribe from a channel. If there are no subscribers for - * any channels, this method will close the subscription - * connection with redis. - * - * @method unsubscribe - * @async - * - * @param {String} channel - * - * @return {String} `OK` is return if unsubscribed - */ - unsubscribe (channel) { - return new Promise((resolve, reject) => { - _.unset(this.subscribers, channel) - - if (!this.subscriberConnection) { - resolve('OK') - } - - this - .subscriberConnection - .unsubscribe(channel) - .then(() => { - /** - * Close subscriber connection when there are no - * subscribers for any channels - */ - if (_.size(this.subscribers) === 0) { - return this._closeConnection(this.subscriberConnection) - } - return 'OK' - }).then(resolve).catch(reject) - }) - } - - /** - * Unsubscribe from a pattern. If there are no subscribers for - * any patterns, this method will close the subscription - * connection with redis. - * - * @method punsubscribe - * @async - * - * @param {String} pattern - * - * @return {String} `OK` is return if unsubscribed - */ - punsubscribe (pattern) { - return new Promise((resolve, reject) => { - _.unset(this.psubscribers, pattern) - - if (!this.subscriberConnection) { - resolve('OK') - } - - this - .subscriberConnection - .punsubscribe(pattern) - .then(() => { - /** - * Close subscriber connection when there are no - * subscribers for any patterns - */ - if (_.size(this.psubscribers) === 0) { - return this._closeConnection(this.subscriberConnection) - } - return 'OK' - }).then(resolve).catch(reject) - }) - } - - /** - * Closes redis connection - * - * @return {Promise} - * - * @public - */ - quit () { - return Promise.all(_([this.connection, this.subscriberConnection]) - .filter((connection) => connection && connection.status !== 'end') - .map((connection) => this._closeConnection(connection)) - .value()) - } -} - -module.exports = RedisFactory diff --git a/src/RedisFactory/proxyHandler.js b/src/RedisFactory/proxyHandler.js deleted file mode 100644 index 543429e..0000000 --- a/src/RedisFactory/proxyHandler.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict' - -/** - * adonis-redis - * - * (c) Harminder Virk - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. -*/ -let proxyHandler = exports = module.exports = {} - -/** - * proxies the target attributes and returns defined implementation - * for them - * - * @param {Object} target - * @param {String} name - * - * @return {Mixed} - * @public - */ -proxyHandler.get = function (target, name) { - /** - * Node.js inspecting target - */ - if (typeof (name) === 'symbol' || name === 'inspect') { - return target[name] - } - - /** - * Property exists on target - */ - if (typeof (target[name]) !== 'undefined') { - return target[name] - } - - if (typeof (target.connection[name]) === 'function') { - return target.connection[name].bind(target.connection) - } - - /** - * Fallback to redis connection - */ - return target.connection[name] -} diff --git a/test/redis-factory.spec.js b/test/redis-factory.spec.js deleted file mode 100644 index e836bd8..0000000 --- a/test/redis-factory.spec.js +++ /dev/null @@ -1,266 +0,0 @@ -'use strict' - -/** - * adonis-redis - * - * (c) Harminder Virk - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. -*/ - -const test = require('japa') -const { ioc } = require('@adonisjs/fold') -const { setupResolver } = require('@adonisjs/sink') - -const RedisFactory = require('../src/RedisFactory') - -test.group('RedisFactory', function (group) { - group.before(() => { - ioc.restore() - setupResolver() - }) - - test('should setup connection with redis', (assert, done) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - redis.once('connect', function () { - redis.quit() - done() - }) - }) - - test('should use proxy to call command over redis client', async (assert) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - redis.set('foo', 'bar') - const foo = await redis.get('foo') - assert.equal(foo, 'bar') - await redis.quit() - }) - - test('should proxy ioredis error event', (assert, done) => { - const redis = new RedisFactory({port: 6389, host: 'localhost', retryStrategy: function () { return null }}) - redis.on('error', function (error) { - assert.equal(error.code, 'ECONNREFUSED') - done() - }) - }) - - test('should be able to quit redis connection', (assert, done) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - redis.once('end', () => { - done() - }) - redis.quit() - }) - - test('should be able to set/get buffer', async (assert) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - redis.set('foo', Buffer.from('bar')) - const foo = await redis.getBuffer('foo') - assert.equal(foo instanceof Buffer, true) - await redis.quit() - }) - - test('subscribe to a channel', async (assert) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - await redis.subscribe('news', function () { }) - assert.isDefined(redis.subscribers.news) - await redis.quit() - }) - - test('subscribing multiple times should throw exception', async (assert) => { - assert.plan(1) - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - await redis.subscribe('news', function () { }) - try { - await redis.subscribe('news', function () { }) - } catch ({ message }) { - assert.match(message, /E_RUNTIME_ERROR: Cannot subscribe to news channel twice/) - } - await redis.quit() - }) - - test('do not register any subscribers when unable to subscribe', async (assert) => { - assert.plan(3) - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - redis.subscriberConnection = redis._newConnection() - try { - await redis.subscriberConnection.quit() - await redis.subscribe('news', function () { }) - } catch ({ message }) { - assert.equal(message, 'Connection is closed.') - assert.deepEqual(redis.subscribers, {}) - assert.equal(redis.subscriberConnection.listenerCount('message'), 0) - } - await redis.quit() - }) - - test('should be able to define subscriber as an autoload namespace', (assert, done) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - const RedisSubscriber = { - async onNewUser (message) { - assert.equal(message, 'virk') - await redis.quit() - done() - } - } - - ioc.fake('App/Listeners/Redis', function () { - return RedisSubscriber - }) - - redis - .subscribe('new:user', 'Redis.onNewUser') - .then(() => { - redis.publish('new:user', 'virk') - }).catch(done) - }) - - test('unsubscribe from a channel', (assert, done) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - redis - .subscribe('new:user', function () {}) - .then(() => { - return redis.unsubscribe('new:user') - }).then(() => { - setTimeout(() => { - assert.isUndefined(redis.subscribers['new:user']) - assert.deepEqual(redis.subscribers, {}) - assert.equal(redis.subscriberConnection.listenerCount('message'), 0) - assert.equal(redis.subscriberConnection.listenerCount('pmessage'), 0) - return redis.quit() - }) - }).then(() => { - done() - }).catch(done) - }) - - test('subscribe to a pattern', async (assert) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - await redis.psubscribe('new?', function () { }) - assert.isDefined(redis.psubscribers['new?']) - await redis.quit() - }) - - test('receive messages related to a pattern', (assert, done) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - redis - .psubscribe('new?', async function (pattern, message, channel) { - assert.equal(pattern, 'new?') - assert.equal(message, 'hello') - assert.equal(channel, 'news') - await redis.quit() - done() - }) - .then(() => { - redis.publish('news', 'hello') - }) - }) - - test('unsubscribe from a pattern', (assert, done) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - - redis.once('connect', function () { - redis - .psubscribe('new?', function () {}) - .then(() => { - return redis.punsubscribe('new?') - }) - .then(() => { - setTimeout(() => { - assert.isUndefined(redis.psubscribers['new:user']) - assert.deepEqual(redis.psubscribers, {}) - assert.equal(redis.subscriberConnection.listenerCount('message'), 0) - assert.equal(redis.subscriberConnection.listenerCount('pmessage'), 0) - return redis.quit() - }) - }).then(() => { - done() - }).catch(done) - }) - }) - - test('should throw error when subscriber handler is not defined', async (assert) => { - assert.plan(1) - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - - try { - await redis.subscribe('bar', {}) - } catch ({ message }) { - assert.match(message, /E_INVALID_PARAMETER: Redis.subscribe needs a callback function or ioc reference string instead received object/) - } - - redis.quit() - }) - - test('should throw error when pattern subscriber handler is not defined', async (assert) => { - assert.plan(1) - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - - try { - await redis.psubscribe('new?', {}) - } catch ({ message }) { - assert.match(message, /E_INVALID_PARAMETER: Redis.psubscribe needs a callback function or ioc reference string instead received object/) - } - - redis.quit() - }) - - test('should not listen to messages on different channels', (assert, done) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - redis.subscribe('bar', async (message, channel) => { - assert.equal(channel, 'bar') - await redis.quit() - done() - }).then(function () { - redis.publish('foo', 'baz') - redis.publish('bar', 'baz') - }) - }) - - test('should be able to pipe commands', async (assert) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - const pipe = redis.pipeline() - const currentTime = new Date().getTime() - pipe.set('time', currentTime) - pipe.get('time') - const result = await pipe.exec() - assert.equal(result[1][1], currentTime.toString()) - await redis.quit() - }) - - test('should not throw exception when unsubscribing from unknown channels', async (assert) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - await redis.unsubscribe('bar') - await redis.quit() - }) - - test('should not throw exception when unsubscribing from unknown channels', async (assert) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - await redis.punsubscribe('new?') - await redis.quit() - }) - - test('should be able to pipeline commands', async (assert) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - const results = await redis.pipeline().set('foo', 'bar').get('foo').exec() - assert.deepEqual(results, [[null, 'OK'], [null, 'bar']]) - await redis.quit() - }) - - test('should close subscriber connection with normal connection when quit is called', (assert, done) => { - const redis = new RedisFactory({port: 6379, host: 'localhost'}) - - redis - .subscribe('foo', async function () {}) - .then(() => redis.quit()) - .then((response) => { - assert.deepEqual(response, ['OK', 'OK']) - setTimeout(() => { - assert.equal(redis.connection.status, 'end') - assert.equal(redis.subscriberConnection.status, 'end') - done() - }, 200) - }).catch(done) - }) -}) diff --git a/test/redis.spec.js b/test/redis.spec.js deleted file mode 100644 index 78eefbf..0000000 --- a/test/redis.spec.js +++ /dev/null @@ -1,212 +0,0 @@ -'use strict' - -/** - * adonis-redis - * - * (c) Harminder Virk - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. -*/ - -const test = require('japa') -const { Config } = require('@adonisjs/sink') -const Redis = require('../src/Redis') -const RedisFactory = require('../src/RedisFactory') - -test.group('Redis', () => { - test('should throw exception when connection is not defined in redis config file', (assert) => { - const connection = new Redis(new Config(), RedisFactory) - const fn = () => connection._getConfig() - assert.throw(fn, 'E_MISSING_CONFIG: configuration for redis is not defined inside config/redis.js file') - }) - - test('should return the instance of redis factory when using connection method', (assert, done) => { - const config = new Config() - config.set('redis', { - connection: 'primary', - primary: { host: '127.0.0.1', port: 6379 } - }) - - const connection = new Redis(config, RedisFactory) - connection.once('end', done) - connection.once('connect', () => { - assert.equal(connection.connection() instanceof RedisFactory, true) - connection.disconnect() - }) - - connection.connection() - }) - - test('should throw error when unable to find config for a given connection', async (assert) => { - const config = new Config() - config.set('redis', { - connection: 'primary', - primary: { host: '127.0.0.1', port: 6379 } - }) - - const connection = new Redis(config, RedisFactory) - const fn = () => connection.connection('foo') - assert.throw(fn, 'E_MISSING_CONFIG: foo is not defined inside config/redis.js file') - }) - - test('should proxy redis factory methods', (assert, done) => { - const config = new Config() - config.set('redis', { - connection: 'primary', - primary: { host: '127.0.0.1', port: 6379 } - }) - - const redis = new Redis(config, RedisFactory) - redis.on('end', done) - - redis.once('connect', () => { - const get = redis.get - assert.isFunction(get, 'function') - redis.disconnect() - }) - }) - - test('should be able to connect to redis to set and get data', (assert, done) => { - const config = new Config() - config.set('redis', { - connection: 'primary', - primary: { host: '127.0.0.1', port: 6379 } - }) - - const redis = new Redis(config, RedisFactory) - redis.once('end', done) - - redis.once('connect', () => { - redis.set('foo', 'bar') - redis - .get('foo') - .then((foo) => { - assert.equal(foo, 'bar') - redis.disconnect() - }) - .catch(done) - }) - }) - - test('should reuse the connection pool when trying to access redis for same connection', (assert, done) => { - const config = new Config() - config.set('redis', { - connection: 'primary', - primary: { host: '127.0.0.1', port: 6379 } - }) - - const redis = new Redis(config, RedisFactory) - redis.once('end', done) - - redis.once('connect', () => { - redis - .set('foo', 'bar') - .then(() => { - redis.get('foo') - }) - .then(() => { - assert.equal(Object.keys(redis.getConnections()).length, 1) - assert.property(redis.getConnections(), 'primary') - redis.disconnect() - }) - .catch(done) - }) - }) - - test('should close a given connection using quit method', async (assert) => { - const config = new Config() - config.set('redis', { - connection: 'primary', - primary: { host: '127.0.0.1', port: 6379 } - }) - - const redis = new Redis(config, RedisFactory) - await redis.set('foo', 'bar') - const response = await redis.quit('primary') - assert.deepEqual(response, [['OK']]) - assert.equal(Object.keys(redis.getConnections()).length, 0) - }) - - test('should throw an error event when unable to connect to redis', function (assert, done) { - const config = new Config() - config.set('redis', { - connection: 'primary', - primary: { host: '127.0.0.1', port: 6389 }, - secondary: 'self::redis.primary' - }) - - const redis = new Redis(config, RedisFactory) - - redis.on('error', (error) => { - redis.disconnect() - assert.equal(error.code, 'ECONNREFUSED') - }) - - redis.on('end', () => { - done() - }) - }) - - test('should be able to create a new redis connection using connection method', (assert, done) => { - const config = new Config() - config.set('redis', { - connection: 'primary', - primary: { host: '127.0.0.1', port: 6379 }, - secondary: 'self::redis.primary' - }) - - const redis = new Redis(config, RedisFactory) - redis.connection('secondary').on('end', done) - - redis.connection('secondary').on('connect', () => { - redis - .connection('secondary') - .set('foo', 'bar') - .then(() => { - return redis.connection('secondary').get('foo') - }) - .then((foo) => { - assert.equal(foo, 'bar') - assert.equal(Object.keys(redis.getConnections()).length, 1) - assert.property(redis.getConnections(), 'secondary') - redis.connection('secondary').disconnect() - }) - .catch(done) - }) - }) - - test('return connection and add it to the pool', (assert, done) => { - const config = new Config() - config.set('redis', { - connection: 'primary', - primary: { host: '127.0.0.1', port: 6379 } - }) - - const redis = new Redis(config, RedisFactory) - const rawConfig = { - host: '127.0.0.1', port: 6379 - } - - redis.namedConnection('secondary', rawConfig) - redis.namedConnection('secondary', rawConfig).on('end', done) - - redis.namedConnection('secondary', rawConfig).on('ready', () => { - redis - .connection('secondary') - .set('foo', 'bar') - .then(() => { - return redis.connection('secondary', rawConfig).get('foo') - }) - .then((foo) => { - assert.equal(foo, 'bar') - return redis.client('list') - }) - .then((connectedClients) => { - assert.equal(connectedClients.split('\n').filter((line) => line.trim()).length, 2) - redis.connection('secondary').disconnect() - }) - .catch(done) - }) - }) -}) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ff4e273 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./node_modules/@adonisjs/mrm-preset/_tsconfig" +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..5f51f2a --- /dev/null +++ b/tslint.json @@ -0,0 +1,6 @@ +{ + "extends": [ + "@adonisjs/mrm-preset/_tslint" + ], + "rules": {} +}