Explorar o código

chore(server) Update NestJs to V9 (#1312)

* chore(server) update nestjs to v9

* remove deadcode

* downgrade local-reverse-geocoder

* Added ignore script

* remove ignore script

* Fixed local-reverse-geocoder to a working version

* Fixed issue with eslint mismatch typescript version

* chore: remove unused package

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
Alex %!s(int64=2) %!d(string=hai) anos
pai
achega
6db541c89b

+ 3 - 1
server/apps/immich/src/main.ts

@@ -24,7 +24,9 @@ async function bootstrap() {
     app.enableCors();
   }
 
-  app.useWebSocketAdapter(new RedisIoAdapter(app));
+  const redisIoAdapter = new RedisIoAdapter(app);
+  await redisIoAdapter.connectToRedis();
+  app.useWebSocketAdapter(redisIoAdapter);
 
   const config = new DocumentBuilder()
     .setTitle('Immich')

+ 17 - 16
server/apps/immich/src/middlewares/redis-io.adapter.middleware.ts

@@ -1,31 +1,32 @@
 import { IoAdapter } from '@nestjs/platform-socket.io';
-import { RedisClient } from 'redis';
+import { createClient } from 'redis';
 import { ServerOptions } from 'socket.io';
-import { createAdapter } from 'socket.io-redis';
+import { createAdapter } from '@socket.io/redis-adapter';
 
 const redisHost = process.env.REDIS_HOSTNAME || 'immich_redis';
 const redisPort = parseInt(process.env.REDIS_PORT || '6379');
 const redisDb = parseInt(process.env.REDIS_DBINDEX || '0');
 const redisPassword = process.env.REDIS_PASSWORD || undefined;
-const redisSocket = process.env.REDIS_SOCKET || undefined;
-// const pubClient = createClient({ url: `redis://${redis_host}:6379` });
-// const subClient = pubClient.duplicate();
+// const redisSocket = process.env.REDIS_SOCKET || undefined;
 
-const pubClient = new RedisClient({
-  host: redisHost,
-  port: redisPort,
-  db: redisDb,
-  password: redisPassword,
-  path: redisSocket,
-});
+export class RedisIoAdapter extends IoAdapter {
+  private adapterConstructor: any;
 
-const subClient = pubClient.duplicate();
-const redisAdapter = createAdapter({ pubClient, subClient });
+  async connectToRedis(): Promise<void> {
+    const pubClient = createClient({
+      url: `redis://${redisHost}:${redisPort}/${redisDb}`,
+      password: redisPassword,
+    });
+    const subClient = pubClient.duplicate();
+
+    await Promise.all([pubClient.connect(), subClient.connect()]);
+
+    this.adapterConstructor = createAdapter(pubClient, subClient);
+  }
 
-export class RedisIoAdapter extends IoAdapter {
   createIOServer(port: number, options?: ServerOptions): any {
     const server = super.createIOServer(port, options);
-    server.adapter(redisAdapter);
+    server.adapter(this.adapterConstructor);
     return server;
   }
 }

+ 3 - 1
server/apps/microservices/src/main.ts

@@ -9,7 +9,9 @@ const logger = new Logger('ImmichMicroservice');
 async function bootstrap() {
   const app = await NestFactory.create(MicroservicesModule);
 
-  app.useWebSocketAdapter(new RedisIoAdapter(app));
+  const redisIoAdapter = new RedisIoAdapter(app);
+  await redisIoAdapter.connectToRedis();
+  app.useWebSocketAdapter(redisIoAdapter);
 
   await app.listen(3002, () => {
     const envName = (process.env.NODE_ENV || 'development').toUpperCase();

+ 75 - 0
server/immich-openapi-specs.json

@@ -4,6 +4,7 @@
     "/user": {
       "get": {
         "operationId": "getAllUsers",
+        "description": "",
         "parameters": [
           {
             "name": "isAll",
@@ -40,6 +41,7 @@
       },
       "post": {
         "operationId": "createUser",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -74,6 +76,7 @@
       },
       "put": {
         "operationId": "updateUser",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -110,6 +113,7 @@
     "/user/info/{userId}": {
       "get": {
         "operationId": "getUserById",
+        "description": "",
         "parameters": [
           {
             "name": "userId",
@@ -140,6 +144,7 @@
     "/user/me": {
       "get": {
         "operationId": "getMyUserInfo",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -166,6 +171,7 @@
     "/user/count": {
       "get": {
         "operationId": "getUserCount",
+        "description": "",
         "parameters": [
           {
             "name": "admin",
@@ -197,6 +203,7 @@
     "/user/{userId}": {
       "delete": {
         "operationId": "deleteUser",
+        "description": "",
         "parameters": [
           {
             "name": "userId",
@@ -232,6 +239,7 @@
     "/user/{userId}/restore": {
       "post": {
         "operationId": "restoreUser",
+        "description": "",
         "parameters": [
           {
             "name": "userId",
@@ -267,6 +275,7 @@
     "/user/profile-image": {
       "post": {
         "operationId": "createProfileImage",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -304,6 +313,7 @@
     "/user/profile-image/{userId}": {
       "get": {
         "operationId": "getProfileImage",
+        "description": "",
         "parameters": [
           {
             "name": "userId",
@@ -334,6 +344,7 @@
     "/api-key": {
       "post": {
         "operationId": "createKey",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -363,6 +374,7 @@
       },
       "get": {
         "operationId": "getKeys",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -387,6 +399,7 @@
     "/api-key/{id}": {
       "get": {
         "operationId": "getKey",
+        "description": "",
         "parameters": [
           {
             "name": "id",
@@ -415,6 +428,7 @@
       },
       "put": {
         "operationId": "updateKey",
+        "description": "",
         "parameters": [
           {
             "name": "id",
@@ -453,6 +467,7 @@
       },
       "delete": {
         "operationId": "deleteKey",
+        "description": "",
         "parameters": [
           {
             "name": "id",
@@ -476,6 +491,7 @@
     "/asset/upload": {
       "post": {
         "operationId": "uploadFile",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -513,6 +529,7 @@
     "/asset/download/{assetId}": {
       "get": {
         "operationId": "downloadFile",
+        "description": "",
         "parameters": [
           {
             "name": "isThumb",
@@ -566,6 +583,7 @@
     "/asset/download-files": {
       "post": {
         "operationId": "downloadFiles",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -602,6 +620,7 @@
     "/asset/download-library": {
       "get": {
         "operationId": "downloadLibrary",
+        "description": "",
         "parameters": [
           {
             "name": "skip",
@@ -637,6 +656,7 @@
     "/asset/file/{assetId}": {
       "get": {
         "operationId": "serveFile",
+        "description": "",
         "parameters": [
           {
             "name": "isThumb",
@@ -690,6 +710,7 @@
     "/asset/thumbnail/{assetId}": {
       "get": {
         "operationId": "getAssetThumbnail",
+        "description": "",
         "parameters": [
           {
             "name": "assetId",
@@ -733,6 +754,7 @@
     "/asset/curated-objects": {
       "get": {
         "operationId": "getCuratedObjects",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -762,6 +784,7 @@
     "/asset/curated-locations": {
       "get": {
         "operationId": "getCuratedLocations",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -791,6 +814,7 @@
     "/asset/search-terms": {
       "get": {
         "operationId": "getAssetSearchTerms",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -820,6 +844,7 @@
     "/asset/search": {
       "post": {
         "operationId": "searchAsset",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -859,6 +884,7 @@
     "/asset/count-by-time-bucket": {
       "post": {
         "operationId": "getAssetCountByTimeBucket",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -895,6 +921,7 @@
     "/asset/count-by-user-id": {
       "get": {
         "operationId": "getAssetCountByUserId",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -959,6 +986,7 @@
       },
       "delete": {
         "operationId": "deleteAsset",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -998,6 +1026,7 @@
     "/asset/time-bucket": {
       "post": {
         "operationId": "getAssetByTimeBucket",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -1232,6 +1261,7 @@
     "/share": {
       "get": {
         "operationId": "getAllSharedLinks",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -1256,6 +1286,7 @@
     "/share/me": {
       "get": {
         "operationId": "getMySharedLink",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -1277,6 +1308,7 @@
     "/share/{id}": {
       "get": {
         "operationId": "getSharedLinkById",
+        "description": "",
         "parameters": [
           {
             "name": "id",
@@ -1305,6 +1337,7 @@
       },
       "delete": {
         "operationId": "removeSharedLink",
+        "description": "",
         "parameters": [
           {
             "name": "id",
@@ -1333,6 +1366,7 @@
       },
       "patch": {
         "operationId": "editSharedLink",
+        "description": "",
         "parameters": [
           {
             "name": "id",
@@ -1373,6 +1407,7 @@
     "/album/count-by-user-id": {
       "get": {
         "operationId": "getAlbumCountByUserId",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -1399,6 +1434,7 @@
     "/album": {
       "post": {
         "operationId": "createAlbum",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -1433,6 +1469,7 @@
       },
       "get": {
         "operationId": "getAllAlbums",
+        "description": "",
         "parameters": [
           {
             "name": "shared",
@@ -1480,6 +1517,7 @@
     "/album/{albumId}/users": {
       "put": {
         "operationId": "addUsersToAlbum",
+        "description": "",
         "parameters": [
           {
             "name": "albumId",
@@ -1525,6 +1563,7 @@
     "/album/{albumId}/assets": {
       "put": {
         "operationId": "addAssetsToAlbum",
+        "description": "",
         "parameters": [
           {
             "name": "albumId",
@@ -1568,6 +1607,7 @@
       },
       "delete": {
         "operationId": "removeAssetFromAlbum",
+        "description": "",
         "parameters": [
           {
             "name": "albumId",
@@ -1613,6 +1653,7 @@
     "/album/{albumId}": {
       "get": {
         "operationId": "getAlbumInfo",
+        "description": "",
         "parameters": [
           {
             "name": "albumId",
@@ -1646,6 +1687,7 @@
       },
       "delete": {
         "operationId": "deleteAlbum",
+        "description": "",
         "parameters": [
           {
             "name": "albumId",
@@ -1672,6 +1714,7 @@
       },
       "patch": {
         "operationId": "updateAlbumInfo",
+        "description": "",
         "parameters": [
           {
             "name": "albumId",
@@ -1717,6 +1760,7 @@
     "/album/{albumId}/user/{userId}": {
       "delete": {
         "operationId": "removeUserFromAlbum",
+        "description": "",
         "parameters": [
           {
             "name": "albumId",
@@ -1753,6 +1797,7 @@
     "/album/{albumId}/download": {
       "get": {
         "operationId": "downloadArchive",
+        "description": "",
         "parameters": [
           {
             "name": "albumId",
@@ -1796,6 +1841,7 @@
     "/album/create-shared-link": {
       "post": {
         "operationId": "createAlbumSharedLink",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -1832,6 +1878,7 @@
     "/tag": {
       "post": {
         "operationId": "create",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -1861,6 +1908,7 @@
       },
       "get": {
         "operationId": "findAll",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -1885,6 +1933,7 @@
     "/tag/{id}": {
       "get": {
         "operationId": "findOne",
+        "description": "",
         "parameters": [
           {
             "name": "id",
@@ -1913,6 +1962,7 @@
       },
       "patch": {
         "operationId": "update",
+        "description": "",
         "parameters": [
           {
             "name": "id",
@@ -1951,6 +2001,7 @@
       },
       "delete": {
         "operationId": "delete",
+        "description": "",
         "parameters": [
           {
             "name": "id",
@@ -1974,6 +2025,7 @@
     "/auth/login": {
       "post": {
         "operationId": "login",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2005,6 +2057,7 @@
     "/auth/admin-sign-up": {
       "post": {
         "operationId": "adminSignUp",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2039,6 +2092,7 @@
     "/auth/validateToken": {
       "post": {
         "operationId": "validateAccessToken",
+        "description": "",
         "parameters": [],
         "responses": {
           "201": {
@@ -2065,6 +2119,7 @@
     "/auth/change-password": {
       "post": {
         "operationId": "changePassword",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2101,6 +2156,7 @@
     "/auth/logout": {
       "post": {
         "operationId": "logout",
+        "description": "",
         "parameters": [],
         "responses": {
           "201": {
@@ -2122,6 +2178,7 @@
     "/oauth/mobile-redirect": {
       "get": {
         "operationId": "mobileRedirect",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -2136,6 +2193,7 @@
     "/oauth/config": {
       "post": {
         "operationId": "generateConfig",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2167,6 +2225,7 @@
     "/oauth/callback": {
       "post": {
         "operationId": "callback",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2198,6 +2257,7 @@
     "/oauth/link": {
       "post": {
         "operationId": "link",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2229,6 +2289,7 @@
     "/oauth/unlink": {
       "post": {
         "operationId": "unlink",
+        "description": "",
         "parameters": [],
         "responses": {
           "201": {
@@ -2251,6 +2312,7 @@
       "post": {
         "operationId": "createDeviceInfo",
         "description": "@deprecated",
+        "deprecated": true,
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2286,6 +2348,7 @@
       "patch": {
         "operationId": "updateDeviceInfo",
         "description": "@deprecated",
+        "deprecated": true,
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2320,6 +2383,7 @@
       },
       "put": {
         "operationId": "upsertDeviceInfo",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2356,6 +2420,7 @@
     "/server-info": {
       "get": {
         "operationId": "getServerInfo",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -2377,6 +2442,7 @@
     "/server-info/ping": {
       "get": {
         "operationId": "pingServer",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -2398,6 +2464,7 @@
     "/server-info/version": {
       "get": {
         "operationId": "getServerVersion",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -2419,6 +2486,7 @@
     "/server-info/stats": {
       "get": {
         "operationId": "getStats",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -2440,6 +2508,7 @@
     "/jobs": {
       "get": {
         "operationId": "getAllJobsStatus",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -2466,6 +2535,7 @@
     "/jobs/{jobId}": {
       "get": {
         "operationId": "getJobStatus",
+        "description": "",
         "parameters": [
           {
             "name": "jobId",
@@ -2499,6 +2569,7 @@
       },
       "put": {
         "operationId": "sendJobCommand",
+        "description": "",
         "parameters": [
           {
             "name": "jobId",
@@ -2544,6 +2615,7 @@
     "/system-config": {
       "get": {
         "operationId": "getConfig",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -2568,6 +2640,7 @@
       },
       "put": {
         "operationId": "updateConfig",
+        "description": "",
         "parameters": [],
         "requestBody": {
           "required": true,
@@ -2604,6 +2677,7 @@
     "/system-config/defaults": {
       "get": {
         "operationId": "getDefaults",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {
@@ -2630,6 +2704,7 @@
     "/system-config/storage-template-options": {
       "get": {
         "operationId": "getStorageTemplateOptions",
+        "description": "",
         "parameters": [],
         "responses": {
           "200": {

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 481 - 357
server/package-lock.json


+ 27 - 28
server/package.json

@@ -34,24 +34,24 @@
     "api:generate": "bash ./bin/generate-open-api.sh"
   },
   "dependencies": {
-    "@nestjs/bull": "^0.5.5",
-    "@nestjs/common": "^8.4.7",
-    "@nestjs/config": "^2.1.0",
-    "@nestjs/core": "^8.4.7",
-    "@nestjs/jwt": "^8.0.1",
-    "@nestjs/mapped-types": "*",
-    "@nestjs/passport": "^8.2.2",
-    "@nestjs/platform-express": "^8.4.7",
-    "@nestjs/platform-socket.io": "^8.4.7",
-    "@nestjs/schedule": "^2.0.1",
-    "@nestjs/swagger": "^5.2.1",
-    "@nestjs/typeorm": "^8.1.4",
-    "@nestjs/websockets": "^8.4.7",
-    "@socket.io/redis-adapter": "^7.1.0",
+    "@nestjs/bull": "^0.6.2",
+    "@nestjs/common": "^9.2.1",
+    "@nestjs/config": "^2.2.0",
+    "@nestjs/core": "^9.2.1",
+    "@nestjs/jwt": "^10.0.1",
+    "@nestjs/mapped-types": "1.2.0",
+    "@nestjs/passport": "^9.0.0",
+    "@nestjs/platform-express": "^9.2.1",
+    "@nestjs/platform-socket.io": "^9.2.1",
+    "@nestjs/schedule": "^2.1.0",
+    "@nestjs/swagger": "^6.1.4",
+    "@nestjs/typeorm": "^9.0.1",
+    "@nestjs/websockets": "^9.2.1",
+    "@socket.io/redis-adapter": "^8.0.1",
     "archiver": "^5.3.1",
     "axios": "^0.26.0",
     "bcrypt": "^5.0.1",
-    "bull": "^4.4.0",
+    "bull": "^4.10.2",
     "class-transformer": "^0.5.1",
     "class-validator": "^0.13.2",
     "cookie-parser": "^1.4.6",
@@ -63,9 +63,10 @@
     "geo-tz": "^7.0.2",
     "handlebars": "^4.7.7",
     "i18n-iso-countries": "^7.5.0",
+    "ioredis": "^5.2.4",
     "jest-when": "^3.5.2",
     "joi": "^17.5.0",
-    "local-reverse-geocoder": "^0.12.5",
+    "local-reverse-geocoder": "0.12.5",
     "lodash": "^4.17.21",
     "luxon": "^3.0.3",
     "mv": "^2.1.1",
@@ -75,22 +76,20 @@
     "passport-custom": "^1.1.1",
     "passport-http-header-strategy": "^1.1.0",
     "passport-jwt": "^4.0.0",
-    "pg": "^8.7.1",
-    "redis": "^3.1.2",
+    "pg": "^8.8.0",
+    "redis": "^4.5.1",
     "reflect-metadata": "^0.1.13",
     "rimraf": "^3.0.2",
     "rxjs": "^7.2.0",
     "sanitize-filename": "^1.6.3",
     "sharp": "^0.28.0",
-    "socket.io-redis": "^6.1.1",
-    "swagger-ui-express": "^4.4.0",
     "systeminformation": "^5.11.0",
-    "typeorm": "^0.3.6"
+    "typeorm": "^0.3.11"
   },
   "devDependencies": {
-    "@nestjs/cli": "^8.2.8",
-    "@nestjs/schematics": "^8.0.11",
-    "@nestjs/testing": "^8.4.7",
+    "@nestjs/cli": "^9.1.8",
+    "@nestjs/schematics": "^9.0.4",
+    "@nestjs/testing": "^9.2.1",
     "@openapitools/openapi-generator-cli": "2.5.1",
     "@types/archiver": "^5.3.1",
     "@types/bcrypt": "^5.0.0",
@@ -109,9 +108,9 @@
     "@types/passport-jwt": "^3.0.6",
     "@types/sharp": "^0.30.2",
     "@types/supertest": "^2.0.11",
-    "@typescript-eslint/eslint-plugin": "^5.0.0",
-    "@typescript-eslint/parser": "^5.0.0",
-    "eslint": "^8.0.1",
+    "@typescript-eslint/eslint-plugin": "^5.48.1",
+    "@typescript-eslint/parser": "^5.48.1",
+    "eslint": "^8.31.0",
     "eslint-config-prettier": "^8.3.0",
     "eslint-plugin-prettier": "^4.0.0",
     "jest": "^27.2.5",
@@ -122,7 +121,7 @@
     "ts-loader": "^9.2.3",
     "ts-node": "^10.0.0",
     "tsconfig-paths": "^3.10.1",
-    "typescript": "^4.3.5"
+    "typescript": "^4.9.4"
   },
   "jest": {
     "clearMocks": true,

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio