-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
252a138
commit 74f23ee
Showing
34 changed files
with
3,397 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
logs | ||
yarn-error.log |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dist | ||
node_modules | ||
.env |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"parser": "@typescript-eslint/parser", | ||
"parserOptions": { | ||
"ecmaVersion": 12, | ||
"sourceType": "module" | ||
}, | ||
"plugins": ["@typescript-eslint", "unused-imports"], | ||
"extends": [ | ||
"eslint:recommended", | ||
"plugin:@typescript-eslint/recommended", | ||
"prettier" | ||
], | ||
"rules": { | ||
"@typescript-eslint/no-unused-vars": "off", | ||
"@typescript-eslint/consistent-type-definitions": ["error", "type"], | ||
"unused-imports/no-unused-imports": "error", | ||
"@typescript-eslint/no-explicit-any": "off" | ||
}, | ||
"env": { | ||
"browser": true, | ||
"es2021": true | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.env | ||
.env.local | ||
node_modules | ||
logs | ||
yarn-error.log |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/usr/bin/env sh | ||
. "$(dirname -- "$0")/_/husky.sh" | ||
|
||
yarn lint-staged |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"semi": false, | ||
"singleQuote": true, | ||
"arrowParens": "avoid" | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Use a Node.js image | ||
FROM node:18.18.0-alpine | ||
|
||
# Set the working directory | ||
WORKDIR /app | ||
|
||
# Copy all the application files | ||
COPY . . | ||
|
||
# Install dependencies | ||
RUN yarn install | ||
|
||
# Build the application | ||
RUN yarn build | ||
|
||
# Expose the port if required | ||
EXPOSE 5000 | ||
|
||
# Command to run the application | ||
CMD ["yarn", "start"] |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
{ | ||
"name": "express-ts-boilerplate", | ||
"version": "1.0.0", | ||
"main": "index.js", | ||
"repository": "", | ||
"author": "", | ||
"license": "MIT", | ||
"scripts": { | ||
"dev": "ts-node-dev --respawn --transpile-only ./src/index.ts", | ||
"start": "node ./dist/index.js", | ||
"lint": "eslint . --ext .ts", | ||
"lint:fix": "eslint . --ext .ts --fix", | ||
"prettier": "prettier --write \"src/**/*.ts\"", | ||
"format": "yarn prettier && yarn lint:fix", | ||
"pre": "git pull && yarn && yarn dev", | ||
"build": "rm -rf dist && yarn tsc", | ||
"tsc": "tsc" | ||
}, | ||
"lint-staged": { | ||
"*.{js,jsx,ts,tsx}": [ | ||
"yarn lint:fix", | ||
"yarn prettier" | ||
] | ||
}, | ||
"dependencies": { | ||
"body-parser": "^1.20.2", | ||
"cors": "^2.8.5", | ||
"dotenv": "^16.4.5", | ||
"ejs": "^3.1.9", | ||
"eslint": "^9.0.0", | ||
"eslint-config-prettier": "^8.8.0", | ||
"eslint-plugin-unused-imports": "^3.1.0", | ||
"express": "^4.19.2", | ||
"http-status": "^1.7.4", | ||
"husky": "^9.0.11", | ||
"lint-staged": "^15.2.2", | ||
"mongoose": "^8.3.0", | ||
"pino": "^8.20.0", | ||
"pino-pretty": "^11.0.0", | ||
"prettier": "^3.2.5", | ||
"ts-node-dev": "^2.0.0", | ||
"typescript": "^5.4.4", | ||
"winston": "^3.13.0", | ||
"winston-daily-rotate-file": "^5.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/body-parser": "^1.19.5", | ||
"@types/cors": "^2.8.13", | ||
"@types/ejs": "^3.1.4", | ||
"@types/express": "^4.17.17", | ||
"@typescript-eslint/eslint-plugin": "^7.5.0", | ||
"@typescript-eslint/parser": "^7.5.0", | ||
"ts-node": "^10.9.1" | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import cors from 'cors' | ||
import 'dotenv/config' | ||
import express, { Application, NextFunction, Request, Response } from 'express' | ||
import * as path from 'path' | ||
import routes from './app/routes' | ||
|
||
// import routes here | ||
import globalErrorHandler from './errors/globalErrorHandler' | ||
import { dbConnect } from './utils/dbConnect' | ||
const app: Application = express() | ||
|
||
app.use(cors()) | ||
|
||
// Set EJS as the view engine | ||
app.set('view engine', 'ejs') | ||
|
||
// Set the path to the views directory | ||
app.set('views', path.join(__dirname, '../views')) | ||
|
||
//parser | ||
app.use(express.json()) | ||
app.use(express.urlencoded({ extended: true })) | ||
|
||
// Database connection | ||
dbConnect() | ||
|
||
// Application routes | ||
app.use('/', routes) | ||
|
||
//Welcome route | ||
app.get('/', async (req: Request, res: Response, next: NextFunction) => { | ||
res.render('welcome') | ||
}) | ||
|
||
// Error handling | ||
app.use(globalErrorHandler) | ||
|
||
export { app } |
Binary file not shown.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { NextFunction, Request, Response } from 'express' | ||
|
||
import sendResponse from '../../../utils/responseHandler' | ||
import { stateServices } from './state.service' | ||
|
||
const getAllStates = async ( | ||
req: Request, | ||
res: Response, | ||
next: NextFunction | ||
) => { | ||
try { | ||
const result = await stateServices.getStates() | ||
// console.log(result) | ||
sendResponse(res, { | ||
statusCode: 200, | ||
success: true, | ||
message: 'Successfully fetched all states', | ||
data: result, | ||
}) | ||
} catch (error) { | ||
next(error) | ||
} | ||
} | ||
|
||
export const statesControllers = { getAllStates } |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// State.ts | ||
import { Document } from 'mongoose' | ||
|
||
export type State = { | ||
stateName: string | ||
abbreviation: string | ||
capital: string | ||
} & Document |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// main.ts | ||
import mongoose, { Document, Model, Schema } from 'mongoose' | ||
import { State } from './state.interface' | ||
|
||
const objectId = mongoose.Schema.Types.ObjectId | ||
|
||
const stateSchema = new Schema<State>({ | ||
stateName: { | ||
type: String, | ||
}, | ||
abbreviation: { | ||
type: String, | ||
}, | ||
capital: { | ||
type: String, | ||
}, | ||
}) | ||
|
||
const States: Model<Document & State> = mongoose.model('State', stateSchema) | ||
export default States |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import express, { Router } from 'express' | ||
import { statesControllers } from './state.controller' | ||
|
||
const router: Router = express.Router() | ||
|
||
router.get('/', statesControllers.getAllStates) | ||
|
||
export const statesRoutes = router |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { State } from './state.interface' | ||
import States from './state.model' | ||
|
||
const getStates = async (): Promise<State[]> => { | ||
const result: State[] = await States.find({}) | ||
return result | ||
} | ||
|
||
export const stateServices = { getStates } |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import express from 'express' | ||
import { statesRoutes } from './../modules/States/state.routes' | ||
|
||
const router = express.Router() | ||
|
||
const moduleRoutes = [{ path: '/states', route: statesRoutes }] | ||
|
||
moduleRoutes.forEach(route => router.use(route.path, route.route)) | ||
export default router |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export default { | ||
port: process.env.PORT, | ||
database_url: process.env.MONGO_URI, | ||
env: process.env.NODE_ENV, | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
class ApiError extends Error { | ||
statusCode: number | ||
constructor(statusCode: number, message: string | undefined, stack = '') { | ||
super(message) | ||
this.statusCode = statusCode | ||
if (stack) { | ||
this.stack = stack | ||
} else { | ||
Error.captureStackTrace(this, this.constructor) | ||
} | ||
} | ||
} | ||
|
||
export { ApiError } |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { ErrorRequestHandler } from 'express' | ||
import configs from '../configs' | ||
import { IErrorSources } from '../interfaces/error' | ||
import { ApiError } from './ApiErrors' | ||
import handleCastError from './handleCastError' | ||
import handleDuplicateError from './handleDuplicateError' | ||
import handleValidationError from './handlevadiationErrors' | ||
|
||
const globalErrorHandler: ErrorRequestHandler = (err, req, res, next) => { | ||
if (configs.env === 'development') console.log(err) //logging the error in development mode only | ||
//setting default values | ||
let statusCode = 500 | ||
let message = 'Something went wrong!' | ||
let errorSources: IErrorSources = [ | ||
{ | ||
path: '', | ||
message: 'Something went wrong', | ||
}, | ||
] | ||
|
||
if (err?.name === 'ValidationError') { | ||
const simplifiedError = handleValidationError(err) | ||
statusCode = simplifiedError?.statusCode | ||
message = simplifiedError?.message | ||
errorSources = simplifiedError?.errorSources | ||
} else if (err?.name === 'CastError') { | ||
const simplifiedError = handleCastError(err) | ||
statusCode = simplifiedError?.statusCode | ||
message = simplifiedError?.message | ||
errorSources = simplifiedError?.errorSources | ||
} else if (err?.code === 11000) { | ||
const simplifiedError = handleDuplicateError(err) | ||
statusCode = simplifiedError?.statusCode | ||
message = simplifiedError?.message | ||
errorSources = simplifiedError?.errorSources | ||
} else if (err instanceof ApiError) { | ||
statusCode = err?.statusCode | ||
message = err.message | ||
errorSources = [ | ||
{ | ||
path: '', | ||
message: err?.message, | ||
}, | ||
] | ||
} else if (err instanceof Error) { | ||
message = err.message | ||
errorSources = [ | ||
{ | ||
path: '', | ||
message: err?.message, | ||
}, | ||
] | ||
} | ||
|
||
//ultimate return | ||
return res.status(statusCode).json({ | ||
success: false, | ||
message, | ||
errorSources, | ||
err, | ||
stack: configs.env === 'development' ? err?.stack : null, | ||
}) | ||
} | ||
|
||
export default globalErrorHandler |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import mongoose from 'mongoose' | ||
import { IErrorSources, IGenericErrorResponse } from '../interfaces/error' | ||
|
||
//CastError is thrown when a value is passed to mongoose that is not a valid type for the Schema type it is defined in. For example, passing a string to a Number type field. This error can be caught and handled by the handleCastError function. | ||
const handleCastError = ( | ||
err: mongoose.Error.CastError | ||
): IGenericErrorResponse => { | ||
const errorSources: IErrorSources = [ | ||
{ | ||
path: err.path, | ||
message: err.message, | ||
}, | ||
] | ||
|
||
const statusCode = 400 | ||
|
||
return { | ||
statusCode, | ||
message: 'Invalid ID', | ||
errorSources, | ||
} | ||
} | ||
|
||
export default handleCastError |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
|
||
import { IErrorSources, IGenericErrorResponse } from '../interfaces/error' | ||
|
||
const handleDuplicateError = (err: any): IGenericErrorResponse => { | ||
// Extract value within double quotes using regex | ||
const match = err.message.match(/"([^"]*)"/) | ||
|
||
// The extracted value will be in the first capturing group | ||
const extractedMessage = match && match[1] | ||
|
||
const errorSources: IErrorSources = [ | ||
{ | ||
path: '', | ||
message: `${extractedMessage} is already exists`, | ||
}, | ||
] | ||
|
||
const statusCode = 400 | ||
|
||
return { | ||
statusCode, | ||
message: 'Invalid ID', | ||
errorSources, | ||
} | ||
} | ||
|
||
export default handleDuplicateError |
Oops, something went wrong.