@nocoo/zhe 1.19.3 → 1.24.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 +27 -0
- package/dist/api/client.d.ts +18 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +25 -8
- package/dist/api/client.js.map +1 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/commands/connector.d.ts +2 -0
- package/dist/commands/connector.d.ts.map +1 -0
- package/dist/commands/connector.js +93 -0
- package/dist/commands/connector.js.map +1 -0
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +1 -1
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/delete.js +1 -1
- package/dist/commands/delete.js.map +1 -1
- package/dist/commands/folder.d.ts.map +1 -1
- package/dist/commands/folder.js +1 -1
- package/dist/commands/folder.js.map +1 -1
- package/dist/commands/folders.js +1 -1
- package/dist/commands/folders.js.map +1 -1
- package/dist/commands/get.js +1 -1
- package/dist/commands/get.js.map +1 -1
- package/dist/commands/idea/add.d.ts.map +1 -1
- package/dist/commands/idea/add.js +1 -1
- package/dist/commands/idea/add.js.map +1 -1
- package/dist/commands/idea/delete.js +1 -1
- package/dist/commands/idea/delete.js.map +1 -1
- package/dist/commands/idea/get.d.ts.map +1 -1
- package/dist/commands/idea/get.js +2 -2
- package/dist/commands/idea/get.js.map +1 -1
- package/dist/commands/idea/helpers.d.ts.map +1 -1
- package/dist/commands/idea/helpers.js +1 -1
- package/dist/commands/idea/helpers.js.map +1 -1
- package/dist/commands/idea/list.d.ts.map +1 -1
- package/dist/commands/idea/list.js +2 -2
- package/dist/commands/idea/list.js.map +1 -1
- package/dist/commands/idea/update.d.ts.map +1 -1
- package/dist/commands/idea/update.js +1 -1
- package/dist/commands/idea/update.js.map +1 -1
- package/dist/commands/idea.js +1 -1
- package/dist/commands/idea.js.map +1 -1
- package/dist/commands/inbox.js +1 -1
- package/dist/commands/inbox.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +3 -4
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/open.js +1 -1
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/tag.d.ts.map +1 -1
- package/dist/commands/tag.js +1 -1
- package/dist/commands/tag.js.map +1 -1
- package/dist/commands/tags.js +1 -1
- package/dist/commands/tags.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/connector/core.d.ts +64 -0
- package/dist/connector/core.d.ts.map +1 -0
- package/dist/connector/core.js +237 -0
- package/dist/connector/core.js.map +1 -0
- package/dist/connector/dns.d.ts +3 -0
- package/dist/connector/dns.d.ts.map +1 -0
- package/dist/connector/dns.js +92 -0
- package/dist/connector/dns.js.map +1 -0
- package/dist/connector/download.d.ts +5 -0
- package/dist/connector/download.d.ts.map +1 -0
- package/dist/connector/download.js +183 -0
- package/dist/connector/download.js.map +1 -0
- package/dist/connector/opencli.d.ts +6 -0
- package/dist/connector/opencli.d.ts.map +1 -0
- package/dist/connector/opencli.js +136 -0
- package/dist/connector/opencli.js.map +1 -0
- package/dist/connector/runtime.d.ts +11 -0
- package/dist/connector/runtime.d.ts.map +1 -0
- package/dist/connector/runtime.js +117 -0
- package/dist/connector/runtime.js.map +1 -0
- package/dist/connector/types.d.ts +25 -0
- package/dist/connector/types.d.ts.map +1 -0
- package/dist/connector/types.js +2 -0
- package/dist/connector/types.js.map +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/resolve.d.ts.map +1 -1
- package/dist/utils/resolve.js +1 -1
- package/dist/utils/resolve.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -1
- package/dist/utils.js.map +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +13 -7
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
export class ConnectorError extends Error {
|
|
2
|
+
code;
|
|
3
|
+
status;
|
|
4
|
+
constructor(code, status = 0) {
|
|
5
|
+
super(code);
|
|
6
|
+
this.code = code;
|
|
7
|
+
this.status = status;
|
|
8
|
+
this.name = "ConnectorError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function record(value) {
|
|
12
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
13
|
+
? value
|
|
14
|
+
: {};
|
|
15
|
+
}
|
|
16
|
+
const text = (value) => (typeof value === "string" ? value : "");
|
|
17
|
+
const count = (value) => {
|
|
18
|
+
const n = Number(value);
|
|
19
|
+
return Number.isSafeInteger(n) && n >= 0 ? n : 0;
|
|
20
|
+
};
|
|
21
|
+
const items = (value) => Array.isArray(value) ? value.slice(0, 100).map(record) : [];
|
|
22
|
+
export function canonicalXPost(raw) {
|
|
23
|
+
try {
|
|
24
|
+
const url = new URL(raw);
|
|
25
|
+
const match = /^\/(?:[a-zA-Z0-9_]{1,50}|i\/web)\/status\/(\d{1,22})(?:\/(?:video|photo)\/[1-4])?\/?$/.exec(url.pathname);
|
|
26
|
+
if (url.protocol !== "https:" ||
|
|
27
|
+
url.port ||
|
|
28
|
+
url.username ||
|
|
29
|
+
url.password ||
|
|
30
|
+
![
|
|
31
|
+
"x.com",
|
|
32
|
+
"www.x.com",
|
|
33
|
+
"mobile.x.com",
|
|
34
|
+
"twitter.com",
|
|
35
|
+
"www.twitter.com",
|
|
36
|
+
"mobile.twitter.com",
|
|
37
|
+
].includes(url.hostname) ||
|
|
38
|
+
!match?.[1])
|
|
39
|
+
return null;
|
|
40
|
+
return { id: match[1], url: `https://x.com/i/status/${match[1]}` };
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Reject redirects too at the download boundary. Never fetch arbitrary URLs from a post.
|
|
47
|
+
export function mediaUrl(raw, mediaId, kind) {
|
|
48
|
+
try {
|
|
49
|
+
const url = new URL(raw);
|
|
50
|
+
if (url.protocol !== "https:" ||
|
|
51
|
+
url.port ||
|
|
52
|
+
url.username ||
|
|
53
|
+
url.password ||
|
|
54
|
+
url.hash ||
|
|
55
|
+
!/^\d{1,22}$/.test(mediaId))
|
|
56
|
+
return null;
|
|
57
|
+
const path = kind === "photo"
|
|
58
|
+
? /^\/media\/[A-Za-z0-9_-]+(?:\.(?:jpg|jpeg|png|webp))?$/
|
|
59
|
+
: kind === "poster"
|
|
60
|
+
? new RegExp(`^/(?:(?:amplify_video_thumb|ext_tw_video_thumb)/${mediaId}/(?:pu/)?img|tweet_video_thumb)/[A-Za-z0-9_-]+(?:\\.(?:jpg|jpeg|png|webp))?$`)
|
|
61
|
+
: new RegExp(`^/(?:(?:amplify_video|ext_tw_video)/${mediaId}/(?:pu/)?vid/(?:avc1/)?[0-9]+x[0-9]+|tweet_video)/[A-Za-z0-9_-]+\\.mp4$`);
|
|
62
|
+
const queryKeys = kind === "video" ? ["tag"] : ["format", "name"];
|
|
63
|
+
if (url.hostname !== (kind === "video" ? "video.twimg.com" : "pbs.twimg.com") ||
|
|
64
|
+
!path.test(url.pathname) ||
|
|
65
|
+
[...url.searchParams.keys()].some((key) => !queryKeys.includes(key)))
|
|
66
|
+
return null;
|
|
67
|
+
return url.href;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function normalizeMedia(legacy, postId) {
|
|
74
|
+
const media = [];
|
|
75
|
+
for (const raw of items(record(legacy.extended_entities).media).slice(0, 16)) {
|
|
76
|
+
const id = text(raw.id_str);
|
|
77
|
+
if (raw.source_status_id_str && raw.source_status_id_str !== postId)
|
|
78
|
+
continue;
|
|
79
|
+
if (raw.ext_media_availability && record(raw.ext_media_availability).status !== "Available")
|
|
80
|
+
continue;
|
|
81
|
+
const dimensions = record(raw.original_info);
|
|
82
|
+
if (raw.type === "photo") {
|
|
83
|
+
const url = mediaUrl(text(raw.media_url_https), id, "photo");
|
|
84
|
+
if (url)
|
|
85
|
+
media.push({
|
|
86
|
+
id,
|
|
87
|
+
type: "PHOTO",
|
|
88
|
+
url,
|
|
89
|
+
width: count(dimensions.width),
|
|
90
|
+
height: count(dimensions.height),
|
|
91
|
+
});
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (raw.type !== "video" && raw.type !== "animated_gif")
|
|
95
|
+
continue;
|
|
96
|
+
const info = record(raw.video_info);
|
|
97
|
+
const variants = items(info.variants)
|
|
98
|
+
.filter((v) => v.content_type === "video/mp4")
|
|
99
|
+
.sort((a, b) => count(b.bitrate) - count(a.bitrate));
|
|
100
|
+
const url = variants.map((v) => mediaUrl(text(v.url), id, "video")).find(Boolean);
|
|
101
|
+
if (!url)
|
|
102
|
+
continue;
|
|
103
|
+
const resolution = /\/(\d+)x(\d+)\//.exec(new URL(url).pathname);
|
|
104
|
+
media.push({
|
|
105
|
+
id,
|
|
106
|
+
type: raw.type === "video" ? "VIDEO" : "GIF",
|
|
107
|
+
url,
|
|
108
|
+
thumbnail_url: mediaUrl(text(raw.media_url_https), id, "poster") ?? undefined,
|
|
109
|
+
width: count(dimensions.width) || count(resolution?.[1]),
|
|
110
|
+
height: count(dimensions.height) || count(resolution?.[2]),
|
|
111
|
+
duration: count(info.duration_millis) / 1000,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return media;
|
|
115
|
+
}
|
|
116
|
+
export function normalizeXPost(raw, targetId, depth = 0) {
|
|
117
|
+
const wrapper = record(raw);
|
|
118
|
+
const tw = record(wrapper.tweet ?? wrapper);
|
|
119
|
+
const legacy = record(tw.legacy);
|
|
120
|
+
if (tw.rest_id !== targetId ||
|
|
121
|
+
!/^\d{1,22}$/.test(targetId) ||
|
|
122
|
+
tw.__typename === "TweetUnavailable")
|
|
123
|
+
return null;
|
|
124
|
+
const user = record(record(record(tw.core).user_results).result);
|
|
125
|
+
const userLegacy = record(user.legacy);
|
|
126
|
+
if (userLegacy.protected === true || record(user.privacy).protected === true)
|
|
127
|
+
return null;
|
|
128
|
+
const username = text(userLegacy.screen_name) || text(record(user.core).screen_name);
|
|
129
|
+
if (!/^[a-zA-Z0-9_]{1,50}$/.test(username))
|
|
130
|
+
return null;
|
|
131
|
+
const note = record(record(record(tw.note_tweet).note_tweet_results).result);
|
|
132
|
+
const body = text(note.text) || text(legacy.full_text);
|
|
133
|
+
if (!body || body.length > 100_000)
|
|
134
|
+
return null;
|
|
135
|
+
const date = new Date(text(legacy.created_at));
|
|
136
|
+
if (!Number.isFinite(date.getTime()))
|
|
137
|
+
return null;
|
|
138
|
+
const entities = record(note.entity_set ?? legacy.entities);
|
|
139
|
+
const avatar = text(userLegacy.profile_image_url_https) || text(record(user.avatar).image_url);
|
|
140
|
+
const media = normalizeMedia(legacy, targetId);
|
|
141
|
+
const quote = record(record(tw.quoted_status_result).result);
|
|
142
|
+
const quoteId = text(record(quote.tweet ?? quote).rest_id);
|
|
143
|
+
const quoted = depth === 0 && quoteId ? normalizeXPost(quote, quoteId, 1)?.tweet : undefined;
|
|
144
|
+
// The task is bound to the focal post; quote text is useful context but its media is not this post's media.
|
|
145
|
+
if (quoted)
|
|
146
|
+
quoted.media = [];
|
|
147
|
+
const tweet = {
|
|
148
|
+
id: targetId,
|
|
149
|
+
text: body,
|
|
150
|
+
url: `https://x.com/${username}/status/${targetId}`,
|
|
151
|
+
created_at: date.toISOString(),
|
|
152
|
+
lang: text(legacy.lang).slice(0, 20),
|
|
153
|
+
author: {
|
|
154
|
+
id: text(user.rest_id),
|
|
155
|
+
username,
|
|
156
|
+
name: (text(userLegacy.name) || text(record(user.core).name)).slice(0, 200),
|
|
157
|
+
profile_image_url: /^https:\/\/pbs\.twimg\.com\/profile_images\/[A-Za-z0-9_/.-]+$/.test(avatar)
|
|
158
|
+
? avatar
|
|
159
|
+
: "",
|
|
160
|
+
followers_count: count(userLegacy.followers_count),
|
|
161
|
+
is_verified: user.is_blue_verified === true || userLegacy.verified === true,
|
|
162
|
+
},
|
|
163
|
+
metrics: {
|
|
164
|
+
retweet_count: count(legacy.retweet_count),
|
|
165
|
+
like_count: count(legacy.favorite_count),
|
|
166
|
+
reply_count: count(legacy.reply_count),
|
|
167
|
+
quote_count: count(legacy.quote_count),
|
|
168
|
+
view_count: count(record(tw.views).count),
|
|
169
|
+
bookmark_count: count(legacy.bookmark_count),
|
|
170
|
+
},
|
|
171
|
+
entities: {
|
|
172
|
+
hashtags: items(entities.hashtags)
|
|
173
|
+
.map((e) => text(e.text))
|
|
174
|
+
.filter(Boolean),
|
|
175
|
+
mentioned_users: items(entities.user_mentions)
|
|
176
|
+
.map((e) => text(e.screen_name))
|
|
177
|
+
.filter(Boolean),
|
|
178
|
+
urls: items(entities.urls)
|
|
179
|
+
.map((e) => text(e.expanded_url))
|
|
180
|
+
.filter((url) => /^https?:\/\//.test(url)),
|
|
181
|
+
},
|
|
182
|
+
is_retweet: Boolean(legacy.retweeted_status_id_str),
|
|
183
|
+
is_quote: Boolean(quoteId),
|
|
184
|
+
is_reply: Boolean(legacy.in_reply_to_status_id_str),
|
|
185
|
+
reply_to_id: text(legacy.in_reply_to_status_id_str) || undefined,
|
|
186
|
+
media,
|
|
187
|
+
quoted_tweet: quoted,
|
|
188
|
+
};
|
|
189
|
+
return { tweet, media };
|
|
190
|
+
}
|
|
191
|
+
export function collectTweetEntities(payload) {
|
|
192
|
+
const found = new Map();
|
|
193
|
+
const stack = [payload];
|
|
194
|
+
const seen = new Set();
|
|
195
|
+
while (stack.length && seen.size < 50_000) {
|
|
196
|
+
const value = stack.pop();
|
|
197
|
+
if (!value || typeof value !== "object" || seen.has(value))
|
|
198
|
+
continue;
|
|
199
|
+
seen.add(value);
|
|
200
|
+
const obj = record(value);
|
|
201
|
+
if (typeof obj.rest_id === "string" &&
|
|
202
|
+
typeof record(obj.legacy).full_text === "string" &&
|
|
203
|
+
obj.core)
|
|
204
|
+
found.set(obj.rest_id, obj);
|
|
205
|
+
const children = Array.isArray(value) ? value : Object.values(obj);
|
|
206
|
+
for (const child of children.slice(0, 50_000 - seen.size)) {
|
|
207
|
+
if (child && typeof child === "object")
|
|
208
|
+
stack.push(child);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return found;
|
|
212
|
+
}
|
|
213
|
+
export const MAX_VIDEO_BYTES = 64 * 1024 * 1024;
|
|
214
|
+
export const MAX_IMAGE_BYTES = 10 * 1024 * 1024;
|
|
215
|
+
export function verifySignature(bytes, mime) {
|
|
216
|
+
const text = new TextDecoder("ascii");
|
|
217
|
+
if (mime === "video/mp4" && bytes.length >= 24) {
|
|
218
|
+
const size = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0);
|
|
219
|
+
if (size >= 16 &&
|
|
220
|
+
size <= 4096 &&
|
|
221
|
+
text.decode(bytes.slice(4, 8)) === "ftyp" &&
|
|
222
|
+
/^(isom|iso[2-9]|mp4[12]|avc1|M4V |MSNV|dash)$/.test(text.decode(bytes.slice(8, 12))))
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (mime === "image/jpeg" && bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255)
|
|
226
|
+
return;
|
|
227
|
+
if (mime === "image/png" &&
|
|
228
|
+
bytes.length >= 24 &&
|
|
229
|
+
[137, 80, 78, 71, 13, 10, 26, 10].every((b, i) => bytes[i] === b))
|
|
230
|
+
return;
|
|
231
|
+
if (mime === "image/webp" &&
|
|
232
|
+
text.decode(bytes.slice(0, 4)) === "RIFF" &&
|
|
233
|
+
text.decode(bytes.slice(8, 12)) === "WEBP")
|
|
234
|
+
return;
|
|
235
|
+
throw new ConnectorError("invalid_media", 415);
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/connector/core.ts"],"names":[],"mappings":"AA+CA,MAAM,OAAO,cAAe,SAAQ,KAAK;IAE9B,IAAI;IACJ,MAAM;IAFf,YACS,IAAY,EACZ,MAAM,GAAG,CAAC;QAEjB,KAAK,CAAC,IAAI,CAAC,CAAC;oBAHL,IAAI;sBACJ,MAAM;QAGb,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,MAAM,IAAI,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAClF,MAAM,KAAK,GAAG,CAAC,KAAc,EAAU,EAAE;IACvC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,OAAO,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC;AACF,MAAM,KAAK,GAAG,CAAC,KAAc,EAA6B,EAAE,CAC1D,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAE9D,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,KAAK,GACT,uFAAuF,CAAC,IAAI,CAC1F,GAAG,CAAC,QAAQ,CACb,CAAC;QACJ,IACE,GAAG,CAAC,QAAQ,KAAK,QAAQ;YACzB,GAAG,CAAC,IAAI;YACR,GAAG,CAAC,QAAQ;YACZ,GAAG,CAAC,QAAQ;YACZ,CAAC;gBACC,OAAO;gBACP,WAAW;gBACX,cAAc;gBACd,aAAa;gBACb,iBAAiB;gBACjB,oBAAoB;aACrB,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC;YACxB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAEX,OAAO,IAAI,CAAC;QACd,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,0BAA0B,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,QAAQ,CACtB,GAAW,EACX,OAAe,EACf,IAAkC;IAElC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACzB,IACE,GAAG,CAAC,QAAQ,KAAK,QAAQ;YACzB,GAAG,CAAC,IAAI;YACR,GAAG,CAAC,QAAQ;YACZ,GAAG,CAAC,QAAQ;YACZ,GAAG,CAAC,IAAI;YACR,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;YAE3B,OAAO,IAAI,CAAC;QACd,MAAM,IAAI,GACR,IAAI,KAAK,OAAO;YACd,CAAC,CAAC,uDAAuD;YACzD,CAAC,CAAC,IAAI,KAAK,QAAQ;gBACjB,CAAC,CAAC,IAAI,MAAM,CACR,mDAAmD,OAAO,8EAA8E,CACzI;gBACH,CAAC,CAAC,IAAI,MAAM,CACR,uCAAuC,OAAO,yEAAyE,CACxH,CAAC;QACV,MAAM,SAAS,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAClE,IACE,GAAG,CAAC,QAAQ,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,eAAe,CAAC;YACzE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YACxB,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAEpE,OAAO,IAAI,CAAC;QACd,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,MAA+B,EAAE,MAAc;IACrE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC7E,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,GAAG,CAAC,oBAAoB,IAAI,GAAG,CAAC,oBAAoB,KAAK,MAAM;YAAE,SAAS;QAC9E,IAAI,GAAG,CAAC,sBAAsB,IAAI,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,MAAM,KAAK,WAAW;YACzF,SAAS;QACX,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC7C,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YAC7D,IAAI,GAAG;gBACL,KAAK,CAAC,IAAI,CAAC;oBACT,EAAE;oBACF,IAAI,EAAE,OAAO;oBACb,GAAG;oBACH,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC;oBAC9B,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;iBACjC,CAAC,CAAC;YACL,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc;YAAE,SAAS;QAClE,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;aAClC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,WAAW,CAAC;aAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClF,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QACjE,KAAK,CAAC,IAAI,CAAC;YACT,EAAE;YACF,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;YAC5C,GAAG;YACH,aAAa,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,IAAI,SAAS;YAC7E,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;YACxD,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1D,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,IAAI;SAC7C,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,QAAgB,EAAE,KAAK,GAAG,CAAC;IACtE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IACjC,IACE,EAAE,CAAC,OAAO,KAAK,QAAQ;QACvB,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC5B,EAAE,CAAC,UAAU,KAAK,kBAAkB;QAEpC,OAAO,IAAI,CAAC;IACd,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,UAAU,CAAC,SAAS,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC1F,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC;IACrF,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO;QAAE,OAAO,IAAI,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,uBAAuB,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC;IAC/F,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7F,4GAA4G;IAC5G,IAAI,MAAM;QAAE,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAU;QACnB,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,IAAI;QACV,GAAG,EAAE,iBAAiB,QAAQ,WAAW,QAAQ,EAAE;QACnD,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE;QAC9B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,EAAE;YACN,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;YACtB,QAAQ;YACR,IAAI,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;YAC3E,iBAAiB,EAAE,+DAA+D,CAAC,IAAI,CACrF,MAAM,CACP;gBACC,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,EAAE;YACN,eAAe,EAAE,KAAK,CAAC,UAAU,CAAC,eAAe,CAAC;YAClD,WAAW,EAAE,IAAI,CAAC,gBAAgB,KAAK,IAAI,IAAI,UAAU,CAAC,QAAQ,KAAK,IAAI;SAC5E;QACD,OAAO,EAAE;YACP,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC;YAC1C,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC;YACxC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;YACtC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;YACtC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;YACzC,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC;SAC7C;QACD,QAAQ,EAAE;YACR,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;iBAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;iBACxB,MAAM,CAAC,OAAO,CAAC;YAClB,eAAe,EAAE,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC;iBAC3C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;iBAC/B,MAAM,CAAC,OAAO,CAAC;YAClB,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;iBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;iBAChC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAC7C;QACD,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAAC;QACnD,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC;QAC1B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,yBAAyB,CAAC;QACnD,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,yBAAyB,CAAC,IAAI,SAAS;QAChE,KAAK;QACL,YAAY,EAAE,MAAM;KACrB,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;IACzC,MAAM,KAAK,GAAc,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,GAAG,MAAM,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QACrE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,IACE,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;YAC/B,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,QAAQ;YAChD,GAAG,CAAC,IAAI;YAER,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACnE,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1D,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAChD,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhD,MAAM,UAAU,eAAe,CAAC,KAAiB,EAAE,IAAY;IAC7D,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACzF,IACE,IAAI,IAAI,EAAE;YACV,IAAI,IAAI,IAAI;YACZ,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM;YACzC,+CAA+C,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAErF,OAAO;IACX,CAAC;IACD,IAAI,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO;IAC9F,IACE,IAAI,KAAK,WAAW;QACpB,KAAK,CAAC,MAAM,IAAI,EAAE;QAClB,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAEjE,OAAO;IACT,IACE,IAAI,KAAK,YAAY;QACrB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,MAAM;QACzC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM;QAE1C,OAAO;IACT,MAAM,IAAI,cAAc,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dns.d.ts","sourceRoot":"","sources":["../../src/connector/dns.ts"],"names":[],"mappings":"AAEA,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,WA0B9C;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,GAAE,OAAO,KAAa,iBAsC9B"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ConnectorError } from "./core.js";
|
|
2
|
+
export function isPublicAddress(address) {
|
|
3
|
+
if (address.includes(":")) {
|
|
4
|
+
// Accept global IPv6 unicast only; exclude documentation and transition ranges.
|
|
5
|
+
if (!/^[23][a-f0-9]{3}:/i.test(address) || /^200[12]:/i.test(address))
|
|
6
|
+
return false;
|
|
7
|
+
try {
|
|
8
|
+
return new URL(`https://[${address}]/`).hostname.startsWith("[");
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
if (!/^\d{1,3}(\.\d{1,3}){3}$/.test(address))
|
|
15
|
+
return false;
|
|
16
|
+
const octets = address.split(".").map(Number);
|
|
17
|
+
if (octets.some((n) => n > 255))
|
|
18
|
+
return false;
|
|
19
|
+
const [a, b, c] = octets;
|
|
20
|
+
return !(a === 0 ||
|
|
21
|
+
a === 10 ||
|
|
22
|
+
a === 127 ||
|
|
23
|
+
a >= 224 ||
|
|
24
|
+
(a === 169 && b === 254) ||
|
|
25
|
+
(a === 172 && b >= 16 && b <= 31) ||
|
|
26
|
+
(a === 192 && [0, 168].includes(b)) ||
|
|
27
|
+
(a === 100 && b >= 64 && b <= 127) ||
|
|
28
|
+
(a === 198 && ([18, 19].includes(b) || (b === 51 && c === 100))) ||
|
|
29
|
+
(a === 203 && b === 0 && c === 113));
|
|
30
|
+
}
|
|
31
|
+
export async function assertPublicMediaDns(host, signal, fetcher = fetch) {
|
|
32
|
+
if (!["video.twimg.com", "pbs.twimg.com"].includes(host))
|
|
33
|
+
throw new ConnectorError("unsafe_media_address");
|
|
34
|
+
const bounded = AbortSignal.any([AbortSignal.timeout(10_000), ...(signal ? [signal] : [])]);
|
|
35
|
+
let count = 0;
|
|
36
|
+
// The proxy may supply fake local DNS. Check the fixed CDN's public DNS over authenticated HTTPS.
|
|
37
|
+
// This is a preflight, not general-purpose DNS pinning; arbitrary/user-controlled hosts stay forbidden.
|
|
38
|
+
for (const type of ["A", "AAAA"]) {
|
|
39
|
+
let records;
|
|
40
|
+
try {
|
|
41
|
+
const response = await fetcher(`https://cloudflare-dns.com/dns-query?name=${host}&type=${type}`, {
|
|
42
|
+
headers: { Accept: "application/dns-json" },
|
|
43
|
+
redirect: "manual",
|
|
44
|
+
signal: bounded,
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok || !response.headers.get("content-type")?.includes("json")) {
|
|
47
|
+
await response.body?.cancel();
|
|
48
|
+
throw new Error();
|
|
49
|
+
}
|
|
50
|
+
records = JSON.parse(new TextDecoder().decode(await readBytes(response, 16_384)));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
throw new ConnectorError("media_dns_unavailable");
|
|
54
|
+
}
|
|
55
|
+
if (!records || typeof records !== "object" || !("Status" in records) || records.Status !== 0)
|
|
56
|
+
throw new ConnectorError("media_dns_unavailable");
|
|
57
|
+
const answers = "Answer" in records && Array.isArray(records.Answer) ? records.Answer : [];
|
|
58
|
+
for (const answer of answers) {
|
|
59
|
+
if (![1, 28].includes(answer.type))
|
|
60
|
+
continue;
|
|
61
|
+
if (typeof answer.data !== "string" || !isPublicAddress(answer.data))
|
|
62
|
+
throw new ConnectorError("unsafe_media_address");
|
|
63
|
+
count++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (!count)
|
|
67
|
+
throw new ConnectorError("media_dns_unavailable");
|
|
68
|
+
}
|
|
69
|
+
async function readBytes(response, limit) {
|
|
70
|
+
if (!response.body)
|
|
71
|
+
throw new ConnectorError("media_dns_unavailable");
|
|
72
|
+
const reader = response.body.getReader();
|
|
73
|
+
const parts = [];
|
|
74
|
+
let size = 0;
|
|
75
|
+
try {
|
|
76
|
+
for (;;) {
|
|
77
|
+
const { value, done } = await reader.read();
|
|
78
|
+
if (done)
|
|
79
|
+
break;
|
|
80
|
+
size += value.length;
|
|
81
|
+
if (size > limit)
|
|
82
|
+
throw new ConnectorError("media_dns_unavailable");
|
|
83
|
+
parts.push(value);
|
|
84
|
+
}
|
|
85
|
+
return Buffer.concat(parts);
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
await reader.cancel().catch(() => { });
|
|
89
|
+
reader.releaseLock();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=dns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dns.js","sourceRoot":"","sources":["../../src/connector/dns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type XMedia } from "./core.js";
|
|
2
|
+
import type { DownloadedMedia } from "./types.js";
|
|
3
|
+
export declare function downloadMedia(media: XMedia, directory: string, signal?: AbortSignal): Promise<DownloadedMedia>;
|
|
4
|
+
export declare function makePoster(video: string, signal?: AbortSignal): Promise<DownloadedMedia | null>;
|
|
5
|
+
//# sourceMappingURL=download.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/connector/download.ts"],"names":[],"mappings":"AAMA,OAAO,EAOL,KAAK,MAAM,EACZ,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAyClD,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,eAAe,CAAC,CA0G1B;AAED,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAkCjC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
+
import { createReadStream } from "node:fs";
|
|
4
|
+
import { mkdir, open, rename, rm, stat } from "node:fs/promises";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { ConnectorError, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, mediaUrl, record, verifySignature, } from "./core.js";
|
|
8
|
+
import { assertPublicMediaDns } from "./dns.js";
|
|
9
|
+
const execute = promisify(execFile);
|
|
10
|
+
async function mediaResponse(media, signal) {
|
|
11
|
+
const video = media.type !== "PHOTO";
|
|
12
|
+
const kind = video ? "video" : "photo";
|
|
13
|
+
const initialUrl = mediaUrl(media.url, media.id, kind);
|
|
14
|
+
if (!initialUrl)
|
|
15
|
+
throw new ConnectorError("invalid_media");
|
|
16
|
+
let url = initialUrl;
|
|
17
|
+
for (let redirects = 0; redirects <= 2; redirects++) {
|
|
18
|
+
await assertPublicMediaDns(new URL(url).hostname, signal);
|
|
19
|
+
const response = await fetch(url, { redirect: "manual", signal });
|
|
20
|
+
if ([301, 302, 303, 307, 308].includes(response.status)) {
|
|
21
|
+
await response.body?.cancel();
|
|
22
|
+
const location = response.headers.get("location");
|
|
23
|
+
const next = location ? mediaUrl(new URL(location, url).href, media.id, kind) : null;
|
|
24
|
+
if (!next || redirects === 2)
|
|
25
|
+
throw new ConnectorError("unsafe_redirect");
|
|
26
|
+
url = next;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const mime = response.headers.get("content-type")?.split(";")[0]?.trim() ?? "";
|
|
30
|
+
const declared = response.headers.get("content-length") ?? "";
|
|
31
|
+
const size = Number(declared);
|
|
32
|
+
if (response.status !== 200 ||
|
|
33
|
+
!response.body ||
|
|
34
|
+
!/^\d+$/.test(declared) ||
|
|
35
|
+
!Number.isSafeInteger(size) ||
|
|
36
|
+
size < (video ? 24 : 3) ||
|
|
37
|
+
size > (video ? MAX_VIDEO_BYTES : MAX_IMAGE_BYTES) ||
|
|
38
|
+
!(video ? ["video/mp4"] : ["image/jpeg", "image/png", "image/webp"]).includes(mime)) {
|
|
39
|
+
await response.body?.cancel();
|
|
40
|
+
throw new ConnectorError("invalid_media");
|
|
41
|
+
}
|
|
42
|
+
return { body: response.body, size, mime };
|
|
43
|
+
}
|
|
44
|
+
throw new ConnectorError("unsafe_redirect");
|
|
45
|
+
}
|
|
46
|
+
export async function downloadMedia(media, directory, signal) {
|
|
47
|
+
const video = media.type !== "PHOTO";
|
|
48
|
+
const bounded = AbortSignal.any([AbortSignal.timeout(120_000), ...(signal ? [signal] : [])]);
|
|
49
|
+
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
50
|
+
const path = join(directory, randomUUID());
|
|
51
|
+
const partial = `${path}.partial`;
|
|
52
|
+
let file;
|
|
53
|
+
try {
|
|
54
|
+
const { body, size, mime } = await mediaResponse(media, bounded);
|
|
55
|
+
file = await open(partial, "wx", 0o600);
|
|
56
|
+
const reader = body.getReader();
|
|
57
|
+
const hash = createHash("sha256");
|
|
58
|
+
let received = 0;
|
|
59
|
+
let head = new Uint8Array();
|
|
60
|
+
try {
|
|
61
|
+
for (;;) {
|
|
62
|
+
bounded.throwIfAborted();
|
|
63
|
+
const { value, done } = await reader.read();
|
|
64
|
+
if (done)
|
|
65
|
+
break;
|
|
66
|
+
received += value.length;
|
|
67
|
+
if (received > size)
|
|
68
|
+
throw new ConnectorError("size_mismatch");
|
|
69
|
+
if (head.length < 32) {
|
|
70
|
+
const next = new Uint8Array(Math.min(32, head.length + value.length));
|
|
71
|
+
next.set(head);
|
|
72
|
+
next.set(value.subarray(0, next.length - head.length), head.length);
|
|
73
|
+
head = next;
|
|
74
|
+
}
|
|
75
|
+
hash.update(value);
|
|
76
|
+
await file.writeFile(value);
|
|
77
|
+
}
|
|
78
|
+
if (received !== size)
|
|
79
|
+
throw new ConnectorError("size_mismatch");
|
|
80
|
+
verifySignature(head, mime);
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
await reader.cancel().catch(() => { });
|
|
84
|
+
reader.releaseLock();
|
|
85
|
+
}
|
|
86
|
+
await file.close();
|
|
87
|
+
file = undefined;
|
|
88
|
+
let probe;
|
|
89
|
+
try {
|
|
90
|
+
const output = await execute("ffprobe", [
|
|
91
|
+
"-v",
|
|
92
|
+
"error",
|
|
93
|
+
"-show_entries",
|
|
94
|
+
"format=duration:stream=codec_type,codec_name,width,height",
|
|
95
|
+
"-of",
|
|
96
|
+
"json",
|
|
97
|
+
partial,
|
|
98
|
+
], { timeout: 120_000, maxBuffer: 1_048_576, signal: bounded });
|
|
99
|
+
probe = record(JSON.parse(output.stdout));
|
|
100
|
+
await execute("ffmpeg", [
|
|
101
|
+
"-nostdin",
|
|
102
|
+
"-hide_banner",
|
|
103
|
+
"-v",
|
|
104
|
+
"error",
|
|
105
|
+
"-xerror",
|
|
106
|
+
"-i",
|
|
107
|
+
partial,
|
|
108
|
+
"-map",
|
|
109
|
+
"0:v:0",
|
|
110
|
+
"-map",
|
|
111
|
+
"0:a?",
|
|
112
|
+
"-f",
|
|
113
|
+
"null",
|
|
114
|
+
"-",
|
|
115
|
+
], { timeout: 120_000, maxBuffer: 1_048_576, signal: bounded });
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
throw new ConnectorError("decode_failed");
|
|
119
|
+
}
|
|
120
|
+
const streams = Array.isArray(probe.streams) ? probe.streams.map(record) : [];
|
|
121
|
+
const frame = streams.find((s) => s.codec_type === "video");
|
|
122
|
+
const duration = Number(record(probe.format).duration);
|
|
123
|
+
if (!frame ||
|
|
124
|
+
!Number.isFinite(Number(frame.width)) ||
|
|
125
|
+
!Number.isFinite(Number(frame.height)) ||
|
|
126
|
+
Number(frame.width) <= 0 ||
|
|
127
|
+
Number(frame.height) <= 0 ||
|
|
128
|
+
(video && (!Number.isFinite(duration) || duration <= 0)))
|
|
129
|
+
throw new ConnectorError("decode_failed");
|
|
130
|
+
await rename(partial, path);
|
|
131
|
+
return {
|
|
132
|
+
path,
|
|
133
|
+
size,
|
|
134
|
+
mime,
|
|
135
|
+
sha256: hash.digest("hex"),
|
|
136
|
+
width: Number(frame.width),
|
|
137
|
+
height: Number(frame.height),
|
|
138
|
+
duration: video ? duration : undefined,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
await file?.close().catch(() => { });
|
|
143
|
+
await Promise.all([rm(partial, { force: true }), rm(path, { force: true })]);
|
|
144
|
+
throw error instanceof ConnectorError
|
|
145
|
+
? error
|
|
146
|
+
: new ConnectorError(signal?.aborted ? "interrupted" : "download_failed");
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export async function makePoster(video, signal) {
|
|
150
|
+
const path = `${video}.jpg`;
|
|
151
|
+
try {
|
|
152
|
+
await execute("ffmpeg", [
|
|
153
|
+
"-nostdin",
|
|
154
|
+
"-hide_banner",
|
|
155
|
+
"-v",
|
|
156
|
+
"error",
|
|
157
|
+
"-y",
|
|
158
|
+
"-ss",
|
|
159
|
+
"0",
|
|
160
|
+
"-i",
|
|
161
|
+
video,
|
|
162
|
+
"-frames:v",
|
|
163
|
+
"1",
|
|
164
|
+
"-vf",
|
|
165
|
+
"scale=640:-2",
|
|
166
|
+
"-q:v",
|
|
167
|
+
"3",
|
|
168
|
+
path,
|
|
169
|
+
], { timeout: 30_000, maxBuffer: 1_048_576, signal });
|
|
170
|
+
const { size } = await stat(path);
|
|
171
|
+
if (size < 3 || size > MAX_IMAGE_BYTES)
|
|
172
|
+
throw new ConnectorError("invalid_media");
|
|
173
|
+
const hash = createHash("sha256");
|
|
174
|
+
for await (const bytes of createReadStream(path))
|
|
175
|
+
hash.update(bytes);
|
|
176
|
+
return { path, size, mime: "image/jpeg", sha256: hash.digest("hex") };
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
await rm(path, { force: true });
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=download.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/connector/download.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type XCapture } from "./core.js";
|
|
2
|
+
export declare function readInChild(postId: string): Promise<XCapture>;
|
|
3
|
+
/** Isolate raw browser responses and upstream logs; IPC only carries the normalized focal post. */
|
|
4
|
+
export declare function readPost(postId: string, signal?: AbortSignal): Promise<XCapture>;
|
|
5
|
+
export declare function runIsolated(postId: string): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=opencli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencli.d.ts","sourceRoot":"","sources":["../../src/connector/opencli.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,QAAQ,EACd,MAAM,WAAW,CAAC;AAgBnB,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsEnE;AAED,mGAAmG;AACnG,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkChF;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB/D"}
|