From 1fff931941b00e0371e771bb9994d858c44d20c2 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Wed, 13 Sep 2023 22:09:25 -0500 Subject: [PATCH 01/13] =?UTF-8?q?=F0=9F=8C=8A=20Modified=20settings=20mode?= =?UTF-8?q?l=20schema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/settings.model.ts | 23 ++++++---- services/settings.service.ts | 88 ++++++++++++++++++++++++++---------- 2 files changed, 79 insertions(+), 32 deletions(-) diff --git a/models/settings.model.ts b/models/settings.model.ts index 1c11548..a60f75d 100644 --- a/models/settings.model.ts +++ b/models/settings.model.ts @@ -1,21 +1,28 @@ const mongoose = require("mongoose"); const paginate = require("mongoose-paginate-v2"); +const HostSchema = mongoose.Schema({ + _id: false, + username: String, + password: String, + hostname: String, + port: String, + protocol: String, +}); const SettingsScehma = mongoose.Schema({ directConnect: { client: { - host: { - username: String, - password: String, - hostname: String, - port: String, - protocol: String, - }, + host: HostSchema, airDCPPUserSettings: Object, - hubs: Array, }, }, + bittorrent: { + client: { + name: String, + host: HostSchema, + }, + }, }); const Settings = mongoose.model("Settings", SettingsScehma); diff --git a/services/settings.service.ts b/services/settings.service.ts index 9ca5638..cf65ab3 100644 --- a/services/settings.service.ts +++ b/services/settings.service.ts @@ -42,43 +42,83 @@ export default class SettingsService extends Service { params: {}, async handler( ctx: Context<{ - settingsPayload: { - host: object; - airDCPPUserSettings: object; - hubs: []; + settingsPayload?: { + protocol: string; + hostname: string; + port: string; + username: string; + password: string; + _id?: string; + airDCPPUserSettings?: object; + hubs?: []; }; - settingsObjectId: string; + settingsObjectId?: string; + settingsKey: string; }> ) { - console.log("varan bhat", ctx.params); - const { host, airDCPPUserSettings, hubs } = + let query = {}; + const { settingsKey, settingsObjectId } = ctx.params; + const { hostname, protocol, port, username, password } = ctx.params.settingsPayload; - let query = { - host, - airDCPPUserSettings, - hubs, - }; - const keysToUpdate = pickBy(query, identity); - let updateQuery = {}; - map(Object.keys(keysToUpdate), (key) => { - updateQuery[`directConnect.client.${key}`] = - query[key]; - }); + switch (settingsKey) { + case "bittorrent": + console.log( + `Recieved settings for ${settingsKey}, building query...` + ); + query = { + bittorrent: { + client: { + host: { + hostname, + protocol, + port, + username, + password, + }, + name: "qbittorrent", + }, + }, + }; + break; + case "directConnect": + const { hubs, airDCPPUserSettings } = + ctx.params.settingsPayload; + query = { + directConnect: { + client: { + host: { + hostname, + protocol, + port, + username, + password, + }, + hubs, + airDCPPUserSettings, + }, + }, + }; + break; + + default: + return false; + } + const options = { upsert: true, - new: true, setDefaultsOnInsert: true, }; const filter = { - _id: new ObjectId(ctx.params.settingsObjectId), + _id: settingsObjectId, }; - const result = Settings.findOneAndUpdate( - filter, - { $set: updateQuery }, + + const result = await Settings.updateOne( + {}, + query, options ); - + console.log(result); return result; }, }, From 3efdc7c2e225134ca5f49b6ca99820d200417b8e Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Fri, 15 Sep 2023 15:49:13 -0400 Subject: [PATCH 02/13] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20Refactored=20saveSet?= =?UTF-8?q?tings=20endpoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 720 ++++++++++++++++++----------------- services/settings.service.ts | 128 ++++--- 2 files changed, 432 insertions(+), 416 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e8e930..4739bad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -201,44 +201,44 @@ "optional": true }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.398.0.tgz", - "integrity": "sha512-Pr/S1f8R2FsJ8DwBC6g0CSdtZNNV5dMHhlIi+t8YAmCJvP4KT+UhzFjbvQRINlBRLFuGUuP7p5vRcGVELD3+wA==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.410.0.tgz", + "integrity": "sha512-J4iPhXswm66Fsk1x0Kly+PWzBizmms4kkkoAU1sk9n08XfWqNBTyf01mx6/t/X+Yh43p2zaeB/XvUwa0jSsWaQ==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.398.0", - "@aws-sdk/credential-provider-node": "3.398.0", - "@aws-sdk/middleware-host-header": "3.398.0", - "@aws-sdk/middleware-logger": "3.398.0", - "@aws-sdk/middleware-recursion-detection": "3.398.0", - "@aws-sdk/middleware-signing": "3.398.0", - "@aws-sdk/middleware-user-agent": "3.398.0", - "@aws-sdk/types": "3.398.0", - "@aws-sdk/util-endpoints": "3.398.0", - "@aws-sdk/util-user-agent-browser": "3.398.0", - "@aws-sdk/util-user-agent-node": "3.398.0", - "@smithy/config-resolver": "^2.0.5", - "@smithy/fetch-http-handler": "^2.0.5", - "@smithy/hash-node": "^2.0.5", - "@smithy/invalid-dependency": "^2.0.5", - "@smithy/middleware-content-length": "^2.0.5", - "@smithy/middleware-endpoint": "^2.0.5", - "@smithy/middleware-retry": "^2.0.5", - "@smithy/middleware-serde": "^2.0.5", + "@aws-sdk/client-sts": "3.410.0", + "@aws-sdk/credential-provider-node": "3.410.0", + "@aws-sdk/middleware-host-header": "3.410.0", + "@aws-sdk/middleware-logger": "3.410.0", + "@aws-sdk/middleware-recursion-detection": "3.410.0", + "@aws-sdk/middleware-signing": "3.410.0", + "@aws-sdk/middleware-user-agent": "3.410.0", + "@aws-sdk/types": "3.410.0", + "@aws-sdk/util-endpoints": "3.410.0", + "@aws-sdk/util-user-agent-browser": "3.410.0", + "@aws-sdk/util-user-agent-node": "3.410.0", + "@smithy/config-resolver": "^2.0.7", + "@smithy/fetch-http-handler": "^2.1.2", + "@smithy/hash-node": "^2.0.6", + "@smithy/invalid-dependency": "^2.0.6", + "@smithy/middleware-content-length": "^2.0.8", + "@smithy/middleware-endpoint": "^2.0.6", + "@smithy/middleware-retry": "^2.0.9", + "@smithy/middleware-serde": "^2.0.6", "@smithy/middleware-stack": "^2.0.0", - "@smithy/node-config-provider": "^2.0.5", - "@smithy/node-http-handler": "^2.0.5", - "@smithy/protocol-http": "^2.0.5", - "@smithy/smithy-client": "^2.0.5", - "@smithy/types": "^2.2.2", - "@smithy/url-parser": "^2.0.5", + "@smithy/node-config-provider": "^2.0.9", + "@smithy/node-http-handler": "^2.1.2", + "@smithy/protocol-http": "^3.0.2", + "@smithy/smithy-client": "^2.1.3", + "@smithy/types": "^2.3.0", + "@smithy/url-parser": "^2.0.6", "@smithy/util-base64": "^2.0.0", "@smithy/util-body-length-browser": "^2.0.0", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.5", - "@smithy/util-defaults-mode-node": "^2.0.5", + "@smithy/util-defaults-mode-browser": "^2.0.7", + "@smithy/util-defaults-mode-node": "^2.0.9", "@smithy/util-retry": "^2.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" @@ -248,41 +248,41 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.398.0.tgz", - "integrity": "sha512-CygL0jhfibw4kmWXG/3sfZMFNjcXo66XUuPC4BqZBk8Rj5vFoxp1vZeMkDLzTIk97Nvo5J5Bh+QnXKhub6AckQ==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.410.0.tgz", + "integrity": "sha512-MC9GrgwtlOuSL2WS3DRM3dQ/5y+49KSMMJRH6JiEcU5vE0dX/OtEcX+VfEwpi73x5pSfIjm7xnzjzOFx+sQBIg==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.398.0", - "@aws-sdk/middleware-logger": "3.398.0", - "@aws-sdk/middleware-recursion-detection": "3.398.0", - "@aws-sdk/middleware-user-agent": "3.398.0", - "@aws-sdk/types": "3.398.0", - "@aws-sdk/util-endpoints": "3.398.0", - "@aws-sdk/util-user-agent-browser": "3.398.0", - "@aws-sdk/util-user-agent-node": "3.398.0", - "@smithy/config-resolver": "^2.0.5", - "@smithy/fetch-http-handler": "^2.0.5", - "@smithy/hash-node": "^2.0.5", - "@smithy/invalid-dependency": "^2.0.5", - "@smithy/middleware-content-length": "^2.0.5", - "@smithy/middleware-endpoint": "^2.0.5", - "@smithy/middleware-retry": "^2.0.5", - "@smithy/middleware-serde": "^2.0.5", + "@aws-sdk/middleware-host-header": "3.410.0", + "@aws-sdk/middleware-logger": "3.410.0", + "@aws-sdk/middleware-recursion-detection": "3.410.0", + "@aws-sdk/middleware-user-agent": "3.410.0", + "@aws-sdk/types": "3.410.0", + "@aws-sdk/util-endpoints": "3.410.0", + "@aws-sdk/util-user-agent-browser": "3.410.0", + "@aws-sdk/util-user-agent-node": "3.410.0", + "@smithy/config-resolver": "^2.0.7", + "@smithy/fetch-http-handler": "^2.1.2", + "@smithy/hash-node": "^2.0.6", + "@smithy/invalid-dependency": "^2.0.6", + "@smithy/middleware-content-length": "^2.0.8", + "@smithy/middleware-endpoint": "^2.0.6", + "@smithy/middleware-retry": "^2.0.9", + "@smithy/middleware-serde": "^2.0.6", "@smithy/middleware-stack": "^2.0.0", - "@smithy/node-config-provider": "^2.0.5", - "@smithy/node-http-handler": "^2.0.5", - "@smithy/protocol-http": "^2.0.5", - "@smithy/smithy-client": "^2.0.5", - "@smithy/types": "^2.2.2", - "@smithy/url-parser": "^2.0.5", + "@smithy/node-config-provider": "^2.0.9", + "@smithy/node-http-handler": "^2.1.2", + "@smithy/protocol-http": "^3.0.2", + "@smithy/smithy-client": "^2.1.3", + "@smithy/types": "^2.3.0", + "@smithy/url-parser": "^2.0.6", "@smithy/util-base64": "^2.0.0", "@smithy/util-body-length-browser": "^2.0.0", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.5", - "@smithy/util-defaults-mode-node": "^2.0.5", + "@smithy/util-defaults-mode-browser": "^2.0.7", + "@smithy/util-defaults-mode-node": "^2.0.9", "@smithy/util-retry": "^2.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" @@ -292,44 +292,44 @@ } }, "node_modules/@aws-sdk/client-sts": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.398.0.tgz", - "integrity": "sha512-/3Pa9wLMvBZipKraq3AtbmTfXW6q9kyvhwOno64f1Fz7kFb8ijQFMGoATS70B2pGEZTlxkUqJFWDiisT6Q6dFg==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.410.0.tgz", + "integrity": "sha512-e6VMrBJtnTxxUXwDmkADGIvyppmDMFf4+cGGA68tVCUm1cFNlCI6M/67bVSIPN/WVKAAfhEL5O2vVXCM7aatYg==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/credential-provider-node": "3.398.0", - "@aws-sdk/middleware-host-header": "3.398.0", - "@aws-sdk/middleware-logger": "3.398.0", - "@aws-sdk/middleware-recursion-detection": "3.398.0", - "@aws-sdk/middleware-sdk-sts": "3.398.0", - "@aws-sdk/middleware-signing": "3.398.0", - "@aws-sdk/middleware-user-agent": "3.398.0", - "@aws-sdk/types": "3.398.0", - "@aws-sdk/util-endpoints": "3.398.0", - "@aws-sdk/util-user-agent-browser": "3.398.0", - "@aws-sdk/util-user-agent-node": "3.398.0", - "@smithy/config-resolver": "^2.0.5", - "@smithy/fetch-http-handler": "^2.0.5", - "@smithy/hash-node": "^2.0.5", - "@smithy/invalid-dependency": "^2.0.5", - "@smithy/middleware-content-length": "^2.0.5", - "@smithy/middleware-endpoint": "^2.0.5", - "@smithy/middleware-retry": "^2.0.5", - "@smithy/middleware-serde": "^2.0.5", + "@aws-sdk/credential-provider-node": "3.410.0", + "@aws-sdk/middleware-host-header": "3.410.0", + "@aws-sdk/middleware-logger": "3.410.0", + "@aws-sdk/middleware-recursion-detection": "3.410.0", + "@aws-sdk/middleware-sdk-sts": "3.410.0", + "@aws-sdk/middleware-signing": "3.410.0", + "@aws-sdk/middleware-user-agent": "3.410.0", + "@aws-sdk/types": "3.410.0", + "@aws-sdk/util-endpoints": "3.410.0", + "@aws-sdk/util-user-agent-browser": "3.410.0", + "@aws-sdk/util-user-agent-node": "3.410.0", + "@smithy/config-resolver": "^2.0.7", + "@smithy/fetch-http-handler": "^2.1.2", + "@smithy/hash-node": "^2.0.6", + "@smithy/invalid-dependency": "^2.0.6", + "@smithy/middleware-content-length": "^2.0.8", + "@smithy/middleware-endpoint": "^2.0.6", + "@smithy/middleware-retry": "^2.0.9", + "@smithy/middleware-serde": "^2.0.6", "@smithy/middleware-stack": "^2.0.0", - "@smithy/node-config-provider": "^2.0.5", - "@smithy/node-http-handler": "^2.0.5", - "@smithy/protocol-http": "^2.0.5", - "@smithy/smithy-client": "^2.0.5", - "@smithy/types": "^2.2.2", - "@smithy/url-parser": "^2.0.5", + "@smithy/node-config-provider": "^2.0.9", + "@smithy/node-http-handler": "^2.1.2", + "@smithy/protocol-http": "^3.0.2", + "@smithy/smithy-client": "^2.1.3", + "@smithy/types": "^2.3.0", + "@smithy/url-parser": "^2.0.6", "@smithy/util-base64": "^2.0.0", "@smithy/util-body-length-browser": "^2.0.0", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.5", - "@smithy/util-defaults-mode-node": "^2.0.5", + "@smithy/util-defaults-mode-browser": "^2.0.7", + "@smithy/util-defaults-mode-node": "^2.0.9", "@smithy/util-retry": "^2.0.0", "@smithy/util-utf8": "^2.0.0", "fast-xml-parser": "4.2.5", @@ -340,15 +340,15 @@ } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.398.0.tgz", - "integrity": "sha512-MFUhy1YayHg5ypRTk4OTfDumQRP+OJBagaGv14kA8DzhKH1sNrU4HV7A7y2J4SvkN5hG/KnLJqxpakCtB2/O2g==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.410.0.tgz", + "integrity": "sha512-2QMvdnwnYsKnwy8O+o9ozKL80VFWI0skXVvKB3DFW4cr9IX5cBCx7xuhI7TXbCqiBxuz5SSiA1s19fVtq0sUmw==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.398.0", - "@aws-sdk/types": "3.398.0", + "@aws-sdk/client-cognito-identity": "3.410.0", + "@aws-sdk/types": "3.410.0", "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -356,14 +356,14 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.398.0.tgz", - "integrity": "sha512-Z8Yj5z7FroAsR6UVML+XUdlpoqEe9Dnle8c2h8/xWwIC2feTfIBhjLhRVxfbpbM1pLgBSNEcZ7U8fwq5l7ESVQ==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.410.0.tgz", + "integrity": "sha512-c7TB9LbN0PkFOsXI0lcRJnqPNOmc4VBvrHf8jP/BkTDg4YUoKQKOFd4d0SqzODmlZiAyoMQVZTR4ISZo95Zj4Q==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", + "@aws-sdk/types": "3.410.0", "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -371,20 +371,20 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.398.0.tgz", - "integrity": "sha512-AsK1lStK3nB9Cn6S6ODb1ktGh7SRejsNVQVKX3t5d3tgOaX+aX1Iwy8FzM/ZEN8uCloeRifUGIY9uQFygg5mSw==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.410.0.tgz", + "integrity": "sha512-D8rcr5bRCFD0f42MPQ7K6TWZq5d3pfqrKINL1/bpfkK5BJbvq1BGYmR88UC6CLpTRtZ1LHY2HgYG0fp/2zjjww==", "optional": true, "dependencies": { - "@aws-sdk/credential-provider-env": "3.398.0", - "@aws-sdk/credential-provider-process": "3.398.0", - "@aws-sdk/credential-provider-sso": "3.398.0", - "@aws-sdk/credential-provider-web-identity": "3.398.0", - "@aws-sdk/types": "3.398.0", + "@aws-sdk/credential-provider-env": "3.410.0", + "@aws-sdk/credential-provider-process": "3.410.0", + "@aws-sdk/credential-provider-sso": "3.410.0", + "@aws-sdk/credential-provider-web-identity": "3.410.0", + "@aws-sdk/types": "3.410.0", "@smithy/credential-provider-imds": "^2.0.0", "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -392,21 +392,21 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.398.0.tgz", - "integrity": "sha512-odmI/DSKfuWUYeDnGTCEHBbC8/MwnF6yEq874zl6+owoVv0ZsYP8qBHfiJkYqrwg7wQ7Pi40sSAPC1rhesGwzg==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.410.0.tgz", + "integrity": "sha512-0wmVm33T/j1FS7MZ/j+WsPlgSc0YnCXnpbWSov1Mn6R86SHI2b2JhdIPRRE4XbGfyW2QGNUl2CwoZVaqhXeF5g==", "optional": true, "dependencies": { - "@aws-sdk/credential-provider-env": "3.398.0", - "@aws-sdk/credential-provider-ini": "3.398.0", - "@aws-sdk/credential-provider-process": "3.398.0", - "@aws-sdk/credential-provider-sso": "3.398.0", - "@aws-sdk/credential-provider-web-identity": "3.398.0", - "@aws-sdk/types": "3.398.0", + "@aws-sdk/credential-provider-env": "3.410.0", + "@aws-sdk/credential-provider-ini": "3.410.0", + "@aws-sdk/credential-provider-process": "3.410.0", + "@aws-sdk/credential-provider-sso": "3.410.0", + "@aws-sdk/credential-provider-web-identity": "3.410.0", + "@aws-sdk/types": "3.410.0", "@smithy/credential-provider-imds": "^2.0.0", "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -414,15 +414,15 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.398.0.tgz", - "integrity": "sha512-WrkBL1W7TXN508PA9wRXPFtzmGpVSW98gDaHEaa8GolAPHMPa5t2QcC/z/cFpglzrcVv8SA277zu9Z8tELdZhg==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.410.0.tgz", + "integrity": "sha512-BMju1hlDCDNkkSZpKF5SQ8G0WCLRj6/Jvw9QmudLHJuVwYJXEW1r2AsVMg98OZ3hB9G+MAvHruHZIbMiNmUMXQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", + "@aws-sdk/types": "3.410.0", "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -430,17 +430,17 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.398.0.tgz", - "integrity": "sha512-2Dl35587xbnzR/GGZqA2MnFs8+kS4wbHQO9BioU0okA+8NRueohNMdrdQmQDdSNK4BfIpFspiZmFkXFNyEAfgw==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.410.0.tgz", + "integrity": "sha512-zEaoY/sY+KYTlQUkp9dvveAHf175b8RIt0DsQkDrRPtrg/RBHR00r5rFvz9+nrwsR8546RaBU7h/zzTaQGhmcA==", "optional": true, "dependencies": { - "@aws-sdk/client-sso": "3.398.0", - "@aws-sdk/token-providers": "3.398.0", - "@aws-sdk/types": "3.398.0", + "@aws-sdk/client-sso": "3.410.0", + "@aws-sdk/token-providers": "3.410.0", + "@aws-sdk/types": "3.410.0", "@smithy/property-provider": "^2.0.0", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -448,14 +448,14 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.398.0.tgz", - "integrity": "sha512-iG3905Alv9pINbQ8/MIsshgqYMbWx+NDQWpxbIW3W0MkSH3iAqdVpSCteYidYX9G/jv2Um1nW3y360ib20bvNg==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.410.0.tgz", + "integrity": "sha512-cE0l8LmEHdWbDkdPNgrfdYSgp4/cIVXrjUKI1QCATA729CrHZ/OQjB/maOBOrMHO9YTiggko887NkslVvwVB7w==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", + "@aws-sdk/types": "3.410.0", "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -463,25 +463,25 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.398.0.tgz", - "integrity": "sha512-355vXmImn2e85mIWSYDVb101AF2lIVHKNCaH6sV1U/8i0ZOXh2cJYNdkRYrxNt1ezDB0k97lSKvuDx7RDvJyRg==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.410.0.tgz", + "integrity": "sha512-QcunzQRNi9dJdAGdduST7itRW+QhDrb9zZHn+HhLKUoVwLrqk1iuH2R9SoEdZg8eV5jR04yoOPdjj1jzdIkFXQ==", "optional": true, "dependencies": { - "@aws-sdk/client-cognito-identity": "3.398.0", - "@aws-sdk/client-sso": "3.398.0", - "@aws-sdk/client-sts": "3.398.0", - "@aws-sdk/credential-provider-cognito-identity": "3.398.0", - "@aws-sdk/credential-provider-env": "3.398.0", - "@aws-sdk/credential-provider-ini": "3.398.0", - "@aws-sdk/credential-provider-node": "3.398.0", - "@aws-sdk/credential-provider-process": "3.398.0", - "@aws-sdk/credential-provider-sso": "3.398.0", - "@aws-sdk/credential-provider-web-identity": "3.398.0", - "@aws-sdk/types": "3.398.0", + "@aws-sdk/client-cognito-identity": "3.410.0", + "@aws-sdk/client-sso": "3.410.0", + "@aws-sdk/client-sts": "3.410.0", + "@aws-sdk/credential-provider-cognito-identity": "3.410.0", + "@aws-sdk/credential-provider-env": "3.410.0", + "@aws-sdk/credential-provider-ini": "3.410.0", + "@aws-sdk/credential-provider-node": "3.410.0", + "@aws-sdk/credential-provider-process": "3.410.0", + "@aws-sdk/credential-provider-sso": "3.410.0", + "@aws-sdk/credential-provider-web-identity": "3.410.0", + "@aws-sdk/types": "3.410.0", "@smithy/credential-provider-imds": "^2.0.0", "@smithy/property-provider": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -489,14 +489,14 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.398.0.tgz", - "integrity": "sha512-m+5laWdBaxIZK2ko0OwcCHJZJ5V1MgEIt8QVQ3k4/kOkN9ICjevOYmba751pHoTnbOYB7zQd6D2OT3EYEEsUcA==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.410.0.tgz", + "integrity": "sha512-ED/OVcyITln5rrxnajZP+V0PN1nug+gSDHJDqdDo/oLy7eiDr/ZWn3nlWW7WcMplQ1/Jnb+hK0UetBp/25XooA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", - "@smithy/protocol-http": "^2.0.5", - "@smithy/types": "^2.2.2", + "@aws-sdk/types": "3.410.0", + "@smithy/protocol-http": "^3.0.2", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -504,13 +504,13 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.398.0.tgz", - "integrity": "sha512-CiJjW+FL12elS6Pn7/UVjVK8HWHhXMfvHZvOwx/Qkpy340sIhkuzOO6fZEruECDTZhl2Wqn81XdJ1ZQ4pRKpCg==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.410.0.tgz", + "integrity": "sha512-YtmKYCVtBfScq3/UFJk+aSZOktKJBNZL9DaSc2aPcy/goCVsYDOkGwtHk0jIkC1JRSNCkVTqL7ya60sSr8zaQQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", - "@smithy/types": "^2.2.2", + "@aws-sdk/types": "3.410.0", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -518,14 +518,14 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.398.0.tgz", - "integrity": "sha512-7QpOqPQAZNXDXv6vsRex4R8dLniL0E/80OPK4PPFsrCh9btEyhN9Begh4i1T+5lL28hmYkztLOkTQ2N5J3hgRQ==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.410.0.tgz", + "integrity": "sha512-KWaes5FLzRqj28vaIEE4Bimpga2E596WdPF2HaH6zsVMJddoRDsc3ZX9ZhLOGrXzIO1RqBd0QxbLrM0S/B2aOQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", - "@smithy/protocol-http": "^2.0.5", - "@smithy/types": "^2.2.2", + "@aws-sdk/types": "3.410.0", + "@smithy/protocol-http": "^3.0.2", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -533,14 +533,14 @@ } }, "node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.398.0.tgz", - "integrity": "sha512-+JH76XHEgfVihkY+GurohOQ5Z83zVN1nYcQzwCFnCDTh4dG4KwhnZKG+WPw6XJECocY0R+H0ivofeALHvVWJtQ==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.410.0.tgz", + "integrity": "sha512-YfBpctDocRR4CcROoDueJA7D+aMLBV8nTFfmVNdLLLgyuLZ/AUR11VQSu1lf9gQZKl8IpKE/BLf2fRE/qV1ZuA==", "optional": true, "dependencies": { - "@aws-sdk/middleware-signing": "3.398.0", - "@aws-sdk/types": "3.398.0", - "@smithy/types": "^2.2.2", + "@aws-sdk/middleware-signing": "3.410.0", + "@aws-sdk/types": "3.410.0", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -548,16 +548,16 @@ } }, "node_modules/@aws-sdk/middleware-signing": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.398.0.tgz", - "integrity": "sha512-O0KqXAix1TcvZBFt1qoFkHMUNJOSgjJTYS7lFTRKSwgsD27bdW2TM2r9R8DAccWFt5Amjkdt+eOwQMIXPGTm8w==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.410.0.tgz", + "integrity": "sha512-KBAZ/eoAJUSJv5us2HsKwK2OszG2s9FEyKpEhgnHLcbbKzW873zHBH5GcOGEQu4AWArTy2ndzJu3FF+9/J9hJQ==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", + "@aws-sdk/types": "3.410.0", "@smithy/property-provider": "^2.0.0", - "@smithy/protocol-http": "^2.0.5", + "@smithy/protocol-http": "^3.0.2", "@smithy/signature-v4": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.0", "@smithy/util-middleware": "^2.0.0", "tslib": "^2.5.0" }, @@ -566,15 +566,15 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.398.0.tgz", - "integrity": "sha512-nF1jg0L+18b5HvTcYzwyFgfZQQMELJINFqI0mi4yRKaX7T5a3aGp5RVLGGju/6tAGTuFbfBoEhkhU3kkxexPYQ==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.410.0.tgz", + "integrity": "sha512-ZayDtLfvCZUohSxQc/49BfoU/y6bDHLfLdyyUJbJ54Sv8zQcrmdyKvCBFUZwE6tHQgAmv9/ZT18xECMl+xiONA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", - "@aws-sdk/util-endpoints": "3.398.0", - "@smithy/protocol-http": "^2.0.5", - "@smithy/types": "^2.2.2", + "@aws-sdk/types": "3.410.0", + "@aws-sdk/util-endpoints": "3.410.0", + "@smithy/protocol-http": "^3.0.2", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -582,43 +582,43 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.398.0.tgz", - "integrity": "sha512-nrYgjzavGCKJL/48Vt0EL+OlIc5UZLfNGpgyUW9cv3XZwl+kXV0QB+HH0rHZZLfpbBgZ2RBIJR9uD5ieu/6hpQ==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.410.0.tgz", + "integrity": "sha512-d5Nc0xydkH/X0LA1HDyhGY5sEv4LuADFk+QpDtT8ogLilcre+b1jpdY8Sih/gd1KoGS1H+d1tz2hSGwUHAbUbw==", "optional": true, "dependencies": { "@aws-crypto/sha256-browser": "3.0.0", "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/middleware-host-header": "3.398.0", - "@aws-sdk/middleware-logger": "3.398.0", - "@aws-sdk/middleware-recursion-detection": "3.398.0", - "@aws-sdk/middleware-user-agent": "3.398.0", - "@aws-sdk/types": "3.398.0", - "@aws-sdk/util-endpoints": "3.398.0", - "@aws-sdk/util-user-agent-browser": "3.398.0", - "@aws-sdk/util-user-agent-node": "3.398.0", - "@smithy/config-resolver": "^2.0.5", - "@smithy/fetch-http-handler": "^2.0.5", - "@smithy/hash-node": "^2.0.5", - "@smithy/invalid-dependency": "^2.0.5", - "@smithy/middleware-content-length": "^2.0.5", - "@smithy/middleware-endpoint": "^2.0.5", - "@smithy/middleware-retry": "^2.0.5", - "@smithy/middleware-serde": "^2.0.5", + "@aws-sdk/middleware-host-header": "3.410.0", + "@aws-sdk/middleware-logger": "3.410.0", + "@aws-sdk/middleware-recursion-detection": "3.410.0", + "@aws-sdk/middleware-user-agent": "3.410.0", + "@aws-sdk/types": "3.410.0", + "@aws-sdk/util-endpoints": "3.410.0", + "@aws-sdk/util-user-agent-browser": "3.410.0", + "@aws-sdk/util-user-agent-node": "3.410.0", + "@smithy/config-resolver": "^2.0.7", + "@smithy/fetch-http-handler": "^2.1.2", + "@smithy/hash-node": "^2.0.6", + "@smithy/invalid-dependency": "^2.0.6", + "@smithy/middleware-content-length": "^2.0.8", + "@smithy/middleware-endpoint": "^2.0.6", + "@smithy/middleware-retry": "^2.0.9", + "@smithy/middleware-serde": "^2.0.6", "@smithy/middleware-stack": "^2.0.0", - "@smithy/node-config-provider": "^2.0.5", - "@smithy/node-http-handler": "^2.0.5", + "@smithy/node-config-provider": "^2.0.9", + "@smithy/node-http-handler": "^2.1.2", "@smithy/property-provider": "^2.0.0", - "@smithy/protocol-http": "^2.0.5", - "@smithy/shared-ini-file-loader": "^2.0.0", - "@smithy/smithy-client": "^2.0.5", - "@smithy/types": "^2.2.2", - "@smithy/url-parser": "^2.0.5", + "@smithy/protocol-http": "^3.0.2", + "@smithy/shared-ini-file-loader": "^2.0.6", + "@smithy/smithy-client": "^2.1.3", + "@smithy/types": "^2.3.0", + "@smithy/url-parser": "^2.0.6", "@smithy/util-base64": "^2.0.0", "@smithy/util-body-length-browser": "^2.0.0", "@smithy/util-body-length-node": "^2.1.0", - "@smithy/util-defaults-mode-browser": "^2.0.5", - "@smithy/util-defaults-mode-node": "^2.0.5", + "@smithy/util-defaults-mode-browser": "^2.0.7", + "@smithy/util-defaults-mode-node": "^2.0.9", "@smithy/util-retry": "^2.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" @@ -628,12 +628,12 @@ } }, "node_modules/@aws-sdk/types": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.398.0.tgz", - "integrity": "sha512-r44fkS+vsEgKCuEuTV+TIk0t0m5ZlXHNjSDYEUvzLStbbfUFiNus/YG4UCa0wOk9R7VuQI67badsvvPeVPCGDQ==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.410.0.tgz", + "integrity": "sha512-D7iaUCszv/v04NDaZUmCmekamy6VD/lKozm/3gS9+dkfU6cC2CsNoUfPV8BlV6dPdw0oWgF91am3I1stdvfVrQ==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -641,12 +641,12 @@ } }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.398.0.tgz", - "integrity": "sha512-Fy0gLYAei/Rd6BrXG4baspCnWTUSd0NdokU1pZh4KlfEAEN1i8SPPgfiO5hLk7+2inqtCmqxVJlfqbMVe9k4bw==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.410.0.tgz", + "integrity": "sha512-iNiqJyC7N3+8zFwnXUqcWSxrZecVZLToo1iTQQdeYL2af1IcOtRgb7n8jpAI/hmXhBSx2+3RI+Y7pxyFo1vu+w==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", + "@aws-sdk/types": "3.410.0", "tslib": "^2.5.0" }, "engines": { @@ -666,26 +666,26 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.398.0.tgz", - "integrity": "sha512-A3Tzx1tkDHlBT+IgxmsMCHbV8LM7SwwCozq2ZjJRx0nqw3MCrrcxQFXldHeX/gdUMO+0Oocb7HGSnVODTq+0EA==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.410.0.tgz", + "integrity": "sha512-i1G/XGpXGMRT2zEiAhi1xucJsfCWk8nNYjk/LbC0sA+7B9Huri96YAzVib12wkHPsJQvZxZC6CpQDIHWm4lXMA==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", - "@smithy/types": "^2.2.2", + "@aws-sdk/types": "3.410.0", + "@smithy/types": "^2.3.0", "bowser": "^2.11.0", "tslib": "^2.5.0" } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.398.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.398.0.tgz", - "integrity": "sha512-RTVQofdj961ej4//fEkppFf4KXqKGMTCqJYghx3G0C/MYXbg7MGl7LjfNGtJcboRE8pfHHQ/TUWBDA7RIAPPlQ==", + "version": "3.410.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.410.0.tgz", + "integrity": "sha512-bK70t1jHRl8HrJXd4hEIwc5PBZ7U0w+81AKFnanIVKZwZedd6nLibUXDTK14z/Jp2GFcBqd4zkt2YLGkRt/U4A==", "optional": true, "dependencies": { - "@aws-sdk/types": "3.398.0", - "@smithy/node-config-provider": "^2.0.5", - "@smithy/types": "^2.2.2", + "@aws-sdk/types": "3.410.0", + "@smithy/node-config-provider": "^2.0.9", + "@smithy/types": "^2.3.0", "tslib": "^2.5.0" }, "engines": { @@ -2318,12 +2318,12 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.5.tgz", - "integrity": "sha512-byVZ2KWLMPYAZGKjRpniAzLcygJO4ruClZKdJTuB0eCB76ONFTdptBHlviHpAZXknRz7skYWPfcgO9v30A1SyA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.0.7.tgz", + "integrity": "sha512-rITz65zk8QA3GQ1OeoJ3/Q4+8j/HqubWU8TBqk57BMYTOX+P+LNMoVHPqzLHhE6qKot5muhThNCYvOKNt7ojJA==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2331,12 +2331,13 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.5.tgz", - "integrity": "sha512-n0c2AXz+kjALY2FQr7Zy9zhYigXzboIh1AuUUVCqFBKFtdEvTwnwPXrTDoEehLiRTUHNL+4yzZ3s+D0kKYSLSg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.0.8.tgz", + "integrity": "sha512-e7mwQteHjo9S1GK+TfzP3o7ujE2ZK30d6wkv5brKtabrZF7MBflj9CwUP2XYuOYebdWirHOtv8ZfkMrpcbJfYw==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/node-config-provider": "^2.0.10", + "@smithy/types": "^2.3.1", "@smithy/util-config-provider": "^2.0.0", "@smithy/util-middleware": "^2.0.0", "tslib": "^2.5.0" @@ -2346,15 +2347,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.5.tgz", - "integrity": "sha512-KFcf/e0meFkQNyteJ65f1G19sgUEY1e5zL7hyAEUPz2SEfBmC9B37WyRq87G3MEEsvmAWwCRu7nFFYUKtR3svQ==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.0.10.tgz", + "integrity": "sha512-may2/gYlDip2rjlU1Z5fcCEWY0Fu3tSu/HykgZrLfb2/171P6OYuz7dGNKBOCS1W57vP4W5wmUhm0WGehrixig==", "optional": true, "dependencies": { - "@smithy/node-config-provider": "^2.0.5", - "@smithy/property-provider": "^2.0.5", - "@smithy/types": "^2.2.2", - "@smithy/url-parser": "^2.0.5", + "@smithy/node-config-provider": "^2.0.10", + "@smithy/property-provider": "^2.0.8", + "@smithy/types": "^2.3.1", + "@smithy/url-parser": "^2.0.7", "tslib": "^2.5.0" }, "engines": { @@ -2362,37 +2363,37 @@ } }, "node_modules/@smithy/eventstream-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.5.tgz", - "integrity": "sha512-iqR6OuOV3zbQK8uVs9o+9AxhVk8kW9NAxA71nugwUB+kTY9C35pUd0A5/m4PRT0Y0oIW7W4kgnSR3fdYXQjECw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.0.7.tgz", + "integrity": "sha512-sW3AhXZhmmhh0f11EOotmNNa0rjrKwnMYNKfbp3B/qigdw6foKcmFGX+HF3XGN7w7fFeEFuXr97Ok24gRj92Xg==", "optional": true, "dependencies": { "@aws-crypto/crc32": "3.0.0", - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "@smithy/util-hex-encoding": "^2.0.0", "tslib": "^2.5.0" } }, "node_modules/@smithy/fetch-http-handler": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.0.5.tgz", - "integrity": "sha512-EzFoMowdBNy1VqtvkiXgPFEdosIAt4/4bgZ8uiDiUyfhmNXq/3bV+CagPFFBsgFOR/X2XK4zFZHRsoa7PNHVVg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.1.3.tgz", + "integrity": "sha512-kUg+Ey4mJeR/3+Ponuhb1rsmsfZRwjCLvC+WcPgeI+ittretEzuWAPN+9anD0HJEoApVjHpndzxPtlncbCUJDQ==", "optional": true, "dependencies": { - "@smithy/protocol-http": "^2.0.5", - "@smithy/querystring-builder": "^2.0.5", - "@smithy/types": "^2.2.2", + "@smithy/protocol-http": "^3.0.3", + "@smithy/querystring-builder": "^2.0.7", + "@smithy/types": "^2.3.1", "@smithy/util-base64": "^2.0.0", "tslib": "^2.5.0" } }, "node_modules/@smithy/hash-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.5.tgz", - "integrity": "sha512-mk551hIywBITT+kXruRNXk7f8Fy7DTzBjZJSr/V6nolYKmUHIG3w5QU6nO9qPYEQGKc/yEPtkpdS28ndeG93lA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.0.7.tgz", + "integrity": "sha512-aB5lvIDP1v+ZUUS8ek3XW5xnZ6jUQ86JXqG7a5jMP6AbjAc3439mIbs6+f1EQ5MtYmrQCEtRRyvv5QofvotH0w==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "@smithy/util-buffer-from": "^2.0.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" @@ -2402,12 +2403,12 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.5.tgz", - "integrity": "sha512-0wEi+JT0hM+UUwrJVYbqjuGFhy5agY/zXyiN7BNAJ1XoCDjU5uaNSj8ekPWsXd/d4yM6NSe8UbPd8cOc1+3oBQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.0.7.tgz", + "integrity": "sha512-qVOZnHFPzQo4BS47/PANHX32Y69c0tJxKBkqTL795D/DKInqBwmBO/m1gS7v0ZQqmtCuoy2l87RflQfRY2xEIw==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" } }, @@ -2424,13 +2425,13 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.5.tgz", - "integrity": "sha512-E7VwV5H02fgZIUGRli4GevBCAPvkyEI/fgl9SU47nPPi3DAAX3nEtUb8xfGbXjOcJ5BdSUoWWZn42tEd/blOqA==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.0.9.tgz", + "integrity": "sha512-2XVFsGqswxrIBi0w4Njwzb1zsbte26U513K+WPFm9z6SB/3WR5/VBVjTaTcamrXznTAqBjTwTL0Ysisv1dW0Rw==", "optional": true, "dependencies": { - "@smithy/protocol-http": "^2.0.5", - "@smithy/types": "^2.2.2", + "@smithy/protocol-http": "^3.0.3", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2438,14 +2439,14 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.5.tgz", - "integrity": "sha512-tyzDuoNTbsMQCq5Xkc4QOt6e2GACUllQIV8SQ5fc59FtOIV9/vbf58/GxVjZm2o8+MMbdDBANjTDZe/ijZKfyA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.0.7.tgz", + "integrity": "sha512-4/L0wV7PzHEprJB0gazSTIwlW/2cCfwC9EHavUMhoCyl1tLer6CJwDbAMit1IMvwbHkwuKopueb8dFPHfpS2Pw==", "optional": true, "dependencies": { - "@smithy/middleware-serde": "^2.0.5", - "@smithy/types": "^2.2.2", - "@smithy/url-parser": "^2.0.5", + "@smithy/middleware-serde": "^2.0.7", + "@smithy/types": "^2.3.1", + "@smithy/url-parser": "^2.0.7", "@smithy/util-middleware": "^2.0.0", "tslib": "^2.5.0" }, @@ -2454,14 +2455,15 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.5.tgz", - "integrity": "sha512-ulIfbFyzQTVnJbLjUl1CTSi0etg6tej/ekwaLp0Gn8ybUkDkKYa+uB6CF/m2J5B6meRwyJlsryR+DjaOVyiicg==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.0.10.tgz", + "integrity": "sha512-VwAQOR5Rh/y9BzUgb5DzUk7qYBiMZu3pEQa5EwwAf/F7lpMuNildGrAxtDmsXk90490FJwa6LyFknXP3kO5BnA==", "optional": true, "dependencies": { - "@smithy/protocol-http": "^2.0.5", + "@smithy/node-config-provider": "^2.0.10", + "@smithy/protocol-http": "^3.0.3", "@smithy/service-error-classification": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "@smithy/util-middleware": "^2.0.0", "@smithy/util-retry": "^2.0.0", "tslib": "^2.5.0", @@ -2481,12 +2483,12 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.5.tgz", - "integrity": "sha512-in0AA5sous74dOfTGU9rMJBXJ0bDVNxwdXtEt5lh3FVd2sEyjhI+rqpLLRF1E4ixbw3RSEf80hfRpcPdjg4vvQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.0.7.tgz", + "integrity": "sha512-tOldis4PUNafdGErLZ+33p9Pf3MmTlLa176X321Z6ZaCf1XNEow9m3T5vXrcHErVAvjPG0mp3l54J94HnPc+rQ==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2506,14 +2508,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.0.5.tgz", - "integrity": "sha512-LRtjV9WkhONe2lVy+ipB/l1GX60ybzBmFyeRUoLUXWKdnZ3o81jsnbKzMK8hKq8eFSWPk+Lmyx6ZzCQabGeLxg==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.0.10.tgz", + "integrity": "sha512-e5MiLH5Eu+BbYsmhZIkvUKCzite6JCBPL75PNjlRK2TWvSpfp19hNf2SiJIQbPalcFj5zlyBvtcEkF1sfYIdhg==", "optional": true, "dependencies": { - "@smithy/property-provider": "^2.0.5", - "@smithy/shared-ini-file-loader": "^2.0.5", - "@smithy/types": "^2.2.2", + "@smithy/property-provider": "^2.0.8", + "@smithy/shared-ini-file-loader": "^2.0.9", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2521,15 +2523,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.0.5.tgz", - "integrity": "sha512-lZm5DZf4b3V0saUw9WTC4/du887P6cy2fUyQgQQKRRV6OseButyD5yTzeMmXE53CaXJBMBsUvvIQ0hRVxIq56w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.1.3.tgz", + "integrity": "sha512-TGkgpx68SqvbspVHaG3iwqP2mKYOT4whiq7Kv2X9v+InngL4MkpH3LQ0Dk7kbloahZr+hAOyb6s8D7T8TXRrzA==", "optional": true, "dependencies": { - "@smithy/abort-controller": "^2.0.5", - "@smithy/protocol-http": "^2.0.5", - "@smithy/querystring-builder": "^2.0.5", - "@smithy/types": "^2.2.2", + "@smithy/abort-controller": "^2.0.7", + "@smithy/protocol-http": "^3.0.3", + "@smithy/querystring-builder": "^2.0.7", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2537,12 +2539,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.5.tgz", - "integrity": "sha512-cAFSUhX6aiHcmpWfrCLKvwBtgN1F6A0N8qY/8yeSi0LRLmhGqsY1/YTxFE185MCVzYbqBGXVr9TBv4RUcIV4rA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.0.8.tgz", + "integrity": "sha512-oaaP/i7bGG8XbxG9Kx4PZh83iJ2jo/vt8RmJdi9hmc8APBaW1HGDperVXDCyPQdVYXmiqrtxc/rPImyBma1G3A==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2550,12 +2552,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-2.0.5.tgz", - "integrity": "sha512-d2hhHj34mA2V86doiDfrsy2fNTnUOowGaf9hKb0hIPHqvcnShU4/OSc4Uf1FwHkAdYF3cFXTrj5VGUYbEuvMdw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.0.3.tgz", + "integrity": "sha512-UGfmQNdijlFV+UzgdRyfe05S5vLDdcdkvNcxhGvQ+Er7TjUkZSxjukQB9VXtT8oTHztgOMX74DDlPBsVzZR5Pg==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2563,12 +2565,12 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.5.tgz", - "integrity": "sha512-4DCX9krxLzATj+HdFPC3i8pb7XTAWzzKqSw8aTZMjXjtQY+vhe4azMAqIvbb6g7JKwIkmkRAjK6EXO3YWSnJVQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.0.7.tgz", + "integrity": "sha512-RPHnqt4iH1Kwp1Zbf4gJI88hZiynEZjE5hEWJNBmKqCe1Q6v7HBLtaovTaiuYaMEmPyb2KxOi3lISAdT6uuPqw==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "@smithy/util-uri-escape": "^2.0.0", "tslib": "^2.5.0" }, @@ -2577,12 +2579,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.5.tgz", - "integrity": "sha512-C2stCULH0r54KBksv3AWcN8CLS3u9+WsEW8nBrvctrJ5rQTNa1waHkffpVaiKvcW2nP0aIMBPCobD/kYf/q9mA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.0.7.tgz", + "integrity": "sha512-Cwi/Hgs73nbLKfgH7dXAxzvDxyTrK+BLrlAd0KXU7xcBR94V132nvxoq39BMWckYAPmnMwxCwq8uusNH4Dnagw==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2599,12 +2601,12 @@ } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.5.tgz", - "integrity": "sha512-Mvtk6FwMtfbKRC4YuSsIqRYp9WTxsSUJVVo2djgyhcacKGMqicHDWSAmgy3sDrKv+G/G6xTZCPwm6pJARtdxVg==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.0.9.tgz", + "integrity": "sha512-vBLgJI+Qpz1TZ0W2kUBOmG2Q+geVEhiXE99UX02+UFag2WzOQ6frvV6rpadwJu0uwF02GG620NbiKGboqZ19YA==", "optional": true, "dependencies": { - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2612,14 +2614,14 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.5.tgz", - "integrity": "sha512-ABIzXmUDXK4n2c9cXjQLELgH2RdtABpYKT+U131e2I6RbCypFZmxIHmIBufJzU2kdMCQ3+thBGDWorAITFW04A==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.0.7.tgz", + "integrity": "sha512-qNCJpyhRWxT5RWmeSo/Zv+miQ60Y/D2JmPdFw7v2WpPVxVK7JDpqUbvq0QYE+dBGPX/uagAkE3NvJUcn0fTE3A==", "optional": true, "dependencies": { - "@smithy/eventstream-codec": "^2.0.5", + "@smithy/eventstream-codec": "^2.0.7", "@smithy/is-array-buffer": "^2.0.0", - "@smithy/types": "^2.2.2", + "@smithy/types": "^2.3.1", "@smithy/util-hex-encoding": "^2.0.0", "@smithy/util-middleware": "^2.0.0", "@smithy/util-uri-escape": "^2.0.0", @@ -2631,14 +2633,14 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.0.5.tgz", - "integrity": "sha512-kCTFr8wfOAWKDzGvfBElc6shHigWtHNhMQ1IbosjC4jOlayFyZMSs2PysKB+Ox/dhQ41KqOzgVjgiQ+PyWqHMQ==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.1.4.tgz", + "integrity": "sha512-KRQvYYjEGqvmwnKSAZ8EL0hZvPxGQMYbAKS/AMGq2fuRmwAlinSVJ/fkIs65bZp2oYjcskd1ZgKcP+2UDjNPTQ==", "optional": true, "dependencies": { "@smithy/middleware-stack": "^2.0.0", - "@smithy/types": "^2.2.2", - "@smithy/util-stream": "^2.0.5", + "@smithy/types": "^2.3.1", + "@smithy/util-stream": "^2.0.10", "tslib": "^2.5.0" }, "engines": { @@ -2646,9 +2648,9 @@ } }, "node_modules/@smithy/types": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.2.2.tgz", - "integrity": "sha512-4PS0y1VxDnELGHGgBWlDksB2LJK8TG8lcvlWxIsgR+8vROI7Ms8h1P4FQUx+ftAX2QZv5g1CJCdhdRmQKyonyw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.3.1.tgz", + "integrity": "sha512-cS48e4Yawb6pGakj7DBJUIPFIkqnUWyXTe2ndPRNagD73b6kEJqTc8bhTyfUve0A+sijK256UKE0J1juAfCeDA==", "optional": true, "dependencies": { "tslib": "^2.5.0" @@ -2658,13 +2660,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.5.tgz", - "integrity": "sha512-OdMBvZhpckQSkugCXNJQCvqJ71wE7Ftxce92UOQLQ9pwF6hoS5PLL7wEfpnuEXtStzBqJYkzu1C1ZfjuFGOXAA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.0.7.tgz", + "integrity": "sha512-SwMl1Lq3yFR2hzhwWYKg04uJHpfcXWMBPycm4Z8GkLI6Dw7rJNDApEbMtujlYw6pVP2WKbrpaGHjQ9MdP92kMQ==", "optional": true, "dependencies": { - "@smithy/querystring-parser": "^2.0.5", - "@smithy/types": "^2.2.2", + "@smithy/querystring-parser": "^2.0.7", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" } }, @@ -2728,13 +2730,13 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.5.tgz", - "integrity": "sha512-yciP6TPttLsj731aHTvekgyuCGXQrEAJibEwEWAh3kzaDsfGAVCuZSBlyvC2Dl3TZmHKCOQwHV8mIE7KQCTPuQ==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.0.8.tgz", + "integrity": "sha512-8znx01mkmfKxhiSB2bOF5eMutuCLMd8m2Kh0ulRp8vgzhwRLDJoU6aHSEUoNptbuTAtiFf4u0gpkYC2XfbWwuA==", "optional": true, "dependencies": { - "@smithy/property-provider": "^2.0.5", - "@smithy/types": "^2.2.2", + "@smithy/property-provider": "^2.0.8", + "@smithy/types": "^2.3.1", "bowser": "^2.11.0", "tslib": "^2.5.0" }, @@ -2743,16 +2745,16 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.5.tgz", - "integrity": "sha512-M07t99rWasXt+IaDZDyP3BkcoEm/mgIE1RIMASrE49LKSNxaVN7PVcgGc77+4uu2kzBAyqJKy79pgtezuknyjQ==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.0.10.tgz", + "integrity": "sha512-QUcUckL4ZqDFVwLnh7zStRUnXtTC6hcJZ4FmMqnxlPcL33Rko0sMQwrMDnMdzF3rS3wvqugAaq3zzop1HCluvw==", "optional": true, "dependencies": { - "@smithy/config-resolver": "^2.0.5", - "@smithy/credential-provider-imds": "^2.0.5", - "@smithy/node-config-provider": "^2.0.5", - "@smithy/property-provider": "^2.0.5", - "@smithy/types": "^2.2.2", + "@smithy/config-resolver": "^2.0.8", + "@smithy/credential-provider-imds": "^2.0.10", + "@smithy/node-config-provider": "^2.0.10", + "@smithy/property-provider": "^2.0.8", + "@smithy/types": "^2.3.1", "tslib": "^2.5.0" }, "engines": { @@ -2797,14 +2799,14 @@ } }, "node_modules/@smithy/util-stream": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.5.tgz", - "integrity": "sha512-ylx27GwI05xLpYQ4hDIfS15vm+wYjNN0Sc2P0FxuzgRe8v0BOLHppGIQ+Bezcynk8C9nUzsUue3TmtRhjut43g==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.0.10.tgz", + "integrity": "sha512-2EgK5cBiv9OaDmhSXmsZY8ZByBl1dg/Tbc51iBJ5GkLGVYhaA6/1l6vHHV41m4Im3D0XfZV1tmeLlQgmRnYsTQ==", "optional": true, "dependencies": { - "@smithy/fetch-http-handler": "^2.0.5", - "@smithy/node-http-handler": "^2.0.5", - "@smithy/types": "^2.2.2", + "@smithy/fetch-http-handler": "^2.1.3", + "@smithy/node-http-handler": "^2.1.3", + "@smithy/types": "^2.3.1", "@smithy/util-base64": "^2.0.0", "@smithy/util-buffer-from": "^2.0.0", "@smithy/util-hex-encoding": "^2.0.0", diff --git a/services/settings.service.ts b/services/settings.service.ts index cf65ab3..2bcaf02 100644 --- a/services/settings.service.ts +++ b/services/settings.service.ts @@ -56,70 +56,84 @@ export default class SettingsService extends Service { settingsKey: string; }> ) { - let query = {}; - const { settingsKey, settingsObjectId } = ctx.params; - const { hostname, protocol, port, username, password } = - ctx.params.settingsPayload; + try { + let query = {}; + const { settingsKey, settingsObjectId } = + ctx.params; + const { + hostname, + protocol, + port, + username, + password, + } = ctx.params.settingsPayload; - switch (settingsKey) { - case "bittorrent": - console.log( - `Recieved settings for ${settingsKey}, building query...` - ); - query = { - bittorrent: { - client: { - host: { - hostname, - protocol, - port, - username, - password, + // Update, depending what key was passed in params + // 1. Construct the update query + switch (settingsKey) { + case "bittorrent": + console.log( + `Recieved settings for ${settingsKey}, building query...` + ); + query = { + bittorrent: { + client: { + host: { + hostname, + protocol, + port, + username, + password, + }, + name: "qbittorrent", }, - name: "qbittorrent", }, - }, - }; - break; - case "directConnect": - const { hubs, airDCPPUserSettings } = - ctx.params.settingsPayload; - query = { - directConnect: { - client: { - host: { - hostname, - protocol, - port, - username, - password, + }; + break; + case "directConnect": + console.log( + `Recieved settings for ${settingsKey}, building query...` + ); + const { hubs, airDCPPUserSettings } = + ctx.params.settingsPayload; + query = { + directConnect: { + client: { + host: { + hostname, + protocol, + port, + username, + password, + }, + hubs, + airDCPPUserSettings, }, - hubs, - airDCPPUserSettings, }, - }, - }; - break; + }; + break; - default: - return false; - } + default: + return false; + } - const options = { - upsert: true, - setDefaultsOnInsert: true, - }; - const filter = { - _id: settingsObjectId, - }; - - const result = await Settings.updateOne( - {}, - query, - options - ); - console.log(result); - return result; + // 2. Set up options, filters + const options = { + upsert: true, + setDefaultsOnInsert: true, + returnDocument: "after", + }; + const filter = { + _id: settingsObjectId, + }; + // 3. Execute the mongo query + const result = await Settings.findOneAndUpdate( + {}, + query, + options + ); + return result; + } catch (err) {} }, }, deleteSettings: { From 1229feb69cb2796e4fe486bf0b72367aee6d168a Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Thu, 9 Nov 2023 10:22:45 -0600 Subject: [PATCH 03/13] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20Refactor=20for=20?= =?UTF-8?q?zustand=20and=20tanstack=20react=20query=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/jobqueue.service.ts | 91 +++++++++++++++++++++++++----------- services/settings.service.ts | 1 + 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/services/jobqueue.service.ts b/services/jobqueue.service.ts index 348e6d8..591665d 100644 --- a/services/jobqueue.service.ts +++ b/services/jobqueue.service.ts @@ -49,9 +49,14 @@ export default class JobQueueService extends Service { rest: "/GET enqueue", handler: async (ctx: Context<{}>) => { // Enqueue the job - const job = await this.localQueue(ctx, "enqueue.async", ctx.params, { - priority: 10, - }); + const job = await this.localQueue( + ctx, + "enqueue.async", + ctx.params, + { + priority: 10, + } + ); console.log(`Job ${job.id} enqueued`); return job.id; @@ -65,13 +70,17 @@ export default class JobQueueService extends Service { }> ) => { try { - console.log(`Recieved Job ID ${ctx.locals.job.id}, processing...`); + console.log( + `Recieved Job ID ${ctx.locals.job.id}, processing...` + ); console.log(ctx.params); // 1. De-structure the job params const { fileObject } = ctx.locals.job.data.params; // 2. Extract metadata from the archive - const result = await extractFromArchive(fileObject.filePath); + const result = await extractFromArchive( + fileObject.filePath + ); const { name, filePath, @@ -84,7 +93,9 @@ export default class JobQueueService extends Service { } = result; // 3a. Infer any issue-related metadata from the filename - const { inferredIssueDetails } = refineQuery(result.name); + const { inferredIssueDetails } = refineQuery( + result.name + ); console.log( "Issue metadata inferred: ", JSON.stringify(inferredIssueDetails, null, 2) @@ -124,7 +135,8 @@ export default class JobQueueService extends Service { // "acquisition.directconnect.downloads": [], // mark the metadata source - "acquisition.source.name": ctx.locals.job.data.params.sourcedFrom, + "acquisition.source.name": + ctx.locals.job.data.params.sourcedFrom, }; // 3c. Add the bundleId, if present to the payload @@ -135,8 +147,13 @@ export default class JobQueueService extends Service { // 3d. Add the sourcedMetadata, if present if ( - !isNil(ctx.locals.job.data.params.sourcedMetadata) && - !isUndefined(ctx.locals.job.data.params.sourcedMetadata.comicvine) + !isNil( + ctx.locals.job.data.params.sourcedMetadata + ) && + !isUndefined( + ctx.locals.job.data.params.sourcedMetadata + .comicvine + ) ) { Object.assign( payload.sourcedMetadata, @@ -145,11 +162,15 @@ export default class JobQueueService extends Service { } // 4. write to mongo - const importResult = await this.broker.call("library.rawImportToDB", { - importType: ctx.locals.job.data.params.importType, - bundleId, - payload, - }); + const importResult = await this.broker.call( + "library.rawImportToDB", + { + importType: + ctx.locals.job.data.params.importType, + bundleId, + payload, + } + ); return { data: { importResult, @@ -161,9 +182,14 @@ export default class JobQueueService extends Service { console.error( `An error occurred processing Job ID ${ctx.locals.job.id}` ); - throw new MoleculerError(error, 500, "IMPORT_JOB_ERROR", { - data: ctx.params.sessionId, - }); + throw new MoleculerError( + error, + 500, + "IMPORT_JOB_ERROR", + { + data: ctx.params.sessionId, + } + ); } }, }, @@ -191,7 +217,8 @@ export default class JobQueueService extends Service { statuses: { $push: { status: "$_id.status", - earliestTimestamp: "$earliestTimestamp", + earliestTimestamp: + "$earliestTimestamp", count: "$count", }, }, @@ -211,7 +238,10 @@ export default class JobQueueService extends Service { { $cond: [ { - $eq: ["$$this.status", "completed"], + $eq: [ + "$$this.status", + "completed", + ], }, "$$this.count", 0, @@ -231,7 +261,10 @@ export default class JobQueueService extends Service { { $cond: [ { - $eq: ["$$this.status", "failed"], + $eq: [ + "$$this.status", + "failed", + ], }, "$$this.count", 0, @@ -260,10 +293,10 @@ export default class JobQueueService extends Service { console.log("Queue drained."); await this.broker.call("socket.broadcast", { namespace: "/", - event: "action", + event: "LS_IMPORT_QUEUE_DRAINED", args: [ { - type: "LS_IMPORT_QUEUE_DRAINED", + message: "drained", }, ], }); @@ -274,14 +307,15 @@ export default class JobQueueService extends Service { // 2. Increment the completed job counter await pubClient.incr("completedJobCount"); // 3. Fetch the completed job count for the final payload to be sent to the client - const completedJobCount = await pubClient.get("completedJobCount"); + const completedJobCount = await pubClient.get( + "completedJobCount" + ); // 4. Emit the LS_COVER_EXTRACTED event with the necessary details await this.broker.call("socket.broadcast", { namespace: "/", - event: "action", + event: "LS_COVER_EXTRACTED", args: [ { - type: "LS_COVER_EXTRACTED", completedJobCount, importResult: job.returnvalue.data.importResult, }, @@ -302,7 +336,9 @@ export default class JobQueueService extends Service { async "enqueue.async.failed"(ctx) { const job = await this.job(ctx.params.id); await pubClient.incr("failedJobCount"); - const failedJobCount = await pubClient.get("failedJobCount"); + const failedJobCount = await pubClient.get( + "failedJobCount" + ); await JobResult.create({ id: ctx.params.id, @@ -315,10 +351,9 @@ export default class JobQueueService extends Service { // 4. Emit the LS_COVER_EXTRACTION_FAILED event with the necessary details await this.broker.call("socket.broadcast", { namespace: "/", - event: "action", + event: "LS_COVER_EXTRACTION_FAILED", args: [ { - type: "LS_COVER_EXTRACTION_FAILED", failedJobCount, importResult: job, }, diff --git a/services/settings.service.ts b/services/settings.service.ts index 2bcaf02..95c5e4e 100644 --- a/services/settings.service.ts +++ b/services/settings.service.ts @@ -57,6 +57,7 @@ export default class SettingsService extends Service { }> ) { try { + console.log(ctx.params); let query = {}; const { settingsKey, settingsObjectId } = ctx.params; From 11fbaf10db0e0bd3126e835b2f462ad2d9ff57f8 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Mon, 13 Nov 2023 16:41:58 -0500 Subject: [PATCH 04/13] =?UTF-8?q?=F0=9F=8F=97=20Wired=20up=20the=20events?= =?UTF-8?q?=20correctly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/socket.service.ts | 172 +++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 83 deletions(-) diff --git a/services/socket.service.ts b/services/socket.service.ts index e48bde5..373aa1d 100644 --- a/services/socket.service.ts +++ b/services/socket.service.ts @@ -26,90 +26,92 @@ export default class SocketService extends Service { "/": { events: { call: { - // whitelist: ["math.*", "say.*", "accounts.*", "rooms.*", "io.*"], + whitelist: ["socket.resumeSession"], }, - action: async (data) => { - switch (data.type) { - case "RESUME_SESSION": - console.log("Attempting to resume session..."); - try { - const sessionRecord = await Session.find({ - sessionId: data.session.sessionId, - }); - // 1. Check for sessionId's existence, and a match - if ( - sessionRecord.length !== 0 && - sessionRecord[0].sessionId === - data.session.sessionId - ) { - // 2. Find if the queue has active jobs - const jobs: JobType = await this.broker.call( - "jobqueue.getJobCountsByType", - {} - ); - const { active } = jobs; - if (active > 0) { - // 3. Get job counts - const completedJobCount = - await pubClient.get( - "completedJobCount" - ); - const failedJobCount = await pubClient.get( - "failedJobCount" - ); - - // 4. Send the counts to the active socket.io session - await this.broker.call("socket.broadcast", { - namespace: "/", - event: "action", - args: [ - { - type: "RESTORE_JOB_COUNTS_AFTER_SESSION_RESTORATION", - completedJobCount, - failedJobCount, - queueStatus: "running", - }, - ], - }); - } - } - } catch (err) { - throw new MoleculerError( - err, - 500, - "SESSION_ID_NOT_FOUND", - { - data: data.session.sessionId, - } - ); - } - - break; - - case "LS_SET_QUEUE_STATUS": - console.log(data); - await this.broker.call( - "jobqueue.toggle", - { action: data.data.queueAction }, - {} - ); - break; - case "LS_SINGLE_IMPORT": - console.info("AirDC++ finished a download -> "); - console.log(data); - await this.broker.call( - "library.importDownloadedComic", - { bundle: data }, - {} - ); - break; - // uncompress archive events - case "COMICBOOK_EXTRACTION_SUCCESS": - console.log(data); - return data; - } - }, + // async (data) => { + // console.log("uldas", data); + // switch (data.type) { + // case "RESUME_SESSION": + // console.log("Attempting to resume session..."); + // try { + // const sessionRecord = await Session.find({ + // sessionId: data.session.sessionId, + // }); + // // 1. Check for sessionId's existence, and a match + // if ( + // sessionRecord.length !== 0 && + // sessionRecord[0].sessionId === + // data.session.sessionId + // ) { + // // 2. Find if the queue has active jobs + // const jobs: JobType = await this.broker.call( + // "jobqueue.getJobCountsByType", + // {} + // ); + // const { active } = jobs; + // + // if (active > 0) { + // // 3. Get job counts + // const completedJobCount = + // await pubClient.get( + // "completedJobCount" + // ); + // const failedJobCount = await pubClient.get( + // "failedJobCount" + // ); + // + // // 4. Send the counts to the active socket.io session + // await this.broker.call("socket.broadcast", { + // namespace: "/", + // event: "action", + // args: [ + // { + // type: "RESTORE_JOB_COUNTS_AFTER_SESSION_RESTORATION", + // completedJobCount, + // failedJobCount, + // queueStatus: "running", + // }, + // ], + // }); + // } + // } + // } catch (err) { + // throw new MoleculerError( + // err, + // 500, + // "SESSION_ID_NOT_FOUND", + // { + // data: data.session.sessionId, + // } + // ); + // } + // + // break; + // + // case "LS_SET_QUEUE_STATUS": + // console.log(data); + // await this.broker.call( + // "jobqueue.toggle", + // { action: data.data.queueAction }, + // {} + // ); + // break; + // case "LS_SINGLE_IMPORT": + // console.info("AirDC++ finished a download -> "); + // console.log(data); + // await this.broker.call( + // "library.importDownloadedComic", + // { bundle: data }, + // {} + // ); + // break; + // // uncompress archive events + // case "COMICBOOK_EXTRACTION_SUCCESS": + // console.log(data); + // return data; + // } + // }, }, }, }, @@ -119,7 +121,11 @@ export default class SocketService extends Service { }, }, hooks: {}, - actions: {}, + actions: { + resumeSession: (ctx: Context<{}>) => { + console.log("aya re", ctx.params); + }, + }, methods: {}, async started() { this.io.on("connection", async (socket) => { From b87b0c875d3a5c3f7317421857574e43a2149bc5 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Mon, 13 Nov 2023 21:18:19 -0500 Subject: [PATCH 05/13] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20Fleshed=20out=20r?= =?UTF-8?q?esumeSession=20event?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/socket.service.ts | 60 ++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/services/socket.service.ts b/services/socket.service.ts index 373aa1d..dba9f4d 100644 --- a/services/socket.service.ts +++ b/services/socket.service.ts @@ -122,8 +122,59 @@ export default class SocketService extends Service { }, hooks: {}, actions: { - resumeSession: (ctx: Context<{}>) => { - console.log("aya re", ctx.params); + resumeSession: async (ctx: Context<{ sessionId: string }>) => { + const { sessionId } = ctx.params; + console.log("asdasdA"); + console.log("Attempting to resume session..."); + try { + const sessionRecord = await Session.find({ + sessionId, + }); + // 1. Check for sessionId's existence, and a match + if ( + sessionRecord.length !== 0 && + sessionRecord[0].sessionId === sessionId + ) { + // 2. Find if the queue has active jobs + const jobs: JobType = await this.broker.call( + "jobqueue.getJobCountsByType", + {} + ); + const { active } = jobs; + + if (active > 0) { + // 3. Get job counts + const completedJobCount = await pubClient.get( + "completedJobCount" + ); + const failedJobCount = await pubClient.get( + "failedJobCount" + ); + + // 4. Send the counts to the active socket.io session + await this.broker.call("socket.broadcast", { + namespace: "/", + event: "RESTORE_JOB_COUNTS_AFTER_SESSION_RESTORATION", + args: [ + { + completedJobCount, + failedJobCount, + queueStatus: "running", + }, + ], + }); + } + } + } catch (err) { + throw new MoleculerError( + err, + 500, + "SESSION_ID_NOT_FOUND", + { + data: sessionId, + } + ); + } }, }, methods: {}, @@ -152,10 +203,7 @@ export default class SocketService extends Service { } // 2. else, retrieve it from Mongo and "resume" the socket.io connection else { - console.log( - `Found socketId ${socket.id}, attempting to resume socket.io connection...` - ); - console.log(socket.handshake.query.sessionId); + console.log(`Found socketId ${socket.id}, no-op.`); } }); }, From b8ca03220f2e0cac803387f237b66417174ff64c Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Mon, 13 Nov 2023 22:01:01 -0500 Subject: [PATCH 06/13] =?UTF-8?q?=F0=9F=8F=97=20Implemented=20setQueueStat?= =?UTF-8?q?us?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/socket.service.ts | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/services/socket.service.ts b/services/socket.service.ts index dba9f4d..64393d9 100644 --- a/services/socket.service.ts +++ b/services/socket.service.ts @@ -124,7 +124,6 @@ export default class SocketService extends Service { actions: { resumeSession: async (ctx: Context<{ sessionId: string }>) => { const { sessionId } = ctx.params; - console.log("asdasdA"); console.log("Attempting to resume session..."); try { const sessionRecord = await Session.find({ @@ -144,12 +143,8 @@ export default class SocketService extends Service { if (active > 0) { // 3. Get job counts - const completedJobCount = await pubClient.get( - "completedJobCount" - ); - const failedJobCount = await pubClient.get( - "failedJobCount" - ); + const completedJobCount = await pubClient.get("completedJobCount"); + const failedJobCount = await pubClient.get("failedJobCount"); // 4. Send the counts to the active socket.io session await this.broker.call("socket.broadcast", { @@ -166,16 +161,20 @@ export default class SocketService extends Service { } } } catch (err) { - throw new MoleculerError( - err, - 500, - "SESSION_ID_NOT_FOUND", - { - data: sessionId, - } - ); + throw new MoleculerError(err, 500, "SESSION_ID_NOT_FOUND", { + data: sessionId, + }); } }, + + setQueueStatus: async (ctx: Context<{}>) => { + console.log(data); + await this.broker.call( + "jobqueue.toggle", + { action: data.data.queueAction }, + {} + ); + }, }, methods: {}, async started() { From c2bbbf311de6d95ff47e46fe23769c0d85e4d727 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Tue, 14 Nov 2023 13:24:49 -0600 Subject: [PATCH 07/13] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20Fixed=20setQueueS?= =?UTF-8?q?tatus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/socket.service.ts | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/services/socket.service.ts b/services/socket.service.ts index 64393d9..43559fa 100644 --- a/services/socket.service.ts +++ b/services/socket.service.ts @@ -26,7 +26,7 @@ export default class SocketService extends Service { "/": { events: { call: { - whitelist: ["socket.resumeSession"], + whitelist: ["socket.*"], }, // async (data) => { @@ -143,8 +143,12 @@ export default class SocketService extends Service { if (active > 0) { // 3. Get job counts - const completedJobCount = await pubClient.get("completedJobCount"); - const failedJobCount = await pubClient.get("failedJobCount"); + const completedJobCount = await pubClient.get( + "completedJobCount" + ); + const failedJobCount = await pubClient.get( + "failedJobCount" + ); // 4. Send the counts to the active socket.io session await this.broker.call("socket.broadcast", { @@ -161,17 +165,27 @@ export default class SocketService extends Service { } } } catch (err) { - throw new MoleculerError(err, 500, "SESSION_ID_NOT_FOUND", { - data: sessionId, - }); + throw new MoleculerError( + err, + 500, + "SESSION_ID_NOT_FOUND", + { + data: sessionId, + } + ); } }, - setQueueStatus: async (ctx: Context<{}>) => { - console.log(data); + setQueueStatus: async ( + ctx: Context<{ + queueAction: string; + queueStatus: string; + }> + ) => { + const { queueAction } = ctx.params; await this.broker.call( "jobqueue.toggle", - { action: data.data.queueAction }, + { action: queueAction }, {} ); }, From 7b0c0a7420128e0ccf772a905c43c4804be712fc Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Wed, 15 Nov 2023 15:59:27 -0600 Subject: [PATCH 08/13] =?UTF-8?q?=E2=9E=95=20Added=20the=20importSingleIss?= =?UTF-8?q?ue=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/socket.service.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/services/socket.service.ts b/services/socket.service.ts index 43559fa..8b0f52d 100644 --- a/services/socket.service.ts +++ b/services/socket.service.ts @@ -134,14 +134,14 @@ export default class SocketService extends Service { sessionRecord.length !== 0 && sessionRecord[0].sessionId === sessionId ) { - // 2. Find if the queue has active jobs + // 2. Find if the queue has active, paused or waiting jobs const jobs: JobType = await this.broker.call( "jobqueue.getJobCountsByType", {} ); - const { active } = jobs; + const { active, paused, waiting } = jobs; - if (active > 0) { + if (active > 0 || paused > 0 || waiting > 0) { // 3. Get job counts const completedJobCount = await pubClient.get( "completedJobCount" @@ -189,6 +189,15 @@ export default class SocketService extends Service { {} ); }, + importSingleIssue: async (ctx: Context<{}>) => { + console.info("AirDC++ finished a download -> "); + console.log(ctx.params); + // await this.broker.call( + // "library.importDownloadedComic", + // { bundle: data }, + // {} + // ); + }, }, methods: {}, async started() { From f35e3ccbe0260375785a57277fa66e0b847ba87c Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Wed, 15 Nov 2023 16:02:07 -0600 Subject: [PATCH 09/13] =?UTF-8?q?=E2=9D=8C=20Removed=20useless=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/socket.service.ts | 84 -------------------------------------- 1 file changed, 84 deletions(-) diff --git a/services/socket.service.ts b/services/socket.service.ts index 8b0f52d..02a40cd 100644 --- a/services/socket.service.ts +++ b/services/socket.service.ts @@ -28,90 +28,6 @@ export default class SocketService extends Service { call: { whitelist: ["socket.*"], }, - - // async (data) => { - // console.log("uldas", data); - // switch (data.type) { - // case "RESUME_SESSION": - // console.log("Attempting to resume session..."); - // try { - // const sessionRecord = await Session.find({ - // sessionId: data.session.sessionId, - // }); - // // 1. Check for sessionId's existence, and a match - // if ( - // sessionRecord.length !== 0 && - // sessionRecord[0].sessionId === - // data.session.sessionId - // ) { - // // 2. Find if the queue has active jobs - // const jobs: JobType = await this.broker.call( - // "jobqueue.getJobCountsByType", - // {} - // ); - // const { active } = jobs; - // - // if (active > 0) { - // // 3. Get job counts - // const completedJobCount = - // await pubClient.get( - // "completedJobCount" - // ); - // const failedJobCount = await pubClient.get( - // "failedJobCount" - // ); - // - // // 4. Send the counts to the active socket.io session - // await this.broker.call("socket.broadcast", { - // namespace: "/", - // event: "action", - // args: [ - // { - // type: "RESTORE_JOB_COUNTS_AFTER_SESSION_RESTORATION", - // completedJobCount, - // failedJobCount, - // queueStatus: "running", - // }, - // ], - // }); - // } - // } - // } catch (err) { - // throw new MoleculerError( - // err, - // 500, - // "SESSION_ID_NOT_FOUND", - // { - // data: data.session.sessionId, - // } - // ); - // } - // - // break; - // - // case "LS_SET_QUEUE_STATUS": - // console.log(data); - // await this.broker.call( - // "jobqueue.toggle", - // { action: data.data.queueAction }, - // {} - // ); - // break; - // case "LS_SINGLE_IMPORT": - // console.info("AirDC++ finished a download -> "); - // console.log(data); - // await this.broker.call( - // "library.importDownloadedComic", - // { bundle: data }, - // {} - // ); - // break; - // // uncompress archive events - // case "COMICBOOK_EXTRACTION_SUCCESS": - // console.log(data); - // return data; - // } - // }, }, }, }, From b2b35aedc0e7d6ecfb0fd7b3a705c61fa8ed7406 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Mon, 27 Nov 2023 02:14:16 -0500 Subject: [PATCH 10/13] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20Fixed=20a=20mongo?= =?UTF-8?q?=20update=20query?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/settings.service.ts | 59 ++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/services/settings.service.ts b/services/settings.service.ts index 95c5e4e..2e9ee64 100644 --- a/services/settings.service.ts +++ b/services/settings.service.ts @@ -8,7 +8,7 @@ import { } from "moleculer"; import { DbMixin } from "../mixins/db.mixin"; import Settings from "../models/settings.model"; -import { isEmpty, pickBy, identity, map } from "lodash"; +import { isEmpty, pickBy, identity, map, isNil } from "lodash"; const ObjectId = require("mongoose").Types.ObjectId; export default class SettingsService extends Service { @@ -57,7 +57,6 @@ export default class SettingsService extends Service { }> ) { try { - console.log(ctx.params); let query = {}; const { settingsKey, settingsObjectId } = ctx.params; @@ -68,6 +67,16 @@ export default class SettingsService extends Service { username, password, } = ctx.params.settingsPayload; + const host = { + hostname, + protocol, + port, + username, + password, + }; + const undefinedPropsInHostname = Object.values( + host + ).filter((value) => value === undefined); // Update, depending what key was passed in params // 1. Construct the update query @@ -79,13 +88,7 @@ export default class SettingsService extends Service { query = { bittorrent: { client: { - host: { - hostname, - protocol, - port, - username, - password, - }, + ...(host && host), name: "qbittorrent", }, }, @@ -98,20 +101,21 @@ export default class SettingsService extends Service { const { hubs, airDCPPUserSettings } = ctx.params.settingsPayload; query = { - directConnect: { - client: { - host: { - hostname, - protocol, - port, - username, - password, - }, - hubs, - airDCPPUserSettings, + ...(undefinedPropsInHostname.length === + 0 && { + $set: { + "directConnect.client.host": + host, }, - }, + }), + ...(!isNil(hubs) && { + $set: { + "directConnect.client.hubs": + hubs, + }, + }), }; + console.log(JSON.stringify(query, null, 4)); break; default: @@ -124,17 +128,20 @@ export default class SettingsService extends Service { setDefaultsOnInsert: true, returnDocument: "after", }; - const filter = { - _id: settingsObjectId, - }; + const filter = settingsObjectId + ? { _id: settingsObjectId } + : {}; + // 3. Execute the mongo query const result = await Settings.findOneAndUpdate( - {}, + filter, query, options ); return result; - } catch (err) {} + } catch (err) { + return err; + } }, }, deleteSettings: { From c926758db6dcb4599a1a97617ee6a680fe1ecc4a Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Wed, 20 Dec 2023 00:08:38 -0500 Subject: [PATCH 11/13] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20Added=20a=20downl?= =?UTF-8?q?oads=20array=20to=20bittorent=20schema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/comic.model.ts | 3 ++- services/settings.service.ts | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/models/comic.model.ts b/models/comic.model.ts index ce52894..0483445 100644 --- a/models/comic.model.ts +++ b/models/comic.model.ts @@ -2,7 +2,7 @@ const paginate = require("mongoose-paginate-v2"); const { Client } = require("@elastic/elasticsearch"); import ComicVineMetadataSchema from "./comicvine.metadata.model"; import { mongoosastic } from "mongoosastic-ts"; -const mongoose = require("mongoose") +const mongoose = require("mongoose"); import { MongoosasticDocument, MongoosasticModel, @@ -112,6 +112,7 @@ const ComicSchema = mongoose.Schema( }, }, torrent: { + downloads: [], sourceApplication: String, magnet: String, tracker: String, diff --git a/services/settings.service.ts b/services/settings.service.ts index 2e9ee64..7159a00 100644 --- a/services/settings.service.ts +++ b/services/settings.service.ts @@ -86,12 +86,12 @@ export default class SettingsService extends Service { `Recieved settings for ${settingsKey}, building query...` ); query = { - bittorrent: { - client: { - ...(host && host), - name: "qbittorrent", + ...(undefinedPropsInHostname.length === + 0 && { + $set: { + "bittorrent.client.host": host, }, - }, + }), }; break; case "directConnect": From 78e0e9f8ced269a872ad3d2b40134f5bc20f0404 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Thu, 28 Dec 2023 22:52:33 -0500 Subject: [PATCH 12/13] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20Refactored=20the?= =?UTF-8?q?=20searchIssue=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/library.service.ts | 226 +++++++++++++++++++++++------------- services/search.service.ts | 4 +- 2 files changed, 148 insertions(+), 82 deletions(-) diff --git a/services/library.service.ts b/services/library.service.ts index b885628..bc372eb 100644 --- a/services/library.service.ts +++ b/services/library.service.ts @@ -33,7 +33,13 @@ SOFTWARE. "use strict"; import { isNil } from "lodash"; -import { Context, Service, ServiceBroker, ServiceSchema, Errors } from "moleculer"; +import { + Context, + Service, + ServiceBroker, + ServiceSchema, + Errors, +} from "moleculer"; import { DbMixin } from "../mixins/db.mixin"; import Comic from "../models/comic.model"; import { walkFolder, getSizeOfDirectory } from "../utils/file.utils"; @@ -95,7 +101,9 @@ export default class ImportService extends Service { uncompressFullArchive: { rest: "POST /uncompressFullArchive", params: {}, - handler: async (ctx: Context<{ filePath: string; options: any }>) => { + handler: async ( + ctx: Context<{ filePath: string; options: any }> + ) => { await broker.call("importqueue.uncompressResize", { filePath: ctx.params.filePath, options: ctx.params.options, @@ -113,7 +121,8 @@ export default class ImportService extends Service { }); // Determine source where the comic was added from // and gather identifying information about it - const sourceName = referenceComicObject[0].acquisition.source.name; + const sourceName = + referenceComicObject[0].acquisition.source.name; const { sourcedMetadata } = referenceComicObject[0]; const filePath = `${COMICS_DIRECTORY}/${ctx.params.bundle.data.name}`; @@ -157,8 +166,14 @@ export default class ImportService extends Service { // 1.1 Filter on .cb* extensions .pipe( through2.obj(function (item, enc, next) { - let fileExtension = path.extname(item.path); - if ([".cbz", ".cbr", ".cb7"].includes(fileExtension)) { + let fileExtension = path.extname( + item.path + ); + if ( + [".cbz", ".cbr", ".cb7"].includes( + fileExtension + ) + ) { this.push(item); } next(); @@ -167,7 +182,10 @@ export default class ImportService extends Service { // 1.2 Pipe filtered results to the next step // Enqueue the job in the queue .on("data", async (item) => { - console.info("Found a file at path: %s", item.path); + console.info( + "Found a file at path: %s", + item.path + ); let comicExists = await Comic.exists({ "rawFileDetails.name": `${path.basename( item.path, @@ -176,8 +194,14 @@ export default class ImportService extends Service { }); if (!comicExists) { // 2.1 Reset the job counters in Redis - await pubClient.set("completedJobCount", 0); - await pubClient.set("failedJobCount", 0); + await pubClient.set( + "completedJobCount", + 0 + ); + await pubClient.set( + "failedJobCount", + 0 + ); // 2.2 Send the extraction job to the queue this.broker.call("jobqueue.enqueue", { fileObject: { @@ -188,7 +212,9 @@ export default class ImportService extends Service { importType: "new", }); } else { - console.log("Comic already exists in the library."); + console.log( + "Comic already exists in the library." + ); } }) .on("end", () => { @@ -240,19 +266,28 @@ export default class ImportService extends Service { // we solicit volume information and add that to mongo if ( comicMetadata.sourcedMetadata.comicvine && - !isNil(comicMetadata.sourcedMetadata.comicvine.volume) + !isNil( + comicMetadata.sourcedMetadata.comicvine + .volume + ) ) { - volumeDetails = await this.broker.call("comicvine.getVolumes", { - volumeURI: - comicMetadata.sourcedMetadata.comicvine.volume - .api_detail_url, - }); + volumeDetails = await this.broker.call( + "comicvine.getVolumes", + { + volumeURI: + comicMetadata.sourcedMetadata + .comicvine.volume + .api_detail_url, + } + ); comicMetadata.sourcedMetadata.comicvine.volumeInformation = volumeDetails.results; } console.log("Saving to Mongo..."); - console.log(`Import type: [${ctx.params.importType}]`); + console.log( + `Import type: [${ctx.params.importType}]` + ); switch (ctx.params.importType) { case "new": return await Comic.create(comicMetadata); @@ -273,7 +308,10 @@ export default class ImportService extends Service { } } catch (error) { console.log(error); - throw new Errors.MoleculerError("Import failed.", 500); + throw new Errors.MoleculerError( + "Import failed.", + 500 + ); } }, }, @@ -291,7 +329,9 @@ export default class ImportService extends Service { ) { // 1. Find mongo object by id // 2. Import payload into sourcedMetadata.comicvine - const comicObjectId = new ObjectId(ctx.params.comicObjectId); + const comicObjectId = new ObjectId( + ctx.params.comicObjectId + ); return new Promise(async (resolve, reject) => { let volumeDetails = {}; @@ -300,15 +340,18 @@ export default class ImportService extends Service { const volumeDetails = await this.broker.call( "comicvine.getVolumes", { - volumeURI: matchedResult.volume.api_detail_url, + volumeURI: + matchedResult.volume.api_detail_url, } ); - matchedResult.volumeInformation = volumeDetails.results; + matchedResult.volumeInformation = + volumeDetails.results; Comic.findByIdAndUpdate( comicObjectId, { $set: { - "sourcedMetadata.comicvine": matchedResult, + "sourcedMetadata.comicvine": + matchedResult, }, }, { new: true }, @@ -339,7 +382,9 @@ export default class ImportService extends Service { }> ) { console.log(JSON.stringify(ctx.params, null, 2)); - const comicObjectId = new ObjectId(ctx.params.comicObjectId); + const comicObjectId = new ObjectId( + ctx.params.comicObjectId + ); return new Promise((resolve, reject) => { Comic.findByIdAndUpdate( @@ -385,6 +430,7 @@ export default class ImportService extends Service { rest: "POST /getComicBookById", params: { id: "string" }, async handler(ctx: Context<{ id: string }>) { + console.log(ctx.params.id); return await Comic.findById(ctx.params.id); }, }, @@ -393,7 +439,9 @@ export default class ImportService extends Service { params: { ids: "array" }, handler: async (ctx: Context<{ ids: [string] }>) => { console.log(ctx.params.ids); - const queryIds = ctx.params.ids.map((id) => new ObjectId(id)); + const queryIds = ctx.params.ids.map( + (id) => new ObjectId(id) + ); return await Comic.find({ _id: { $in: queryIds, @@ -409,7 +457,8 @@ export default class ImportService extends Service { const volumes = await Comic.aggregate([ { $project: { - volumeInfo: "$sourcedMetadata.comicvine.volumeInformation", + volumeInfo: + "$sourcedMetadata.comicvine.volumeInformation", }, }, { @@ -455,46 +504,52 @@ export default class ImportService extends Service { const { queryObjects } = ctx.params; // construct the query for ElasticSearch let elasticSearchQuery = {}; - const elasticSearchQueries = queryObjects.map((queryObject) => { - console.log("Volume: ", queryObject.volumeName); - console.log("Issue: ", queryObject.issueName); - if (queryObject.issueName === null) { - queryObject.issueName = ""; - } - if (queryObject.volumeName === null) { - queryObject.volumeName = ""; - } - elasticSearchQuery = { - bool: { - must: [ - { - match_phrase: { - "rawFileDetails.name": queryObject.volumeName, + const elasticSearchQueries = queryObjects.map( + (queryObject) => { + console.log("Volume: ", queryObject.volumeName); + console.log("Issue: ", queryObject.issueName); + if (queryObject.issueName === null) { + queryObject.issueName = ""; + } + if (queryObject.volumeName === null) { + queryObject.volumeName = ""; + } + elasticSearchQuery = { + bool: { + must: [ + { + match_phrase: { + "rawFileDetails.name": + queryObject.volumeName, + }, }, - }, - { - term: { - "inferredMetadata.issue.number": parseInt( - queryObject.issueNumber, - 10 - ), + { + term: { + "inferredMetadata.issue.number": + parseInt( + queryObject.issueNumber, + 10 + ), + }, }, - }, - ], - }, - }; + ], + }, + }; - return [ - { - index: "comics", - search_type: "dfs_query_then_fetch", - }, - { - query: elasticSearchQuery, - }, - ]; - }); - console.log(JSON.stringify(elasticSearchQueries, null, 2)); + return [ + { + index: "comics", + search_type: "dfs_query_then_fetch", + }, + { + query: elasticSearchQuery, + }, + ]; + } + ); + console.log( + JSON.stringify(elasticSearchQueries, null, 2) + ); return await ctx.broker.call("search.searchComic", { elasticSearchQueries, @@ -507,11 +562,10 @@ export default class ImportService extends Service { rest: "GET /libraryStatistics", params: {}, handler: async (ctx: Context<{}>) => { - const comicDirectorySize = await getSizeOfDirectory(COMICS_DIRECTORY, [ - ".cbz", - ".cbr", - ".cb7", - ]); + const comicDirectorySize = await getSizeOfDirectory( + COMICS_DIRECTORY, + [".cbz", ".cbr", ".cb7"] + ); const totalCount = await Comic.countDocuments({}); const statistics = await Comic.aggregate([ { @@ -520,7 +574,11 @@ export default class ImportService extends Service { { $match: { "rawFileDetails.extension": { - $in: [".cbr", ".cbz", ".cb7"], + $in: [ + ".cbr", + ".cbz", + ".cb7", + ], }, }, }, @@ -534,9 +592,10 @@ export default class ImportService extends Service { issues: [ { $match: { - "sourcedMetadata.comicvine.volumeInformation": { - $gt: {}, - }, + "sourcedMetadata.comicvine.volumeInformation": + { + $gt: {}, + }, }, }, { @@ -599,16 +658,23 @@ export default class ImportService extends Service { .drop() .then(async (data) => { console.info(data); - const coversFolderDeleteResult = fsExtra.emptyDirSync( - path.resolve(`${USERDATA_DIRECTORY}/covers`) - ); - const expandedFolderDeleteResult = fsExtra.emptyDirSync( - path.resolve(`${USERDATA_DIRECTORY}/expanded`) - ); - const eSIndicesDeleteResult = await ctx.broker.call( - "search.deleteElasticSearchIndices", - {} - ); + const coversFolderDeleteResult = + fsExtra.emptyDirSync( + path.resolve( + `${USERDATA_DIRECTORY}/covers` + ) + ); + const expandedFolderDeleteResult = + fsExtra.emptyDirSync( + path.resolve( + `${USERDATA_DIRECTORY}/expanded` + ) + ); + const eSIndicesDeleteResult = + await ctx.broker.call( + "search.deleteElasticSearchIndices", + {} + ); return { data, coversFolderDeleteResult, diff --git a/services/search.service.ts b/services/search.service.ts index 29d1205..c7aac6a 100644 --- a/services/search.service.ts +++ b/services/search.service.ts @@ -75,9 +75,9 @@ export default class SettingsService extends Service { ) => { try { console.log(ctx.params); - const { query, pagination } = ctx.params; + const { query, pagination, type } = ctx.params; let eSQuery = {}; - switch (ctx.params.type) { + switch (type) { case "all": Object.assign(eSQuery, { match_all: {}, From f3965437b524ec04b5733e0e46332ade9e3d7eda Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Sat, 30 Dec 2023 00:50:06 -0500 Subject: [PATCH 13/13] =?UTF-8?q?=F0=9F=8F=97=20Added=20a=20job=20for=20fu?= =?UTF-8?q?ll=20archive=20extraction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 141 ++++++++++----------- services/jobqueue.service.ts | 103 +++++++--------- services/library.service.ts | 230 +++++++++++++---------------------- utils/uncompression.utils.ts | 174 +++++++++----------------- 4 files changed, 246 insertions(+), 402 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4739bad..e01d113 100644 --- a/package-lock.json +++ b/package-lock.json @@ -710,11 +710,11 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -840,12 +840,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.22.10", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -892,22 +892,22 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -990,18 +990,18 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } @@ -1030,11 +1030,11 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, @@ -1107,9 +1107,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.13.tgz", - "integrity": "sha512-3l6+4YOvc9wx7VlCSw4yQfcBo01ECA8TicQfbnCPuCEpRQrf+gTUyGdxNw+pyTUyywp6JRD1w0YQs9TpBXYlkw==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1319,34 +1319,34 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", - "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.11", - "@babel/types": "^7.22.11", - "debug": "^4.1.0", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -1363,13 +1363,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -4272,17 +4272,6 @@ "node": ">=10" } }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -9934,9 +9923,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/msgpackr": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.9.7.tgz", - "integrity": "sha512-baUNaLvKQvVhzfWTNO07njwbZK1Lxjtb0P1JL6/EhXdLTHzR57/mZqqJC39TtQKvOmkJA4pcejS4dbk7BDgLLA==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.10.1.tgz", + "integrity": "sha512-r5VRLv9qouXuLiIBrLpl2d5ZvPt8svdQTl5/vMvE4nzDMyEX4sgW5yWhuBBj5UmgwOTWj8CIdSXn5sAfsHAWIQ==", "optionalDependencies": { "msgpackr-extract": "^3.0.2" } @@ -14794,14 +14783,6 @@ "node": ">=0.10.0" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -15668,16 +15649,24 @@ } }, "node_modules/undici": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz", - "integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==", + "version": "5.28.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.2.tgz", + "integrity": "sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w==", "dependencies": { - "busboy": "^1.6.0" + "@fastify/busboy": "^2.0.0" }, "engines": { "node": ">=14.0" } }, + "node_modules/undici/node_modules/@fastify/busboy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", + "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", + "engines": { + "node": ">=14" + } + }, "node_modules/unit-compare": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unit-compare/-/unit-compare-1.0.1.tgz", diff --git a/services/jobqueue.service.ts b/services/jobqueue.service.ts index 591665d..f1105e4 100644 --- a/services/jobqueue.service.ts +++ b/services/jobqueue.service.ts @@ -2,7 +2,7 @@ import { Context, Service, ServiceBroker } from "moleculer"; import JobResult from "../models/jobresult.model"; import { refineQuery } from "filename-parser"; import BullMqMixin from "moleculer-bullmq"; -import { extractFromArchive } from "../utils/uncompression.utils"; +import { extractFromArchive, uncompressEntireArchive } from "../utils/uncompression.utils"; import { isNil, isUndefined } from "lodash"; import { pubClient } from "../config/redis.config"; @@ -47,17 +47,15 @@ export default class JobQueueService extends Service { enqueue: { queue: true, rest: "/GET enqueue", - handler: async (ctx: Context<{}>) => { + handler: async (ctx: Context<{ queueName: string; description: string }>) => { + console.log(ctx.params); + const { queueName, description } = ctx.params; // Enqueue the job - const job = await this.localQueue( - ctx, - "enqueue.async", - ctx.params, - { - priority: 10, - } - ); + const job = await this.localQueue(ctx, queueName, ctx.params, { + priority: 10, + }); console.log(`Job ${job.id} enqueued`); + console.log(`${description}`); return job.id; }, @@ -70,17 +68,13 @@ export default class JobQueueService extends Service { }> ) => { try { - console.log( - `Recieved Job ID ${ctx.locals.job.id}, processing...` - ); + console.log(`Recieved Job ID ${ctx.locals.job.id}, processing...`); console.log(ctx.params); // 1. De-structure the job params const { fileObject } = ctx.locals.job.data.params; // 2. Extract metadata from the archive - const result = await extractFromArchive( - fileObject.filePath - ); + const result = await extractFromArchive(fileObject.filePath); const { name, filePath, @@ -93,9 +87,7 @@ export default class JobQueueService extends Service { } = result; // 3a. Infer any issue-related metadata from the filename - const { inferredIssueDetails } = refineQuery( - result.name - ); + const { inferredIssueDetails } = refineQuery(result.name); console.log( "Issue metadata inferred: ", JSON.stringify(inferredIssueDetails, null, 2) @@ -135,8 +127,7 @@ export default class JobQueueService extends Service { // "acquisition.directconnect.downloads": [], // mark the metadata source - "acquisition.source.name": - ctx.locals.job.data.params.sourcedFrom, + "acquisition.source.name": ctx.locals.job.data.params.sourcedFrom, }; // 3c. Add the bundleId, if present to the payload @@ -147,13 +138,8 @@ export default class JobQueueService extends Service { // 3d. Add the sourcedMetadata, if present if ( - !isNil( - ctx.locals.job.data.params.sourcedMetadata - ) && - !isUndefined( - ctx.locals.job.data.params.sourcedMetadata - .comicvine - ) + !isNil(ctx.locals.job.data.params.sourcedMetadata) && + !isUndefined(ctx.locals.job.data.params.sourcedMetadata.comicvine) ) { Object.assign( payload.sourcedMetadata, @@ -162,15 +148,11 @@ export default class JobQueueService extends Service { } // 4. write to mongo - const importResult = await this.broker.call( - "library.rawImportToDB", - { - importType: - ctx.locals.job.data.params.importType, - bundleId, - payload, - } - ); + const importResult = await this.broker.call("library.rawImportToDB", { + importType: ctx.locals.job.data.params.importType, + bundleId, + payload, + }); return { data: { importResult, @@ -182,14 +164,9 @@ export default class JobQueueService extends Service { console.error( `An error occurred processing Job ID ${ctx.locals.job.id}` ); - throw new MoleculerError( - error, - 500, - "IMPORT_JOB_ERROR", - { - data: ctx.params.sessionId, - } - ); + throw new MoleculerError(error, 500, "IMPORT_JOB_ERROR", { + data: ctx.params.sessionId, + }); } }, }, @@ -217,8 +194,7 @@ export default class JobQueueService extends Service { statuses: { $push: { status: "$_id.status", - earliestTimestamp: - "$earliestTimestamp", + earliestTimestamp: "$earliestTimestamp", count: "$count", }, }, @@ -238,10 +214,7 @@ export default class JobQueueService extends Service { { $cond: [ { - $eq: [ - "$$this.status", - "completed", - ], + $eq: ["$$this.status", "completed"], }, "$$this.count", 0, @@ -261,10 +234,7 @@ export default class JobQueueService extends Service { { $cond: [ { - $eq: [ - "$$this.status", - "failed", - ], + $eq: ["$$this.status", "failed"], }, "$$this.count", 0, @@ -282,9 +252,24 @@ export default class JobQueueService extends Service { ]); }, }, + "uncompressFullArchive.async": { + rest: "POST /uncompressFullArchive", + handler: async (ctx: Context<{ filePath: string; options: any }>) => { + const { filePath, options } = ctx.params; + console.log("asd", filePath); + // 2. Extract metadata from the archive + return await uncompressEntireArchive(filePath, options); + }, + }, }, events: { + async "uncompressFullArchive.async.active"(ctx: Context<{ id: number }>) { + console.log(`Uncompression Job ID ${ctx.params.id} is set to active.`); + }, + async "uncompressFullArchive.async.completed"(ctx: Context<{ id: number }>) { + console.log(`Uncompression Job ID ${ctx.params.id} completed.`); + }, // use the `${QUEUE_NAME}.QUEUE_EVENT` scheme async "enqueue.async.active"(ctx: Context<{ id: Number }>) { console.log(`Job ID ${ctx.params.id} is set to active.`); @@ -307,9 +292,7 @@ export default class JobQueueService extends Service { // 2. Increment the completed job counter await pubClient.incr("completedJobCount"); // 3. Fetch the completed job count for the final payload to be sent to the client - const completedJobCount = await pubClient.get( - "completedJobCount" - ); + const completedJobCount = await pubClient.get("completedJobCount"); // 4. Emit the LS_COVER_EXTRACTED event with the necessary details await this.broker.call("socket.broadcast", { namespace: "/", @@ -336,9 +319,7 @@ export default class JobQueueService extends Service { async "enqueue.async.failed"(ctx) { const job = await this.job(ctx.params.id); await pubClient.incr("failedJobCount"); - const failedJobCount = await pubClient.get( - "failedJobCount" - ); + const failedJobCount = await pubClient.get("failedJobCount"); await JobResult.create({ id: ctx.params.id, diff --git a/services/library.service.ts b/services/library.service.ts index bc372eb..3bc5284 100644 --- a/services/library.service.ts +++ b/services/library.service.ts @@ -33,13 +33,7 @@ SOFTWARE. "use strict"; import { isNil } from "lodash"; -import { - Context, - Service, - ServiceBroker, - ServiceSchema, - Errors, -} from "moleculer"; +import { Context, Service, ServiceBroker, ServiceSchema, Errors } from "moleculer"; import { DbMixin } from "../mixins/db.mixin"; import Comic from "../models/comic.model"; import { walkFolder, getSizeOfDirectory } from "../utils/file.utils"; @@ -101,9 +95,7 @@ export default class ImportService extends Service { uncompressFullArchive: { rest: "POST /uncompressFullArchive", params: {}, - handler: async ( - ctx: Context<{ filePath: string; options: any }> - ) => { + handler: async (ctx: Context<{ filePath: string; options: any }>) => { await broker.call("importqueue.uncompressResize", { filePath: ctx.params.filePath, options: ctx.params.options, @@ -121,8 +113,7 @@ export default class ImportService extends Service { }); // Determine source where the comic was added from // and gather identifying information about it - const sourceName = - referenceComicObject[0].acquisition.source.name; + const sourceName = referenceComicObject[0].acquisition.source.name; const { sourcedMetadata } = referenceComicObject[0]; const filePath = `${COMICS_DIRECTORY}/${ctx.params.bundle.data.name}`; @@ -166,14 +157,8 @@ export default class ImportService extends Service { // 1.1 Filter on .cb* extensions .pipe( through2.obj(function (item, enc, next) { - let fileExtension = path.extname( - item.path - ); - if ( - [".cbz", ".cbr", ".cb7"].includes( - fileExtension - ) - ) { + let fileExtension = path.extname(item.path); + if ([".cbz", ".cbr", ".cb7"].includes(fileExtension)) { this.push(item); } next(); @@ -182,10 +167,7 @@ export default class ImportService extends Service { // 1.2 Pipe filtered results to the next step // Enqueue the job in the queue .on("data", async (item) => { - console.info( - "Found a file at path: %s", - item.path - ); + console.info("Found a file at path: %s", item.path); let comicExists = await Comic.exists({ "rawFileDetails.name": `${path.basename( item.path, @@ -194,14 +176,8 @@ export default class ImportService extends Service { }); if (!comicExists) { // 2.1 Reset the job counters in Redis - await pubClient.set( - "completedJobCount", - 0 - ); - await pubClient.set( - "failedJobCount", - 0 - ); + await pubClient.set("completedJobCount", 0); + await pubClient.set("failedJobCount", 0); // 2.2 Send the extraction job to the queue this.broker.call("jobqueue.enqueue", { fileObject: { @@ -210,11 +186,10 @@ export default class ImportService extends Service { }, sessionId, importType: "new", + queueName: "enqueue.async", }); } else { - console.log( - "Comic already exists in the library." - ); + console.log("Comic already exists in the library."); } }) .on("end", () => { @@ -266,28 +241,19 @@ export default class ImportService extends Service { // we solicit volume information and add that to mongo if ( comicMetadata.sourcedMetadata.comicvine && - !isNil( - comicMetadata.sourcedMetadata.comicvine - .volume - ) + !isNil(comicMetadata.sourcedMetadata.comicvine.volume) ) { - volumeDetails = await this.broker.call( - "comicvine.getVolumes", - { - volumeURI: - comicMetadata.sourcedMetadata - .comicvine.volume - .api_detail_url, - } - ); + volumeDetails = await this.broker.call("comicvine.getVolumes", { + volumeURI: + comicMetadata.sourcedMetadata.comicvine.volume + .api_detail_url, + }); comicMetadata.sourcedMetadata.comicvine.volumeInformation = volumeDetails.results; } console.log("Saving to Mongo..."); - console.log( - `Import type: [${ctx.params.importType}]` - ); + console.log(`Import type: [${ctx.params.importType}]`); switch (ctx.params.importType) { case "new": return await Comic.create(comicMetadata); @@ -308,10 +274,7 @@ export default class ImportService extends Service { } } catch (error) { console.log(error); - throw new Errors.MoleculerError( - "Import failed.", - 500 - ); + throw new Errors.MoleculerError("Import failed.", 500); } }, }, @@ -329,9 +292,7 @@ export default class ImportService extends Service { ) { // 1. Find mongo object by id // 2. Import payload into sourcedMetadata.comicvine - const comicObjectId = new ObjectId( - ctx.params.comicObjectId - ); + const comicObjectId = new ObjectId(ctx.params.comicObjectId); return new Promise(async (resolve, reject) => { let volumeDetails = {}; @@ -340,18 +301,15 @@ export default class ImportService extends Service { const volumeDetails = await this.broker.call( "comicvine.getVolumes", { - volumeURI: - matchedResult.volume.api_detail_url, + volumeURI: matchedResult.volume.api_detail_url, } ); - matchedResult.volumeInformation = - volumeDetails.results; + matchedResult.volumeInformation = volumeDetails.results; Comic.findByIdAndUpdate( comicObjectId, { $set: { - "sourcedMetadata.comicvine": - matchedResult, + "sourcedMetadata.comicvine": matchedResult, }, }, { new: true }, @@ -382,9 +340,7 @@ export default class ImportService extends Service { }> ) { console.log(JSON.stringify(ctx.params, null, 2)); - const comicObjectId = new ObjectId( - ctx.params.comicObjectId - ); + const comicObjectId = new ObjectId(ctx.params.comicObjectId); return new Promise((resolve, reject) => { Comic.findByIdAndUpdate( @@ -439,9 +395,7 @@ export default class ImportService extends Service { params: { ids: "array" }, handler: async (ctx: Context<{ ids: [string] }>) => { console.log(ctx.params.ids); - const queryIds = ctx.params.ids.map( - (id) => new ObjectId(id) - ); + const queryIds = ctx.params.ids.map((id) => new ObjectId(id)); return await Comic.find({ _id: { $in: queryIds, @@ -457,8 +411,7 @@ export default class ImportService extends Service { const volumes = await Comic.aggregate([ { $project: { - volumeInfo: - "$sourcedMetadata.comicvine.volumeInformation", + volumeInfo: "$sourcedMetadata.comicvine.volumeInformation", }, }, { @@ -504,52 +457,46 @@ export default class ImportService extends Service { const { queryObjects } = ctx.params; // construct the query for ElasticSearch let elasticSearchQuery = {}; - const elasticSearchQueries = queryObjects.map( - (queryObject) => { - console.log("Volume: ", queryObject.volumeName); - console.log("Issue: ", queryObject.issueName); - if (queryObject.issueName === null) { - queryObject.issueName = ""; - } - if (queryObject.volumeName === null) { - queryObject.volumeName = ""; - } - elasticSearchQuery = { - bool: { - must: [ - { - match_phrase: { - "rawFileDetails.name": - queryObject.volumeName, - }, - }, - { - term: { - "inferredMetadata.issue.number": - parseInt( - queryObject.issueNumber, - 10 - ), - }, - }, - ], - }, - }; - - return [ - { - index: "comics", - search_type: "dfs_query_then_fetch", - }, - { - query: elasticSearchQuery, - }, - ]; + const elasticSearchQueries = queryObjects.map((queryObject) => { + console.log("Volume: ", queryObject.volumeName); + console.log("Issue: ", queryObject.issueName); + if (queryObject.issueName === null) { + queryObject.issueName = ""; } - ); - console.log( - JSON.stringify(elasticSearchQueries, null, 2) - ); + if (queryObject.volumeName === null) { + queryObject.volumeName = ""; + } + elasticSearchQuery = { + bool: { + must: [ + { + match_phrase: { + "rawFileDetails.name": queryObject.volumeName, + }, + }, + { + term: { + "inferredMetadata.issue.number": parseInt( + queryObject.issueNumber, + 10 + ), + }, + }, + ], + }, + }; + + return [ + { + index: "comics", + search_type: "dfs_query_then_fetch", + }, + { + query: elasticSearchQuery, + }, + ]; + }); + console.log(JSON.stringify(elasticSearchQueries, null, 2)); return await ctx.broker.call("search.searchComic", { elasticSearchQueries, @@ -562,10 +509,11 @@ export default class ImportService extends Service { rest: "GET /libraryStatistics", params: {}, handler: async (ctx: Context<{}>) => { - const comicDirectorySize = await getSizeOfDirectory( - COMICS_DIRECTORY, - [".cbz", ".cbr", ".cb7"] - ); + const comicDirectorySize = await getSizeOfDirectory(COMICS_DIRECTORY, [ + ".cbz", + ".cbr", + ".cb7", + ]); const totalCount = await Comic.countDocuments({}); const statistics = await Comic.aggregate([ { @@ -574,11 +522,7 @@ export default class ImportService extends Service { { $match: { "rawFileDetails.extension": { - $in: [ - ".cbr", - ".cbz", - ".cb7", - ], + $in: [".cbr", ".cbz", ".cb7"], }, }, }, @@ -592,10 +536,9 @@ export default class ImportService extends Service { issues: [ { $match: { - "sourcedMetadata.comicvine.volumeInformation": - { - $gt: {}, - }, + "sourcedMetadata.comicvine.volumeInformation": { + $gt: {}, + }, }, }, { @@ -658,23 +601,16 @@ export default class ImportService extends Service { .drop() .then(async (data) => { console.info(data); - const coversFolderDeleteResult = - fsExtra.emptyDirSync( - path.resolve( - `${USERDATA_DIRECTORY}/covers` - ) - ); - const expandedFolderDeleteResult = - fsExtra.emptyDirSync( - path.resolve( - `${USERDATA_DIRECTORY}/expanded` - ) - ); - const eSIndicesDeleteResult = - await ctx.broker.call( - "search.deleteElasticSearchIndices", - {} - ); + const coversFolderDeleteResult = fsExtra.emptyDirSync( + path.resolve(`${USERDATA_DIRECTORY}/covers`) + ); + const expandedFolderDeleteResult = fsExtra.emptyDirSync( + path.resolve(`${USERDATA_DIRECTORY}/expanded`) + ); + const eSIndicesDeleteResult = await ctx.broker.call( + "search.deleteElasticSearchIndices", + {} + ); return { data, coversFolderDeleteResult, diff --git a/utils/uncompression.utils.ts b/utils/uncompression.utils.ts index ef8e962..1304f8f 100644 --- a/utils/uncompression.utils.ts +++ b/utils/uncompression.utils.ts @@ -74,15 +74,14 @@ const errors = []; */ export const extractComicInfoXMLFromRar = async ( filePath: string, - mimeType: string, + mimeType: string ): Promise => { try { // Create the target directory const directoryOptions = { mode: 0o2775, }; - const { fileNameWithoutExtension, extension } = - getFileConstituents(filePath); + const { fileNameWithoutExtension, extension } = getFileConstituents(filePath); const targetDirectory = `${USERDATA_DIRECTORY}/covers/${sanitize( fileNameWithoutExtension )}`; @@ -93,17 +92,15 @@ export const extractComicInfoXMLFromRar = async ( bin: `${UNRAR_BIN_PATH}`, // this will change depending on Docker base OS arguments: ["-v"], }); - const filesInArchive: [RarFile] = await new Promise( - (resolve, reject) => { - return archive.list((err, entries) => { - if (err) { - console.log(`DEBUG: ${JSON.stringify(err, null, 2)}`); - reject(err); - } - resolve(entries); - }); - } - ); + const filesInArchive: [RarFile] = await new Promise((resolve, reject) => { + return archive.list((err, entries) => { + if (err) { + console.log(`DEBUG: ${JSON.stringify(err, null, 2)}`); + reject(err); + } + resolve(entries); + }); + }); remove(filesInArchive, ({ type }) => type === "Directory"); const comicInfoXML = remove( @@ -113,10 +110,7 @@ export const extractComicInfoXMLFromRar = async ( remove( filesInArchive, - ({ name }) => - !IMPORT_IMAGE_FILE_FORMATS.includes( - path.extname(name).toLowerCase() - ) + ({ name }) => !IMPORT_IMAGE_FILE_FORMATS.includes(path.extname(name).toLowerCase()) ); const files = filesInArchive.sort((a, b) => { if (!isUndefined(a) && !isUndefined(b)) { @@ -129,12 +123,8 @@ export const extractComicInfoXMLFromRar = async ( const comicInfoXMLFilePromise = new Promise((resolve, reject) => { let comicinfostring = ""; if (!isUndefined(comicInfoXML[0])) { - const comicInfoXMLFileName = path.basename( - comicInfoXML[0].name - ); - const writeStream = createWriteStream( - `${targetDirectory}/${comicInfoXMLFileName}` - ); + const comicInfoXMLFileName = path.basename(comicInfoXML[0].name); + const writeStream = createWriteStream(`${targetDirectory}/${comicInfoXMLFileName}`); archive.stream(comicInfoXML[0]["name"]).pipe(writeStream); writeStream.on("finish", async () => { @@ -147,11 +137,7 @@ export const extractComicInfoXMLFromRar = async ( }); readStream.on("error", (error) => reject(error)); readStream.on("end", async () => { - if ( - existsSync( - `${targetDirectory}/${comicInfoXMLFileName}` - ) - ) { + if (existsSync(`${targetDirectory}/${comicInfoXMLFileName}`)) { const comicInfoJSON = await convertXMLToJSON( comicinfostring.toString() ); @@ -172,34 +158,29 @@ export const extractComicInfoXMLFromRar = async ( const sharpStream = sharp().resize(275).toFormat("png"); const coverExtractionStream = archive.stream(files[0].name); const resizeStream = coverExtractionStream.pipe(sharpStream); - resizeStream.toFile( - `${targetDirectory}/${coverFile}`, - (err, info) => { - if (err) { - reject(err); - } - checkFileExists(`${targetDirectory}/${coverFile}`).then( - (bool) => { - console.log(`${coverFile} exists: ${bool}`); - // orchestrate result - resolve({ - filePath, - name: fileNameWithoutExtension, - extension, - containedIn: targetDirectory, - fileSize: fse.statSync(filePath).size, - mimeType, - cover: { - filePath: path.relative( - process.cwd(), - `${targetDirectory}/${coverFile}` - ), - }, - }); - } - ); + resizeStream.toFile(`${targetDirectory}/${coverFile}`, (err, info) => { + if (err) { + reject(err); } - ); + checkFileExists(`${targetDirectory}/${coverFile}`).then((bool) => { + console.log(`${coverFile} exists: ${bool}`); + // orchestrate result + resolve({ + filePath, + name: fileNameWithoutExtension, + extension, + containedIn: targetDirectory, + fileSize: fse.statSync(filePath).size, + mimeType, + cover: { + filePath: path.relative( + process.cwd(), + `${targetDirectory}/${coverFile}` + ), + }, + }); + }); + }); }); return Promise.all([comicInfoXMLFilePromise, coverFilePromise]); @@ -210,15 +191,14 @@ export const extractComicInfoXMLFromRar = async ( export const extractComicInfoXMLFromZip = async ( filePath: string, - mimeType: string, + mimeType: string ): Promise => { try { // Create the target directory const directoryOptions = { mode: 0o2775, }; - const { fileNameWithoutExtension, extension } = - getFileConstituents(filePath); + const { fileNameWithoutExtension, extension } = getFileConstituents(filePath); const targetDirectory = `${USERDATA_DIRECTORY}/covers/${sanitize( fileNameWithoutExtension )}`; @@ -237,10 +217,7 @@ export const extractComicInfoXMLFromZip = async ( // only allow allowed image formats remove( filesFromArchive.files, - ({ name }) => - !IMPORT_IMAGE_FILE_FORMATS.includes( - path.extname(name).toLowerCase() - ) + ({ name }) => !IMPORT_IMAGE_FILE_FORMATS.includes(path.extname(name).toLowerCase()) ); // Natural sort @@ -261,13 +238,7 @@ export const extractComicInfoXMLFromZip = async ( extractionTargets.push(filesToWriteToDisk.comicInfoXML); } // Extract the files. - await p7zip.extract( - filePath, - targetDirectory, - extractionTargets, - "", - false - ); + await p7zip.extract(filePath, targetDirectory, extractionTargets, "", false); // ComicInfoXML detection, parsing and conversion to JSON // Write ComicInfo.xml to disk @@ -275,26 +246,15 @@ export const extractComicInfoXMLFromZip = async ( const comicInfoXMLPromise = new Promise((resolve, reject) => { if ( !isNil(filesToWriteToDisk.comicInfoXML) && - existsSync( - `${targetDirectory}/${path.basename( - filesToWriteToDisk.comicInfoXML - )}` - ) + existsSync(`${targetDirectory}/${path.basename(filesToWriteToDisk.comicInfoXML)}`) ) { let comicinfoString = ""; const comicInfoXMLStream = createReadStream( - `${targetDirectory}/${path.basename( - filesToWriteToDisk.comicInfoXML - )}` - ); - comicInfoXMLStream.on( - "data", - (data) => (comicinfoString += data) + `${targetDirectory}/${path.basename(filesToWriteToDisk.comicInfoXML)}` ); + comicInfoXMLStream.on("data", (data) => (comicinfoString += data)); comicInfoXMLStream.on("end", async () => { - const comicInfoJSON = await convertXMLToJSON( - comicinfoString.toString() - ); + const comicInfoJSON = await convertXMLToJSON(comicinfoString.toString()); resolve({ comicInfoJSON: comicInfoJSON.comicinfo, }); @@ -314,9 +274,7 @@ export const extractComicInfoXMLFromZip = async ( coverStream .pipe(sharpStream) .toFile( - `${targetDirectory}/${path.basename( - filesToWriteToDisk.coverFile - )}`, + `${targetDirectory}/${path.basename(filesToWriteToDisk.coverFile)}`, (err, info) => { if (err) { reject(err); @@ -365,13 +323,10 @@ export const extractFromArchive = async (filePath: string) => { return Object.assign({}, ...cbrResult); default: - console.error( - "Error inferring filetype for comicinfo.xml extraction." - ); + console.error("Error inferring filetype for comicinfo.xml extraction."); throw new MoleculerError({}, 500, "FILETYPE_INFERENCE_ERROR", { - data: { message: "Cannot infer filetype."}, + data: { message: "Cannot infer filetype." }, }); - } }; @@ -381,10 +336,7 @@ export const extractFromArchive = async (filePath: string) => { * @param {any} options * @returns {Promise} A promise containing the contents of the uncompressed archive. */ -export const uncompressEntireArchive = async ( - filePath: string, - options: any -) => { +export const uncompressEntireArchive = async (filePath: string, options: any) => { const mimeType = await getMimeType(filePath); console.log(`File has the following mime-type: ${mimeType}`); switch (mimeType) { @@ -426,8 +378,7 @@ export const uncompressRarArchive = async (filePath: string, options: any) => { const directoryOptions = { mode: 0o2775, }; - const { fileNameWithoutExtension, extension } = - getFileConstituents(filePath); + const { fileNameWithoutExtension, extension } = getFileConstituents(filePath); const targetDirectory = `${USERDATA_DIRECTORY}/expanded/${options.purpose}/${fileNameWithoutExtension}`; await createDirectory(directoryOptions, targetDirectory); @@ -464,10 +415,7 @@ export const uncompressRarArchive = async (filePath: string, options: any) => { return await resizeImageDirectory(targetDirectory, options); }; -export const resizeImageDirectory = async ( - directoryPath: string, - options: any -) => { +export const resizeImageDirectory = async (directoryPath: string, options: any) => { const files = await walkFolder(directoryPath, [ ".jpg", ".jpeg", @@ -495,25 +443,15 @@ export const resizeImage = (directoryPath: string, file: any, options: any) => { const { baseWidth } = options.imageResizeOptions; const sharpResizeInstance = sharp().resize(baseWidth).toFormat("jpg"); return new Promise((resolve, reject) => { - const resizedStream = createReadStream( - `${directoryPath}/${file.name}${file.extension}` - ); + const resizedStream = createReadStream(`${directoryPath}/${file.name}${file.extension}`); if (fse.existsSync(`${directoryPath}/${file.name}${file.extension}`)) { resizedStream .pipe(sharpResizeInstance) - .toFile( - `${directoryPath}/${file.name}_${baseWidth}px${file.extension}` - ) + .toFile(`${directoryPath}/${file.name}_${baseWidth}px${file.extension}`) .then((data) => { - console.log( - `Resized image ${JSON.stringify(data, null, 4)}` - ); - fse.unlink( - `${directoryPath}/${file.name}${file.extension}` - ); - resolve( - `${directoryPath}/${file.name}_${baseWidth}px${file.extension}` - ); + console.log(`Resized image ${JSON.stringify(data, null, 4)}`); + fse.unlink(`${directoryPath}/${file.name}${file.extension}`); + resolve(`${directoryPath}/${file.name}_${baseWidth}px${file.extension}`); }); } });