Last active
August 18, 2024 02:07
-
-
Save aldy505/e2c65663ccedb30536f1f39ea2ba57da to your computer and use it in GitHub Desktop.
Async Redis functions in Typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file redis.ts | |
* @fileoverview Async Redis functions with JSDoc annotations | |
* @author Reinaldy Rafli <[email protected]> | |
* @copyright 2021 MIT | |
*/ | |
import path from 'path'; | |
import * as RedisModule from 'redis'; | |
import * as dotenv from 'dotenv'; | |
dotenv.config({ path: path.resolve(__dirname, '.env') }); | |
const client = RedisModule.createClient(String(process.env.REDIS_URL)); | |
interface SetOptions { | |
mode?: string, | |
duration?: number, | |
flag?: string | |
} | |
const redis = { | |
/** | |
* Returns PONG if no argument is provided, otherwise return a copy of the argument as a bulk. | |
* This command is often used to test if a connection is still alive, or to measure latency. | |
* @returns {Promise<String>} Reply | |
* @see Documentation https://redis.io/commands/ping | |
*/ | |
PING(): Promise<String> { | |
return new Promise((resolve, reject) => { | |
client.PING((error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Ask the server to close the connection. | |
* The connection is closed as soon as all pending replies have been written to the client. | |
* @returns {Promise<String>} "OK" | |
* @see Documentation https://redis.io/commands/quit | |
*/ | |
QUIT(): Promise<string> { | |
return new Promise((resolve, reject) => { | |
client.QUIT((error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Get the value of key. If the key does not exist the special value nil is returned. | |
* An error is returned if the value stored at key is not a string, because GET only handles string values. | |
* @param {String} key Key | |
* @returns {Promise<string|null>} The value of key, or nil when key does not exist. | |
* @see Documentation https://redis.io/commands/get | |
*/ | |
GET(key: string): Promise<string|null> { | |
return new Promise((resolve, reject) => { | |
client.GET(key, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Returns the values of all specified keys. | |
* For every key that does not hold a string value or does not exist, the special value nil is returned. | |
* Because of this, the operation never fails. | |
* @param {Array<string>} key Array of keys | |
* @returns {Promise<Array<string>>} List of values at the specified keys. | |
* @see Documentation https://redis.io/commands/mget | |
*/ | |
MGET(...key: Array<string>): Promise<Array<string>> { | |
return new Promise((resolve, reject) => { | |
client.MGET(key.flat(99), (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Returns all keys matching pattern. | |
* @param {String} pattern Glob-style pattern | |
* @returns {Promise<Array<string>>} list of keys matching pattern. | |
* @see Documentation https://redis.io/commands/keys | |
*/ | |
KEYS(pattern: string): Promise<Array<string>> { | |
return new Promise((resolve, reject) => { | |
client.KEYS(pattern, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Set key to hold the string value. | |
* If key already holds a value, it is overwritten, regardless of its type. | |
* Any previous time to live associated with the key is discarded on successful SET operation. | |
* @param {String} key Key | |
* @param {String} value Value | |
* @param {SetOptions} options | |
* @returns {Promise<string|undefined>} "OK" | |
* @see Documentation https://redis.io/commands/set | |
*/ | |
SET(key: string, value: string, options?: SetOptions): Promise<string|undefined> { | |
return new Promise((resolve, reject) => { | |
client.SET(key, value, options?.mode ?? '', options?.flag ?? '', options?.duration ?? 0, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Put a key and value to Redis if not exists | |
* @param {String} key Key | |
* @param {String} value Value | |
* @returns {Promise<Number>} 1 if key was set, 0 if key wasn't set | |
* @see Documentation https://redis.io/commands/setnx | |
*/ | |
SETNX(key: string, value: string): Promise<number> { | |
return new Promise((resolve, reject) => { | |
client.SETNX(key, value, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Set key to hold the string value and set key to timeout after a given number of seconds. | |
* @param {String} key Key | |
* @param {Number} seconds Expiry time in seconds | |
* @param {String} value Value | |
* @returns {Promise<String>} "OK" | |
* @see Documentation https://redis.io/commands/setex | |
*/ | |
SETEX(key: string, seconds: number, value: string): Promise<string> { | |
return new Promise((resolve, reject) => { | |
client.SETEX(key, seconds, value, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Sets the given keys to their respective values. | |
* @param {Array<String>} keys Keys and Values | |
* @returns {Promise<boolean>} True if the all the keys were set. False if no key was set (at least one key already existed). | |
* @see Documentation https://redis.io/commands/mset | |
*/ | |
MSET(...keys: Array<string>): Promise<boolean> { | |
return new Promise((resolve, reject) => { | |
client.MSET(keys.flat(99), (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Sets the given keys to their respective values. | |
* MSETNX will not perform any operation at all even if just a single key already exists. | |
* @param {Array<String>} keys Keys and Values | |
* @returns {Promise<boolean>} True if the all the keys were set. False if no key was set (at least one key already existed). | |
* @see Documentation https://redis.io/commands/msetnx | |
*/ | |
MSETNX(...keys: Array<string>): Promise<boolean> { | |
return new Promise((resolve, reject) => { | |
client.MSETNX(keys.flat(99), (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Returns if key exists. | |
* @param {String} key Key | |
* @returns {Promise<Number>} 1 if key exists, 0 is key doesn't exist. | |
* @see Documentation https://redis.io/commands/exists | |
*/ | |
EXISTS(key: string): Promise<number> { | |
return new Promise((resolve, reject) => { | |
client.EXISTS(key, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Renames key to newkey. It returns an error when key does not exist. | |
* If newkey already exists it is overwritten, when this happens RENAME executes an implicit DEL operation, | |
* so if the deleted key contains a very big value it may cause high latency | |
* even if RENAME itself is usually a constant-time operation. | |
* @param {String} key Old Key | |
* @param {String} newkey New Key | |
* @returns {Promise<String>} "OK" | |
* @see Documentation https://redis.io/commands/rename | |
*/ | |
RENAME(key: string, newkey: string): Promise<string> { | |
return new Promise((resolve, reject) => { | |
client.RENAME(key, newkey, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Set a timeout on key. After the timeout has expired, the key will automatically be deleted. | |
* A key with an associated timeout is often said to be volatile in Redis terminology. | |
* @param {String} key Key | |
* @param {Number} seconds Expiry time in seconds | |
* @returns {Promise<number>} 1 is timeout was set. 0 if key does not exist. | |
* @see Documentation https://redis.io/commands/expire | |
*/ | |
EXPIRE(key: string, seconds: number): Promise<number> { | |
return new Promise((resolve, reject) => { | |
client.EXPIRE(key, seconds, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Returns the remaining time to live of a key that has a timeout. | |
* This introspection capability allows a Redis client to check how many seconds a given key | |
* will continue to be part of the dataset. | |
* @param {String} key Key | |
* @returns {Promise<number>} TTL in seconds, or a negative value in order to signal an error. | |
* @see Documentation https://redis.io/commands/ttl | |
*/ | |
TTL(key: string): Promise<number> { | |
return new Promise((resolve, reject) => { | |
client.TTL(key, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Remove the existing timeout on key, turning the key from volatile (a key with an expire set) | |
* to persistent (a key that will never expire as no timeout is associated). | |
* @param {String} key Key | |
* @returns {Promise<Number>} 1 if the timeout was removed. 0 if key does not exist or does not have an associated timeout. | |
* @see Documentation https://redis.io/commands/persist | |
*/ | |
PERSIST(key: string): Promise<number> { | |
return new Promise((resolve, reject) => { | |
client.PERSIST(key, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Returns the string representation of the type of the value stored at key. | |
* The different types that can be returned are: string, list, set, zset, hash and stream. | |
* @param {String} key Key | |
* @returns {Promise<String>} type of key, or none when key does not exist. | |
* @see Documentation https://redis.io/commands/type | |
*/ | |
TYPE(key: string): Promise<string> { | |
return new Promise((resolve, reject) => { | |
client.TYPE(key, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Increments the number stored at key by one. | |
* If the key does not exist, it is set to 0 before performing the operation. | |
* An error is returned if the key contains a value of the wrong type or contains a string | |
* that can not be represented as integer. | |
* This operation is limited to 64 bit signed integers. | |
* @param {String} key Key | |
* @returns {Promise<Number>} the value of key after the increment | |
* @see Documentation https://redis.io/commands/incr | |
*/ | |
INCR(key: string): Promise<number> { | |
return new Promise((resolve, reject) => { | |
client.INCR(key, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Decrements the number stored at key by one. | |
* If the key does not exist, it is set to 0 before performing the operation. | |
* An error is returned if the key contains a value of the wrong type or contains a string that can not be represented as integer. | |
* This operation is limited to 64 bit signed integers. | |
* @param {String} key Key | |
* @returns {Promise<Number>} the value of key after the decrement | |
* @see Documentation https://redis.io/commands/decr | |
*/ | |
DECR(key: string): Promise<number> { | |
return new Promise((resolve, reject) => { | |
client.DECR(key, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* If key already exists and is a string, this command appends the value at the end of the string. | |
* If key does not exist it is created and set as an empty string, so APPEND will be similar to SET in this special case. | |
* @param {String} key Key | |
* @param {String} value Added value | |
* @returns {Promise<Number>} the length of the string after the append operation. | |
* @see Documentation https://redis.io/commands/append | |
*/ | |
APPEND(key: string, value: string): Promise<number> { | |
return new Promise((resolve, reject) => { | |
client.APPEND(key, value, (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
/** | |
* Removes the specified keys. A key is ignored if it does not exist. | |
* @param {Array<String>} key Key | |
* @returns {Promise<Number>} The number of keys that were removed. | |
* @see Documentation https://redis.io/commands/del | |
*/ | |
DEL(...key: Array<string>): Promise<number> { | |
return new Promise((resolve, reject) => { | |
client.DEL(key.flat(99), (error, reply) => { | |
if (error) { | |
return reject(error); | |
} | |
return resolve(reply); | |
}); | |
}); | |
}, | |
}; | |
export default redis |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment