@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.
Files changed (102) hide show
  1. package/README.md +27 -0
  2. package/dist/api/client.d.ts +18 -1
  3. package/dist/api/client.d.ts.map +1 -1
  4. package/dist/api/client.js +25 -8
  5. package/dist/api/client.js.map +1 -1
  6. package/dist/api/types.d.ts.map +1 -1
  7. package/dist/commands/connector.d.ts +2 -0
  8. package/dist/commands/connector.d.ts.map +1 -0
  9. package/dist/commands/connector.js +93 -0
  10. package/dist/commands/connector.js.map +1 -0
  11. package/dist/commands/create.d.ts.map +1 -1
  12. package/dist/commands/create.js +1 -1
  13. package/dist/commands/create.js.map +1 -1
  14. package/dist/commands/delete.js +1 -1
  15. package/dist/commands/delete.js.map +1 -1
  16. package/dist/commands/folder.d.ts.map +1 -1
  17. package/dist/commands/folder.js +1 -1
  18. package/dist/commands/folder.js.map +1 -1
  19. package/dist/commands/folders.js +1 -1
  20. package/dist/commands/folders.js.map +1 -1
  21. package/dist/commands/get.js +1 -1
  22. package/dist/commands/get.js.map +1 -1
  23. package/dist/commands/idea/add.d.ts.map +1 -1
  24. package/dist/commands/idea/add.js +1 -1
  25. package/dist/commands/idea/add.js.map +1 -1
  26. package/dist/commands/idea/delete.js +1 -1
  27. package/dist/commands/idea/delete.js.map +1 -1
  28. package/dist/commands/idea/get.d.ts.map +1 -1
  29. package/dist/commands/idea/get.js +2 -2
  30. package/dist/commands/idea/get.js.map +1 -1
  31. package/dist/commands/idea/helpers.d.ts.map +1 -1
  32. package/dist/commands/idea/helpers.js +1 -1
  33. package/dist/commands/idea/helpers.js.map +1 -1
  34. package/dist/commands/idea/list.d.ts.map +1 -1
  35. package/dist/commands/idea/list.js +2 -2
  36. package/dist/commands/idea/list.js.map +1 -1
  37. package/dist/commands/idea/update.d.ts.map +1 -1
  38. package/dist/commands/idea/update.js +1 -1
  39. package/dist/commands/idea/update.js.map +1 -1
  40. package/dist/commands/idea.js +1 -1
  41. package/dist/commands/idea.js.map +1 -1
  42. package/dist/commands/inbox.js +1 -1
  43. package/dist/commands/inbox.js.map +1 -1
  44. package/dist/commands/list.d.ts.map +1 -1
  45. package/dist/commands/list.js +3 -4
  46. package/dist/commands/list.js.map +1 -1
  47. package/dist/commands/login.d.ts.map +1 -1
  48. package/dist/commands/login.js +1 -1
  49. package/dist/commands/login.js.map +1 -1
  50. package/dist/commands/logout.js +1 -1
  51. package/dist/commands/logout.js.map +1 -1
  52. package/dist/commands/open.js +1 -1
  53. package/dist/commands/open.js.map +1 -1
  54. package/dist/commands/tag.d.ts.map +1 -1
  55. package/dist/commands/tag.js +1 -1
  56. package/dist/commands/tag.js.map +1 -1
  57. package/dist/commands/tags.js +1 -1
  58. package/dist/commands/tags.js.map +1 -1
  59. package/dist/commands/update.d.ts.map +1 -1
  60. package/dist/commands/update.js +1 -1
  61. package/dist/commands/update.js.map +1 -1
  62. package/dist/config.d.ts +1 -1
  63. package/dist/config.d.ts.map +1 -1
  64. package/dist/config.js +1 -1
  65. package/dist/config.js.map +1 -1
  66. package/dist/connector/core.d.ts +64 -0
  67. package/dist/connector/core.d.ts.map +1 -0
  68. package/dist/connector/core.js +237 -0
  69. package/dist/connector/core.js.map +1 -0
  70. package/dist/connector/dns.d.ts +3 -0
  71. package/dist/connector/dns.d.ts.map +1 -0
  72. package/dist/connector/dns.js +92 -0
  73. package/dist/connector/dns.js.map +1 -0
  74. package/dist/connector/download.d.ts +5 -0
  75. package/dist/connector/download.d.ts.map +1 -0
  76. package/dist/connector/download.js +183 -0
  77. package/dist/connector/download.js.map +1 -0
  78. package/dist/connector/opencli.d.ts +6 -0
  79. package/dist/connector/opencli.d.ts.map +1 -0
  80. package/dist/connector/opencli.js +136 -0
  81. package/dist/connector/opencli.js.map +1 -0
  82. package/dist/connector/runtime.d.ts +11 -0
  83. package/dist/connector/runtime.d.ts.map +1 -0
  84. package/dist/connector/runtime.js +117 -0
  85. package/dist/connector/runtime.js.map +1 -0
  86. package/dist/connector/types.d.ts +25 -0
  87. package/dist/connector/types.d.ts.map +1 -0
  88. package/dist/connector/types.js +2 -0
  89. package/dist/connector/types.js.map +1 -0
  90. package/dist/index.js +3 -1
  91. package/dist/index.js.map +1 -1
  92. package/dist/utils/format.d.ts.map +1 -1
  93. package/dist/utils/format.js.map +1 -1
  94. package/dist/utils/resolve.d.ts.map +1 -1
  95. package/dist/utils/resolve.js +1 -1
  96. package/dist/utils/resolve.js.map +1 -1
  97. package/dist/utils.d.ts.map +1 -1
  98. package/dist/utils.js +1 -1
  99. package/dist/utils.js.map +1 -1
  100. package/dist/version.d.ts.map +1 -1
  101. package/dist/version.js.map +1 -1
  102. 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":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function isPublicAddress(address: string): boolean;
