chore: env validation

This commit is contained in:
Kakious 2024-08-02 14:34:31 -04:00
parent 8a283f46e7
commit 17ed2c892d
12 changed files with 604 additions and 13 deletions

View file

@ -17,9 +17,66 @@ module.exports = {
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
"curly": "error",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"import/first": "error",
"import/newline-after-import": "error",
"import/no-duplicates": "error",
"eqeqeq": "warn",
"no-lonely-if": "error",
"no-multi-assign": "error",
"@typescript-eslint/no-shadow": "warn",
"no-useless-return": "error",
"no-useless-rename": "error",
"object-shorthand": "error",
"one-var-declaration-per-line": "error",
"prefer-object-spread": "error",
"no-unreachable-loop": "error",
"no-template-curly-in-string": "error",
"default-case-last": "error",
"no-array-constructor": "error",
"no-else-return": "error",
"no-negated-condition": "error",
"array-callback-return": "error",
"@typescript-eslint/consistent-type-definitions": "error",
"no-type-assertion/no-type-assertion": "warn",
"@typescript-eslint/ban-ts-comment": "error",
"@typescript-eslint/no-extraneous-class": "off",
"@typescript-eslint/prefer-nullish-coalescing": "off",
"@typescript-eslint/no-unsafe-assignment": "warn",
"@typescript-eslint/restrict-template-expressions": "warn",
"@typescript-eslint/no-unsafe-member-access": "warn",
"@typescript-eslint/no-unsafe-argument": "warn",
"@typescript-eslint/no-unsafe-return": "warn",
"@typescript-eslint/no-unsafe-call": "warn",
"@typescript-eslint/require-await": "warn",
"@typescript-eslint/restrict-plus-operands": "warn",
"@typescript-eslint/no-non-null-asserted-optional-chain": "warn",
"@typescript-eslint/no-misused-promises": [
"warn",
{
"checksVoidReturn": {
"attributes": false
}
}
],
"@typescript-eslint/await-thenable": "warn",
"@typescript-eslint/no-floating-promises": "warn",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-unnecessary-condition": "warn",
"@typescript-eslint/non-nullable-type-assertion-style": "warn",
"@typescript-eslint/no-confusing-void-expression": "warn",
"@typescript-eslint/no-redundant-type-constituents": "warn",
"@typescript-eslint/no-invalid-void-type": "warn",
"@typescript-eslint/dot-notation": "warn",
"@typescript-eslint/prefer-optional-chain": "warn",
"@typescript-eslint/no-meaningless-void-operator": "warn",
"@typescript-eslint/no-unnecessary-type-arguments": "warn",
"@typescript-eslint/consistent-indexed-object-style": "warn",
"unused-imports/no-unused-imports": "error"
},
};

126
.eslintrc.json Normal file
View file

