Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6af4ec5
chore: Update dependencies versions
ruben-conmag Feb 9, 2025
9aee21b
chore: Define import map
ruben-conmag Feb 9, 2025
dfe78bd
chore: Update lock file
ruben-conmag Feb 9, 2025
488d361
fix: Remove helpers
ruben-conmag Feb 9, 2025
a28ab39
feat: Add getQuery helper for handling URL search parameters
ruben-conmag Feb 9, 2025
c61edc2
refactor: Replace helpers.getQuery with getQueryHelper in validate mi…
ruben-conmag Feb 9, 2025
4d28068
refactor: Update Database seeder initialization and simplify seeding …
ruben-conmag Feb 9, 2025
0267ac3
refactor: Conditionally seed database based on configuration
ruben-conmag Feb 9, 2025
5bebf9b
refactor: Remove unused seeder property from Database class
ruben-conmag Feb 9, 2025
ac53b79
refactor: Update request body handling to use json() method in contro…
ruben-conmag Feb 9, 2025
ee4206d
refactor: Update validate middleware to handle JSON request body cond…
ruben-conmag Feb 9, 2025
97bb2c6
refactor: Remove unique constraint from email index in user model
ruben-conmag Feb 9, 2025
fbeff82
refactor: Improve error handling in user controller and middlewares
ruben-conmag Feb 9, 2025
a267270
refactor: Convert ObjectId to string for consistency in token and use…
ruben-conmag Feb 9, 2025
8092a53
Merge pull request #65 from ruben-conmag/fix-window-not-defined
vicky-gonsalves Feb 9, 2025
5c6b9fa
chore: updating code for deno 2.x support
Feb 9, 2025
67222cd
chore: correcting dockerfile
Feb 9, 2025
d24dbc6
fix: correcting container failure
Feb 9, 2025
d090e81
fix: correcting container failure
Feb 9, 2025
44976d4
Revert "fix: correcting container failure"
Feb 9, 2025
6d61cbc
Revert "fix: correcting container failure"
Feb 9, 2025
a31340a
chore: updating deno image
Feb 9, 2025
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 .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ jobs:
workflows:
test:
jobs:
- test
- test
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ about: Create a report to help us improve
title: "[BUG]: Bug Title"
labels: bug
assignees: ''

---

**Describe the bug** A clear and concise description of what the bug is.
Expand Down
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ about: Suggest an idea for this project
title: "[FEAT]: Feature Request Title"
labels: Feature
assignees: ''

---

**Is your feature request related to a problem? Please describe.** A clear and
Expand Down
8 changes: 1 addition & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
FROM denoland/deno:1.34.3
FROM denoland/deno:2.1.9

EXPOSE 9000

WORKDIR /app/deno-rest

COPY deps.ts .
COPY deno.lock .
COPY import_map.json .

ADD . .

RUN deno install --allow-read --allow-run --allow-write --allow-net -f --unstable https://deno.land/x/denon/denon.ts
41 changes: 22 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,21 @@ Deno's http server, and deno_mongo is a MongoDB driver for Deno.
application.
- **Password hashing with BCrypt:** Securely store user passwords with BCrypt
hashing.
- **Denon Integration:** Use Denon, a utility like nodemon for Deno, to
automatically restart the server on file changes.
- **Integration tests:** Test your application with our pre-written integration
tests.
- **Docker and CircleCI integration:** Containerize your application with Docker
and set up continuous integration with CircleCI.

## Libraries Utilized

