From 0f7055e8b42e79f0a7d3f9b7626096b40a1b8995 Mon Sep 17 00:00:00 2001 From: Connor McSwain Date: Fri, 17 Apr 2026 15:14:31 +0200 Subject: [PATCH 1/4] create dto of post-api --- package-lock.json | 774 +++++++++++++++++-- package.json | 7 +- src/app.module.ts | 17 +- src/modules/orders/dto/create-order.dto.ts | 25 + src/modules/orders/dto/update-order.dto.ts | 4 + src/modules/orders/entities/order.entity.ts | 1 + src/modules/orders/orders.controller.spec.ts | 20 + src/modules/orders/orders.controller.ts | 24 + src/modules/orders/orders.module.ts | 9 + src/modules/orders/orders.service.spec.ts | 18 + src/modules/orders/orders.service.ts | 26 + src/utils/transformer.ts | 6 + 12 files changed, 864 insertions(+), 67 deletions(-) create mode 100644 src/modules/orders/dto/create-order.dto.ts create mode 100644 src/modules/orders/dto/update-order.dto.ts create mode 100644 src/modules/orders/entities/order.entity.ts create mode 100644 src/modules/orders/orders.controller.spec.ts create mode 100644 src/modules/orders/orders.controller.ts create mode 100644 src/modules/orders/orders.module.ts create mode 100644 src/modules/orders/orders.service.spec.ts create mode 100644 src/modules/orders/orders.service.ts create mode 100644 src/utils/transformer.ts diff --git a/package-lock.json b/package-lock.json index caf1c48..4f1aa98 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,17 +9,22 @@ "version": "0.0.1", "license": "UNLICENSED", "dependencies": { + "@nestjs/class-transformer": "^0.4.0", + "@nestjs/class-validator": "^0.13.4", "@nestjs/common": "^11.1.19", "@nestjs/config": "^4.0.4", "@nestjs/core": "^11.1.19", "@nestjs/platform-express": "^11.0.1", "@nestjs/swagger": "^11.3.0", + "@nestjs/typeorm": "^11.0.1", "@prisma/adapter-pg": "^7.7.0", "@prisma/client": "^7.7.0", "pg": "^8.20.0", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", - "swagger-ui-express": "^5.0.1" + "sanitize-html": "^2.17.3", + "swagger-ui-express": "^5.0.1", + "typeorm": "^0.3.28" }, "devDependencies": { "@eslint/eslintrc": "^3.2.0", @@ -638,7 +643,7 @@ }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -649,7 +654,7 @@ }, "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -1232,7 +1237,6 @@ }, "node_modules/@isaacs/cliui": { "version": "8.0.2", - "dev": true, "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -1248,7 +1252,6 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.2.2", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -1259,7 +1262,6 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.3", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -1270,12 +1272,10 @@ }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", - "dev": true, "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", - "dev": true, "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -1291,7 +1291,6 @@ }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" @@ -1305,7 +1304,6 @@ }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -1803,7 +1801,7 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1820,7 +1818,7 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -1865,6 +1863,22 @@ "@tybys/wasm-util": "^0.10.0" } }, + "node_modules/@nestjs/class-transformer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/class-transformer/-/class-transformer-0.4.0.tgz", + "integrity": "sha512-aHKhqPVixFCo8m7n2iP1uGgfyF0eYlAgGJKfW27l0BvRCTPBjmoL4956Cf9xVu6WNJzVsp//SOcpIavdnNHYZg==", + "license": "MIT" + }, + "node_modules/@nestjs/class-validator": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/@nestjs/class-validator/-/class-validator-0.13.4.tgz", + "integrity": "sha512-/mqZL36LJ5uV5WDhi87Cd52IssuO+SStaOr2+6sBsvCCGUWkoJes4Wwzmm3m/gdHH+tsNxX60sVSzYcU6hAy9Q==", + "license": "MIT", + "dependencies": { + "libphonenumber-js": "^1.9.43", + "validator": "^13.7.0" + } + }, "node_modules/@nestjs/cli": { "version": "11.0.21", "dev": true, @@ -2338,6 +2352,19 @@ } } }, + "node_modules/@nestjs/typeorm": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-11.0.1.tgz", + "integrity": "sha512-8rw/nKT0S+L+MkzgE9F2/mox7mAgsPlwfzmW9gsESN1lmQtIrVEfiiBwC2O8+guS1jBfQehJIdcdUj2OAp4VUQ==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "@nestjs/core": "^10.0.0 || ^11.0.0", + "reflect-metadata": "^0.1.13 || ^0.2.0", + "rxjs": "^7.2.0", + "typeorm": "^0.3.0 || ^1.0.0-dev" + } + }, "node_modules/@noble/hashes": { "version": "1.8.0", "dev": true, @@ -2373,7 +2400,6 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -2800,6 +2826,12 @@ "@sinonjs/commons": "^3.0.1" } }, + "node_modules/@sqltools/formatter": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", + "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==", + "license": "MIT" + }, "node_modules/@standard-schema/spec": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", @@ -2828,22 +2860,22 @@ }, "node_modules/@tsconfig/node10": { "version": "1.0.12", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tybys/wasm-util": { @@ -3786,7 +3818,7 @@ }, "node_modules/acorn": { "version": "8.16.0", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -3816,7 +3848,7 @@ }, "node_modules/acorn-walk": { "version": "8.3.5", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "acorn": "^8.11.0" @@ -3908,7 +3940,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3916,7 +3947,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3930,7 +3960,6 @@ }, "node_modules/ansis": { "version": "4.2.0", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -3959,13 +3988,22 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/app-root-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/append-field": { "version": "1.0.0", "license": "MIT" }, "node_modules/arg": { "version": "4.1.3", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/argparse": { @@ -3987,6 +4025,21 @@ "dev": true, "license": "MIT" }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/aws-ssl-profiles": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", @@ -4088,12 +4141,10 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", - "dev": true, "funding": [ { "type": "github", @@ -4316,6 +4367,24 @@ "url": "https://dotenvx.com" } }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "license": "MIT", @@ -4514,7 +4583,6 @@ }, "node_modules/cliui": { "version": "8.0.1", - "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -4527,7 +4595,6 @@ }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -4565,7 +4632,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4576,7 +4642,6 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/combined-stream": { @@ -4734,12 +4799,11 @@ }, "node_modules/create-require": { "version": "1.1.1", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", - "devOptional": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -4758,6 +4822,12 @@ "license": "MIT", "peer": true }, + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.3", "license": "MIT", @@ -4775,7 +4845,6 @@ }, "node_modules/dedent": { "version": "1.7.2", - "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -4793,7 +4862,6 @@ }, "node_modules/deepmerge": { "version": "4.3.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4820,6 +4888,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/defu": { "version": "6.1.7", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", @@ -4878,12 +4963,79 @@ }, "node_modules/diff": { "version": "4.0.4", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dotenv": { "version": "17.4.2", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", @@ -4938,7 +5090,6 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "dev": true, "license": "MIT" }, "node_modules/ee-first": { @@ -4974,7 +5125,6 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, "license": "MIT" }, "node_modules/empathic": { @@ -5006,6 +5156,18 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/env-paths": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", @@ -5072,7 +5234,6 @@ }, "node_modules/escalade": { "version": "3.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5084,7 +5245,6 @@ }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -5560,9 +5720,23 @@ "dev": true, "license": "ISC" }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/foreground-child": { "version": "3.3.1", - "devOptional": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", @@ -5730,7 +5904,6 @@ }, "node_modules/get-caller-file": { "version": "2.0.5", - "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -5954,6 +6127,18 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "license": "MIT", @@ -5966,7 +6151,6 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -6003,6 +6187,25 @@ "dev": true, "license": "MIT" }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, "node_modules/http-errors": { "version": "2.0.1", "license": "MIT", @@ -6142,6 +6345,18 @@ "dev": true, "license": "MIT" }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "dev": true, @@ -6152,7 +6367,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6193,6 +6407,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-promise": { "version": "4.0.0", "license": "MIT" @@ -6215,6 +6438,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "dev": true, @@ -6226,9 +6464,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", - "devOptional": true, "license": "ISC" }, "node_modules/istanbul-lib-coverage": { @@ -6301,7 +6544,6 @@ }, "node_modules/jackspeak": { "version": "3.4.3", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -7088,6 +7330,12 @@ "node": ">= 0.8.0" } }, + "node_modules/libphonenumber-js": { + "version": "1.12.41", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.41.tgz", + "integrity": "sha512-lsmMmGXBxXIK/VMLEj0kL6MtUs1kBGj1nTCzi6zgQoG1DEwqwt2DQyHxcLykceIxAnfE3hya7NuIh6PpC6S3fA==", + "license": "MIT" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "dev": true, @@ -7220,7 +7468,7 @@ }, "node_modules/make-error": { "version": "1.3.6", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/makeerror": { @@ -7363,7 +7611,6 @@ }, "node_modules/minipass": { "version": "7.1.3", - "dev": true, "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" @@ -7467,6 +7714,24 @@ "node": ">=8.0.0" } }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/napi-postinstall": { "version": "0.3.4", "dev": true, @@ -7703,7 +7968,6 @@ }, "node_modules/package-json-from-dist": { "version": "1.0.1", - "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { @@ -7734,6 +7998,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-srcset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", + "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==", + "license": "MIT" + }, "node_modules/parseurl": { "version": "1.3.3", "license": "MIT", @@ -7759,7 +8029,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -7918,7 +8187,6 @@ }, "node_modules/picocolors": { "version": "1.1.1", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -8019,6 +8287,43 @@ "node": ">=4" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/postgres": { "version": "3.4.7", "resolved": "https://registry.npmjs.org/postgres/-/postgres-3.4.7.tgz", @@ -8319,7 +8624,6 @@ }, "node_modules/require-directory": { "version": "2.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8430,6 +8734,20 @@ "version": "2.1.2", "license": "MIT" }, + "node_modules/sanitize-html": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.3.tgz", + "integrity": "sha512-Kn4srCAo2+wZyvCNKCSyB2g8RQ8IkX/gQs2uqoSRNu5t9I2qvUyAVvRDiFUVAiX3N3PNuwStY0eNr+ooBHVWEg==", + "license": "MIT", + "dependencies": { + "deepmerge": "^4.2.2", + "escape-string-regexp": "^4.0.0", + "htmlparser2": "^10.1.0", + "is-plain-object": "^5.0.0", + "parse-srcset": "^1.0.2", + "postcss": "^8.3.11" + } + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -8513,13 +8831,49 @@ "url": "https://opencollective.com/express" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "license": "ISC" }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/shebang-command": { "version": "2.0.0", - "devOptional": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -8530,7 +8884,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "devOptional": true, "license": "MIT", "engines": { "node": ">=8" @@ -8602,7 +8955,6 @@ }, "node_modules/signal-exit": { "version": "4.1.0", - "devOptional": true, "license": "ISC", "engines": { "node": ">=14" @@ -8627,6 +8979,15 @@ "node": ">= 8" } }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.21", "dev": true, @@ -8658,6 +9019,22 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/sql-highlight": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sql-highlight/-/sql-highlight-6.1.0.tgz", + "integrity": "sha512-ed7OK4e9ywpE7pgRMkMQmZDPKSVdm0oX5IEtZiKnFucSF0zu6c80GZBe38UqHuVhTWJ9xsKgSMjCG2bml86KvA==", + "funding": [ + "https://github.com/scriptcoded/sql-highlight?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/scriptcoded" + } + ], + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/sqlstring": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", @@ -8728,7 +9105,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -8742,7 +9118,6 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -8755,7 +9130,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -8767,7 +9141,6 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -9126,6 +9499,20 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "dev": true, @@ -9254,7 +9641,7 @@ }, "node_modules/ts-node": { "version": "10.9.2", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -9375,10 +9762,229 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/typedarray": { "version": "0.0.6", "license": "MIT" }, + "node_modules/typeorm": { + "version": "0.3.28", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.28.tgz", + "integrity": "sha512-6GH7wXhtfq2D33ZuRXYwIsl/qM5685WZcODZb7noOOcRMteM9KF2x2ap3H0EBjnSV0VO4gNAfJT5Ukp0PkOlvg==", + "license": "MIT", + "dependencies": { + "@sqltools/formatter": "^1.2.5", + "ansis": "^4.2.0", + "app-root-path": "^3.1.0", + "buffer": "^6.0.3", + "dayjs": "^1.11.19", + "debug": "^4.4.3", + "dedent": "^1.7.0", + "dotenv": "^16.6.1", + "glob": "^10.5.0", + "reflect-metadata": "^0.2.2", + "sha.js": "^2.4.12", + "sql-highlight": "^6.1.0", + "tslib": "^2.8.1", + "uuid": "^11.1.0", + "yargs": "^17.7.2" + }, + "bin": { + "typeorm": "cli.js", + "typeorm-ts-node-commonjs": "cli-ts-node-commonjs.js", + "typeorm-ts-node-esm": "cli-ts-node-esm.js" + }, + "engines": { + "node": ">=16.13.0" + }, + "funding": { + "url": "https://opencollective.com/typeorm" + }, + "peerDependencies": { + "@google-cloud/spanner": "^5.18.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@sap/hana-client": "^2.14.22", + "better-sqlite3": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0", + "ioredis": "^5.0.4", + "mongodb": "^5.8.0 || ^6.0.0", + "mssql": "^9.1.1 || ^10.0.0 || ^11.0.0 || ^12.0.0", + "mysql2": "^2.2.5 || ^3.0.1", + "oracledb": "^6.3.0", + "pg": "^8.5.1", + "pg-native": "^3.0.0", + "pg-query-stream": "^4.0.0", + "redis": "^3.1.1 || ^4.0.0 || ^5.0.14", + "sql.js": "^1.4.0", + "sqlite3": "^5.0.3", + "ts-node": "^10.7.0", + "typeorm-aurora-data-api-driver": "^2.0.0 || ^3.0.0" + }, + "peerDependenciesMeta": { + "@google-cloud/spanner": { + "optional": true + }, + "@sap/hana-client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "mongodb": { + "optional": true + }, + "mssql": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "oracledb": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-native": { + "optional": true + }, + "pg-query-stream": { + "optional": true + }, + "redis": { + "optional": true + }, + "sql.js": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "ts-node": { + "optional": true + }, + "typeorm-aurora-data-api-driver": { + "optional": true + } + } + }, + "node_modules/typeorm/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typeorm/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/typeorm/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/typeorm/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typeorm/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/typeorm/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typeorm/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/typescript": { "version": "5.9.3", "devOptional": true, @@ -9538,9 +10144,22 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -9571,6 +10190,15 @@ } } }, + "node_modules/validator": { + "version": "13.15.35", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz", + "integrity": "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "license": "MIT", @@ -9785,7 +10413,6 @@ }, "node_modules/which": { "version": "2.0.2", - "devOptional": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -9797,6 +10424,27 @@ "node": ">= 8" } }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "dev": true, @@ -9826,7 +10474,6 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -9867,7 +10514,6 @@ }, "node_modules/y18n": { "version": "5.0.8", - "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -9880,7 +10526,6 @@ }, "node_modules/yargs": { "version": "17.7.2", - "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -9897,7 +10542,6 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -9905,7 +10549,7 @@ }, "node_modules/yn": { "version": "3.1.1", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" diff --git a/package.json b/package.json index 15eed16..7e25180 100644 --- a/package.json +++ b/package.json @@ -21,17 +21,22 @@ "prisma": "prisma" }, "dependencies": { + "@nestjs/class-transformer": "^0.4.0", + "@nestjs/class-validator": "^0.13.4", "@nestjs/common": "^11.1.19", "@nestjs/config": "^4.0.4", "@nestjs/core": "^11.1.19", "@nestjs/platform-express": "^11.0.1", "@nestjs/swagger": "^11.3.0", + "@nestjs/typeorm": "^11.0.1", "@prisma/adapter-pg": "^7.7.0", "@prisma/client": "^7.7.0", "pg": "^8.20.0", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", - "swagger-ui-express": "^5.0.1" + "sanitize-html": "^2.17.3", + "swagger-ui-express": "^5.0.1", + "typeorm": "^0.3.28" }, "devDependencies": { "@eslint/eslintrc": "^3.2.0", diff --git a/src/app.module.ts b/src/app.module.ts index 278b638..1419e13 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -2,9 +2,24 @@ import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { AppController } from './app.controller'; import { AppService } from './app.service'; +import { OrdersModule } from './modules/orders/orders.module'; +import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ - imports: [ConfigModule.forRoot()], + imports: [ + ConfigModule.forRoot(), + OrdersModule, + TypeOrmModule.forRoot({ + type: 'postgres', + host: 'postgresdb', + port: 5432, + username: 'postgres', + password: 'postgres', + database: 'db', + autoLoadEntities: true, + synchronize: true, + }), + ], controllers: [AppController], providers: [AppService], }) diff --git a/src/modules/orders/dto/create-order.dto.ts b/src/modules/orders/dto/create-order.dto.ts new file mode 100644 index 0000000..cce7ce0 --- /dev/null +++ b/src/modules/orders/dto/create-order.dto.ts @@ -0,0 +1,25 @@ +import { IsNotEmpty, IsString, IsUUID, MaxLength } from '@nestjs/class-validator'; +import { UUID } from 'crypto'; +import { Timestamp } from 'typeorm'; + +export class CreateOrderDto { + @MaxLength(128) + @IsString() + @IsNotEmpty() + name: string; + + @IsString() + @IsNotEmpty() + size?: string; + + @IsUUID() + @IsNotEmpty() + id: UUID; + + @IsString() + @IsNotEmpty() + costumer: string; + + @IsNotEmpty() + createdAt: Timestamp; +} diff --git a/src/modules/orders/dto/update-order.dto.ts b/src/modules/orders/dto/update-order.dto.ts new file mode 100644 index 0000000..93dff6d --- /dev/null +++ b/src/modules/orders/dto/update-order.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/swagger'; +import { CreateOrderDto } from './create-order.dto'; + +export class UpdateOrderDto extends PartialType(CreateOrderDto) {} diff --git a/src/modules/orders/entities/order.entity.ts b/src/modules/orders/entities/order.entity.ts new file mode 100644 index 0000000..f3ec29e --- /dev/null +++ b/src/modules/orders/entities/order.entity.ts @@ -0,0 +1 @@ +export class Order {} diff --git a/src/modules/orders/orders.controller.spec.ts b/src/modules/orders/orders.controller.spec.ts new file mode 100644 index 0000000..3be4604 --- /dev/null +++ b/src/modules/orders/orders.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { OrdersController } from './orders.controller'; +import { OrdersService } from './orders.service'; + +describe('OrdersController', () => { + let controller: OrdersController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [OrdersController], + providers: [OrdersService], + }).compile(); + + controller = module.get(OrdersController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/modules/orders/orders.controller.ts b/src/modules/orders/orders.controller.ts new file mode 100644 index 0000000..bc744f1 --- /dev/null +++ b/src/modules/orders/orders.controller.ts @@ -0,0 +1,24 @@ +import { Controller, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { OrdersService } from './orders.service'; +import { CreateOrderDto } from './dto/create-order.dto'; +import { UpdateOrderDto } from './dto/update-order.dto'; + +@Controller('orders') +export class OrdersController { + constructor(private readonly ordersService: OrdersService) {} + + @Post() + create(@Body() createOrderDto: CreateOrderDto) { + return this.ordersService.create(createOrderDto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updateOrderDto: UpdateOrderDto) { + return this.ordersService.update(+id, updateOrderDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.ordersService.remove(+id); + } +} diff --git a/src/modules/orders/orders.module.ts b/src/modules/orders/orders.module.ts new file mode 100644 index 0000000..de72044 --- /dev/null +++ b/src/modules/orders/orders.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { OrdersService } from './orders.service'; +import { OrdersController } from './orders.controller'; + +@Module({ + controllers: [OrdersController], + providers: [OrdersService], +}) +export class OrdersModule {} diff --git a/src/modules/orders/orders.service.spec.ts b/src/modules/orders/orders.service.spec.ts new file mode 100644 index 0000000..3d111a7 --- /dev/null +++ b/src/modules/orders/orders.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { OrdersService } from './orders.service'; + +describe('OrdersService', () => { + let service: OrdersService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [OrdersService], + }).compile(); + + service = module.get(OrdersService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/modules/orders/orders.service.ts b/src/modules/orders/orders.service.ts new file mode 100644 index 0000000..ddc00ed --- /dev/null +++ b/src/modules/orders/orders.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@nestjs/common'; +import { CreateOrderDto } from './dto/create-order.dto'; +import { UpdateOrderDto } from './dto/update-order.dto'; + +@Injectable() +export class OrdersService { + create(createOrderDto: CreateOrderDto) { + return 'This action adds a new order'; + } + + findAll() { + return `This action returns all orders`; + } + + findOne(id: number) { + return `This action returns a #${id} order`; + } + + update(id: number, updateOrderDto: UpdateOrderDto) { + return `This action updates a #${id} order`; + } + + remove(id: number) { + return `This action removes a #${id} order`; + } +} diff --git a/src/utils/transformer.ts b/src/utils/transformer.ts new file mode 100644 index 0000000..deff5e1 --- /dev/null +++ b/src/utils/transformer.ts @@ -0,0 +1,6 @@ +import { TransformFnParams } from '@nestjs/class-transformer'; +import sanitizeHtml from 'sanitize-html'; + +export function sanitizeHtmlTransformer(params: TransformFnParams): unknown { + return typeof params.value === 'string' ? sanitizeHtml(params.value as string) : params.value; +} From b2ec62488b03e44691580fe29c07efd054aaab40 Mon Sep 17 00:00:00 2001 From: Connor McSwain Date: Mon, 20 Apr 2026 13:50:03 +0200 Subject: [PATCH 2/4] init prisma service --- .gitignore | 2 +- prisma/schema.prisma | 2 +- src/app.module.ts | 2 ++ src/modules/orders/orders.controller.ts | 3 ++- src/prisma/dto/create-prisma.dto.ts | 1 + src/prisma/dto/update-prisma.dto.ts | 4 +++ src/prisma/entities/prisma.entity.ts | 1 + src/prisma/prisma.controller.spec.ts | 20 +++++++++++++++ src/prisma/prisma.controller.ts | 34 +++++++++++++++++++++++++ src/prisma/prisma.module.ts | 9 +++++++ src/prisma/prisma.service.spec.ts | 18 +++++++++++++ src/prisma/prisma.service.ts | 26 +++++++++++++++++++ 12 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 src/prisma/dto/create-prisma.dto.ts create mode 100644 src/prisma/dto/update-prisma.dto.ts create mode 100644 src/prisma/entities/prisma.entity.ts create mode 100644 src/prisma/prisma.controller.spec.ts create mode 100644 src/prisma/prisma.controller.ts create mode 100644 src/prisma/prisma.module.ts create mode 100644 src/prisma/prisma.service.spec.ts create mode 100644 src/prisma/prisma.service.ts diff --git a/.gitignore b/.gitignore index 4c1afd5..a8f9a93 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ node_modules .env dist -/prisma/generated \ No newline at end of file +src/generated \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1426da3..ce278de 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,6 +1,6 @@ generator client { provider = "prisma-client" - output = "./generated/prisma" + output = "../src/generated/prisma" } datasource db { diff --git a/src/app.module.ts b/src/app.module.ts index 1419e13..6cd23bd 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,6 +4,7 @@ import { AppController } from './app.controller'; import { AppService } from './app.service'; import { OrdersModule } from './modules/orders/orders.module'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { PrismaModule } from './prisma/prisma.module'; @Module({ imports: [ @@ -19,6 +20,7 @@ import { TypeOrmModule } from '@nestjs/typeorm'; autoLoadEntities: true, synchronize: true, }), + PrismaModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/modules/orders/orders.controller.ts b/src/modules/orders/orders.controller.ts index bc744f1..d82a18d 100644 --- a/src/modules/orders/orders.controller.ts +++ b/src/modules/orders/orders.controller.ts @@ -2,10 +2,11 @@ import { Controller, Post, Body, Patch, Param, Delete } from '@nestjs/common'; import { OrdersService } from './orders.service'; import { CreateOrderDto } from './dto/create-order.dto'; import { UpdateOrderDto } from './dto/update-order.dto'; +import { PrismaService } from '../../prisma/prisma.service'; @Controller('orders') export class OrdersController { - constructor(private readonly ordersService: OrdersService) {} + constructor(private readonly prisma: PrismaService) {} @Post() create(@Body() createOrderDto: CreateOrderDto) { diff --git a/src/prisma/dto/create-prisma.dto.ts b/src/prisma/dto/create-prisma.dto.ts new file mode 100644 index 0000000..055ebc9 --- /dev/null +++ b/src/prisma/dto/create-prisma.dto.ts @@ -0,0 +1 @@ +export class CreatePrismaDto {} diff --git a/src/prisma/dto/update-prisma.dto.ts b/src/prisma/dto/update-prisma.dto.ts new file mode 100644 index 0000000..56407bb --- /dev/null +++ b/src/prisma/dto/update-prisma.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/swagger'; +import { CreatePrismaDto } from './create-prisma.dto'; + +export class UpdatePrismaDto extends PartialType(CreatePrismaDto) {} diff --git a/src/prisma/entities/prisma.entity.ts b/src/prisma/entities/prisma.entity.ts new file mode 100644 index 0000000..ee9d396 --- /dev/null +++ b/src/prisma/entities/prisma.entity.ts @@ -0,0 +1 @@ +export class Prisma {} diff --git a/src/prisma/prisma.controller.spec.ts b/src/prisma/prisma.controller.spec.ts new file mode 100644 index 0000000..4d29518 --- /dev/null +++ b/src/prisma/prisma.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PrismaController } from './prisma.controller'; +import { PrismaService } from './prisma.service'; + +describe('PrismaController', () => { + let controller: PrismaController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [PrismaController], + providers: [PrismaService], + }).compile(); + + controller = module.get(PrismaController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/src/prisma/prisma.controller.ts b/src/prisma/prisma.controller.ts new file mode 100644 index 0000000..0512c90 --- /dev/null +++ b/src/prisma/prisma.controller.ts @@ -0,0 +1,34 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { PrismaService } from './prisma.service'; +import { CreatePrismaDto } from './dto/create-prisma.dto'; +import { UpdatePrismaDto } from './dto/update-prisma.dto'; + +@Controller('prisma') +export class PrismaController { + constructor(private readonly prismaService: PrismaService) {} + + @Post() + create(@Body() createPrismaDto: CreatePrismaDto) { + return this.prismaService.create(createPrismaDto); + } + + @Get() + findAll() { + return this.prismaService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.prismaService.findOne(+id); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updatePrismaDto: UpdatePrismaDto) { + return this.prismaService.update(+id, updatePrismaDto); + } + + @Delete(':id') + remove(@Param('id') id: string) { + return this.prismaService.remove(+id); + } +} diff --git a/src/prisma/prisma.module.ts b/src/prisma/prisma.module.ts new file mode 100644 index 0000000..81fa4a2 --- /dev/null +++ b/src/prisma/prisma.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { PrismaService } from './prisma.service'; +import { PrismaController } from './prisma.controller'; + +@Module({ + controllers: [PrismaController], + providers: [PrismaService], +}) +export class PrismaModule {} diff --git a/src/prisma/prisma.service.spec.ts b/src/prisma/prisma.service.spec.ts new file mode 100644 index 0000000..a68cb9e --- /dev/null +++ b/src/prisma/prisma.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PrismaService } from './prisma.service'; + +describe('PrismaService', () => { + let service: PrismaService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PrismaService], + }).compile(); + + service = module.get(PrismaService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/prisma/prisma.service.ts b/src/prisma/prisma.service.ts new file mode 100644 index 0000000..ca52f03 --- /dev/null +++ b/src/prisma/prisma.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@nestjs/common'; +import { CreatePrismaDto } from './dto/create-prisma.dto'; +import { UpdatePrismaDto } from './dto/update-prisma.dto'; + +@Injectable() +export class PrismaService { + create(createPrismaDto: CreatePrismaDto) { + return 'This action adds a new prisma'; + } + + findAll() { + return `This action returns all prisma`; + } + + findOne(id: number) { + return `This action returns a #${id} prisma`; + } + + update(id: number, updatePrismaDto: UpdatePrismaDto) { + return `This action updates a #${id} prisma`; + } + + remove(id: number) { + return `This action removes a #${id} prisma`; + } +} From 74d7fe80423fc2919e6b766b91d47f040e249dd9 Mon Sep 17 00:00:00 2001 From: Connor McSwain Date: Mon, 20 Apr 2026 16:13:41 +0200 Subject: [PATCH 3/4] feat: add order api with dto --- prisma/schema.prisma | 3 +- src/app.module.ts | 17 +----- src/modules/orders/dto/create-order.dto.ts | 17 ++---- src/modules/orders/orders.controller.ts | 19 +++++-- src/modules/orders/orders.module.ts | 2 + src/modules/orders/orders.service.ts | 24 +++++--- src/prisma/dto/create-prisma.dto.ts | 17 +++++- src/prisma/prisma.controller.ts | 6 +- src/prisma/prisma.module.ts | 1 + src/prisma/prisma.service.ts | 65 ++++++++++++++++++---- src/utils/transformer.ts | 6 -- 11 files changed, 114 insertions(+), 63 deletions(-) delete mode 100644 src/utils/transformer.ts diff --git a/prisma/schema.prisma b/prisma/schema.prisma index ce278de..3e34b91 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,6 +1,7 @@ generator client { provider = "prisma-client" output = "../src/generated/prisma" + moduleFormat = "cjs" } datasource db { @@ -20,4 +21,4 @@ model Products { size String? description String? createdAt DateTime @default(now()) @db.Timestamptz(6) -} \ No newline at end of file +} diff --git a/src/app.module.ts b/src/app.module.ts index 6cd23bd..6599451 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -3,25 +3,10 @@ import { ConfigModule } from '@nestjs/config'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { OrdersModule } from './modules/orders/orders.module'; -import { TypeOrmModule } from '@nestjs/typeorm'; import { PrismaModule } from './prisma/prisma.module'; @Module({ - imports: [ - ConfigModule.forRoot(), - OrdersModule, - TypeOrmModule.forRoot({ - type: 'postgres', - host: 'postgresdb', - port: 5432, - username: 'postgres', - password: 'postgres', - database: 'db', - autoLoadEntities: true, - synchronize: true, - }), - PrismaModule, - ], + imports: [ConfigModule.forRoot(), OrdersModule, PrismaModule], controllers: [AppController], providers: [AppService], }) diff --git a/src/modules/orders/dto/create-order.dto.ts b/src/modules/orders/dto/create-order.dto.ts index cce7ce0..7852603 100644 --- a/src/modules/orders/dto/create-order.dto.ts +++ b/src/modules/orders/dto/create-order.dto.ts @@ -1,6 +1,4 @@ -import { IsNotEmpty, IsString, IsUUID, MaxLength } from '@nestjs/class-validator'; -import { UUID } from 'crypto'; -import { Timestamp } from 'typeorm'; +import { IsNotEmpty, IsOptional, IsString, MaxLength } from '@nestjs/class-validator'; export class CreateOrderDto { @MaxLength(128) @@ -9,17 +7,10 @@ export class CreateOrderDto { name: string; @IsString() - @IsNotEmpty() + @IsOptional() size?: string; - @IsUUID() - @IsNotEmpty() - id: UUID; - @IsString() - @IsNotEmpty() - costumer: string; - - @IsNotEmpty() - createdAt: Timestamp; + @IsOptional() + description?: string; } diff --git a/src/modules/orders/orders.controller.ts b/src/modules/orders/orders.controller.ts index d82a18d..9debafe 100644 --- a/src/modules/orders/orders.controller.ts +++ b/src/modules/orders/orders.controller.ts @@ -1,25 +1,34 @@ -import { Controller, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { Controller, Post, Body, Patch, Param, Delete, Get } from '@nestjs/common'; import { OrdersService } from './orders.service'; import { CreateOrderDto } from './dto/create-order.dto'; import { UpdateOrderDto } from './dto/update-order.dto'; -import { PrismaService } from '../../prisma/prisma.service'; @Controller('orders') export class OrdersController { - constructor(private readonly prisma: PrismaService) {} + constructor(private readonly ordersService: OrdersService) {} @Post() create(@Body() createOrderDto: CreateOrderDto) { return this.ordersService.create(createOrderDto); } + @Get() + findAll() { + return this.ordersService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string) { + return this.ordersService.findOne(id); + } + @Patch(':id') update(@Param('id') id: string, @Body() updateOrderDto: UpdateOrderDto) { - return this.ordersService.update(+id, updateOrderDto); + return this.ordersService.update(id, updateOrderDto); } @Delete(':id') remove(@Param('id') id: string) { - return this.ordersService.remove(+id); + return this.ordersService.remove(id); } } diff --git a/src/modules/orders/orders.module.ts b/src/modules/orders/orders.module.ts index de72044..b2cb5d4 100644 --- a/src/modules/orders/orders.module.ts +++ b/src/modules/orders/orders.module.ts @@ -1,8 +1,10 @@ import { Module } from '@nestjs/common'; import { OrdersService } from './orders.service'; import { OrdersController } from './orders.controller'; +import { PrismaModule } from '../../prisma/prisma.module'; @Module({ + imports: [PrismaModule], controllers: [OrdersController], providers: [OrdersService], }) diff --git a/src/modules/orders/orders.service.ts b/src/modules/orders/orders.service.ts index ddc00ed..43c4e86 100644 --- a/src/modules/orders/orders.service.ts +++ b/src/modules/orders/orders.service.ts @@ -1,26 +1,34 @@ import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../../prisma/prisma.service'; import { CreateOrderDto } from './dto/create-order.dto'; import { UpdateOrderDto } from './dto/update-order.dto'; @Injectable() export class OrdersService { + constructor(private readonly prisma: PrismaService) {} + create(createOrderDto: CreateOrderDto) { - return 'This action adds a new order'; + const { name, size, description } = createOrderDto; + return this.prisma.create({ + name, + size, + description, + }); } findAll() { - return `This action returns all orders`; + return this.prisma.findAll(); } - findOne(id: number) { - return `This action returns a #${id} order`; + findOne(id: string) { + return this.prisma.findOne(id); } - update(id: number, updateOrderDto: UpdateOrderDto) { - return `This action updates a #${id} order`; + update(id: string, updateOrderDto: UpdateOrderDto) { + return this.prisma.update(id, updateOrderDto); } - remove(id: number) { - return `This action removes a #${id} order`; + remove(id: string) { + return this.prisma.remove(id); } } diff --git a/src/prisma/dto/create-prisma.dto.ts b/src/prisma/dto/create-prisma.dto.ts index 055ebc9..bb2d22b 100644 --- a/src/prisma/dto/create-prisma.dto.ts +++ b/src/prisma/dto/create-prisma.dto.ts @@ -1 +1,16 @@ -export class CreatePrismaDto {} +import { IsNotEmpty, IsOptional, IsString, MaxLength } from '@nestjs/class-validator'; + +export class CreatePrismaDto { + @MaxLength(128) + @IsString() + @IsNotEmpty() + name: string; + + @IsString() + @IsOptional() + size?: string; + + @IsString() + @IsOptional() + description?: string; +} diff --git a/src/prisma/prisma.controller.ts b/src/prisma/prisma.controller.ts index 0512c90..9896688 100644 --- a/src/prisma/prisma.controller.ts +++ b/src/prisma/prisma.controller.ts @@ -19,16 +19,16 @@ export class PrismaController { @Get(':id') findOne(@Param('id') id: string) { - return this.prismaService.findOne(+id); + return this.prismaService.findOne(id); } @Patch(':id') update(@Param('id') id: string, @Body() updatePrismaDto: UpdatePrismaDto) { - return this.prismaService.update(+id, updatePrismaDto); + return this.prismaService.update(id, updatePrismaDto); } @Delete(':id') remove(@Param('id') id: string) { - return this.prismaService.remove(+id); + return this.prismaService.remove(id); } } diff --git a/src/prisma/prisma.module.ts b/src/prisma/prisma.module.ts index 81fa4a2..4aecb62 100644 --- a/src/prisma/prisma.module.ts +++ b/src/prisma/prisma.module.ts @@ -5,5 +5,6 @@ import { PrismaController } from './prisma.controller'; @Module({ controllers: [PrismaController], providers: [PrismaService], + exports: [PrismaService], }) export class PrismaModule {} diff --git a/src/prisma/prisma.service.ts b/src/prisma/prisma.service.ts index ca52f03..daa94c7 100644 --- a/src/prisma/prisma.service.ts +++ b/src/prisma/prisma.service.ts @@ -1,26 +1,71 @@ -import { Injectable } from '@nestjs/common'; +// src/prisma/prisma.service.ts +import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'; +import { PrismaClient } from '../generated/prisma/client'; +import { PrismaPg } from '@prisma/adapter-pg'; import { CreatePrismaDto } from './dto/create-prisma.dto'; import { UpdatePrismaDto } from './dto/update-prisma.dto'; +type ProductRecord = { + id: string; + name: string; + size: string | null; + description: string | null; + createdAt: Date; +}; + +type ProductsDelegate = { + create(args: { data: CreatePrismaDto }): Promise; + findMany(): Promise; + findUnique(args: { where: { id: string } }): Promise; + update(args: { where: { id: string }; data: UpdatePrismaDto }): Promise; + delete(args: { where: { id: string } }): Promise; +}; + @Injectable() -export class PrismaService { +export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy { + constructor() { + super({ + adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL }), + }); + } + async onModuleInit() { + await this.$connect(); + } + async onModuleDestroy() { + await this.$disconnect(); + } + + private productsDelegate(): ProductsDelegate { + const prismaClient = this as unknown as { products: ProductsDelegate }; + return prismaClient.products; + } + create(createPrismaDto: CreatePrismaDto) { - return 'This action adds a new prisma'; + return this.productsDelegate().create({ + data: createPrismaDto, + }); } findAll() { - return `This action returns all prisma`; + return this.productsDelegate().findMany(); } - findOne(id: number) { - return `This action returns a #${id} prisma`; + findOne(id: string) { + return this.productsDelegate().findUnique({ + where: { id }, + }); } - update(id: number, updatePrismaDto: UpdatePrismaDto) { - return `This action updates a #${id} prisma`; + update(id: string, updatePrismaDto: UpdatePrismaDto) { + return this.productsDelegate().update({ + where: { id }, + data: updatePrismaDto, + }); } - remove(id: number) { - return `This action removes a #${id} prisma`; + remove(id: string) { + return this.productsDelegate().delete({ + where: { id }, + }); } } diff --git a/src/utils/transformer.ts b/src/utils/transformer.ts deleted file mode 100644 index deff5e1..0000000 --- a/src/utils/transformer.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { TransformFnParams } from '@nestjs/class-transformer'; -import sanitizeHtml from 'sanitize-html'; - -export function sanitizeHtmlTransformer(params: TransformFnParams): unknown { - return typeof params.value === 'string' ? sanitizeHtml(params.value as string) : params.value; -} From dae3bae30be08e0f2d9e7dc7e2a1a19623b2d6df Mon Sep 17 00:00:00 2001 From: Connor McSwain Date: Wed, 22 Apr 2026 15:15:48 +0200 Subject: [PATCH 4/4] create post api with validation --- package-lock.json | 106 +++++++++++++++++- package.json | 1 + .../migration.sql | 11 ++ prisma/schema.prisma | 8 ++ src/app.module.ts | 3 +- src/modules/orders/dto/create-order.dto.ts | 11 +- src/modules/orders/dto/update-order.dto.ts | 17 ++- src/modules/orders/entities/order.entity.ts | 1 - .../orders/mappings/order-dto.mappers.ts | 10 ++ ...oller.spec.ts => order.controller.spec.ts} | 6 +- src/modules/orders/order.controller.ts | 25 +++++ .../{orders.module.ts => order.module.ts} | 6 +- ....service.spec.ts => order.service.spec.ts} | 10 +- src/modules/orders/order.service.ts | 34 ++++++ src/modules/orders/orders.controller.ts | 34 ------ src/modules/orders/orders.service.ts | 34 ------ src/prisma/prisma.controller.ts | 2 + 17 files changed, 228 insertions(+), 91 deletions(-) rename prisma/migrations/{20260422080517_init => 20260422114150}/migration.sql (68%) delete mode 100644 src/modules/orders/entities/order.entity.ts create mode 100644 src/modules/orders/mappings/order-dto.mappers.ts rename src/modules/orders/{orders.controller.spec.ts => order.controller.spec.ts} (75%) create mode 100644 src/modules/orders/order.controller.ts rename src/modules/orders/{orders.module.ts => order.module.ts} (60%) rename src/modules/orders/{orders.service.spec.ts => order.service.spec.ts} (55%) create mode 100644 src/modules/orders/order.service.ts delete mode 100644 src/modules/orders/orders.controller.ts delete mode 100644 src/modules/orders/orders.service.ts diff --git a/package-lock.json b/package-lock.json index de46583..8617329 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@nestjs/typeorm": "^11.0.1", "@prisma/adapter-pg": "^7.7.0", "@prisma/client": "^7.7.0", + "class-validator": "^0.15.1", "pg": "^8.20.0", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", @@ -2223,7 +2224,7 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -2240,7 +2241,7 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -3529,6 +3530,12 @@ "@types/superagent": "^8.1.0" } }, + "node_modules/@types/validator": { + "version": "13.15.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz", + "integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==", + "license": "MIT" + }, "node_modules/@types/yargs": { "version": "17.0.35", "dev": true, @@ -4220,7 +4227,7 @@ }, "node_modules/acorn": { "version": "8.16.0", - "devOptional": true, + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -4923,6 +4930,17 @@ "dev": true, "license": "MIT" }, + "node_modules/class-validator": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.15.1.tgz", + "integrity": "sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw==", + "license": "MIT", + "dependencies": { + "@types/validator": "^13.15.3", + "libphonenumber-js": "^1.11.1", + "validator": "^13.15.22" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "dev": true, @@ -5342,6 +5360,73 @@ "wrappy": "1" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dotenv": { "version": "17.4.2", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", @@ -7829,7 +7914,7 @@ }, "node_modules/make-error": { "version": "1.3.6", - "devOptional": true, + "dev": true, "license": "ISC" }, "node_modules/makeerror": { @@ -10493,6 +10578,19 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "dev": true, diff --git a/package.json b/package.json index 1a03c95..36c43c4 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@nestjs/typeorm": "^11.0.1", "@prisma/adapter-pg": "^7.7.0", "@prisma/client": "^7.7.0", + "class-validator": "^0.15.1", "pg": "^8.20.0", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", diff --git a/prisma/migrations/20260422080517_init/migration.sql b/prisma/migrations/20260422114150/migration.sql similarity index 68% rename from prisma/migrations/20260422080517_init/migration.sql rename to prisma/migrations/20260422114150/migration.sql index 63d47d5..cc3840a 100644 --- a/prisma/migrations/20260422080517_init/migration.sql +++ b/prisma/migrations/20260422114150/migration.sql @@ -19,5 +19,16 @@ CREATE TABLE "Product" ( CONSTRAINT "Product_pkey" PRIMARY KEY ("id") ); +-- CreateTable +CREATE TABLE "Order" ( + "id" UUID NOT NULL DEFAULT gen_random_uuid(), + "name" TEXT NOT NULL, + "size" TEXT, + "costumer" TEXT NOT NULL, + "createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Order_pkey" PRIMARY KEY ("id") +); + -- CreateIndex CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 2b62a98..a45e4c6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -22,3 +22,11 @@ model Product { description String? createdAt DateTime @default(now()) @db.Timestamptz(6) } + +model Order { + id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid + name String + size String? + costumer String + createdAt DateTime @default(now()) @db.Timestamptz(6) +} diff --git a/src/app.module.ts b/src/app.module.ts index 766648b..66e7822 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -4,9 +4,10 @@ import { AppController } from './app.controller'; import { AppService } from './app.service'; import { PrismaModule } from './modules/prisma/prisma.module'; import { ProductModule } from './modules/products/product.module'; +import { OrdersModule } from './modules/orders/order.module'; @Module({ - imports: [ConfigModule.forRoot(), PrismaModule, ProductModule], + imports: [ConfigModule.forRoot(), PrismaModule, ProductModule, OrdersModule], controllers: [AppController], providers: [AppService], }) diff --git a/src/modules/orders/dto/create-order.dto.ts b/src/modules/orders/dto/create-order.dto.ts index 7852603..29d733a 100644 --- a/src/modules/orders/dto/create-order.dto.ts +++ b/src/modules/orders/dto/create-order.dto.ts @@ -1,16 +1,17 @@ -import { IsNotEmpty, IsOptional, IsString, MaxLength } from '@nestjs/class-validator'; +import { IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator'; export class CreateOrderDto { - @MaxLength(128) @IsString() @IsNotEmpty() - name: string; + @MaxLength(128) + name!: string; @IsString() @IsOptional() size?: string; @IsString() - @IsOptional() - description?: string; + @IsNotEmpty() + @MaxLength(128) + costumer!: string; } diff --git a/src/modules/orders/dto/update-order.dto.ts b/src/modules/orders/dto/update-order.dto.ts index 93dff6d..13b07a3 100644 --- a/src/modules/orders/dto/update-order.dto.ts +++ b/src/modules/orders/dto/update-order.dto.ts @@ -1,4 +1,19 @@ import { PartialType } from '@nestjs/swagger'; import { CreateOrderDto } from './create-order.dto'; +import { IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator'; -export class UpdateOrderDto extends PartialType(CreateOrderDto) {} +export class UpdateOrderDto extends PartialType(CreateOrderDto) { + @IsString() + @IsNotEmpty() + @MaxLength(128) + name!: string; + + @IsString() + @IsOptional() + size?: string; + + @IsString() + @IsNotEmpty() + @MaxLength(128) + costumer!: string; +} diff --git a/src/modules/orders/entities/order.entity.ts b/src/modules/orders/entities/order.entity.ts deleted file mode 100644 index f3ec29e..0000000 --- a/src/modules/orders/entities/order.entity.ts +++ /dev/null @@ -1 +0,0 @@ -export class Order {} diff --git a/src/modules/orders/mappings/order-dto.mappers.ts b/src/modules/orders/mappings/order-dto.mappers.ts new file mode 100644 index 0000000..a06809a --- /dev/null +++ b/src/modules/orders/mappings/order-dto.mappers.ts @@ -0,0 +1,10 @@ +import { Order } from '../../../generated/prisma/client'; +import { CreateOrderDto } from '../dto/create-order.dto'; + +export function mapOrderDTO(order: Order): CreateOrderDto { + return { + name: order.name, + size: order.size ?? undefined, + costumer: order.costumer, + }; +} diff --git a/src/modules/orders/orders.controller.spec.ts b/src/modules/orders/order.controller.spec.ts similarity index 75% rename from src/modules/orders/orders.controller.spec.ts rename to src/modules/orders/order.controller.spec.ts index 3be4604..349cdf5 100644 --- a/src/modules/orders/orders.controller.spec.ts +++ b/src/modules/orders/order.controller.spec.ts @@ -1,6 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { OrdersController } from './orders.controller'; -import { OrdersService } from './orders.service'; +import { OrdersController } from './order.controller'; +import { OrderService } from './order.service'; describe('OrdersController', () => { let controller: OrdersController; @@ -8,7 +8,7 @@ describe('OrdersController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [OrdersController], - providers: [OrdersService], + providers: [OrderService], }).compile(); controller = module.get(OrdersController); diff --git a/src/modules/orders/order.controller.ts b/src/modules/orders/order.controller.ts new file mode 100644 index 0000000..7c10adc --- /dev/null +++ b/src/modules/orders/order.controller.ts @@ -0,0 +1,25 @@ +import { Body, Controller, Delete, Param, Patch, Post } from '@nestjs/common'; +import { Order } from '../../generated/prisma/client'; +import { CreateOrderDto } from './dto/create-order.dto'; +import { UpdateOrderDto } from './dto/update-order.dto'; +import { OrderService } from './order.service'; + +@Controller('orders') +export class OrdersController { + constructor(private readonly orderService: OrderService) {} + + @Post() + create(@Body() createOrderDto: CreateOrderDto): Promise { + return this.orderService.create(createOrderDto); + } + + @Patch(':id') + update(@Param('id') id: string, @Body() updateOrderDto: UpdateOrderDto): Promise { + return this.orderService.update(id, updateOrderDto); + } + + @Delete(':id') + remove(@Param('id') id: string): Promise { + return this.orderService.remove(id); + } +} diff --git a/src/modules/orders/orders.module.ts b/src/modules/orders/order.module.ts similarity index 60% rename from src/modules/orders/orders.module.ts rename to src/modules/orders/order.module.ts index b2cb5d4..ec9a7d6 100644 --- a/src/modules/orders/orders.module.ts +++ b/src/modules/orders/order.module.ts @@ -1,11 +1,11 @@ import { Module } from '@nestjs/common'; -import { OrdersService } from './orders.service'; -import { OrdersController } from './orders.controller'; +import { OrderService } from './order.service'; +import { OrdersController } from './order.controller'; import { PrismaModule } from '../../prisma/prisma.module'; @Module({ imports: [PrismaModule], controllers: [OrdersController], - providers: [OrdersService], + providers: [OrderService], }) export class OrdersModule {} diff --git a/src/modules/orders/orders.service.spec.ts b/src/modules/orders/order.service.spec.ts similarity index 55% rename from src/modules/orders/orders.service.spec.ts rename to src/modules/orders/order.service.spec.ts index 3d111a7..31a8118 100644 --- a/src/modules/orders/orders.service.spec.ts +++ b/src/modules/orders/order.service.spec.ts @@ -1,15 +1,15 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { OrdersService } from './orders.service'; +import { OrderService } from './order.service'; -describe('OrdersService', () => { - let service: OrdersService; +describe('OrderService', () => { + let service: OrderService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [OrdersService], + providers: [OrderService], }).compile(); - service = module.get(OrdersService); + service = module.get(OrderService); }); it('should be defined', () => { diff --git a/src/modules/orders/order.service.ts b/src/modules/orders/order.service.ts new file mode 100644 index 0000000..b0fd3cf --- /dev/null +++ b/src/modules/orders/order.service.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@nestjs/common'; +import { Order } from '../../generated/prisma/client'; +import { PrismaService } from '../../prisma/prisma.service'; +import { CreateOrderDto } from './dto/create-order.dto'; +import { UpdateOrderDto } from './dto/update-order.dto'; + +@Injectable() +export class OrderService { + constructor(private readonly prisma: PrismaService) {} + + async create(order: CreateOrderDto): Promise { + return this.prisma.order.create({ + data: { + ...order, + createdAt: new Date(), + }, + }); + } + + async findAll(): Promise { + return this.prisma.order.findMany(); + } + + async update(id: string, data: UpdateOrderDto): Promise { + return this.prisma.order.update({ + where: { id }, + data, + }); + } + + async remove(id: string): Promise { + return this.prisma.order.delete({ where: { id } }); + } +} diff --git a/src/modules/orders/orders.controller.ts b/src/modules/orders/orders.controller.ts deleted file mode 100644 index 9debafe..0000000 --- a/src/modules/orders/orders.controller.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Controller, Post, Body, Patch, Param, Delete, Get } from '@nestjs/common'; -import { OrdersService } from './orders.service'; -import { CreateOrderDto } from './dto/create-order.dto'; -import { UpdateOrderDto } from './dto/update-order.dto'; - -@Controller('orders') -export class OrdersController { - constructor(private readonly ordersService: OrdersService) {} - - @Post() - create(@Body() createOrderDto: CreateOrderDto) { - return this.ordersService.create(createOrderDto); - } - - @Get() - findAll() { - return this.ordersService.findAll(); - } - - @Get(':id') - findOne(@Param('id') id: string) { - return this.ordersService.findOne(id); - } - - @Patch(':id') - update(@Param('id') id: string, @Body() updateOrderDto: UpdateOrderDto) { - return this.ordersService.update(id, updateOrderDto); - } - - @Delete(':id') - remove(@Param('id') id: string) { - return this.ordersService.remove(id); - } -} diff --git a/src/modules/orders/orders.service.ts b/src/modules/orders/orders.service.ts deleted file mode 100644 index 43c4e86..0000000 --- a/src/modules/orders/orders.service.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { PrismaService } from '../../prisma/prisma.service'; -import { CreateOrderDto } from './dto/create-order.dto'; -import { UpdateOrderDto } from './dto/update-order.dto'; - -@Injectable() -export class OrdersService { - constructor(private readonly prisma: PrismaService) {} - - create(createOrderDto: CreateOrderDto) { - const { name, size, description } = createOrderDto; - return this.prisma.create({ - name, - size, - description, - }); - } - - findAll() { - return this.prisma.findAll(); - } - - findOne(id: string) { - return this.prisma.findOne(id); - } - - update(id: string, updateOrderDto: UpdateOrderDto) { - return this.prisma.update(id, updateOrderDto); - } - - remove(id: string) { - return this.prisma.remove(id); - } -} diff --git a/src/prisma/prisma.controller.ts b/src/prisma/prisma.controller.ts index 9896688..91b6d89 100644 --- a/src/prisma/prisma.controller.ts +++ b/src/prisma/prisma.controller.ts @@ -1,8 +1,10 @@ import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { ApiExcludeController } from '@nestjs/swagger'; import { PrismaService } from './prisma.service'; import { CreatePrismaDto } from './dto/create-prisma.dto'; import { UpdatePrismaDto } from './dto/update-prisma.dto'; +@ApiExcludeController() @Controller('prisma') export class PrismaController { constructor(private readonly prismaService: PrismaService) {}