@ -0,0 +1,126 @@
{
"env": {
"browser": true,
"es6": true,
"node": true,
"es2021": true
},
"settings": {
"react": {
"version": "detect"
}
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/strict-type-checked",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/stylistic-type-checked",
"plugin:@typescript-eslint/strict",
"next/core-web-vitals",
"plugin:cypress/recommended",
"plugin:prettier/recommended",
"plugin:sonarjs/recommended"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module",
"project": "./tsconfig.json"
},
"plugins": [
"react",
"@typescript-eslint",
"prettier",
"simple-import-sort",
"no-type-assertion",
"sonarjs",
"import",
"unused-imports"
],
"rules": {
"react/prop-types": "off",
"react/react-in-jsx-scope": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
],
"@typescript-eslint/explicit-function-return-type": [
"warn",
{
"allowExpressions": true,
"allowTypedFunctionExpressions": true,
"allowHigherOrderFunctions": true
}
],
"@next/next/no-img-element": "off",
"curly": "error",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"import/first": "error",
"import/newline-after-import": "error",
"import/no-duplicates": "error",
"eqeqeq": "warn",
"no-lonely-if": "error",
"no-multi-assign": "error",
"@typescript-eslint/no-shadow": "warn",
"no-useless-return": "error",
"no-useless-rename": "error",
"object-shorthand": "error",
"one-var-declaration-per-line": "error",
"prefer-object-spread": "error",
"no-unreachable-loop": "error",
"no-template-curly-in-string": "error",
"default-case-last": "error",
"no-array-constructor": "error",
"no-else-return": "error",
"no-negated-condition": "error",
"array-callback-return": "error",
"@typescript-eslint/consistent-type-definitions": "error",
"no-type-assertion/no-type-assertion": "warn",
"@typescript-eslint/ban-ts-comment": "error",
"@typescript-eslint/no-extraneous-class": "off",
"@typescript-eslint/prefer-nullish-coalescing": "off",
"@typescript-eslint/no-unsafe-assignment": "warn",
"@typescript-eslint/restrict-template-expressions": "warn",
"@typescript-eslint/no-unsafe-member-access": "warn",
"@typescript-eslint/no-unsafe-argument": "warn",
"@typescript-eslint/no-unsafe-return": "warn",
"@typescript-eslint/no-unsafe-call": "warn",
"@typescript-eslint/require-await": "warn",
"@typescript-eslint/restrict-plus-operands": "warn",
"@typescript-eslint/no-non-null-asserted-optional-chain": "warn",
"@typescript-eslint/no-misused-promises": [
"warn",
{
"checksVoidReturn": {
"attributes": false
}
}
],
"@typescript-eslint/await-thenable": "warn",
"@typescript-eslint/no-floating-promises": "warn",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-unnecessary-condition": "warn",
"@typescript-eslint/non-nullable-type-assertion-style": "warn",
"@typescript-eslint/no-confusing-void-expression": "warn",
"@typescript-eslint/no-redundant-type-constituents": "warn",
"@typescript-eslint/no-invalid-void-type": "warn",
"@typescript-eslint/dot-notation": "warn",
"@typescript-eslint/prefer-optional-chain": "warn",
"@typescript-eslint/no-meaningless-void-operator": "warn",
"@typescript-eslint/no-unnecessary-type-arguments": "warn",
"@typescript-eslint/consistent-indexed-object-style": "warn",
"unused-imports/no-unused-imports": "error"
}
}

View file

@ -3,5 +3,8 @@
"trailingComma": "all",
"tabWidth": 2,
"semi": true,
"printWidth": 100
"printWidth": 100,
"importOrderSeparation": true,
"importOrderSortSpecifiers": true,
"plugins": ["@trivago/prettier-plugin-sort-imports"]
}

View file

