@chilfish/gallery-dl-instagram 0.1.0 → 0.2.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.
@@ -1,189 +0,0 @@
1
- import { access, mkdir, writeFile } from "fs/promises";
2
- import { dirname } from "path";
3
- import axios from "axios";
4
- //#region cli/cookies.ts
5
- function createCookieJar() {
6
- const cookies = /* @__PURE__ */ new Map();
7
- let cookieString = "";
8
- return {
9
- setFromResponse(headers) {
10
- const raw = headers["set-cookie"];
11
- if (!raw) return;
12
- const cookieHeaders = Array.isArray(raw) ? raw : [raw];
13
- for (const header of cookieHeaders) {
14
- const parts = header.split(";");
15
- if (parts.length === 0) continue;
16
- const [nameValue] = parts;
17
- const eqIdx = nameValue.indexOf("=");
18
- if (eqIdx <= 0) continue;
19
- const name = nameValue.slice(0, eqIdx).trim();
20
- const value = nameValue.slice(eqIdx + 1).trim();
21
- if (parts.slice(1).map((s) => s.trim().toLowerCase()).includes("max-age=0")) continue;
22
- cookies.set(name, value);
23
- }
24
- cookieString = Array.from(cookies.entries()).map(([k, v]) => `${k}=${v}`).join("; ");
25
- },
26
- getCookieHeader() {
27
- return cookieString;
28
- }
29
- };
30
- }
31
- //#endregion
32
- //#region cli/adapter.ts
33
- /** NodeHttpClient — axios wrapper */
34
- /**
35
- * Extract csrftoken value from a Cookie header string.
36
- */
37
- function extractCsrfFromCookies(cookies) {
38
- return cookies.match(/(?:^|;\s*)csrftoken=([^;]+)/)?.[1] ?? "";
39
- }
40
- function createHttpClient(sessionId, fullCookies, logger) {
41
- const instance = axios.create({
42
- timeout: 3e4,
43
- maxRedirects: 20,
44
- validateStatus: () => true,
45
- headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" }
46
- });
47
- const baseCookie = fullCookies || (sessionId ? `sessionid=${sessionId}` : null);
48
- return { async request(config) {
49
- const method = config.method ?? "GET";
50
- logger?.debug(`${method} ${config.url}`);
51
- const mergedHeaders = {};
52
- if (baseCookie) mergedHeaders.Cookie = baseCookie;
53
- if (config.headers) for (const [k, v] of Object.entries(config.headers)) if (k.toLowerCase() === "cookie" && mergedHeaders.Cookie) mergedHeaders.Cookie = `${mergedHeaders.Cookie}; ${v}`;
54
- else mergedHeaders[k] = v;
55
- if (mergedHeaders.Cookie) logger?.debug(` Cookie: ${mergedHeaders.Cookie.slice(0, 200)}`);
56
- try {
57
- const resp = await instance.request({
58
- url: config.url,
59
- method,
60
- headers: mergedHeaders,
61
- params: cleanupParams(config.params),
62
- data: config.data,
63
- signal: config.signal,
64
- timeout: config.timeout,
65
- responseType: config.responseType ?? "json"
66
- });
67
- const finalUrl = resp.request?.res?.responseUrl ?? config.url;
68
- logger?.debug(` ← ${resp.status} ${resp.status >= 400 ? "⚠️" : ""} (${finalUrl.slice(0, 100)})`);
69
- return {
70
- status: resp.status,
71
- data: resp.data,
72
- headers: resp.headers,
73
- url: finalUrl
74
- };
75
- } catch (err) {
76
- const msg = String(err);
77
- if (msg.includes("TOO_MANY_REDIRECTS") || msg.includes("too many redirects")) throw new Error("Too many redirects — sessionid may be expired or invalid. Export a fresh sessionid from your browser.");
78
- throw err;
79
- }
80
- } };
81
- }
82
- /** WebClient — anonymous cookie-jar HTTP client */
83
- /**
84
- * Create an HTTP client with an in-memory cookie jar.
85
- *
86
- * Use this when you don't have a sessionid — the client first seeds its
87
- * cookie jar by visiting ``instagram.com``, then uses those anonymous
88
- * cookies for subsequent API calls. This is how incognito browsing works.
89
- *
90
- * Returns the client + the initial CSRF token extracted from cookies.
91
- */
92
- async function createWebClient(logger) {
93
- const jar = createCookieJar();
94
- logger?.info("Seeding anonymous session (visiting instagram.com)…");
95
- const seedResp = await axios.get("https://www.instagram.com/", {
96
- headers: {
97
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
98
- "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
99
- },
100
- maxRedirects: 20,
101
- validateStatus: () => true
102
- });
103
- jar.setFromResponse(seedResp.headers);
104
- logger?.debug(` ← ${seedResp.status} — got ${jar.getCookieHeader().split(";").length} cookies`);
105
- return {
106
- http: { async request(config) {
107
- const method = config.method ?? "GET";
108
- logger?.debug(`${method} ${config.url}`);
109
- const jarCookie = jar.getCookieHeader();
110
- const mergedHeaders = {};
111
- if (jarCookie) mergedHeaders.Cookie = jarCookie;
112
- if (config.headers) for (const [k, v] of Object.entries(config.headers)) if (k.toLowerCase() === "cookie" && mergedHeaders.Cookie) mergedHeaders.Cookie = `${mergedHeaders.Cookie}; ${v}`;
113
- else mergedHeaders[k] = v;
114
- try {
115
- const resp = await axios.request({
116
- url: config.url,
117
- method,
118
- headers: mergedHeaders,
119
- params: cleanupParams(config.params),
120
- data: config.data,
121
- signal: config.signal,
122
- timeout: config.timeout ?? 3e4,
123
- maxRedirects: 20,
124
- validateStatus: () => true,
125
- responseType: config.responseType ?? "json"
126
- });
127
- jar.setFromResponse(resp.headers);
128
- const finalUrl = resp.request?.res?.responseUrl ?? config.url;
129
- logger?.debug(` ← ${resp.status} ${resp.status >= 400 ? "⚠️" : ""} (${finalUrl.slice(0, 100)})`);
130
- return {
131
- status: resp.status,
132
- data: resp.data,
133
- headers: resp.headers,
134
- url: finalUrl
135
- };
136
- } catch (err) {
137
- const msg = String(err);
138
- if (msg.includes("TOO_MANY_REDIRECTS") || msg.includes("too many redirects")) throw new Error("Too many redirects — Instagram may be blocking the request. Try again later or use --sessionid.");
139
- throw err;
140
- }
141
- } },
142
- csrfToken: jar.getCookieHeader().match(/(?:^|;\s*)csrftoken=([^;]+)/)?.[1] ?? ""
143
- };
144
- }
145
- function cleanupParams(params) {
146
- if (!params) return void 0;
147
- const cleaned = {};
148
- for (const [k, v] of Object.entries(params)) if (v != null) cleaned[k] = String(v);
149
- return cleaned;
150
- }
151
- /** NodeStorage — fs/promises wrapper */
152
- function createStorage() {
153
- return {
154
- async exists(path) {
155
- try {
156
- await access(path);
157
- return true;
158
- } catch {
159
- return false;
160
- }
161
- },
162
- async write(path, data) {
163
- await mkdir(dirname(path), { recursive: true });
164
- await writeFile(path, data);
165
- },
166
- async mkdir(path) {
167
- await mkdir(path, { recursive: true });
168
- }
169
- };
170
- }
171
- /** NodeLogger — console wrapper */
172
- function createLogger(verbose) {
173
- return {
174
- debug(message, ...args) {
175
- if (verbose) console.debug(`[debug] ${message}`, ...args);
176
- },
177
- info(message, ...args) {
178
- console.info(`[info] ${message}`, ...args);
179
- },
180
- warn(message, ...args) {
181
- console.warn(`[warn] ${message}`, ...args);
182
- },
183
- error(message, ...args) {
184
- console.error(`[error] ${message}`, ...args);
185
- }
186
- };
187
- }
188
- //#endregion
189
- export { extractCsrfFromCookies as a, createWebClient as i, createLogger as n, createStorage as r, createHttpClient as t };
@@ -1 +0,0 @@
1
- export { };