WORK-RRE #2

Merged
rayhan.hassou merged 4 commits from WORK-RRE into WORK-RHA 1 year ago

@ -14,9 +14,13 @@
"express": "^4.18.2",
"morgan": "^1.10.0",
"nodemon": "^3.0.1",
"pg": "^8.11.3",
"ts-node": "^10.9.1",
"tsup": "^7.2.0",
"typescript": "^5.2.2"
},
"devDependencies": {
"@types/pg": "^8.10.9"
}
},
"node_modules/@cspotcode/source-map-support": {
@ -520,6 +524,74 @@
"undici-types": "~5.26.4"
}
},
"node_modules/@types/pg": {
"version": "8.10.9",
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.10.9.tgz",
"integrity": "sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ==",
"dev": true,
"dependencies": {
"@types/node": "*",
"pg-protocol": "*",
"pg-types": "^4.0.1"
}
},
"node_modules/@types/pg/node_modules/pg-types": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.1.tgz",
"integrity": "sha512-hRCSDuLII9/LE3smys1hRHcu5QGcLs9ggT7I/TCs0IE+2Eesxi9+9RWAAwZ0yaGjxoWICF/YHLOEjydGujoJ+g==",
"dev": true,
"dependencies": {
"pg-int8": "1.0.1",
"pg-numeric": "1.0.2",
"postgres-array": "~3.0.1",
"postgres-bytea": "~3.0.0",
"postgres-date": "~2.0.1",
"postgres-interval": "^3.0.0",
"postgres-range": "^1.1.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@types/pg/node_modules/postgres-array": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz",
"integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/@types/pg/node_modules/postgres-bytea": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz",
"integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==",
"dev": true,
"dependencies": {
"obuf": "~1.1.2"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/@types/pg/node_modules/postgres-date": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.0.1.tgz",
"integrity": "sha512-YtMKdsDt5Ojv1wQRvUhnyDJNSr2dGIC96mQVKz7xufp07nfuFONzdaowrMHjlAzY6GDLd4f+LUHHAAM1h4MdUw==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/@types/pg/node_modules/postgres-interval": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz",
"integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==",
"dev": true,
"engines": {
"node": ">=12"
}
},
"node_modules/@types/qs": {
"version": "6.9.10",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz",
@ -692,6 +764,14 @@
"node": ">=8"
}
},
"node_modules/buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==",
"engines": {
"node": ">=4"
}
},
"node_modules/bundle-require": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-4.0.2.tgz",
@ -1642,6 +1722,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/obuf": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
"dev": true
},
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@ -1683,6 +1769,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/packet-reader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
"integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@ -1720,6 +1811,98 @@
"node": ">=8"
}
},
"node_modules/pg": {
"version": "8.11.3",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz",
"integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==",
"dependencies": {
"buffer-writer": "2.0.0",
"packet-reader": "1.0.0",
"pg-connection-string": "^2.6.2",
"pg-pool": "^3.6.1",
"pg-protocol": "^1.6.0",
"pg-types": "^2.1.0",
"pgpass": "1.x"
},
"engines": {
"node": ">= 8.0.0"
},
"optionalDependencies": {
"pg-cloudflare": "^1.1.1"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
},
"peerDependenciesMeta": {
"pg-native": {
"optional": true
}
}
},
"node_modules/pg-cloudflare": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz",
"integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==",
"optional": true
},
"node_modules/pg-connection-string": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
"integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA=="
},
"node_modules/pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/pg-numeric": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz",
"integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/pg-pool": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz",
"integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-protocol": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz",
"integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q=="
},
"node_modules/pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"dependencies": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/pgpass": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
"dependencies": {
"split2": "^4.1.0"
}
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@ -1767,6 +1950,47 @@
}
}
},
"node_modules/postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
"engines": {
"node": ">=4"
}
},
"node_modules/postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"dependencies": {
"xtend": "^4.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-range": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.3.tgz",
"integrity": "sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g==",
"dev": true
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -2078,6 +2302,14 @@
"node": ">= 8"
}
},
"node_modules/split2": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
"engines": {
"node": ">= 10.x"
}
},
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@ -2400,6 +2632,14 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"engines": {
"node": ">=0.4"
}
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",

@ -16,8 +16,12 @@
"express": "^4.18.2",
"morgan": "^1.10.0",
"nodemon": "^3.0.1",
"pg": "^8.11.3",
"ts-node": "^10.9.1",
"tsup": "^7.2.0",
"typescript": "^5.2.2"
},
"devDependencies": {
"@types/pg": "^8.10.9"
}
}