@ -46,6 +46,7 @@
"handlebars": "^4.7.8",
"hbs": "^4.2.0",
"ioredis": "^5.4.1",
"joi": "^17.13.3",
"keygrip": "^1.1.0",
"mysql2": "^3.10.2",
"nanoid": "^5.0.7",
@ -63,10 +64,13 @@
"wildcard": "^2.0.1"
},
"devDependencies": {
"@eslint/js": "^9.8.0",
"@nestjs/cli": "^10.4.2",
"@nestjs/schematics": "^10.1.2",
"@nestjs/testing": "^10.3.10",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/cookie-parser": "^1.4.7",
"@types/eslint__js": "^8.42.3",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.12",
"@types/keygrip": "^1.0.6",
@ -89,7 +93,8 @@
"ts-node": "^10.9.2",
"ts-patch": "^3.2.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.5.2"
"typescript": "^5.5.2",
"typescript-eslint": "^7.17.0"
},
"jest": {
"moduleFileExtensions": [

View file

@ -68,6 +68,9 @@ importers:
ioredis:
specifier: ^5.4.1
version: 5.4.1
joi:
specifier: ^17.13.3
version: 17.13.3
keygrip:
specifier: ^1.1.0
version: 1.1.0
@ -114,6 +117,9 @@ importers:
specifier: ^2.0.1
version: 2.0.1
devDependencies:
'@eslint/js':
specifier: ^9.8.0
version: 9.8.0
'@nestjs/cli':
specifier: ^10.4.2
version: 10.4.2
@ -123,9 +129,15 @@ importers:
'@nestjs/testing':
specifier: ^10.3.10
version: 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10))
'@trivago/prettier-plugin-sort-imports':
specifier: ^4.3.0
version: 4.3.0(prettier@3.3.3)
'@types/cookie-parser':
specifier: ^1.4.7
version: 1.4.7
'@types/eslint__js':
specifier: ^8.42.3
version: 8.42.3
'@types/express':
specifier: ^4.17.21
version: 4.17.21
@ -195,6 +207,9 @@ importers:
typescript:
specifier: ^5.5.2
version: 5.5.2
typescript-eslint:
specifier: ^7.17.0
version: 7.17.0(eslint@8.57.0)(typescript@5.5.2)
packages:
@ -239,6 +254,10 @@ packages:
resolution: {integrity: sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.17.7':
resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==}
engines: {node: '>=6.9.0'}
'@babel/generator@7.24.9':
resolution: {integrity: sha512-G8v3jRg+z8IwY1jHFxvCNhOPYPterE4XljNgdGTYfSTtzzwjIswIzIaSPSLs3R7yFuqnqNeay5rjICfqVr+/6A==}
engines: {node: '>=6.9.0'}
@ -383,10 +402,18 @@ packages:
resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==}
engines: {node: '>=6.9.0'}
'@babel/traverse@7.23.2':
resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==}
engines: {node: '>=6.9.0'}
'@babel/traverse@7.24.8':
resolution: {integrity: sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==}
engines: {node: '>=6.9.0'}
'@babel/types@7.17.0':
resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==}
engines: {node: '>=6.9.0'}
'@babel/types@7.24.9':
resolution: {integrity: sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==}
engines: {node: '>=6.9.0'}
@ -420,6 +447,10 @@ packages:
resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
'@eslint/js@9.8.0':
resolution: {integrity: sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@fastify/ajv-compiler@3.6.0':
resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==}
@ -432,6 +463,12 @@ packages:
'@fastify/merge-json-schemas@0.1.1':
resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==}
'@hapi/hoek@9.3.0':
resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==}
'@hapi/topo@5.1.0':
resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==}
'@humanwhocodes/config-array@0.11.14':
resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
engines: {node: '>=10.10.0'}
@ -863,6 +900,15 @@ packages:
'@samchon/openapi@0.4.2':
resolution: {integrity: sha512-lpL+HExpCH65EA8M4L0+bcC0T+0MQCaXjaHdmQ6oHQeSjTgS7ZyoA3l2B6FrkF6XA+mWosQhCmXH5t+VqmoGUQ==}
'@sideway/address@4.1.5':
resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==}
'@sideway/formula@3.0.1':
resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==}
'@sideway/pinpoint@2.0.0':
resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==}
'@sinclair/typebox@0.27.8':
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
@ -883,6 +929,15 @@ packages:
resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==}
engines: {node: '>=14.16'}
'@trivago/prettier-plugin-sort-imports@4.3.0':
resolution: {integrity: sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==}
peerDependencies:
'@vue/compiler-sfc': 3.x
prettier: 2.x - 3.x
peerDependenciesMeta:
'@vue/compiler-sfc':
optional: true
'@tsconfig/node10@1.0.11':
resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
@ -934,6 +989,9 @@ packages:
'@types/eslint@8.56.10':
resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==}
'@types/eslint__js@8.42.3':
resolution: {integrity: sha512-alfG737uhmPdnvkrLdZLcEKJ/B8s9Y4hrZ+YAdzUeoArBlSUERA2E87ROfOaS4jd/C45fzOoZzidLc1IPwLqOw==}
'@types/estree@1.0.5':
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
@ -1032,6 +1090,17 @@ packages:
typescript:
optional: true
'@typescript-eslint/eslint-plugin@7.17.0':
resolution: {integrity: sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
'@typescript-eslint/parser': ^7.0.0
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/parser@7.16.1':
resolution: {integrity: sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==}
engines: {node: ^18.18.0 || >=20.0.0}
@ -1042,10 +1111,24 @@ packages:
typescript:
optional: true
'@typescript-eslint/parser@7.17.0':
resolution: {integrity: sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/scope-manager@7.16.1':
resolution: {integrity: sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/scope-manager@7.17.0':
resolution: {integrity: sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/type-utils@7.16.1':
resolution: {integrity: sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==}
engines: {node: ^18.18.0 || >=20.0.0}
@ -1056,10 +1139,24 @@ packages:
typescript:
optional: true
'@typescript-eslint/type-utils@7.17.0':
resolution: {integrity: sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/types@7.16.1':
resolution: {integrity: sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/types@7.17.0':
resolution: {integrity: sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/typescript-estree@7.16.1':
resolution: {integrity: sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==}
engines: {node: ^18.18.0 || >=20.0.0}
@ -1069,16 +1166,35 @@ packages:
typescript:
optional: true
'@typescript-eslint/typescript-estree@7.17.0':
resolution: {integrity: sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
'@typescript-eslint/utils@7.16.1':
resolution: {integrity: sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
'@typescript-eslint/utils@7.17.0':
resolution: {integrity: sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
'@typescript-eslint/visitor-keys@7.16.1':
resolution: {integrity: sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==}
engines: {node: ^18.18.0 || >=20.0.0}
'@typescript-eslint/visitor-keys@7.17.0':
resolution: {integrity: sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==}
engines: {node: ^18.18.0 || >=20.0.0}
'@ungap/structured-clone@1.2.0':
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
@ -2462,6 +2578,9 @@ packages:
engines: {node: '>=10'}
hasBin: true
javascript-natural-sort@0.7.1:
resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==}
jest-changed-files@29.7.0:
resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@ -2599,6 +2718,9 @@ packages:
resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
hasBin: true
joi@17.13.3:
resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==}
jose@5.6.3:
resolution: {integrity: sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g==}
@ -3603,6 +3725,10 @@ packages:
source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
source-map@0.5.7:
resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==}
engines: {node: '>=0.10.0'}
source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
@ -3976,6 +4102,16 @@ packages:
typeorm-aurora-data-api-driver:
optional: true
typescript-eslint@7.17.0:
resolution: {integrity: sha512-spQxsQvPguduCUfyUvLItvKqK3l8KJ/kqs5Pb/URtzQ5AC53Z6us32St37rpmlt2uESG23lOFpV4UErrmy4dZQ==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
typescript: '*'
peerDependenciesMeta:
typescript:
optional: true
typescript@5.3.3:
resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==}
engines: {node: '>=14.17'}
@ -4259,6 +4395,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@babel/generator@7.17.7':
dependencies:
'@babel/types': 7.24.9
jsesc: 2.5.2
source-map: 0.5.7
'@babel/generator@7.24.9':
dependencies:
'@babel/types': 7.24.9
@ -4416,6 +4558,21 @@ snapshots:
'@babel/parser': 7.24.8
'@babel/types': 7.24.9
'@babel/traverse@7.23.2':
dependencies:
'@babel/code-frame': 7.24.7
'@babel/generator': 7.24.9
'@babel/helper-environment-visitor': 7.24.7
'@babel/helper-function-name': 7.24.7
'@babel/helper-hoist-variables': 7.24.7
'@babel/helper-split-export-declaration': 7.24.7
'@babel/parser': 7.24.8
'@babel/types': 7.24.9
debug: 4.3.5
globals: 11.12.0
transitivePeerDependencies:
- supports-color
'@babel/traverse@7.24.8':
dependencies:
'@babel/code-frame': 7.24.7
@ -4431,6 +4588,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@babel/types@7.17.0':
dependencies:
'@babel/helper-validator-identifier': 7.24.7
to-fast-properties: 2.0.0
'@babel/types@7.24.9':
dependencies:
'@babel/helper-string-parser': 7.24.8
@ -4469,6 +4631,8 @@ snapshots:
'@eslint/js@8.57.0': {}
'@eslint/js@9.8.0': {}
'@fastify/ajv-compiler@3.6.0':
dependencies:
ajv: 8.17.1
@ -4485,6 +4649,12 @@ snapshots:
dependencies:
fast-deep-equal: 3.1.3
'@hapi/hoek@9.3.0': {}
'@hapi/topo@5.1.0':
dependencies:
'@hapi/hoek': 9.3.0
'@humanwhocodes/config-array@0.11.14':
dependencies:
'@humanwhocodes/object-schema': 2.0.3
@ -4983,6 +5153,14 @@ snapshots:
'@samchon/openapi@0.4.2': {}
'@sideway/address@4.1.5':
dependencies:
'@hapi/hoek': 9.3.0
'@sideway/formula@3.0.1': {}
'@sideway/pinpoint@2.0.0': {}
'@sinclair/typebox@0.27.8': {}
'@sindresorhus/is@5.6.0': {}
@ -5001,6 +5179,18 @@ snapshots:
dependencies:
defer-to-connect: 2.0.1
'@trivago/prettier-plugin-sort-imports@4.3.0(prettier@3.3.3)':
dependencies:
'@babel/generator': 7.17.7
'@babel/parser': 7.24.8
'@babel/traverse': 7.23.2
'@babel/types': 7.17.0
javascript-natural-sort: 0.7.1
lodash: 4.17.21
prettier: 3.3.3
transitivePeerDependencies:
- supports-color
'@tsconfig/node10@1.0.11': {}
'@tsconfig/node12@1.0.11': {}
@ -5068,6 +5258,10 @@ snapshots:
'@types/estree': 1.0.5
'@types/json-schema': 7.0.15
'@types/eslint__js@8.42.3':
dependencies:
'@types/eslint': 8.56.10
'@types/estree@1.0.5': {}
'@types/express-serve-static-core@4.19.5':
@ -5195,6 +5389,24 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/eslint-plugin@7.17.0(@typescript-eslint/parser@7.17.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@eslint-community/regexpp': 4.11.0
'@typescript-eslint/parser': 7.17.0(eslint@8.57.0)(typescript@5.5.2)
'@typescript-eslint/scope-manager': 7.17.0
'@typescript-eslint/type-utils': 7.17.0(eslint@8.57.0)(typescript@5.5.2)
'@typescript-eslint/utils': 7.17.0(eslint@8.57.0)(typescript@5.5.2)
'@typescript-eslint/visitor-keys': 7.17.0
eslint: 8.57.0
graphemer: 1.4.0
ignore: 5.3.1
natural-compare: 1.4.0
ts-api-utils: 1.3.0(typescript@5.5.2)
optionalDependencies:
typescript: 5.5.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@7.16.1(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@typescript-eslint/scope-manager': 7.16.1
@ -5208,11 +5420,29 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@7.17.0(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@typescript-eslint/scope-manager': 7.17.0
'@typescript-eslint/types': 7.17.0
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.2)
'@typescript-eslint/visitor-keys': 7.17.0
debug: 4.3.5
eslint: 8.57.0
optionalDependencies:
typescript: 5.5.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/scope-manager@7.16.1':
dependencies:
'@typescript-eslint/types': 7.16.1
'@typescript-eslint/visitor-keys': 7.16.1
'@typescript-eslint/scope-manager@7.17.0':
dependencies:
'@typescript-eslint/types': 7.17.0
'@typescript-eslint/visitor-keys': 7.17.0
'@typescript-eslint/type-utils@7.16.1(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.2)
@ -5225,8 +5455,22 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/type-utils@7.17.0(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.2)
'@typescript-eslint/utils': 7.17.0(eslint@8.57.0)(typescript@5.5.2)
debug: 4.3.5
eslint: 8.57.0
ts-api-utils: 1.3.0(typescript@5.5.2)
optionalDependencies:
typescript: 5.5.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@7.16.1': {}
'@typescript-eslint/types@7.17.0': {}
'@typescript-eslint/typescript-estree@7.16.1(typescript@5.5.2)':
dependencies:
'@typescript-eslint/types': 7.16.1
@ -5242,6 +5486,21 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/typescript-estree@7.17.0(typescript@5.5.2)':
dependencies:
'@typescript-eslint/types': 7.17.0
'@typescript-eslint/visitor-keys': 7.17.0
debug: 4.3.5
globby: 11.1.0
is-glob: 4.0.3
minimatch: 9.0.5
semver: 7.6.2
ts-api-utils: 1.3.0(typescript@5.5.2)
optionalDependencies:
typescript: 5.5.2
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@7.16.1(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
@ -5253,11 +5512,27 @@ snapshots:
- supports-color
- typescript
'@typescript-eslint/utils@7.17.0(eslint@8.57.0)(typescript@5.5.2)':
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@typescript-eslint/scope-manager': 7.17.0
'@typescript-eslint/types': 7.17.0
'@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.2)
eslint: 8.57.0
transitivePeerDependencies:
- supports-color
- typescript
'@typescript-eslint/visitor-keys@7.16.1':
dependencies:
'@typescript-eslint/types': 7.16.1
eslint-visitor-keys: 3.4.3
'@typescript-eslint/visitor-keys@7.17.0':
dependencies:
'@typescript-eslint/types': 7.17.0
eslint-visitor-keys: 3.4.3
'@ungap/structured-clone@1.2.0': {}
'@webassemblyjs/ast@1.12.1':
@ -6826,6 +7101,8 @@ snapshots:
filelist: 1.0.4
minimatch: 3.1.2
javascript-natural-sort@0.7.1: {}
jest-changed-files@29.7.0:
dependencies:
execa: 5.1.1
@ -7143,6 +7420,14 @@ snapshots:
jiti@1.21.6: {}
joi@17.13.3:
dependencies:
'@hapi/hoek': 9.3.0
'@hapi/topo': 5.1.0
'@sideway/address': 4.1.5
'@sideway/formula': 3.0.1
'@sideway/pinpoint': 2.0.0
jose@5.6.3: {}
js-beautify@1.15.1:
@ -8129,6 +8414,8 @@ snapshots:
buffer-from: 1.1.2
source-map: 0.6.1
source-map@0.5.7: {}
source-map@0.6.1: {}
source-map@0.7.4: {}
@ -8465,6 +8752,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
typescript-eslint@7.17.0(eslint@8.57.0)(typescript@5.5.2):
dependencies:
'@typescript-eslint/eslint-plugin': 7.17.0(@typescript-eslint/parser@7.17.0(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2)
'@typescript-eslint/parser': 7.17.0(eslint@8.57.0)(typescript@5.5.2)
'@typescript-eslint/utils': 7.17.0(eslint@8.57.0)(typescript@5.5.2)
eslint: 8.57.0
optionalDependencies:
typescript: 5.5.2
transitivePeerDependencies:
- supports-color
typescript@5.3.3: {}
typescript@5.5.2: {}

View file

@ -15,6 +15,7 @@ import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
import { AuthMiddleware } from './auth/middleware/auth.middleware';
import { ClsModule } from 'nestjs-cls';
import { validate } from './config/env.validation';
@Module({
imports: [
@ -37,6 +38,7 @@ import { ClsModule } from 'nestjs-cls';
},
}),
ConfigModule.forRoot({
validate,
cache: true,
isGlobal: true,
load: [config, databaseConfig],

View file

@ -27,7 +27,7 @@ import {
import { ConfigService } from '@nestjs/config';
import { DataSource } from 'typeorm';
import { RedisService } from '../../redis/redis.service';
import { UserService } from 'src/user/user.service';
import { UserService } from '../../user/service/user.service';
import { Span } from 'nestjs-otel';
import generateId from './helper/nanoid.helper';
import { context, trace } from '@opentelemetry/api';

View file

@ -1,6 +1,6 @@
import { BadRequestException, Injectable } from '@nestjs/common';
import { UserService } from '../../user/user.service';
import { UserService } from '../../user/service/user.service';
import { RedisService } from '../../redis/redis.service';
import { MailService } from '../../mail/mail.service';
import { getResetKey, PASSWORD_RESET_EXPIRATION } from '../auth.const';

View file

@ -6,7 +6,7 @@ export default registerAs('database', () => {
type: 'mysql',
autoLoadEntities: true,
host: process.env['DATABASE_HOST'],
port: parseInt(process.env['DATABASE_PORT'] || '0', 10),
port: parseInt(process.env['DATABASE_PORT'] || '3306', 10),
database: process.env['DATABASE_NAME'],
username: process.env['DATABASE_USERNAME'],
password: process.env['DATABASE_PASSWORD'],

View file

@ -0,0 +1,100 @@
import { plainToInstance } from 'class-transformer';
import {
IsBoolean,
IsEnum,
IsNumber,
IsOptional,
IsString,
Max,
Min,
validateSync,
} from 'class-validator';
enum Environment {
Development = 'development',
Production = 'production',
Test = 'test',
}
class EnvironmentVariables {
@IsEnum(Environment)
@IsOptional()
NODE_ENV: Environment;
@IsString()
BASE_URL: string;
@IsString()
@IsOptional()
APP_NAME: string;
@IsString()
DATABASE_HOST: string;
@IsNumber()
@IsOptional()
@Min(0)
@Max(65535)
DATABASE_PORT: number;
@IsString()
DATABASE_USERNAME: string;
@IsString()
DATABASE_PASSWORD: string;
@IsString()
DATABASE_NAME: string;
@IsBoolean()
@IsOptional()
DATABASE_SYNCHRONIZE: boolean;
@IsBoolean()
@IsOptional()
DATABASE_DISABLE_MIGRATIONS: boolean;
@IsBoolean()
@IsOptional()
DATABASE_DEBUG_LOGGING: boolean;
@IsString()
REDIS_HOST: string;
@IsNumber()
@IsOptional()
@Min(0)
@Max(65535)
REDIS_PORT: number;
@IsString()
@IsOptional()
REDIS_PASSWORD: string;
@IsNumber()
@IsOptional()
@Min(0)
@Max(10)
REDIS_DB: number;
@IsString()
POSTAL_BASE_URL: string;
@IsString()
POSTAL_API_KEY: string;
@IsString()
FROM_EMAIL: string;
}
export function validate(config: Record<string, unknown>) {
const validatedConfig = plainToInstance(EnvironmentVariables, config, {
enableImplicitConversion: true,
});
const errors = validateSync(validatedConfig, { skipMissingProperties: false });
if (errors.length > 0) {
throw new Error(errors.toString());
}
return validatedConfig;
}

View file

@ -3,15 +3,15 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { hash, verify } from 'argon2';
import { User } from '../database/models/user.model';
import { RedisService } from '../redis/redis.service';
import { User } from '../../database/models/user.model';
import { RedisService } from '../../redis/redis.service';
import { Span } from 'nestjs-otel';
import {
DISABLED_USER_ERROR,
INVALID_CREDENTIALS_ERROR,
USER_NOT_FOUND_ERROR,
userCacheKey,
} from './user.constant';
} from '../user.constant';
import { ClsService } from 'nestjs-cls';
@Injectable()

View file

@ -2,7 +2,7 @@ import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { RedisModule } from '../redis/redis.module';
import { UserService } from './user.service';
import { UserService } from './service/user.service';
import { DATABASE_ENTITIES } from 'src/database/database.entities';
@Module({