diff --git a/.eslintrc.js b/.eslintrc.js index 885e908..7d487c3 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,31 +3,34 @@ module.exports = { root: true, parser: '@typescript-eslint/parser', plugins: ['@typescript-eslint'], - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended' + ], rules: { '@typescript-eslint/no-explicit-any': 'off', - "@typescript-eslint/no-unused-vars": [ - "warn", + '@typescript-eslint/no-unused-vars': [ + 'warn', { - "args": "all", - "argsIgnorePattern": "^_", - "caughtErrors": "all", - "caughtErrorsIgnorePattern": "^_", - "destructuredArrayIgnorePattern": "^_", - "varsIgnorePattern": "^_", - "ignoreRestSiblings": true - } + args: 'all', + argsIgnorePattern: '^_', + caughtErrors: 'all', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + varsIgnorePattern: '^_', + ignoreRestSiblings: true, + }, ], 'no-undef': 'off', 'semi': ['warn', 'always'], 'no-multi-spaces': 'warn', 'no-trailing-spaces': 'warn', 'space-before-function-paren': ['warn', 'always'], - 'func-style': ['warn', 'declaration', { 'allowArrowFunctions': true }], + 'func-style': ['warn', 'declaration', { allowArrowFunctions: true }], 'camelcase': 'warn', '@typescript-eslint/explicit-function-return-type': ['warn', { allowExpressions: true }], '@typescript-eslint/explicit-member-accessibility': ['off', { accessibility: 'explicit' }], 'no-unused-vars': 'warn', 'no-extra-semi': 'warn', }, -}; \ No newline at end of file +}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..99db3dd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,40 @@ +name: knights-ecomm-be CI + +on: [push, pull_request] + +env: + DEV_DB_HOST: ${{secrets.DEV_DB_HOST}} + DEV_DB_PORT: ${{secrets.DEV_DB_PORT}} + DEV_DB_USER: ${{secrets.DEV_DB_USER}} + DEV_DB_PASS: ${{secrets.DEV_DB_PASS}} + DEV_DB_NAME: ${{secrets.DEV_DB_NAME}} + +jobs: + build-lint-test-coverage: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install dependencies + run: npm install + + - name: Run ESLint and Prettier + run: npm run lint + + - name: Build project + run: npm run build --if-present + + - name: Run tests + run: npm test + + - name: Upload coverage report to Coveralls + uses: coverallsapp/github-action@v2.2.3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 1500c37..66612c2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ package-lock.json coverage/ dist /src/logs -.DS_Store \ No newline at end of file +.DS_Stor \ No newline at end of file diff --git a/README.md b/README.md index 96947a9..782f032 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,9 @@ functionalities for the frontend, such as storing, retrieving, deleting data and List of endpoints exposed by the service ## Setup + - to use loggers in program use below functions + ```bash logger.error('This is an error message'); logger.warn('This is a warning message'); diff --git a/jest.config.ts b/jest.config.ts index 3d8dfdc..296ffe3 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,18 +1,18 @@ /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */ export default { - preset: "ts-jest", - testEnvironment: "node", - testMatch: ["**/**/*.test.ts"], - verbose: true, - forceExit: true, - clearMocks: true, - resetMocks: true, - restoreMocks: true, - collectCoverageFrom: [ - "src/**/*.{ts,tsx}", // Include all JavaScript/JSX files in the src directory - ], - coveragePathIgnorePatterns: [ - "/node_modules/", // Exclude the node_modules directory - "/__tests__/", // Exclude the tests directory - ], - }; + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/**/*.test.ts'], + verbose: true, + forceExit: true, + clearMocks: true, + resetMocks: true, + restoreMocks: true, + collectCoverageFrom: [ + 'src/**/*.{ts,tsx}', // Include all JavaScript/JSX files in the src directory + ], + coveragePathIgnorePatterns: [ + '/node_modules/', // Exclude the node_modules directory + '/__tests__/', // Exclude the tests directory + ], +}; diff --git a/ormconfig.js b/ormconfig.js new file mode 100644 index 0000000..a4d78a5 --- /dev/null +++ b/ormconfig.js @@ -0,0 +1,24 @@ +module.exports = { + "type": "postgres", + "host": `${process.env.DEV_DB_HOST}`, + "port": `${process.env.DEV_DB_PORT}`, + "username": `${process.env.DEV_DB_USER}`, + "password": `${process.env.DEV_DB_PASS}`, + "database": `${process.env.DEV_DB_NAME}`, + "synchronize": true, + "logging": false, + "entities": [ + "src/entities/**/*.ts" + ], + "migrations": [ + "src/migrations/**/*.ts" + ], + "subscribers": [ + "src/subscribers/**/*.ts" + ], + "cli": { + "entitiesDir": "src/entities", + "migrationsDir": "src/migrations", + "subscribersDir": "src/subscribers" + } +}; \ No newline at end of file diff --git a/src/__test__/route.test.ts b/src/__test__/route.test.ts index af92a44..401f5b8 100644 --- a/src/__test__/route.test.ts +++ b/src/__test__/route.test.ts @@ -1,14 +1,24 @@ import request from 'supertest'; -import {app, server} from '../index'; // update this with the path to your app file +import { app, server } from '../index'; // update this with the path to your app file + +import { createConnection, getConnection, getConnectionOptions } from 'typeorm'; + +beforeAll(async () => { + // Connect to the test database + const connectionOptions = await getConnectionOptions(); + await createConnection({ ...connectionOptions, name: 'testConnection' }); +}); +afterAll(async () => { + await getConnection('testConnection').close(); + server.close(); +}); describe('GET /', () => { - afterAll(done => { - server.close(done); - }); + // afterAll(done => { + // server.close(done); + // }); it('responds with "Knights Ecommerce API"', done => { - request(app) - .get('/') - .expect(200, 'Knights Ecommerce API', done); + request(app).get('/').expect(200, 'Knights Ecommerce API', done); }); }); diff --git a/src/configs/db_config.ts b/src/configs/db_config.ts deleted file mode 100644 index d2a19a4..0000000 --- a/src/configs/db_config.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { DataSource } from 'typeorm'; - -const PORT = process.env.DEV_DB_PORT; -const DB_HOST = process.env.DEV_DB_HOST; -const DB_USER = process.env.DEV_DB_USER; -const DB_PASS = process.env.DEV_DB_PASS; -const DB_NAME = process.env.DEV_DB_NAME; -const DEV_DB_TYPE = process.env.DEV_DB_TYPE; - -const port = PORT ? Number(PORT) : 5432; -const dbHost = DB_HOST ? DB_HOST : 'localhost'; -const dbUser = DB_USER ? DB_USER : 'test'; -const dbPass = DB_PASS ? DB_PASS : 'test'; -const dbName = DB_NAME ? DB_NAME : 'test'; -const dbType = DEV_DB_TYPE ? DEV_DB_TYPE : 'postgres'; - -const OrmConfig = new DataSource({ - type: dbType as any, - host: dbHost, - port: port, - username: dbUser, - password: dbPass, - database: dbName, - synchronize: true, - logging: false, -}); - -export { OrmConfig }; diff --git a/src/controllers/index.ts b/src/controllers/index.ts index 8c85221..4ba41c9 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -1,5 +1,5 @@ // export all controllers -function myFunction () { +function myFunction (): void { console.log('Hello'); } myFunction(); diff --git a/src/index.ts b/src/index.ts index d118a8e..36b592e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,7 +10,7 @@ import { dbConnection } from './startups/dbConnection'; dotenv.config(); export const app = express(); -const port = process.env.PORT as string; +const port = process.env.PORT || 8000; app.use(express.json()); app.use(cors({ origin: '*' })); diff --git a/src/middlewares/errorHandler.ts b/src/middlewares/errorHandler.ts index 74cca91..e4e967f 100644 --- a/src/middlewares/errorHandler.ts +++ b/src/middlewares/errorHandler.ts @@ -1,30 +1,25 @@ import { Request, Response } from 'express'; class CustomError extends Error { - statusCode: number; - status: string; + statusCode: number; + status: string; - constructor (message: string, statusCode: number) { - super(message); - this.statusCode = statusCode; - this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error'; - Error.captureStackTrace(this, this.constructor); - } + constructor (message: string, statusCode: number) { + super(message); + this.statusCode = statusCode; + this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error'; + Error.captureStackTrace(this, this.constructor); + } } -const errorHandler = ( - err: CustomError, - req: Request, - res: Response, - -) => { - err.statusCode = err.statusCode || 500; - err.status = err.status || 'error'; - res.status(err.statusCode).json({ - status: err.statusCode, - message: err.message - }); - console.error(err.stack); +const errorHandler = (err: CustomError, req: Request, res: Response) => { + err.statusCode = err.statusCode || 500; + err.status = err.status || 'error'; + res.status(err.statusCode).json({ + status: err.statusCode, + message: err.message, + }); + console.error(err.stack); }; export { CustomError, errorHandler }; diff --git a/src/startups/dbConnection.ts b/src/startups/dbConnection.ts index fc7843a..7fb387c 100644 --- a/src/startups/dbConnection.ts +++ b/src/startups/dbConnection.ts @@ -1,14 +1,11 @@ -import { OrmConfig } from "../configs/db_config"; +import { createConnection } from "typeorm"; const dbConnection = async () => { - await OrmConfig.initialize() - .then(() => { - console.log("[db]: Database connected successfully"); - }) - .catch((error) => { - console.log("[db]: Database connection failed"); - console.log(error); - }); + try { + const connection = await createConnection(); + console.log('Connected to the database'); + } catch (error) { + console.error('Error connecting to the database:', error); + } }; - export { dbConnection }; diff --git a/src/utils/response.utils.ts b/src/utils/response.utils.ts index 0f4b680..6f097a7 100644 --- a/src/utils/response.utils.ts +++ b/src/utils/response.utils.ts @@ -9,13 +9,13 @@ interface ApiResponse { export const responseSuccess = ( res: Response, - status_code: number, + statusCode: number, message: string, data?: any ): Response => { return res.status(200).json( jsend.success({ - code: status_code, + code: statusCode, message, data, }) @@ -24,13 +24,13 @@ export const responseSuccess = ( export const responseError = ( res: Response, - status_code: number, + statusCode: number, message: string, data?: any ): Response => { return res.status(400).json( jsend.error({ - code: status_code, + code: statusCode, message, data, })