snapsaver-downloader 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # SnapSaver Downloader
2
+
3
+ [![npm version](https://img.shields.io/npm/v/snapsaver-downloader.svg)](https://www.npmjs.com/package/snapsaver-downloader)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ An unofficial Node.js package to download media from Facebook, Instagram, and TikTok using SnapSave API.
7
+
8
+ ## Features
9
+
10
+ - 📥 Download videos and images from:
11
+ - Facebook posts, reels, and watch videos
12
+ - Instagram posts and reels
13
+ - TikTok videos
14
+ - 📱 Support for multiple quality options (when available)
15
+ - 🌐 URL normalization and validation
16
+ - 🔄 Automatic platform detection
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install snapsaver-downloader
22
+ ```
23
+
24
+ Or with yarn:
25
+
26
+ ```bash
27
+ yarn add snapsaver-downloader
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ```typescript
33
+ import { SnapSaver } from 'snapsaver-downloader';
34
+
35
+ // Example: Download from Facebook
36
+ async function downloadMedia() {
37
+ try {
38
+ const result = await SnapSaver('https://www.facebook.com/watch/?v=1377532133417378');
39
+
40
+ if (result.success) {
41
+ console.log('Media found:', result.data);
42
+ // Access download URLs:
43
+ const mediaUrls = result.data?.media?.map(item => item.url);
44
+ console.log('Download URLs:', mediaUrls);
45
+ } else {
46
+ console.error('Error:', result.message);
47
+ }
48
+ } catch (error) {
49
+ console.error('Failed to download:', error);
50
+ }
51
+ }
52
+
53
+ downloadMedia();
54
+ ```
55
+
56
+ ### Supported URLs
57
+
58
+ The package supports various URL formats:
59
+
60
+ #### Facebook
61
+ - `https://www.facebook.com/watch/?v=1234567890`
62
+ - `https://www.facebook.com/share/v/123ABC456/`
63
+ - `https://www.facebook.com/username/videos/1234567890`
64
+ - `https://fb.watch/abcdef123/`
65
+
66
+ #### Instagram
67
+ - `https://www.instagram.com/p/ABC123def/`
68
+ - `https://www.instagram.com/reel/ABC123def/`
69
+ - URLs with query parameters (e.g., `?utm_source=ig_web_copy_link`)
70
+
71
+ #### TikTok
72
+ - `https://www.tiktok.com/@username/video/1234567890`
73
+ - `https://vt.tiktok.com/ABCDEF/`
74
+
75
+ ## API Reference
76
+
77
+ ### SnapSaver(url: string): Promise<SnapSaveDownloaderResponse>
78
+
79
+ The main function to download media from supported social platforms.
80
+
81
+ #### Parameters
82
+
83
+ - `url` (string): URL of the social media post to download
84
+
85
+ #### Returns
86
+
87
+ Returns a Promise that resolves to a `SnapSaveDownloaderResponse` object:
88
+
89
+ ```typescript
90
+ interface SnapSaveDownloaderResponse {
91
+ success: boolean;
92
+ message?: string;
93
+ data?: SnapSaveDownloaderData;
94
+ }
95
+
96
+ interface SnapSaveDownloaderData {
97
+ description?: string;
98
+ preview?: string;
99
+ media?: SnapSaveDownloaderMedia[];
100
+ }
101
+
102
+ interface SnapSaveDownloaderMedia {
103
+ resolution?: string;
104
+ shouldRender?: boolean;
105
+ thumbnail?: string;
106
+ type?: "image" | "video";
107
+ url?: string;
108
+ }
109
+ ```
110
+
111
+ #### Response Structure
112
+
113
+ - `success` - Boolean indicating if the download was successful
114
+ - `message` - Error message (only present when `success` is false)
115
+ - `data` - Result data (only present when `success` is true)
116
+ - `description` - Description of the post (when available)
117
+ - `preview` - Preview image URL (when available)
118
+ - `media` - Array of media objects containing:
119
+ - `type` - Media type ("video" or "image")
120
+ - `url` - Direct download URL
121
+ - `resolution` - Resolution (for videos, when available)
122
+ - `thumbnail` - Thumbnail URL (for videos, when available)
123
+ - `shouldRender` - Whether the media needs special rendering
124
+
125
+ ## Utilities
126
+
127
+ The package exports several utility functions that might be useful:
128
+
129
+ ```typescript
130
+ import {
131
+ normalizeURL,
132
+ detectPlatformFromURL,
133
+ fixThumbnail
134
+ } from 'snapsaver-downloader/dist/utils';
135
+
136
+ // Normalize a URL (add www if missing)
137
+ const normalizedUrl = normalizeURL('https://facebook.com/video/123');
138
+ // Result: 'https://www.facebook.com/video/123'
139
+
140
+ // Detect platform from URL
141
+ const platform = detectPlatformFromURL('https://www.instagram.com/reel/ABC123/');
142
+ // Result: 'Instagram'
143
+ ```
144
+
145
+ ## Limitations
146
+
147
+ - This package relies on the SnapSave.app service, which may change its API without notice
148
+ - Some platforms may block scraping attempts or change their URL structure
149
+ - For high-volume applications, consider implementing rate limiting
150
+
151
+ ## Contributing
152
+
153
+ Contributions are welcome! Please feel free to submit a Pull Request.
154
+
155
+ 1. Fork the project
156
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
157
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
158
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
159
+ 5. Open a Pull Request
160
+
161
+ ## License
162
+
163
+ This project is licensed under the MIT License - see the LICENSE file for details.
164
+
165
+ ## Disclaimer
166
+
167
+ This package is not affiliated with, endorsed by, or connected to SnapSave.app or any of the social media platforms it supports. It is provided for educational purposes only. Always respect the terms of service of the platforms you are downloading content from, and ensure you have the right to download and use the content.
@@ -0,0 +1,17 @@
1
+ import type { SnapSaveDownloaderResponse } from "./types";
2
+ /**
3
+ * SnapSaver service - orchestrates the workflow but delegates specific tasks
4
+ */
5
+ export declare class SnapSaverService {
6
+ private readonly urlValidator;
7
+ private readonly decoder;
8
+ private readonly extractor;
9
+ private readonly apiClient;
10
+ constructor();
11
+ /**
12
+ * Main method to download media from social platforms via SnapSave
13
+ * @param url URL of the social media post to download
14
+ * @returns Response containing success status and download data
15
+ */
16
+ download(url: string): Promise<SnapSaveDownloaderResponse>;
17
+ }
@@ -0,0 +1,311 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnapSaverService = void 0;
4
+ const cheerio_1 = require("cheerio");
5
+ const utils_1 = require("./utils");
6
+ /**
7
+ * URL Validator class - responsible for validating URLs against supported platforms
8
+ */
9
+ class UrlValidator {
10
+ constructor(regexes = [utils_1.facebookRegex, utils_1.instagramRegex, utils_1.tiktokRegex]) {
11
+ this.supportedRegexes = regexes;
12
+ }
13
+ /**
14
+ * Validates if the URL is from a supported platform
15
+ * @param url URL to validate
16
+ * @returns Boolean indicating if the URL is supported
17
+ */
18
+ isValid(url) {
19
+ return this.supportedRegexes.some(regex => url.match(regex));
20
+ }
21
+ }
22
+ /**
23
+ * SnapSave Decoder class - responsible for all decoding and decryption logic
24
+ */
25
+ class SnapSaveDecoder {
26
+ /**
27
+ * Decodes SnapApp encoded content
28
+ * @param args Array of arguments from the encoded content
29
+ * @returns Decoded content
30
+ */
31
+ decodeSnapApp(args) {
32
+ let [encodedContent, u, charMap, subtractValue, base, decodedResult] = args;
33
+ /**
34
+ * Internal decoder function for number conversion
35
+ */
36
+ const decodeNumber = (value, fromBase, toBase) => {
37
+ const charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/".split("");
38
+ const fromCharset = charset.slice(0, fromBase);
39
+ const toCharset = charset.slice(0, toBase);
40
+ // @ts-expect-error - Known limitation in type inference for this algorithm
41
+ let decimal = value.split("").reverse().reduce((sum, char, index) => {
42
+ if (fromCharset.indexOf(char) !== -1)
43
+ return sum += fromCharset.indexOf(char) * (Math.pow(fromBase, index));
44
+ return sum;
45
+ }, 0);
46
+ let result = "";
47
+ while (decimal > 0) {
48
+ result = toCharset[decimal % toBase] + result;
49
+ decimal = (decimal - (decimal % toBase)) / toBase;
50
+ }
51
+ return result || "0";
52
+ };
53
+ decodedResult = "";
54
+ for (let i = 0, len = encodedContent.length; i < len; i++) {
55
+ let segment = "";
56
+ while (encodedContent[i] !== charMap[Number(base)]) {
57
+ segment += encodedContent[i];
58
+ i++;
59
+ }
60
+ for (let j = 0; j < charMap.length; j++) {
61
+ segment = segment.replace(new RegExp(charMap[j], "g"), j.toString());
62
+ }
63
+ // @ts-expect-error - Known limitation in type inference for this algorithm
64
+ decodedResult += String.fromCharCode(decodeNumber(segment, base, 10) - subtractValue);
65
+ }
66
+ return this.fixEncoding(decodedResult);
67
+ }
68
+ /**
69
+ * Fixes UTF-8 encoding issues in the decoded content
70
+ */
71
+ fixEncoding(str) {
72
+ const bytes = new Uint8Array(str.split("").map(char => char.charCodeAt(0)));
73
+ return new TextDecoder("utf-8").decode(bytes);
74
+ }
75
+ /**
76
+ * Extracts the encoded arguments from SnapSave HTML response
77
+ */
78
+ getEncodedSnapApp(data) {
79
+ return data.split("decodeURIComponent(escape(r))}(")[1]
80
+ .split("))")[0]
81
+ .split(",")
82
+ .map(v => v.replace(/"/g, "").trim());
83
+ }
84
+ /**
85
+ * Extracts the decoded HTML content from SnapSave response
86
+ */
87
+ getDecodedSnapSave(data) {
88
+ return data.split("getElementById(\"download-section\").innerHTML = \"")[1]
89
+ .split("\"; document.getElementById(\"inputData\").remove(); ")[0]
90
+ .replace(/\\(\\)?/g, "");
91
+ }
92
+ /**
93
+ * Decrypts the SnapSave response by chaining the decoding functions
94
+ * @param data Raw HTML response from SnapSave
95
+ * @returns Decrypted HTML content
96
+ */
97
+ decrypt(data) {
98
+ return this.getDecodedSnapSave(this.decodeSnapApp(this.getEncodedSnapApp(data)));
99
+ }
100
+ }
101
+ /**
102
+ * Media Extractor class - responsible for extracting media from different HTML layouts
103
+ */
104
+ class MediaExtractor {
105
+ /**
106
+ * Extract metadata from HTML content
107
+ * @param $ Cheerio API instance
108
+ * @returns Extracted metadata
109
+ */
110
+ extractMetadata($) {
111
+ const data = {};
112
+ const description = $("span.video-des").text().trim();
113
+ const preview = $("article.media > figure").find("img").attr("src");
114
+ if (description)
115
+ data.description = description;
116
+ if (preview)
117
+ data.preview = preview;
118
+ return data;
119
+ }
120
+ /**
121
+ * Extract media items from table layout
122
+ * @param $ Cheerio API instance
123
+ * @returns Array of extracted media
124
+ */
125
+ extractTableMedia($) {
126
+ const media = [];
127
+ $("tbody > tr").each((_, el) => {
128
+ var _a;
129
+ const $el = $(el);
130
+ const $td = $el.find("td");
131
+ const resolution = $td.eq(0).text();
132
+ let mediaUrl = $td.eq(2).find("a").attr("href") || $td.eq(2).find("button").attr("onclick");
133
+ const shouldRender = /get_progressApi/ig.test(mediaUrl || "");
134
+ if (shouldRender) {
135
+ mediaUrl = "https://snapsave.app" + ((_a = /get_progressApi\('(.*?)'\)/.exec(mediaUrl || "")) === null || _a === void 0 ? void 0 : _a[1]) || mediaUrl;
136
+ }
137
+ media.push({
138
+ resolution,
139
+ ...(shouldRender ? { shouldRender } : {}),
140
+ url: mediaUrl,
141
+ type: resolution ? "video" : "image"
142
+ });
143
+ });
144
+ return media;
145
+ }
146
+ /**
147
+ * Extract media items from card layout
148
+ * @param $ Cheerio API instance
149
+ * @returns Array of extracted media
150
+ */
151
+ extractCardMedia($) {
152
+ const media = [];
153
+ $("div.card").each((_, el) => {
154
+ const cardBody = $(el).find("div.card-body");
155
+ const aText = cardBody.find("a").text().trim();
156
+ const url = cardBody.find("a").attr("href");
157
+ const type = aText === "Download Photo" ? "image" : "video";
158
+ media.push({
159
+ url,
160
+ type
161
+ });
162
+ });
163
+ return media;
164
+ }
165
+ /**
166
+ * Extract media from simple layout
167
+ * @param $ Cheerio API instance
168
+ * @returns Array of extracted media
169
+ */
170
+ extractSimpleMedia($) {
171
+ const media = [];
172
+ const url = $("a").attr("href") || $("button").attr("onclick");
173
+ const aText = $("a").text().trim();
174
+ const type = aText === "Download Photo" ? "image" : "video";
175
+ media.push({
176
+ url,
177
+ type
178
+ });
179
+ return media;
180
+ }
181
+ /**
182
+ * Extract media from download items layout
183
+ * @param $ Cheerio API instance
184
+ * @returns Array of extracted media
185
+ */
186
+ extractDownloadItemsMedia($) {
187
+ const media = [];
188
+ $("div.download-items").each((_, el) => {
189
+ const itemThumbnail = $(el).find("div.download-items__thumb > img").attr("src");
190
+ const itemBtn = $(el).find("div.download-items__btn");
191
+ const url = itemBtn.find("a").attr("href");
192
+ const spanText = itemBtn.find("span").text().trim();
193
+ const type = spanText === "Download Photo" ? "image" : "video";
194
+ media.push({
195
+ url,
196
+ ...(type === "video" && itemThumbnail ? {
197
+ thumbnail: (0, utils_1.fixThumbnail)(itemThumbnail)
198
+ } : {}),
199
+ type
200
+ });
201
+ });
202
+ return media;
203
+ }
204
+ }
205
+ /**
206
+ * SnapSave API Client - responsible for making API requests
207
+ */
208
+ class SnapSaveApiClient {
209
+ constructor(apiUrl = "https://snapsave.app/action.php?lang=en") {
210
+ this.apiUrl = apiUrl;
211
+ }
212
+ /**
213
+ * Make a request to the SnapSave API
214
+ * @param url URL to download from
215
+ * @returns Raw HTML response
216
+ */
217
+ async fetchMedia(url) {
218
+ // Prepare request to SnapSave API
219
+ const formData = new URLSearchParams();
220
+ formData.append("url", (0, utils_1.normalizeURL)(url));
221
+ const response = await fetch(this.apiUrl, {
222
+ method: "POST",
223
+ headers: {
224
+ "accept": "*/*",
225
+ "content-type": "application/x-www-form-urlencoded",
226
+ "origin": "https://snapsave.app",
227
+ "referer": "https://snapsave.app/",
228
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0"
229
+ },
230
+ body: formData
231
+ });
232
+ // Return raw response
233
+ return response.text();
234
+ }
235
+ }
236
+ /**
237
+ * SnapSaver service - orchestrates the workflow but delegates specific tasks
238
+ */
239
+ class SnapSaverService {
240
+ constructor() {
241
+ this.urlValidator = new UrlValidator();
242
+ this.decoder = new SnapSaveDecoder();
243
+ this.extractor = new MediaExtractor();
244
+ this.apiClient = new SnapSaveApiClient();
245
+ }
246
+ /**
247
+ * Main method to download media from social platforms via SnapSave
248
+ * @param url URL of the social media post to download
249
+ * @returns Response containing success status and download data
250
+ */
251
+ async download(url) {
252
+ try {
253
+ // Validate URL against supported platforms
254
+ if (!this.urlValidator.isValid(url)) {
255
+ return {
256
+ success: false,
257
+ message: "Invalid URL"
258
+ };
259
+ }
260
+ // Fetch media from SnapSave API
261
+ const html = await this.apiClient.fetchMedia(url);
262
+ // Decrypt the response
263
+ const decodedHtml = this.decoder.decrypt(html);
264
+ // Parse HTML and extract media
265
+ const $ = (0, cheerio_1.load)(decodedHtml);
266
+ // Initialize data structure
267
+ const data = {};
268
+ let media = [];
269
+ // Extract data based on the HTML structure
270
+ if ($("table.table").length || $("article.media > figure").length) {
271
+ // Extract metadata
272
+ Object.assign(data, this.extractor.extractMetadata($));
273
+ // Extract media based on layout
274
+ if ($("table.table").length) {
275
+ media = this.extractor.extractTableMedia($);
276
+ }
277
+ else if ($("div.card").length) {
278
+ media = this.extractor.extractCardMedia($);
279
+ }
280
+ else {
281
+ media = this.extractor.extractSimpleMedia($);
282
+ }
283
+ }
284
+ // Extract media from download items layout
285
+ else if ($("div.download-items").length) {
286
+ media = this.extractor.extractDownloadItemsMedia($);
287
+ }
288
+ // Validate results
289
+ if (!media.length) {
290
+ return {
291
+ success: false,
292
+ message: "No downloadable media found"
293
+ };
294
+ }
295
+ // Add media to data and return
296
+ data.media = media;
297
+ return {
298
+ success: true,
299
+ data
300
+ };
301
+ }
302
+ catch (error) {
303
+ console.error("SnapSaver error:", error);
304
+ return {
305
+ success: false,
306
+ message: "Failed to process download request"
307
+ };
308
+ }
309
+ }
310
+ }
311
+ exports.SnapSaverService = SnapSaverService;
@@ -0,0 +1,7 @@
1
+ import { SnapSaveDownloaderResponse } from "./types";
2
+ /**
3
+ * Main function to download media from social platforms via SnapSave
4
+ * @param url URL of the social media post to download
5
+ * @returns Response containing success status and download data
6
+ */
7
+ export declare const SnapSaver: (url: string) => Promise<SnapSaveDownloaderResponse>;
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SnapSaver = void 0;
4
+ const Download_1 = require("./Download");
5
+ // Create singleton instance
6
+ const snapSaverInstance = new Download_1.SnapSaverService();
7
+ /**
8
+ * Main function to download media from social platforms via SnapSave
9
+ * @param url URL of the social media post to download
10
+ * @returns Response containing success status and download data
11
+ */
12
+ const SnapSaver = async (url) => {
13
+ return snapSaverInstance.download(url);
14
+ };
15
+ exports.SnapSaver = SnapSaver;
@@ -0,0 +1,17 @@
1
+ export interface SnapSaveDownloaderMedia {
2
+ resolution?: string;
3
+ shouldRender?: boolean;
4
+ thumbnail?: string;
5
+ type?: "image" | "video";
6
+ url?: string;
7
+ }
8
+ export interface SnapSaveDownloaderData {
9
+ description?: string;
10
+ preview?: string;
11
+ media?: SnapSaveDownloaderMedia[];
12
+ }
13
+ export interface SnapSaveDownloaderResponse {
14
+ success: boolean;
15
+ message?: string;
16
+ data?: SnapSaveDownloaderData;
17
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Regular expression patterns for various social media platforms
3
+ * Each regex is designed to match the URL format for a specific platform
4
+ */
5
+ export declare const facebookRegex: RegExp;
6
+ export declare const instagramRegex: RegExp;
7
+ export declare const tiktokRegex: RegExp;
8
+ export declare const youtubeRegex: RegExp;
9
+ export declare const twitterRegex: RegExp;
10
+ export declare const normalizeURL: (url: string) => string;
11
+ export declare const fixThumbnail: (url: string) => string;
12
+ export declare const detectPlatformFromURL: (url: string) => string | null;
package/dist/utils.js ADDED
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * Regular expression patterns for various social media platforms
4
+ * Each regex is designed to match the URL format for a specific platform
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.detectPlatformFromURL = exports.fixThumbnail = exports.normalizeURL = exports.twitterRegex = exports.youtubeRegex = exports.tiktokRegex = exports.instagramRegex = exports.facebookRegex = void 0;
8
+ // Facebook URLs including watch, reels, videos, posts and fb.watch short links
9
+ exports.facebookRegex = /^https?:\/\/(?:www\.|web\.|m\.)?facebook\.com\/(watch(\?v=|\/\?v=)[0-9]+(?!\/)|reel\/[0-9]+|[a-zA-Z0-9.\-_]+\/(videos|posts)\/[0-9]+|[0-9]+\/(videos|posts)\/[0-9]+|[a-zA-Z0-9]+\/(videos|posts)\/[0-9]+|share\/(v|r)\/[a-zA-Z0-9]+\/?)([^/?#&]+).*$|^https:\/\/fb\.watch\/[a-zA-Z0-9]+$/;
10
+ // Instagram URLs for posts, reels, stories, tv and share links
11
+ exports.instagramRegex = /^https?:\/\/(?:www\.)?instagram\.com\/(?:p|reel|reels|tv|stories|share)\/([^/?#&]+).*/;
12
+ // TikTok URLs for various formats including user videos, photos and short links
13
+ exports.tiktokRegex = /^https?:\/\/(?:www\.|m\.|vm\.|vt\.)?tiktok\.com\/(?:@[^/]+\/(?:video|photo)\/\d+|v\/\d+|t\/[\w]+|[\w-]+)\/?/i;
14
+ // YouTube URLs for standard watch URLs, shorts and embed links
15
+ exports.youtubeRegex = /^https?:\/\/(?:www\.)?(?:youtube\.com\/(?:watch\?(?:.*&)?v=|shorts\/|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})(?:[?&][^#\s]*)?/;
16
+ // Twitter/X URLs for tweet status links
17
+ exports.twitterRegex = /^https?:\/\/(?:www\.)?(?:twitter\.com|x\.com)\/(?:#!\/)?(?:[\w_]+\/status(?:es)?\/)([0-9]+)(?:[?&][^#\s]*)?/;
18
+ const normalizeURL = (url) => {
19
+ return /^(https?:\/\/)(?!www\.)[a-z0-9]+/i.test(url)
20
+ ? url.replace(/^(https?:\/\/)([^./]+\.[^./]+)(\/.*)?$/, "$1www.$2$3")
21
+ : url;
22
+ };
23
+ exports.normalizeURL = normalizeURL;
24
+ const fixThumbnail = (url) => {
25
+ const toReplace = "https://snapinsta.app/photo.php?photo=";
26
+ return url.includes(toReplace) ? decodeURIComponent(url.replace(toReplace, "")) : url;
27
+ };
28
+ exports.fixThumbnail = fixThumbnail;
29
+ const detectPlatformFromURL = (url) => {
30
+ if (exports.facebookRegex.test(url))
31
+ return "Facebook";
32
+ if (exports.instagramRegex.test(url))
33
+ return "Instagram";
34
+ if (exports.tiktokRegex.test(url))
35
+ return "TikTok";
36
+ if (exports.youtubeRegex.test(url))
37
+ return "YouTube";
38
+ if (exports.twitterRegex.test(url))
39
+ return "Twitter";
40
+ return null;
41
+ };
42
+ exports.detectPlatformFromURL = detectPlatformFromURL;
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "snapsaver-downloader",
3
+ "version": "1.0.0",
4
+ "description": "An Unofficial Package to Download From Facebook, TikTok and Instagram. Relais on SnapSave",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "prepublishOnly": "npm run build",
10
+ "test": "jest"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/gitnasr/snapsaver-dl.git"
15
+ },
16
+ "keywords": [
17
+ "snapsaver",
18
+ "instagram",
19
+ "facebook",
20
+ "twitter"
21
+ ],
22
+ "author": "gitnasr",
23
+ "license": "MIT",
24
+ "bugs": {
25
+ "url": "https://github.com/gitnasr/snapsaver-dl/issues"
26
+ },
27
+ "homepage": "https://github.com/gitnasr/snapsaver-dl#readme",
28
+ "dependencies": {
29
+ "cheerio": "^1.0.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/jest": "^29.5.14",
33
+ "@types/node": "^18.0.0",
34
+ "jest": "^29.7.0",
35
+ "jest-fetch-mock": "^3.0.3",
36
+ "ts-jest": "^29.3.2",
37
+ "ts-node": "^10.9.1",
38
+ "typescript": "^5.0.0"
39
+ },
40
+ "files": [
41
+ "dist/**/*",
42
+ "LICENSE",
43
+ "README.md"
44
+ ]
45
+ }