From 8460d0b53576acf0fae4628f2bc651d8309a4612 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Mon, 28 Oct 2024 23:23:10 +0100
Subject: [PATCH 1/7] Worked on http endpoints for dynamic tile loading

---
 src/repositories/tileRepository.ts | 22 ++++++++
 src/repositories/zoneRepository.ts | 46 ----------------
 src/services/zoneService.ts        | 53 +++++++++++++++++++
 src/utilities/http.ts              | 85 +++++++++++++++++++-----------
 src/utilities/utilities.ts         |  3 ++
 src/utilities/zone.ts              |  9 ++++
 6 files changed, 142 insertions(+), 76 deletions(-)
 create mode 100644 src/utilities/utilities.ts
 create mode 100644 src/utilities/zone.ts

diff --git a/src/repositories/tileRepository.ts b/src/repositories/tileRepository.ts
index edbfdb5..f02a8a0 100644
--- a/src/repositories/tileRepository.ts
+++ b/src/repositories/tileRepository.ts
@@ -1,5 +1,8 @@
 import prisma from '../utilities/prisma' // Import the global Prisma instance
 import { Tile } from '@prisma/client'
+import zoneRepository from './zoneRepository'
+import { unduplicateArray } from '../utilities/utilities'
+import { FlattenZoneArray } from '../utilities/zone'
 
 class TileRepository {
   async getById(id: string): Promise<Tile | null> {
@@ -8,9 +11,28 @@ class TileRepository {
     })
   }
 
+  async getByIds(ids: string[]): Promise<Tile[]> {
+    return prisma.tile.findMany({
+      where: {
+        id: {
+          in: ids
+        }
+      }
+    })
+  }
+
   async getAll(): Promise<Tile[]> {
     return prisma.tile.findMany()
   }
+
+  async getByZoneId(zoneId: number): Promise<Tile[]> {
+    const zone = await zoneRepository.getById(zoneId)
+    if (!zone) return []
+
+    const zoneTileArray = unduplicateArray(FlattenZoneArray(JSON.parse(JSON.stringify(zone.tiles))))
+
+    return this.getByIds(zoneTileArray)
+  }
 }
 
 export default new TileRepository()
diff --git a/src/repositories/zoneRepository.ts b/src/repositories/zoneRepository.ts
index c596027..40bbd8c 100644
--- a/src/repositories/zoneRepository.ts
+++ b/src/repositories/zoneRepository.ts
@@ -91,52 +91,6 @@ class ZoneRepository {
       return []
     }
   }
-
-  async getZoneAssets(zone_id: number): Promise<TAsset[]> {
-    const zone = await this.getById(zone_id)
-    if (!zone) return []
-
-    const assets: TAsset[] = []
-
-    // zone.tiles is prisma jsonvalue
-    let tiles = JSON.parse(JSON.stringify(zone.tiles))
-    tiles = [...new Set(tiles.flat())]
-
-    // Add tile assets
-    for (const tile of tiles) {
-      const tileInfo = await tileRepository.getById(tile)
-      if (!tileInfo) continue
-
-      assets.push({
-        key: tileInfo.id,
-        url: '/assets/tiles/' + tileInfo.id + '.png',
-        group: 'tiles',
-        updatedAt: tileInfo?.updatedAt || new Date()
-      })
-    }
-
-    // Add object assets
-    for (const zoneObject of zone.zoneObjects) {
-      if (!zoneObject.object) continue
-
-      assets.push({
-        key: zoneObject.object.id,
-        url: '/assets/objects/' + zoneObject.object.id + '.png',
-        group: 'objects',
-        updatedAt: zoneObject.object.updatedAt || new Date()
-      })
-    }
-
-    // Filter out duplicate assets
-    return assets.reduce((acc: TAsset[], current) => {
-      const x = acc.find((item) => item.key === current.key && item.group === current.group)
-      if (!x) {
-        return acc.concat([current])
-      } else {
-        return acc
-      }
-    }, [])
-  }
 }
 
 export default new ZoneRepository()
