Skip to content
Snippets Groups Projects
Unverified Commit 45c91dc1 authored by Konstantin Tsabolov's avatar Konstantin Tsabolov
Browse files

chore: update dependencies, fix style

* Upgraded the dependencies to the latest versions
* Switched output to ESM format
* Switched NestJS and Jest to SWC to improve speed of building and testing
* Refactored TSConfig to remove tsconfig-paths
* Updated imports in all files to reflect the change in TSConfig
* Changed the linting rules (removed AirBnB config)
* Fixed Prettier installation (added ignore file)
* Fixed typing errors (mainly usage of any's)
* Fixed the non-working E2E test

P.S. None of the mentioned makes sense alone, therefore a huge commit :man_shrugging:
parent 9c2cfed8
No related branches found
No related tags found
2 merge requests!9feat(ssi): Establish a trusted connection with yourself,!8Project house-keeping, refactoring and reorganizing
Showing
with 12011 additions and 226 deletions
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
ecmaVersion: 2021,
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'airbnb-base',
'airbnb-typescript/base',
],
parserOptions: {
project: './tsconfig.json',
},
root: true,
env: {
node: true,
jest: true,
},
plugins: ['prettier', '@typescript-eslint/eslint-plugin', 'jest'],
extends: [
'prettier',
'plugin:@typescript-eslint/recommended',
'plugin:jest/recommended',
],
ignorePatterns: ['.eslintrc.js'],
overrides: [],
settings: {
jest: {
version: '29',
},
},
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'no-unused-vars': 0,
'@typescript-eslint/no-unused-vars': [1, { argsIgnorePattern: '^_' }],
},
overrides: [
{
files: [
'*.spec.ts',
'*.e2e-spec.ts',
'__mocks__/*.ts',
'__mocks__/**/*.ts',
],
rules: {
'@typescript-eslint/no-explicit-any': 0,
'jest/no-mocks-import': 0,
},
},
],
};
# Ignore everything
*
# Except for these files
!*.ts
!*.d.ts
!jest.config.js
# .. also in subdirectories
!*/
# ... in these ones
!src/*
# Explicitly ignore these locations
node_modules
dist
{
"jsc": {
"preserveAllComments": true,
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"target": "es2022"
},
"module": {
"type": "es6"
},
"sourceMaps": true,
"exclude": [".spec.ts", ".e2e-spec.ts"]
}
/** @type {import('jest').Config} */
import { readFileSync } from 'node:fs';
const swcConfig = JSON.parse(readFileSync('./.swcrc', 'utf8'));
export default {
moduleFileExtensions: ['js', 'ts'],
testEnvironment: 'node',
transform: {
'^.+\\.ts$': [
'@swc/jest',
{
...swcConfig,
sourceMaps: false,
exclude: [],
swcrc: false,
},
],
},
extensionsToTreatAsEsm: ['.ts'],
moduleNameMapper: {
// ESM modules require `.js` extension to be specified, but Jest doesn't work with them
// Removing `.js` extension from module imports
'^uuid$': 'uuid',
'^(.*)/(.*)\\.js$': '$1/$2',
},
collectCoverageFrom: ['src/**/*.(t|j)s'],
coverageReporters:
process.env.CI === 'true'
? ['text-summary', 'json-summary']
: ['text-summary', 'html'],
coveragePathIgnorePatterns: [
'<rootDir>/node_modules/',
'<rootDir>/test/',
'<rootDir>/coverage/',
'<rootDir>/dist/',
'<rootDir>/**/test',
'@types',
'.dto.(t|j)s',
'.enum.ts',
'.interface.ts',
'.type.ts',
'.spec.ts',
],
coverageDirectory: './coverage',
// With v8 coverage provider it's much faster, but
// with this enabled it's not possible to ignore whole files' coverage
coverageProvider: 'v8',
};
{
"collection": "@nestjs/schematics",
"sourceRoot": "src"
"sourceRoot": "src",
"compilerOptions": {
"builder": "swc",
"typeCheck": true
}
}
This diff is collapsed.
......@@ -5,18 +5,22 @@
"author": "Sagar",
"private": true,
"license": "Apache 2.0",
"type": "module",
"scripts": {
"clean": "rm -r dist",
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"dbSchema": "npx prisma db push --schema=./src/prisma/schema.prisma",
"prisma:generate": "prisma generate --schema=./src/prisma/schema.prisma",
"prisma:migrate": "npx prisma migrate deploy --schema=./src/prisma/schema.prisma",
"prismaStudio": "npx prisma studio",
"start": "nest start",
"start:dev": "nest start --watch --preserveWatchOutput",
"start:docker": "pnpm prisma:migrate && pnpm start",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"lint": "eslint --fix",
"lint:all": "npm run lint -- .",
"format": "prettier --write",
"format:all": "npm run format -- .",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
......@@ -24,111 +28,66 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@elastic/ecs-winston-format": "^1.3.1",
"@nestjs/axios": "^0.0.8",
"@nestjs/common": "^8.0.0",
"@nestjs/config": "^1.1.6",
"@nestjs/core": "^8.0.0",
"@elastic/ecs-winston-format": "^1.5.0",
"@nestjs/axios": "^3.0.1",
"@nestjs/common": "^10.2.8",
"@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.2.8",
"@nestjs/mapped-types": "*",
"@nestjs/microservices": "^8.2.6",
"@nestjs/platform-express": "^8.0.0",
"@nestjs/schedule": "^1.0.2",
"@nestjs/swagger": "^5.2.0",
"@nestjs/terminus": "^8.0.4",
"@prisma/client": "^3.9.2",
"@types/node": "^16.0.0",
"class-validator": "^0.13.2",
"express": "^4.17.3",
"joi": "^17.6.0",
"jsonwebtoken": "^8.5.1",
"jwks-rsa": "^3.0.0",
"@nestjs/microservices": "^10.2.8",
"@nestjs/platform-express": "^10.2.8",
"@nestjs/schedule": "^4.0.0",
"@nestjs/swagger": "^7.1.16",
"@nestjs/terminus": "^10.1.1",
"@prisma/client": "^5.6.0",
"class-validator": "^0.14.0",
"joi": "^17.11.0",
"jsonwebtoken": "^9.0.2",
"jwks-rsa": "^3.1.0",
"liquibase": "^4.4.0",
"moment": "^2.29.1",
"nats": "^2.6.0",
"openid-client": "^5.1.6",
"pg": "^8.7.3",
"prisma": "^3.9.2",
"moment": "^2.29.4",
"nats": "^2.18.0",
"openid-client": "^5.6.1",
"pg": "^8.11.3",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"swagger-ui-express": "^4.3.0",
"winston": "^3.6.0",
"winston-elasticsearch": "^0.16.1"
"rxjs": "^7.8.1",
"swagger-ui-express": "^5.0.0",
"winston": "^3.11.0",
"winston-elasticsearch": "^0.17.4"
},
"devDependencies": {
"@nestjs/cli": "^8.0.0",
"@nestjs/schematics": "^8.0.0",
"@nestjs/testing": "^8.0.0",
"@nestjs/cli": "^10.2.1",
"@nestjs/schematics": "^10.0.3",
"@nestjs/testing": "^10.2.8",
"@swc/cli": "^0.1.62",
"@swc/core": "^1.3.96",
"@swc/jest": "^0.2.29",
"@types/express": "^4.17.13",
"@types/jest": "27.0.2",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"dotenv-cli": "^4.1.1",
"eslint": "^8.12.0",
"@types/jsonwebtoken": "^9.0.5",
"@types/node": "^20.9.0",
"@types/supertest": "^2.0.16",
"@typescript-eslint/eslint-plugin": "^6.11.0",
"@typescript-eslint/parser": "^6.11.0",
"dotenv-cli": "^7.3.0",
"eslint": "^8.53.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^16.1.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-prettier": "^4.0.0",
"husky": "^7.0.4",
"jest": "^27.2.5",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "^27.0.3",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "^3.10.1",
"typescript": "^4.3.5"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node",
"setupFiles": [
"<rootDir>/../setup.js"
],
"coveragePathIgnorePatterns": [
"<rootDir>/main"
],
"moduleNameMapper": {
"@src/(.*)": [
"<rootDir>/$1"
],
"@client/(.*)": [
"<rootDir>/client/$1"
],
"@config/(.*)": [
"<rootDir>/../config/$1"
],
"@utils/*": [
"<rootDir>/utils/$1"
],
"@common/(.*)": [
"<rootDir>/common/$1"
],
"@principal/(.*)": [
"<rootDir>/principal/$1"
],
"@health/(.*)": [
"<rootDir>/health/$1"
],
"@DB/(.*)": [
"<rootDir>/prisma/$1"
]
}
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-jest": "^27.6.0",
"eslint-plugin-prettier": "^5.0.1",
"husky": "^8.0.3",
"jest": "^29.7.0",
"prettier": "^3.1.0",
"prisma": "^5.6.0",
"rimraf": "^5.0.5",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "^29.1.1",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.2.2"
}
}
import PrismaService from '@DB/prisma.service';
import { APP_FILTER } from '@nestjs/core';
import { HttpModule } from '@nestjs/axios';
import {
MiddlewareConsumer,
Module,
......@@ -7,16 +6,17 @@ import {
RequestMethod,
} from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { TerminusModule } from '@nestjs/terminus';
import validationSchema from '@config/validation';
import config from '@config/config';
import HealthController from '@health/health.controller';
import ExceptionHandler from '@common/exception.handler';
import PrincipalModule from '@principal/module';
import { APP_FILTER } from '@nestjs/core';
import { ScheduleModule } from '@nestjs/schedule';
import { HttpModule } from '@nestjs/axios';
import { AuthMiddleware } from './middleware/auth.middleware';
import { TerminusModule } from '@nestjs/terminus';
import ExceptionHandler from './common/exception.handler.js';
import config from './config/config.js';
import validationSchema from './config/validation.js';
import HealthController from './health/health.controller.js';
import { AuthMiddleware } from './middleware/auth.middleware.js';
import PrincipalModule from './principal/module.js';
import PrismaService from './prisma/prisma.service.js';
import PrismaModule from './prisma/prisma.module.js';
@Module({
imports: [
......@@ -27,6 +27,7 @@ import { AuthMiddleware } from './middleware/auth.middleware';
load: [config],
validationSchema,
}),
PrismaModule,
PrincipalModule,
HttpModule,
],
......@@ -36,7 +37,6 @@ import { AuthMiddleware } from './middleware/auth.middleware';
provide: APP_FILTER,
useClass: ExceptionHandler,
},
PrismaService,
],
})
export default class AppModule implements NestModule {
......
import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import { ResponseType } from 'openid-client';
import { lastValueFrom } from 'rxjs';
import { Attestation, NATSServices } from '@common/constants';
import ResponseType from '@common/response';
import OfferMembershipCredentialDto from '@principal/entities/offerMembershipCredentialDto.entity';
import logger from '@src/utils/logger';
import { Attestation, NATSServices } from '../common/constants.js';
import OfferMembershipCredentialDto from '../principal/entities/offerMembershipCredentialDto.entity.js';
import logger from '../utils/logger.js';
@Injectable()
export default class NatsClientService {
......
import {
ExceptionFilter,
Catch,
ArgumentsHost,
Catch,
ExceptionFilter,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';
import ResponseType from './response';
import ResponseType from './response.js';
@Catch()
export default class ExceptionHandler implements ExceptionFilter {
constructor(private readonly httpAdapterHost: HttpAdapterHost) {}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
catch(exception: any, host: ArgumentsHost): void {
// In certain situations `httpAdapter` might not be available in the
// constructor method, thus we should resolve it here.
......@@ -25,10 +26,13 @@ export default class ExceptionHandler implements ExceptionFilter {
exception.message.error || exception.message || 'Something went wrong!';
if (exception instanceof HttpException) {
const errorResponse: any = exception.getResponse();
const errorResponse: string | object = exception.getResponse();
statusCode = exception.getStatus();
message = errorResponse.error || message;
message =
(typeof errorResponse === 'object' &&
Reflect.get(errorResponse, 'error')) ||
message;
}
const responseBody: ResponseType = {
......
export default interface ResponseType {
statusCode: number;
message: string;
data?: any;
error?: any;
data?: unknown;
error?: unknown;
}
import { fileURLToPath } from 'node:url';
const parentDirectory = fileURLToPath(new URL('..', import.meta.url));
const config = () => ({
PORT: Number(process.env.PORT),
......@@ -16,7 +19,7 @@ const config = () => ({
port: 5432,
synchronize: false,
logging: false,
entities: [`${__dirname}/../**/**.model{.ts,.js}`],
entities: [`${parentDirectory}/../**/**.model{.ts,.js}`],
},
ECSURL: process.env.ECSURL,
});
......
import * as Joi from 'joi';
import Joi from 'joi';
const validationSchema = Joi.object({
DATABASE_URL: Joi.string().required(),
......
import { Controller, Get, Version, HttpStatus } from '@nestjs/common';
import ResponseType from '@common/response';
import type ResponseType from '../common/response.js';
@Controller('health')
export default class HealthController {
......
import { NestFactory } from '@nestjs/core';
import { ConfigService } from '@nestjs/config';
import { VersioningType } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { NestFactory } from '@nestjs/core';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import AppModule from './app.module';
import logger from './utils/logger';
import AppModule from './app.module.js';
import logger from './utils/logger.js';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
......
import { HttpStatus, Injectable, NestMiddleware } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import logger from '@src/utils/logger';
import { Request, Response, NextFunction } from 'express';
// import { ClientCredentials } from 'simple-oauth2';
import * as jwt from 'jsonwebtoken';
import jwksClient = require('jwks-rsa');
// interface IOAuthConfig {
// client: {
// id: string,
// secret: string
// };
// auth: {
// tokenHost: string
// }
// }
import type { NextFunction, Request, Response } from 'express';
import jwt from 'jsonwebtoken';
import jwksClient from 'jwks-rsa';
import logger from '../utils/logger.js';
@Injectable()
export class AuthMiddleware implements NestMiddleware {
constructor(private readonly configService: ConfigService) {}
/* eslint-disable */
async use(req: Request, res: Response, next: NextFunction) {
if (this.configService.get('auth.useAuth') === 'false') {
return next();
......@@ -42,48 +29,6 @@ export class AuthMiddleware implements NestMiddleware {
return;
}
// ClientID string `envconfig:"OAUTH_CLIENT_ID"`
// ClientSecret string `envconfig:"OAUTH_CLIENT_SECRET"`
// TokenURL string `envconfig:"OAUTH_TOKEN_URL"`
// const oauthConfig = {
// client: {
// id: this.configService.get('auth.clientId'),
// secret: this.configService.get('auth.clientSecret')
// },
// auth: {
// tokenHost: this.configService.get('auth.tokenUrl') || 'https://api.oauth.com'
// }
// };
// async function getAccessToken(conf: IOAuthConfig) {
// const client = new ClientCredentials(conf);
// let accessToken: any;
// const tokenParams = {
// scope: '<scope>',
// };
// try {
// accessToken = await client.getToken(tokenParams);
// } catch (error) {
// logger.error('Access Token error', error.message);
// }
// return accessToken;
// }
// let result = getAccessToken(oauthConfig);
// if (!result) {
// res.json({
// status: HttpStatus.UNAUTHORIZED,
// message: 'Unauthorized. Access token error.',
// data: undefined,
// })
// return;
// }
const getKey = (
header: jwt.JwtHeader,
callback: jwt.SigningKeyCallback,
......@@ -97,12 +42,15 @@ export class AuthMiddleware implements NestMiddleware {
.catch(callback);
};
function verify(token: string): Promise<any> | undefined {
function verify(token: string): Promise<unknown> | undefined {
return new Promise(
(resolve: (decoded: any) => void, reject: (error: Error) => void) => {
(
resolve: (decoded: unknown) => void,
reject: (error: Error) => void,
) => {
const verifyCallback: jwt.VerifyCallback<jwt.JwtPayload | string> = (
error: jwt.VerifyErrors | null,
decoded: any,
decoded: unknown,
): void => {
if (error) {
return reject(error);
......
import ResponseType from '@common/response';
import {
BadRequestException,
Body,
......@@ -10,15 +9,15 @@ import {
Res,
Version, // Post, Version, Body, Res, Req,
} from '@nestjs/common';
import { Response, Request } from 'express';
import { isURL } from 'class-validator';
import PrincipalService from '@principal/services/service';
import logger from '@src/utils/logger';
import { MessagePattern } from '@nestjs/microservices';
import { NATSServices } from '@common/constants';
import OfferMembershipCredentialDto from '@principal/entities/offerMembershipCredentialDto.entity';
import MapUserInfoDTO from '@principal/entities/mapUserInfoDTO.entity';
import { isURL } from 'class-validator';
import type { Request, Response } from 'express';
import { NATSServices } from '../../common/constants.js';
import type ResponseType from '../../common/response.js';
import logger from '../../utils/logger.js';
import MapUserInfoDTO from '../entities/mapUserInfoDTO.entity.js';
import OfferMembershipCredentialDto from '../entities/offerMembershipCredentialDto.entity.js';
import PrincipalService from '../services/service.js';
@Controller()
export default class PrincipalController {
......@@ -75,10 +74,10 @@ export default class PrincipalController {
};
return response.send(res);
} catch (error) {
} catch (error: unknown) {
throw new HttpException(
error?.message || 'Internal server error',
error?.status || 500,
Reflect.get(error || {}, 'message') || 'Internal server error',
Reflect.get(error || {}, 'status') || 500,
);
}
}
......
import { ApiProperty } from '@nestjs/swagger';
export type UserData = {
[key: string]: any;
[key: string]: unknown;
};
export default class MapUserInfoDTO {
@ApiProperty()
......
import { Module } from '@nestjs/common';
import PrismaService from '@DB/prisma.service';
import { HttpModule } from '@nestjs/axios';
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { NATSServices } from '@common/constants';
import PrincipalController from '@principal/controller/controller';
import PrincipalService from '@principal/services/service';
import NatsClientService from '@client/nats.client';
import config from '@config/config';
import NatsClientService from '../client/nats.client.js';
import { NATSServices } from '../common/constants.js';
import config from '../config/config.js';
import PrismaService from '../prisma/prisma.service.js';
import PrincipalController from './controller/controller.js';
import PrincipalService from './services/service.js';
@Module({
imports: [
......
import { HttpService } from '@nestjs/axios';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import ResponseType from '@src/common/response';
import NatsClientService from '@src/client/nats.client';
import OfferMembershipCredentialDto from '@principal/entities/offerMembershipCredentialDto.entity';
import NatsClientService from '../../client/nats.client.js';
import {
AttestationManagerUrl,
SaveUserInfo,
ConnectionManagerUrl,
CreateMemberConnection,
} from '@src/common/constants';
import MapUserInfoDTO from '@principal/entities/mapUserInfoDTO.entity';
import { HttpService } from '@nestjs/axios';
SaveUserInfo,
} from '../../common/constants.js';
import ResponseType from '../../common/response.js';
import MapUserInfoDTO from '../entities/mapUserInfoDTO.entity.js';
import OfferMembershipCredentialDto from '../entities/offerMembershipCredentialDto.entity.js';
@Injectable()
export default class PrincipalService {
......@@ -27,7 +27,10 @@ export default class PrincipalService {
return response;
}
async mapUserInfo({ userData, userInfoURL }: MapUserInfoDTO): Promise<any> {
async mapUserInfo({
userData,
userInfoURL,
}: MapUserInfoDTO): Promise<unknown> {
try {
let userInfo;
......@@ -71,10 +74,10 @@ export default class PrincipalService {
invitationUrl: connection.data.invitationUrl,
userInfo: savedUserInfo.data,
};
} catch (error) {
} catch (error: unknown) {
throw new HttpException(
error?.message || 'Internal server error',
error?.status || 500,
Reflect.get(error || {}, 'message') || 'Internal server error',
Reflect.get(error || {}, 'status') || 500,
);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment