diff --git a/.gitignore b/.gitignore index 13101b7..274b9d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ -.vscode -node_modules -output +.vscode/ +node_modules/ +output/ tests/* !tests/index.test.js .env config.json +test*.* diff --git a/jsconfig.json b/jsconfig.json index 488dc22..ffd4286 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -6,7 +6,7 @@ "resolveJsonModule": true, "checkJs": true, "strict": true, - "skipLibCheck": true, + "skipLibCheck": false, "noImplicitAny": false, "strictNullChecks": false, "strictPropertyInitialization": false, diff --git a/package.json b/package.json index c415e12..c5dd26a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "author": "Kayo Souza", "name": "insta-downloader", - "version": "3.0.0", + "version": "3.1.0", "description": "An application to download content from Instagram", "main": "src/index.js", "scripts": { @@ -19,18 +19,18 @@ "videos" ], "dependencies": { - "axios": "~1.6.7", + "axios": "~1.6.8", "chalk": "^5.3.0", "commander": "~12.0.0", - "dotenv": "~16.4.4", + "dotenv": "~16.4.5", "mime": "~3.0.0", - "sharp": "~0.33.2" + "sharp": "~0.33.3" }, "devDependencies": { "@types/mime": "~3.0.4", "@types/node": "20.x", "@types/sharp": "~0.31.1", - "typescript": "^5.3.3" + "typescript": "^5.4.4" }, "repository": { "type": "git", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4d11125..b3e2329 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: axios: - specifier: ~1.6.7 - version: 1.6.7 + specifier: ~1.6.8 + version: 1.6.8 chalk: specifier: ^5.3.0 version: 5.3.0 @@ -15,14 +15,14 @@ dependencies: specifier: ~12.0.0 version: 12.0.0 dotenv: - specifier: ~16.4.4 - version: 16.4.4 + specifier: ~16.4.5 + version: 16.4.5 mime: specifier: ~3.0.0 version: 3.0.0 sharp: - specifier: ~0.33.2 - version: 0.33.2 + specifier: ~0.33.3 + version: 0.33.3 devDependencies: '@types/mime': @@ -30,48 +30,48 @@ devDependencies: version: 3.0.4 '@types/node': specifier: 20.x - version: 20.11.19 + version: 20.12.5 '@types/sharp': specifier: ~0.31.1 version: 0.31.1 typescript: - specifier: ^5.3.3 - version: 5.3.3 + specifier: ^5.4.4 + version: 5.4.4 packages: - /@emnapi/runtime@0.45.0: - resolution: {integrity: sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==} + /@emnapi/runtime@1.1.1: + resolution: {integrity: sha512-3bfqkzuR1KLx57nZfjr2NLnFOobvyS0aTszaEGCGqmYMVDRaGvgIZbjGSV/MHSSmLgQ/b9JFHQ5xm5WRZYd+XQ==} requiresBuild: true dependencies: tslib: 2.6.2 dev: false optional: true - /@img/sharp-darwin-arm64@0.33.2: - resolution: {integrity: sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w==} + /@img/sharp-darwin-arm64@0.33.3: + resolution: {integrity: sha512-FaNiGX1MrOuJ3hxuNzWgsT/mg5OHG/Izh59WW2mk1UwYHUwtfbhk5QNKYZgxf0pLOhx9ctGiGa2OykD71vOnSw==} 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'} cpu: [arm64] os: [darwin] requiresBuild: true optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.1 + '@img/sharp-libvips-darwin-arm64': 1.0.2 dev: false optional: true - /@img/sharp-darwin-x64@0.33.2: - resolution: {integrity: sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg==} + /@img/sharp-darwin-x64@0.33.3: + resolution: {integrity: sha512-2QeSl7QDK9ru//YBT4sQkoq7L0EAJZA3rtV+v9p8xTKl4U1bUqTIaCnoC7Ctx2kCjQgwFXDasOtPTCT8eCTXvw==} 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'} cpu: [x64] os: [darwin] requiresBuild: true optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.1 + '@img/sharp-libvips-darwin-x64': 1.0.2 dev: false optional: true - /@img/sharp-libvips-darwin-arm64@1.0.1: - resolution: {integrity: sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw==} + /@img/sharp-libvips-darwin-arm64@1.0.2: + resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==} engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [darwin] @@ -79,8 +79,8 @@ packages: dev: false optional: true - /@img/sharp-libvips-darwin-x64@1.0.1: - resolution: {integrity: sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog==} + /@img/sharp-libvips-darwin-x64@1.0.2: + resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==} engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [darwin] @@ -88,8 +88,8 @@ packages: dev: false optional: true - /@img/sharp-libvips-linux-arm64@1.0.1: - resolution: {integrity: sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA==} + /@img/sharp-libvips-linux-arm64@1.0.2: + resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==} engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] @@ -97,8 +97,8 @@ packages: dev: false optional: true - /@img/sharp-libvips-linux-arm@1.0.1: - resolution: {integrity: sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ==} + /@img/sharp-libvips-linux-arm@1.0.2: + resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==} engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm] os: [linux] @@ -106,8 +106,8 @@ packages: dev: false optional: true - /@img/sharp-libvips-linux-s390x@1.0.1: - resolution: {integrity: sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ==} + /@img/sharp-libvips-linux-s390x@1.0.2: + resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==} engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [s390x] os: [linux] @@ -115,8 +115,8 @@ packages: dev: false optional: true - /@img/sharp-libvips-linux-x64@1.0.1: - resolution: {integrity: sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw==} + /@img/sharp-libvips-linux-x64@1.0.2: + resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==} engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] @@ -124,8 +124,8 @@ packages: dev: false optional: true - /@img/sharp-libvips-linuxmusl-arm64@1.0.1: - resolution: {integrity: sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg==} + /@img/sharp-libvips-linuxmusl-arm64@1.0.2: + resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==} engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] @@ -133,8 +133,8 @@ packages: dev: false optional: true - /@img/sharp-libvips-linuxmusl-x64@1.0.1: - resolution: {integrity: sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw==} + /@img/sharp-libvips-linuxmusl-x64@1.0.2: + resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==} engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] @@ -142,84 +142,84 @@ packages: dev: false optional: true - /@img/sharp-linux-arm64@0.33.2: - resolution: {integrity: sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew==} + /@img/sharp-linux-arm64@0.33.3: + resolution: {integrity: sha512-Zf+sF1jHZJKA6Gor9hoYG2ljr4wo9cY4twaxgFDvlG0Xz9V7sinsPp8pFd1XtlhTzYo0IhDbl3rK7P6MzHpnYA==} 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'} cpu: [arm64] os: [linux] requiresBuild: true optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.1 + '@img/sharp-libvips-linux-arm64': 1.0.2 dev: false optional: true - /@img/sharp-linux-arm@0.33.2: - resolution: {integrity: sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA==} + /@img/sharp-linux-arm@0.33.3: + resolution: {integrity: sha512-Q7Ee3fFSC9P7vUSqVEF0zccJsZ8GiiCJYGWDdhEjdlOeS9/jdkyJ6sUSPj+bL8VuOYFSbofrW0t/86ceVhx32w==} 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'} cpu: [arm] os: [linux] requiresBuild: true optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.1 + '@img/sharp-libvips-linux-arm': 1.0.2 dev: false optional: true - /@img/sharp-linux-s390x@0.33.2: - resolution: {integrity: sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA==} + /@img/sharp-linux-s390x@0.33.3: + resolution: {integrity: sha512-vFk441DKRFepjhTEH20oBlFrHcLjPfI8B0pMIxGm3+yilKyYeHEVvrZhYFdqIseSclIqbQ3SnZMwEMWonY5XFA==} 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'} cpu: [s390x] os: [linux] requiresBuild: true optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.1 + '@img/sharp-libvips-linux-s390x': 1.0.2 dev: false optional: true - /@img/sharp-linux-x64@0.33.2: - resolution: {integrity: sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A==} + /@img/sharp-linux-x64@0.33.3: + resolution: {integrity: sha512-Q4I++herIJxJi+qmbySd072oDPRkCg/SClLEIDh5IL9h1zjhqjv82H0Seupd+q2m0yOfD+/fJnjSoDFtKiHu2g==} 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'} cpu: [x64] os: [linux] requiresBuild: true optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.1 + '@img/sharp-libvips-linux-x64': 1.0.2 dev: false optional: true - /@img/sharp-linuxmusl-arm64@0.33.2: - resolution: {integrity: sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA==} + /@img/sharp-linuxmusl-arm64@0.33.3: + resolution: {integrity: sha512-qnDccehRDXadhM9PM5hLvcPRYqyFCBN31kq+ErBSZtZlsAc1U4Z85xf/RXv1qolkdu+ibw64fUDaRdktxTNP9A==} 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'} cpu: [arm64] os: [linux] requiresBuild: true optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.1 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 dev: false optional: true - /@img/sharp-linuxmusl-x64@0.33.2: - resolution: {integrity: sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A==} + /@img/sharp-linuxmusl-x64@0.33.3: + resolution: {integrity: sha512-Jhchim8kHWIU/GZ+9poHMWRcefeaxFIs9EBqf9KtcC14Ojk6qua7ghKiPs0sbeLbLj/2IGBtDcxHyjCdYWkk2w==} 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'} cpu: [x64] os: [linux] requiresBuild: true optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.1 + '@img/sharp-libvips-linuxmusl-x64': 1.0.2 dev: false optional: true - /@img/sharp-wasm32@0.33.2: - resolution: {integrity: sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ==} + /@img/sharp-wasm32@0.33.3: + resolution: {integrity: sha512-68zivsdJ0koE96stdUfM+gmyaK/NcoSZK5dV5CAjES0FUXS9lchYt8LAB5rTbM7nlWtxaU/2GON0HVN6/ZYJAQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [wasm32] requiresBuild: true dependencies: - '@emnapi/runtime': 0.45.0 + '@emnapi/runtime': 1.1.1 dev: false optional: true - /@img/sharp-win32-ia32@0.33.2: - resolution: {integrity: sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g==} + /@img/sharp-win32-ia32@0.33.3: + resolution: {integrity: sha512-CyimAduT2whQD8ER4Ux7exKrtfoaUiVr7HG0zZvO0XTFn2idUWljjxv58GxNTkFb8/J9Ub9AqITGkJD6ZginxQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [ia32] os: [win32] @@ -227,8 +227,8 @@ packages: dev: false optional: true - /@img/sharp-win32-x64@0.33.2: - resolution: {integrity: sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg==} + /@img/sharp-win32-x64@0.33.3: + resolution: {integrity: sha512-viT4fUIDKnli3IfOephGnolMzhz5VaTvDRkYqtZxOMIoMQ4MrAziO7pT1nVnOt2FAm7qW5aa+CCc13aEY6Le0g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [win32] @@ -240,8 +240,8 @@ packages: resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} dev: true - /@types/node@20.11.19: - resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==} + /@types/node@20.12.5: + resolution: {integrity: sha512-BD+BjQ9LS/D8ST9p5uqBxghlN+S42iuNxjsUGjeZobe/ciXzk2qb1B6IXc6AnRLS+yFJRpN2IPEHMzwspfDJNw==} dependencies: undici-types: 5.26.5 dev: true @@ -249,17 +249,17 @@ packages: /@types/sharp@0.31.1: resolution: {integrity: sha512-5nWwamN9ZFHXaYEincMSuza8nNfOof8nmO+mcI+Agx1uMUk4/pQnNIcix+9rLPXzKrm1pS34+6WRDbDV0Jn7ag==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.12.5 dev: true /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /axios@1.6.7: - resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + /axios@1.6.8: + resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} dependencies: - follow-redirects: 1.15.5 + follow-redirects: 1.15.6 form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -314,18 +314,18 @@ packages: engines: {node: '>=0.4.0'} dev: false - /detect-libc@2.0.2: - resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + /detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} dev: false - /dotenv@16.4.4: - resolution: {integrity: sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==} + /dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} dev: false - /follow-redirects@1.15.5: - resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + /follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -384,34 +384,34 @@ packages: lru-cache: 6.0.0 dev: false - /sharp@0.33.2: - resolution: {integrity: sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ==} - engines: {libvips: '>=8.15.1', node: ^18.17.0 || ^20.3.0 || >=21.0.0} + /sharp@0.33.3: + resolution: {integrity: sha512-vHUeXJU1UvlO/BNwTpT0x/r53WkLUVxrmb5JTgW92fdFCFk0ispLMAeu/jPO2vjkXM1fYUi3K7/qcLF47pwM1A==} + engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0} requiresBuild: true dependencies: color: 4.2.3 - detect-libc: 2.0.2 + detect-libc: 2.0.3 semver: 7.6.0 optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.2 - '@img/sharp-darwin-x64': 0.33.2 - '@img/sharp-libvips-darwin-arm64': 1.0.1 - '@img/sharp-libvips-darwin-x64': 1.0.1 - '@img/sharp-libvips-linux-arm': 1.0.1 - '@img/sharp-libvips-linux-arm64': 1.0.1 - '@img/sharp-libvips-linux-s390x': 1.0.1 - '@img/sharp-libvips-linux-x64': 1.0.1 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.1 - '@img/sharp-libvips-linuxmusl-x64': 1.0.1 - '@img/sharp-linux-arm': 0.33.2 - '@img/sharp-linux-arm64': 0.33.2 - '@img/sharp-linux-s390x': 0.33.2 - '@img/sharp-linux-x64': 0.33.2 - '@img/sharp-linuxmusl-arm64': 0.33.2 - '@img/sharp-linuxmusl-x64': 0.33.2 - '@img/sharp-wasm32': 0.33.2 - '@img/sharp-win32-ia32': 0.33.2 - '@img/sharp-win32-x64': 0.33.2 + '@img/sharp-darwin-arm64': 0.33.3 + '@img/sharp-darwin-x64': 0.33.3 + '@img/sharp-libvips-darwin-arm64': 1.0.2 + '@img/sharp-libvips-darwin-x64': 1.0.2 + '@img/sharp-libvips-linux-arm': 1.0.2 + '@img/sharp-libvips-linux-arm64': 1.0.2 + '@img/sharp-libvips-linux-s390x': 1.0.2 + '@img/sharp-libvips-linux-x64': 1.0.2 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 + '@img/sharp-libvips-linuxmusl-x64': 1.0.2 + '@img/sharp-linux-arm': 0.33.3 + '@img/sharp-linux-arm64': 0.33.3 + '@img/sharp-linux-s390x': 0.33.3 + '@img/sharp-linux-x64': 0.33.3 + '@img/sharp-linuxmusl-arm64': 0.33.3 + '@img/sharp-linuxmusl-x64': 0.33.3 + '@img/sharp-wasm32': 0.33.3 + '@img/sharp-win32-ia32': 0.33.3 + '@img/sharp-win32-x64': 0.33.3 dev: false /simple-swizzle@0.2.2: @@ -426,8 +426,8 @@ packages: dev: false optional: true - /typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + /typescript@5.4.4: + resolution: {integrity: sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==} engines: {node: '>=14.17'} hasBin: true dev: true diff --git a/src/Downloader.js b/src/Downloader.js index 7625267..68a697c 100644 --- a/src/Downloader.js +++ b/src/Downloader.js @@ -175,11 +175,9 @@ export default class Downloader { const folder = join(output, username) - if(highlights) this.Log(new Error("Highlights download disabled temporarily")) - const results = await Promise.allSettled([ timeline && this.DownloadTimeline(username, folder), - // highlights && this.DownloadHighlights(user_id, folder, hcover, this.limit, username), + highlights && this.DownloadHighlights(user_id, folder, hcover, this.limit, username), stories && this.DownloadStories(user_id, folder, this.limit, username) ]) @@ -233,25 +231,20 @@ export default class Downloader { async GetHighlights(user_id, username){ const url = new URL(API_QUERY, BASE_URL) - url.searchParams.set("user_id", user_id) - url.searchParams.set("include_chaining", "false") - url.searchParams.set("include_reel", "false") - url.searchParams.set("include_suggested_users", "false") - url.searchParams.set("include_logged_out_extras", "false") - url.searchParams.set("include_live_status", "false") - url.searchParams.set("include_highlight_reels", "true") - - /** @type {import("axios").AxiosResponse} */ - const response = await this.Request(url, "GET", { + /** @type {import("axios").AxiosResponse} */ + const response = await this.Request(url, "POST", { + data: new URLSearchParams({ + variables: JSON.stringify({ user_id }), + doc_id: "8298007123561120" + }), headers: { - Referer: username ? `${BASE_URL}/${username}/` : BASE_URL + "/", - "X-Requested-With": "XMLHttpRequest" + Referer: username ? `${BASE_URL}/${username}/` : BASE_URL + "/" }, responseType: "json" }) try{ - return response.data.data.user.edge_highlight_reels.edges.map(({ node }) => node) + return response.data.data.highlights.edges.map(({ node }) => node) }catch(error){ throw new Error(`Failed to get user (${username || user_id}) highlights`, { cause: /** @type {Error} */ (error).message.replace(/\[?Error\]?:? ?/, "") @@ -259,21 +252,35 @@ export default class Downloader { } } /** - * @param {`${number}`[]} reelsIds + * @param {import("./typings/api.js").HighlightId[]} reelsIds * @param {string} [username] + * @param {number} [first] */ - async GetHighlightsContents(reelsIds, username){ - const url = new URL(API_REELS, BASE_URL) + async GetHighlightsContents(reelsIds, username, first){ + const url = new URL(API_QUERY, BASE_URL) - for(const id of reelsIds) url.searchParams.append("reel_ids", "highlight:" + id) + first ??= this.queue?.limit ?? 10 /** @type {import("axios").AxiosResponse} */ - const response = await this.Request(url, "GET", { - headers: { Referer: username ? `${BASE_URL}/${username}/` : BASE_URL + "/" }, + const response = await this.Request(url, "POST", { + data: new URLSearchParams({ + variables: JSON.stringify({ + after: null, + before: null, + first: reelsIds.length, + initial_reel_id: reelsIds[0], + reel_ids: reelsIds, + last: null + }), + doc_id: "25536143079310158" + }), + headers: { + Referer: username ? `${BASE_URL}/${username}/` : BASE_URL + "/" + }, responseType: "json" }) - return response.data.reels_media + return response.data.data.xdt_api__v1__feed__reels_media__connection.edges.map(({ node }) => node) } /** * @param {`${number}`} userId @@ -329,20 +336,18 @@ export default class Downloader { for(const { id, items } of highlightsContents){ if(count > limit) throw new Error("Unexpected error") - const highlightId = /** @type {`${number}`} */ (id.substring(id.indexOf(":") + 1)) - - this.Log(`Downloading highlight: ${highlightId}`) + this.Log(`Downloading highlight: ${id.substring(id.indexOf(":") + 1)}`) for(const item of items){ const { url } = GetCorrectContent(item)[0] filesSet.add(GetURLFilename(url)) } - const shouldDownloadCover = hcover && highlightsMap.has(highlightId) + const shouldDownloadCover = hcover && highlightsMap.has(id) let coverUrl if(shouldDownloadCover){ - const { thumbnail_src: url } = highlightsMap.get(highlightId).cover_media + const { cropped_image_version: { url } } = highlightsMap.get(id).cover_media coverUrl = url } @@ -453,7 +458,7 @@ export default class Downloader { if(count === 0) this.Log("No content found in timeline") } /** - * @param {import("./typings/api.js").FeedItem[]} items + * @param {(import("./typings/api.js").FeedItem | import("./typings/api.js").GraphHighlightsMedia | import("./typings/api.js").GraphReelsMedia)[]} items * @param {string} folder * @param {{ count: number, limit: number }} [data] * @param {string} [username] @@ -590,7 +595,11 @@ export default class Downloader { setCookies.forEach(cookieConfig => { const [key, ...values] = cookieConfig.split(";")[0].split("=") + + if(key === "th_eu_pref") return + const value = encodeURIComponent(values.join("=")) + if(key === "csrftoken") this.config.csrftoken = value this.config.cookie[key] = value }) diff --git a/src/helpers/GetCorrectContent.js b/src/helpers/GetCorrectContent.js index 39c57ad..11b93fb 100644 --- a/src/helpers/GetCorrectContent.js +++ b/src/helpers/GetCorrectContent.js @@ -1,7 +1,7 @@ /** - * @param {{ video_versions?: import("../typings/api.js").VideoVersion[], image_versions2: { candidates: import("../typings/api.js").ImageVersion[] } }} item + * @param {{ video_versions?: import("../typings/api.js").VideoVersion[] | null, image_versions2: { candidates: import("../typings/api.js").ImageVersion[] } }} item * @returns {import("../typings/api.js").ImageVersion[] | import("../typings/api.js").VideoVersion[]} */ export default function GetCorrectContent(item){ - return "video_versions" in item ? item.video_versions : item.image_versions2.candidates + return "video_versions" in item && item.video_versions ? item.video_versions : item.image_versions2.candidates } diff --git a/src/typings/api.d.ts b/src/typings/api.d.ts index fe4a85f..144fe03 100644 --- a/src/typings/api.d.ts +++ b/src/typings/api.d.ts @@ -42,14 +42,15 @@ export interface VideoVersion extends MediaVersion { } export interface GenericUser { + id: `${number}` | null pk: string pk_id: string - username: string + username: string | null full_name: string is_private: boolean is_verified: boolean profile_pic_id: string - profile_pic_url: string + profile_pic_url: string | null profile_grid_display_type: "default" } @@ -226,7 +227,7 @@ export interface FeedItem { height: number url: string id: string - }[] + }[] | null video_duration?: number is_dash_eligible?: number video_dash_manifest?: string @@ -418,7 +419,7 @@ export interface Caption { } export interface Reel { - id: string + id: `${number}` expiring_at: number has_pride_media: boolean latest_reel_media: number @@ -444,10 +445,10 @@ export interface ReelChainNode { username: string } -export interface ReelUser { - id: string - profile_pic_url: string - username: string +export interface ReelUser extends Pick, "pk" | "is_private" | "interop_messaging_user_fbid"> { + id: string | null + profile_pic_url: string | null + username: string | null } export interface ReelOwner extends ReelUser { @@ -464,53 +465,34 @@ export interface FeedAPIResponse { status: APIStatus } -export interface QueryHighlightsResponse { +export interface QueryHighlightsAPIResponse { data: { - viewer: { - edge_suggested_users?: { - count: number - } - } - user: { - is_live: boolean - reel: Reel - /** Suggested users */ - edge_chaining: { - edges: { - node: ReelChainNode - }[] - } - edge_highlight_reels: { - edges: { - node: { - __typename: "GraphHighlightReel" - id: `${number}` - cover_media: { - thumbnail_src: string - } - cover_media_cropped_thumbnail: { + highlights: { + edges: { + node: { + id: HighlightId + title: "pictures" + cover_media: { + cropped_image_version: { url: string } - owner: ReelOwner - title: string } - }[] - } - has_public_story?: boolean - is_live?: boolean - reel?: { - expiring_at: number - has_pride_media: boolean - id: `${number}` - latest_reel_media: number - owner: ReelOwner - seen: boolean | null - user: ReelUser - __typename: "GraphReel" + user: { + username: string + id: string | null + } + __typename: "XDTReelDict" + } + cursor: string + }[] + page_info: { + end_cursor: string + has_previous_page: boolean + has_next_page: boolean } } } - extensions?: { + extensions: { is_final: boolean } status: APIStatus @@ -1103,7 +1085,7 @@ export interface FacebookAccountAPIResponse { display_name: string sso_login_available: boolean is_sso_enabled: boolean - }, + } status: APIStatus } @@ -1122,8 +1104,9 @@ export interface HighlightCoverMedia { upload_id: any } -export interface HighlightUser extends Omit { - interop_messaging_user_fbid: number +export interface HighlightUser extends Omit { + interop_messaging_user_fbid: number | null + friendship_status?: null } interface ReelMedia { @@ -1155,11 +1138,111 @@ interface ReelMedia { highlight_reel_type: string } +interface GraphReelsMedia { + preview: null + product_type: "story" + reshared_story_media_author: null + sharing_friction_info: { + bloks_app_url: null + should_have_sharing_friction: boolean + } + sponsor_tags: null + story_app_attribution: null + story_bloks_stickers: null + story_countdowns: null + story_cta: null + story_feed_media: null + story_hashtags: null + story_link_stickers: null + story_locations: null + story_music_stickers: null + story_questions: null + story_sliders: null + taken_at: number + text_post_share_to_ig_story_stickers: null + video_dash_manifest: null + video_duration: null + video_versions: null + viewer_count: null + viewers: null + visual_comment_reply_sticker_info: null + accessibility_caption: string + audience: null | "besties" + boost_unavailable_identifier: null + boost_unavailable_reason: null + boosted_status: null + can_see_insights_as_brand: boolean + can_viewer_reshare: null + carousel_media: null + carousel_media_count: null + expiring_at: number + has_audio: null + has_liked: boolean + has_translation: boolean + ig_media_sharing_disabled: boolean + inventory_source: null + is_dash_eligible: null + is_paid_partnership: boolean + media_overlay_info: null + media_type: number + number_of_qualities: null + organic_tracking_token: string + original_height: number + original_width: number + pk: `${number}` + user: ReelUser + image_versions2: { + candidates: ImageVersion[] + } +} + +export interface GraphHighlightsMedia extends GraphReelsMedia { + id: string + can_reply: boolean + can_reshare: boolean + __typename: "XDTMediaDict" +} + +export interface GraphReelUser { + id: null | string + pk: `${number}` + profile_pic_url: null | string + username: null | string + is_private: false +} + export interface HighlightsAPIResponse { - reels: { - [highlightId: HighlightId]: ReelMedia + data: { + xdt_api__v1__feed__reels_media__connection: { + edges: [{ + node: { + id: HighlightId + items: GraphHighlightsMedia[] + user: HighlightUser + reel_type: "highlight_reel" + cover_media: { + cropped_image_version: { + url: string + } + full_image_version: string | null + } + title: string + seen: number | null + __typename: "XDTReelDict" + } + cursor: string + }] + page_info: { + start_cursor: HighlightId + end_cursor: HighlightId + has_next_page: boolean + has_previous_page: boolean + } + } + } + extensions: { + is_final: boolean } - reels_media: ReelMedia[] status: APIStatus } diff --git a/tests/index.test.js b/tests/index.test.js index a7575ad..78594df 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -94,12 +94,12 @@ test("Instagram API", async t => { assert.strictEqual((await readdir(folder)).length, 20) }) - /* await EmptyFolder() + await EmptyFolder() await t.test("should download 20 items from highlights", async () => { await downloader.DownloadHighlights("25025320", folder, true, 20) assert.strictEqual((await readdir(folder)).length, 20) - }) */ + }) await rm(folder, { recursive: true }) })