@chilfish/gallery-dl-instagram 0.2.0 → 0.2.2

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/dist/index.cjs CHANGED
@@ -1,5 +1,157 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sdk = require("./sdk-nzhAxf1O.cjs");
2
+ const require_sdk = require("./sdk-BClg0Kv2.cjs");
3
+ //#region src/core/print-job.ts
4
+ var PrintJob = class PrintJob extends require_sdk.Job {
5
+ _currentDir = {};
6
+ _files = [];
7
+ _postCount = 0;
8
+ _fileCount = 0;
9
+ _width;
10
+ constructor(extractor) {
11
+ super(extractor);
12
+ this._width = Math.min(process.stdout.columns ?? 80, 100);
13
+ }
14
+ async handleDirectory(msg) {
15
+ if (this._postCount > 0) this._flushPost();
16
+ this._currentDir = { ...msg.metadata };
17
+ this._postCount++;
18
+ this._files = [];
19
+ }
20
+ async handleUrl(msg) {
21
+ const meta = {
22
+ ...this._currentDir,
23
+ ...msg.metadata
24
+ };
25
+ this._fileCount++;
26
+ const ext = meta.extension ?? "jpg";
27
+ const mid = meta.media_id ?? "?";
28
+ this._files.push({
29
+ num: meta.num ?? this._files.length + 1,
30
+ filename: `${mid}.${ext}`,
31
+ width: meta.width ?? 0,
32
+ height: meta.height ?? 0,
33
+ videoUrl: meta.video_url ?? null,
34
+ audioUrl: meta.audio_url ?? null
35
+ });
36
+ }
37
+ async handleQueue(msg) {
38
+ if (this._files.length > 0 || this._postCount > 0) this._flushPost();
39
+ this._postCount = 0;
40
+ this._files = [];
41
+ const extrClass = {
42
+ ...this._currentDir,
43
+ ...msg.metadata
44
+ }._extractor;
45
+ if (!extrClass || typeof extrClass !== "object") return;
46
+ const cls = extrClass;
47
+ const match = cls.pattern.exec(msg.url);
48
+ if (!match) return;
49
+ const parentExtr = this.extractor;
50
+ const childJob = new PrintJob(Reflect.construct(cls, [{
51
+ url: msg.url,
52
+ match,
53
+ config: parentExtr.config,
54
+ http: parentExtr.http,
55
+ storage: parentExtr.storage,
56
+ log: parentExtr.log
57
+ }]));
58
+ const childStatus = await childJob.run();
59
+ this.status |= childStatus;
60
+ this._postCount += childJob._postCount;
61
+ this._fileCount += childJob._fileCount;
62
+ }
63
+ _flushPost() {
64
+ const m = this._currentDir;
65
+ if (Object.keys(m).length === 0) return;
66
+ const w = this._width;
67
+ const labelW = 14;
68
+ const shortcode = m.post_shortcode ?? "?";
69
+ const header = ` Post #${this._postCount}: ${shortcode} `;
70
+ const padTotal = w - 2 - header.length;
71
+ const padL = Math.floor(padTotal / 2);
72
+ const padR = padTotal - padL;
73
+ process.stdout.write(`\n${require_sdk.dim("┌")}${"─".repeat(padL)}${require_sdk.b(header)}${"─".repeat(padR)}${require_sdk.dim("┐")}\n`);
74
+ const row = (label, value, color) => {
75
+ const colored = typeof color === "function" ? color(value) : color ? `${color}${value}${require_sdk._RESET}` : value;
76
+ process.stdout.write(` ${require_sdk.dim("│")} ${require_sdk.c(require_sdk.pad(label, labelW))} ${colored}\n`);
77
+ };
78
+ const username = m.username ?? "?";
79
+ const fullname = m.fullname ?? "";
80
+ row("Author:", fullname ? `${username} (${fullname})` : username, require_sdk.g);
81
+ row("Date:", m.date ?? m.post_date ?? "?");
82
+ row("Likes:", `${typeof m.likes === "number" ? m.likes.toLocaleString() : "?"} | Liked: ${m.liked ? "yes" : "no"}`);
83
+ row("Type:", `${m.type ?? "?"} (${this._files.length} files)`);
84
+ row("URL:", m.post_url ?? "?");
85
+ const desc = m.description ?? "";
86
+ if (desc) {
87
+ process.stdout.write(` ${require_sdk.dim("│")}\n`);
88
+ process.stdout.write(` ${require_sdk.dim("│")} ${require_sdk.b("Description:")}\n`);
89
+ for (const line of desc.split("\n")) for (const wl of this._wrap(line, w - 8)) process.stdout.write(` ${require_sdk.dim("│")} ${require_sdk.dim(wl)}\n`);
90
+ }
91
+ const tags = m.tags;
92
+ if (tags && tags.length > 0) {
93
+ process.stdout.write(` ${require_sdk.dim("│")}\n`);
94
+ process.stdout.write(` ${require_sdk.dim("│")} ${require_sdk.b("Tags:")} ${require_sdk.dim(tags.map((t) => `#${t}`).join(" "))}\n`);
95
+ }
96
+ const locName = m.location_slug ?? "";
97
+ const locId = m.location_id ?? "";
98
+ if (locName || locId) row("Location:", locId ? `${locName} (ID: ${locId})` : locName);
99
+ const coauthors = m.coauthors;
100
+ if (coauthors && coauthors.length > 0) row("Co-authors:", coauthors.map((c) => c.full_name ? `${c.username} (${c.full_name})` : c.username).join(", "));
101
+ const pinned = m.pinned;
102
+ if (pinned && pinned.length > 0) row("Pinned:", pinned.join(", "));
103
+ const expires = m.expires;
104
+ if (expires) row("Expires:", expires, require_sdk._YELLOW);
105
+ const hlTitle = m.highlight_title;
106
+ if (hlTitle) row("Highlight:", hlTitle);
107
+ const taggedUser = m.tagged_username ?? "";
108
+ if (taggedUser) {
109
+ const taggedFull = m.tagged_full_name ?? "";
110
+ row("Tagged by:", taggedFull ? `${taggedUser} (${taggedFull})` : taggedUser);
111
+ }
112
+ if (this._files.length > 0) {
113
+ process.stdout.write(` ${require_sdk.dim("│")}\n`);
114
+ process.stdout.write(` ${require_sdk.dim("│")} ${require_sdk.b(`Media (${this._files.length} files):`)}\n`);
115
+ const maxNumW = String(this._files.length).length;
116
+ const maxFileW = Math.max(...this._files.map((f) => f.filename.length));
117
+ const dimW = Math.min(maxFileW, 40);
118
+ for (const f of this._files) {
119
+ const numStr = `[${String(f.num).padStart(maxNumW)}]`;
120
+ const dimStr = f.filename.length > 40 ? `${f.filename.slice(0, 37)}...` : require_sdk.pad(f.filename, dimW);
121
+ const res = f.width ? `${f.width}x${f.height}` : "?x?";
122
+ const badges = [];
123
+ if (f.videoUrl) badges.push("video");
124
+ if (f.audioUrl) badges.push("audio");
125
+ let line = ` ${require_sdk.dim("│")} ${require_sdk.g(numStr)} ${dimStr} ${res}`;
126
+ if (badges.length > 0) line += ` ${require_sdk._YELLOW}(${badges.join("+")})${require_sdk._RESET}`;
127
+ process.stdout.write(`${line}\n`);
128
+ }
129
+ }
130
+ process.stdout.write(` ${require_sdk.dim("└")}${"─".repeat(w - 2)}${require_sdk.dim("┘")}\n`);
131
+ }
132
+ _wrap(text, maxLen) {
133
+ if (text.length <= maxLen) return [text];
134
+ const lines = [];
135
+ let remaining = text;
136
+ while (remaining.length > maxLen) {
137
+ let cut = maxLen;
138
+ while (cut > 0 && remaining[cut] !== " ") cut--;
139
+ if (cut === 0) cut = maxLen;
140
+ lines.push(remaining.slice(0, cut).trimEnd());
141
+ remaining = remaining.slice(cut).trimStart();
142
+ }
143
+ if (remaining) lines.push(remaining);
144
+ return lines;
145
+ }
146
+ _report() {
147
+ this._flushPost();
148
+ process.stdout.write(`\n${require_sdk.dim("──")} ${require_sdk.b("Summary")} ${require_sdk.dim("───")}\n`);
149
+ process.stdout.write(` Posts: ${require_sdk.g(String(this._postCount))}\n`);
150
+ process.stdout.write(` Files: ${require_sdk.g(String(this._fileCount))}\n`);
151
+ process.stdout.write(`\n`);
152
+ }
153
+ };
154
+ //#endregion
3
155
  exports.ConfigManager = require_sdk.ConfigManager;
4
156
  exports.DownloadJob = require_sdk.DownloadJob;
5
157
  exports.Extractor = require_sdk.Extractor;
@@ -18,7 +170,7 @@ exports.InstagramTagExtractor = require_sdk.InstagramTagExtractor;
18
170
  exports.InstagramTaggedExtractor = require_sdk.InstagramTaggedExtractor;
19
171
  exports.InstagramUserExtractor = require_sdk.InstagramUserExtractor;
20
172
  exports.Job = require_sdk.Job;
21
- exports.PrintJob = require_sdk.PrintJob;
173
+ exports.PrintJob = PrintJob;
22
174
  exports.directory = require_sdk.directory;
23
175
  exports.ensureHttpScheme = require_sdk.ensureHttpScheme;
24
176
  exports.extr = require_sdk.extr;
package/dist/index.d.cts CHANGED
@@ -1,14 +1,11 @@
1
- import { _ as Metadata, a as ExtractorOptions, b as Storage, c as ConfigManager, d as DirectoryMsg, f as ExtractorClass, g as MessageIter, h as Message, i as Extractor, l as Config, m as HttpResponse, n as InstagramSDK, o as Logger, p as HttpClient, r as SDKOptions, s as noopLogger, t as ExtractOptions, u as ConfigValue, v as QueueMsg, x as UrlMsg, y as RequestConfig } from "./sdk-CK9x5wFL.cjs";
1
+ import { _ as Metadata, a as ExtractorOptions, b as Storage, c as ConfigManager, d as DirectoryMsg, f as ExtractorClass, g as MessageIter, h as Message, i as Extractor, l as Config, m as HttpResponse, n as InstagramSDK, o as Logger, p as HttpClient, r as SDKOptions, s as noopLogger, t as ExtractOptions, u as ConfigValue, v as QueueMsg, x as UrlMsg, y as RequestConfig } from "./sdk-DyZz22bT.cjs";
2
2
 
3
3
  //#region src/core/job.d.ts
4
4
  declare abstract class Job {
5
5
  readonly extractor: Extractor;
6
6
  status: number;
7
7
  constructor(extractor: Extractor);
8
- /**
9
- * Main entry point. Calls ``extractor[Symbol.asyncIterator]()`` and
10
- * dispatches every yielded message.
11
- */
8
+ /** Main entry point. Dispatches every yielded message. */
12
9
  run(): Promise<number>;
13
10
  /** Override in subclasses to print a summary. */
14
11
  protected _report(): void;
@@ -16,7 +13,8 @@ declare abstract class Job {
16
13
  abstract handleUrl(msg: UrlMsg): Promise<void>;
17
14
  abstract handleQueue(msg: QueueMsg): Promise<void>;
18
15
  }
19
- /** An in-memory archive: category → Set<archive-key>. */
16
+ //#endregion
17
+ //#region src/core/download-job.d.ts
20
18
  type ArchiveMap = Map<string, Set<string>>;
21
19
  declare class DownloadJob extends Job {
22
20
  /** Base output directory (prepended to all paths). */
@@ -25,32 +23,24 @@ declare class DownloadJob extends Job {
25
23
  private _currentDir;
26
24
  /** In-memory archive keyed by archive format. */
27
25
  readonly archive: ArchiveMap;
28
- /**
29
- * Registry of per-category "archive formats" — the key is formed
30
- * by interpolating this format string over the metadata.
31
- */
32
26
  private readonly _archiveFmts;
33
27
  private _postCount;
34
28
  private _fileCount;
35
29
  private _downloadedBytes;
36
30
  private _skippedCount;
37
31
  registerArchive(category: string, format: string): void;
38
- /** Simple format-string interpolation for archive keys. */
39
32
  private _interp;
40
- /** Check whether this URL has already been downloaded (and skip). */
41
33
  private _isArchived;
42
- /** Mark a post/media as archived. */
43
34
  private _archive;
44
- /** Handlers */
45
35
  handleDirectory(msg: DirectoryMsg): Promise<void>;
46
36
  handleUrl(msg: UrlMsg): Promise<void>;
47
37
  handleQueue(msg: QueueMsg): Promise<void>;
48
- /** Report */
49
38
  protected _report(): void;
50
- /** Path builders */
51
39
  private _buildDirPath;
52
40
  private _buildFilename;
53
41
  }
42
+ //#endregion
43
+ //#region src/core/print-job.d.ts
54
44
  declare class PrintJob extends Job {
55
45
  private _currentDir;
56
46
  private _files;
@@ -61,7 +51,6 @@ declare class PrintJob extends Job {
61
51
  handleDirectory(msg: DirectoryMsg): Promise<void>;
62
52
  handleUrl(msg: UrlMsg): Promise<void>;
63
53
  handleQueue(msg: QueueMsg): Promise<void>;
64
- /** Output */
65
54
  private _flushPost;
66
55
  private _wrap;
67
56
  protected _report(): void;
@@ -433,24 +422,48 @@ declare abstract class InstagramExtractor extends Extractor {
433
422
  protected _assignUser(user: InstagramUser): void;
434
423
  }
435
424
  //#endregion
436
- //#region src/instagram/extractors.d.ts
437
- declare class InstagramPostExtractor extends InstagramExtractor {
438
- static readonly subcategory = "post";
425
+ //#region src/instagram/extractors/avatar.d.ts
426
+ declare class InstagramAvatarExtractor extends InstagramExtractor {
427
+ static readonly subcategory = "avatar";
439
428
  static pattern: RegExp;
440
- readonly subcategory = "post";
429
+ readonly subcategory = "avatar";
441
430
  constructor(opts: InstagramExtractorOptions);
442
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramPostExtractor | null;
431
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramAvatarExtractor | null;
443
432
  posts(): AsyncGenerator<InstagramPost>;
444
433
  }
445
- declare class InstagramUserExtractor extends InstagramExtractor {
446
- static readonly subcategory = "user";
434
+ //#endregion
435
+ //#region src/instagram/extractors/highlights.d.ts
436
+ declare class InstagramHighlightsExtractor extends InstagramExtractor {
437
+ static readonly subcategory = "highlights";
447
438
  static pattern: RegExp;
448
- readonly subcategory = "user";
439
+ readonly subcategory = "highlights";
449
440
  constructor(opts: InstagramExtractorOptions);
450
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramUserExtractor | null;
441
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramHighlightsExtractor | null;
442
+ posts(): AsyncGenerator<InstagramPost>;
443
+ }
444
+ //#endregion
445
+ //#region src/instagram/extractors/info.d.ts
446
+ declare class InstagramInfoExtractor extends InstagramExtractor {
447
+ static readonly subcategory = "info";
448
+ static pattern: RegExp;
449
+ readonly subcategory = "info";
450
+ constructor(opts: InstagramExtractorOptions);
451
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramInfoExtractor | null;
451
452
  items(): MessageIter;
452
453
  posts(): AsyncGenerator<InstagramPost>;
453
454
  }
455
+ //#endregion
456
+ //#region src/instagram/extractors/post.d.ts
457
+ declare class InstagramPostExtractor extends InstagramExtractor {
458
+ static readonly subcategory = "post";
459
+ static pattern: RegExp;
460
+ readonly subcategory = "post";
461
+ constructor(opts: InstagramExtractorOptions);
462
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramPostExtractor | null;
463
+ posts(): AsyncGenerator<InstagramPost>;
464
+ }
465
+ //#endregion
466
+ //#region src/instagram/extractors/posts-list.d.ts
454
467
  declare class InstagramPostsExtractor extends InstagramExtractor {
455
468
  static readonly subcategory = "posts";
456
469
  static pattern: RegExp;
@@ -459,6 +472,8 @@ declare class InstagramPostsExtractor extends InstagramExtractor {
459
472
  static fromURL(url: string, opts: InstagramExtractorOptions): InstagramPostsExtractor | null;
460
473
  posts(): AsyncGenerator<InstagramPost>;
461
474
  }
475
+ //#endregion
476
+ //#region src/instagram/extractors/reels-list.d.ts
462
477
  declare class InstagramReelsExtractor extends InstagramExtractor {
463
478
  static readonly subcategory = "reels";
464
479
  static pattern: RegExp;
@@ -467,16 +482,18 @@ declare class InstagramReelsExtractor extends InstagramExtractor {
467
482
  static fromURL(url: string, opts: InstagramExtractorOptions): InstagramReelsExtractor | null;
468
483
  posts(): AsyncGenerator<InstagramPost>;
469
484
  }
470
- declare class InstagramTaggedExtractor extends InstagramExtractor {
471
- static readonly subcategory = "tagged";
485
+ //#endregion
486
+ //#region src/instagram/extractors/saved.d.ts
487
+ declare class InstagramSavedExtractor extends InstagramExtractor {
488
+ static readonly subcategory = "saved";
472
489
  static pattern: RegExp;
473
- readonly subcategory = "tagged";
474
- private _taggedUserId;
490
+ readonly subcategory = "saved";
475
491
  constructor(opts: InstagramExtractorOptions);
476
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramTaggedExtractor | null;
477
- metadata(): Promise<Record<string, unknown>>;
492
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramSavedExtractor | null;
478
493
  posts(): AsyncGenerator<InstagramPost>;
479
494
  }
495
+ //#endregion
496
+ //#region src/instagram/extractors/stories.d.ts
480
497
  declare class InstagramStoriesExtractor extends InstagramExtractor {
481
498
  static readonly subcategory = "stories";
482
499
  static pattern: RegExp;
@@ -487,14 +504,8 @@ declare class InstagramStoriesExtractor extends InstagramExtractor {
487
504
  static fromURL(url: string, opts: InstagramExtractorOptions): InstagramStoriesExtractor | null;
488
505
  posts(): AsyncGenerator<InstagramPost>;
489
506
  }
490
- declare class InstagramHighlightsExtractor extends InstagramExtractor {
491
- static readonly subcategory = "highlights";
492
- static pattern: RegExp;
493
- readonly subcategory = "highlights";
494
- constructor(opts: InstagramExtractorOptions);
495
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramHighlightsExtractor | null;
496
- posts(): AsyncGenerator<InstagramPost>;
497
- }
507
+ //#endregion
508
+ //#region src/instagram/extractors/tag.d.ts
498
509
  declare class InstagramTagExtractor extends InstagramExtractor {
499
510
  static readonly subcategory = "tag";
500
511
  static pattern: RegExp;
@@ -504,41 +515,41 @@ declare class InstagramTagExtractor extends InstagramExtractor {
504
515
  metadata(): Promise<Record<string, unknown>>;
505
516
  posts(): AsyncGenerator<InstagramPost>;
506
517
  }
507
- declare class InstagramInfoExtractor extends InstagramExtractor {
508
- static readonly subcategory = "info";
509
- static pattern: RegExp;
510
- readonly subcategory = "info";
511
- constructor(opts: InstagramExtractorOptions);
512
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramInfoExtractor | null;
513
- items(): MessageIter;
514
- posts(): AsyncGenerator<InstagramPost>;
515
- }
516
- declare class InstagramAvatarExtractor extends InstagramExtractor {
517
- static readonly subcategory = "avatar";
518
+ //#endregion
519
+ //#region src/instagram/extractors/tagged.d.ts
520
+ declare class InstagramTaggedExtractor extends InstagramExtractor {
521
+ static readonly subcategory = "tagged";
518
522
  static pattern: RegExp;
519
- readonly subcategory = "avatar";
523
+ readonly subcategory = "tagged";
524
+ private _taggedUserId;
520
525
  constructor(opts: InstagramExtractorOptions);
521
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramAvatarExtractor | null;
526
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramTaggedExtractor | null;
527
+ metadata(): Promise<Record<string, unknown>>;
522
528
  posts(): AsyncGenerator<InstagramPost>;
523
529
  }
524
- declare class InstagramSavedExtractor extends InstagramExtractor {
525
- static readonly subcategory = "saved";
530
+ //#endregion
531
+ //#region src/instagram/extractors/user.d.ts
532
+ declare class InstagramUserExtractor extends InstagramExtractor {
533
+ static readonly subcategory = "user";
526
534
  static pattern: RegExp;
527
- readonly subcategory = "saved";
535
+ readonly subcategory = "user";
528
536
  constructor(opts: InstagramExtractorOptions);
529
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramSavedExtractor | null;
537
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramUserExtractor | null;
538
+ items(): MessageIter;
530
539
  posts(): AsyncGenerator<InstagramPost>;
531
540
  }
532
541
  //#endregion
533
- //#region src/instagram/parsers.d.ts
534
- /** Main entry REST */
542
+ //#region src/instagram/parsers/graphql.d.ts
543
+ /** Parse a GraphQL post/edge response. */
544
+ declare function parsePostGraphql(post: Record<string, unknown>, cfg: ParserConfig): ParsedPost;
545
+ //#endregion
546
+ //#region src/instagram/parsers/rest.d.ts
547
+ /** Main entry — parse a REST post response. */
535
548
  declare function parsePostRest(post: InstagramPost, cfg: ParserConfig): ParsedPost;
536
- /** Tagged users */
549
+ /** Extract tagged users from various field formats. */
537
550
  declare function extractTaggedUsers(src: Record<string, unknown>, dest: ParsedMedia): void;
538
- /** Audio / music extraction */
551
+ /** Extract audio/music metadata from a story sticker. */
539
552
  declare function extractAudio(src: Record<string, unknown>, dest: Record<string, unknown>, sticker: MusicSticker, cfg: ParserConfig): ParsedMedia | null;
540
- /** GraphQL parser */
541
- declare function parsePostGraphql(post: Record<string, unknown>, cfg: ParserConfig): ParsedPost;
542
553
  //#endregion
543
554
  //#region src/message.d.ts
544
555
  declare function directory(metadata?: Metadata): DirectoryMsg;
package/dist/index.d.mts CHANGED
@@ -1,14 +1,11 @@
1
- import { _ as Metadata, a as ExtractorOptions, b as Storage, c as ConfigManager, d as DirectoryMsg, f as ExtractorClass, g as MessageIter, h as Message, i as Extractor, l as Config, m as HttpResponse, n as InstagramSDK, o as Logger, p as HttpClient, r as SDKOptions, s as noopLogger, t as ExtractOptions, u as ConfigValue, v as QueueMsg, x as UrlMsg, y as RequestConfig } from "./sdk-CK9x5wFL.mjs";
1
+ import { _ as Metadata, a as ExtractorOptions, b as Storage, c as ConfigManager, d as DirectoryMsg, f as ExtractorClass, g as MessageIter, h as Message, i as Extractor, l as Config, m as HttpResponse, n as InstagramSDK, o as Logger, p as HttpClient, r as SDKOptions, s as noopLogger, t as ExtractOptions, u as ConfigValue, v as QueueMsg, x as UrlMsg, y as RequestConfig } from "./sdk-DyZz22bT.mjs";
2
2
 
3
3
  //#region src/core/job.d.ts
4
4
  declare abstract class Job {
5
5
  readonly extractor: Extractor;
6
6
  status: number;
7
7
  constructor(extractor: Extractor);
8
- /**
9
- * Main entry point. Calls ``extractor[Symbol.asyncIterator]()`` and
10
- * dispatches every yielded message.
11
- */
8
+ /** Main entry point. Dispatches every yielded message. */
12
9
  run(): Promise<number>;
13
10
  /** Override in subclasses to print a summary. */
14
11
  protected _report(): void;
@@ -16,7 +13,8 @@ declare abstract class Job {
16
13
  abstract handleUrl(msg: UrlMsg): Promise<void>;
17
14
  abstract handleQueue(msg: QueueMsg): Promise<void>;
18
15
  }
19
- /** An in-memory archive: category → Set<archive-key>. */
16
+ //#endregion
17
+ //#region src/core/download-job.d.ts
20
18
  type ArchiveMap = Map<string, Set<string>>;
21
19
  declare class DownloadJob extends Job {
22
20
  /** Base output directory (prepended to all paths). */
@@ -25,32 +23,24 @@ declare class DownloadJob extends Job {
25
23
  private _currentDir;
26
24
  /** In-memory archive keyed by archive format. */
27
25
  readonly archive: ArchiveMap;
28
- /**
29
- * Registry of per-category "archive formats" — the key is formed
30
- * by interpolating this format string over the metadata.
31
- */
32
26
  private readonly _archiveFmts;
33
27
  private _postCount;
34
28
  private _fileCount;
35
29
  private _downloadedBytes;
36
30
  private _skippedCount;
37
31
  registerArchive(category: string, format: string): void;
38
- /** Simple format-string interpolation for archive keys. */
39
32
  private _interp;
40
- /** Check whether this URL has already been downloaded (and skip). */
41
33
  private _isArchived;
42
- /** Mark a post/media as archived. */
43
34
  private _archive;
44
- /** Handlers */
45
35
  handleDirectory(msg: DirectoryMsg): Promise<void>;
46
36
  handleUrl(msg: UrlMsg): Promise<void>;
47
37
  handleQueue(msg: QueueMsg): Promise<void>;
48
- /** Report */
49
38
  protected _report(): void;
50
- /** Path builders */
51
39
  private _buildDirPath;
52
40
  private _buildFilename;
53
41
  }
42
+ //#endregion
43
+ //#region src/core/print-job.d.ts
54
44
  declare class PrintJob extends Job {
55
45
  private _currentDir;
56
46
  private _files;
@@ -61,7 +51,6 @@ declare class PrintJob extends Job {
61
51
  handleDirectory(msg: DirectoryMsg): Promise<void>;
62
52
  handleUrl(msg: UrlMsg): Promise<void>;
63
53
  handleQueue(msg: QueueMsg): Promise<void>;
64
- /** Output */
65
54
  private _flushPost;
66
55
  private _wrap;
67
56
  protected _report(): void;
@@ -433,24 +422,48 @@ declare abstract class InstagramExtractor extends Extractor {
433
422
  protected _assignUser(user: InstagramUser): void;
434
423
  }
435
424
  //#endregion
436
- //#region src/instagram/extractors.d.ts
437
- declare class InstagramPostExtractor extends InstagramExtractor {
438
- static readonly subcategory = "post";
425
+ //#region src/instagram/extractors/avatar.d.ts
426
+ declare class InstagramAvatarExtractor extends InstagramExtractor {
427
+ static readonly subcategory = "avatar";
439
428
  static pattern: RegExp;
440
- readonly subcategory = "post";
429
+ readonly subcategory = "avatar";
441
430
  constructor(opts: InstagramExtractorOptions);
442
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramPostExtractor | null;
431
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramAvatarExtractor | null;
443
432
  posts(): AsyncGenerator<InstagramPost>;
444
433
  }
445
- declare class InstagramUserExtractor extends InstagramExtractor {
446
- static readonly subcategory = "user";
434
+ //#endregion
435
+ //#region src/instagram/extractors/highlights.d.ts
436
+ declare class InstagramHighlightsExtractor extends InstagramExtractor {
437
+ static readonly subcategory = "highlights";
447
438
  static pattern: RegExp;
448
- readonly subcategory = "user";
439
+ readonly subcategory = "highlights";
449
440
  constructor(opts: InstagramExtractorOptions);
450
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramUserExtractor | null;
441
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramHighlightsExtractor | null;
442
+ posts(): AsyncGenerator<InstagramPost>;
443
+ }
444
+ //#endregion
445
+ //#region src/instagram/extractors/info.d.ts
446
+ declare class InstagramInfoExtractor extends InstagramExtractor {
447
+ static readonly subcategory = "info";
448
+ static pattern: RegExp;
449
+ readonly subcategory = "info";
450
+ constructor(opts: InstagramExtractorOptions);
451
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramInfoExtractor | null;
451
452
  items(): MessageIter;
452
453
  posts(): AsyncGenerator<InstagramPost>;
453
454
  }
455
+ //#endregion
456
+ //#region src/instagram/extractors/post.d.ts
457
+ declare class InstagramPostExtractor extends InstagramExtractor {
458
+ static readonly subcategory = "post";
459
+ static pattern: RegExp;
460
+ readonly subcategory = "post";
461
+ constructor(opts: InstagramExtractorOptions);
462
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramPostExtractor | null;
463
+ posts(): AsyncGenerator<InstagramPost>;
464
+ }
465
+ //#endregion
466
+ //#region src/instagram/extractors/posts-list.d.ts
454
467
  declare class InstagramPostsExtractor extends InstagramExtractor {
455
468
  static readonly subcategory = "posts";
456
469
  static pattern: RegExp;
@@ -459,6 +472,8 @@ declare class InstagramPostsExtractor extends InstagramExtractor {
459
472
  static fromURL(url: string, opts: InstagramExtractorOptions): InstagramPostsExtractor | null;
460
473
  posts(): AsyncGenerator<InstagramPost>;
461
474
  }
475
+ //#endregion
476
+ //#region src/instagram/extractors/reels-list.d.ts
462
477
  declare class InstagramReelsExtractor extends InstagramExtractor {
463
478
  static readonly subcategory = "reels";
464
479
  static pattern: RegExp;
@@ -467,16 +482,18 @@ declare class InstagramReelsExtractor extends InstagramExtractor {
467
482
  static fromURL(url: string, opts: InstagramExtractorOptions): InstagramReelsExtractor | null;
468
483
  posts(): AsyncGenerator<InstagramPost>;
469
484
  }
470
- declare class InstagramTaggedExtractor extends InstagramExtractor {
471
- static readonly subcategory = "tagged";
485
+ //#endregion
486
+ //#region src/instagram/extractors/saved.d.ts
487
+ declare class InstagramSavedExtractor extends InstagramExtractor {
488
+ static readonly subcategory = "saved";
472
489
  static pattern: RegExp;
473
- readonly subcategory = "tagged";
474
- private _taggedUserId;
490
+ readonly subcategory = "saved";
475
491
  constructor(opts: InstagramExtractorOptions);
476
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramTaggedExtractor | null;
477
- metadata(): Promise<Record<string, unknown>>;
492
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramSavedExtractor | null;
478
493
  posts(): AsyncGenerator<InstagramPost>;
479
494
  }
495
+ //#endregion
496
+ //#region src/instagram/extractors/stories.d.ts
480
497
  declare class InstagramStoriesExtractor extends InstagramExtractor {
481
498
  static readonly subcategory = "stories";
482
499
  static pattern: RegExp;
@@ -487,14 +504,8 @@ declare class InstagramStoriesExtractor extends InstagramExtractor {
487
504
  static fromURL(url: string, opts: InstagramExtractorOptions): InstagramStoriesExtractor | null;
488
505
  posts(): AsyncGenerator<InstagramPost>;
489
506
  }
490
- declare class InstagramHighlightsExtractor extends InstagramExtractor {
491
- static readonly subcategory = "highlights";
492
- static pattern: RegExp;
493
- readonly subcategory = "highlights";
494
- constructor(opts: InstagramExtractorOptions);
495
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramHighlightsExtractor | null;
496
- posts(): AsyncGenerator<InstagramPost>;
497
- }
507
+ //#endregion
508
+ //#region src/instagram/extractors/tag.d.ts
498
509
  declare class InstagramTagExtractor extends InstagramExtractor {
499
510
  static readonly subcategory = "tag";
500
511
  static pattern: RegExp;
@@ -504,41 +515,41 @@ declare class InstagramTagExtractor extends InstagramExtractor {
504
515
  metadata(): Promise<Record<string, unknown>>;
505
516
  posts(): AsyncGenerator<InstagramPost>;
506
517
  }
507
- declare class InstagramInfoExtractor extends InstagramExtractor {
508
- static readonly subcategory = "info";
509
- static pattern: RegExp;
510
- readonly subcategory = "info";
511
- constructor(opts: InstagramExtractorOptions);
512
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramInfoExtractor | null;
513
- items(): MessageIter;
514
- posts(): AsyncGenerator<InstagramPost>;
515
- }
516
- declare class InstagramAvatarExtractor extends InstagramExtractor {
517
- static readonly subcategory = "avatar";
518
+ //#endregion
519
+ //#region src/instagram/extractors/tagged.d.ts
520
+ declare class InstagramTaggedExtractor extends InstagramExtractor {
521
+ static readonly subcategory = "tagged";
518
522
  static pattern: RegExp;
519
- readonly subcategory = "avatar";
523
+ readonly subcategory = "tagged";
524
+ private _taggedUserId;
520
525
  constructor(opts: InstagramExtractorOptions);
521
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramAvatarExtractor | null;
526
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramTaggedExtractor | null;
527
+ metadata(): Promise<Record<string, unknown>>;
522
528
  posts(): AsyncGenerator<InstagramPost>;
523
529
  }
524
- declare class InstagramSavedExtractor extends InstagramExtractor {
525
- static readonly subcategory = "saved";
530
+ //#endregion
531
+ //#region src/instagram/extractors/user.d.ts
532
+ declare class InstagramUserExtractor extends InstagramExtractor {
533
+ static readonly subcategory = "user";
526
534
  static pattern: RegExp;
527
- readonly subcategory = "saved";
535
+ readonly subcategory = "user";
528
536
  constructor(opts: InstagramExtractorOptions);
529
- static fromURL(url: string, opts: InstagramExtractorOptions): InstagramSavedExtractor | null;
537
+ static fromURL(url: string, opts: InstagramExtractorOptions): InstagramUserExtractor | null;
538
+ items(): MessageIter;
530
539
  posts(): AsyncGenerator<InstagramPost>;
531
540
  }
532
541
  //#endregion
533
- //#region src/instagram/parsers.d.ts
534
- /** Main entry REST */
542
+ //#region src/instagram/parsers/graphql.d.ts
543
+ /** Parse a GraphQL post/edge response. */
544
+ declare function parsePostGraphql(post: Record<string, unknown>, cfg: ParserConfig): ParsedPost;
545
+ //#endregion
546
+ //#region src/instagram/parsers/rest.d.ts
547
+ /** Main entry — parse a REST post response. */
535
548
  declare function parsePostRest(post: InstagramPost, cfg: ParserConfig): ParsedPost;
536
- /** Tagged users */
549
+ /** Extract tagged users from various field formats. */
537
550
  declare function extractTaggedUsers(src: Record<string, unknown>, dest: ParsedMedia): void;
538
- /** Audio / music extraction */
551
+ /** Extract audio/music metadata from a story sticker. */
539
552
  declare function extractAudio(src: Record<string, unknown>, dest: Record<string, unknown>, sticker: MusicSticker, cfg: ParserConfig): ParsedMedia | null;
540
- /** GraphQL parser */
541
- declare function parsePostGraphql(post: Record<string, unknown>, cfg: ParserConfig): ParsedPost;
542
553
  //#endregion
543
554
  //#region src/message.d.ts
544
555
  declare function directory(metadata?: Metadata): DirectoryMsg;