diff --git a/.env.dist b/.env.dist index 1851299..8576069 100644 --- a/.env.dist +++ b/.env.dist @@ -51,6 +51,7 @@ FAIRPOST_REQUEST_PORT=8000 # FAIRPOST_LINKEDIN_CLIENT_ID=xxx # FAIRPOST_LINKEDIN_CLIENT_SECRET=xxx # FAIRPOST_LINKEDIN_COMPANY_ID=xxx +# linkedin_auth # FAIRPOST_LINKEDIN_ACCESS_TOKEN=xxx # FAIRPOST_LINKEDIN_REFRESH_TOKEN=xxx diff --git a/README.md b/README.md index 19c2b42..61d872c 100644 --- a/README.md +++ b/README.md @@ -116,12 +116,12 @@ fairpost.js get-platform --platform=xxx fairpost.js get-platforms [--platforms=xxx,xxx] fairpost.js get-folder --folder=xxx fairpost.js get-folders [--folders=xxx,xxx] -fairpost.js get-post --folder=xxx --platform=xxx +fairpost.js get-post --post=xxx:xxx fairpost.js get-posts [--status=xxx] [--folders=xxx,xxx] [--platforms=xxx,xxx] -fairpost.js prepare-post --folder=xxx --platform=xxx -fairpost.js schedule-post --folder=xxx --platform=xxx --date=xxxx-xx-xx +fairpost.js prepare-post --post=xxx:xxx +fairpost.js schedule-post --post=xxx:xxx --date=xxxx-xx-xx fairpost.js schedule-posts [--folders=xxx,xxx] [--platforms=xxx,xxx] --date=xxxx-xx-xx -fairpost.js publish-post --folder=xxx --platform=xxx [--dry-run] +fairpost.js publish-post --post=xxx:xxx [--dry-run] fairpost.js publish-posts [--folders=xxx,xxx] [--platforms=xxx,xxx] # feed planning: diff --git a/docs/Facebook.md b/docs/Facebook.md index b5a91cb..ed3518f 100644 --- a/docs/Facebook.md +++ b/docs/Facebook.md @@ -1,6 +1,6 @@ # Platform: Facebook -The `facebook` platform manage a facebook **page* (not your feed) +The `facebook` platform manages a facebook **page** (not your feed) using the plain graph api - no extensions installed. ## Setting up the Facebook platform @@ -13,11 +13,11 @@ using the plain graph api - no extensions installed. - save this as `FAIRPOST_FACEBOOK_APP_ID` in your .env - under 'settings', find your app secret - save this as `FAIRPOST_FACEBOOK_APP_SECRET` in your .env - - before you use the app, set the App Mode to 'Live' - - use https://github.com/commonpike/fairpost/blob/master/public/privacy-policy.md for the privacy policy url + - keep the app under development, otherwise the localhost return url wont work + ### Find the page id of the page you want the app to manage - go to https://business.facebook.com/ - - find your page (currently under 'settings > business assets') + - find your page (currently under 'settings > accounts > pages') - save the page id as `FAIRPOST_FACEBOOK_PAGE_ID` in your .env ### Enable the platform @@ -26,7 +26,7 @@ using the plain graph api - no extensions installed. ### Get a (long lived) Page Access Token for the page you want the app to manage This token should last forever. It involves getting a user access token, -exchaning it for a long-lived user token and +exchanging it for a long-lived user token and then requesting the 'accounts' for your 'app scoped user id'; but this app provides a tool to help you do that: @@ -36,6 +36,14 @@ but this app provides a tool to help you do that: ### Test the platform - call `./fairpost.js test-platform --platform=facebook` +### Make the app live + - before you use the app, set the App Mode to 'Live' + - use https://github.com/commonpike/fairpost/blob/master/public/privacy-policy.md for the privacy policy url + +### Other settings + +`FAIRPOST_FACEBOOK_PUBLISH_POSTS` - if false, posts will be posted but not be published + # Limitations ## Images diff --git a/package-lock.json b/package-lock.json index c1f1526..1a86f1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,10 +13,11 @@ "fast-xml-parser": "^4.3.2", "log4js": "^6.9.1", "node-fetch": "^2.6.7", - "sharp": "0.31.1", + "sharp": "0.33.1", "twitter-api-v2": "^1.15.2" }, "devDependencies": { + "@types/node": "^20.10.5", "@typescript-eslint/eslint-plugin": "^6.7.5", "@typescript-eslint/parser": "^6.7.5", "eslint": "^8.51.0", @@ -49,6 +50,15 @@ "node": ">=12" } }, + "node_modules/@emnapi/runtime": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.44.0.tgz", + "integrity": "sha512-ZX/etZEZw8DR7zAB1eVQT40lNo0jeqpb6dCgOvctB6FIQ5PoXfMuNY8+ayQfu8tNQbAB8gQWSSJupR8NxeiZXw==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@es-joy/jsdoccomment": { "version": "0.40.1", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.40.1.tgz", @@ -164,6 +174,437 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.1.tgz", + "integrity": "sha512-esr2BZ1x0bo+wl7Gx2hjssYhjrhUsD88VQulI0FrG8/otRQUOxLWHMBd1Y1qo2Gfg2KUvXNpT0ASnV9BzJCexw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.0" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.1.tgz", + "integrity": "sha512-YrnuB3bXuWdG+hJlXtq7C73lF8ampkhU3tMxg5Hh+E7ikxbUVOU9nlNtVTloDXz6pRHt2y2oKJq7DY/yt+UXYw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-VzYd6OwnUR81sInf3alj1wiokY50DjsHz5bvfnsFpxs5tqQxESoHtJO6xyksDs3RIkyhMWq2FufXo6GNSU9BMw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.0.tgz", + "integrity": "sha512-dD9OznTlHD6aovRswaPNEy8dKtSAmNo4++tO7uuR4o5VxbVAOoEQ1uSmN4iFAdQneTHws1lkTZeiXPrcCkh6IA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=10.13", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.0.tgz", + "integrity": "sha512-VwgD2eEikDJUk09Mn9Dzi1OW2OJFRQK+XlBTkUNmAWPrtj8Ly0yq05DFgu1VCMx2/DqCGQVi5A1dM9hTmxf3uw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.0.tgz", + "integrity": "sha512-xTYThiqEZEZc0PRU90yVtM3KE7lw1bKdnDQ9kCTHWbqWyHOe4NpPOtMGy27YnN51q0J5dqRrvicfPbALIOeAZA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.0.tgz", + "integrity": "sha512-o9E46WWBC6JsBlwU4QyU9578G77HBDT1NInd+aERfxeOPbk0qBZHgoDsQmA2v9TbqJRWzoBPx1aLOhprBMgPjw==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.0.tgz", + "integrity": "sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.0.tgz", + "integrity": "sha512-OdorplCyvmSAPsoJLldtLh3nLxRrkAAAOHsGWGDYfN0kh730gifK+UZb3dWORRa6EusNqCTjfXV4GxvgJ/nPDQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.0.tgz", + "integrity": "sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.1.tgz", + "integrity": "sha512-Ii4X1vnzzI4j0+cucsrYA5ctrzU9ciXERfJR633S2r39CiD8npqH2GMj63uFZRCFt3E687IenAdbwIpQOJ5BNA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.1.tgz", + "integrity": "sha512-59B5GRO2d5N3tIfeGHAbJps7cLpuWEQv/8ySd9109ohQ3kzyCACENkFVAnGPX00HwPTQcaBNF7HQYEfZyZUFfw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.0" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.1.tgz", + "integrity": "sha512-tRGrb2pHnFUXpOAj84orYNxHADBDIr0J7rrjwQrTNMQMWA4zy3StKmMvwsI7u3dEZcgwuMMooIIGWEWOjnmG8A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.1.tgz", + "integrity": "sha512-4y8osC0cAc1TRpy02yn5omBeloZZwS62fPZ0WUAYQiLhSFSpWJfY/gMrzKzLcHB9ulUV6ExFiu2elMaixKDbeg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.1.tgz", + "integrity": "sha512-D3lV6clkqIKUizNS8K6pkuCKNGmWoKlBGh5p0sLO2jQERzbakhu4bVX1Gz+RS4vTZBprKlWaf+/Rdp3ni2jLfA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.1.tgz", + "integrity": "sha512-LOGKNu5w8uu1evVqUAUKTix2sQu1XDRIYbsi5Q0c/SrXhvJ4QyOx+GaajxmOg5PZSsSnCYPSmhjHHsRBx06/wQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.1.tgz", + "integrity": "sha512-vWI/sA+0p+92DLkpAMb5T6I8dg4z2vzCUnp8yvxHlwBpzN8CIcO3xlSXrLltSvK6iMsVMNswAv+ub77rsf25lA==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/runtime": "^0.44.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.1.tgz", + "integrity": "sha512-/xhYkylsKL05R+NXGJc9xr2Tuw6WIVl2lubFJaFYfW4/MQ4J+dgjIo/T4qjNRizrqs/szF/lC9a5+updmY9jaQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.1.tgz", + "integrity": "sha512-XaM69X0n6kTEsp9tVYYLhXdg7Qj32vYJlAKRutxUsm1UlgQNx6BOhHwZPwukCGXBU2+tH87ip2eV1I/E8MQnZg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", @@ -275,11 +716,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.7.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.2.tgz", - "integrity": "sha512-RcdC3hOBOauLP+r/kRt27NrByYtDjsXyAuSbR87O6xpsvi763WI+5fbSIvYJrXnt9w4RuxhV6eAXfIs7aaf/FQ==", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dev": true, - "peer": true + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/semver": { "version": "7.5.3", @@ -582,25 +1025,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/big-integer": { "version": "1.6.51", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", @@ -610,16 +1034,6 @@ "node": ">=0.6" } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, "node_modules/bplist-parser": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", @@ -654,29 +1068,6 @@ "node": ">=8" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", @@ -729,11 +1120,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -830,28 +1216,6 @@ } } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -956,14 +1320,6 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1204,14 +1560,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "engines": { - "node": ">=6" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1353,11 +1701,6 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -1389,11 +1732,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1490,25 +1828,6 @@ "node": ">=14.18.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -1556,12 +1875,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-arrayish": { "version": "0.3.2", @@ -1862,17 +2177,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -1881,55 +2185,21 @@ "dependencies": { "brace-expansion": "^1.1.7" }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "*" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/node-abi": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.47.0.tgz", - "integrity": "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -1980,6 +2250,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "dependencies": { "wrappy": "1" } @@ -2130,31 +2401,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2191,15 +2437,6 @@ "node": ">=6.0.0" } }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -2229,33 +2466,6 @@ } ] }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -2422,25 +2632,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -2456,25 +2647,42 @@ } }, "node_modules/sharp": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.1.tgz", - "integrity": "sha512-GR8M1wBwOiFKLkm9JPun27OQnNRZdHfSf9VwcdZX6UrRmM1/XnOrLFTF0GAil+y/YK4E6qcM/ugxs80QirsHxg==", + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.1.tgz", + "integrity": "sha512-iAYUnOdTqqZDb3QjMneBKINTllCJDZ3em6WaWy7NPECM4aHncvqHRm0v0bN9nqJxMiwamv5KIdauJ6lUzKDpTQ==", "hasInstallScript": true, "dependencies": { "color": "^4.2.3", - "detect-libc": "^2.0.1", - "node-addon-api": "^5.0.0", - "prebuild-install": "^7.1.1", - "semver": "^7.3.7", - "simple-get": "^4.0.1", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" + "detect-libc": "^2.0.2", + "semver": "^7.5.4" }, "engines": { - "node": ">=14.15.0" + "libvips": ">=8.15.0", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.1", + "@img/sharp-darwin-x64": "0.33.1", + "@img/sharp-libvips-darwin-arm64": "1.0.0", + "@img/sharp-libvips-darwin-x64": "1.0.0", + "@img/sharp-libvips-linux-arm": "1.0.0", + "@img/sharp-libvips-linux-arm64": "1.0.0", + "@img/sharp-libvips-linux-s390x": "1.0.0", + "@img/sharp-libvips-linux-x64": "1.0.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.0", + "@img/sharp-libvips-linuxmusl-x64": "1.0.0", + "@img/sharp-linux-arm": "0.33.1", + "@img/sharp-linux-arm64": "0.33.1", + "@img/sharp-linux-s390x": "0.33.1", + "@img/sharp-linux-x64": "0.33.1", + "@img/sharp-linuxmusl-arm64": "0.33.1", + "@img/sharp-linuxmusl-x64": "0.33.1", + "@img/sharp-wasm32": "0.33.1", + "@img/sharp-win32-ia32": "0.33.1", + "@img/sharp-win32-x64": "0.33.1" } }, "node_modules/shebang-command": { @@ -2504,49 +2712,6 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -2599,14 +2764,6 @@ "node": ">=8.0" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -2631,14 +2788,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strnum": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", @@ -2672,32 +2821,6 @@ "url": "https://opencollective.com/unts" } }, - "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -2792,18 +2915,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } + "devOptional": true }, "node_modules/twitter-api-v2": { "version": "1.15.2", @@ -2847,6 +2959,12 @@ "node": ">=14.17" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -2873,11 +2991,6 @@ "punycode": "^2.1.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -2916,7 +3029,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "node_modules/yallist": { "version": "4.0.0", @@ -2961,6 +3075,15 @@ "@jridgewell/trace-mapping": "0.3.9" } }, + "@emnapi/runtime": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.44.0.tgz", + "integrity": "sha512-ZX/etZEZw8DR7zAB1eVQT40lNo0jeqpb6dCgOvctB6FIQ5PoXfMuNY8+ayQfu8tNQbAB8gQWSSJupR8NxeiZXw==", + "optional": true, + "requires": { + "tslib": "^2.4.0" + } + }, "@es-joy/jsdoccomment": { "version": "0.40.1", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.40.1.tgz", @@ -3041,6 +3164,147 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@img/sharp-darwin-arm64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.1.tgz", + "integrity": "sha512-esr2BZ1x0bo+wl7Gx2hjssYhjrhUsD88VQulI0FrG8/otRQUOxLWHMBd1Y1qo2Gfg2KUvXNpT0ASnV9BzJCexw==", + "optional": true, + "requires": { + "@img/sharp-libvips-darwin-arm64": "1.0.0" + } + }, + "@img/sharp-darwin-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.1.tgz", + "integrity": "sha512-YrnuB3bXuWdG+hJlXtq7C73lF8ampkhU3tMxg5Hh+E7ikxbUVOU9nlNtVTloDXz6pRHt2y2oKJq7DY/yt+UXYw==", + "optional": true, + "requires": { + "@img/sharp-libvips-darwin-x64": "1.0.0" + } + }, + "@img/sharp-libvips-darwin-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-VzYd6OwnUR81sInf3alj1wiokY50DjsHz5bvfnsFpxs5tqQxESoHtJO6xyksDs3RIkyhMWq2FufXo6GNSU9BMw==", + "optional": true + }, + "@img/sharp-libvips-darwin-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.0.tgz", + "integrity": "sha512-dD9OznTlHD6aovRswaPNEy8dKtSAmNo4++tO7uuR4o5VxbVAOoEQ1uSmN4iFAdQneTHws1lkTZeiXPrcCkh6IA==", + "optional": true + }, + "@img/sharp-libvips-linux-arm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.0.tgz", + "integrity": "sha512-VwgD2eEikDJUk09Mn9Dzi1OW2OJFRQK+XlBTkUNmAWPrtj8Ly0yq05DFgu1VCMx2/DqCGQVi5A1dM9hTmxf3uw==", + "optional": true + }, + "@img/sharp-libvips-linux-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.0.tgz", + "integrity": "sha512-xTYThiqEZEZc0PRU90yVtM3KE7lw1bKdnDQ9kCTHWbqWyHOe4NpPOtMGy27YnN51q0J5dqRrvicfPbALIOeAZA==", + "optional": true + }, + "@img/sharp-libvips-linux-s390x": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.0.tgz", + "integrity": "sha512-o9E46WWBC6JsBlwU4QyU9578G77HBDT1NInd+aERfxeOPbk0qBZHgoDsQmA2v9TbqJRWzoBPx1aLOhprBMgPjw==", + "optional": true + }, + "@img/sharp-libvips-linux-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.0.tgz", + "integrity": "sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==", + "optional": true + }, + "@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.0.tgz", + "integrity": "sha512-OdorplCyvmSAPsoJLldtLh3nLxRrkAAAOHsGWGDYfN0kh730gifK+UZb3dWORRa6EusNqCTjfXV4GxvgJ/nPDQ==", + "optional": true + }, + "@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.0.tgz", + "integrity": "sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==", + "optional": true + }, + "@img/sharp-linux-arm": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.1.tgz", + "integrity": "sha512-Ii4X1vnzzI4j0+cucsrYA5ctrzU9ciXERfJR633S2r39CiD8npqH2GMj63uFZRCFt3E687IenAdbwIpQOJ5BNA==", + "optional": true, + "requires": { + "@img/sharp-libvips-linux-arm": "1.0.0" + } + }, + "@img/sharp-linux-arm64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.1.tgz", + "integrity": "sha512-59B5GRO2d5N3tIfeGHAbJps7cLpuWEQv/8ySd9109ohQ3kzyCACENkFVAnGPX00HwPTQcaBNF7HQYEfZyZUFfw==", + "optional": true, + "requires": { + "@img/sharp-libvips-linux-arm64": "1.0.0" + } + }, + "@img/sharp-linux-s390x": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.1.tgz", + "integrity": "sha512-tRGrb2pHnFUXpOAj84orYNxHADBDIr0J7rrjwQrTNMQMWA4zy3StKmMvwsI7u3dEZcgwuMMooIIGWEWOjnmG8A==", + "optional": true, + "requires": { + "@img/sharp-libvips-linux-s390x": "1.0.0" + } + }, + "@img/sharp-linux-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.1.tgz", + "integrity": "sha512-4y8osC0cAc1TRpy02yn5omBeloZZwS62fPZ0WUAYQiLhSFSpWJfY/gMrzKzLcHB9ulUV6ExFiu2elMaixKDbeg==", + "optional": true, + "requires": { + "@img/sharp-libvips-linux-x64": "1.0.0" + } + }, + "@img/sharp-linuxmusl-arm64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.1.tgz", + "integrity": "sha512-D3lV6clkqIKUizNS8K6pkuCKNGmWoKlBGh5p0sLO2jQERzbakhu4bVX1Gz+RS4vTZBprKlWaf+/Rdp3ni2jLfA==", + "optional": true, + "requires": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.0" + } + }, + "@img/sharp-linuxmusl-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.1.tgz", + "integrity": "sha512-LOGKNu5w8uu1evVqUAUKTix2sQu1XDRIYbsi5Q0c/SrXhvJ4QyOx+GaajxmOg5PZSsSnCYPSmhjHHsRBx06/wQ==", + "optional": true, + "requires": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.0" + } + }, + "@img/sharp-wasm32": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.1.tgz", + "integrity": "sha512-vWI/sA+0p+92DLkpAMb5T6I8dg4z2vzCUnp8yvxHlwBpzN8CIcO3xlSXrLltSvK6iMsVMNswAv+ub77rsf25lA==", + "optional": true, + "requires": { + "@emnapi/runtime": "^0.44.0" + } + }, + "@img/sharp-win32-ia32": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.1.tgz", + "integrity": "sha512-/xhYkylsKL05R+NXGJc9xr2Tuw6WIVl2lubFJaFYfW4/MQ4J+dgjIo/T4qjNRizrqs/szF/lC9a5+updmY9jaQ==", + "optional": true + }, + "@img/sharp-win32-x64": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.1.tgz", + "integrity": "sha512-XaM69X0n6kTEsp9tVYYLhXdg7Qj32vYJlAKRutxUsm1UlgQNx6BOhHwZPwukCGXBU2+tH87ip2eV1I/E8MQnZg==", + "optional": true + }, "@jridgewell/resolve-uri": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", @@ -3134,11 +3398,13 @@ "dev": true }, "@types/node": { - "version": "20.7.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.2.tgz", - "integrity": "sha512-RcdC3hOBOauLP+r/kRt27NrByYtDjsXyAuSbR87O6xpsvi763WI+5fbSIvYJrXnt9w4RuxhV6eAXfIs7aaf/FQ==", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dev": true, - "peer": true + "requires": { + "undici-types": "~5.26.4" + } }, "@types/semver": { "version": "7.5.3", @@ -3322,27 +3588,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, "big-integer": { "version": "1.6.51", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", "dev": true }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, "bplist-parser": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", @@ -3371,15 +3622,6 @@ "fill-range": "^7.0.1" } }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", @@ -3411,11 +3653,6 @@ "supports-color": "^7.1.0" } }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, "color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -3489,19 +3726,6 @@ "ms": "2.1.2" } }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "requires": { - "mimic-response": "^3.1.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -3570,14 +3794,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3737,11 +3953,6 @@ "strip-final-newline": "^3.0.0" } }, - "expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3851,11 +4062,6 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -3878,11 +4084,6 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" - }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3952,11 +4153,6 @@ "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -3992,12 +4188,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "is-arrayish": { "version": "0.3.2", @@ -4213,11 +4405,6 @@ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true }, - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" - }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4227,45 +4414,17 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node-abi": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.47.0.tgz", - "integrity": "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A==", - "requires": { - "semver": "^7.3.5" - } - }, - "node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" - }, "node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -4295,6 +4454,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "requires": { "wrappy": "1" } @@ -4397,25 +4557,6 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", - "requires": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - } - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4437,15 +4578,6 @@ "fast-diff": "^1.1.2" } }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -4458,27 +4590,6 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -4584,11 +4695,6 @@ "queue-microtask": "^1.2.2" } }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, "semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -4598,18 +4704,32 @@ } }, "sharp": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.1.tgz", - "integrity": "sha512-GR8M1wBwOiFKLkm9JPun27OQnNRZdHfSf9VwcdZX6UrRmM1/XnOrLFTF0GAil+y/YK4E6qcM/ugxs80QirsHxg==", + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.1.tgz", + "integrity": "sha512-iAYUnOdTqqZDb3QjMneBKINTllCJDZ3em6WaWy7NPECM4aHncvqHRm0v0bN9nqJxMiwamv5KIdauJ6lUzKDpTQ==", "requires": { + "@img/sharp-darwin-arm64": "0.33.1", + "@img/sharp-darwin-x64": "0.33.1", + "@img/sharp-libvips-darwin-arm64": "1.0.0", + "@img/sharp-libvips-darwin-x64": "1.0.0", + "@img/sharp-libvips-linux-arm": "1.0.0", + "@img/sharp-libvips-linux-arm64": "1.0.0", + "@img/sharp-libvips-linux-s390x": "1.0.0", + "@img/sharp-libvips-linux-x64": "1.0.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.0", + "@img/sharp-libvips-linuxmusl-x64": "1.0.0", + "@img/sharp-linux-arm": "0.33.1", + "@img/sharp-linux-arm64": "0.33.1", + "@img/sharp-linux-s390x": "0.33.1", + "@img/sharp-linux-x64": "0.33.1", + "@img/sharp-linuxmusl-arm64": "0.33.1", + "@img/sharp-linuxmusl-x64": "0.33.1", + "@img/sharp-wasm32": "0.33.1", + "@img/sharp-win32-ia32": "0.33.1", + "@img/sharp-win32-x64": "0.33.1", "color": "^4.2.3", - "detect-libc": "^2.0.1", - "node-addon-api": "^5.0.0", - "prebuild-install": "^7.1.1", - "semver": "^7.3.7", - "simple-get": "^4.0.1", - "tar-fs": "^2.1.1", - "tunnel-agent": "^0.6.0" + "detect-libc": "^2.0.2", + "semver": "^7.5.4" } }, "shebang-command": { @@ -4633,21 +4753,6 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" - }, - "simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "requires": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -4694,14 +4799,6 @@ "fs-extra": "^8.1.0" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4717,11 +4814,6 @@ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" - }, "strnum": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", @@ -4746,29 +4838,6 @@ "tslib": "^2.5.0" } }, - "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4827,15 +4896,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "requires": { - "safe-buffer": "^5.0.1" - } + "devOptional": true }, "twitter-api-v2": { "version": "1.15.2", @@ -4863,6 +4924,12 @@ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -4883,11 +4950,6 @@ "punycode": "^2.1.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -4920,7 +4982,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true }, "yallist": { "version": "4.0.0", diff --git a/package.json b/package.json index e54db88..da6ed39 100644 --- a/package.json +++ b/package.json @@ -26,10 +26,11 @@ "fast-xml-parser": "^4.3.2", "log4js": "^6.9.1", "node-fetch": "^2.6.7", - "sharp": "0.31.1", + "sharp": "0.33.1", "twitter-api-v2": "^1.15.2" }, "devDependencies": { + "@types/node": "^20.10.5", "@typescript-eslint/eslint-plugin": "^6.7.5", "@typescript-eslint/parser": "^6.7.5", "eslint": "^8.51.0", diff --git a/src/cli.ts b/src/cli.ts index 5408d0e..8f1d518 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -105,8 +105,12 @@ async function main() { } case "get-folder": { const folder = feed.getFolder(FOLDER); - report += folder.report() + "\n"; - result = folder; + if (folder) { + report += folder.report() + "\n"; + result = folder; + } else { + report += "not found:" + FOLDER + "\n"; + } break; } case "get-folders": { @@ -120,8 +124,12 @@ async function main() { } case "get-post": { const post = feed.getPost(FOLDER, PLATFORM); - report += post.report(); - result = post; + if (post) { + report += post.report(); + result = post; + } else { + report += "Not found:" + FOLDER + ":" + PLATFORM; + } break; } case "get-posts": { @@ -139,8 +147,12 @@ async function main() { } case "prepare-post": { const preppost = await feed.preparePost(FOLDER, PLATFORM); - report += preppost.report(); - result = preppost; + if (preppost) { + report += preppost.report(); + result = preppost; + } else { + report += "Failed: " + FOLDER + ":" + PLATFORM; + } break; } case "prepare-posts": { @@ -257,7 +269,7 @@ async function main() { } } } catch (e) { - console.error(e.message); + console.error((e as Error).message ?? e); } switch (REPORT) { diff --git a/src/models/Feed.ts b/src/models/Feed.ts index 9ed1d45..deb1b4f 100644 --- a/src/models/Feed.ts +++ b/src/models/Feed.ts @@ -56,7 +56,7 @@ export default class Feed { report += "\n - folders: " + this.getFolders() - .map((f) => f.path) + .map((f) => f.id) .join(); return report; } @@ -81,7 +81,7 @@ export default class Feed { platformsIds?: PlatformId[], ): Promise<{ [id: string]: unknown }> { Logger.trace("Feed", "setupPlatforms", platformsIds); - const results = {}; + const results = {} as { [id: string]: unknown }; for (const platformId of platformsIds ?? (Object.keys(this.platforms) as PlatformId[])) { results[platformId] = await this.setupPlatform(platformId); @@ -134,7 +134,7 @@ export default class Feed { platformsIds?: PlatformId[], ): Promise<{ [id: string]: unknown }> { Logger.trace("Feed", "testPlatforms", platformsIds); - const results = {}; + const results = {} as { [id: string]: unknown }; for (const platformId of platformsIds ?? (Object.keys(this.platforms) as PlatformId[])) { results[platformId] = await this.testPlatform(platformId); @@ -161,7 +161,7 @@ export default class Feed { platformsIds?: PlatformId[], ): Promise<{ [id: string]: boolean }> { Logger.trace("Feed", "refreshPlatforms", platformsIds); - const results = {}; + const results = {} as { [id: string]: boolean }; for (const platformId of platformsIds ?? (Object.keys(this.platforms) as PlatformId[])) { results[platformId] = await this.refreshPlatform(platformId); @@ -313,6 +313,9 @@ export default class Feed { schedulePost(path: string, platformId: PlatformId, date: Date): Post { Logger.trace("Feed", "schedulePost", path, platformId, date); const post = this.getPost(path, platformId); + if (!post) { + throw Logger.error("Post not found"); + } if (!post.valid) { throw Logger.error("Post is not valid"); } @@ -350,6 +353,9 @@ export default class Feed { for (const platform of platforms) { for (const folder of folders) { const post = platform.getPost(folder); + if (!post) { + throw Logger.error("Post not found"); + } if (!post.valid) { throw Logger.error("Post is not valid"); } @@ -385,7 +391,13 @@ export default class Feed { const now = new Date(); const platform = this.getPlatform(platformId); const folder = this.getFolder(path); + if (!folder) { + throw Logger.error("Folder not found", path); + } const post = platform.getPost(folder); + if (!post) { + throw Logger.error("Post not found", path, platformId); + } if (!post.valid) { throw Logger.error("Post is not valid"); } @@ -421,17 +433,21 @@ export default class Feed { for (const platform of platforms) { for (const folder of folders) { const post = platform.getPost(folder); - if (post.valid) { - if (!post.skip) { - post.schedule(now); - Logger.trace("Posting", post.id); - await platform.publishPost(post, dryrun); - posts.push(post); + if (post) { + if (post.valid) { + if (!post.skip) { + post.schedule(now); + Logger.trace("Posting", post.id); + await platform.publishPost(post, dryrun); + posts.push(post); + } else { + Logger.warn("Skipping post marked skip", post.id); + } } else { - Logger.warn("Skipping post marked skip", post.id); + Logger.warn("Skipping invalid post", post.id); } } else { - Logger.warn("Skipping invalid post", post.id); + Logger.warn("Skipping post not found", folder.id, platform.id); } } } @@ -449,14 +465,20 @@ export default class Feed { */ getLastPost(platformId: PlatformId): Post | void { Logger.trace("Feed", "getLastPost"); - let lastPost: Post = undefined; + let lastPost: Post | undefined = undefined; const posts = this.getPosts({ platforms: [platformId], status: PostStatus.PUBLISHED, }); for (const post of posts) { - if (!lastPost || post.published >= lastPost.published) { - lastPost = post; + if (post.published) { + if ( + !lastPost || + !lastPost.published || + post.published >= lastPost.published + ) { + lastPost = post; + } } } return lastPost; @@ -474,7 +496,7 @@ export default class Feed { Logger.trace("Feed", "getNextPostDate"); let nextDate = null; const lastPost = this.getLastPost(platformId); - if (lastPost) { + if (lastPost && lastPost.published) { nextDate = new Date(lastPost.published); nextDate.setDate(nextDate.getDate() + this.interval); } else { @@ -553,6 +575,15 @@ export default class Feed { for (const folder of folders) { const post = platform.getPost(folder); if (post && post.status === PostStatus.SCHEDULED) { + if (!post.scheduled) { + Logger.warn( + "Not publishing scheduled post without date. Unscheduling post.", + post.id, + ); + post.status = PostStatus.UNSCHEDULED; + post.save(); + continue; + } if (post.skip) { Logger.warn( "Not publishing scheduled post marked skip. Unscheduling post.", diff --git a/src/models/Folder.ts b/src/models/Folder.ts index 1690520..13e8849 100644 --- a/src/models/Folder.ts +++ b/src/models/Folder.ts @@ -17,6 +17,9 @@ export default class Folder { files?: FileInfo[]; constructor(path: string) { + if (!fs.statSync(path).isDirectory()) { + throw Logger.error("No such folder: " + path); + } this.id = path.replace(/^\//, "").split("/").slice(1).join("/"); this.path = path; } @@ -35,23 +38,6 @@ export default class Folder { return report; } - /** - * Get the filenames in this folder - * @returns array of filenames relative to folder - */ - - getFileNames(): string[] { - Logger.trace("Folder", "getFileNames"); - if (this.files !== undefined) { - return this.files.map((file) => file.name); - } - const files = fs.readdirSync(this.path).filter((file) => { - const regex = /^[^._]/; - return fs.statSync(this.path + "/" + file).isFile() && file.match(regex); - }); - return files; - } - /** * Get the files in this folder * @@ -59,7 +45,7 @@ export default class Folder { * @returns array of fileinfo for all files in this folder */ - async getFiles(): Promise { + public async getFiles(): Promise { Logger.trace("Folder", "getFiles"); if (this.files !== undefined) { return structuredClone(this.files); @@ -67,15 +53,21 @@ export default class Folder { const fileNames = this.getFileNames(); this.files = []; for (let index = 0; index < fileNames.length; index++) { - this.files.push(await this.getFile(fileNames[index], index)); + this.files.push(await this.getFileInfo(fileNames[index], index)); } return structuredClone(this.files); } - public async getFile(name: string, order: number): Promise { + /** + * Get info for a single file + * @param name - name of the file in this folder + * @param order - order to set on this file + * @returns fileinfo object for the file + */ + public async getFileInfo(name: string, order: number): Promise { Logger.trace("Folder", "getFile", name); const filepath = this.path + "/" + name; - const mime = Folder.guessMimeType(name); + const mime = this.guessMimeType(name); const group = mime !== "application/unknown" ? mime.split("/")[0] : "other"; const stats = fs.statSync(filepath); const extension = path.extname(name); @@ -96,8 +88,25 @@ export default class Folder { return file; } - public static guessMimeType(filename: string) { - const extension = path.extname(filename); + /** + * Get the filenames in this folder + * @returns array of filenames relative to folder + */ + + private getFileNames(): string[] { + Logger.trace("Folder", "getFileNames"); + if (this.files !== undefined) { + return this.files.map((file) => file.name); + } + const files = fs.readdirSync(this.path).filter((file) => { + const regex = /^[^._]/; + return fs.statSync(this.path + "/" + file).isFile() && file.match(regex); + }); + return files; + } + + private guessMimeType(filename: string): string { + const extension = path.extname(filename).toLowerCase(); const mimeTypes = { ".txt": "text/plain", ".png": "image/png", @@ -106,8 +115,11 @@ export default class Folder { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", - }; - return mimeTypes[extension.toLowerCase()] ?? "application/unknown"; + } as { [ext: string]: string }; + if (extension in mimeTypes) { + return mimeTypes[extension]; + } + return "application/unknown"; } } diff --git a/src/models/Platform.ts b/src/models/Platform.ts index 0841424..32b9a85 100644 --- a/src/models/Platform.ts +++ b/src/models/Platform.ts @@ -199,10 +199,7 @@ export default class Platform { * publishPost * * - publish the post for this platform, sync. - * - set the posted date to now. - * - add the result to post.results - * - on success, set the status to published and return true, - * - else set the status to failed and return false + * - when done, pass the result to post.processResult() * * do not throw errors, instead catch and log them, and * set the post to failed. @@ -211,15 +208,12 @@ export default class Platform { async publishPost(post: Post, dryrun: boolean = false): Promise { Logger.trace("Platform", "publishPost", post.id, dryrun); - post.results.push({ + return post.processResult("-99", "#undefined", { date: new Date(), + dryrun: dryrun, success: false, - error: new Error("publishing not implemented for " + this.id), response: {}, + error: new Error("publishing not implemented for " + this.id), }); - post.published = undefined; - post.status = PostStatus.FAILED; - post.save(); - return false; } } diff --git a/src/models/Post.ts b/src/models/Post.ts index affc875..30d7c3a 100644 --- a/src/models/Post.ts +++ b/src/models/Post.ts @@ -75,7 +75,8 @@ export default class Post { save(): void { Logger.trace("Post", "save"); - const data = { ...this }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const data = { ...this } as { [key: string]: any }; delete data.folder; delete data.platform; fs.writeFileSync( @@ -104,12 +105,13 @@ export default class Post { * Does not save. */ decompileBody() { - const lines = this.body.split("\n"); + const lines = this.body?.trim().split("\n") ?? []; // chop title - const title = lines.shift(); + const title = lines[0]; if (!this.title || this.title === title) { - this.title = title; + this.title = title ?? ""; + lines.shift(); this.body = lines.join("\n"); } @@ -123,7 +125,7 @@ export default class Post { const rxgeo = /^%geo\s+(.*)/i; let line = ""; while (lines.length) { - line = lines.pop(); + line = lines.pop() ?? ""; if (!line.trim()) { this.body = lines.join("\n"); @@ -132,7 +134,7 @@ export default class Post { if (line.match(rxtags)) { const tags = line.match(rxtag); - if (!this.tags?.length || isSimilarArray(tags, this.tags)) { + if (tags && (!this.tags?.length || isSimilarArray(tags, this.tags))) { this.tags = tags; this.body = lines.join("\n"); } @@ -141,7 +143,10 @@ export default class Post { if (line.match(rxmentions)) { const mentions = line.match(rxmention); - if (!this.mentions?.length || isSimilarArray(mentions, this.mentions)) { + if ( + mentions && + (!this.mentions?.length || isSimilarArray(mentions, this.mentions)) + ) { this.mentions = mentions; this.body = lines.join("\n"); } @@ -149,7 +154,7 @@ export default class Post { } if (line.match(rxgeo)) { - const geo = line.match(rxgeo)[1] ?? ""; + const geo = line.match(rxgeo)?.[1] ?? ""; if (!this.geo || this.geo === geo) { this.geo = geo; this.body = lines.join("\n"); @@ -207,10 +212,15 @@ export default class Post { * @returns the files grouped by their group property */ getGroupedFiles(): { [group: string]: FileInfo[] } { - return this.files.reduce(function (collector, file) { - (collector[file["group"]] = collector[file["group"]] || []).push(file); - return collector; - }, {}); + return ( + this.files?.reduce(function ( + collector: { [group: string]: FileInfo[] }, + file: FileInfo, + ) { + (collector[file["group"]] = collector[file["group"]] || []).push(file); + return collector; + }, {}) ?? {} + ); } /** @@ -219,11 +229,13 @@ export default class Post { */ getFiles(...groups: string[]): FileInfo[] { if (!groups.length) { - return this.files.sort((a, b) => a.order - b.order); + return this.files?.sort((a, b) => a.order - b.order) ?? []; } - return this.files - .filter((file) => groups.includes(file.group)) - .sort((a, b) => a.order - b.order); + return ( + this.files + ?.filter((file) => groups.includes(file.group)) + .sort((a, b) => a.order - b.order) ?? [] + ); } /** @@ -232,9 +244,11 @@ export default class Post { */ hasFiles(...groups: string[]): boolean { if (!groups.length) { - return !!this.files.length; + return !!(this.files?.length ?? 0); } - return !!this.files.filter((file) => groups.includes(file.group)).length; + return !!( + this.files?.filter((file) => groups.includes(file.group)).length ?? 0 + ); } /** @@ -242,7 +256,7 @@ export default class Post { * Does not save. */ removeFiles(group: string) { - this.files = this.files.filter((file) => file.group !== group); + this.files = this.files?.filter((file) => file.group !== group); } /** @@ -290,7 +304,7 @@ export default class Post { */ reorderFiles() { this.files - .sort((a, b) => a.order - b.order) + ?.sort((a, b) => a.order - b.order) .forEach((file, index) => { file.order = index; }); @@ -309,7 +323,7 @@ export default class Post { * @returns the files info if any */ getFile(name: string): FileInfo | undefined { - return this.files.find((file) => file.name === name); + return this.files?.find((file) => file.name === name); } /** @@ -317,13 +331,14 @@ export default class Post { * Does not save. */ putFile(file: FileInfo) { - const oldFile = this.files.find( + const oldFile = this.files?.find( (oldfile) => oldfile.name === file.name || oldfile.original === file.name, ); if (oldFile) { file.order = oldFile.order; this.removeFile(oldFile.name); } + if (!this.files) this.files = []; this.files.push(file); } @@ -332,7 +347,7 @@ export default class Post { * Does not save. */ removeFile(name: string) { - this.files = this.files.filter((file) => file.name !== name); + this.files = this.files?.filter((file) => file.name !== name); } /** @@ -345,15 +360,20 @@ export default class Post { * @param replace - the name of the file to replace it with * @returns the info of the replaced file */ - async replaceFile(search: string, replace: string): Promise { - const index = this.files.findIndex((file) => file.name === search); + async replaceFile( + search: string, + replace: string, + ): Promise { + const index = this.files?.findIndex((file) => file.name === search) ?? -1; if (index > -1) { const oldFile = this.getFile(search); - const newFile = await this.folder.getFile(replace, oldFile.order); - newFile.original = oldFile.name; - this.files[index] = newFile; + if (this.files && oldFile) { + const newFile = await this.folder.getFileInfo(replace, oldFile.order); + newFile.original = oldFile.name; + this.files[index] = newFile; + return this.files[index]; + } } - return this.files[index]; } /** diff --git a/src/platforms/Ayrshare/AsFacebook.ts b/src/platforms/Ayrshare/AsFacebook.ts index 9a7e099..0a3f348 100644 --- a/src/platforms/Ayrshare/AsFacebook.ts +++ b/src/platforms/Ayrshare/AsFacebook.ts @@ -17,7 +17,7 @@ export default class AsFacebook extends Ayrshare { super(); } - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { const post = await super.preparePost(folder); if (post) { // facebook : max 10mb images diff --git a/src/platforms/Ayrshare/AsInstagram.ts b/src/platforms/Ayrshare/AsInstagram.ts index cb7ef8c..9d1b762 100644 --- a/src/platforms/Ayrshare/AsInstagram.ts +++ b/src/platforms/Ayrshare/AsInstagram.ts @@ -18,7 +18,7 @@ export default class AsInstagram extends Ayrshare { super(); } - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { const post = await super.preparePost(folder); if (post && post.files) { if (post.getFiles("video").length > 10) { @@ -34,7 +34,7 @@ export default class AsInstagram extends Ayrshare { // instagram : scale images, jpeg only for (const file of post.getFiles("image")) { const src = file.name; - if (file.width > 1440) { + if (file.width && file.width > 1440) { Logger.trace("Resizing " + src + " for instagram .."); const dst = this.assetsFolder + "/instagram-" + file.basename + ".JPEG"; diff --git a/src/platforms/Ayrshare/AsLinkedIn.ts b/src/platforms/Ayrshare/AsLinkedIn.ts index 7e81a62..c9a72d3 100644 --- a/src/platforms/Ayrshare/AsLinkedIn.ts +++ b/src/platforms/Ayrshare/AsLinkedIn.ts @@ -18,7 +18,7 @@ export default class AsLinkedIn extends Ayrshare { super(); } - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { const post = await super.preparePost(folder); if (post) { // linkedin: max 9 media diff --git a/src/platforms/Ayrshare/AsReddit.ts b/src/platforms/Ayrshare/AsReddit.ts index b8cc17a..d3df479 100644 --- a/src/platforms/Ayrshare/AsReddit.ts +++ b/src/platforms/Ayrshare/AsReddit.ts @@ -19,7 +19,7 @@ export default class AsReddit extends Ayrshare { this.SUBREDDIT = Storage.get("settings", "AYRSHARE_SUBREDDIT", ""); } - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { const post = await super.preparePost(folder); if (post) { // reddit: max 1 image, no video diff --git a/src/platforms/Ayrshare/AsTikTok.ts b/src/platforms/Ayrshare/AsTikTok.ts index 3149a4e..dd7b892 100644 --- a/src/platforms/Ayrshare/AsTikTok.ts +++ b/src/platforms/Ayrshare/AsTikTok.ts @@ -15,7 +15,7 @@ export default class AsTikTok extends Ayrshare { super(); } - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { const post = await super.preparePost(folder); if (post) { // tiktok: one video diff --git a/src/platforms/Ayrshare/AsTwitter.ts b/src/platforms/Ayrshare/AsTwitter.ts index eac5d31..4664adb 100644 --- a/src/platforms/Ayrshare/AsTwitter.ts +++ b/src/platforms/Ayrshare/AsTwitter.ts @@ -18,7 +18,7 @@ export default class AsTwitter extends Ayrshare { super(); } - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { const post = await super.preparePost(folder); if (post) { // twitter: no video diff --git a/src/platforms/Ayrshare/AsYouTube.ts b/src/platforms/Ayrshare/AsYouTube.ts index 5ce793a..fa7af13 100644 --- a/src/platforms/Ayrshare/AsYouTube.ts +++ b/src/platforms/Ayrshare/AsYouTube.ts @@ -15,7 +15,7 @@ export default class AsYouTube extends Ayrshare { super(); } - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { const post = await super.preparePost(folder); if (post) { // youtube: only 1 video diff --git a/src/platforms/Ayrshare/Ayrshare.ts b/src/platforms/Ayrshare/Ayrshare.ts index 5be1099..f08adc6 100644 --- a/src/platforms/Ayrshare/Ayrshare.ts +++ b/src/platforms/Ayrshare/Ayrshare.ts @@ -56,7 +56,7 @@ export default abstract class Ayrshare extends Platform { } /** @inheritdoc */ - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { return super.preparePost(folder); } @@ -90,7 +90,7 @@ export default abstract class Ayrshare extends Platform { response = await this.postAyrshare(post, platformOptions, uploads); } } catch (e) { - error = e; + error = e as Error; } return post.processResult( diff --git a/src/platforms/Facebook/Facebook.ts b/src/platforms/Facebook/Facebook.ts index 8bc41a7..5b48740 100644 --- a/src/platforms/Facebook/Facebook.ts +++ b/src/platforms/Facebook/Facebook.ts @@ -43,7 +43,7 @@ export default class Facebook extends Platform { } /** @inheritdoc */ - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { Logger.trace("Facebook.preparePost", folder.id); const post = await super.preparePost(folder); if (post && post.files) { @@ -77,25 +77,25 @@ export default class Facebook extends Platform { Logger.trace("Facebook.publishPost", post.id, dryrun); let response = { id: "-99" } as { id: string }; - let error = undefined; + let error = undefined as Error | undefined; if (post.hasFiles("video")) { try { response = await this.publishVideoPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else if (post.hasFiles("image")) { try { response = await this.publishImagesPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else { try { response = await this.publishTextPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } diff --git a/src/platforms/Facebook/FacebookAuth.ts b/src/platforms/Facebook/FacebookAuth.ts index c7fa58f..5d59ae0 100644 --- a/src/platforms/Facebook/FacebookAuth.ts +++ b/src/platforms/Facebook/FacebookAuth.ts @@ -34,7 +34,7 @@ export default class FacebookAuth { } protected async requestCode(clientId: string): Promise { - Logger.trace('FacebookAuth','requestCode'); + Logger.trace("FacebookAuth", "requestCode"); const state = String(Math.random()).substring(2); // create auth url @@ -80,7 +80,7 @@ export default class FacebookAuth { clientId: string, clientSecret: string, ): Promise { - Logger.trace('FacebookAuth','exchangeCode'); + Logger.trace("FacebookAuth", "exchangeCode"); const redirectUri = OAuth2Service.getCallbackUrl(); const tokens = (await this.get("oauth/access_token", { @@ -118,7 +118,7 @@ export default class FacebookAuth { pageId: string, userAccessToken: string, ): Promise { - Logger.trace('FacebookAuth','getLLPageToken'); + Logger.trace("FacebookAuth", "getLLPageToken"); const appUserId = await this.getAppUserId(userAccessToken); const llUserAccessToken = await this.getLLUserAccessToken( appId, @@ -143,9 +143,7 @@ export default class FacebookAuth { data, ); } - const llPageAccessToken = pageData[ - "access_token" - ]; + const llPageAccessToken = pageData["access_token"]; if (!llPageAccessToken) { throw Logger.error( @@ -169,7 +167,7 @@ export default class FacebookAuth { appSecret: string, userAccessToken: string, ): Promise { - Logger.trace('FacebookAuth','getLLUserAccessToken'); + Logger.trace("FacebookAuth", "getLLUserAccessToken"); const query = { grant_type: "fb_exchange_token", client_id: appId, @@ -196,7 +194,7 @@ export default class FacebookAuth { * @returns the app scoped user id ('me') */ private async getAppUserId(accessToken: string): Promise { - Logger.trace('FacebookAuth','getAppUserId'); + Logger.trace("FacebookAuth", "getAppUserId"); const query = { fields: "id,name", access_token: accessToken, diff --git a/src/platforms/Instagram/Instagram.ts b/src/platforms/Instagram/Instagram.ts index e79f66d..5ebfb4b 100644 --- a/src/platforms/Instagram/Instagram.ts +++ b/src/platforms/Instagram/Instagram.ts @@ -42,7 +42,7 @@ export default class Instagram extends Platform { } /** @inheritdoc */ - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { Logger.trace("Instagram.preparePost", folder.id); const post = await super.preparePost(folder); if (post && post.files) { @@ -62,7 +62,7 @@ export default class Instagram extends Platform { // instagram : scale images, jpeg only for (const file of post.getFiles("image")) { - if (file.width > 1440) { + if (file.width && file.width > 1440) { const src = file.name; const dst = this.assetsFolder + "/instagram-" + file.basename + ".JPEG"; @@ -90,25 +90,25 @@ export default class Instagram extends Platform { Logger.trace("Instagram.publishPost", post.id, dryrun); let response = { id: "-99" } as { id: string }; - let error = undefined; + let error = undefined as Error | undefined; if (post.getFiles("video").length === 1 && !post.hasFiles("image")) { try { response = await this.publishVideoPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else if (post.getFiles("image").length === 1 && !post.hasFiles("video")) { try { response = await this.publishImagePost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else { try { response = await this.publishMixedPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } @@ -224,10 +224,10 @@ export default class Instagram extends Platform { const videoLink = await this.getVideoLink(videoId); uploadIds.push( ( - await this.api.postJson("%USER%/media", { + (await this.api.postJson("%USER%/media", { is_carousel_item: true, video_url: videoLink, - }) + })) as { id: string } )["id"], ); } @@ -238,10 +238,10 @@ export default class Instagram extends Platform { const photoLink = await this.getImageLink(photoId); uploadIds.push( ( - await this.api.postJson("%USER%/media", { + (await this.api.postJson("%USER%/media", { is_carousel_item: true, image_url: photoLink, - }) + })) as { id: string } )["id"], ); } diff --git a/src/platforms/LinkedIn/LinkedIn.ts b/src/platforms/LinkedIn/LinkedIn.ts index 00a6011..e0666b2 100644 --- a/src/platforms/LinkedIn/LinkedIn.ts +++ b/src/platforms/LinkedIn/LinkedIn.ts @@ -93,36 +93,36 @@ export default class LinkedIn extends Platform { id?: string; headers?: { [key: string]: string }; }; - let error = undefined; + let error = undefined as Error | undefined; if (post.hasFiles("video")) { try { response = await this.publishVideoPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else if (post.getFiles("image").length > 1) { try { response = await this.publishImagesPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else if (post.getFiles("image").length === 1) { try { response = await this.publishImagePost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else { try { response = await this.publishTextPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } return post.processResult( - response.id, + response.id as string, "https://www.linkedin.com/feed/update/" + response.id, { date: new Date(), @@ -141,7 +141,13 @@ export default class LinkedIn extends Platform { * @returns object, incl. some ids and names */ private async getProfile() { - const me = await this.api.get("me"); + const me = (await this.api.get("me")) as { + id: string; + localizedFirstName: string; + localizedLastName: string; + localizedHeadline: string; + vanityName: string; + }; if (!me) return false; return { id: me["id"], diff --git a/src/platforms/LinkedIn/LinkedInApi.ts b/src/platforms/LinkedIn/LinkedInApi.ts index d43ff07..8857c69 100644 --- a/src/platforms/LinkedIn/LinkedInApi.ts +++ b/src/platforms/LinkedIn/LinkedInApi.ts @@ -85,14 +85,21 @@ export default class LinkedInApi { : handleJsonResponse(res, true), ) .then((res) => { - if (!res["id"] && "headers" in res) { - if (res.headers?.["x-restli-id"]) { - res["id"] = res.headers["x-restli-id"]; - } else if (res.headers?.["x-linkedin-id"]) { - res["id"] = res.headers["x-linkedin-id"]; + const linkedinRes = res as { + id?: string; + headers?: { + "x-restli-id"?: string; + "x-linkedin-id"?: string; + }; + }; + if (!linkedinRes["id"] && "headers" in linkedinRes) { + if (linkedinRes.headers?.["x-restli-id"]) { + linkedinRes["id"] = linkedinRes.headers["x-restli-id"]; + } else if (linkedinRes.headers?.["x-linkedin-id"]) { + linkedinRes["id"] = linkedinRes.headers["x-linkedin-id"]; } } - return res; + return linkedinRes; }) .catch((err) => this.handleLinkedInError(err)) .catch((err) => handleApiError(err)); @@ -114,9 +121,12 @@ export default class LinkedInApi { ") " + error.responseData.message; } - if (error.response?.headers?.["x-linkedin-error-response"]) { + if ( + error.response?.headers && + "x-linkedin-error-response" in error.response.headers + ) { error.message += - " - " + error.response?.headers["x-linkedin-error-response"]; + " - " + error.response.headers["x-linkedin-error-response"]; } throw error; diff --git a/src/platforms/Reddit/Reddit.ts b/src/platforms/Reddit/Reddit.ts index acb21da..0ebd39a 100644 --- a/src/platforms/Reddit/Reddit.ts +++ b/src/platforms/Reddit/Reddit.ts @@ -38,7 +38,10 @@ export default class Reddit extends Platform { /** @inheritdoc */ async test() { - const me = await this.api.get("me"); + const me = (await this.api.get("me")) as { + id: string; + name: string; + }; if (!me) return false; return { id: me["id"], @@ -53,7 +56,7 @@ export default class Reddit extends Platform { } /** @inheritdoc */ - async preparePost(folder: Folder): Promise { + async preparePost(folder: Folder): Promise { Logger.trace("Reddit.preparePost", folder.id); const post = await super.preparePost(folder); if (post) { @@ -68,7 +71,7 @@ export default class Reddit extends Platform { // 20971520 const file = post.getFiles("image")[0]; const src = file.name; - if (file.width > 3000) { + if (file.width && file.width > 3000) { Logger.trace("Resizing " + src + " for reddit .."); const dst = this.assetsFolder + "/reddit-" + file.basename + ".jpg"; await sharp(post.getFilePath(src)) @@ -89,25 +92,25 @@ export default class Reddit extends Platform { Logger.trace("Reddit.publishPost", post.id, dryrun); let response = {}; - let error = undefined; + let error = undefined as Error | undefined; if (post.hasFiles("video")) { try { response = await this.publishVideoPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else if (post.hasFiles("image")) { try { response = await this.publishImagePost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else { try { response = await this.publishTextPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } @@ -166,8 +169,9 @@ export default class Reddit extends Platform { private async publishImagePost(post: Post, dryrun = false): Promise { Logger.trace("Reddit.publishImagePost"); const title = post.title; - const file = post.getFilePath(post.getFiles("image")[0].name); - const leash = await this.getUploadLeash(file); + const image = post.getFiles("image")[0]; + const file = post.getFilePath(image.name); + const leash = await this.getUploadLeash(file, image.mimetype); const imageUrl = await this.uploadFile(leash, file); if (!dryrun) { return (await this.api.post("submit", { @@ -201,8 +205,9 @@ export default class Reddit extends Platform { private async publishVideoPost(post: Post, dryrun = false): Promise { Logger.trace("Reddit.publishVideoPost"); const title = post.title; - const file = post.getFilePath(post.getFiles("video")[0].name); - const leash = await this.getUploadLeash(file); + const video = post.getFiles("video")[0]; + const file = post.getFilePath(video.name); + const leash = await this.getUploadLeash(file, video.mimetype); const videoUrl = await this.uploadFile(leash, file); if (!dryrun) { return (await this.api.post("submit", { @@ -233,16 +238,19 @@ export default class Reddit extends Platform { * * All these fields should be reposted on the upload * @param file - path to the file to upload + * @param mimetype * @returns leash - args with action and fields */ - private async getUploadLeash(file: string): Promise<{ + private async getUploadLeash( + file: string, + mimetype: string, + ): Promise<{ action: string; fields: { [name: string]: string; }; }> { const filename = path.basename(file); - const mimetype = Folder.guessMimeType(filename); const form = new FormData(); form.append("filepath", filename); diff --git a/src/platforms/Twitter/Twitter.ts b/src/platforms/Twitter/Twitter.ts index cc2a411..b88e590 100644 --- a/src/platforms/Twitter/Twitter.ts +++ b/src/platforms/Twitter/Twitter.ts @@ -89,19 +89,19 @@ export default class Twitter extends Platform { id: string; }; }; - let error = undefined; + let error = undefined as Error | undefined; if (post.hasFiles("image")) { try { response = await this.publishImagesPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } else { try { response = await this.publishTextPost(post, dryrun); } catch (e) { - error = e; + error = e as Error; } } diff --git a/src/platforms/Twitter/TwitterAuth.ts b/src/platforms/Twitter/TwitterAuth.ts index e814098..97f6383 100644 --- a/src/platforms/Twitter/TwitterAuth.ts +++ b/src/platforms/Twitter/TwitterAuth.ts @@ -5,7 +5,7 @@ import { TwitterApi } from "twitter-api-v2"; import { strict as assert } from "assert"; export default class TwitterAuth extends OAuth2Service { - client: TwitterApi; + client?: TwitterApi; /** * Set up Twitter platform diff --git a/src/services/Logger.ts b/src/services/Logger.ts index 4952375..38bd335 100644 --- a/src/services/Logger.ts +++ b/src/services/Logger.ts @@ -49,25 +49,31 @@ class Logger { } return Logger.instance; } - trace(...args) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + trace(...args: any[]) { this.logger.trace(args); } - debug(...args) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + debug(...args: any[]) { this.logger.debug(args); } - info(...args) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + info(...args: any[]) { this.logger.info(args); } - warn(...args) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + warn(...args: any[]) { this.logger.warn(args); } - error(...args): Error { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + error(...args: any[]): Error { this.logger.error(args); return new Error( "Error: " + args.filter((arg) => typeof arg === "string").join("; "), ); } - fatal(...args): Error { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + fatal(...args: any[]): Error { this.logger.fatal(args); const code = parseInt(args[0]); process.exitCode = code || 1; diff --git a/src/services/OAuth2Service.ts b/src/services/OAuth2Service.ts index 1d7d6c4..926102a 100644 --- a/src/services/OAuth2Service.ts +++ b/src/services/OAuth2Service.ts @@ -6,8 +6,8 @@ import Storage from "./Storage"; class DeferredResponseQuery { promise: Promise<{ [key: string]: string | string[] }>; - reject: Function; // eslint-disable-line - resolve: Function; // eslint-disable-line + reject: Function = () => {}; // eslint-disable-line + resolve: Function = () => {}; // eslint-disable-line constructor() { this.promise = new Promise((resolve, reject) => { this.reject = reject; diff --git a/src/utilities.ts b/src/utilities.ts index f22258e..e11a579 100644 --- a/src/utilities.ts +++ b/src/utilities.ts @@ -1,16 +1,18 @@ import Logger from "./services/Logger"; -export function isSimilarArray(a, b) { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function isSimilarArray(a: any, b: any) { a = Array.isArray(a) ? a : []; b = Array.isArray(b) ? b : []; - return a.length === b.length && a.every((el) => b.includes(el)); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return a.length === b.length && a.every((el: any) => b.includes(el)); } export class ApiResponseError extends Error { response: Response; // eslint-disable-next-line @typescript-eslint/no-explicit-any - responseData: any; - responseText: string; + responseData?: any; + responseText?: string; constructor(response: Response, data?: object | string) { super("ApiResponseError: " + response.status + " " + response.statusText); this.response = response; @@ -31,7 +33,7 @@ export async function handleEmptyResponse( response: Response, includeHeaders = false, ): Promise { - const data = {}; + const data = {} as { headers: { [key: string]: string } }; if (includeHeaders) { data["headers"] = {}; for (const [name, value] of response.headers) { @@ -94,7 +96,8 @@ export async function handleFormResponse( response: Response, includeHeaders = false, ): Promise { - const data = Object.fromEntries(await response.formData()) as object; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const data = Object.fromEntries(await response.formData()) as any; if (includeHeaders) { data["headers"] = {}; for (const [name, value] of response.headers) { diff --git a/tsconfig.json b/tsconfig.json index 6163b4b..cce8457 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,6 +3,7 @@ "target": "esnext", "module": "commonjs", "sourceMap": true, + "strict" : true, "outDir": "build" }, "include": [