Skip to content

Commit

Permalink
Release v1.0.3 (#7)
Browse files Browse the repository at this point in the history
* Refactor and upgrade dependencies (#5)
* Prepare for release 1.0.3 (#6)
  • Loading branch information
Francesco authored Dec 13, 2021
1 parent e06315d commit ee41ea4
Show file tree
Hide file tree
Showing 13 changed files with 150 additions and 112 deletions.
7 changes: 6 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: ['./tsconfig.json']
},
plugins: [
'@typescript-eslint',
],
extends: [
'airbnb-base',
'airbnb-typescript/base',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking'
],
rules: {
'@typescript-eslint/indent': ['error', 4],
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Publish Package to npmjs

on:
release:
types: [ created ]

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16.x'
registry-url: 'https://registry.npmjs.org'
- run: npm install
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
28 changes: 28 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: run-tests

on:
push:
branches:
- main
- v1.x
pull_request:

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
node: [ '14.x', '16.x' ]

name: Node v${{ matrix.node }}

steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node }}
- run: npm install
- run: npm run lint
- run: npm run test
- run: npm run build
8 changes: 0 additions & 8 deletions .npmignore

This file was deleted.

22 changes: 7 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Cache JS

[![Build Status](https://travis-ci.com/Pod-Point/cache-js.svg?branch=master)](https://travis-ci.com/Pod-Point/cache-js)
![Build Status](https://github.com/Pod-Point/cache-js/actions/workflows/run-tests.yml/badge.svg)

A cache service for JS.

Expand Down Expand Up @@ -41,22 +41,14 @@ This package uses jest. To run the test suites for this project, run the followi
npm run test
```

### Releases
## License

This package is distributed via NPM and published automatically by Travis when creating a tagged commit. This can be done in one of 2 ways:
The MIT License (MIT). Please see [License File](LICENCE) for more information.

#### 1. Pre-merge via the CLI
---

**Before** merging your PR following code review & QA, run the following commands to update the package version and create a new release/tag.
```
npm version <major|minor|patch|prerelease>
git push && git push --tags
```

If you forget to do this before merging, this is not a problem, just create a new branch from master and run these same commands, remembering to open and merge a PR for this branch so that the `package.json` file is updated, alternatively, see option 2.

#### 2. Post-merge via code & GitHub
<img src="https://d3h256n3bzippp.cloudfront.net/pod-point-logo.svg" align="right" />

**After** merging your code changes, create a new branch/PR from master and update the package version in `package.json` to whatever you wish the next release to be.
Travel shouldn't damage the earth 🌍

**Before** merging this PR, create a release via GitHub with a tag version to match this package version number, this will trigger the tagged commit and in turn the automatic deployment to NPM.
Made with ❤️&nbsp;&nbsp;at [Pod Point](https://pod-point.com)
40 changes: 22 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pod-point/cache-js",
"version": "1.0.2",
"version": "1.0.3",
"description": "A cache service for JS.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand All @@ -20,30 +20,34 @@
"Cache",
"Redis"
],
"files": [
"lib"
],
"scripts": {
"build": "node_modules/.bin/tsc",
"lint": "node_modules/.bin/eslint 'src/**/*.{ts,tsx}'",
"build": "node_modules/.bin/tsc --project tsconfig.build.json",
"lint": "node_modules/.bin/eslint 'src/**/*.ts'",
"lint:fix": "npm run lint -- --fix",
"test": "node_modules/.bin/jest --watch",
"test": "node_modules/.bin/jest",
"test:watch": "node_modules/.bin/jest --watch",
"test:coverage": "node_modules/.bin/jest --coverage --runInBand --ci"
},
"dependencies": {
"redis": "^2.8.0"
"redis": "^3.1.2"
},
"devDependencies": {
"@types/faker": "^4.1.8",
"@types/jest": "^24.0.25",
"@types/node": "^13.1.1",
"@types/redis": "^2.8.14",
"@typescript-eslint/eslint-plugin": "^2.13.0",
"@typescript-eslint/parser": "^2.13.0",
"eslint": "^6.8.0",
"eslint-config-airbnb-typescript": "^6.3.1",
"eslint-plugin-import": "^2.19.1",
"faker": "^4.1.0",
"jest": "^24.9.0",
"ts-jest": "^24.2.0",
"typescript": "^3.7.4"
"@types/faker": "^5.5.9",
"@types/jest": "^27.0.3",
"@types/redis": "^2.8.32",
"@types/node": "^16.11.12",
"@typescript-eslint/eslint-plugin": "^5.6.0",
"@typescript-eslint/parser": "^5.6.0",
"eslint": "^8.4.1",
"eslint-config-airbnb-typescript": "^16.1.0",
"eslint-plugin-import": "^2.25.3",
"faker": "^5.5.3",
"jest": "^27.4.4",
"ts-jest": "^27.1.1",
"typescript": "^4.5.3"
},
"jest": {
"collectCoverageFrom": [
Expand Down
5 changes: 5 additions & 0 deletions src/__tests__/services/redis/Redis.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { createClient } from 'redis';
import Redis from '../../../services/Redis';

/* eslint-disable
@typescript-eslint/no-unsafe-call,
@typescript-eslint/no-unsafe-return
*/
const mockSet = jest.fn((key, value, cb) => cb());
const mockQuit = jest.fn();
const mockDel = jest.fn((key, cb) => cb());
const mockExpire = jest.fn((key, time, cb) => cb());
const mockExpireAt = jest.fn((key, time, cb) => cb());
const mockGet = jest.fn((key, cb) => cb(null, 'someData'));
/* eslint-enable */

jest.mock('redis', () => ({
createClient: jest.fn(() => ({
Expand Down
88 changes: 41 additions & 47 deletions src/services/Redis.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,56 @@
import { ClientOpts, createClient } from 'redis';
import { ClientOpts, createClient, RedisClient } from 'redis';
import { promisify } from 'util';
import Expire from '../types/Expire';
import Service from '../types/Service';
import RedisService from '../types/redis/Service';

class Redis implements Service {
private config: ClientOpts;
interface AsyncRedisClient {
del: (key: string) => Promise<void>;
expire: (key: string, seconds: number) => Promise<void>;
expireAt: (key: string, seconds: number) => Promise<void>;
get: (key: string) => Promise<string>;
quit: () => void
set: (key: string, value: string) => Promise<void>;
}

function getClient(client: RedisClient): AsyncRedisClient {
return {
/* eslint-disable
@typescript-eslint/unbound-method,
@typescript-eslint/no-unsafe-assignment
*/
del: promisify(client.del).bind(client),
expire: promisify(client.expire).bind(client),
expireAt: promisify(client.expireat).bind(client),
get: promisify(client.get).bind(client),
quit: client.quit as () => void,
set: promisify(client.set).bind(client),
/* eslint-enable */
};
}

export default class Redis implements Service {
private readonly config: ClientOpts;

private ephemeral: boolean;
private readonly ephemeral: boolean;

private service: RedisService;
private readonly client: AsyncRedisClient;

/**
* Creates a Redis client instance depending on config.
*/
public constructor(config?: ClientOpts, ephemeral?: boolean) {
this.ephemeral = ephemeral;
this.config = config;

if (!this.ephemeral) {
this.service = this.getService(true);
}
this.client = getClient(createClient(config));
}

/**
* Retrieves the keys value from the cache.
*/
public async get(key: string): Promise<string> {
const service = this.getService();
const value = await this.client.get(key);

const value = await service.get(key);

this.quitIfNeeded(service);
this.quitIfNeeded();

return value;
}
Expand All @@ -41,61 +60,36 @@ class Redis implements Service {
* optionally setting it to expire at a particular time or in a given number of seconds.
*/
public async put(key: string, value: string, expire?: Expire): Promise<void> {
const service = this.getService();

await service.set(key, value);
await this.client.set(key, value);

if (expire) {
if (expire.at) {
await service.expireAt(key, expire.at);
await this.client.expireAt(key, expire.at);
}

if (expire.in) {
await service.expire(key, expire.in);
await this.client.expire(key, expire.in);
}
}

this.quitIfNeeded(service);
this.quitIfNeeded();
}

/**
* Removes the key/value pair from the cache.
*/
public async remove(key: string): Promise<void> {
const service = this.getService();
await this.client.del(key);

await service.del(key);

this.quitIfNeeded(service);
this.quitIfNeeded();
}

/**
* Quits the redis client if required.
*/
private async quitIfNeeded(service): Promise<void> {
private quitIfNeeded(): void {
if (this.ephemeral) {
service.client.quit();
}
}

/**
* Creates new Redis instance if one does not already exist or if is configured to be ephemeral.
*/
private getService(force: boolean = false): RedisService {
if (this.ephemeral || force) {
const client = createClient(this.config);
this.service = {
client,
del: promisify(client.del).bind(client),
expire: promisify(client.expire).bind(client),
expireAt: promisify(client.expireat).bind(client),
get: promisify(client.get).bind(client),
set: promisify(client.set).bind(client),
};
this.client.quit();
}

return this.service;
}
}

export default Redis;
14 changes: 11 additions & 3 deletions src/types/Expire.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
interface Expire {
interface ExpireAt {
/**
* The timestamp when the key/value pair should expire.
*/
at?: number;
at: number;

in?: never;
}

interface ExpireIn {
/**
* The number of seconds until the key/value pair should expire.
*/
in?: number;
in: number;

at?: never;
}

type Expire = ExpireAt | ExpireIn;

export default Expire;
8 changes: 4 additions & 4 deletions src/types/Service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
interface Service {
import Expire from './Expire';

export default interface Service {
/**
* Retrieves the keys value from the cache.
*/
Expand All @@ -7,12 +9,10 @@ interface Service {
/**
* Persists the key/value pair in the cache.
*/
put(key: string, value: string): Promise<void>;
put(key: string, value: string, expire: Expire): Promise<void>;

/**
* Removes the key/value pair from the cache.
*/
remove(key: string): Promise<void>;
}

export default Service;
12 changes: 0 additions & 12 deletions src/types/redis/Service.ts

This file was deleted.

7 changes: 7 additions & 0 deletions tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"exclude": [
"**/__mocks__",
"**/__tests__"
]
}
Loading

0 comments on commit ee41ea4

Please sign in to comment.