- [Oak](https://deno.land/x/oak) - Middleware framework for Deno's net server
- [deno_mongo](https://deno.land/x/mongo) - MongoDB driver for Deno
- [cors](https://deno.land/x/cors) - CORS middleware for Deno
- [djwt](https://deno.land/x/djwt) - JSON Web Tokens in Deno, based on JWT and
JWS specifications
- [yup](https://deno.land/x/yup) - Schema builder for value parsing and
validation
- [bcrypt](https://deno.land/x/bcrypt) - OpenBSD Blowfish password hashing
- [Oak](https://jsr.io/@oak/oak) - Middleware framework for Deno's net server
- [deno_mongo](https://jsr.io/@db/mongo) - MongoDB driver for Deno
- [cors](https://jsr.io/@tajpouria/cors) - CORS middleware for Deno
- [djwt](https://jsr.io/@zaubrik/djwt) - JSON Web Tokens in Deno, based on JWT
and JWS specifications
- [yup](https://www.npmjs.com/package/yup) - Schema builder for value parsing
and validation
- [bcrypt](https://jsr.io/@da/bcrypt) - OpenBSD Blowfish password hashing
algorithm

## Getting Started
Expand All @@ -71,33 +69,38 @@ based on your needs. For example, create a `.env.development` file under the
create a `.env.test` file under the `.environments` directory. Then, add the
necessary variables.

### Install Denon

Follow this Denon Installation Guide: https://deno.land/x/denon

### Database Seeding

We use a seeding script to populate the database with initial data. Run the
following command to execute the seeding script:

```bash
denon run --allow-read --allow-write --allow-net --unstable seed.ts
deno run seed
```

Ensure that you have the necessary permissions by including the `--allow-read`
and `--allow-write` flags.

### Running the Project

After setting up everything, you can run the project using the following
command:

```bash
denon start
deno start
```

#### with file watch:

```bash
deno start:watch
```

The server will start and listen for incoming requests.

### Tests

```bash
deno test
```

## User Roles and Permissions

User roles and permissions are defined in the `config/roles.ts` file. You can
Expand Down
3 changes: 2 additions & 1 deletion app.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Application, oakCors } from './deps.ts';
import { Application } from 'jsr:@oak/oak';
import { oakCors } from 'jsr:@tajpouria/cors';
import { errorHandler } from './middlewares/errorHandler.middleware.ts';
import log from './middlewares/logger.middleware.ts';
import configs from './config/config.ts';
Expand Down
2 changes: 1 addition & 1 deletion config/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { loadSync } from '../deps.ts';
import { loadSync } from 'jsr:@std/dotenv';

const env: string = Deno.env.get('ENV') || 'development';
const envPath: string = `environments/.env.${env}`.toString();
Expand Down
10 changes: 5 additions & 5 deletions controllers/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
* @exports AuthController - This class is exported for use in other parts of the application.
*/
import type { RouterContext } from '../deps.ts';
import type { RouterContext } from 'jsr:@oak/oak';
import log from '../middlewares/logger.middleware.ts';
import AuthService from '../services/auth.service.ts';

Expand All @@ -35,8 +35,8 @@ class AuthController {
public static async login(
{ request, response }: RouterContext<string>,
): Promise<void> {
const body = request.body();
const { email, password } = await body.value;
const body = request.body;
const { email, password } = await body.json();
log.debug('Trying Login user');
response.body = await AuthService.login({ email, password });
}
Expand All @@ -53,8 +53,8 @@ class AuthController {
public static async refreshTokens(
{ request, response }: RouterContext<string>,
): Promise<void> {
const body = request.body();
const { refreshToken } = await body.value;
const body = request.body;
const { refreshToken } = await body.json();
log.debug('Getting refresh token');
response.body = await AuthService.getRefreshToken(refreshToken);
}
Expand Down
25 changes: 13 additions & 12 deletions controllers/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
* @exports UserController - This class is exported for use in other parts of the application.
*/
import { Role } from '../config/roles.ts';
import type { RouterContext } from '../deps.ts';
import { Status } from '../deps.ts';
import type { RouterContext } from 'jsr:@oak/oak';
import { Status } from 'jsr:@oak/oak';
import log from '../middlewares/logger.middleware.ts';
import UserService from '../services/user.service.ts';

Expand All @@ -46,14 +46,14 @@ class UserController {
public static async create(
{ request, response }: RouterContext<string>,
): Promise<void> {
const body = request.body();
const body = request.body;
const {
name,
email,
password,
role,
isDisabled,
} = await body.value;
} = await body.json();
log.debug('Creating user');
response.body = await UserService.createUser({
name,
Expand All @@ -66,15 +66,16 @@ class UserController {
}

/**
* Get single user function
* Get all users function
* @param params
* @param response
* @returns Promise<void>
*/
public static async fetch(
{ response }: RouterContext<string>,
): Promise<void> {
log.debug('Getting users list');
response.body = await UserService.getUsers();
response.body = JSON.stringify(await UserService.getUsers());
}

/**
Expand All @@ -89,8 +90,7 @@ class UserController {
}

/**
* Get all users function
* @param params
* Get single user function
* @param response
* @returns Promise<void>
*/
Expand All @@ -114,8 +114,8 @@ class UserController {
{ params, request, response, state }: RouterContext<string>,
): Promise<void | Error> {
const { id } = params;
const body = request.body();
const { name, email, role, isDisabled } = await body.value;
const body = request.body;
const { name, email, role, isDisabled } = await body.json();
log.debug('Updating user');
await UserService.updateUser(id as string, state, {
name,
Expand Down Expand Up @@ -143,8 +143,9 @@ class UserController {
);
response.status = Status.NoContent;
} catch (e) {
response.body = e;
response.status = e.status;
response.body = (e as Error).message;
response.status = (e as { status: number }).status ||
Status.InternalServerError;
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions db/db.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { clearTimeout, setTimeout } from 'node:timers';
import configs from '../config/config.ts';
import { MongoClient } from '../deps.ts';
import { MongoClient } from 'jsr:@db/mongo';
import log from '../middlewares/logger.middleware.ts';
import Seed from '../seed.ts';

Expand All @@ -10,7 +11,6 @@ const { dbName, mongoUrl, seed } = configs;
*/
class Database {
public client: MongoClient;
private seeder: Seed = new Seed();

/**
* Constructor function for Database
Expand All @@ -34,7 +34,7 @@ class Database {
log.info('Database connected!');
if (seed) {
const ev = setTimeout(async () => {
await this.seeder.seedCollection();
await new Seed().seedCollection();
log.info('All Seed done');
clearTimeout(ev);
}, 10);
Expand Down
26 changes: 25 additions & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
{
"tasks": {
"start": "deno run --allow-env --allow-read --allow-net --lock=deno.lock app.ts",
"start:watch": "deno run --watch --allow-env --allow-read --allow-net --lock=deno.lock app.ts",
"test": "deno test --env-file=environments/.env.test --allow-env --allow-read --allow-net --lock=deno.lock",
"test:cov": "deno test --coverage=./cov --env-file=environments/.env.test --allow-env --allow-read --allow-net --lock=deno.lock",
"format": "deno fmt",
"lint": "deno lint",
"seed": "deno --allow-read --allow-env --allow-write --allow-net seed.ts"
},
"imports": {
"@da/bcrypt": "jsr:@da/bcrypt@^1.0.1",
"@db/mongo": "jsr:@db/mongo@^0.33.0",
"@oak/oak": "jsr:@oak/oak@^17.1.4",
"@std/assert": "jsr:@std/assert@1",
"@std/async": "jsr:@std/async@^1.0.10",
"@std/dotenv": "jsr:@std/dotenv@^0.225.3",
"@std/expect": "jsr:@std/expect@^1.0.13",
"@std/log": "jsr:@std/log@^0.224.14",
"@std/testing": "jsr:@std/testing@^1.0.9",
"@tajpouria/cors": "jsr:@tajpouria/cors@^1.2.1",
"@zaubrik/djwt": "jsr:@zaubrik/djwt@^3.0.2",
"supertest": "npm:supertest@^7.0.0",
"yup": "npm:yup@^1.6.1"
},
"compilerOptions": {
"lib": ["deno.ns", "deno.unstable"],
"lib": ["deno.ns", "deno.unstable", "dom", "esnext"],
"strict": true
},
"fmt": {
Expand Down
Loading