From 6457b1aef6c743d8e0c35db4ada73d3759e93dde Mon Sep 17 00:00:00 2001 From: Rubin Bhandari Date: Tue, 26 Sep 2023 19:40:51 +0545 Subject: [PATCH] feat: eslint flat config --- eslint.config.mjs | 44 ++ package.json | 16 +- pnpm-lock.yaml | 696 ++++++++++++++++-- src/_mocks_/index.ts | 6 +- src/common/@types/classes/offset.response.ts | 3 +- src/common/@types/enums/misc.enum.ts | 10 +- src/common/@types/global.d.ts | 150 ++-- .../@types/interfaces/crud.interface.ts | 6 +- .../@types/interfaces/pagination.interface.ts | 3 +- src/common/database/base.repository.spec.ts | 44 +- src/common/database/base.repository.ts | 6 +- src/common/database/seeders/admin.seeder.ts | 3 +- .../decorators/custom-cache.decorator.ts | 3 +- .../validation/is-after.validator.spec.ts | 68 +- .../validation/is-after.validator.ts | 2 - .../is-date-format.validator.spec.ts | 36 +- .../validation/is-date-format.validator.ts | 1 - .../validation/is-equal-to.validator.spec.ts | 48 +- .../validation/is-equal-to.validator.ts | 2 - .../is-greater-than.validator.spec.ts | 68 +- .../validation/is-password.validator.spec.ts | 48 +- .../validation/is-password.validator.ts | 3 +- .../validation/is-profane.validator.spec.ts | 42 +- .../validation/is-string-field.decorator.ts | 5 +- .../validation/is-unique.validator.spec.ts | 87 ++- .../validation/is-username.validator.spec.ts | 46 +- .../validation/is-username.validator.ts | 4 +- .../validation/validation-field.generator.ts | 2 +- src/common/dtos/cursor-pagination.dto.ts | 2 +- src/common/dtos/offset-pagination.dto.ts | 2 +- src/common/guards/auth.guard.spec.ts | 78 +- src/common/guards/jwt.guard.spec.ts | 57 +- src/common/helpers/app.utils.ts | 4 +- src/common/helpers/helpers.utils.ts | 1 - .../interceptors/app-exit.interceptor.spec.ts | 26 +- .../request-sanitizer.interceptor.spec.ts | 67 +- .../interceptors/timeout.interceptor.spec.ts | 26 +- .../middlewares/cache.middleware.spec.ts | 52 +- src/common/middlewares/ip.middleware.spec.ts | 41 +- src/common/misc/pool.ts | 7 +- src/entities/category.entity.ts | 3 +- src/entities/comment.entity.ts | 3 +- src/entities/conversation.entity.ts | 3 +- src/entities/message.entity.ts | 3 +- src/entities/otp-log.entity.ts | 3 +- src/entities/points-redemption-log.entity.ts | 3 +- src/entities/post.entity.ts | 5 +- src/entities/referral.entity.ts | 2 +- src/entities/refresh-token.entity.ts | 3 +- src/entities/tag.entity.ts | 3 +- src/generated/i18n.generated.ts | 92 +-- src/lib/casl/casl-ability.factory.spec.ts | 10 +- src/lib/casl/generic.policy.ts | 6 +- src/lib/casl/policies.decorator.ts | 3 +- src/lib/casl/policies.guard.spec.ts | 40 +- src/lib/casl/policies.guard.ts | 4 +- src/lib/config/config.module.ts | 3 +- src/lib/crud/crud.controller.ts | 2 +- src/lib/mailer/index.ts | 3 +- src/lib/mailer/mailer.service.ts | 3 +- src/lib/twilio/twilio.service.ts | 3 +- src/main.ts | 5 +- src/modules/auth/auth.controller.ts | 18 +- src/modules/auth/auth.module.ts | 6 +- src/modules/auth/auth.service.spec.ts | 215 +++--- src/modules/auth/auth.service.ts | 14 +- .../auth/strategies/jwt-2fa.strategy.ts | 3 +- src/modules/auth/strategies/jwt.strategy.ts | 3 +- .../auth/strategies/magic-login.strategy.ts | 2 +- src/modules/category/category.controller.ts | 4 +- src/modules/category/category.service.ts | 2 +- src/modules/chat/chat.controller.ts | 2 +- src/modules/chat/chat.gateway.ts | 6 +- src/modules/chat/chat.module.ts | 6 +- .../newsletter/newsletter.controller.ts | 4 +- src/modules/newsletter/newsletter.service.ts | 2 +- src/modules/post/post.controller.ts | 4 +- src/modules/post/post.service.spec.ts | 186 ++--- src/modules/post/post.service.ts | 2 +- src/modules/profile/profile.controller.ts | 2 +- src/modules/profile/profile.service.spec.ts | 84 +-- src/modules/tags/tags.controller.ts | 4 +- .../token/refresh-tokens.repository.spec.ts | 104 +-- src/modules/token/tokens.service.spec.ts | 208 +++--- src/modules/token/tokens.service.ts | 2 +- src/modules/twofa/twofa.controller.ts | 4 +- src/modules/twofa/twofa.module.ts | 4 +- src/modules/twofa/twofa.service.spec.ts | 146 ++-- src/modules/user/user.controller.ts | 4 +- src/modules/user/user.service.spec.ts | 177 ++--- src/modules/user/user.service.ts | 2 +- test/e2e/user.e2e-spec.ts | 3 +- tsconfig.json | 2 +- 93 files changed, 1921 insertions(+), 1324 deletions(-) create mode 100644 eslint.config.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..625e9c56 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,44 @@ +import rubiin from "@rubiin/eslint-config"; + +export default rubiin({ + stylistic: true, // enable stylistic rules + typescript: { + tsconfigPath: "tsconfig.json", // path to tsconfig.json + }, +}, +{ + rules: { + "unicorn/prefer-module": "off", + "ts/no-floating-promises": "off", + "ts/no-extraneous-class": "off", + "ts/unbound-method": "off", + "no-useless-constructor": "off", // optimize this + "ts/require-await": "off", // optimize this + "ts/no-unsafe-assignment": "off", // optimize this + "ts/no-unsafe-member-access": "off", // optimize this + "unicorn/prefer-top-level-await": "off", + "max-nested-callbacks": "off", // rxjs is nested + "ts/no-misused-promises": [ + "error", + { + checksVoidReturn: false, + }, + ], + "unicorn/prevent-abbreviations": [ + "error", + { + ignore: [ + "\\.e2e*", + "\\.spec*", + "\\.decorator*", + "\\*idx*", + ], + allowList: { + ProcessEnv: true, + UUIDParam: true, + }, + }, + ], + }, +}, +); diff --git a/package.json b/package.json index 164b7211..b935e3d4 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,8 @@ ], "scripts": { "build": "nest build", - "lint": "eslint '{src,test}/**/*.ts' --cache", - "lint:fix": "eslint '{src,test}/**/*.ts' --cache --fix", + "lint": "ESLINT_USE_FLAT_CONFIG=true eslint -c eslint.config.mjs '{src,test}/**/*.ts' --cache", + "lint:fix": "ESLINT_USE_FLAT_CONFIG=true eslint -c eslint.config.mjs '{src,test}/**/*.ts' --cache --fix --debug", "orm": "npx mikro-orm", "prebuild": "rimraf dist", "sample": "cd env; npx sample-env --env .env.dev", @@ -52,7 +52,7 @@ "test:e2e": "jest --config ./test/jest-e2e.json --runInBand --forceExit" }, "dependencies": { - "@aws-sdk/client-s3": "^3.418.0", + "@aws-sdk/client-s3": "^3.420.0", "@aws-sdk/client-ses": "^3.418.0", "@casl/ability": "^6.5.0", "@golevelup/nestjs-rabbitmq": "^4.0.0", @@ -82,8 +82,8 @@ "@nestjs/websockets": "^10.2.6", "@ntegral/nestjs-sentry": "^4.0.0", "@paralleldrive/cuid2": "^2.2.2", - "@sentry/hub": "^7.71.0", - "@sentry/node": "^7.71.0", + "@sentry/hub": "^7.72.0", + "@sentry/node": "^7.72.0", "@socket.io/redis-adapter": "^8.2.1", "@supercharge/request-ip": "^1.2.0", "argon2": "^0.31.1", @@ -146,9 +146,10 @@ "@nestjs/cli": "10.1.18", "@nestjs/schematics": "10.0.2", "@nestjs/testing": "10.2.6", + "@rubiin/eslint-config": "^1.8.1", "@rubiin/eslint-config-ts": "^1.5.1", "@rubiin/tsconfig": "^1.1.0", - "@sentry/types": "^7.71.0", + "@sentry/types": "^7.72.0", "@side/jest-runtime": "^1.1.0", "@swc/core": "^1.3.89", "@swc/jest": "^0.2.29", @@ -172,13 +173,10 @@ "@types/supertest": "2.0.13", "@types/swagger-stats": "^0.95.9", "@types/swagger-ui-express": "^4.1.4", - "@typescript-eslint/eslint-plugin": "^6.7.3", - "@typescript-eslint/parser": "^6.7.3", "cross-env": "^7.0.3", "cz-conventional-changelog": "3.3.0", "eslint": "^8.50.0", "eslint-define-config": "^1.23.0", - "eslint-import-resolver-typescript": "^3.6.1", "eslint_d": "^12.2.1", "husky": "^8.0.3", "jest": "29.7.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2cdee016..dd3d50d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@aws-sdk/client-s3': - specifier: ^3.418.0 - version: 3.418.0 + specifier: ^3.420.0 + version: 3.420.0 '@aws-sdk/client-ses': specifier: ^3.418.0 version: 3.418.0 @@ -91,16 +91,16 @@ dependencies: version: 10.2.6(@nestjs/common@10.2.6)(@nestjs/core@10.2.6)(@nestjs/platform-socket.io@10.2.6)(reflect-metadata@0.1.13)(rxjs@7.8.1) '@ntegral/nestjs-sentry': specifier: ^4.0.0 - version: 4.0.0(@nestjs/common@10.2.6)(@nestjs/core@10.2.6)(@sentry/hub@7.71.0)(@sentry/node@7.71.0)(class-transformer@0.5.1)(class-validator@0.14.0)(graphql@16.8.1)(reflect-metadata@0.1.13)(rimraf@3.0.2)(rxjs@7.8.1) + version: 4.0.0(@nestjs/common@10.2.6)(@nestjs/core@10.2.6)(@sentry/hub@7.72.0)(@sentry/node@7.72.0)(class-transformer@0.5.1)(class-validator@0.14.0)(graphql@16.8.1)(reflect-metadata@0.1.13)(rimraf@3.0.2)(rxjs@7.8.1) '@paralleldrive/cuid2': specifier: ^2.2.2 version: 2.2.2 '@sentry/hub': - specifier: ^7.71.0 - version: 7.71.0 + specifier: ^7.72.0 + version: 7.72.0 '@sentry/node': - specifier: ^7.71.0 - version: 7.71.0 + specifier: ^7.72.0 + version: 7.72.0 '@socket.io/redis-adapter': specifier: ^8.2.1 version: 8.2.1(socket.io-adapter@2.5.2) @@ -283,15 +283,18 @@ devDependencies: '@nestjs/testing': specifier: 10.2.6 version: 10.2.6(@nestjs/common@10.2.6)(@nestjs/core@10.2.6)(@nestjs/platform-express@10.2.6) + '@rubiin/eslint-config': + specifier: ^1.8.1 + version: 1.8.1(eslint@8.50.0)(typescript@5.2.2) '@rubiin/eslint-config-ts': specifier: ^1.5.1 - version: 1.5.1(eslint-import-resolver-typescript@3.6.1)(jest@29.7.0)(typescript@5.2.2) + version: 1.5.1(jest@29.7.0)(typescript@5.2.2) '@rubiin/tsconfig': specifier: ^1.1.0 version: 1.1.0 '@sentry/types': - specifier: ^7.71.0 - version: 7.71.0 + specifier: ^7.72.0 + version: 7.72.0 '@side/jest-runtime': specifier: ^1.1.0 version: 1.1.0(@jest/transform@29.7.0)(jest-runtime@29.7.0)(jest@29.7.0) @@ -361,12 +364,6 @@ devDependencies: '@types/swagger-ui-express': specifier: ^4.1.4 version: 4.1.4 - '@typescript-eslint/eslint-plugin': - specifier: ^6.7.3 - version: 6.7.3(@typescript-eslint/parser@6.7.3)(eslint@8.50.0)(typescript@5.2.2) - '@typescript-eslint/parser': - specifier: ^6.7.3 - version: 6.7.3(eslint@8.50.0)(typescript@5.2.2) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -379,9 +376,6 @@ devDependencies: eslint-define-config: specifier: ^1.23.0 version: 1.23.0 - eslint-import-resolver-typescript: - specifier: ^3.6.1 - version: 3.6.1(@typescript-eslint/parser@6.7.3)(eslint-plugin-import@2.28.1)(eslint@8.50.0) eslint_d: specifier: ^12.2.1 version: 12.2.1 @@ -582,8 +576,8 @@ packages: tslib: 1.14.1 dev: false - /@aws-sdk/client-s3@3.418.0: - resolution: {integrity: sha512-VdDM9xS84t8W1B2/QJTK6mYVCnf7Hovg8Aum9NHm+bD7F0Ni2NTLVjm8+qq9STi4YSeXAy3Pe+FBUP9Wthw7Iw==} + /@aws-sdk/client-s3@3.420.0: + resolution: {integrity: sha512-fmU0b8tM8vPCrEW8kNcY2yhFQBGuN4asYUAqybiSpzyF9Xy3Q0diQQE9WmoJVTO+DXB8tOhZZqUC1kxHCUDjww==} engines: {node: '>=14.0.0'} dependencies: '@aws-crypto/sha1-browser': 3.0.0 @@ -3238,7 +3232,7 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 - /@ntegral/nestjs-sentry@4.0.0(@nestjs/common@10.2.6)(@nestjs/core@10.2.6)(@sentry/hub@7.71.0)(@sentry/node@7.71.0)(class-transformer@0.5.1)(class-validator@0.14.0)(graphql@16.8.1)(reflect-metadata@0.1.13)(rimraf@3.0.2)(rxjs@7.8.1): + /@ntegral/nestjs-sentry@4.0.0(@nestjs/common@10.2.6)(@nestjs/core@10.2.6)(@sentry/hub@7.72.0)(@sentry/node@7.72.0)(class-transformer@0.5.1)(class-validator@0.14.0)(graphql@16.8.1)(reflect-metadata@0.1.13)(rimraf@3.0.2)(rxjs@7.8.1): resolution: {integrity: sha512-6WHZcK7NLeg7ue1y3Z61msEBzCGZeXQ0hWhliH1ddQH0kPbZ6lXLxduGMWYb0N/fPjXAX1Astz8urqnoTOZBQw==} peerDependencies: '@nestjs/common': ^9.0.4 @@ -3251,8 +3245,8 @@ packages: dependencies: '@nestjs/common': 10.2.6(class-transformer@0.5.1)(class-validator@0.14.0)(reflect-metadata@0.1.13)(rxjs@7.8.1) '@nestjs/core': 10.2.6(@nestjs/common@10.2.6)(@nestjs/platform-express@10.2.6)(@nestjs/websockets@10.2.6)(reflect-metadata@0.1.13)(rxjs@7.8.1) - '@sentry/hub': 7.71.0 - '@sentry/node': 7.71.0 + '@sentry/hub': 7.72.0 + '@sentry/node': 7.72.0 reflect-metadata: 0.1.13 rimraf: 3.0.2 rxjs: 7.8.1 @@ -3455,7 +3449,7 @@ packages: - typescript dev: true - /@rubiin/eslint-config-ts@1.5.1(eslint-import-resolver-typescript@3.6.1)(jest@29.7.0)(typescript@5.2.2): + /@rubiin/eslint-config-ts@1.5.1(jest@29.7.0)(typescript@5.2.2): resolution: {integrity: sha512-S2Bef6E9xNh5C7Edu6XC8ZrsLNVrJdx9LveS4e/AvVmcZG2d518O2rDV4JG/27ypW09pckjztl+fl+8KDKS+Ow==} dependencies: '@rubiin/eslint-config-basic': 1.5.1(typescript@5.2.2) @@ -3475,6 +3469,42 @@ packages: - typescript dev: true + /@rubiin/eslint-config@1.8.1(eslint@8.50.0)(typescript@5.2.2): + resolution: {integrity: sha512-/b0Bk6W6QXF61afr5uxnANFvUnuF2D/lYgjIECXkepMnTHKIdLTJfwerjj4fA+n2CtbPRUYkcWE5TvZa2JaKxA==} + peerDependencies: + eslint: '>=8.0.0' + dependencies: + '@stylistic/eslint-plugin': 0.0.5(eslint@8.50.0)(typescript@5.2.2) + '@typescript-eslint/eslint-plugin': 6.7.3(@typescript-eslint/parser@6.7.3)(eslint@8.50.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + eslint: 8.50.0 + eslint-config-flat-gitignore: 0.1.0 + eslint-define-config: 1.23.0 + eslint-plugin-deprecation: 2.0.0(eslint@8.50.0)(typescript@5.2.2) + eslint-plugin-eslint-comments: 3.2.0(eslint@8.50.0) + eslint-plugin-i: 2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.50.0) + eslint-plugin-jsdoc: 46.8.2(eslint@8.50.0) + eslint-plugin-jsonc: 2.9.0(eslint@8.50.0) + eslint-plugin-markdown: 3.0.1(eslint@8.50.0) + eslint-plugin-n: 16.1.0(eslint@8.50.0) + eslint-plugin-no-only-tests: 3.1.0 + eslint-plugin-react: 7.33.2(eslint@8.50.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.50.0) + eslint-plugin-unicorn: 48.0.1(eslint@8.50.0) + eslint-plugin-unused-imports: 3.0.0(@typescript-eslint/eslint-plugin@6.7.3)(eslint@8.50.0) + eslint-plugin-vue: 9.17.0(eslint@8.50.0) + eslint-plugin-yml: 1.9.0(eslint@8.50.0) + globals: 13.22.0 + jsonc-eslint-parser: 2.3.0 + local-pkg: 0.4.3 + yaml-eslint-parser: 1.2.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - typescript + dev: true + /@rubiin/tsconfig@1.1.0: resolution: {integrity: sha512-uCudO9VLzBTGJfrEALpeBuZS2DJKWnfHkOrrI6sZmXsibH+Y8SEbNBl7v/WCqslkzrTXVCXUkXAlxaCfo8tQCw==} engines: {node: '>=18'} @@ -3495,43 +3525,43 @@ packages: selderee: 0.11.0 dev: false - /@sentry-internal/tracing@7.71.0: - resolution: {integrity: sha512-HRGsQOrA2Y3Ga+NTgCkTWO+qtU2SFTJ7t9pt/LR8Har9cvVcjLIlHNwPoDx6bVkICK3cGOF8ZtXVmLizVbXoAg==} + /@sentry-internal/tracing@7.72.0: + resolution: {integrity: sha512-DToryaRSHk9R5RLgN4ktYEXZjQdqncOAWPqyyIurji8lIobXFRfmLtGL1wjoCK6sQNgWsjhSM9kXxwGnva1DNw==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.71.0 - '@sentry/types': 7.71.0 - '@sentry/utils': 7.71.0 + '@sentry/core': 7.72.0 + '@sentry/types': 7.72.0 + '@sentry/utils': 7.72.0 tslib: 2.6.2 dev: false - /@sentry/core@7.71.0: - resolution: {integrity: sha512-kZcWnzxzMxyNuCwq65owu0yGbY+C9QJhWFMDBsqmKK1/dSt0bdhNjf3VQW1dJLnWaQTk7rUTHEHGH8JSdV5EAg==} + /@sentry/core@7.72.0: + resolution: {integrity: sha512-G03JdQ5ZsFNRjcNNi+QvCjqOuBvYqU92Gs1T2iK3GE8dSBTu2khThydMpG4xrKZQLIpHOyiIhlFZiuPtZ66W8w==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.71.0 - '@sentry/utils': 7.71.0 + '@sentry/types': 7.72.0 + '@sentry/utils': 7.72.0 tslib: 2.6.2 dev: false - /@sentry/hub@7.71.0: - resolution: {integrity: sha512-fvnNELNCCMlptDe6oCr40VYAEaTqWgfhjGps+ezqaE6Prb8y5XrEaZI3x7WrzQ2t/0GdR2hjoM4R43ZcSpudVg==} + /@sentry/hub@7.72.0: + resolution: {integrity: sha512-d160f2UMQPDnazVdPiUN39N7Bi7ulPKsB8YbUGEzVgnqMNSIkp4l98Ti3blE7sFMw4E3JeI9sKx1aaBHubItNg==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.71.0 - '@sentry/types': 7.71.0 - '@sentry/utils': 7.71.0 + '@sentry/core': 7.72.0 + '@sentry/types': 7.72.0 + '@sentry/utils': 7.72.0 tslib: 2.6.2 dev: false - /@sentry/node@7.71.0: - resolution: {integrity: sha512-rvCzfLWAeX+16mOJeb08xDlpBdn/H/G8dj9mENQAom8O0SgMkkRyfYc9pnvsmU5gjuS7C9u+e4ZlOLLr1xZ+zQ==} + /@sentry/node@7.72.0: + resolution: {integrity: sha512-R5kNCIdaDa92EN6oCLiGJehw5wxayOM53WF60Ap6EJHZb5U8dM2BnODmQ6SCRLNB677p+620oSV6CCU286IleQ==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.71.0 - '@sentry/core': 7.71.0 - '@sentry/types': 7.71.0 - '@sentry/utils': 7.71.0 + '@sentry-internal/tracing': 7.72.0 + '@sentry/core': 7.72.0 + '@sentry/types': 7.72.0 + '@sentry/utils': 7.72.0 cookie: 0.5.0 https-proxy-agent: 5.0.1 lru_map: 0.3.3 @@ -3540,15 +3570,15 @@ packages: - supports-color dev: false - /@sentry/types@7.71.0: - resolution: {integrity: sha512-30PRLZI1RoeWbLE9K7AHsRPWDH22CqC4WcLNeVmRfLC5m1vE1FHb53r98QSKFhLoONMPMVzDhZZgl4ZcC5mptQ==} + /@sentry/types@7.72.0: + resolution: {integrity: sha512-g6u0mk62yGshx02rfFADIfyR/S9VXcf3RG2qQPuvykrWtOfN/BOTrZypF7I+MiqKwRW76r3Pcu2C/AB+6z9XQA==} engines: {node: '>=8'} - /@sentry/utils@7.71.0: - resolution: {integrity: sha512-aS53l/E/5XsSJMOXHKvS0GlX4gZHBgNAMfhEB3f8rUIn5iLF2uu8lCA1uEvX6VB8b7q/Cg4WFTi6BiJ0hvJHQg==} + /@sentry/utils@7.72.0: + resolution: {integrity: sha512-o/MtqI7WJXuswidH0bSgBP40KN2lrnyQEIx5uoyJUJi/QEaboIsqbxU62vaFJpde8SYrbA+rTnP3J3ujF2gUag==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.71.0 + '@sentry/types': 7.72.0 tslib: 2.6.2 dev: false @@ -4047,6 +4077,17 @@ packages: graphemer: 1.4.0 dev: true + /@stylistic/eslint-plugin-js@0.0.5: + resolution: {integrity: sha512-Ca3DAk4lHGELPHnHIOUc/SF3Pg58xd/AATqNMSTSoxjoadRk6MGDblriURXjEg7gif4ygiB3+EcIuphAceFYvQ==} + dependencies: + acorn: 8.10.0 + escape-string-regexp: 4.0.0 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esutils: 2.0.3 + graphemer: 1.4.0 + dev: true + /@stylistic/eslint-plugin-ts@0.0.3(eslint@8.50.0)(typescript@5.2.2): resolution: {integrity: sha512-G/jZ+XHlZtkxABOXswJNTmN4h8qNmECTjPLkWPMykPlfQeD1RSpBMEQHiJHZ3GAxnEcqAgi7CNA1FTvGWz6qwQ==} peerDependencies: @@ -4065,6 +4106,35 @@ packages: - supports-color dev: true + /@stylistic/eslint-plugin-ts@0.0.5(eslint@8.50.0)(typescript@5.2.2): + resolution: {integrity: sha512-Ei/arToTJEF2nxxJLsXqK9qMxPgZi8IyM2X+1q8HRA11Q3zRMut8u1B1zwE8q9EhorBwZsgnmphgzmDG0Mot+w==} + peerDependencies: + eslint: '*' + dependencies: + '@stylistic/eslint-plugin-js': 0.0.5 + '@typescript-eslint/scope-manager': 6.7.3 + '@typescript-eslint/type-utils': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + eslint: 8.50.0 + graphemer: 1.4.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@stylistic/eslint-plugin@0.0.5(eslint@8.50.0)(typescript@5.2.2): + resolution: {integrity: sha512-8InMNsdJrQqdKxCxd7Zc8HCYg2p5a4XXkqxRzjG7Soy+RWQdj7bAGfTmaDWB0i28CffYabOfOsAgRlfG9oe3Wg==} + peerDependencies: + eslint: '*' + dependencies: + '@stylistic/eslint-plugin-js': 0.0.5 + '@stylistic/eslint-plugin-ts': 0.0.5(eslint@8.50.0)(typescript@5.2.2) + eslint: 8.50.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + /@supercharge/request-ip@1.2.0: resolution: {integrity: sha512-wlt6JW69MHqLY2M6Sm/jVyCojNRKq2CBvwH0Hbx24SFhDQQGkgEjeKxVutDxHSyrWixFaOSLXC27euzxijhyMQ==} dev: false @@ -4441,6 +4511,12 @@ packages: dev: false optional: true + /@types/mdast@3.0.12: + resolution: {integrity: sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==} + dependencies: + '@types/unist': 2.0.8 + dev: true + /@types/mdurl@1.0.2: resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} requiresBuild: true @@ -4649,6 +4725,10 @@ packages: resolution: {integrity: sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ==} dev: false + /@types/unist@2.0.8: + resolution: {integrity: sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==} + dev: true + /@types/validator@13.11.1: resolution: {integrity: sha512-d/MUkJYdOeKycmm75Arql4M5+UuXmf4cHdHKsyw1GcvnNgL6s77UkgSgJ8TE/rI5PYsnwYq5jkcWBLuN/MpQ1A==} @@ -5401,6 +5481,16 @@ packages: es-shim-unscopables: 1.0.0 dev: true + /array.prototype.tosorted@1.1.2: + resolution: {integrity: sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + es-shim-unscopables: 1.0.0 + get-intrinsic: 1.2.1 + dev: true + /arraybuffer.prototype.slice@1.0.2: resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} engines: {node: '>= 0.4'} @@ -5449,6 +5539,12 @@ packages: resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} dev: false + /asynciterator.prototype@1.0.0: + resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} + dependencies: + has-symbols: 1.0.3 + dev: true + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -5701,6 +5797,10 @@ packages: transitivePeerDependencies: - supports-color + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + /bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} dev: false @@ -5800,6 +5900,12 @@ packages: engines: {node: '>=6'} dev: true + /builtins@5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.5.4 + dev: true + /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -5918,12 +6024,24 @@ packages: engines: {node: '>=10'} dev: true + /character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + dev: true + + /character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + dev: true + /character-parser@2.2.0: resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} dependencies: is-regex: 1.1.4 dev: false + /character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + dev: true + /chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true @@ -6438,6 +6556,12 @@ packages: dev: false optional: true + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + /cssstyle@3.0.0: resolution: {integrity: sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==} engines: {node: '>=14'} @@ -6896,6 +7020,25 @@ packages: which-typed-array: 1.1.11 dev: true + /es-iterator-helpers@1.0.15: + resolution: {integrity: sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==} + dependencies: + asynciterator.prototype: 1.0.0 + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + es-set-tostringtag: 2.0.1 + function-bind: 1.1.1 + get-intrinsic: 1.2.1 + globalthis: 1.0.3 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + iterator.prototype: 1.1.2 + safe-array-concat: 1.0.1 + dev: true + /es-module-lexer@1.3.1: resolution: {integrity: sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==} dev: true @@ -6964,6 +7107,12 @@ packages: dev: false optional: true + /eslint-config-flat-gitignore@0.1.0: + resolution: {integrity: sha512-5nQMQFRkkhCb+ejFhKSATn/41I7ot9oRcnEDzfqwMlBE9036qM9ioYBDtKLpwmlICXr/J7naMFfb39pa4v4sGA==} + dependencies: + parse-gitignore: 2.0.0 + dev: true + /eslint-define-config@1.23.0: resolution: {integrity: sha512-4mMyu0JuBkQHsCtR+42irIQdFLmLIW+pMAVcyOV/gZRL4O1R8iuH0eMG3oL3Cbi1eo9fDAfT5CIHVHgdyxcf6w==} engines: {node: ^16.13.0 || >=18.0.0, npm: '>=7.0.0', pnpm: '>= 8.6.0'} @@ -7048,6 +7197,66 @@ packages: - supports-color dev: true + /eslint-plugin-deprecation@2.0.0(eslint@8.50.0)(typescript@5.2.2): + resolution: {integrity: sha512-OAm9Ohzbj11/ZFyICyR5N6LbOIvQMp7ZU2zI7Ej0jIc8kiGUERXPNMfw2QqqHD1ZHtjMub3yPZILovYEYucgoQ==} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: ^4.2.4 || ^5.0.0 + dependencies: + '@typescript-eslint/utils': 6.7.3(eslint@8.50.0)(typescript@5.2.2) + eslint: 8.50.0 + tslib: 2.6.2 + tsutils: 3.21.0(typescript@5.2.2) + typescript: 5.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-es-x@7.2.0(eslint@8.50.0): + resolution: {integrity: sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0) + '@eslint-community/regexpp': 4.8.1 + eslint: 8.50.0 + dev: true + + /eslint-plugin-eslint-comments@3.2.0(eslint@8.50.0): + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + escape-string-regexp: 1.0.5 + eslint: 8.50.0 + ignore: 5.2.4 + dev: true + + /eslint-plugin-i@2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.50.0): + resolution: {integrity: sha512-a4oVt0j3ixNhGhvV4XF6NS7OWRFK2rrJ0Q5C4S2dSRb8FxZi31J0uUd5WJLL58wnVJ/OiQ1BxiXnFA4dWQO1Cg==} + engines: {node: '>=12'} + peerDependencies: + eslint: ^7.2.0 || ^8 + dependencies: + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.50.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.3)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.50.0) + get-tsconfig: 4.7.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + resolve: 1.22.6 + semver: 7.5.4 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.7.3)(eslint-import-resolver-typescript@3.6.1)(eslint@8.50.0): resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==} engines: {node: '>=4'} @@ -7125,6 +7334,87 @@ packages: - supports-color dev: true + /eslint-plugin-jsonc@2.9.0(eslint@8.50.0): + resolution: {integrity: sha512-RK+LeONVukbLwT2+t7/OY54NJRccTXh/QbnXzPuTLpFMVZhPuq1C9E07+qWenGx7rrQl0kAalAWl7EmB+RjpGA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0) + eslint: 8.50.0 + jsonc-eslint-parser: 2.3.0 + natural-compare: 1.4.0 + dev: true + + /eslint-plugin-markdown@3.0.1(eslint@8.50.0): + resolution: {integrity: sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.50.0 + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-n@16.1.0(eslint@8.50.0): + resolution: {integrity: sha512-3wv/TooBst0N4ND+pnvffHuz9gNPmk/NkLwAxOt2JykTl/hcuECe6yhTtLJcZjIxtZwN+GX92ACp/QTLpHA3Hg==} + engines: {node: '>=16.0.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0) + builtins: 5.0.1 + eslint: 8.50.0 + eslint-plugin-es-x: 7.2.0(eslint@8.50.0) + get-tsconfig: 4.7.1 + ignore: 5.2.4 + is-core-module: 2.13.0 + minimatch: 3.1.2 + resolve: 1.22.6 + semver: 7.5.4 + dev: true + + /eslint-plugin-no-only-tests@3.1.0: + resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} + engines: {node: '>=5.0.0'} + dev: true + + /eslint-plugin-react-hooks@4.6.0(eslint@8.50.0): + resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 8.50.0 + dev: true + + /eslint-plugin-react@7.33.2(eslint@8.50.0): + resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + array-includes: 3.1.7 + array.prototype.flatmap: 1.3.2 + array.prototype.tosorted: 1.1.2 + doctrine: 2.1.0 + es-iterator-helpers: 1.0.15 + eslint: 8.50.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.7 + object.fromentries: 2.0.7 + object.hasown: 1.1.3 + object.values: 1.1.7 + prop-types: 15.8.1 + resolve: 2.0.0-next.4 + semver: 6.3.1 + string.prototype.matchall: 4.0.10 + dev: true + /eslint-plugin-unicorn@48.0.1(eslint@8.50.0): resolution: {integrity: sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==} engines: {node: '>=16'} @@ -7164,6 +7454,39 @@ packages: eslint-rule-composer: 0.3.0 dev: true + /eslint-plugin-vue@9.17.0(eslint@8.50.0): + resolution: {integrity: sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.50.0) + eslint: 8.50.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.0.13 + semver: 7.5.4 + vue-eslint-parser: 9.3.1(eslint@8.50.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-yml@1.9.0(eslint@8.50.0): + resolution: {integrity: sha512-ayuC57WyVQ5+QZ02y62GiB//5+zsiyzUGxUX/mrhLni+jfsKA4KoITjkbR65iUdjjhWpyTJHPcAIFLKQIOwgsw==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4 + eslint: 8.50.0 + lodash: 4.17.21 + natural-compare: 1.4.0 + yaml-eslint-parser: 1.2.2 + transitivePeerDependencies: + - supports-color + dev: true + /eslint-rule-composer@0.3.0: resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} engines: {node: '>=4.0.0'} @@ -8600,6 +8923,17 @@ packages: engines: {node: '>= 10'} dev: false + /is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + dev: true + + /is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + dev: true + /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -8624,6 +8958,13 @@ packages: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} dev: false + /is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + /is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: @@ -8671,6 +9012,10 @@ packages: has-tostringtag: 1.0.0 dev: true + /is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + dev: true + /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} @@ -8688,6 +9033,12 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + /is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + dependencies: + call-bind: 1.0.2 + dev: true + /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -8707,7 +9058,6 @@ packages: engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 - dev: false /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} @@ -8715,11 +9065,19 @@ packages: dependencies: is-extglob: 2.1.1 + /is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + dev: true + /is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} dev: true + /is-map@2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true + /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -8756,6 +9114,10 @@ packages: call-bind: 1.0.2 has-tostringtag: 1.0.0 + /is-set@2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true + /is-shared-array-buffer@1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: @@ -8811,12 +9173,23 @@ packages: resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} dev: true + /is-weakmap@2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true + /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.2 dev: true + /is-weakset@2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + dev: true + /is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -8925,6 +9298,16 @@ packages: resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} engines: {node: '>=6'} + /iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.1 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.4 + set-function-name: 2.0.1 + dev: true + /jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9526,6 +9909,16 @@ packages: hasBin: true dev: true + /jsonc-eslint-parser@2.3.0: + resolution: {integrity: sha512-9xZPKVYp9DxnM3sd1yAsh/d59iIaswDkai8oTxbursfKYbg/ibjX0IzFt35+VZ8iEW453TVTXztnRvYUQlAfUQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.10.0 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.5.4 + dev: true + /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} dev: true @@ -9584,6 +9977,16 @@ packages: promise: 7.3.1 dev: false + /jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.7 + array.prototype.flat: 1.3.2 + object.assign: 4.1.4 + object.values: 1.1.7 + dev: true + /jwa@1.4.1: resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} dependencies: @@ -9844,6 +10247,11 @@ packages: engines: {node: '>=6.11.5'} dev: true + /local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + dev: true + /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -9955,6 +10363,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + /lru-cache@10.0.1: resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==} engines: {node: 14 || >=16.14} @@ -10105,6 +10520,22 @@ packages: is-buffer: 1.1.6 dev: false + /mdast-util-from-markdown@0.8.5: + resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + dependencies: + '@types/mdast': 3.0.12 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-to-string@2.0.0: + resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + dev: true + /mdurl@1.0.1: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} requiresBuild: true @@ -10141,6 +10572,15 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} + /micromark@2.11.4: + resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} + dependencies: + debug: 4.3.4 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -10584,6 +11024,12 @@ packages: set-blocking: 2.0.0 dev: false + /nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + /nwsapi@2.2.7: resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} dev: false @@ -10618,6 +11064,15 @@ packages: object-keys: 1.1.1 dev: true + /object.entries@1.1.7: + resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + dev: true + /object.fromentries@2.0.7: resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} engines: {node: '>= 0.4'} @@ -10636,6 +11091,13 @@ packages: get-intrinsic: 1.2.1 dev: true + /object.hasown@1.1.3: + resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.22.2 + dev: true + /object.values@1.1.7: resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} engines: {node: '>= 0.4'} @@ -10824,6 +11286,22 @@ packages: engines: {node: '>= 0.4.0'} dev: true + /parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + dev: true + + /parse-gitignore@2.0.0: + resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} + engines: {node: '>=14'} + dev: true + /parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -11170,6 +11648,14 @@ packages: requiresBuild: true dev: false + /postcss-selector-parser@6.0.13: + resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + /postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -11285,6 +11771,14 @@ packages: sisteransi: 1.0.5 dev: true + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + /proto3-json-serializer@1.1.1: resolution: {integrity: sha512-AwAuY4g9nxx0u52DnSMkqqgyLHaW/XaPLtaAo3y/ZCfeaQB/g4YDH4kb8Wc/mWzWvu0YjOznVnfn373MVZZrgw==} engines: {node: '>=12.0.0'} @@ -11578,6 +12072,10 @@ packages: strip-json-comments: 2.0.1 dev: false + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + /react-is@18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true @@ -11700,6 +12198,18 @@ packages: /reflect-metadata@0.1.13: resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} + /reflect.getprototypeof@1.0.4: + resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + get-intrinsic: 1.2.1 + globalthis: 1.0.3 + which-builtin-type: 1.1.3 + dev: true + /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} requiresBuild: true @@ -11812,6 +12322,15 @@ packages: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + /resolve@2.0.0-next.4: + resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} + hasBin: true + dependencies: + is-core-module: 2.13.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -12367,6 +12886,20 @@ packages: strip-ansi: 7.1.0 dev: true + /string.prototype.matchall@4.0.10: + resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.1 + es-abstract: 1.22.2 + get-intrinsic: 1.2.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + regexp.prototype.flags: 1.5.1 + set-function-name: 2.0.1 + side-channel: 1.0.4 + dev: true + /string.prototype.trim@1.2.8: resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} engines: {node: '>= 0.4'} @@ -13164,6 +13697,12 @@ packages: dev: false optional: true + /unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + dependencies: + '@types/unist': 2.0.8 + dev: true + /universalify@0.2.0: resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} engines: {node: '>= 4.0.0'} @@ -13292,6 +13831,24 @@ packages: engines: {node: '>=0.10.0'} dev: false + /vue-eslint-parser@9.3.1(eslint@8.50.0): + resolution: {integrity: sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4 + eslint: 8.50.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + lodash: 4.17.21 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + /w3c-xmlserializer@4.0.0: resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} engines: {node: '>=14'} @@ -13435,6 +13992,33 @@ packages: is-symbol: 1.0.4 dev: true + /which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.0 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.11 + dev: true + + /which-collection@1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + dev: true + /which-module@2.0.1: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} dev: false @@ -13595,7 +14179,6 @@ packages: /xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} - dev: false /xml2js@0.5.0: resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} @@ -13652,6 +14235,15 @@ packages: /yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + /yaml-eslint-parser@1.2.2: + resolution: {integrity: sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==} + engines: {node: ^14.17.0 || >=16.0.0} + dependencies: + eslint-visitor-keys: 3.4.3 + lodash: 4.17.21 + yaml: 2.3.1 + dev: true + /yaml@1.10.2: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} diff --git a/src/_mocks_/index.ts b/src/_mocks_/index.ts index cded197d..156ec77d 100644 --- a/src/_mocks_/index.ts +++ b/src/_mocks_/index.ts @@ -1,4 +1,5 @@ -/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable ts/no-unsafe-return */ +import path from "node:path"; import type { Request, Response } from "express"; import type { AmqpConnection } from "@golevelup/nestjs-rabbitmq"; import { createMock } from "@golevelup/ts-jest"; @@ -70,11 +71,12 @@ export const mockFile = { fieldname: "file", originalname: "test.png", mimetype: "text/png", - buffer: Buffer.from(`${__dirname}/../../test/test.png`, "utf8"), + buffer: Buffer.from(path.join(__dirname, "/../../test/test.png"), "utf8"), size: 13_148, } as File; export const mockedOtpLog = { + id: 1, expiresIn: new Date(), otpCode: "12344", isUsed: false, diff --git a/src/common/@types/classes/offset.response.ts b/src/common/@types/classes/offset.response.ts index e4611273..c3fae13d 100644 --- a/src/common/@types/classes/offset.response.ts +++ b/src/common/@types/classes/offset.response.ts @@ -1,8 +1,7 @@ import { ApiProperty } from "@nestjs/swagger"; import { IsArray } from "class-validator"; -import type { PaginationAbstractResponse } from "../interfaces"; - import type { OffsetPaginationDto } from "@common/dtos/offset-pagination.dto"; +import type { PaginationAbstractResponse } from "../interfaces"; export class OffsetMeta { /** diff --git a/src/common/@types/enums/misc.enum.ts b/src/common/@types/enums/misc.enum.ts index b2dcf769..04f03345 100644 --- a/src/common/@types/enums/misc.enum.ts +++ b/src/common/@types/enums/misc.enum.ts @@ -1,7 +1,5 @@ import type { TEmailSubject } from "../interfaces"; -const BITS_TO_MB = 1024 * 1024; - export enum EmailTemplate { RESET_PASSWORD_TEMPLATE = "reset", WELCOME_TEMPLATE = "welcome", @@ -16,10 +14,10 @@ export const EmailSubject: Record = { NEWSLETTER: "Newsletter", }; -export enum FileSize { - IMAGE = 5 * BITS_TO_MB, // 5MB - DOC = 10 * BITS_TO_MB, // 10MB -} +export const FileSize = { + IMAGE: 5 * 1024 * 1024, // 5MB + DOC: 10 * 1024 * 1024, // 10MB +}; export enum PostStateEnum { DRAFT = "DRAFT", diff --git a/src/common/@types/global.d.ts b/src/common/@types/global.d.ts index a7347b6b..c8580475 100644 --- a/src/common/@types/global.d.ts +++ b/src/common/@types/global.d.ts @@ -1,95 +1,95 @@ -import {User as UserEntity} from "@entities"; -import {I18nTranslations as I18nTranslationTypes} from "@generated"; -import {Config as ConfigInterface} from "@lib/config/config.interface"; +import type { User as UserEntity } from "@entities"; +import type { I18nTranslations as I18nTranslationTypes } from "@generated"; +import type { Config as ConfigInterface } from "@lib/config/config.interface"; export {}; declare global { - namespace Express { - export interface Request { - user?: UserEntity; - realIp: string; - body: Record; - ip: string; - ips: string[]; - } + namespace Express { + export interface Request { + user?: UserEntity + realIp: string + body: Record + ip: string + ips: string[] } + } - namespace NodeJS { - interface ProcessEnv { - APP_PORT: number; - APP_PREFIX: string; - APP_NAME: string; - NODE_ENV: - | "dev" - | "development" - | "stage" - | "staging" - | "test" - | "testing" - | "prod" - | "production"; - API_URL: string; - CLIENT_URL: string; - SWAGGER_USER: string; - ALLOWED_ORIGINS?: string; - SWAGGER_PASSWORD: string; + namespace NodeJS { + interface ProcessEnv { + APP_PORT: number + APP_PREFIX: string + APP_NAME: string + NODE_ENV: + | "dev" + | "development" + | "stage" + | "staging" + | "test" + | "testing" + | "prod" + | "production" + API_URL: string + CLIENT_URL: string + SWAGGER_USER: string + ALLOWED_ORIGINS?: string + SWAGGER_PASSWORD: string - DB_HOST: string; - DB_PORT: number; - DB_USERNAME: string; - DB_PASSWORD: string; - DB_DATABASE: string; + DB_HOST: string + DB_PORT: number + DB_USERNAME: string + DB_PASSWORD: string + DB_DATABASE: string - ENC_IV: string; - ENC_KEY: string; + ENC_IV: string + ENC_KEY: string - JWT_ACCESS_EXPIRY: string; - JWT_REFRESH_EXPIRY: string; - JWT_SECRET: string; + JWT_ACCESS_EXPIRY: string + JWT_REFRESH_EXPIRY: string + JWT_SECRET: string - MAIL_HOST: string; - MAIL_PASSWORD: string; - MAIL_USERNAME: string; - MAIL_PORT: number; - MAIL_SERVER: string; - MAIL_PREVIEW_EMAIL: boolean; - MAIL_BCC_LIST?: string; - MAIL_SENDER_EMAIL: string; - MAIL_TEMPLATE_DIR: string; + MAIL_HOST: string + MAIL_PASSWORD: string + MAIL_USERNAME: string + MAIL_PORT: number + MAIL_SERVER: string + MAIL_PREVIEW_EMAIL: boolean + MAIL_BCC_LIST?: string + MAIL_SENDER_EMAIL: string + MAIL_TEMPLATE_DIR: string - CLOUDINARY_CLOUD_NAME: string; - CLOUDINARY_API_KEY: string; - CLOUDINARY_API_SECRET: string; + CLOUDINARY_CLOUD_NAME: string + CLOUDINARY_API_KEY: string + CLOUDINARY_API_SECRET: string - REDIS_TTL: number; - REDIS_URI: string; - REDIS_HOST: string; - REDIS_PASSWORD: string; - REDIS_USERNAME: string; - REDIS_PORT: number; + REDIS_TTL: number + REDIS_URI: string + REDIS_HOST: string + REDIS_PASSWORD: string + REDIS_USERNAME: string + REDIS_PORT: number - RABBITMQ_URI: string; - RABBITMQ_EXCHANGE: string; - RABBITMQ_QUEUE: string; - RABBITMQ_DEFAULT_PREFETCH: number; + RABBITMQ_URI: string + RABBITMQ_EXCHANGE: string + RABBITMQ_QUEUE: string + RABBITMQ_DEFAULT_PREFETCH: number - SENTRY_DSN: string; - SENTRY_ENVIRONMENT: string; + SENTRY_DSN: string + SENTRY_ENVIRONMENT: string - GOOGLE_CLIENT_ID: string; - GOOGLE_CLIENT_SECRET: string; - GOOGLE_CALLBACK_URL: string; + GOOGLE_CLIENT_ID: string + GOOGLE_CLIENT_SECRET: string + GOOGLE_CALLBACK_URL: string - FACEBOOK_CLIENT_ID: string; - FACEBOOK_CLIENT_SECRET: string; - FACEBOOK_CALLBACK_URL: string; + FACEBOOK_CLIENT_ID: string + FACEBOOK_CLIENT_SECRET: string + FACEBOOK_CALLBACK_URL: string - THROTTLE_LIMIT: string; - THROTTLE_TTL: number; - } + THROTTLE_LIMIT: string + THROTTLE_TTL: number } + } - export type I18nTranslations = I18nTranslationTypes; - export type Configs = ConfigInterface; + export type I18nTranslations = I18nTranslationTypes; + export type Configs = ConfigInterface; } diff --git a/src/common/@types/interfaces/crud.interface.ts b/src/common/@types/interfaces/crud.interface.ts index 3b2d22f1..6c182d55 100644 --- a/src/common/@types/interfaces/crud.interface.ts +++ b/src/common/@types/interfaces/crud.interface.ts @@ -1,13 +1,13 @@ import type { EntityData, RequiredEntityData } from "@mikro-orm/core"; import type { Observable } from "rxjs"; + +import type { User } from "@entities"; +import type { BaseEntity } from "@common/database"; import type { PaginationResponse, PaginationRequest as TPaginationRequest, } from "./pagination.interface"; -import type { User } from "@entities"; -import type { BaseEntity } from "@common/database"; - /** * common interface that enforces common methods for controller and service */ diff --git a/src/common/@types/interfaces/pagination.interface.ts b/src/common/@types/interfaces/pagination.interface.ts index 2c685c63..5f0bf4eb 100644 --- a/src/common/@types/interfaces/pagination.interface.ts +++ b/src/common/@types/interfaces/pagination.interface.ts @@ -1,10 +1,9 @@ import type { Dictionary } from "@mikro-orm/core"; import type { QueryBuilder } from "@mikro-orm/postgresql"; +import type { CursorPaginationDto, OffsetPaginationDto } from "@common/dtos"; import type { CursorPaginationResponse, OffsetPaginationResponse } from "../classes"; import { CursorType, QueryCursor, QueryOrder } from "../enums"; -import type { CursorPaginationDto, OffsetPaginationDto } from "@common/dtos"; - export interface QBCursorPaginationOptions { qb: QueryBuilder pageOptionsDto: Omit & { diff --git a/src/common/database/base.repository.spec.ts b/src/common/database/base.repository.spec.ts index 1f4531fe..bdd53197 100644 --- a/src/common/database/base.repository.spec.ts +++ b/src/common/database/base.repository.spec.ts @@ -1,31 +1,31 @@ -import {createMock} from '@golevelup/ts-jest'; -import type {EntityManager} from '@mikro-orm/postgresql'; -import {BaseRepository} from './base.repository'; -import {loggedInUser} from '@mocks'; +import { createMock } from "@golevelup/ts-jest"; +import type { EntityManager } from "@mikro-orm/postgresql"; +import { loggedInUser } from "@mocks"; -import {User} from '@entities'; +import { User } from "@entities"; +import { BaseRepository } from "./base.repository"; -describe('BaseRepository', () => { - const mockEm = createMock({ - findAndCount: jest.fn().mockResolvedValue([[], 0]), - }); +describe("BaseRepository", () => { + const mockEm = createMock({ + findAndCount: jest.fn().mockResolvedValue([[], 0]), + }); - const userRepo = new BaseRepository(mockEm, User); + const userRepo = new BaseRepository(mockEm, User); - it('should be defined', () => { - expect(userRepo).toBeDefined(); - }); + it("should be defined", () => { + expect(userRepo).toBeDefined(); + }); - it('should softremove and flush', async () => { - userRepo.softRemoveAndFlush(loggedInUser).subscribe((result) => { - expect(result.isDeleted).toEqual(true); - expect(result.deletedAt).toBeInstanceOf(Date); - }); + it("should softremove and flush", async () => { + userRepo.softRemoveAndFlush(loggedInUser).subscribe((result) => { + expect(result.isDeleted).toEqual(true); + expect(result.deletedAt).toBeInstanceOf(Date); }); + }); - it('should softremove', () => { - userRepo.softRemove(loggedInUser); + it("should softremove", () => { + userRepo.softRemove(loggedInUser); - expect(loggedInUser.isDeleted).toEqual(true); - }); + expect(loggedInUser.isDeleted).toEqual(true); + }); }); diff --git a/src/common/database/base.repository.ts b/src/common/database/base.repository.ts index 79691ca8..dcca5752 100644 --- a/src/common/database/base.repository.ts +++ b/src/common/database/base.repository.ts @@ -12,7 +12,6 @@ import { BadRequestException, NotFoundException } from "@nestjs/common"; import type { Observable } from "rxjs"; import { from, map, of, switchMap, throwError } from "rxjs"; import { formatSearch } from "helper-fns"; -import type { BaseEntity } from "./base.entity"; import type { CursorPaginationResponse, @@ -31,6 +30,7 @@ import { getQueryOrder, } from "@common/@types"; import { translate } from "@lib/i18n"; +import type { BaseEntity } from "./base.entity"; export class BaseRepository extends EntityRepository { private readonly encoding: BufferEncoding = "base64"; @@ -484,11 +484,11 @@ export class BaseRepository extends EntityRepository { const oppositeOrder = getOppositeOrder(order); const countWhere = where; - // eslint-disable-next-line @typescript-eslint/dot-notation + // eslint-disable-next-line ts/dot-notation countWhere["$and"] = this.getFilters("createdAt", decoded, oppositeOrder); previousCount = await repo.count(countWhere); - // eslint-disable-next-line @typescript-eslint/dot-notation + // eslint-disable-next-line ts/dot-notation where["$and"] = this.getFilters("createdAt", decoded, queryOrder); } diff --git a/src/common/database/seeders/admin.seeder.ts b/src/common/database/seeders/admin.seeder.ts index 92fe7caa..9b283a50 100644 --- a/src/common/database/seeders/admin.seeder.ts +++ b/src/common/database/seeders/admin.seeder.ts @@ -1,8 +1,7 @@ import type { EntityManager } from "@mikro-orm/core"; import { Seeder } from "@mikro-orm/seeder"; -import { UserFactory } from "../factories"; - import { Roles } from "@common/@types"; +import { UserFactory } from "../factories"; /* * It creates a user with the email and password specified in the .env file, and gives them the admin role diff --git a/src/common/decorators/custom-cache.decorator.ts b/src/common/decorators/custom-cache.decorator.ts index 83d49ae7..a15fe80f 100644 --- a/src/common/decorators/custom-cache.decorator.ts +++ b/src/common/decorators/custom-cache.decorator.ts @@ -1,7 +1,6 @@ import { UseInterceptors, applyDecorators } from "@nestjs/common"; -import { NoCache } from "./nocache.decorator"; - import { CacheKeyInterceptor } from "@common/interceptors"; +import { NoCache } from "./nocache.decorator"; /** * Use this to override the default cache interceptor. diff --git a/src/common/decorators/validation/is-after.validator.spec.ts b/src/common/decorators/validation/is-after.validator.spec.ts index bd7d4dae..2c9dad77 100644 --- a/src/common/decorators/validation/is-after.validator.spec.ts +++ b/src/common/decorators/validation/is-after.validator.spec.ts @@ -1,52 +1,52 @@ -import {Validator} from 'class-validator'; -import {IsAfterField} from './is-after.validator'; +import { Validator } from "class-validator"; +import { IsAfterField } from "./is-after.validator"; const validator = new Validator(); -describe('IsAfter', () => { - class MyClass { - startDate!: Date; +describe("IsAfter", () => { + class MyClass { + startDate!: Date; - @IsAfterField('startDate') + @IsAfterField("startDate") endDate!: Date; - } + } - it('if endDate is after than startDate then it should succeed', () => { - const model = new MyClass(); + it("if endDate is after than startDate then it should succeed", () => { + const model = new MyClass(); - model.startDate = new Date('2022-02-21'); - model.endDate = new Date('2022-05-01'); + model.startDate = new Date("2022-02-21"); + model.endDate = new Date("2022-05-01"); - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(0); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(0); }); + }); - it('if endDate is not after than startDate then it should fail', () => { - const model = new MyClass(); + it("if endDate is not after than startDate then it should fail", () => { + const model = new MyClass(); - model.startDate = new Date('2022-02-21'); - model.endDate = new Date('2022-01-01'); + model.startDate = new Date("2022-02-21"); + model.endDate = new Date("2022-01-01"); - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(1); - expect(errors[0].constraints).toEqual({ - IsAfterConstraint: 'endDate should be after startDate', - }); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(1); + expect(errors[0].constraints).toEqual({ + IsAfterConstraint: "endDate should be after startDate", + }); }); + }); - it('if endDate is equal to startDate then it should fail', () => { - const model = new MyClass(); + it("if endDate is equal to startDate then it should fail", () => { + const model = new MyClass(); - model.startDate = new Date('2022-02-21'); - model.endDate = model.startDate; + model.startDate = new Date("2022-02-21"); + model.endDate = model.startDate; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(1); - expect(errors[0].constraints).toEqual({ - IsAfterConstraint: 'endDate should be after startDate', - }); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(1); + expect(errors[0].constraints).toEqual({ + IsAfterConstraint: "endDate should be after startDate", + }); }); + }); }); diff --git a/src/common/decorators/validation/is-after.validator.ts b/src/common/decorators/validation/is-after.validator.ts index 7cf4640d..9eb15726 100644 --- a/src/common/decorators/validation/is-after.validator.ts +++ b/src/common/decorators/validation/is-after.validator.ts @@ -40,5 +40,3 @@ export const IsAfterField = ( }); }; }; - - diff --git a/src/common/decorators/validation/is-date-format.validator.spec.ts b/src/common/decorators/validation/is-date-format.validator.spec.ts index 81f83df5..c692f5c6 100644 --- a/src/common/decorators/validation/is-date-format.validator.spec.ts +++ b/src/common/decorators/validation/is-date-format.validator.spec.ts @@ -1,31 +1,31 @@ -import {Validator} from 'class-validator'; -import {IsDateInFormat} from './is-date-format.validator'; +import { Validator } from "class-validator"; +import { IsDateInFormat } from "./is-date-format.validator"; const validator = new Validator(); -describe('IsDateInFormat', () => { - class MyClass { - @IsDateInFormat('yyyy-MM-dd') +describe("IsDateInFormat", () => { + class MyClass { + @IsDateInFormat("yyyy-MM-dd") date: string; - } + } - it('if date satisfies the format then it should succeed', () => { - const model = new MyClass(); + it("if date satisfies the format then it should succeed", () => { + const model = new MyClass(); - model.date = '2014-04-03'; + model.date = "2014-04-03"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(0); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(0); }); + }); - it('if date does not satisfies the format then it should fail', () => { - const model = new MyClass(); + it("if date does not satisfies the format then it should fail", () => { + const model = new MyClass(); - model.date = '2014/04/03'; + model.date = "2014/04/03"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(1); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(1); }); + }); }); diff --git a/src/common/decorators/validation/is-date-format.validator.ts b/src/common/decorators/validation/is-date-format.validator.ts index 479a8b0a..d6a86bea 100644 --- a/src/common/decorators/validation/is-date-format.validator.ts +++ b/src/common/decorators/validation/is-date-format.validator.ts @@ -12,7 +12,6 @@ import { isArray } from "helper-fns"; /* It validates that a date is in a given format */ - export type DateFormats = | "yyyy-MM-dd" // ISO 8601 Format | "dd/MM/yyyy" diff --git a/src/common/decorators/validation/is-equal-to.validator.spec.ts b/src/common/decorators/validation/is-equal-to.validator.spec.ts index 078d9340..46331682 100644 --- a/src/common/decorators/validation/is-equal-to.validator.spec.ts +++ b/src/common/decorators/validation/is-equal-to.validator.spec.ts @@ -1,38 +1,38 @@ -import {Validator} from 'class-validator'; -import {IsEqualToField} from './is-equal-to.validator'; +import { Validator } from "class-validator"; +import { IsEqualToField } from "./is-equal-to.validator"; const validator = new Validator(); -describe('IsEqualToField', () => { - class MyClass { - password!: string; +describe("IsEqualToField", () => { + class MyClass { + password!: string; - @IsEqualToField('password') + @IsEqualToField("password") confirmPassword!: string; - } + } - it('if password and confirm password are same then it should succeed', () => { - const model = new MyClass(); + it("if password and confirm password are same then it should succeed", () => { + const model = new MyClass(); - model.password = 'Test@1234'; - model.confirmPassword = 'Test@1234'; + model.password = "Test@1234"; + model.confirmPassword = "Test@1234"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(0); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(0); }); + }); - it('if password and confirm password are not same then it should fail', () => { - const model = new MyClass(); + it("if password and confirm password are not same then it should fail", () => { + const model = new MyClass(); - model.password = 'UniquePassword@123'; - model.confirmPassword = 'DifferentPassword@1234'; + model.password = "UniquePassword@123"; + model.confirmPassword = "DifferentPassword@1234"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(1); - expect(errors[0].constraints).toEqual({ - IsEqualToConstraint: 'confirmPassword should be equal to password', - }); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(1); + expect(errors[0].constraints).toEqual({ + IsEqualToConstraint: "confirmPassword should be equal to password", + }); }); + }); }); diff --git a/src/common/decorators/validation/is-equal-to.validator.ts b/src/common/decorators/validation/is-equal-to.validator.ts index bd018e5b..570b594b 100644 --- a/src/common/decorators/validation/is-equal-to.validator.ts +++ b/src/common/decorators/validation/is-equal-to.validator.ts @@ -39,5 +39,3 @@ export const IsEqualToField = ( }); }; }; - - diff --git a/src/common/decorators/validation/is-greater-than.validator.spec.ts b/src/common/decorators/validation/is-greater-than.validator.spec.ts index 610605ba..fd5e3843 100644 --- a/src/common/decorators/validation/is-greater-than.validator.spec.ts +++ b/src/common/decorators/validation/is-greater-than.validator.spec.ts @@ -1,52 +1,52 @@ -import {Validator} from 'class-validator'; -import {IsGreaterThan} from './is-greater-than.validator'; +import { Validator } from "class-validator"; +import { IsGreaterThan } from "./is-greater-than.validator"; const validator = new Validator(); -describe('IsGreaterThan', () => { - class MyClass { - passMarks!: number; +describe("IsGreaterThan", () => { + class MyClass { + passMarks!: number; - @IsGreaterThan('passMarks') + @IsGreaterThan("passMarks") totalMarks!: number; - } + } - it('if totalMarks is greater than passMarks then it should succeed', () => { - const model = new MyClass(); + it("if totalMarks is greater than passMarks then it should succeed", () => { + const model = new MyClass(); - model.passMarks = 40; - model.totalMarks = 100; + model.passMarks = 40; + model.totalMarks = 100; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(0); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(0); }); + }); - it('if totalMarks is less than passMarks then it should fail', () => { - const model = new MyClass(); + it("if totalMarks is less than passMarks then it should fail", () => { + const model = new MyClass(); - model.passMarks = 100; - model.totalMarks = 40; + model.passMarks = 100; + model.totalMarks = 40; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(1); - expect(errors[0].constraints).toEqual({ - IsGreaterThanConstraint: 'totalMarks should be greater than passMarks', - }); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(1); + expect(errors[0].constraints).toEqual({ + IsGreaterThanConstraint: "totalMarks should be greater than passMarks", + }); }); + }); - it('if totalMarks is equal to passMarks then it should fail', () => { - const model = new MyClass(); + it("if totalMarks is equal to passMarks then it should fail", () => { + const model = new MyClass(); - model.passMarks = 100; - model.totalMarks = 100; + model.passMarks = 100; + model.totalMarks = 100; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(1); - expect(errors[0].constraints).toEqual({ - IsGreaterThanConstraint: 'totalMarks should be greater than passMarks', - }); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(1); + expect(errors[0].constraints).toEqual({ + IsGreaterThanConstraint: "totalMarks should be greater than passMarks", + }); }); + }); }); diff --git a/src/common/decorators/validation/is-password.validator.spec.ts b/src/common/decorators/validation/is-password.validator.spec.ts index 10422d7c..90ecc76d 100644 --- a/src/common/decorators/validation/is-password.validator.spec.ts +++ b/src/common/decorators/validation/is-password.validator.spec.ts @@ -1,37 +1,37 @@ -import { Validator } from 'class-validator'; -import { IsPasswordField } from './is-password.validator'; +import { Validator } from "class-validator"; +import { IsPasswordField } from "./is-password.validator"; const validator = new Validator(); -describe('IsPassword', () => { - class MyClass { - @IsPasswordField() +describe("IsPassword", () => { + class MyClass { + @IsPasswordField() password: string; - } + } - it('if password satisfies then it should succeed (one uppercase,one lowercase, one number and one symbol and more than 8 characters)', () => { - const model = new MyClass(); + it("if password satisfies then it should succeed (one uppercase,one lowercase, one number and one symbol and more than 8 characters)", () => { + const model = new MyClass(); - model.password = 'Test-1234'; + model.password = "Test-1234"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(0); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(0); }); + }); - it('if password is not valid then it should fail', () => { - const model = new MyClass(); + it("if password is not valid then it should fail", () => { + const model = new MyClass(); - model.password = 'notStrongPassword'; + model.password = "notStrongPassword"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(1); - expect(errors[0].property).toEqual('password'); - expect(errors[0].constraints).toEqual({ - IsPasswordConstraint: - 'password should contain at least one lowercase letter, one uppercase letter, one numeric digit, and one special character', - }); - expect(errors[0].value).toEqual('notStrongPassword'); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(1); + expect(errors[0].property).toEqual("password"); + expect(errors[0].constraints).toEqual({ + IsPasswordConstraint: + "password should contain at least one lowercase letter, one uppercase letter, one numeric digit, and one special character", + }); + expect(errors[0].value).toEqual("notStrongPassword"); }); + }); }); diff --git a/src/common/decorators/validation/is-password.validator.ts b/src/common/decorators/validation/is-password.validator.ts index d1958c2a..5d705650 100644 --- a/src/common/decorators/validation/is-password.validator.ts +++ b/src/common/decorators/validation/is-password.validator.ts @@ -9,9 +9,9 @@ import { registerDecorator, } from "class-validator"; import { applyDecorators } from "@nestjs/common"; -import { MinMaxLength } from "./min-max-length.decorator"; import { PASSWORD_REGEX } from "@common/constant"; import { validationI18nMessage } from "@lib/i18n"; +import { MinMaxLength } from "./min-max-length.decorator"; /** * @@ -48,7 +48,6 @@ export const IsPassword = (validationOptions?: ValidationOptions): PropertyDecor }; }; - export const IsPasswordField = (validationOptions?: ValidationOptions & { minLength?: number; maxLength?: number }) => { return applyDecorators( IsNotEmpty({ diff --git a/src/common/decorators/validation/is-profane.validator.spec.ts b/src/common/decorators/validation/is-profane.validator.spec.ts index e7a6b09e..081d4efe 100644 --- a/src/common/decorators/validation/is-profane.validator.spec.ts +++ b/src/common/decorators/validation/is-profane.validator.spec.ts @@ -1,34 +1,34 @@ -import {Validator} from 'class-validator'; -import {IsProfane} from './is-profane.validator'; +import { Validator } from "class-validator"; +import { IsProfane } from "./is-profane.validator"; const validator = new Validator(); -describe('IsProfane', () => { - class MyClass { - @IsProfane() +describe("IsProfane", () => { + class MyClass { + @IsProfane() text!: string; - } + } - it('it should pass if text doesn\'t profane words', () => { - const model = new MyClass(); + it("it should pass if text doesn't profane words", () => { + const model = new MyClass(); - model.text = 'clean text'; + model.text = "clean text"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(0); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(0); }); + }); - it('it should fail if text has profane words', () => { - const model = new MyClass(); + it("it should fail if text has profane words", () => { + const model = new MyClass(); - model.text = 'Don\'t be an ash0le'; + model.text = "Don't be an ash0le"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(1); - expect(errors[0].constraints).toEqual({ - IsProfaneConstraint: 'text has profane words', - }); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(1); + expect(errors[0].constraints).toEqual({ + IsProfaneConstraint: "text has profane words", + }); }); + }); }); diff --git a/src/common/decorators/validation/is-string-field.decorator.ts b/src/common/decorators/validation/is-string-field.decorator.ts index 1fac5e9d..6df35208 100644 --- a/src/common/decorators/validation/is-string-field.decorator.ts +++ b/src/common/decorators/validation/is-string-field.decorator.ts @@ -9,11 +9,10 @@ import { IsString, Matches, } from "class-validator"; -import { MinMaxLength } from "./min-max-length.decorator"; -import { Sanitize, Trim } from "./transform.decorator"; - import { validationI18nMessage } from "@lib/i18n"; import type { StringFieldOptions } from "@common/@types"; +import { MinMaxLength } from "./min-max-length.decorator"; +import { Sanitize, Trim } from "./transform.decorator"; /** * It's a decorator that validates a string field diff --git a/src/common/decorators/validation/is-unique.validator.spec.ts b/src/common/decorators/validation/is-unique.validator.spec.ts index f754bb07..c8ef74f9 100644 --- a/src/common/decorators/validation/is-unique.validator.spec.ts +++ b/src/common/decorators/validation/is-unique.validator.spec.ts @@ -1,45 +1,44 @@ -import {createMock} from '@golevelup/ts-jest'; -import {EntityManager} from '@mikro-orm/core'; -import {Test} from '@nestjs/testing'; -import {IsUniqueConstraint} from './is-unique.validator'; -import type {IsUniqueValidationContext} from './is-unique.validator'; - -import {User} from '@entities'; - -describe('IsUnique', () => { - let isUnique: IsUniqueConstraint; - const mockEm = createMock(); - const username = 'tester'; - - const validatorArguments: IsUniqueValidationContext = { - object: {username}, - constraints: [() => User, 'username' as never], - value: username, - targetName: '', - property: 'username', - }; - - beforeEach(async () => { - const module = await Test.createTestingModule({ - providers: [IsUniqueConstraint, {provide: EntityManager, useValue: mockEm}], - }).compile(); - - isUnique = module.get(IsUniqueConstraint); - }); - - it('should pass if there are no duplicates', async () => { - mockEm.count.mockResolvedValue(0); - const result = await isUnique.validate(username, validatorArguments); - - expect(result).toBeTruthy(); - expect(mockEm.count).toBeCalledWith(User, {username}); - }); - - it('should fail if there are duplicates', async () => { - mockEm.count.mockResolvedValue(1); - const result = await isUnique.validate(username, validatorArguments); - - expect(result).toBeFalsy(); - expect(mockEm.count).toBeCalledWith(User, {username}); - }); +import { createMock } from "@golevelup/ts-jest"; +import { EntityManager } from "@mikro-orm/core"; +import { Test } from "@nestjs/testing"; +import { User } from "@entities"; +import { IsUniqueConstraint } from "./is-unique.validator"; +import type { IsUniqueValidationContext } from "./is-unique.validator"; + +describe("IsUnique", () => { + let isUnique: IsUniqueConstraint; + const mockEm = createMock(); + const username = "tester"; + + const validatorArguments: IsUniqueValidationContext = { + object: { username }, + constraints: [() => User, "username" as never], + value: username, + targetName: "", + property: "username", + }; + + beforeEach(async () => { + const module = await Test.createTestingModule({ + providers: [IsUniqueConstraint, { provide: EntityManager, useValue: mockEm }], + }).compile(); + + isUnique = module.get(IsUniqueConstraint); + }); + + it("should pass if there are no duplicates", async () => { + mockEm.count.mockResolvedValue(0); + const result = await isUnique.validate(username, validatorArguments); + + expect(result).toBeTruthy(); + expect(mockEm.count).toBeCalledWith(User, { username }); + }); + + it("should fail if there are duplicates", async () => { + mockEm.count.mockResolvedValue(1); + const result = await isUnique.validate(username, validatorArguments); + + expect(result).toBeFalsy(); + expect(mockEm.count).toBeCalledWith(User, { username }); + }); }); diff --git a/src/common/decorators/validation/is-username.validator.spec.ts b/src/common/decorators/validation/is-username.validator.spec.ts index 98a8e5dc..cb4967a5 100644 --- a/src/common/decorators/validation/is-username.validator.spec.ts +++ b/src/common/decorators/validation/is-username.validator.spec.ts @@ -1,36 +1,36 @@ -import {Validator} from 'class-validator'; -import {IsUsernameField} from './is-username.validator'; +import { Validator } from "class-validator"; +import { IsUsernameField } from "./is-username.validator"; const validator = new Validator(); -describe('IsUserName', () => { - class MyClass { - @IsUsernameField() +describe("IsUserName", () => { + class MyClass { + @IsUsernameField() username: string; - } + } - it('if username satisfies then it should succeed', () => { - const model = new MyClass(); + it("if username satisfies then it should succeed", () => { + const model = new MyClass(); - model.username = 'username123'; + model.username = "username123"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(0); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(0); }); + }); - it('if username is not valid then it should fail', () => { - const model = new MyClass(); + it("if username is not valid then it should fail", () => { + const model = new MyClass(); - model.username = '@123Yest'; + model.username = "@123Yest"; - return validator.validate(model).then((errors) => { - expect(errors.length).toEqual(1); - expect(errors[0].property).toEqual('username'); - expect(errors[0].constraints).toEqual({ - IsUsernameConstraint: 'username must fulfill username\'s criteria', - }); - expect(errors[0].value).toEqual('@123Yest'); - }); + return validator.validate(model).then((errors) => { + expect(errors.length).toEqual(1); + expect(errors[0].property).toEqual("username"); + expect(errors[0].constraints).toEqual({ + IsUsernameConstraint: "username must fulfill username's criteria", + }); + expect(errors[0].value).toEqual("@123Yest"); }); + }); }); diff --git a/src/common/decorators/validation/is-username.validator.ts b/src/common/decorators/validation/is-username.validator.ts index 40bc45f1..46321f74 100644 --- a/src/common/decorators/validation/is-username.validator.ts +++ b/src/common/decorators/validation/is-username.validator.ts @@ -20,10 +20,10 @@ import { ValidatorConstraint, registerDecorator, } from "class-validator"; -import { MinMaxLength } from "./min-max-length.decorator"; import { validationI18nMessage } from "@lib/i18n"; import { USERNAME_REGEX } from "@common/constant"; +import { MinMaxLength } from "./min-max-length.decorator"; @ValidatorConstraint({ async: true }) class IsUsernameConstraint implements ValidatorConstraintInterface { @@ -50,7 +50,7 @@ export const IsUsername = (validationOptions?: ValidationOptions): PropertyDecor }; }; -export const IsUsernameField = (validationOptions?: ValidationOptions & { minLength?: number; maxLength?: number } ) => { +export const IsUsernameField = (validationOptions?: ValidationOptions & { minLength?: number; maxLength?: number }) => { return applyDecorators( IsNotEmpty({ message: validationI18nMessage("validation.isNotEmpty"), diff --git a/src/common/decorators/validation/validation-field.generator.ts b/src/common/decorators/validation/validation-field.generator.ts index 9a0e7589..87cf6643 100644 --- a/src/common/decorators/validation/validation-field.generator.ts +++ b/src/common/decorators/validation/validation-field.generator.ts @@ -11,11 +11,11 @@ import { } from "class-validator"; import { enumToString } from "helper-fns"; import { i18nValidationMessage } from "nestjs-i18n"; -import { Sanitize, Trim } from "./transform.decorator"; import { validationI18nMessage } from "@lib/i18n"; import { MinMaxLength } from "@common/decorators"; import type { NumberFieldOptions, StringFieldOptions } from "@common/@types"; +import { Sanitize, Trim } from "./transform.decorator"; export class ValidatorFieldBuilder { private decoratorsToApply: PropertyDecorator[]; diff --git a/src/common/dtos/cursor-pagination.dto.ts b/src/common/dtos/cursor-pagination.dto.ts index 9a61a684..c98890d8 100644 --- a/src/common/dtos/cursor-pagination.dto.ts +++ b/src/common/dtos/cursor-pagination.dto.ts @@ -1,9 +1,9 @@ import { ApiHideProperty } from "@nestjs/swagger"; import { Allow, IsBase64 } from "class-validator"; -import { PaginationDto } from "./pagination.dto"; import { PaginationType } from "@common/@types"; import { IsNumberField, IsStringField } from "@common/decorators"; import { validationI18nMessage } from "@lib/i18n"; +import { PaginationDto } from "./pagination.dto"; // TODO: add filters diff --git a/src/common/dtos/offset-pagination.dto.ts b/src/common/dtos/offset-pagination.dto.ts index c568c471..b6bfeed6 100644 --- a/src/common/dtos/offset-pagination.dto.ts +++ b/src/common/dtos/offset-pagination.dto.ts @@ -1,9 +1,9 @@ import { ApiHideProperty } from "@nestjs/swagger"; import { Allow } from "class-validator"; -import { PaginationDto } from "./pagination.dto"; import { IsEnumField, IsNumberField, IsStringField } from "@common/decorators"; import { PaginationType, QueryOrder } from "@common/@types"; +import { PaginationDto } from "./pagination.dto"; export class OffsetPaginationDto extends PaginationDto { @ApiHideProperty() diff --git a/src/common/guards/auth.guard.spec.ts b/src/common/guards/auth.guard.spec.ts index a4036054..0bb0855a 100644 --- a/src/common/guards/auth.guard.spec.ts +++ b/src/common/guards/auth.guard.spec.ts @@ -1,48 +1,48 @@ -import {createMock} from '@golevelup/ts-jest'; -import type {ExecutionContext} from '@nestjs/common'; -import {HttpException} from '@nestjs/common'; -import {AuthGuard} from './auth.guard'; +import { createMock } from "@golevelup/ts-jest"; +import type { ExecutionContext } from "@nestjs/common"; +import { HttpException } from "@nestjs/common"; +import { mockJwtService } from "@mocks"; +import { AuthGuard } from "./auth.guard"; -import {mockJwtService} from '@mocks'; +describe("AuthenticatedGuard", () => { + let authenticatedGuard: AuthGuard; + const mockContext = createMock({ + switchToHttp: () => ({ + getRequest: () => ({ + headers: { + authorization: "Bearer token", + }, + }), + }), + }); -describe('AuthenticatedGuard', () => { - let authenticatedGuard: AuthGuard; - const mockContext = createMock({ - switchToHttp: () => ({ - getRequest: () => ({ - headers: { - authorization: 'Bearer token', - }, - }), - }), - }); + beforeEach(() => { + authenticatedGuard = new AuthGuard(mockJwtService); + }); - beforeEach(() => { - authenticatedGuard = new AuthGuard(mockJwtService); - }); + it("should be defined", () => { + expect(authenticatedGuard).toBeDefined(); + }); - it('should be defined', () => { - expect(authenticatedGuard).toBeDefined(); + describe("canActivate", () => { + it("should return authorization", () => { + mockJwtService.verify.mockImplementationOnce(() => { + return { idx: "idx" }; + }); + expect(authenticatedGuard.canActivate(mockContext)).toBe(true); }); - describe('canActivate', () => { - it('should return authorization', () => { - mockJwtService.verify.mockImplementationOnce(() => { - return {idx: 'idx'}; - }); - expect(authenticatedGuard.canActivate(mockContext)).toBe(true); - }); - - it.skip('should throw error when invalid token', () => { - mockJwtService.verify.mockImplementationOnce(() => { - throw new Error('Invalid token'); - }); + it.skip("should throw error when invalid token", () => { + mockJwtService.verify.mockImplementationOnce(() => { + throw new Error("Invalid token"); + }); - try { - authenticatedGuard.canActivate(mockContext); - } catch (error) { - expect(error).toBeInstanceOf(HttpException); - } - }); + try { + authenticatedGuard.canActivate(mockContext); + } + catch (error) { + expect(error).toBeInstanceOf(HttpException); + } }); + }); }); diff --git a/src/common/guards/jwt.guard.spec.ts b/src/common/guards/jwt.guard.spec.ts index 29ce1dec..3d748271 100644 --- a/src/common/guards/jwt.guard.spec.ts +++ b/src/common/guards/jwt.guard.spec.ts @@ -1,36 +1,35 @@ -import {createMock} from '@golevelup/ts-jest'; -import type {ExecutionContext} from '@nestjs/common'; -import {JwtAuthGuard} from './jwt.guard'; +import { createMock } from "@golevelup/ts-jest"; +import type { ExecutionContext } from "@nestjs/common"; +import { mockReflector } from "@mocks"; +import { JwtAuthGuard } from "./jwt.guard"; -import {mockReflector} from '@mocks'; +describe("JwtAuthGuard", () => { + let authenticatedGuard: JwtAuthGuard; -describe('JwtAuthGuard', () => { - let authenticatedGuard: JwtAuthGuard; + const mockContext = createMock({ + switchToHttp: () => ({ + getRequest: () => ({ + headers: { + authorization: "Bearer token", + }, + }), + }), + }); - const mockContext = createMock({ - switchToHttp: () => ({ - getRequest: () => ({ - headers: { - authorization: 'Bearer token', - }, - }), - }), - }); - - beforeEach(() => { - authenticatedGuard = new JwtAuthGuard(mockReflector); - }); + beforeEach(() => { + authenticatedGuard = new JwtAuthGuard(mockReflector); + }); - it('should be defined', () => { - expect(authenticatedGuard).toBeDefined(); - }); + it("should be defined", () => { + expect(authenticatedGuard).toBeDefined(); + }); - describe('canActivate', () => { - it('should return true for public', () => { - mockReflector.get.mockImplementationOnce(() => { - return true; - }); - expect(authenticatedGuard.canActivate(mockContext)).toBe(true); - }); + describe("canActivate", () => { + it("should return true for public", () => { + mockReflector.get.mockImplementationOnce(() => { + return true; + }); + expect(authenticatedGuard.canActivate(mockContext)).toBe(true); }); + }); }); diff --git a/src/common/helpers/app.utils.ts b/src/common/helpers/app.utils.ts index 31496bd0..75c6433a 100644 --- a/src/common/helpers/app.utils.ts +++ b/src/common/helpers/app.utils.ts @@ -6,7 +6,6 @@ import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"; import { i18nValidationErrorFactory } from "nestjs-i18n"; import { getMiddleware } from "swagger-stats"; import { isArray } from "helper-fns"; -import { HelperService } from "./helpers.utils"; import { swaggerOptions } from "@common/swagger/swagger.plugin"; import { @@ -16,6 +15,7 @@ import { SWAGGER_DESCRIPTION, SWAGGER_TITLE, } from "@common/constant"; +import { HelperService } from "./helpers.utils"; const logger = new Logger("App:Utils"); @@ -85,7 +85,7 @@ export const AppUtils = { for (const method of methods) { if ( isArray(method.security) - // eslint-disable-next-line @typescript-eslint/no-unsafe-call + // eslint-disable-next-line ts/no-unsafe-call && method.security.includes(IS_PUBLIC_KEY_META) ) method.security = []; diff --git a/src/common/helpers/helpers.utils.ts b/src/common/helpers/helpers.utils.ts index 47879e34..307bf902 100644 --- a/src/common/helpers/helpers.utils.ts +++ b/src/common/helpers/helpers.utils.ts @@ -60,7 +60,6 @@ directory of the module. */ return process.env.NODE_ENV === "prod" ? join(currentDirectory, "dist") : currentDirectory; }, - /* The `hashString` function is used to hash a user's password using the Argon2 algorithm. It takes a user's password as input and returns a promise that resolves to the hashed password as a string. The `hash` function from the `argon2` library is used to perform the actual hashing, with the diff --git a/src/common/interceptors/app-exit.interceptor.spec.ts b/src/common/interceptors/app-exit.interceptor.spec.ts index e18ed3d3..d991df41 100644 --- a/src/common/interceptors/app-exit.interceptor.spec.ts +++ b/src/common/interceptors/app-exit.interceptor.spec.ts @@ -1,18 +1,18 @@ -import {ExitInterceptor} from './app-exit.interceptor'; -import {mockContext, mockNext} from '@mocks'; +import { mockContext, mockNext } from "@mocks"; +import { ExitInterceptor } from "./app-exit.interceptor"; -describe('ExitInterceptor', () => { - let interceptor: ExitInterceptor; +describe("ExitInterceptor", () => { + let interceptor: ExitInterceptor; - beforeEach(() => { - interceptor = new ExitInterceptor(); - }); + beforeEach(() => { + interceptor = new ExitInterceptor(); + }); - describe('intercept', () => { - it('should pass', () => { - interceptor.intercept(mockContext, mockNext).subscribe((result) => { - expect(result).toEqual({}); - }); - }); + describe("intercept", () => { + it("should pass", () => { + interceptor.intercept(mockContext, mockNext).subscribe((result) => { + expect(result).toEqual({}); + }); }); + }); }); diff --git a/src/common/interceptors/request-sanitizer.interceptor.spec.ts b/src/common/interceptors/request-sanitizer.interceptor.spec.ts index 949bed30..f77563df 100644 --- a/src/common/interceptors/request-sanitizer.interceptor.spec.ts +++ b/src/common/interceptors/request-sanitizer.interceptor.spec.ts @@ -1,42 +1,41 @@ -import {createMock} from '@golevelup/ts-jest'; -import type {CallHandler, ExecutionContext} from '@nestjs/common'; -import {RequestSanitizerInterceptor} from './request-sanitizer.interceptor'; +import { createMock } from "@golevelup/ts-jest"; +import type { CallHandler, ExecutionContext } from "@nestjs/common"; +import { mockRequest } from "@mocks"; +import { RequestSanitizerInterceptor } from "./request-sanitizer.interceptor"; -import {mockRequest} from '@mocks'; +describe("RequestSanitizerInterceptor", () => { + let interceptor: RequestSanitizerInterceptor; -describe('RequestSanitizerInterceptor', () => { - let interceptor: RequestSanitizerInterceptor; + // create the mock CallHandler for the interceptor + const mockContext = createMock({ + switchToHttp: () => ({ + getRequest: () => ({ + mockRequest, + }), + }), + }); - // create the mock CallHandler for the interceptor - const mockContext = createMock({ - switchToHttp: () => ({ - getRequest: () => ({ - mockRequest, - }), - }), - }); - - const mockNext = createMock(); + const mockNext = createMock(); - beforeEach(() => { - interceptor = new RequestSanitizerInterceptor(); - }); - it('should be defined', () => { - expect(interceptor).toBeDefined(); - }); + beforeEach(() => { + interceptor = new RequestSanitizerInterceptor(); + }); + it("should be defined", () => { + expect(interceptor).toBeDefined(); + }); - it('should clean request', () => { - interceptor.intercept(mockContext, mockNext).subscribe((_result) => { - expect(mockRequest.body.test).toEqual('test'); - expect(mockRequest.query.test).toEqual('test'); - expect(mockRequest.params.test).toEqual('test'); + it("should clean request", () => { + interceptor.intercept(mockContext, mockNext).subscribe((_result) => { + expect(mockRequest.body.test).toEqual("test"); + expect(mockRequest.query.test).toEqual("test"); + expect(mockRequest.params.test).toEqual("test"); - expect(mockRequest.body.xss).toEqual(''); - expect(mockRequest.params.xss).toEqual(''); - expect(mockRequest.query.xss).toEqual(''); - expect(mockRequest.body.password).toEqual( - '