2
+ export declare function assertPublicMediaDns(host: string, signal?: AbortSignal, fetcher?: typeof fetch): Promise<void>;
3
+ //# sourceMappingURL=dns.d.ts.map
@@ -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":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,gFAAgF;QAChF,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QACpF,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,YAAY,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACnE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC;IACzB,OAAO,CAAC,CACN,CAAC,KAAK,CAAC;QACP,CAAC,KAAK,EAAE;QACR,CAAC,KAAK,GAAG;QACT,CAAC,IAAI,GAAG;QACR,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;QACxB,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACjC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC;QAClC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAChE,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CACpC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY,EACZ,MAAoB,EACpB,OAAO,GAAiB,KAAK;IAE7B,IAAI,CAAC,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QACtD,MAAM,IAAI,cAAc,CAAC,sBAAsB,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5F,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,kGAAkG;IAClG,wGAAwG;IACxG,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;QACjC,IAAI,OAAgB,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,6CAA6C,IAAI,SAAS,IAAI,EAAE,EAChE;gBACE,OAAO,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE;gBAC3C,QAAQ,EAAE,QAAQ;gBAClB,MAAM,EAAE,OAAO;aAChB,CACF,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5E,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,EAAE,CAAC;YACpB,CAAC;YACD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QACpF,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,cAAc,CAAC,uBAAuB,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAC3F,MAAM,IAAI,cAAc,CAAC,uBAAuB,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,QAAQ,IAAI,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC7C,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC;gBAClE,MAAM,IAAI,cAAc,CAAC,sBAAsB,CAAC,CAAC;YACnD,KAAK,EAAE,CAAC;QACV,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,cAAc,CAAC,uBAAuB,CAAC,CAAC;AAChE,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,QAAkB,EAAE,KAAa;IACxD,IAAI,CAAC,QAAQ,CAAC,IAAI;QAAE,MAAM,IAAI,cAAc,CAAC,uBAAuB,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,CAAC;QACH,SAAS,CAAC;YACR,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAChB,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YACrB,IAAI,IAAI,GAAG,KAAK;gBAAE,MAAM,IAAI,cAAc,CAAC,uBAAuB,CAAC,CAAC;YACpE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -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"}