diff --git a/src/services/zoneService.ts b/src/services/zoneService.ts
index 0cc4acd..da1e270 100644
--- a/src/services/zoneService.ts
+++ b/src/services/zoneService.ts
@@ -1,4 +1,14 @@
 import prisma from '../utilities/prisma'
+import { TAsset } from '../utilities/types'
+import tileRepository from '../repositories/tileRepository'
+import zoneRepository from '../repositories/zoneRepository'
+import { Object, Zone, ZoneObject } from '@prisma/client'
+
+type getZoneAsetsZoneType = Zone & {
+  zoneObjects: (ZoneObject & {
+    object: Object
+  })[]
+}
 
 class ZoneService {
   async createDemoZone(): Promise<boolean> {
@@ -27,6 +37,49 @@ class ZoneService {
     console.log('Demo zone created.')
     return true
   }
+
+  async getZoneAssets(zone: getZoneAsetsZoneType): Promise<TAsset[]> {
+    const assets: TAsset[] = []
+
+    // zone.tiles is prisma jsonvalue
+    let tiles = JSON.parse(JSON.stringify(zone.tiles))
+    tiles = [...new Set(tiles.flat())]
+
+    // Add tile assets
+    for (const tile of tiles) {
+      const tileInfo = await tileRepository.getById(tile)
+      if (!tileInfo) continue
+
+      assets.push({
+        key: tileInfo.id,
+        url: '/assets/tiles/' + tileInfo.id + '.png',
+        group: 'tiles',
+        updatedAt: tileInfo?.updatedAt || new Date()
+      })
+    }
+
+    // Add object assets
+    for (const zoneObject of zone.zoneObjects) {
+      if (!zoneObject.object) continue
+
+      assets.push({
+        key: zoneObject.object.id,
+        url: '/assets/objects/' + zoneObject.object.id + '.png',
+        group: 'objects',
+        updatedAt: zoneObject.object.updatedAt || new Date()
+      })
+    }
+
+    // Filter out duplicate assets
+    return assets.reduce((acc: TAsset[], current) => {
+      const x = acc.find((item) => item.key === current.key && item.group === current.group)
+      if (!x) {
+        return acc.concat([current])
+      } else {
+        return acc
+      }
+    }, [])
+  }
 }
 
 export default ZoneService
diff --git a/src/utilities/http.ts b/src/utilities/http.ts
index 52cbd63..56ea45d 100644
--- a/src/utilities/http.ts
+++ b/src/utilities/http.ts
@@ -6,7 +6,9 @@ import { loginAccountSchema, registerAccountSchema } from './zodTypes'
 import fs from 'fs'
 import { httpLogger } from './logger'
 import { getPublicPath } from './storage'
-import zoneRepository from '../repositories/zoneRepository'
+import TileRepository from '../repositories/tileRepository'
+import { TAsset } from './types'
+import ZoneRepository from '../repositories/zoneRepository'
 
 async function addHttpRoutes(app: Application) {
   /**
@@ -59,38 +61,61 @@ async function addHttpRoutes(app: Application) {
   })
 
   /**
-   * Get all tiles from a zone as an array of ids
+   * Get all tiles
    * @param req
    * @param res
    */
-  // app.get('/assets/tiles/:zoneId', async (req: Request, res: Response) => {
-  //   const zoneId = req.params.zoneId
-  //
-  //   // Check if zoneId is valid number
-  //   if (!zoneId || parseInt(zoneId) === 0) {
-  //     return res.status(400).json({ message: 'Invalid zone ID' })
-  //   }
-  //
-  //   // Get zone by id
-  //   const zone = await zoneRepository.getById(parseInt(zoneId))
-  //   if (!zone) {
-  //     return res.status(404).json({ message: 'Zone not found' })
-  //   }
-  //
-  //   let tiles = zone.tiles;
-  //
-  //   // Convert to array
-  //   tiles = JSON.parse(JSON.stringify(tiles)) as string[]
-  //
-  //   // Flatten the array
-  //   tiles = [...new Set(tiles.flat())]
-  //
-  //   // Remove duplicates
-  //   tiles = tiles.filter((value, index, self) => self.indexOf(value) === index);
-  //
-  //   // Return the array
-  //   res.json(tiles)
-  // })
+  app.get('/assets/list_tiles', async (req: Request, res: Response) => {
+    // Get all tiles
+    let assets: TAsset[] = []
+    const tiles = await TileRepository.getAll()
+    for (const tile of tiles) {
+      assets.push({
+        key: tile.id,
+        url: '/assets/tiles/' + tile.id + '.png',
+        group: 'tiles',
+        updatedAt: tile.updatedAt
+      })
+    }
+
+    // Return the array
+    res.json(tiles)
+  })
+
+  /**
+   * Get all tiles
+   * @param req
+   * @param res
+   */
+  app.get('/assets/list_tiles/:zoneId', async (req: Request, res: Response) => {
+    const zoneId = req.params.zoneId
+
+    // Check if zoneId is valid number
+    if (!zoneId || parseInt(zoneId) === 0) {
+      return res.status(400).json({ message: 'Invalid zone ID' })
+    }
+
+    // Get zone by id
+    const zone = await ZoneRepository.getById(parseInt(zoneId))
+    if (!zone) {
+      return res.status(404).json({ message: 'Zone not found' })
+    }
+
+    // Get all tiles
+    let assets: TAsset[] = []
+    const tiles = await TileRepository.getByZoneId(parseInt(zoneId))
+    for (const tile of tiles) {
+      assets.push({
+        key: tile.id,
+        url: '/assets/tiles/' + tile.id + '.png',
+        group: 'tiles',
+        updatedAt: tile.updatedAt
+      })
+    }
+
+    // Return the array
+    res.json(tiles)
+  })
 
   /**
    * Get a specific asset
diff --git a/src/utilities/utilities.ts b/src/utilities/utilities.ts
new file mode 100644
index 0000000..fdab9a7
--- /dev/null
+++ b/src/utilities/utilities.ts
@@ -0,0 +1,3 @@
+export function unduplicateArray(array: any[]) {
+  return [...new Set(array.flat())]
+}
\ No newline at end of file
diff --git a/src/utilities/zone.ts b/src/utilities/zone.ts
new file mode 100644
index 0000000..e9c064c
--- /dev/null
+++ b/src/utilities/zone.ts
@@ -0,0 +1,9 @@
+export function FlattenZoneArray(tiles: string[][]) {
+  const normalArray = []
+
+  for (const row of tiles) {
+    normalArray.push(...row)
+  }
+
+  return normalArray
+}
\ No newline at end of file

From f6bac403a2620ca05711f16f33e9ec94d3fc8e0c Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Mon, 28 Oct 2024 23:41:54 +0100
Subject: [PATCH 2/7] Minor changes

---
 src/utilities/http.ts      | 4 ++--
 src/utilities/utilities.ts | 2 +-
 src/utilities/zone.ts      | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/utilities/http.ts b/src/utilities/http.ts
index 56ea45d..f016044 100644
--- a/src/utilities/http.ts
+++ b/src/utilities/http.ts
@@ -79,7 +79,7 @@ async function addHttpRoutes(app: Application) {
     }
 
     // Return the array
-    res.json(tiles)
+    res.json(assets)
   })
 
   /**
@@ -114,7 +114,7 @@ async function addHttpRoutes(app: Application) {
     }
 
     // Return the array
-    res.json(tiles)
+    res.json(assets)
   })
 
   /**
diff --git a/src/utilities/utilities.ts b/src/utilities/utilities.ts
index fdab9a7..e7d776a 100644
--- a/src/utilities/utilities.ts
+++ b/src/utilities/utilities.ts
@@ -1,3 +1,3 @@
 export function unduplicateArray(array: any[]) {
   return [...new Set(array.flat())]
-}
\ No newline at end of file
+}
diff --git a/src/utilities/zone.ts b/src/utilities/zone.ts
index e9c064c..d8d39ec 100644
--- a/src/utilities/zone.ts
+++ b/src/utilities/zone.ts
@@ -6,4 +6,4 @@ export function FlattenZoneArray(tiles: string[][]) {
   }
 
   return normalArray
-}
\ No newline at end of file
+}

From bd04dc2ab8b40d779bfe94d9e1abdee5325d3752 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Wed, 30 Oct 2024 09:34:07 +0100
Subject: [PATCH 3/7] Continuation dynamic asset loading

---
 package-lock.json                  | 12 ++++++------
 src/repositories/zoneRepository.ts |  2 +-
 src/services/zoneService.ts        | 16 ++++++++--------
 src/utilities/http.ts              | 20 ++++++++++----------
 src/utilities/types.ts             |  4 ++--
 5 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 42cbff6..bdc2425 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -719,9 +719,9 @@
       "license": "MIT"
     },
     "node_modules/@types/node": {
-      "version": "20.17.1",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.1.tgz",
-      "integrity": "sha512-j2VlPv1NnwPJbaCNv69FO/1z4lId0QmGvpT41YxitRtWlg96g/j8qcv2RKsLKe2F6OJgyXhupN1Xo17b2m139Q==",
+      "version": "20.17.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.3.tgz",
+      "integrity": "sha512-tSQrmKKatLDGnG92h40GD7FzUt0MjahaHwOME4VAFeeA/Xopayq5qLyQRy7Jg/pjgKIFBXuKcGhJo+UdYG55jQ==",
       "license": "MIT",
       "dependencies": {
         "undici-types": "~6.19.2"
@@ -778,9 +778,9 @@
       }
     },
     "node_modules/acorn": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz",
-      "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+      "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
       "license": "MIT",
       "bin": {
         "acorn": "bin/acorn"
diff --git a/src/repositories/zoneRepository.ts b/src/repositories/zoneRepository.ts
index 40bbd8c..33e55ca 100644
--- a/src/repositories/zoneRepository.ts
+++ b/src/repositories/zoneRepository.ts
@@ -2,7 +2,7 @@ import { Zone, ZoneEventTile, ZoneEventTileType, ZoneObject } from '@prisma/clie
 import prisma from '../utilities/prisma'
 import { ZoneEventTileWithTeleport } from '../socketEvents/zone/characterMove'
 import { appLogger } from '../utilities/logger'
-import { TAsset } from '../utilities/types'
+import { AssetData } from '../utilities/types'
 import tileRepository from './tileRepository'
 
 class ZoneRepository {
diff --git a/src/services/zoneService.ts b/src/services/zoneService.ts
index da1e270..d9abd09 100644
--- a/src/services/zoneService.ts
+++ b/src/services/zoneService.ts
@@ -1,5 +1,5 @@
 import prisma from '../utilities/prisma'
-import { TAsset } from '../utilities/types'
+import { AssetData } from '../utilities/types'
 import tileRepository from '../repositories/tileRepository'
 import zoneRepository from '../repositories/zoneRepository'
 import { Object, Zone, ZoneObject } from '@prisma/client'
@@ -38,8 +38,8 @@ class ZoneService {
     return true
   }
 
-  async getZoneAssets(zone: getZoneAsetsZoneType): Promise<TAsset[]> {
-    const assets: TAsset[] = []
+  async getZoneAssets(zone: getZoneAsetsZoneType): Promise<AssetData[]> {
+    const assets: AssetData[] = []
 
     // zone.tiles is prisma jsonvalue
     let tiles = JSON.parse(JSON.stringify(zone.tiles))
@@ -52,10 +52,10 @@ class ZoneService {
 
       assets.push({
         key: tileInfo.id,
-        url: '/assets/tiles/' + tileInfo.id + '.png',
+        data: '/assets/tiles/' + tileInfo.id + '.png',
         group: 'tiles',
         updatedAt: tileInfo?.updatedAt || new Date()
-      })
+      } as AssetData)
     }
 
     // Add object assets
@@ -64,14 +64,14 @@ class ZoneService {
 
       assets.push({
         key: zoneObject.object.id,
-        url: '/assets/objects/' + zoneObject.object.id + '.png',
+        data: '/assets/objects/' + zoneObject.object.id + '.png',
         group: 'objects',
         updatedAt: zoneObject.object.updatedAt || new Date()
-      })
+      } as AssetData)
     }
 
     // Filter out duplicate assets
-    return assets.reduce((acc: TAsset[], current) => {
+    return assets.reduce((acc: AssetData[], current) => {
       const x = acc.find((item) => item.key === current.key && item.group === current.group)
       if (!x) {
         return acc.concat([current])
diff --git a/src/utilities/http.ts b/src/utilities/http.ts
index f016044..7e84422 100644
--- a/src/utilities/http.ts
+++ b/src/utilities/http.ts
@@ -7,7 +7,7 @@ import fs from 'fs'
 import { httpLogger } from './logger'
 import { getPublicPath } from './storage'
 import TileRepository from '../repositories/tileRepository'
-import { TAsset } from './types'
+import { AssetData } from './types'
 import ZoneRepository from '../repositories/zoneRepository'
 
 async function addHttpRoutes(app: Application) {
@@ -61,21 +61,21 @@ async function addHttpRoutes(app: Application) {
   })
 
   /**
-   * Get all tiles
+   * Get all tiles and serve as AssetData array
    * @param req
    * @param res
    */
   app.get('/assets/list_tiles', async (req: Request, res: Response) => {
     // Get all tiles
-    let assets: TAsset[] = []
+    let assets: AssetData[] = []
     const tiles = await TileRepository.getAll()
     for (const tile of tiles) {
       assets.push({
         key: tile.id,
-        url: '/assets/tiles/' + tile.id + '.png',
+        data: '/assets/tiles/' + tile.id + '.png',
         group: 'tiles',
         updatedAt: tile.updatedAt
-      })
+      } as AssetData)
     }
 
     // Return the array
@@ -83,7 +83,7 @@ async function addHttpRoutes(app: Application) {
   })
 
   /**
-   * Get all tiles
+   * Get all tiles from a zone and serve as AssetData array
    * @param req
    * @param res
    */
@@ -102,15 +102,15 @@ async function addHttpRoutes(app: Application) {
     }
 
     // Get all tiles
-    let assets: TAsset[] = []
+    let assets: AssetData[] = []
     const tiles = await TileRepository.getByZoneId(parseInt(zoneId))
     for (const tile of tiles) {
       assets.push({
         key: tile.id,
-        url: '/assets/tiles/' + tile.id + '.png',
+        data: '/assets/tiles/' + tile.id + '.png',
         group: 'tiles',
         updatedAt: tile.updatedAt
-      })
+      } as AssetData)
     }
 
     // Return the array
