Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ You can clone the full repo and keep only the packages you need in your monorepo
- [React](https://reactjs.org/), [NestJs](https://nestjs.com/), [ExpressJS](https://expressjs.com/), [NestJS](https://nestjs.com/)
- 100% [Typescript](https://www.typescriptlang.org/)
- [Prettier](https://prettier.io/) and [Eslint](https://eslint.org/) setup alongside `pre-commit` hook.
- [Mui v6](https://mui.com/) alongside theme change preconfigured.
- [Mui v7](https://mui.com/) alongside theme change preconfigured.
- [Dockerize](https://docs.docker.com/) images
- Github Actions to build apps and publish their docker images

Expand Down
1 change: 0 additions & 1 deletion apps/express-server/src/app-constants/index.ts

This file was deleted.

20 changes: 14 additions & 6 deletions apps/express-server/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import express, {
type Response
} from 'express';
import cors from 'cors';
import { ENV_VARS } from '@/app-constants';
import { ENV_CONFIG } from '@/constants';
import { requestLogger } from '@/middleware';
import * as Routes from '@/routes';
import { routesList } from '@/routes';
import { sendErrorResponse } from '@/utils';

const app: Express = express();

Expand All @@ -17,15 +18,22 @@ app.use(cors());
app.use(requestLogger);

app.get('/', (_: Request, response: Response) => {
response.status(200).send(`ENV: ${ENV_VARS.env} - Api is up & running!!!`);
response.status(200).json({
env: ENV_CONFIG.env,
message: 'Api is up & running!!!'
});
});

app.use('/api/auth', Routes.authRouter);
routesList.forEach(route => app.use(route.path, route.router));

/* 404 Handler - To be written at last */
app.get('*', (req: Request, response: Response) => {
const notFoundMsg = `Not Found - "${req.originalUrl}"`;
response.status(404).send(notFoundMsg);
const notFoundError = `No route exists for this endpoint: "${req.originalUrl}"`;
return sendErrorResponse(response, {
statusCode: 404,
message: '404 - Not Found',
error: notFoundError
});
});

export default app;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

const env = process.env;

export const ENV_VARS = Object.freeze({
export const ENV_CONFIG = Object.freeze({
env: env.NODE_ENV ?? 'development',
port: env.PORT ?? 8000
});
1 change: 1 addition & 0 deletions apps/express-server/src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './environment';
24 changes: 11 additions & 13 deletions apps/express-server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,27 @@
import 'dotenv/config';
import os from 'os';
import { createServer } from 'node:http';
import { ENV_VARS } from '@/app-constants';
import { ENV_CONFIG } from '@/constants';
import { winstonLogger } from '@/middleware';
import app from './app';

const hostName = os.hostname();
const port = ENV_VARS.port;
const { port, env } = ENV_CONFIG;

function bootstrap() {
/* DB Connection Logic */
// try {
// await mongoose.connect(db_connection_string, { autoIndex: true });
// console_log('Connected to DATABASE', `${db_name}@${db_url}`);
// } catch (err) {
// console.log(chalk.red('⚠ Error connecting to the Database ⚠'));
// console.log(err);
// process.exit(1);
// }

const server = createServer(app);
/**
* You can write any custom logic here, like connecting to the
* database. Refer this snippet to connect to MongoDB, Postgres
* or MySQL database.
*
* https://github.com/nishkohli96/client-server-libs/blob/main/apps/express-server/src/index.ts#L171
*/

const server = createServer(app);
server.listen(port, () => {
winstonLogger.info(
`[ ⚡️ ${hostName} ⚡️ ] - Server running on port ${port}`
`[⚡️ ${hostName}@${env} ⚡️] - Server running on port ${port}`
);
});
}
Expand Down
49 changes: 0 additions & 49 deletions apps/express-server/src/middleware/guard.ts

This file was deleted.

1 change: 0 additions & 1 deletion apps/express-server/src/middleware/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from './guard';
export * from './request-logger';
export * from './winston-logger';
16 changes: 0 additions & 16 deletions apps/express-server/src/middleware/request-logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,3 @@ export function requestLogger(
});
next();
}

export function printSuccessMsg(msg: string): void {
winstonLogger.info(`✅ SUCCESS - ${msg}`);
}

export function printError(error: unknown): void {
winstonLogger.error(
`⚠ ERROR - ${error instanceof Error ? error.message : JSON.stringify(error)}`
);
}

export function errorLogger(res: Response, error: unknown) {
const err = JSON.stringify(error);
printError(error);
res.status(500).send(err);
}
4 changes: 2 additions & 2 deletions apps/express-server/src/middleware/winston-logger.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/restrict-template-expressions */

import { createLogger, addColors, format, transports } from 'winston';
import { ENV_VARS } from '@/app-constants';
import { ENV_CONFIG } from '@/constants';

const { combine, timestamp, printf } = format;

Expand Down Expand Up @@ -72,7 +72,7 @@ addColors(customLevels.colors);
* `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
*/

if (ENV_VARS.env !== 'production') {
if (ENV_CONFIG.env !== 'production') {
winstonLogger.add(
new transports.Console({ format: format.colorize({ all: true }) })
);
Expand Down
7 changes: 3 additions & 4 deletions apps/express-server/src/routes/auth/controller.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import { Router, type Request, type Response } from 'express';
import { Router, type Response } from 'express';
import authService from './service';
import type * as AuthTypes from './types';

const authRouter = Router();

authRouter.get('/test', function printHello(_, res: Response) {
return res.status(200).send('Hello World !!')
.end();
return res.status(200).send('Hello World !!').end();
});

/* Login user */
authRouter.post(
'/login',
function loginUser(
req: Request<object, object, AuthTypes.UserLoginBody>,
req: AuthTypes.UserLoginRequest,
res: Response
) {
const { email, password } = req.body;
Expand Down
9 changes: 5 additions & 4 deletions apps/express-server/src/routes/auth/service.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import type { Response } from 'express';
import { sendErrorResponse } from '@/utils';

class AuthService {
loginUser(res: Response, email: string, password: string) {
try {
res
return res
.status(200)
.send({
email,
password
})
.end();
} catch (error) {
res.status(500).send(`Internal Server Error: ${JSON.stringify(error)}`);
return sendErrorResponse(res, { error });
}
res.end();
}
}

export default new AuthService();
const authService = new AuthService();
export default authService;
3 changes: 3 additions & 0 deletions apps/express-server/src/routes/auth/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { type Request } from 'express';
export interface UserLoginBody {
email: string;
password: string;
}

export type UserLoginRequest = Request<object, object, UserLoginBody>;
19 changes: 18 additions & 1 deletion apps/express-server/src/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
import { type Router } from 'express';
import { authRouter } from './auth/controller';

export { authRouter };
type RouteInfo = {
path: string;
router: Router;
};

function generatePrefix(routeName: string) {
return `/api${routeName}`;
}

const routesList: RouteInfo[] = [
{
path: generatePrefix('/auth'),
router: authRouter
}
];

export { routesList };
2 changes: 2 additions & 0 deletions apps/express-server/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './printObject';
export * from './response';
17 changes: 17 additions & 0 deletions apps/express-server/src/utils/printObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Winston logger expects string message by default.
* If you pass an object directly (like your response),
* Winston doesn't automatically serialize it.
*
* JSON.stringify's 2nd and 3rd args:
* - replacer (Optional): A function or array to control
* which properties are included in the output. Usually
* null if you want to include everything. Specify only
* those keys in an array which you want to log.
* - space (Optional): A number or string to control spacing
* or indentation. 2 means 2 spaces of indentation per level
* (for pretty-printing).
*/
export function printObject(obj: unknown): string {
return JSON.stringify(obj, null, 2);
}
25 changes: 25 additions & 0 deletions apps/express-server/src/utils/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Move this in types/request folder if you want to
* use this code snippet.
*/
type PaginationConfig = {
records_per_page: number;
page: number;
};

export const DefaultPaginationOptions: PaginationConfig = {
records_per_page: 10,
page: 1
};

export function getPaginationParams(
page?: string,
records_per_page?: string
): PaginationConfig {
return {
records_per_page: records_per_page
? Number(records_per_page)
: DefaultPaginationOptions.records_per_page,
page: page ? Number(page) : DefaultPaginationOptions.page
};
}
29 changes: 29 additions & 0 deletions apps/express-server/src/utils/response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { winstonLogger } from '@/middleware';
import type { Response } from 'express';

type ErrorResponseOptions = {
error: unknown;
message?: string;
statusCode?: number;
};

export function sendErrorResponse(
res: Response,
{
error,
message = 'Internal Server Error',
statusCode = 500,
}: ErrorResponseOptions
) {
const errorMessage = error instanceof Error
? error.message
: JSON.stringify(error);

winstonLogger.error(`⚠ ERROR - ${errorMessage}`);
return res.status(statusCode).json({
success: false,
status: statusCode,
message,
error: errorMessage,
});
}
1 change: 1 addition & 0 deletions apps/next-client/src/theme/palette.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*
* https://zenoo.github.io/mui-theme-creator/
* https://m2.material.io/inline-tools/color/
* https://bareynol.github.io/mui-theme-creator/
*/

export const LightThemePalette = {
Expand Down
7 changes: 5 additions & 2 deletions apps/react-client/src/assets/styles/palette.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/**
* Dark mode with MUI.
* https://mui.com/material-ui/customization/dark-mode/
* Check out these resources for building theme -
*
* https://zenoo.github.io/mui-theme-creator/
* https://m2.material.io/inline-tools/color/
* https://bareynol.github.io/mui-theme-creator/
*/

export const LightThemePalette = {
Expand Down