@postfetch/core 0.4.1 → 0.5.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/dist/index.js +5 -4
- package/package.json +1 -1
- package/src/instagram.ts +10 -3
- package/src/reddit.ts +3 -3
package/dist/index.js
CHANGED
|
@@ -266,12 +266,16 @@ async function instagramUnavailable(net, code) {
|
|
|
266
266
|
const response = await net(url.href, { headers: mobileHeaders() }, 1).catch(() => null);
|
|
267
267
|
const body = response ? await response.text().catch(() => "") : "";
|
|
268
268
|
const reason = instagramUnavailableReason(response?.status ?? 0, body);
|
|
269
|
-
|
|
269
|
+
const probe = response ? `oembed ${response.status}` : "oembed unreachable";
|
|
270
|
+
return new PostfetchError(reasonStatus(reason), `Instagram post unavailable: ${reason} (${probe})`, reason);
|
|
270
271
|
}
|
|
271
272
|
function instagramUnavailableReason(status, body) {
|
|
272
273
|
if (status === 404) {
|
|
273
274
|
return "notFound";
|
|
274
275
|
}
|
|
276
|
+
if (status === 429) {
|
|
277
|
+
return "rateLimited";
|
|
278
|
+
}
|
|
275
279
|
if (status !== 0 && status < 400) {
|
|
276
280
|
return "unavailable";
|
|
277
281
|
}
|
|
@@ -1008,9 +1012,6 @@ async function resolveReddit(input) {
|
|
|
1008
1012
|
const token = await appToken(input.net);
|
|
1009
1013
|
const post = await fetchPost(input.net, token, id);
|
|
1010
1014
|
const items = await mediaItems3(input, post, id);
|
|
1011
|
-
if (items.length === 0) {
|
|
1012
|
-
throw new Error("Reddit media not found");
|
|
1013
|
-
}
|
|
1014
1015
|
return { archiveFilename: filename(`reddit_${id}.zip`), id, items, metadata: redditMetadata(post), platform: "reddit" };
|
|
1015
1016
|
}
|
|
1016
1017
|
function redditMetadata(post) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postfetch/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Zero-dependency typed core that turns Facebook, Instagram, Pinterest, Reddit, SoundCloud, TikTok, X and YouTube post URLs into media files.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/instagram.ts
CHANGED
|
@@ -79,16 +79,23 @@ async function instagramUnavailable(net: Net, code: string): Promise<PostfetchEr
|
|
|
79
79
|
const response = await net(url.href, { headers: mobileHeaders() }, 1).catch(() => null);
|
|
80
80
|
const body = response ? await response.text().catch(() => "") : "";
|
|
81
81
|
const reason = instagramUnavailableReason(response?.status ?? 0, body);
|
|
82
|
-
|
|
82
|
+
// Carry the oembed status so an unclassified failure still leaves a raw clue
|
|
83
|
+
// (200 = post is public but no media could be parsed; 429 = throttled; …).
|
|
84
|
+
const probe = response ? `oembed ${response.status}` : "oembed unreachable";
|
|
85
|
+
return new PostfetchError(reasonStatus(reason), `Instagram post unavailable: ${reason} (${probe})`, reason);
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
// Classifies why the post is gone from the oembed endpoint, which returns a
|
|
86
|
-
// telling status and body (404 when removed; 400 with a
|
|
87
|
-
// for 18+ accounts) while the media endpoints just come
|
|
89
|
+
// telling status and body (404 when removed; 429 when throttled; 400 with a
|
|
90
|
+
// MIN_AGE_ACCOUNT block for 18+ accounts) while the media endpoints just come
|
|
91
|
+
// back empty.
|
|
88
92
|
export function instagramUnavailableReason(status: number, body: string): PostfetchReason {
|
|
89
93
|
if (status === 404) {
|
|
90
94
|
return "notFound";
|
|
91
95
|
}
|
|
96
|
+
if (status === 429) {
|
|
97
|
+
return "rateLimited";
|
|
98
|
+
}
|
|
92
99
|
if (status !== 0 && status < 400) {
|
|
93
100
|
return "unavailable";
|
|
94
101
|
}
|
package/src/reddit.ts
CHANGED
|
@@ -27,10 +27,10 @@ export async function resolveReddit(input: ResolveContext): Promise<PostfetchRes
|
|
|
27
27
|
const id = await postId(input.net, input.url);
|
|
28
28
|
const token = await appToken(input.net);
|
|
29
29
|
const post = await fetchPost(input.net, token, id);
|
|
30
|
+
// A text post is a valid result with metadata and no media — fetchPost has
|
|
31
|
+
// already thrown if the post itself is missing, so empty items here mean a
|
|
32
|
+
// self/text post, not a failure.
|
|
30
33
|
const items = await mediaItems(input, post, id);
|
|
31
|
-
if (items.length === 0) {
|
|
32
|
-
throw new Error("Reddit media not found");
|
|
33
|
-
}
|
|
34
34
|
return { archiveFilename: filename(`reddit_${id}.zip`), id, items, metadata: redditMetadata(post), platform: "reddit" };
|
|
35
35
|
}
|
|
36
36
|
|