@lucasygu/redbook 0.1.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.
@@ -0,0 +1,342 @@
1
+ /**
2
+ * XHS API Client
3
+ *
4
+ * Handles all HTTP requests to edith.xiaohongshu.com and creator.xiaohongshu.com
5
+ * with proper signing, headers, and error handling.
6
+ */
7
+ import { signMainApi, USER_AGENT, buildGetUri } from "./signing.js";
8
+ import { signCreator } from "./creator-signing.js";
9
+ import { cookiesToString } from "./cookies.js";
10
+ const EDITH_HOST = "https://edith.xiaohongshu.com";
11
+ const CREATOR_HOST = "https://creator.xiaohongshu.com";
12
+ const HOME_URL = "https://www.xiaohongshu.com";
13
+ const UPLOAD_HOST = "https://ros-upload.xiaohongshu.com";
14
+ export class XhsApiError extends Error {
15
+ code;
16
+ response;
17
+ constructor(message, code, response) {
18
+ super(message);
19
+ this.code = code;
20
+ this.response = response;
21
+ this.name = "XhsApiError";
22
+ }
23
+ }
24
+ export class NeedVerifyError extends XhsApiError {
25
+ verifyType;
26
+ verifyUuid;
27
+ constructor(verifyType, verifyUuid) {
28
+ super(`Captcha required: type=${verifyType}, uuid=${verifyUuid}`);
29
+ this.verifyType = verifyType;
30
+ this.verifyUuid = verifyUuid;
31
+ this.name = "NeedVerifyError";
32
+ }
33
+ }
34
+ export class XhsClient {
35
+ cookies;
36
+ constructor(cookies) {
37
+ this.cookies = cookies;
38
+ }
39
+ baseHeaders() {
40
+ return {
41
+ "user-agent": USER_AGENT,
42
+ "content-type": "application/json",
43
+ cookie: cookiesToString(this.cookies),
44
+ origin: HOME_URL,
45
+ referer: `${HOME_URL}/`,
46
+ };
47
+ }
48
+ async mainApiGet(uri, params) {
49
+ const signHeaders = signMainApi("GET", uri, this.cookies, params);
50
+ const fullUri = buildGetUri(uri, params);
51
+ const url = `${EDITH_HOST}${fullUri}`;
52
+ const res = await fetch(url, {
53
+ method: "GET",
54
+ headers: { ...this.baseHeaders(), ...signHeaders },
55
+ });
56
+ return this.handleResponse(res);
57
+ }
58
+ async mainApiPost(uri, data) {
59
+ const signHeaders = signMainApi("POST", uri, this.cookies, undefined, data);
60
+ const url = `${EDITH_HOST}${uri}`;
61
+ const res = await fetch(url, {
62
+ method: "POST",
63
+ headers: { ...this.baseHeaders(), ...signHeaders },
64
+ body: JSON.stringify(data),
65
+ });
66
+ return this.handleResponse(res);
67
+ }
68
+ // /web_api/ endpoints → edith host; /api/galaxy/ → creator host
69
+ creatorHost(uri) {
70
+ return uri.startsWith("/api/galaxy/") ? CREATOR_HOST : EDITH_HOST;
71
+ }
72
+ async creatorGet(uri, params) {
73
+ let apiStr = `url=${uri}`;
74
+ if (params) {
75
+ const qs = Object.entries(params)
76
+ .map(([k, v]) => `${k}=${v}`)
77
+ .join("&");
78
+ apiStr = `url=${uri}?${qs}`;
79
+ }
80
+ const sign = signCreator(apiStr, null, this.cookies.a1);
81
+ const fullUri = params
82
+ ? `${uri}?${Object.entries(params).map(([k, v]) => `${k}=${v}`).join("&")}`
83
+ : uri;
84
+ const host = this.creatorHost(uri);
85
+ const res = await fetch(`${host}${fullUri}`, {
86
+ method: "GET",
87
+ headers: {
88
+ ...this.baseHeaders(),
89
+ "x-s": sign["x-s"],
90
+ "x-t": sign["x-t"],
91
+ origin: CREATOR_HOST,
92
+ referer: `${CREATOR_HOST}/`,
93
+ },
94
+ });
95
+ return this.handleResponse(res);
96
+ }
97
+ async creatorPost(uri, data) {
98
+ const sign = signCreator(`url=${uri}`, data, this.cookies.a1);
99
+ const host = this.creatorHost(uri);
100
+ const res = await fetch(`${host}${uri}`, {
101
+ method: "POST",
102
+ headers: {
103
+ ...this.baseHeaders(),
104
+ "x-s": sign["x-s"],
105
+ "x-t": sign["x-t"],
106
+ origin: CREATOR_HOST,
107
+ referer: `${CREATOR_HOST}/`,
108
+ },
109
+ body: JSON.stringify(data),
110
+ });
111
+ return this.handleResponse(res);
112
+ }
113
+ async handleResponse(res) {
114
+ if (res.status === 461 || res.status === 471) {
115
+ throw new NeedVerifyError(res.headers.get("verifytype") ?? "unknown", res.headers.get("verifyuuid") ?? "unknown");
116
+ }
117
+ const text = await res.text();
118
+ if (!text)
119
+ return null;
120
+ let data;
121
+ try {
122
+ data = JSON.parse(text);
123
+ }
124
+ catch {
125
+ throw new XhsApiError(`Non-JSON response: ${text.substring(0, 200)}`);
126
+ }
127
+ if (data.success) {
128
+ return data.data ?? data.success;
129
+ }
130
+ const code = data.code;
131
+ if (code === 300012) {
132
+ throw new XhsApiError("IP blocked by XHS", code, data);
133
+ }
134
+ if (code === 300015) {
135
+ throw new XhsApiError("Signature verification failed", code, data);
136
+ }
137
+ if (code === -100) {
138
+ throw new XhsApiError("Session expired — please re-login", code, data);
139
+ }
140
+ throw new XhsApiError(`API error: ${JSON.stringify(data).substring(0, 300)}`, code, data);
141
+ }
142
+ // ─── Reading Endpoints ──────────────────────────────────────────────────
143
+ async getSelfInfo() {
144
+ return this.mainApiGet("/api/sns/web/v2/user/me");
145
+ }
146
+ async getUserInfo(userId) {
147
+ return this.mainApiGet("/api/sns/web/v1/user/otherinfo", {
148
+ target_user_id: userId,
149
+ });
150
+ }
151
+ async getUserNotes(userId, cursor = "") {
152
+ return this.mainApiGet("/api/sns/web/v1/user_posted", {
153
+ num: 30,
154
+ cursor,
155
+ user_id: userId,
156
+ image_scenes: "FD_WM_WEBP",
157
+ });
158
+ }
159
+ async searchNotes(keyword, page = 1, pageSize = 20, sort = "general", noteType = 0) {
160
+ const searchId = generateSearchId();
161
+ return this.mainApiPost("/api/sns/web/v1/search/notes", {
162
+ keyword,
163
+ page,
164
+ page_size: pageSize,
165
+ search_id: searchId,
166
+ sort,
167
+ note_type: noteType,
168
+ });
169
+ }
170
+ async getNoteById(noteId, xsecToken, xsecSource = "pc_feed") {
171
+ return this.mainApiPost("/api/sns/web/v1/feed", {
172
+ source_note_id: noteId,
173
+ image_formats: ["jpg", "webp", "avif"],
174
+ extra: { need_body_topic: 1 },
175
+ xsec_source: xsecSource,
176
+ xsec_token: xsecToken,
177
+ });
178
+ }
179
+ async getHomeFeed(category = "homefeed_recommend") {
180
+ return this.mainApiPost("/api/sns/web/v1/homefeed", {
181
+ cursor_score: "",
182
+ num: 40,
183
+ refresh_type: 1,
184
+ note_index: 0,
185
+ unread_begin_note_id: "",
186
+ unread_end_note_id: "",
187
+ unread_note_count: 0,
188
+ category,
189
+ search_key: "",
190
+ need_num: 40,
191
+ image_scenes: ["FD_PRV_WEBP", "FD_WM_WEBP"],
192
+ });
193
+ }
194
+ async getComments(noteId, cursor = "", xsecToken = "") {
195
+ return this.mainApiGet("/api/sns/web/v2/comment/page", {
196
+ note_id: noteId,
197
+ cursor,
198
+ image_formats: "jpg,webp,avif",
199
+ xsec_token: xsecToken,
200
+ });
201
+ }
202
+ async getSubComments(noteId, rootCommentId, num = 30, cursor = "") {
203
+ return this.mainApiGet("/api/sns/web/v2/comment/sub/page", {
204
+ note_id: noteId,
205
+ root_comment_id: rootCommentId,
206
+ num,
207
+ cursor,
208
+ });
209
+ }
210
+ async postComment(noteId, content) {
211
+ return this.mainApiPost("/api/sns/web/v1/comment/post", {
212
+ note_id: noteId,
213
+ content,
214
+ at_users: [],
215
+ });
216
+ }
217
+ // ─── HTML Fallback ────────────────────────────────────────────────────
218
+ async getNoteFromHtml(noteId, xsecToken) {
219
+ const url = `${HOME_URL}/explore/${noteId}?xsec_token=${xsecToken}&xsec_source=pc_feed`;
220
+ const res = await fetch(url, {
221
+ headers: {
222
+ "user-agent": USER_AGENT,
223
+ referer: `${HOME_URL}/`,
224
+ cookie: cookiesToString(this.cookies),
225
+ },
226
+ });
227
+ const html = await res.text();
228
+ const match = html.match(/window\.__INITIAL_STATE__=({.*})<\/script>/);
229
+ if (!match) {
230
+ throw new XhsApiError("Could not parse __INITIAL_STATE__ from HTML");
231
+ }
232
+ // Replace bare `undefined` values (not inside strings) with ""
233
+ const stateStr = match[1].replace(/:\s*undefined/g, ':""').replace(/,\s*undefined/g, ',""');
234
+ const state = JSON.parse(stateStr);
235
+ const detailMap = state.note?.noteDetailMap;
236
+ if (detailMap) {
237
+ // Try exact noteId first, then fall back to first entry
238
+ const entry = detailMap[noteId] ?? Object.values(detailMap)[0];
239
+ if (entry && entry.note) {
240
+ return entry.note;
241
+ }
242
+ }
243
+ throw new XhsApiError("Note not found in HTML state");
244
+ }
245
+ // ─── Creator/Posting Endpoints ────────────────────────────────────────
246
+ async getUploadPermit(fileType, count = 1) {
247
+ const data = (await this.creatorGet("/api/media/v1/upload/web/permit", {
248
+ biz_name: "spectrum",
249
+ scene: fileType,
250
+ file_count: count,
251
+ version: 1,
252
+ source: "web",
253
+ }));
254
+ const permit = data.uploadTempPermits[0];
255
+ return { fileId: permit.fileIds[0], token: permit.token };
256
+ }
257
+ async uploadFile(fileId, token, filePath, contentType = "image/jpeg") {
258
+ const fs = await import("node:fs");
259
+ const fileData = fs.readFileSync(filePath);
260
+ const url = `${UPLOAD_HOST}/${fileId}`;
261
+ const res = await fetch(url, {
262
+ method: "PUT",
263
+ headers: {
264
+ "X-Cos-Security-Token": token,
265
+ "Content-Type": contentType,
266
+ },
267
+ body: fileData,
268
+ });
269
+ if (!res.ok) {
270
+ throw new XhsApiError(`Upload failed: ${res.status} ${res.statusText}`);
271
+ }
272
+ }
273
+ async createImageNote(title, desc, imageFileIds, options = {}) {
274
+ const images = imageFileIds.map((fileId) => ({
275
+ file_id: fileId,
276
+ metadata: { source: -1 },
277
+ }));
278
+ const businessBinds = {
279
+ version: 1,
280
+ noteId: 0,
281
+ noteOrderBind: {},
282
+ notePostTiming: { postTime: options.postTime ? new Date(options.postTime).getTime() : null },
283
+ noteCollectionBind: { id: "" },
284
+ };
285
+ const data = {
286
+ common: {
287
+ type: "normal",
288
+ title,
289
+ note_id: "",
290
+ desc,
291
+ source: '{"type":"web","ids":"","extraInfo":"{\\"subType\\":\\"official\\"}"}',
292
+ business_binds: JSON.stringify(businessBinds),
293
+ ats: options.ats ?? [],
294
+ hash_tag: options.topics ?? [],
295
+ post_loc: {},
296
+ privacy_info: { op_type: 1, type: options.isPrivate ? 1 : 0 },
297
+ },
298
+ image_info: { images },
299
+ video_info: null,
300
+ };
301
+ return this.creatorPost("/web_api/sns/v2/note", data);
302
+ }
303
+ async searchTopics(keyword) {
304
+ return this.creatorPost("/web_api/sns/v1/search/topic", {
305
+ keyword,
306
+ suggest_topic_request: { title: "", desc: "" },
307
+ page: { page_size: 20, page: 1 },
308
+ });
309
+ }
310
+ async searchUsers(keyword) {
311
+ return this.creatorPost("/web_api/sns/v1/search/user_info", {
312
+ keyword,
313
+ search_id: String(Date.now()),
314
+ page: { page_size: 20, page: 1 },
315
+ });
316
+ }
317
+ async getCreatorNoteList(tab = 0, page = 0) {
318
+ return this.creatorGet("/api/galaxy/creator/note/user/posted", {
319
+ tab,
320
+ page,
321
+ });
322
+ }
323
+ }
324
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
325
+ function generateSearchId() {
326
+ const e = BigInt(Date.now()) << 64n;
327
+ const t = BigInt(Math.floor(Math.random() * 2147483646));
328
+ return base36Encode(e + t);
329
+ }
330
+ function base36Encode(num) {
331
+ const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
332
+ if (num === 0n)
333
+ return "0";
334
+ let result = "";
335
+ let n = num;
336
+ while (n > 0n) {
337
+ result = alphabet[Number(n % 36n)] + result;
338
+ n = n / 36n;
339
+ }
340
+ return result;
341
+ }
342
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Cookie extraction module — wraps @steipete/sweet-cookie
3
+ * Same pattern as bird.fast for Chrome/Safari/Firefox cookie extraction
4
+ */
5
+ export interface XhsCookies {
6
+ a1: string;
7
+ web_session: string;
8
+ webId: string;
9
+ [key: string]: string;
10
+ }
11
+ export type CookieSource = "chrome" | "safari" | "firefox";
12
+ /**
13
+ * Extract XHS cookies from browser cookie store.
14
+ * Requires user to be logged into xiaohongshu.com in the specified browser.
15
+ */
16
+ export declare function extractCookies(source?: CookieSource): Promise<XhsCookies>;
17
+ /**
18
+ * Format cookies as a cookie header string: "a1=xxx; web_session=yyy; ..."
19
+ */
20
+ export declare function cookiesToString(cookies: XhsCookies): string;
21
+ //# sourceMappingURL=cookies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../../src/lib/cookies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE3D;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,GAAE,YAAuB,GAC9B,OAAO,CAAC,UAAU,CAAC,CAkBrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAI3D"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Cookie extraction module — wraps @steipete/sweet-cookie
3
+ * Same pattern as bird.fast for Chrome/Safari/Firefox cookie extraction
4
+ */
5
+ import { getCookies } from "@steipete/sweet-cookie";
6
+ /**
7
+ * Extract XHS cookies from browser cookie store.
8
+ * Requires user to be logged into xiaohongshu.com in the specified browser.
9
+ */
10
+ export async function extractCookies(source = "chrome") {
11
+ const result = await getCookies({
12
+ url: "https://www.xiaohongshu.com/",
13
+ browsers: [source],
14
+ });
15
+ const cookieMap = {};
16
+ for (const cookie of result.cookies) {
17
+ cookieMap[cookie.name] = cookie.value;
18
+ }
19
+ if (!cookieMap.a1) {
20
+ throw new Error(`No 'a1' cookie found for xiaohongshu.com in ${source}. Are you logged into xiaohongshu.com?`);
21
+ }
22
+ return cookieMap;
23
+ }
24
+ /**
25
+ * Format cookies as a cookie header string: "a1=xxx; web_session=yyy; ..."
26
+ */
27
+ export function cookiesToString(cookies) {
28
+ return Object.entries(cookies)
29
+ .map(([k, v]) => `${k}=${v}`)
30
+ .join("; ");
31
+ }
32
+ //# sourceMappingURL=cookies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../src/lib/cookies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAWpD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,SAAuB,QAAQ;IAE/B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;QAC9B,GAAG,EAAE,8BAA8B;QACnC,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB,CAAC,CAAC;IAEH,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,+CAA+C,MAAM,wCAAwC,CAC9F,CAAC;IACJ,CAAC;IAED,OAAO,SAAuB,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SAC3B,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;SAC5B,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Creator platform signing (XYW_ prefix)
3
+ * Used for creator.xiaohongshu.com endpoints (posting, analytics)
4
+ *
5
+ * Algorithm: MD5(api + JSON(data)) → AES-128-CBC encrypt → XYW_ prefix
6
+ * Much simpler than main API signing.
7
+ *
8
+ * Ported from: Spider_XHS/static/xhs_creator_xs.js + ReaJason/xhs help.py
9
+ */
10
+ export interface CreatorSignResult {
11
+ "x-s": string;
12
+ "x-t": string;
13
+ }
14
+ /**
15
+ * Generate creator platform signature headers.
16
+ *
17
+ * @param api - The API path, prefixed with "url=" (e.g., "url=/web_api/sns/v2/note")
18
+ * @param data - Request body data (null for GET requests)
19
+ * @param a1 - The a1 cookie value
20
+ * @returns Object with x-s and x-t headers
21
+ */
22
+ export declare function signCreator(api: string, data: Record<string, unknown> | null, a1: string): CreatorSignResult;
23
+ //# sourceMappingURL=creator-signing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"creator-signing.d.ts","sourceRoot":"","sources":["../../src/lib/creator-signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACpC,EAAE,EAAE,MAAM,GACT,iBAAiB,CA6BnB"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Creator platform signing (XYW_ prefix)
3
+ * Used for creator.xiaohongshu.com endpoints (posting, analytics)
4
+ *
5
+ * Algorithm: MD5(api + JSON(data)) → AES-128-CBC encrypt → XYW_ prefix
6
+ * Much simpler than main API signing.
7
+ *
8
+ * Ported from: Spider_XHS/static/xhs_creator_xs.js + ReaJason/xhs help.py
9
+ */
10
+ import crypto from "node:crypto";
11
+ const AES_KEY = Buffer.from("7cc4adla5ay0701v");
12
+ const AES_IV = Buffer.from("4uzjr7mbsibcaldp");
13
+ function aesEncrypt(data) {
14
+ const cipher = crypto.createCipheriv("aes-128-cbc", AES_KEY, AES_IV);
15
+ let encrypted = cipher.update(data, "utf8", "hex");
16
+ encrypted += cipher.final("hex");
17
+ return encrypted;
18
+ }
19
+ /**
20
+ * Generate creator platform signature headers.
21
+ *
22
+ * @param api - The API path, prefixed with "url=" (e.g., "url=/web_api/sns/v2/note")
23
+ * @param data - Request body data (null for GET requests)
24
+ * @param a1 - The a1 cookie value
25
+ * @returns Object with x-s and x-t headers
26
+ */
27
+ export function signCreator(api, data, a1) {
28
+ let content = api;
29
+ if (data) {
30
+ content += JSON.stringify(data);
31
+ }
32
+ const md5 = crypto.createHash("md5");
33
+ const x1 = md5.update(content).digest("hex");
34
+ const x2 = "0|0|0|1|0|0|1|0|0|0|1|0|0|0|0|1|0|0|0";
35
+ const x3 = a1;
36
+ const x4 = Date.now();
37
+ const plaintext = `x1=${x1};x2=${x2};x3=${x3};x4=${x4};`;
38
+ const payload = aesEncrypt(Buffer.from(plaintext).toString("base64"));
39
+ const envelope = {
40
+ signSvn: "56",
41
+ signType: "x2",
42
+ appId: "ugc",
43
+ signVersion: "1",
44
+ payload,
45
+ };
46
+ const xs = "XYW_" + Buffer.from(JSON.stringify(envelope)).toString("base64");
47
+ return {
48
+ "x-s": xs,
49
+ "x-t": String(x4),
50
+ };
51
+ }
52
+ //# sourceMappingURL=creator-signing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"creator-signing.js","sourceRoot":"","sources":["../../src/lib/creator-signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;AAChD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;AAE/C,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACrE,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACnD,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,SAAS,CAAC;AACnB,CAAC;AAOD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,GAAW,EACX,IAAoC,EACpC,EAAU;IAEV,IAAI,OAAO,GAAG,GAAG,CAAC;IAClB,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,EAAE,GAAG,uCAAuC,CAAC;IACnD,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEtB,MAAM,SAAS,GAAG,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC;IACzD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEtE,MAAM,QAAQ,GAAG;QACf,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,KAAK;QACZ,WAAW,EAAE,GAAG;QAChB,OAAO;KACR,CAAC;IAEF,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE7E,OAAO;QACL,KAAK,EAAE,EAAE;QACT,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;KAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Fingerprint data constants for generating realistic browser fingerprints.
3
+ * Ported from: Cloxl/xhshow data/fingerprint_data.py
4
+ */
5
+ export declare const GPU_VENDORS: string[];
6
+ export declare const SCREEN_RESOLUTIONS: {
7
+ resolutions: string[];
8
+ weights: number[];
9
+ };
10
+ export declare const FINGERPRINT_DEFAULTS: {
11
+ browserPlugins: string;
12
+ fonts: string;
13
+ };
14
+ //# sourceMappingURL=fingerprint-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint-data.d.ts","sourceRoot":"","sources":["../../src/lib/fingerprint-data.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,WAAW,UAevB,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;CAS9B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;CAKhC,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Fingerprint data constants for generating realistic browser fingerprints.
3
+ * Ported from: Cloxl/xhshow data/fingerprint_data.py
4
+ */
5
+ export const GPU_VENDORS = [
6
+ "Google Inc. (Intel)|ANGLE (Intel, Intel(R) HD Graphics 520 (0x1912) Direct3D11 vs_5_0 ps_5_0, D3D11)",
7
+ "Google Inc. (Intel)|ANGLE (Intel, Intel(R) UHD Graphics 620 (0x00003EA0) Direct3D11 vs_5_0 ps_5_0, D3D11)",
8
+ "Google Inc. (Intel)|ANGLE (Intel, Intel(R) UHD Graphics 630 (0x00003E9B) Direct3D11 vs_5_0 ps_5_0, D3D11)",
9
+ "Google Inc. (Intel)|ANGLE (Intel, Intel(R) Iris(R) Xe Graphics (0x000046A8) Direct3D11 vs_5_0 ps_5_0, D3D11)",
10
+ "Google Inc. (AMD)|ANGLE (AMD, AMD Radeon Graphics (0x00001636) Direct3D11 vs_5_0 ps_5_0, D3D11)",
11
+ "Google Inc. (AMD)|ANGLE (AMD, AMD Radeon RX 580 2048SP (0x00006FDF) Direct3D11 vs_5_0 ps_5_0, D3D11)",
12
+ "Google Inc. (AMD)|ANGLE (AMD, AMD Radeon RX 6600 XT (0x000073FF) Direct3D11 vs_5_0 ps_5_0, D3D11)",
13
+ "Google Inc. (NVIDIA)|ANGLE (NVIDIA, NVIDIA GeForce GTX 1060 6GB (0x000010DE) Direct3D11 vs_5_0 ps_5_0, D3D11)",
14
+ "Google Inc. (NVIDIA)|ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 (0x0000250F) Direct3D11 vs_5_0 ps_5_0, D3D11)",
15
+ "Google Inc. (NVIDIA)|ANGLE (NVIDIA, NVIDIA GeForce RTX 3070 (0x00002488) Direct3D11 vs_5_0 ps_5_0, D3D11)",
16
+ "Google Inc. (NVIDIA)|ANGLE (NVIDIA, NVIDIA GeForce RTX 4060 (0x00002882) Direct3D11 vs_5_0 ps_5_0, D3D11)",
17
+ "Google Inc. (NVIDIA)|ANGLE (NVIDIA, NVIDIA GeForce RTX 4070 (0x00002786) Direct3D11 vs_5_0 ps_5_0, D3D11)",
18
+ "Google Inc. (NVIDIA)|ANGLE (NVIDIA, NVIDIA GeForce RTX 4090 (0x00002684) Direct3D11 vs_5_0 ps_5_0, D3D11)",
19
+ "Google Inc. (Google)|ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero) (0x0000C0DE)), SwiftShader driver)",
20
+ ];
21
+ export const SCREEN_RESOLUTIONS = {
22
+ resolutions: [
23
+ "1366;768",
24
+ "1600;900",
25
+ "1920;1080",
26
+ "2560;1440",
27
+ "3840;2160",
28
+ ],
29
+ weights: [0.25, 0.15, 0.4, 0.15, 0.05],
30
+ };
31
+ export const FINGERPRINT_DEFAULTS = {
32
+ browserPlugins: "PDF Viewer,Chrome PDF Viewer,Chromium PDF Viewer,Microsoft Edge PDF Viewer,WebKit built-in PDF",
33
+ fonts: 'system-ui, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", -apple-system, "Segoe UI", Roboto, Ubuntu, Cantarell, "Noto Sans", sans-serif, BlinkMacSystemFont, "Helvetica Neue", Arial, "PingFang SC", "PingFang TC", "PingFang HK", "Microsoft Yahei", "Microsoft JhengHei"',
34
+ };
35
+ //# sourceMappingURL=fingerprint-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint-data.js","sourceRoot":"","sources":["../../src/lib/fingerprint-data.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,sGAAsG;IACtG,2GAA2G;IAC3G,2GAA2G;IAC3G,8GAA8G;IAC9G,iGAAiG;IACjG,sGAAsG;IACtG,mGAAmG;IACnG,+GAA+G;IAC/G,2GAA2G;IAC3G,2GAA2G;IAC3G,2GAA2G;IAC3G,2GAA2G;IAC3G,2GAA2G;IAC3G,mHAAmH;CACpH,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,WAAW,EAAE;QACX,UAAU;QACV,UAAU;QACV,WAAW;QACX,WAAW;QACX,WAAW;KACZ;IACD,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC;CACvC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,cAAc,EACZ,gGAAgG;IAClG,KAAK,EACH,2SAA2S;CAC9S,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Main API signing (XYS_ prefix) for edith.xiaohongshu.com
3
+ *
4
+ * Generates x-s, x-s-common, x-t, x-b3-traceid, x-xray-traceid headers.
5
+ *
6
+ * Algorithm overview:
7
+ * 1. MD5 hash of content string (URI + params/body)
8
+ * 2. Build 124-byte binary payload array
9
+ * 3. XOR with static 124-byte hex key
10
+ * 4. Custom Base64 encode (shuffled alphabet)
11
+ * 5. Wrap in JSON envelope → another custom Base64 → XYS_ prefix
12
+ *
13
+ * Ported from: Cloxl/xhshow (MIT license)
14
+ */
15
+ declare const USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0";
16
+ declare function extractUri(url: string): string;
17
+ declare function buildGetUri(uri: string, params?: Record<string, string | number | string[]>): string;
18
+ export interface SignHeaders {
19
+ "x-s": string;
20
+ "x-s-common": string;
21
+ "x-t": string;
22
+ "x-b3-traceid": string;
23
+ "x-xray-traceid": string;
24
+ }
25
+ /**
26
+ * Generate all signing headers for a main API (edith.xiaohongshu.com) request.
27
+ */
28
+ export declare function signMainApi(method: "GET" | "POST", uri: string, cookies: Record<string, string>, params?: Record<string, string | number | string[]>, payload?: Record<string, unknown>, timestamp?: number): SignHeaders;
29
+ export { USER_AGENT, extractUri, buildGetUri };
30
+ //# sourceMappingURL=signing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../../src/lib/signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA2DH,QAAA,MAAM,UAAU,kIACiH,CAAC;AAkdlI,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQvC;AAED,iBAAS,WAAW,CAClB,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,GAClD,MAAM,CASR;AAID,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,KAAK,GAAG,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,EACnD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,SAAS,CAAC,EAAE,MAAM,GACjB,WAAW,CA8Cb;AAED,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC"}