@@ -118,7 +118,7 @@ async function addHttpRoutes(app: Application) {
   })
 
   /**
-   * Get a specific asset
+   * Download asset file
    * @param req
    * @param res
    */
diff --git a/src/utilities/types.ts b/src/utilities/types.ts
index 4bd7877..f189633 100644
--- a/src/utilities/types.ts
+++ b/src/utilities/types.ts
@@ -21,9 +21,9 @@ export type ExtendedCharacter = Character & {
   resetMovement: boolean
 }
 
-export type TAsset = {
+export type AssetData = {
   key: string
-  url: string
+  data: string
   group: 'tiles' | 'objects' | 'sprites' | 'sprite_animations' | 'sound' | 'music' | 'ui' | 'font' | 'other'
   updatedAt: Date
   frameCount?: number

From 41c71d59643c4338e75fa950778596aed061cd2a Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Wed, 30 Oct 2024 15:26:39 +0100
Subject: [PATCH 4/7] Added list_sprite_actions http endpoint

---
 src/utilities/http.ts  | 31 +++++++++++++++++++++++++++++++
 src/utilities/types.ts |  1 +
 2 files changed, 32 insertions(+)

diff --git a/src/utilities/http.ts b/src/utilities/http.ts
index 7e84422..0a4524a 100644
--- a/src/utilities/http.ts
+++ b/src/utilities/http.ts
@@ -9,6 +9,7 @@ import { getPublicPath } from './storage'
 import TileRepository from '../repositories/tileRepository'
 import { AssetData } from './types'
 import ZoneRepository from '../repositories/zoneRepository'
+import SpriteRepository from '../repositories/spriteRepository'
 
 async function addHttpRoutes(app: Application) {
   /**
@@ -117,6 +118,36 @@ async function addHttpRoutes(app: Application) {
     res.json(assets)
   })
 
+  app.get('/assets/list_sprite_actions/:spriteId', async (req: Request, res: Response) => {
+    const spriteId = req.params.spriteId
+    // Check if spriteId is valid number
+    if (!spriteId || parseInt(spriteId) === 0) {
+      return res.status(400).json({ message: 'Invalid sprite ID' })
+    }
+    // Get sprite by id
+    const sprite = await SpriteRepository.getById(spriteId)
+    if (!sprite) {
+      return res.status(404).json({ message: 'Sprite not found' })
+    }
+
+    let assets: AssetData[] = []
+    sprite.spriteActions.forEach((spriteAction) => {
+      assets.push({
+        key: sprite.id + '-' + spriteAction.action,
+        data: '/assets/sprites/' + sprite.id + '/' + spriteAction.action + '.png',
+        group: spriteAction.isAnimated ? 'sprite_animations' : 'sprites',
+        updatedAt: sprite.updatedAt,
+        isAnimated: spriteAction.isAnimated,
+        frameCount: JSON.parse(JSON.stringify(spriteAction.sprites)).length,
+        frameWidth: spriteAction.frameWidth,
+        frameHeight: spriteAction.frameHeight
+      })
+    })
+
+    // Return the array
+    res.json(assets)
+  })
+
   /**
    * Download asset file
    * @param req
diff --git a/src/utilities/types.ts b/src/utilities/types.ts
index f189633..8fd0e7c 100644
--- a/src/utilities/types.ts
+++ b/src/utilities/types.ts
@@ -26,6 +26,7 @@ export type AssetData = {
   data: string
   group: 'tiles' | 'objects' | 'sprites' | 'sprite_animations' | 'sound' | 'music' | 'ui' | 'font' | 'other'
   updatedAt: Date
+  isAnimated?: boolean
   frameCount?: number
   frameWidth?: number
   frameHeight?: number

From 1b9db64854aa8d879b24ea25dbadde97d8ce7288 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Thu, 31 Oct 2024 12:31:40 +0100
Subject: [PATCH 5/7] npm update

---
 package-lock.json | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index bdc2425..afa3483 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -719,9 +719,9 @@
       "license": "MIT"
     },
     "node_modules/@types/node": {
-      "version": "20.17.3",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.3.tgz",
-      "integrity": "sha512-tSQrmKKatLDGnG92h40GD7FzUt0MjahaHwOME4VAFeeA/Xopayq5qLyQRy7Jg/pjgKIFBXuKcGhJo+UdYG55jQ==",
+      "version": "20.17.4",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.4.tgz",
+      "integrity": "sha512-Fi1Bj8qTJr4f1FDdHFR7oMlOawEYSzkHNdBJK+aRjcDDNHwEV3jPPjuZP2Lh2QNgXeqzM8Y+U6b6urKAog2rZw==",
       "license": "MIT",
       "dependencies": {
         "undici-types": "~6.19.2"
@@ -1895,9 +1895,9 @@
       "license": "MIT"
     },
     "node_modules/msgpackr": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.0.tgz",
-      "integrity": "sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==",
+      "version": "1.11.1",
+      "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.1.tgz",
+      "integrity": "sha512-P6RWMjddZDjSndqKd5XhmHhpnxohGEj4+55w9tSACji7X/P6gTP/KzYGj7/U2RfE2D3HONS6Y63eGkuFXJEMtA==",
       "license": "MIT",
       "optionalDependencies": {
         "msgpackr-extract": "^3.0.2"

From d0e3c95bb0ad622aba15536947d198a4045b983a Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Sat, 2 Nov 2024 02:18:17 +0100
Subject: [PATCH 6/7] npm update

---
 package-lock.json | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index afa3483..87b353b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -719,9 +719,9 @@
       "license": "MIT"
     },
     "node_modules/@types/node": {
-      "version": "20.17.4",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.4.tgz",
-      "integrity": "sha512-Fi1Bj8qTJr4f1FDdHFR7oMlOawEYSzkHNdBJK+aRjcDDNHwEV3jPPjuZP2Lh2QNgXeqzM8Y+U6b6urKAog2rZw==",
+      "version": "20.17.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.5.tgz",
+      "integrity": "sha512-n8FYY/pRxu496441gIcAQFZPKXbhsd6VZygcq+PTSZ75eMh/Ke0hCAROdUa21qiFqKNsPPYic46yXDO1JGiPBQ==",
       "license": "MIT",
       "dependencies": {
         "undici-types": "~6.19.2"
@@ -926,9 +926,9 @@
       "license": "BSD-3-Clause"
     },
     "node_modules/bullmq": {
-      "version": "5.21.2",
-      "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.21.2.tgz",
-      "integrity": "sha512-LPuNoGaDc5CON2X6h4cJ2iVfd+B+02xubFU+IB/fyJHd+/HqUZRqnlYryUCAuhVHBhUKtA6oyVdJxqSa62i+og==",
+      "version": "5.22.0",
+      "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.22.0.tgz",
+      "integrity": "sha512-nwjJSQt/kpO4bIfAznyKKz3+m5OZ6YSaz2Vg7oNoZWTD5wCnJJJy6b9iWM5QIF0bADhDWyorLCO0hU3de+iKMA==",
       "license": "MIT",
       "dependencies": {
         "cron-parser": "^4.6.0",
@@ -1895,9 +1895,9 @@
       "license": "MIT"
     },
     "node_modules/msgpackr": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.1.tgz",
-      "integrity": "sha512-P6RWMjddZDjSndqKd5XhmHhpnxohGEj4+55w9tSACji7X/P6gTP/KzYGj7/U2RfE2D3HONS6Y63eGkuFXJEMtA==",
+      "version": "1.11.2",
+      "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz",
+      "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==",
       "license": "MIT",
       "optionalDependencies": {
         "msgpackr-extract": "^3.0.2"
@@ -2719,9 +2719,9 @@
       }
     },
     "node_modules/tslib": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz",
-      "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==",
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
       "license": "0BSD"
     },
     "node_modules/type-is": {

From 3f19730bd894a54eb9472cf102792803c8104e75 Mon Sep 17 00:00:00 2001
From: Dennis Postma <dennis@directonline.io>
Date: Sat, 2 Nov 2024 21:26:47 +0100
Subject: [PATCH 7/7] Added param to JSdoc

---
 src/services/userService.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/services/userService.ts b/src/services/userService.ts
index 285d08d..87eba2e 100644
--- a/src/services/userService.ts
+++ b/src/services/userService.ts
@@ -31,6 +31,7 @@ class UserService {
   /**
    * Register user
    * @param username
+   * @param email
    * @param password
    */
   async register(username: string, email: string, password: string): Promise<boolean | User> {