diff --git a/Makefile b/Makefile index 358ab79..526e965 100644 --- a/Makefile +++ b/Makefile @@ -30,31 +30,31 @@ dependencies: ## Install dependencies required by the application yarn install .PHONY: infra-up -infra-up: +infra-up: ## Run docker images docker-compose -f ./docker-compose.yml up -d .PHONY: infra-down -infra-down: +infra-down: ## Stop docker images docker-compose down .PHONY: run -run: +run: ## Run api in dev environment yarn dev .PHONY: build -build: +build: ## Build project yarn build .PHONY: check-format -check-format: +check-format: ## Check format using eslint and prettier yarn run lint && yarn run prettier .PHONY: format -format: +format: ## Format project with eslint and prettier yarn run lint:fix && yarn run prettier:fix .PHONY: db-generate -db-generate: +db-generate: ## Apply new model changes to db using prisma orm yarn run prisma generate .PHONY: db-push diff --git a/package.json b/package.json index ebfbfe2..96ef924 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { "name": "express-prisma-boilerplate", "version": "1.0.0", - "main": "index.js", + "main": "index.ts", + "type": "module", "license": "MIT", "author": "Rishit", "scripts": { @@ -37,6 +38,7 @@ "passport": "^0.6.0", "passport-jwt": "^4.0.1", "pm2": "^5.3.0", + "redis": "^4.6.10", "winston": "^3.10.0", "xss-filters": "^1.2.7" }, diff --git a/src/core/config.ts b/src/core/config.ts index c082d1b..1fdc0dc 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -8,6 +8,7 @@ const envVarsSchema = Joi.object() .keys({ ENVIRONMENT: Joi.string().valid('production', 'development', 'staging').required(), PORT: Joi.number().default(3000), + REDIS_URL: Joi.string().required(), JWT_SECRET: Joi.string().required(), JWT_ACCESS_EXPIRATION_MINUTES: Joi.number().required(), JWT_REFRESH_EXPIRATION_DAYS: Joi.number().required(), @@ -28,6 +29,7 @@ if (error) { export default { environment: envVars.ENVIRONMENT, port: envVars.PORT, + redisUrl: envVars.REDIS_URL, logging: { showSqlQueries: envVars.SHOW_SQL_QUERIES, }, diff --git a/src/core/redis.ts b/src/core/redis.ts new file mode 100644 index 0000000..cc73a7c --- /dev/null +++ b/src/core/redis.ts @@ -0,0 +1,37 @@ +import { createClient, SetOptions } from 'redis'; +import config from './config'; + +const RedisClient = await (async function () { + return await createClient({ + url: config.redisUrl, + }) + .on('error', (err) => console.log(err)) + .connect(); +})(); + +export const setValue = async ( + key: string, + value: any, + expiryInSeconds: number = 86400, + shouldNotPreExist: boolean = true, +) => { + await RedisClient.set(key, value, { + EX: expiryInSeconds, + NX: shouldNotPreExist, + } as SetOptions); +}; + +export const hSetValue = async (key: string, field: string, value: any) => { + await RedisClient.hSet(key, field, value); +}; + +export const getValue = async (key: string) => { + return await RedisClient.get(key); +}; + +export const hGetValue = async (key: string, onlyValues: boolean = false) => { + if (onlyValues) return await RedisClient.hVals(key); + return await RedisClient.hGetAll(key); +}; + +export default RedisClient; diff --git a/tsconfig.json b/tsconfig.json index db42beb..ba24498 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "ES2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ @@ -22,7 +22,7 @@ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ + "module": "CommonJS", /* Specify what module code is generated. */ // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ diff --git a/yarn.lock b/yarn.lock index 28f76a6..6d5d2fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -809,6 +809,40 @@ resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.3.1.tgz#53cc72a5ed176dc27d22305fe5569c64cc78b381" integrity sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA== +"@redis/bloom@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@redis/bloom/-/bloom-1.2.0.tgz#d3fd6d3c0af3ef92f26767b56414a370c7b63b71" + integrity sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg== + +"@redis/client@1.5.11": + version "1.5.11" + resolved "https://registry.yarnpkg.com/@redis/client/-/client-1.5.11.tgz#5ee8620fea56c67cb427228c35d8403518efe622" + integrity sha512-cV7yHcOAtNQ5x/yQl7Yw1xf53kO0FNDTdDU6bFIMbW6ljB7U7ns0YRM+QIkpoqTAt6zK5k9Fq0QWlUbLcq9AvA== + dependencies: + cluster-key-slot "1.1.2" + generic-pool "3.9.0" + yallist "4.0.0" + +"@redis/graph@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@redis/graph/-/graph-1.1.0.tgz#cc2b82e5141a29ada2cce7d267a6b74baa6dd519" + integrity sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg== + +"@redis/json@1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@redis/json/-/json-1.0.6.tgz#b7a7725bbb907765d84c99d55eac3fcf772e180e" + integrity sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw== + +"@redis/search@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@redis/search/-/search-1.1.5.tgz#682b68114049ff28fdf2d82c580044dfb74199fe" + integrity sha512-hPP8w7GfGsbtYEJdn4n7nXa6xt6hVZnnDktKW4ArMaFQ/m/aR7eFvsLQmG/mn1Upq99btPJk+F27IQ2dYpCoUg== + +"@redis/time-series@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@redis/time-series/-/time-series-1.0.5.tgz#a6d70ef7a0e71e083ea09b967df0a0ed742bc6ad" + integrity sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg== + "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -1749,6 +1783,11 @@ cliui@^8.0.1: strip-ansi "^6.0.1" wrap-ansi "^7.0.0" +cluster-key-slot@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" + integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -2620,6 +2659,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +generic-pool@3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.9.0.tgz#36f4a678e963f4fdb8707eab050823abc4e8f5e4" + integrity sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g== + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -4467,6 +4511,18 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +redis@^4.6.10: + version "4.6.10" + resolved "https://registry.yarnpkg.com/redis/-/redis-4.6.10.tgz#07f6ea2b2c5455b098e76d1e8c9b3376114e9458" + integrity sha512-mmbyhuKgDiJ5TWUhiKhBssz+mjsuSI/lSZNPI9QvZOYzWvYGejtb+W3RlDDf8LD6Bdl5/mZeG8O1feUGhXTxEg== + dependencies: + "@redis/bloom" "1.2.0" + "@redis/client" "1.5.11" + "@redis/graph" "1.1.0" + "@redis/json" "1.0.6" + "@redis/search" "1.1.5" + "@redis/time-series" "1.0.5" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -5264,16 +5320,16 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@4.0.0, yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yaml@2.0.0-1: version "2.0.0-1" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.0.0-1.tgz#8c3029b3ee2028306d5bcf396980623115ff8d18"