From 9de241e343bd9adfdb7c1d8daa24a84423a3371f Mon Sep 17 00:00:00 2001 From: Bruno Tot Date: Fri, 30 Aug 2024 19:10:24 +0200 Subject: [PATCH] chore: add ci/cd for tests on different packages --- .eslintrc | 2 +- .github/workflows/test-backend.yml | 23 + .github/workflows/test-frontend.yml | 23 + .github/workflows/test-shared.yml | 23 + .vscode/launch.json | 19 +- package.json | 43 +- packages/backend/package.json | 8 +- packages/backend/src/ExpressApp.ts | 4 +- packages/backend/src/decorators/contract.ts | 2 +- .../middleware/global/withKeycloak.ts | 3 +- .../infrastructure/middleware/withSecured.ts | 12 +- .../repository/impl/KeycloakRepository.ts | 3 + .../src/infrastructure/service/UserService.ts | 8 +- .../test/__mocks__/KeycloakRepositoryMock.ts | 31 +- packages/backend/test/__mocks__/index.ts | 4 +- packages/backend/test/random.test.ts | 12 +- packages/backend/test/user.test.ts | 10 +- packages/backend/tsconfig.json | 10 - packages/backend/tsconfig.prod.json | 10 - packages/frontend/.eslintrc | 1 + packages/frontend/package.json | 9 +- packages/shared/package.json | 5 +- packages/shared/test/contracts.test.ts | 24 + packages/shared/test/setup/globalSetup.ts | 1 + packages/shared/vitest.config.js | 22 + pnpm-lock.yaml | 414 ++++-------------- tsconfig.json | 2 +- typedoc.json | 14 +- 28 files changed, 292 insertions(+), 450 deletions(-) create mode 100644 .github/workflows/test-backend.yml create mode 100644 .github/workflows/test-frontend.yml create mode 100644 .github/workflows/test-shared.yml create mode 100644 packages/shared/test/contracts.test.ts create mode 100644 packages/shared/test/setup/globalSetup.ts create mode 100644 packages/shared/vitest.config.js diff --git a/.eslintrc b/.eslintrc index c330e20d..a5733cda 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,7 +10,7 @@ "sourceType": "module" }, "plugins": ["@typescript-eslint"], - "ignorePatterns": ["node_modules/", "dist/", "logger.js", "docs/", "npx", "assets"], + "ignorePatterns": ["node_modules/", "dist/", "docs/", "assets/"], "rules": { "@typescript-eslint/consistent-type-imports": "error", "@typescript-eslint/ban-ts-comment": "off" diff --git a/.github/workflows/test-backend.yml b/.github/workflows/test-backend.yml new file mode 100644 index 00000000..ba9c1e15 --- /dev/null +++ b/.github/workflows/test-backend.yml @@ -0,0 +1,23 @@ +name: MERN Sample App - Backend Tests + +on: + push: + paths: + - "packages/backend/**" + branches: + - main + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: 🛒 Checkout Repository + uses: actions/checkout@v4 + + - name: 🤳 Install + uses: ./.github/composite-actions/install + + - name: 🚀 Run Backend Tests + run: pnpm run backend:test diff --git a/.github/workflows/test-frontend.yml b/.github/workflows/test-frontend.yml new file mode 100644 index 00000000..68b54afc --- /dev/null +++ b/.github/workflows/test-frontend.yml @@ -0,0 +1,23 @@ +name: MERN Sample App - Frontend Tests + +on: + push: + paths: + - "packages/frontend/**" + branches: + - main + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: 🛒 Checkout Repository + uses: actions/checkout@v4 + + - name: 🤳 Install + uses: ./.github/composite-actions/install + + - name: 🚀 Run Frontend Tests + run: pnpm run frontend:test diff --git a/.github/workflows/test-shared.yml b/.github/workflows/test-shared.yml new file mode 100644 index 00000000..ab4d6d9c --- /dev/null +++ b/.github/workflows/test-shared.yml @@ -0,0 +1,23 @@ +name: MERN Sample App - Shared Tests + +on: + push: + paths: + - "packages/shared/**" + branches: + - main + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: 🛒 Checkout Repository + uses: actions/checkout@v4 + + - name: 🤳 Install + uses: ./.github/composite-actions/install + + - name: 🚀 Run Shared Tests + run: pnpm run shared:test diff --git a/.vscode/launch.json b/.vscode/launch.json index 8227b721..a8c1f297 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,19 +1,6 @@ { "version": "2.0.0", "configurations": [ - { - "name": "root > install", - "runtimeArgs": ["install"], - "presentation": { "group": "1" }, - // Defaults below - "runtimeVersion": "21.7.0", - "type": "node", - "request": "launch", - "runtimeExecutable": "pnpm", - "console": "integratedTerminal", - "outputCapture": "std", - "autoAttachChildProcesses": false - }, { "name": "root > lint", "runtimeArgs": ["lint"], @@ -215,7 +202,7 @@ "autoAttachChildProcesses": false }, { - "name": "shared > clean", + "name": "@org/shared: clean", "runtimeArgs": ["run", "--filter", "shared", "clean"], "presentation": { "group": "5" }, // Defaults below @@ -228,7 +215,7 @@ "autoAttachChildProcesses": false }, { - "name": "shared > build", + "name": "@org/shared: build", "runtimeArgs": ["run", "shared:build"], "presentation": { "group": "5" }, // Defaults below @@ -241,7 +228,7 @@ "autoAttachChildProcesses": false }, { - "name": "shared > test", + "name": "@org/shared: test", "runtimeArgs": ["run", "--filter", "shared", "test"], "presentation": { "group": "5" }, // Defaults below diff --git a/package.json b/package.json index d1555cfc..67c5b6a7 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,8 @@ "name": "mern-monorepo-starter", "version": "0.0.1", "description": "mern-monorepo-starter description", + "author": "Bruno Tot", + "license": "MIT", "main": "index.js", "type": "module", "private": true, @@ -18,29 +20,32 @@ "build": "pnpm run -r build", "typedoc": "npx typedoc && npm run script:customizeTypedocOutput", "lint": "npx eslint . --fix", - "backend:build": "pnpm --filter backend run build", - "backend:start": "npm run start --prefix packages/backend", - "shared:build": "npm run build --prefix packages/shared", "script:customizeTypedocOutput": "bash assets/sh/customizeTypedocOutput.sh", "script:writeReadmeMarkdown": "node assets/js/writeReadmeMarkdown.js", - "script:printRepoTreeStructure": "bash assets/sh/printRepoTreeStructure.sh" + "script:printRepoTreeStructure": "bash assets/sh/printRepoTreeStructure.sh", + "backend:build": "npm run build --prefix packages/backend", + "backend:test": "npm run test --prefix packages/backend", + "backend:start": "npm run start --prefix packages/backend", + "frontend:build": "npm run build --prefix packages/frontend", + "frontend:test": "npm run test --prefix packages/frontend", + "frontend:start": "npm run start --prefix packages/frontend", + "shared:build": "npm run build --prefix packages/shared", + "shared:test": "npm run test --prefix packages/shared" }, - "author": "Bruno Tot", - "license": "MIT", "devDependencies": { - "@types/express-session": "^1.18.0", + "@typescript-eslint/eslint-plugin": "^7.0.2", + "@typescript-eslint/parser": "^7.0.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.5", + "eslint": "^8.56.0", + "@types/jest": "^29.5.12", "cross-dirname": "^0.1.0", "markdown-toc": "^1.2.0", "prettier": "^3.2.5", - "ts-node": "^10.9.2", "tsc-alias": "^1.8.8", "typedoc": "^0.26.6", "typedoc-github-theme": "^0.1.2", - "typedoc-material-theme": "^1.0.2", - "typedoc-plugin-custom-tags": "^1.0.2", - "typedoc-plugin-merge-modules": "^6.0.0", - "typedoc-plugin-remove-references": "^0.0.6", - "typedoc-theme-hierarchy": "^4.0.0" + "typedoc-plugin-remove-references": "^0.0.6" }, "keywords": [ "monorepo", @@ -52,15 +57,5 @@ "mongodb", "express", "node" - ], - "dependencies": { - "axios": "^1.6.8", - "express-session": "^1.18.0", - "glob": "^11.0.0", - "helmet": "^7.1.0", - "helmet-csp": "^4.0.0", - "keycloak-connect": "^25.0.2", - "memorystore": "^1.6.7", - "react-use": "^17.5.0" - } + ] } diff --git a/packages/backend/package.json b/packages/backend/package.json index 7978bc08..4decdb09 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -15,6 +15,8 @@ "author": "Bruno Tot", "license": "MIT", "dependencies": { + "keycloak-connect": "^25.0.2", + "axios": "^1.6.8", "@org/shared": "workspace:*", "@ts-rest/core": "^3.45.0", "@ts-rest/express": "^3.45.0", @@ -29,7 +31,6 @@ "dotenv": "^16.4.5", "express": "^4.18.2", "flatted": "^3.3.1", - "glob": "^11.0.0", "helmet": "^7.1.0", "hpp": "^0.2.3", "jsonwebtoken": "^9.0.2", @@ -40,9 +41,11 @@ "winston": "^3.11.0", "winston-daily-rotate-file": "^5.0.0", "zod": "^3.22.5", - "express-session": "^1.18.0" + "express-session": "^1.18.0", + "memorystore": "^1.6.7" }, "devDependencies": { + "@types/express-session": "^1.18.0", "@babel/preset-env": "^7.24.5", "@types/bcrypt": "^5.0.2", "@types/body-parser": "^1.19.5", @@ -64,7 +67,6 @@ "nodemon": "^3.1.4", "supertest": "^7.0.0", "ts-jest": "^29.1.2", - "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", "tsconfig-paths-jest": "^0.0.1", "tsx": "^4.9.3", diff --git a/packages/backend/src/ExpressApp.ts b/packages/backend/src/ExpressApp.ts index 59df5408..9e5ac9a1 100644 --- a/packages/backend/src/ExpressApp.ts +++ b/packages/backend/src/ExpressApp.ts @@ -21,12 +21,12 @@ import { buildMongoClient } from "./config/MongoDB.config"; function getModules() { return { - KeycloakAuthorization, + Authorization: KeycloakAuthorization, UserController, UserRepository, ErrorLogRepository, UserService, - KeycloakRepository, + AuthorizationRepository: KeycloakRepository, } as const satisfies Record TODO>; } diff --git a/packages/backend/src/decorators/contract.ts b/packages/backend/src/decorators/contract.ts index b0923bd3..97bae043 100644 --- a/packages/backend/src/decorators/contract.ts +++ b/packages/backend/src/decorators/contract.ts @@ -33,7 +33,7 @@ export function contract(ErrorLogRepository.name) .insertOne(typedError.content); - return { status: 500, body: typedError.content }; + return { status: typedError.content.status, body: typedError.content }; } finally { session.endSession(); } diff --git a/packages/backend/src/infrastructure/middleware/global/withKeycloak.ts b/packages/backend/src/infrastructure/middleware/global/withKeycloak.ts index e80d1ac8..f76784d0 100644 --- a/packages/backend/src/infrastructure/middleware/global/withKeycloak.ts +++ b/packages/backend/src/infrastructure/middleware/global/withKeycloak.ts @@ -4,9 +4,8 @@ import { type RouteMiddlewareFactory } from "@org/backend/config/Route.config"; import { iocRegistry } from "@org/backend/setup/registry.setup"; -import { KeycloakAuthorization } from "@org/backend/infrastructure/security/KeycloakAuthorization"; import { type Authorization } from "@org/backend/interface/Authorization"; export const withKeycloak: RouteMiddlewareFactory = () => { - return iocRegistry.inject(KeycloakAuthorization.name).middleware(); + return iocRegistry.inject("Authorization").middleware(); }; diff --git a/packages/backend/src/infrastructure/middleware/withSecured.ts b/packages/backend/src/infrastructure/middleware/withSecured.ts index e585db3f..ae115152 100644 --- a/packages/backend/src/infrastructure/middleware/withSecured.ts +++ b/packages/backend/src/infrastructure/middleware/withSecured.ts @@ -2,10 +2,10 @@ import type { NextFunction, Request, RequestHandler, Response } from "express"; import { ErrorResponse } from "@org/shared"; import jwt from "jsonwebtoken"; import { iocRegistry } from "@org/backend/setup/registry.setup"; -import { KeycloakRepository } from "../repository/impl/KeycloakRepository"; -import { KeycloakAuthorization } from "@org/backend/infrastructure/security/KeycloakAuthorization"; import { getTypedError } from "@org/shared"; import { type Authorization } from "@org/backend/interface/Authorization"; +import { type AuthorizationRepository } from "@org/backend/interface/AuthorizationRepository"; +import { env } from "@org/backend/setup/env.setup"; export type KeycloakRole = "admin" | "user"; @@ -20,7 +20,7 @@ export function withSecured(...roles: KeycloakRole[]): RequestHandler[] { const flattenedRoles = roles.flat(); const roleSecuredMiddleware: RequestHandler = async (req, res, next) => { - if (flattenedRoles.length === 0) { + if (flattenedRoles.length === 0 || env.NODE_ENV === "test") { next(); return; } @@ -30,7 +30,7 @@ export function withSecured(...roles: KeycloakRole[]): RequestHandler[] { const token = bearerToken.split(" ")[1]; const { sub: userId } = jwt.decode(token) as KeycloakTokenData; const roles = await iocRegistry - .inject(KeycloakRepository.name) + .inject("AuthorizationRepository") .findRolesByUserId(userId); const hasRole = flattenedRoles.some(role => roles.includes(role)); @@ -40,16 +40,18 @@ export function withSecured(...roles: KeycloakRole[]): RequestHandler[] { next(); } catch (error: unknown) { + console.log("error in withSecured", error); next(getTypedError(error)); } }; const protect = async (req: Request, res: Response, next: NextFunction) => { try { - const keycloakAuthorization = iocRegistry.inject(KeycloakAuthorization.name); + const keycloakAuthorization = iocRegistry.inject("Authorization"); const handler = keycloakAuthorization.protect(); handler(req, res, next); } catch (error: unknown) { + console.log("Error in keycloak.protect()", error); next(getTypedError(error)); } }; diff --git a/packages/backend/src/infrastructure/repository/impl/KeycloakRepository.ts b/packages/backend/src/infrastructure/repository/impl/KeycloakRepository.ts index 9c7e00a0..b079b0be 100644 --- a/packages/backend/src/infrastructure/repository/impl/KeycloakRepository.ts +++ b/packages/backend/src/infrastructure/repository/impl/KeycloakRepository.ts @@ -1,6 +1,9 @@ import * as KC from "@org/backend/config/Keycloak.config"; import { type AuthorizationRepository } from "@org/backend/interface/AuthorizationRepository"; +// PROBLEM JE STO SE KeycloakRepository svakako pokrene (konstruktor, super.KeycloakDao) a to ne zelimo u testovima +// logika je takva da se svi defaultni instanciraju i tek onda se mergaju mockane instance u jedan objekt + /** * @see {@link https://www.keycloak.org/docs-api/22.0.1/rest-api/index.html Keycloak Admin REST API} documentation. */ diff --git a/packages/backend/src/infrastructure/service/UserService.ts b/packages/backend/src/infrastructure/service/UserService.ts index a6b93499..7cc0266f 100644 --- a/packages/backend/src/infrastructure/service/UserService.ts +++ b/packages/backend/src/infrastructure/service/UserService.ts @@ -3,23 +3,23 @@ import { type PaginationResult } from "@org/shared"; import { type UserRepository } from "@org/backend/infrastructure/repository/impl/UserRepository"; import { type User } from "@org/shared"; import { autowired } from "@org/backend/decorators/autowired"; -import { type KeycloakRepository } from "@org/backend/infrastructure/repository/impl/KeycloakRepository"; +import { type AuthorizationRepository } from "@org/backend/interface/AuthorizationRepository"; import type * as KC from "@org/backend/config/Keycloak.config"; export class UserService { @autowired private userRepository: UserRepository; - @autowired private keycloakRepository: KeycloakRepository; + @autowired private authorizationRepository: AuthorizationRepository; async search(options: Partial): Promise> { return await this.userRepository.findAllPaginated(PaginationOptions.parse(options)); } async findAll(): Promise { - return await this.keycloakRepository.findAllUsers(); + return await this.authorizationRepository.findAllUsers(); } async findOneByUsername(username: string): Promise { - const user = await this.keycloakRepository.findUserByUsername(username); + const user = await this.authorizationRepository.findUserByUsername(username); if (user === null) throw new ErrorResponse(404, "User not found"); return user; } diff --git a/packages/backend/test/__mocks__/KeycloakRepositoryMock.ts b/packages/backend/test/__mocks__/KeycloakRepositoryMock.ts index 7f09ac6b..fe05094f 100644 --- a/packages/backend/test/__mocks__/KeycloakRepositoryMock.ts +++ b/packages/backend/test/__mocks__/KeycloakRepositoryMock.ts @@ -1,11 +1,34 @@ +import { type KeycloakUser } from "../../dist/config/Keycloak.config"; import { type AuthorizationRepository } from "../../dist/interface/AuthorizationRepository"; + export class KeycloakRepositoryMock implements AuthorizationRepository { - async findAll(): Promise<[]> { - return []; + static roles: Record = { + admin: ["admin"], + user: ["user"], + }; + static users: KeycloakUser[] = [ + { + id: "1", + username: "admin", + }, + { + id: "2", + username: "user", + }, + ]; + + async findUserByUsername(username: string): Promise { + return await Promise.resolve( + KeycloakRepositoryMock.users.find(user => user.username === username) ?? null, + ); } // eslint-disable-next-line @typescript-eslint/no-unused-vars - async findRolesById(userId: string): Promise { - return ["admin"]; + async findRolesByUserId(userId: string): Promise { + return await Promise.resolve(KeycloakRepositoryMock.roles[userId] ?? []); + } + + async findAllUsers(): Promise { + return await Promise.resolve(KeycloakRepositoryMock.users); } } diff --git a/packages/backend/test/__mocks__/index.ts b/packages/backend/test/__mocks__/index.ts index 5441043e..3f2975a5 100644 --- a/packages/backend/test/__mocks__/index.ts +++ b/packages/backend/test/__mocks__/index.ts @@ -3,6 +3,6 @@ import { KeycloakAuthorizationMock } from "./KeycloakAuthorizationMock"; import { KeycloakRepositoryMock } from "./KeycloakRepositoryMock"; export default { - KeycloakAuthorization: KeycloakAuthorizationMock, - KeycloakRepository: KeycloakRepositoryMock, + Authorization: KeycloakAuthorizationMock, + AuthorizationRepository: KeycloakRepositoryMock, } as const satisfies Record; diff --git a/packages/backend/test/random.test.ts b/packages/backend/test/random.test.ts index 4671516d..8761d1cd 100644 --- a/packages/backend/test/random.test.ts +++ b/packages/backend/test/random.test.ts @@ -9,15 +9,19 @@ describe("user", () => { it("should return a 404", async () => { const nonExistingUsername = "usernameWhichShouldFail"; const userService = iocRegistry.inject("UserService"); - await supertest(globalThis.expressApp).get(`/users/${nonExistingUsername}`).expect(404); - await userService.deleteByUsername("brunotot"); + await supertest(globalThis.expressApp) + .get(`/users/findOneByUsername?username=${nonExistingUsername}`) + .expect(404); + await userService.deleteByUsername("admin"); }); }); describe("given the user does exist", () => { it("should return a 200 status and the user", async () => { - const existingUsername = "brunotot"; - await supertest(globalThis.expressApp).get(`/users/${existingUsername}`).expect(200); + const existingUsername = "admin"; + await supertest(globalThis.expressApp) + .get(`/users/findOneByUsername?username=${existingUsername}`) + .expect(200); }); }); }); diff --git a/packages/backend/test/user.test.ts b/packages/backend/test/user.test.ts index d215ee64..abda0ff7 100644 --- a/packages/backend/test/user.test.ts +++ b/packages/backend/test/user.test.ts @@ -6,14 +6,18 @@ describe("user", () => { describe("given the user does not exist", () => { it("should return a 404", async () => { const nonExistingUsername = "usernameWhichShouldFail"; - await supertest(globalThis.expressApp).get(`/users/${nonExistingUsername}`).expect(404); + await supertest(globalThis.expressApp) + .get(`/users/findOneByUsername?username=${nonExistingUsername}`) + .expect(404); }); }); describe("given the user does exist", () => { it("should return a 200 status and the user", async () => { - const existingUsername = "brunotot"; - await supertest(globalThis.expressApp).get(`/users/${existingUsername}`).expect(200); + const existingUsername = "admin"; + await supertest(globalThis.expressApp) + .get(`/users/findOneByUsername?username=${existingUsername}`) + .expect(200); }); }); }); diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json index 19a21b14..f8c411d2 100644 --- a/packages/backend/tsconfig.json +++ b/packages/backend/tsconfig.json @@ -1,15 +1,5 @@ { "extends": "../../tsconfig.json", - "ts-node": { - "transpileOnly": true, - "files": true, - // Tell ts-node CLI to install the --loader automatically, explained below - "esm": true, - "compilerOptions": { - "module": "ESNext" - }, - "require": ["tsconfig-paths/register"] - }, "compilerOptions": { "skipLibCheck": true, "outDir": "./dist", diff --git a/packages/backend/tsconfig.prod.json b/packages/backend/tsconfig.prod.json index fe2b645a..911f85e1 100644 --- a/packages/backend/tsconfig.prod.json +++ b/packages/backend/tsconfig.prod.json @@ -1,15 +1,5 @@ { "extends": "../../tsconfig.json", - "ts-node": { - "transpileOnly": true, - "files": true, - // Tell ts-node CLI to install the --loader automatically, explained below - "esm": true, - "compilerOptions": { - "module": "ESNext" - }, - "require": ["tsconfig-paths/register"] - }, "compilerOptions": { "skipLibCheck": true, "esModuleInterop": true, diff --git a/packages/frontend/.eslintrc b/packages/frontend/.eslintrc index 586c5f1a..72028774 100644 --- a/packages/frontend/.eslintrc +++ b/packages/frontend/.eslintrc @@ -2,6 +2,7 @@ "root": true, "env": { "browser": true, "es2020": true }, "extends": [ + "../../.eslintrc", "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react-hooks/recommended" diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 3c60b5b5..d420d63d 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -9,9 +9,9 @@ "debug": "vite --mode debug", "dev": "vite", "build": "tsc && vite build --emptyOutDir", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "lint": "npx eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "start": "serve -s dist", - "loadTranslationTypes": "i18next-resources-for-ts interface -i ./public/locales/en -o ./src/@types/resources.d.ts" + "loadTranslationTypes": "i18next-resources-for-ts interface -i ./src/public/locales/en -o ./src/@types/resources.d.ts" }, "dependencies": { "@emotion/react": "^11.11.4", @@ -43,12 +43,7 @@ "@preact/signals-react-transform": "^0.3.1", "@types/react": "^18.2.56", "@types/react-dom": "^18.2.19", - "@typescript-eslint/eslint-plugin": "^7.0.2", - "@typescript-eslint/parser": "^7.0.2", "@vitejs/plugin-react": "^4.2.1", - "eslint": "^8.56.0", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.5", "i18next-resources-for-ts": "^1.5.0", "locize-cli": "^8.0.0", "serve": "^14.2.1", diff --git a/packages/shared/package.json b/packages/shared/package.json index 08c7cd88..5af2836d 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -9,7 +9,7 @@ "prepublishOnly": "pnpm run build", "build": "npm run clean && tsc", "clean": "rm -rf ./dist", - "test": "echo \"Error: no test specified for shared package\"" + "test": "npm run build --silent && vitest --run" }, "keywords": [], "author": "Bruno Tot", @@ -23,6 +23,7 @@ }, "devDependencies": { "rimraf": "^5.0.5", - "typescript": "^5.3.3" + "typescript": "^5.3.3", + "vitest": "^1.6.0" } } diff --git a/packages/shared/test/contracts.test.ts b/packages/shared/test/contracts.test.ts new file mode 100644 index 00000000..cd404976 --- /dev/null +++ b/packages/shared/test/contracts.test.ts @@ -0,0 +1,24 @@ +/// + +import { contracts, type TODO } from "../dist/src"; + +describe("contracts", () => { + describe("given the contracts have valid values filled", () => { + it("should not throw error", async () => { + const localContracts = contracts; + const controllers: TODO = Object.values(localContracts); + const routes: TODO = Object.values(controllers) + .map((r: TODO) => Object.values(r)) + .flat(); + routes.forEach((route: TODO) => { + expect(route.strictStatusCodes).toBe(true); + expect(route.metadata.openApiTags[0]).toBeDefined(); + expect(route.method).toBeDefined(); + expect(route.summary).toBeDefined(); + expect(route.description).toBeDefined(); + expect(Object.keys(route.responses).length > 0).toBe(true); + }); + // + }); + }); +}); diff --git a/packages/shared/test/setup/globalSetup.ts b/packages/shared/test/setup/globalSetup.ts new file mode 100644 index 00000000..cc12314a --- /dev/null +++ b/packages/shared/test/setup/globalSetup.ts @@ -0,0 +1 @@ +export const TEST_PORT = 8888; diff --git a/packages/shared/vitest.config.js b/packages/shared/vitest.config.js new file mode 100644 index 00000000..748703e6 --- /dev/null +++ b/packages/shared/vitest.config.js @@ -0,0 +1,22 @@ +import { defineConfig } from "vitest/config"; +import { TEST_PORT } from "./test/setup/globalSetup"; + +export default defineConfig({ + server: { + port: TEST_PORT, + }, + build: { + target: "ES6", + }, + test: { + globals: true, + environment: "node", + //globalSetup: "test/setup/globalSetup.ts", + //setupFiles: ["test/setup/setupFiles.ts"], + }, + resolve: { + alias: { + //"@org/backend/*": new URL("./dist/*", import.meta.url).pathname, + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c1586bfd..f17aabf9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,47 +7,34 @@ settings: importers: .: - dependencies: - axios: - specifier: ^1.6.8 - version: 1.7.4 - express-session: - specifier: ^1.18.0 - version: 1.18.0 - glob: - specifier: ^11.0.0 - version: 11.0.0 - helmet: - specifier: ^7.1.0 - version: 7.1.0 - helmet-csp: - specifier: ^4.0.0 - version: 4.0.0 - keycloak-connect: - specifier: ^25.0.2 - version: 25.0.2 - memorystore: - specifier: ^1.6.7 - version: 1.6.7 - react-use: - specifier: ^17.5.0 - version: 17.5.0(react-dom@18.3.1)(react@18.3.1) devDependencies: - '@types/express-session': - specifier: ^1.18.0 - version: 1.18.0 + '@types/jest': + specifier: ^29.5.12 + version: 29.5.12 + '@typescript-eslint/eslint-plugin': + specifier: ^7.0.2 + version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^7.0.2 + version: 7.8.0(eslint@8.57.0)(typescript@5.4.5) cross-dirname: specifier: ^0.1.0 version: 0.1.0 + eslint: + specifier: ^8.56.0 + version: 8.57.0 + eslint-plugin-react-hooks: + specifier: ^4.6.0 + version: 4.6.2(eslint@8.57.0) + eslint-plugin-react-refresh: + specifier: ^0.4.5 + version: 0.4.6(eslint@8.57.0) markdown-toc: specifier: ^1.2.0 version: 1.2.0 prettier: specifier: ^3.2.5 version: 3.2.5 - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@20.12.12)(typescript@5.4.5) tsc-alias: specifier: ^1.8.8 version: 1.8.8 @@ -57,21 +44,9 @@ importers: typedoc-github-theme: specifier: ^0.1.2 version: 0.1.2(typedoc@0.26.6) - typedoc-material-theme: - specifier: ^1.0.2 - version: 1.0.2(typedoc@0.26.6) - typedoc-plugin-custom-tags: - specifier: ^1.0.2 - version: 1.0.2(typedoc@0.26.6) - typedoc-plugin-merge-modules: - specifier: ^6.0.0 - version: 6.0.0(typedoc@0.26.6) typedoc-plugin-remove-references: specifier: ^0.0.6 version: 0.0.6 - typedoc-theme-hierarchy: - specifier: ^4.0.0 - version: 4.1.2(typedoc@0.26.6) packages/backend: dependencies: @@ -87,6 +62,9 @@ importers: '@ts-rest/open-api': specifier: ^3.45.0 version: 3.45.2(zod@3.23.6) + axios: + specifier: ^1.6.8 + version: 1.7.4 bcrypt: specifier: ^5.1.1 version: 5.1.1 @@ -120,9 +98,6 @@ importers: flatted: specifier: ^3.3.1 version: 3.3.1 - glob: - specifier: ^11.0.0 - version: 11.0.0 helmet: specifier: ^7.1.0 version: 7.1.0 @@ -132,6 +107,12 @@ importers: jsonwebtoken: specifier: ^9.0.2 version: 9.0.2 + keycloak-connect: + specifier: ^25.0.2 + version: 25.0.2 + memorystore: + specifier: ^1.6.7 + version: 1.6.7 mongodb: specifier: ^6.5.0 version: 6.6.0 @@ -175,6 +156,9 @@ importers: '@types/express': specifier: ^4.17.21 version: 4.17.21 + '@types/express-session': + specifier: ^1.18.0 + version: 1.18.0 '@types/hpp': specifier: ^0.2.6 version: 0.2.6 @@ -204,7 +188,7 @@ importers: version: 29.7.0(@babel/core@7.24.5) jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.12.8)(ts-node@10.9.2) + version: 29.7.0(@types/node@20.12.8) mongodb-memory-server: specifier: ^9.2.0 version: 9.2.0 @@ -217,9 +201,6 @@ importers: ts-jest: specifier: ^29.1.2 version: 29.1.2(@babel/core@7.24.5)(babel-jest@29.7.0)(jest@29.7.0)(typescript@5.4.5) - ts-node: - specifier: ^10.9.2 - version: 10.9.2(@types/node@20.12.8)(typescript@5.4.5) tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 @@ -323,24 +304,9 @@ importers: '@types/react-dom': specifier: ^18.2.19 version: 18.3.0 - '@typescript-eslint/eslint-plugin': - specifier: ^7.0.2 - version: 7.8.0(@typescript-eslint/parser@7.8.0)(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/parser': - specifier: ^7.0.2 - version: 7.8.0(eslint@8.57.0)(typescript@5.4.5) '@vitejs/plugin-react': specifier: ^4.2.1 version: 4.2.1(vite@5.2.11) - eslint: - specifier: ^8.56.0 - version: 8.57.0 - eslint-plugin-react-hooks: - specifier: ^4.6.0 - version: 4.6.2(eslint@8.57.0) - eslint-plugin-react-refresh: - specifier: ^0.4.5 - version: 0.4.6(eslint@8.57.0) i18next-resources-for-ts: specifier: ^1.5.0 version: 1.5.0 @@ -355,7 +321,7 @@ importers: version: 5.4.5 vite: specifier: ^5.1.4 - version: 5.2.11(@types/node@20.12.12) + version: 5.2.11(@types/node@20.12.8) packages/shared: dependencies: @@ -381,6 +347,9 @@ importers: typescript: specifier: ^5.3.3 version: 5.4.5 + vitest: + specifier: ^1.6.0 + version: 1.6.0(@types/node@20.12.8) packages: @@ -1674,13 +1643,6 @@ packages: engines: {node: '>=0.1.90'} dev: false - /@cspotcode/source-map-support@0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true - /@dabh/diagnostics@2.0.3: resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} dependencies: @@ -2112,6 +2074,7 @@ packages: strip-ansi-cjs: /strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true /@istanbuljs/load-nyc-config@1.1.0: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} @@ -2141,7 +2104,7 @@ packages: slash: 3.0.0 dev: true - /@jest/core@29.7.0(ts-node@10.9.2): + /@jest/core@29.7.0: resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -2162,7 +2125,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.12.8)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.8) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -2372,13 +2335,6 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@jridgewell/trace-mapping@0.3.9: - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /@js.properties/properties@0.5.4: resolution: {integrity: sha512-4M/Mb2CxzuI1CtQhVFs6OC9ceuGPAP6SOWnpLcrdB1TcUHroXbsYDVJNOm32koRMfuCoRACbojcm4dPPcQxu0w==} dev: true @@ -2405,10 +2361,6 @@ packages: - supports-color dev: false - /@material/material-color-utilities@0.2.7: - resolution: {integrity: sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==} - dev: true - /@mongodb-js/saslprep@1.1.6: resolution: {integrity: sha512-jqTTXQ46H8cAxmXBu8wm1HTSIMBMrIcoVrsjdQkKdMBj3il/fSCgWyya4P2I1xjPBl69mw+nRphrPlcIqBd20Q==} dependencies: @@ -2708,6 +2660,7 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} requiresBuild: true + dev: true optional: true /@popperjs/core@2.11.8: @@ -2971,22 +2924,6 @@ packages: react: 18.3.1 dev: false - /@tsconfig/node10@1.0.11: - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - dev: true - - /@tsconfig/node12@1.0.11: - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - - /@tsconfig/node14@1.0.3: - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - - /@tsconfig/node16@1.0.4: - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - dev: true - /@types/babel__core@7.20.5: resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} dependencies: @@ -3162,6 +3099,8 @@ packages: requiresBuild: true dependencies: undici-types: 5.26.5 + dev: false + optional: true /@types/node@20.12.8: resolution: {integrity: sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==} @@ -3390,7 +3329,7 @@ packages: debug: 4.3.4(supports-color@5.5.0) globby: 11.1.0 is-glob: 4.0.3 - minimatch: 9.0.4 + minimatch: 9.0.5 semver: 7.6.0 ts-api-utils: 1.3.0(typescript@5.4.5) typescript: 5.4.5 @@ -3440,7 +3379,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.5) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.2.11(@types/node@20.12.12) + vite: 5.2.11(@types/node@20.12.8) transitivePeerDependencies: - supports-color dev: true @@ -3589,6 +3528,7 @@ packages: /ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} + dev: true /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} @@ -3601,6 +3541,7 @@ packages: engines: {node: '>=8'} dependencies: color-convert: 2.0.1 + dev: true /ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} @@ -3610,6 +3551,7 @@ packages: /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + dev: true /ansi-wrap@0.1.0: resolution: {integrity: sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==} @@ -3640,10 +3582,6 @@ packages: readable-stream: 3.6.2 dev: false - /arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - /arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} dev: true @@ -3953,6 +3891,7 @@ packages: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.2 + dev: true /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -4459,7 +4398,7 @@ packages: yaml: 1.10.2 dev: false - /create-jest@29.7.0(@types/node@20.12.8)(ts-node@10.9.2): + /create-jest@29.7.0(@types/node@20.12.8): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -4468,7 +4407,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.12.8)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.8) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -4478,10 +4417,6 @@ packages: - ts-node dev: true - /create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - /cross-dirname@0.1.0: resolution: {integrity: sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==} @@ -4500,6 +4435,7 @@ packages: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + dev: true /css-in-js-utils@3.1.0: resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} @@ -4680,11 +4616,6 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true - /diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - dev: true - /diff@5.2.0: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} @@ -4743,6 +4674,7 @@ packages: /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true /ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} @@ -4780,6 +4712,7 @@ packages: /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true /enabled@2.0.0: resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} @@ -5348,6 +5281,7 @@ packages: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 + dev: true /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} @@ -5375,15 +5309,6 @@ packages: engines: {node: '>= 0.6'} dev: false - /fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} - engines: {node: '>=14.14'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - dev: true - /fs-extra@11.2.0: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} @@ -5533,19 +5458,6 @@ packages: path-scurry: 1.10.2 dev: true - /glob@11.0.0: - resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==} - engines: {node: 20 || >=22} - hasBin: true - dependencies: - foreground-child: 3.1.1 - jackspeak: 4.0.1 - minimatch: 10.0.1 - minipass: 7.1.2 - package-json-from-dist: 1.0.0 - path-scurry: 2.0.0 - dev: false - /glob@7.1.6: resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} deprecated: Glob versions prior to v9 are no longer supported @@ -5668,11 +5580,6 @@ packages: dependencies: function-bind: 1.1.2 - /helmet-csp@4.0.0: - resolution: {integrity: sha512-fNQk70QffZk4lKP6sY545UUjFv7IjZ45qWB2zaDx2rtxXJHORI4hxYTMTE2Awn+EqDWdlllatafmN5Wk7E71hQ==} - engines: {node: '>=18.0.0'} - dev: false - /helmet@7.1.0: resolution: {integrity: sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==} engines: {node: '>=16.0.0'} @@ -6051,6 +5958,7 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true /isobject@2.1.0: resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} @@ -6132,15 +6040,6 @@ packages: '@pkgjs/parseargs': 0.11.0 dev: true - /jackspeak@4.0.1: - resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==} - engines: {node: 20 || >=22} - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - dev: false - /jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6179,7 +6078,7 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@20.12.8)(ts-node@10.9.2): + /jest-cli@29.7.0(@types/node@20.12.8): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -6189,14 +6088,14 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) + '@jest/core': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.12.8)(ts-node@10.9.2) + create-jest: 29.7.0(@types/node@20.12.8) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.12.8)(ts-node@10.9.2) + jest-config: 29.7.0(@types/node@20.12.8) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -6207,7 +6106,7 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@20.12.8)(ts-node@10.9.2): + /jest-config@29.7.0(@types/node@20.12.8): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -6242,7 +6141,6 @@ packages: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 - ts-node: 10.9.2(@types/node@20.12.8)(typescript@5.4.5) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -6531,7 +6429,7 @@ packages: supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@20.12.8)(ts-node@10.9.2): + /jest@29.7.0(@types/node@20.12.8): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -6541,10 +6439,10 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2) + '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.12.8)(ts-node@10.9.2) + jest-cli: 29.7.0(@types/node@20.12.8) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -6618,10 +6516,13 @@ packages: /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + requiresBuild: true dependencies: universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 + dev: false + optional: true /jsonwebtoken@9.0.2: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} @@ -6970,11 +6871,6 @@ packages: engines: {node: 14 || >=16.14} dev: true - /lru-cache@11.0.0: - resolution: {integrity: sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==} - engines: {node: 20 || >=22} - dev: false - /lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} dependencies: @@ -7193,13 +7089,6 @@ packages: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} dev: false - /minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} - engines: {node: 20 || >=22} - dependencies: - brace-expansion: 2.0.1 - dev: false - /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -7240,11 +7129,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dev: true - /minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - dev: false - /minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -7729,10 +7613,6 @@ packages: dev: false optional: true - /package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - dev: false - /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -7782,6 +7662,7 @@ packages: /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + dev: true /path-key@4.0.0: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} @@ -7799,14 +7680,6 @@ packages: minipass: 7.1.0 dev: true - /path-scurry@2.0.0: - resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} - engines: {node: 20 || >=22} - dependencies: - lru-cache: 11.0.0 - minipass: 7.1.2 - dev: false - /path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: false @@ -8538,10 +8411,12 @@ packages: engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 + dev: true /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + dev: true /shiki@1.14.1: resolution: {integrity: sha512-FujAN40NEejeXdzPt+3sZ3F2dx1U24BY2XTY01+MG8mbxCiA2XukXdcbyMyLAHJ/1AUUnQd1tZlvIjefWWEJeA==} @@ -8569,6 +8444,7 @@ packages: /signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + dev: true /simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -8735,6 +8611,7 @@ packages: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 + dev: true /string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} @@ -8765,6 +8642,7 @@ packages: engines: {node: '>=12'} dependencies: ansi-regex: 6.0.1 + dev: true /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} @@ -9095,7 +8973,7 @@ packages: babel-jest: 29.7.0(@babel/core@7.24.5) bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.12.8)(ts-node@10.9.2) + jest: 29.7.0(@types/node@20.12.8) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -9105,68 +8983,6 @@ packages: yargs-parser: 21.1.1 dev: true - /ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5): - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.12.12 - acorn: 8.11.3 - acorn-walk: 8.3.2 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.4.5 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - - /ts-node@10.9.2(@types/node@20.12.8)(typescript@5.4.5): - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.12.8 - acorn: 8.11.3 - acorn-walk: 8.3.2 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.4.5 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - dev: true - /tsc-alias@1.8.8: resolution: {integrity: sha512-OYUOd2wl0H858NvABWr/BoSKNERw3N9GTi3rHPK8Iv4O1UyUXIrTTOAZNHsjlVpXFOhpJBVARI1s+rzwLivN3Q==} hasBin: true @@ -9267,45 +9083,10 @@ packages: typedoc: 0.26.6(typescript@5.4.5) dev: true - /typedoc-material-theme@1.0.2(typedoc@0.26.6): - resolution: {integrity: sha512-/nH/twYeHrnz5sZaaXzYJ85EOgKqnbl1ivzBKmuEAga1dBsARttwQUTPKAT7XrCPD+rRcoqxuCOdXZ6EGiqRQA==} - engines: {node: '>=18.0.0', npm: '>=8.6.0'} - peerDependencies: - typedoc: ^0.25.3 - dependencies: - '@material/material-color-utilities': 0.2.7 - typedoc: 0.26.6(typescript@5.4.5) - dev: true - - /typedoc-plugin-custom-tags@1.0.2(typedoc@0.26.6): - resolution: {integrity: sha512-/1uYW7lS7VkBPKlSlYG0C94zhX01UuIgV0Th/k0W48vV34Qh/eLlKyS2B5dIRkRtQYJy/oNKuL+6wErRUDgY1w==} - peerDependencies: - typedoc: '>=0.15.0 <1.0' - dependencies: - typedoc: 0.26.6(typescript@5.4.5) - dev: true - - /typedoc-plugin-merge-modules@6.0.0(typedoc@0.26.6): - resolution: {integrity: sha512-SzxoA45hUHtI4Het+ggjrauRL+4qgRNZ+2NVh4hXeLbZx/Tzb2qhaxcLero7pwGNMcsXc2IzFKokF09ZAlluRw==} - peerDependencies: - typedoc: 0.26.x - dependencies: - typedoc: 0.26.6(typescript@5.4.5) - dev: true - /typedoc-plugin-remove-references@0.0.6: resolution: {integrity: sha512-QoyHpopznnJbWW/9JT2NHSK+eTmyShkPYebwe5ZnO8aohPLc5okk4puWUDXnNh2Tn7cJU8U3t1tEMO6ghbwE8Q==} dev: true - /typedoc-theme-hierarchy@4.1.2(typedoc@0.26.6): - resolution: {integrity: sha512-X3H+zaDkg7wLNoaPJoqXs3rnMfZ9BZjmlXRwplWDciaPfn2hojHxJJ+yVKdqqmojgiHJgg7MYWGDVpOfNlOJ5A==} - peerDependencies: - typedoc: ^0.24.0 || ^0.25.0 - dependencies: - fs-extra: 11.1.1 - typedoc: 0.26.6(typescript@5.4.5) - dev: true - /typedoc@0.26.6(typescript@5.4.5): resolution: {integrity: sha512-SfEU3SH3wHNaxhFPjaZE2kNl/NFtLNW5c1oHsg7mti7GjmUj1Roq6osBQeMd+F4kL0BoRBBr8gQAuqBlfFu8LA==} engines: {node: '>= 18'} @@ -9376,6 +9157,9 @@ packages: /universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} + requiresBuild: true + dev: false + optional: true /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} @@ -9421,10 +9205,6 @@ packages: engines: {node: '>= 0.4.0'} dev: false - /v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true - /v8-to-istanbul@9.2.0: resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} engines: {node: '>=10.12.0'} @@ -9480,42 +9260,6 @@ packages: - typescript dev: true - /vite@5.2.11(@types/node@20.12.12): - resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - '@types/node': 20.12.12 - esbuild: 0.20.2 - postcss: 8.4.38 - rollup: 4.17.2 - optionalDependencies: - fsevents: 2.3.3 - dev: true - /vite@5.2.11(@types/node@20.12.8): resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -9654,6 +9398,7 @@ packages: hasBin: true dependencies: isexe: 2.0.0 + dev: true /why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} @@ -9728,6 +9473,7 @@ packages: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 + dev: true /wrap-ansi@8.1.0: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} @@ -9736,6 +9482,7 @@ packages: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 + dev: true /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -9851,11 +9598,6 @@ packages: pend: 1.2.0 dev: true - /yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true - /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} diff --git a/tsconfig.json b/tsconfig.json index fee95fd5..4b510a42 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,5 @@ { - "exclude": ["node_modules", "dist"], + "exclude": ["node_modules", "dist", "docs"], "compilerOptions": { "module": "ES6", "target": "ES6", diff --git a/typedoc.json b/typedoc.json index 6e31a6f2..86a265c4 100644 --- a/typedoc.json +++ b/typedoc.json @@ -15,17 +15,5 @@ "entryPoints": ["packages/*"], "entryPointStrategy": "packages", - //"themeColor": "#8787f5"// NEW option of TypeDoc added by this plugin - "mergeModulesMergeMode": "module", - "plugin": [ - "typedoc-github-theme", - "typedoc-plugin-remove-references", - "typedoc-plugin-merge-modules" - ] - - // "entryPoints": ["../packages/backend/src", "../packages/frontend/src", "../packages/shared/src"], - // "exclude": ["../packages/frontend/vite-env"], - // "entryPointStrategy": "expand", - // "plugin": ["typedoc-theme-hierarchy", "typedoc-plugin-remove-references"], - // "theme": "hierarchy" + "plugin": ["typedoc-github-theme", "typedoc-plugin-remove-references"] }