@ -1,29 +1,51 @@
import { Request, Response, NextFunction } from "express";
import { Router } from "express";
import { Exceptions } from "../utils/exception";
import { IIngredient, Ingredient } from "../types/ingredients";
import { pool } from "../database/connection";
import { Query, QueryResult } from "pg";
import { IngredientsGateway } from "../gateways/ingredients.gateway";
const IngredientsController = Router()
const ingredient_gw = new IngredientsGateway()
/** To get all ingredients */
IngredientsController.get('/', (req, res) => {
res.status(200)
res.send("Liste des ingredients");
return res;
IngredientsController.get('/', async (req, res) => {
try {
const ingredients = await ingredient_gw.getAll()
res.status(200).json(ingredients)
} catch (error) {
const error_error = error as Error
res.status(500).send(error_error.message)
}
})
/** To get one ingredient by id */
IngredientsController.get('/:id', (req, res) => {
IngredientsController.get('/:id', async (req, res) => {
const id = Number(req.params.id);
if (!Number.isInteger(id)) {
throw new Exceptions.BadRequestException('id invalid !')
throw new Exceptions.BadRequestException('id invalid !');
}
res.send(`Searching for ingredient with id = ${id}...`);
res.status(200);
try {
const ingredient = await ingredient_gw.findOneById(id)
return res;
if (ingredient == null) {
res.status(404).send('not found')
}
else {
const ingredient_ingredient = ingredient as Ingredient
res.status(200).json(ingredient)
}
} catch (error) {
const error_error = error as Error
res.status(500).send(error_error.message)
}
})
export { IngredientsController }

@ -1,11 +1,32 @@
import { Request, Response, NextFunction } from "express";
import { Router } from "express";
import { pool } from "../database/connection";
import { Query, QueryResult } from "pg";
import { IRecipe, Recipe } from "../types/recipes";
import { IngredientsController } from "./ingredients.controller";
import { IIngredient } from "../types/ingredients";
const RecipesController = Router()
RecipesController.get('/', (req, res) => {
res.send("Liste des recettes");
RecipesController.get('/', async (req, res) => {
let recipes:IRecipe[] = []
await pool.query('SELECT * FROM Recipe ORDER BY id', async (error: Error, result: QueryResult) => {
if (error) {
throw error;
}
for (let key in result.rows) {
const current = result.rows[key]
let recipe = new Recipe(current.id, current.name, current.description, current.time_to_cook);
const ingr_ids = current.ingredients
for (let ingr_id in ingr_ids) {
}
}
res.json(result.rows)
})
return res;
})

@ -0,0 +1,34 @@
import { Client } from "pg"
const Pool = require('pg').Pool
export const pool = new Pool({
user: 'rgregnault',
host: 'localhost',
database: 'leftovers',
password: 'motdepasse',
port: 5432,
})
export class Connection {
public client:Client
clientIsConnected:boolean = false
constructor() {
this.client = new Client({
user: 'rgregnault',
host: 'localhost',
database: 'leftovers',
password: 'motdepasse',
port: 5432,
})
}
public async connect() {
if (!this.clientIsConnected) {
await this.client.connect()
this.clientIsConnected = true
}
}
}

@ -0,0 +1,45 @@
import { QueryResult } from "pg";
import { Ingredient } from "../types/ingredients";
import { Connection } from "../database/connection"
export class IngredientsGateway {
connection:Connection
constructor() {
this.connection = new Connection()
}
async getAll() : Promise<Ingredient[]> {
this.connection.connect()
const res = await this.connection.client.query('SELECT * FROM Ingredients ORDER BY id')
let ingredients:Ingredient[] = []
for (let key in res.rows) {
let ingredient:Ingredient = new Ingredient(Number(res.rows[key].id), res.rows[key].name);
ingredients.push(ingredient);
}
return ingredients
}
async findOneById(id: number) : Promise<any> {
this.connection.connect()
const query = {
text: 'SELECT * FROM Ingredients WHERE id =$1',
values: [id],
}
const res = await this.connection.client.query(query)
if (res.rowCount != 1) {
return null
}
const ingredient = new Ingredient(Number(res.rows[0].id), String(res.rows[0].name))
return ingredient
}
}

@ -1,5 +1,5 @@
import express from "express";
import { IngredientsController } from "./controllers/ingredients.controller"
import { IngredientsController } from "./controllers/ingredients.controller";
import { RecipesController } from "./controllers/recipes.controller";
const app = express();

@ -1,9 +1,14 @@
export class Ingredient {
export interface IIngredient {
readonly id: number;
readonly name: string;
}
export class Ingredient implements IIngredient {
id: number;
name: string;
constructor(init_id: number, init_name: string) {
this.id = init_id;
this.name = init_name;
constructor (id: number, name: string) {
this.id = id
this.name = name
}
}

@ -1,10 +1,36 @@
import type { Ingredient } from "./ingredients"
export interface Recipe {
id: number,
name: string,
description: string,
time_to_cook: number,
ingredients: Ingredient[],
import type { IIngredient } from "./ingredients"
export interface IRecipe {
readonly id: number,
readonly name: string,
readonly description: string,
readonly time_to_cook: number,
ingredients: IIngredient[],
steps: string[]
}
export class Recipe implements IRecipe {
id: number
name: string
description: string
time_to_cook: number
ingredients: IIngredient[]
steps: string[]
constructor(id: number, name: string, description: string, time_to_cook: number) {
this.id = id
this.name = name
this.description = description
this.time_to_cook = time_to_cook
this.ingredients = []
this.steps = []
}
addStep(newStep: string) {
this.steps.push(newStep)
}
addIngredient(newIngredient: IIngredient) {
this.ingredients.push(newIngredient)
}
}
Loading…
Cancel
Save