diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ca5d78e --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +PORT=3000 +UI_URL=http://localhost:3001 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 22f55ad..cffc885 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,7 @@ lerna-debug.log* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json -!.vscode/extensions.json \ No newline at end of file +!.vscode/extensions.json + +# ENV +.env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..04a2265 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# Use an official Node runtime as a parent image +FROM node:16 + +# Set the working directory in the container +WORKDIR /usr/src/app + +# Copy package.json and package-lock.json (or yarn.lock) +COPY package*.json ./ + +# Install dependencies +RUN npm install + +# Bundle app source +COPY . . + +# Build the application if needed +RUN npm run build + +# Your app binds to port 3000 so you'll use the EXPOSE instruction to have it mapped by the docker daemon +EXPOSE 3000 + +# Define the command to run your app +CMD [ "node", "dist/main" ] # Adjust the path if your entry file is different diff --git a/package-lock.json b/package-lock.json index 78b4320..16777b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,10 @@ "license": "UNLICENSED", "dependencies": { "@nestjs/common": "^10.0.0", + "@nestjs/config": "^3.1.1", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", + "dotenv": "^16.3.2", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "shortid": "^2.2.16" @@ -1683,6 +1685,32 @@ } } }, + "node_modules/@nestjs/config": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-3.1.1.tgz", + "integrity": "sha512-qu5QlNiJdqQtOsnB6lx4JCXPQ96jkKUsOGd+JXfXwqJqZcOSAq6heNFg0opW4pq4J/VZoNwoo87TNnx9wthnqQ==", + "dependencies": { + "dotenv": "16.3.1", + "dotenv-expand": "10.0.0", + "lodash": "4.17.21", + "uuid": "9.0.0" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", + "reflect-metadata": "^0.1.13" + } + }, + "node_modules/@nestjs/config/node_modules/dotenv": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, "node_modules/@nestjs/core": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.0.tgz", @@ -3690,6 +3718,25 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.2.tgz", + "integrity": "sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/dotenv-expand": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "engines": { + "node": ">=12" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -6011,8 +6058,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -8267,6 +8313,14 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", diff --git a/package.json b/package.json index 9b8b700..ee2d8b5 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,10 @@ }, "dependencies": { "@nestjs/common": "^10.0.0", + "@nestjs/config": "^3.1.1", "@nestjs/core": "^10.0.0", "@nestjs/platform-express": "^10.0.0", + "dotenv": "^16.3.2", "reflect-metadata": "^0.1.13", "rxjs": "^7.8.1", "shortid": "^2.2.16" diff --git a/src/app.module.ts b/src/app.module.ts index 30c182b..723a8a9 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -2,9 +2,14 @@ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { UrlShortenerModule } from './url-shortener/url-shortener.module'; import { DnsService } from './dns/dns.service'; +import { ConfigModule } from '@nestjs/config'; @Module({ - imports: [UrlShortenerModule], + imports: [ + ConfigModule.forRoot({ + isGlobal: true, // Makes the config globally available + }),UrlShortenerModule, +], controllers: [AppController], providers: [DnsService], }) diff --git a/src/main.ts b/src/main.ts index da5451c..2c17699 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,14 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; +import * as dotenv from 'dotenv'; + +dotenv.config(); async function bootstrap() { const app = await NestFactory.create(AppModule); + const port = process.env.SERVER_PORT || 3004; app.enableCors(); - await app.listen(3000); + await app.listen(port); + console.log(`Application is running on: ${await app.getUrl()}`); } bootstrap(); diff --git a/src/url-shortener/url-shortener.controller.ts b/src/url-shortener/url-shortener.controller.ts index 345f486..0788d6b 100644 --- a/src/url-shortener/url-shortener.controller.ts +++ b/src/url-shortener/url-shortener.controller.ts @@ -2,10 +2,12 @@ import { Controller, Post, Body, Get, Param, HttpException, HttpStatus, Res } fr import { UrlShortenerService } from './url-shortener.service'; import { ApiResponse } from './response.interface'; import { Response } from 'express'; +import { ConfigService } from '@nestjs/config'; + @Controller('url-shortener') export class UrlShortenerController { - constructor(private readonly urlShortenerService: UrlShortenerService) {} + constructor(private readonly urlShortenerService: UrlShortenerService, private configService: ConfigService) {} @Post('shorten') async shortenUrl(@Body('url') url: string): Promise { @@ -25,7 +27,7 @@ export class UrlShortenerController { try { const originalUrl = this.urlShortenerService.getOriginalUrl(shortUrl); if (!originalUrl) { - return res.redirect('http://localhost:3001/404'); + return res.redirect(`${this.configService.get('UI_URL')}/404`); } return res.redirect(originalUrl); } catch (error) {