From 7377bd3538b6e9031cc6932e234ac15572a7bce4 Mon Sep 17 00:00:00 2001 From: qpismont Date: Mon, 30 Dec 2024 21:29:16 +0000 Subject: [PATCH] start DI --- bun.lockb | Bin 15625 -> 34579 bytes migrations/20240703103050_accounts.up.sql | 11 +++++++++++ migrations/20240703103105_movies.up.sql | 15 +++++++++++++++ package.json | 5 ++++- src/accounts/AccountsController.ts | 4 ++++ src/accounts/AccountsRouter.ts | 7 +++++++ src/accounts/repository/AccountsRepository.ts | 0 .../repository/IAccountsRepository.ts | 0 src/accounts/service/AccountsService.ts | 0 src/accounts/service/IAccountsService.ts | 0 src/app.ts | 17 +++++++++++++++++ src/core/databases/PgDatabase.ts | 4 +++- src/core/errors/APIError.ts | 12 +++++++++++- tsconfig.json | 5 ++++- 14 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 migrations/20240703103050_accounts.up.sql create mode 100644 migrations/20240703103105_movies.up.sql create mode 100644 src/accounts/AccountsController.ts create mode 100644 src/accounts/AccountsRouter.ts create mode 100644 src/accounts/repository/AccountsRepository.ts create mode 100644 src/accounts/repository/IAccountsRepository.ts create mode 100644 src/accounts/service/AccountsService.ts create mode 100644 src/accounts/service/IAccountsService.ts diff --git a/bun.lockb b/bun.lockb index 44aaed9bbe77f7de6559a8c3480ac7b954e70f85..38606e07e0db67ee01953938806f61745bee8446 100755 GIT binary patch literal 34579 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 K5%<6E-~RzI6f8mj delta 2737 zcmbtW3v82B6u$RgySB{229C8|=iVLN*w_R1Ub_v0bB#q5nkwk(5HYi&ZvZx70d2B%=Dkd`_k%$JT@v#W_oxlB^k!cWbbN=t1bI-Zw z(fgv^%FZoMXE{$rxQ{;BotORM&A2BP)uva-rK2l#Z#xz`_x0@E)A~YtXQ@z|v)>#4 zklq<&gy>k`>~8|&ZwX2^0n9@5t^(c-tOZ5@{Vkato&M$xC#4Wk;5TIxYr-TI$#X=g}~Xs%n-6uc2GBV z&~cewjwN51-?(XQ>M7^z)k_0DeWa8bG#KudyXd!Yw{lKUvB71EN0=^HNvbdu$cJgr z;5MCutXh=~LuRESqg#5Y6W?7lXmp!K6d~@#xI)9m0vSz3Cb!8GCPY4DVd^~FXb`gF zkj;loN0>*s5=O-lF2$y!q1i5_UPlvveL5c1We$>Xu z23S{WW8}aRRBmcy{lw7tRLJAJd9Wx%3W)hs5XvbsMGwAe=l>yF-%%w){%@)C4ksLB8b~m$m9Q9O4SS{{ZBY;(tw^z>Y(Oi57j1{>D^?H3?oyDmy9W9 zTASjLdKv_G0$g0GM;d5Ns+WAJW;z4TL{^8FEDkeuIXp6gJ_L6fTxOa_nyE9*OPkZo zbP3!H+UfMtoH=G{F7n7II#%SR&%i|&d*m!?D)v&J(@Y
  • 9a&FBPVnX=8~;#?Uah zZ@{INdT{2nmwIVmhM7JA7fXp{UaFdFrpL=XGLA;T{R(b@%Om4yo69Q`=pw#}l;ifw zB-)8@GL7MzLPh0XnM(cmI_L_%X;e{xyt2)KS1XPv88m&ib;-8#jZEh5Q%sU&ULNoA#IS4&YVKW4se^bBLp%X&y|cL(3gKJj80e zDS4QuNC%~X=78pcc=Kd{*wO(?1mU3PLtpUD#tFj*y}EIEPq2I5*u0r-AY2~84#H(3 z?g7Pvcv&Z~8$M!il&Nvz4iqy$ks#cYqL(89PQg&Zi% z7viL((ZR7a)0T*a#=zt56Ch0i=piI}uU z%l+r=rsZ2d?S?ZRK{UrCo%C7k+Jj_$ zNs*jxZh;Vo4OG6yl7DNc-MR3cn^k!0h?YdAk#@sWdyE|ZeD;FjpBInlFn1AGLTJyG z89zSzOuXydz~qSENMEk8*tPe~NPeL5)YCdHRhLA(i%08gE@fV?A+! V;YZ&Iqf7oAirj7p+~|%r{sDC$&?x`_ diff --git a/migrations/20240703103050_accounts.up.sql b/migrations/20240703103050_accounts.up.sql new file mode 100644 index 0000000..66ca2c2 --- /dev/null +++ b/migrations/20240703103050_accounts.up.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS public.accounts +( + id integer NOT NULL GENERATED ALWAYS AS IDENTITY, + username text NOT NULL, + password text NOT NULL, + role_id smallint NOT NULL DEFAULT '1'::smallint, + created_at timestamp without time zone NOT NULL DEFAULT now(), + updated_at timestamp without time zone NOT NULL DEFAULT now(), + CONSTRAINT accounts_pkey PRIMARY KEY (id), + CONSTRAINT accounts_username_key UNIQUE (username) +); \ No newline at end of file diff --git a/migrations/20240703103105_movies.up.sql b/migrations/20240703103105_movies.up.sql new file mode 100644 index 0000000..47faa7d --- /dev/null +++ b/migrations/20240703103105_movies.up.sql @@ -0,0 +1,15 @@ +-- Add migration script here + +CREATE TABLE IF NOT EXISTS public.movies +( + id integer NOT NULL GENERATED ALWAYS AS IDENTITY, + title text NOT NULL, + overview text NOT NULL, + poster_path text NOT NULL, + backdrop_path text, + release_date date NOT NULL, + tmdb_id integer NOT NULL, + created_at timestamp without time zone NOT NULL DEFAULT now(), + updated_at timestamp without time zone NOT NULL DEFAULT now(), + PRIMARY KEY (id) +); \ No newline at end of file diff --git a/package.json b/package.json index 544af2d..2371f8d 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,10 @@ "typescript": "^5.6.2" }, "dependencies": { + "fastify": "^5.2.0", "hono": "^4.6.15", - "pg": "^8.13.1" + "inversify": "^6.2.1", + "pg": "^8.13.1", + "reflect-metadata": "^0.2.2" } } diff --git a/src/accounts/AccountsController.ts b/src/accounts/AccountsController.ts new file mode 100644 index 0000000..020f900 --- /dev/null +++ b/src/accounts/AccountsController.ts @@ -0,0 +1,4 @@ +import { injectable } from "inversify"; + +@injectable() +export default class AccountsController {} diff --git a/src/accounts/AccountsRouter.ts b/src/accounts/AccountsRouter.ts new file mode 100644 index 0000000..62b1486 --- /dev/null +++ b/src/accounts/AccountsRouter.ts @@ -0,0 +1,7 @@ +import type { FastifyInstance, FastifyPluginCallback } from "fastify"; + +const accountsRouter: FastifyPluginCallback = (fastify, opts, done) => { + done(); +}; + +export default accountsRouter; diff --git a/src/accounts/repository/AccountsRepository.ts b/src/accounts/repository/AccountsRepository.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/accounts/repository/IAccountsRepository.ts b/src/accounts/repository/IAccountsRepository.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/accounts/service/AccountsService.ts b/src/accounts/service/AccountsService.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/accounts/service/IAccountsService.ts b/src/accounts/service/IAccountsService.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/app.ts b/src/app.ts index e69de29..e61df32 100644 --- a/src/app.ts +++ b/src/app.ts @@ -0,0 +1,17 @@ +import Fastify from "fastify"; +import APIError from "./core/errors/APIError"; + +import accountsRouter from "./accounts/AccountsRouter"; + +const app = Fastify(); + +app.register(accountsRouter, { prefix: "/accounts" }); + +app.setErrorHandler((err, request, reply) => { + const apiError = + err instanceof APIError + ? err + : new APIError("Internal Server Error", 500, err); + + reply.status(apiError.statusCode).send(apiError.toStruct()); +}); diff --git a/src/core/databases/PgDatabase.ts b/src/core/databases/PgDatabase.ts index b349339..4db0d3f 100644 --- a/src/core/databases/PgDatabase.ts +++ b/src/core/databases/PgDatabase.ts @@ -1,4 +1,5 @@ -import { Client, Pool, type PoolClient, type QueryResult } from "pg"; +import { injectable } from "inversify"; +import { Pool, type PoolClient, type QueryResult } from "pg"; import type { SqlParams } from "./IDatabase"; import type IDatabase from "./IDatabase"; @@ -10,6 +11,7 @@ export interface PgConnectionOptions { password: string; } +@injectable() export default class PgDatabase implements IDatabase { private pool: Pool; diff --git a/src/core/errors/APIError.ts b/src/core/errors/APIError.ts index e808f3f..63bf86e 100644 --- a/src/core/errors/APIError.ts +++ b/src/core/errors/APIError.ts @@ -1,21 +1,31 @@ export interface APIErrorStruct { msg: string; statusCode: number; + cause?: string; } export default class APIError extends Error { public statusCode: number; - constructor(msg?: string, statusCode?: number, options?: ErrorOptions) { + public cause?: Error; + + constructor( + msg?: string, + statusCode?: number, + cause?: Error, + options?: ErrorOptions, + ) { super(msg, options); this.statusCode = statusCode || 500; + this.cause = cause; } toStruct(): APIErrorStruct { return { msg: this.message, statusCode: this.statusCode, + cause: this.cause?.message, }; } } diff --git a/tsconfig.json b/tsconfig.json index ffc08ab..ef809f3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,6 +22,9 @@ // Some stricter flags (disabled by default) "noUnusedLocals": false, "noUnusedParameters": false, - "noPropertyAccessFromIndexSignature": false + "noPropertyAccessFromIndexSignature": false, + + "experimentalDecorators": true, + "emitDecoratorMetadata": true } }