@ikenxuan/amagi 7.0.0-beta.1 → 7.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5094,7 +5094,7 @@ const xiaohongshuJudge = (raw, http) => {
5094
5094
  const createXiaohongshuCryptoConfig = () => new _ikenxuan_xhshow_ts.CryptoConfig().withOverrides({
5095
5095
  DATA_WEB_BUILD: "6.12.3",
5096
5096
  SIGNATURE_DATA_TEMPLATE: {
5097
- x0: "4.3.5",
5097
+ x0: "4.4.3",
5098
5098
  x1: "xhs-pc-web",
5099
5099
  x2: "Windows",
5100
5100
  x3: "",
@@ -5274,10 +5274,18 @@ const createXiaohongshuGuestCookie$1 = async (send, requestConfig) => {
5274
5274
  * 小红书签名算法。
5275
5275
  *
5276
5276
  * 包装 `@ikenxuan/xhshow-ts` 的 `Xhshow` 实例,提供 GET / POST / X-S-Common /
5277
- * X-T / X-B3-Traceid / 搜索 ID 的生成函数。a1 从 cookie 取值的逻辑用
5278
- * `contracts/cookie.ts` 的 `getCookieValue`。
5277
+ * X-T / X-B3-Traceid / X-Xray-Traceid / X-Rap-Param / 搜索 ID / 搜索 request_id
5278
+ * 的生成函数。a1 从 cookie 取值的逻辑用 `contracts/cookie.ts` 的 `getCookieValue`。
5279
5279
  *
5280
5280
  * `Xhshow` 实例是模块级单例,行为与性能无额外开销。
5281
+ *
5282
+ * 上游 2026-02 之后的新协议由这里落地:
5283
+ * - **XYW_ 格式**(`generateXSGetXyw` / `generateXSPostXyw`):数据获取类接口
5284
+ * (`user_posted`、`user/otherinfo` 等)自 2026-03 起以 HTTP 406 拒绝传统 XYS_
5285
+ * 格式,改用基于 AES-128-CBC 的 XYW_ 签名。x-s 值以 `XYW_` 开头。
5286
+ * - **x-rap-param**(`generateXRapParam`):feed / 搜索 / 发布类接口的额外校验头。
5287
+ * - **x-xray-traceid**(`generateXrayTraceid`):追踪头,随现代浏览器每次请求下发。
5288
+ * - **search request_id**(`getSearchRequestId`):搜索接口所需的 `{random}-{ts_ms}`。
5281
5289
  */
5282
5290
  /** 模块级 Xhshow 单例 */
5283
5291
  const client = new _ikenxuan_xhshow_ts.Xhshow(createXiaohongshuCryptoConfig());
@@ -5300,6 +5308,34 @@ const generateXSGet = (path, a1Cookie, clientType = "xhs-pc-web", params = {}) =
5300
5308
  */
5301
5309
  const generateXSPost = (path, a1Cookie, clientType = "xhs-pc-web", body = {}) => client.signXsPost(path, a1Cookie, clientType, body);
5302
5310
  /**
5311
+ * 生成 GET 请求的 XYW_ 格式 X-S 签名(AES-128-CBC)。
5312
+ *
5313
+ * 数据获取类接口(`user_posted` 等)自 2026-03 起以 HTTP 406 拒绝 XYS_ 格式,
5314
+ * 需改用本函数。返回值以 `XYW_` 开头,走独立于 `signXsGet` 的加密路径。
5315
+ * @param path - API 路径,如 `/api/sns/web/v1/user_posted`
5316
+ * @param a1Cookie - a1 cookie 值
5317
+ * @param clientType - 客户端类型,默认 `'xhs-pc-web'`
5318
+ * @param params - 查询参数对象
5319
+ * @returns XYW_ 格式 X-S 签名
5320
+ */
5321
+ const generateXSGetXyw = (path, a1Cookie, clientType = "xhs-pc-web", params = {}) => client.signXyw("GET", path, a1Cookie, clientType, params);
5322
+ /**
5323
+ * 生成 POST 请求的 XYW_ 格式 X-S 签名(AES-128-CBC)。
5324
+ * @param path - API 路径
5325
+ * @param a1Cookie - a1 cookie 值
5326
+ * @param clientType - 客户端类型,默认 `'xhs-pc-web'`
5327
+ * @param body - 请求体对象
5328
+ * @returns XYW_ 格式 X-S 签名
5329
+ */
5330
+ const generateXSPostXyw = (path, a1Cookie, clientType = "xhs-pc-web", body = {}) => client.signXyw("POST", path, a1Cookie, clientType, body);
5331
+ /**
5332
+ * 生成 X-Rap-Param 请求头(feed / 搜索 / 发布类接口的额外校验)。
5333
+ * @param api - 请求 API,形如 `//edith.xiaohongshu.com/api/sns/web/v1/feed`(含 host、去协议)
5334
+ * @param body - 请求体对象(GET 传空对象)
5335
+ * @returns Base64 编码的 x-rap-param 字符串
5336
+ */
5337
+ const generateXRapParam = (api, body = {}) => (0, _ikenxuan_xhshow_ts.xRapParam)(api, body);
5338
+ /**
5303
5339
  * 生成 X-S-Common 参数。
5304
5340
  * @param cookies - cookie 字符串
5305
5341
  * @returns Base64 编码的随机字符串
@@ -5316,26 +5352,40 @@ const generateXT = () => client.getXT();
5316
5352
  */
5317
5353
  const generateXB3Traceid = () => client.getB3TraceId();
5318
5354
  /**
5355
+ * 生成 X-Xray-Traceid。
5356
+ *
5357
+ * 32 位字符(16 位时间戳+序列 + 16 位随机),随现代浏览器每次请求下发。
5358
+ * @returns X-Xray-Traceid 字符串
5359
+ */
5360
+ const generateXrayTraceid = () => client.getXrayTraceId();
5361
+ /**
5319
5362
  * 生成搜索 ID。
5320
5363
  *
5321
- * 实现为 `(BigInt(Date.now()) << 64n) + BigInt(Math.floor(Math.random() * 2147483646)).toString(36)`。
5322
- * 注意:BigInt 与 string 相加,结果是十进制拼 base36 后缀而非预期的位运算结果 ——
5323
- * 这里保持该行为不变。
5364
+ * 交由上游 `client.getSearchId()`:base36 编码的 `(timestamp_ms << 64) + random`。
5365
+ * 旧的本地实现把 BigInt 与 string 相加,得到「十进制拼 base36 后缀」而非预期的
5366
+ * 位运算结果 —— 上游修正后此处直接复用,不再自行拼装。
5324
5367
  * @returns 搜索 ID 字符串
5325
5368
  */
5326
- const getSearchId = () => (BigInt(Date.now()) << 64n) + BigInt(Math.floor(Math.random() * 2147483646)).toString(36);
5369
+ const getSearchId = () => client.getSearchId();
5327
5370
  //#endregion
5328
5371
  //#region src/platforms/xiaohongshu/sign/signers.ts
5329
5372
  /**
5330
5373
  * 小红书签名器表。
5331
5374
  *
5332
- * 三个签名器:
5375
+ * XYS_(传统)路径:
5333
5376
  * - `'xhs-post'`:POST 请求,`x-s` 用 `signXsPost` 对 body 签名
5334
5377
  * - `'xhs-get'`:GET 请求,`x-s` 用 `signXsGet` 对 query 签名
5335
5378
  * - `'xhs-get-trace'`:GET + `x-b3-traceid`(userNoteList 专用)
5379
+ * - `'xhs-post-rap'`:POST + `x-rap-param`(feed / 搜索 / 发布类接口的额外校验)
5380
+ *
5381
+ * XYW_(2026-03 之后)路径 —— 数据获取类接口以 HTTP 406 拒绝 XYS_,`x-s` 改用
5382
+ * 以 `XYW_` 开头的 AES-128-CBC 签名:
5383
+ * - `'xhs-get-xyw'`:GET,`x-s` 用 `signXyw`
5384
+ * - `'xhs-post-xyw'`:POST,`x-s` 用 `signXyw`
5385
+ * - `'xhs-get-xyw-trace'`:GET XYW + `x-b3-traceid`(userNoteList 专用)
5336
5386
  *
5337
5387
  * 签名路径取自 `spec.signPath`(build 里填 `apiPath`),不是 `spec.url`:
5338
- * 小红书签名只用接口路径,与完整 URL 无关。
5388
+ * 小红书签名只用接口路径,与完整 URL 无关。x-rap-param 例外,它要 host + path。
5339
5389
  *
5340
5390
  * 签名输入:a1 取自 cookie,POST 签名含 body,GET 签名含 query。
5341
5391
  */
@@ -5343,9 +5393,26 @@ const getSearchId = () => (BigInt(Date.now()) << 64n) + BigInt(Math.floor(Math.r
5343
5393
  const a1Of = (cookie) => getCookieValue(cookie, "a1") ?? "";
5344
5394
  /** 签名路径:优先 `spec.signPath`(build 填的 apiPath),缺省取 URL 的 pathname */
5345
5395
  const apiPathOf = (spec) => spec.signPath ?? new URL(spec.url).pathname;
5346
- /** 注入 x-s / x-s-common / x-t 三个签名头 */
5396
+ /**
5397
+ * 取签名用的 query 参数:GET 端点在 `build` 里把原始 params 放进 `extra.signParams`。
5398
+ * 小红书 GET 的 x-s 必须覆盖 query(路径 + 参数),只签路径会被判非法请求返回 406。
5399
+ * 无参数端点(emojiList / userProfile)返回空对象,签名退化为只签路径,行为不变。
5400
+ */
5401
+ const signParamsOf = (spec) => spec.extra?.signParams ?? {};
5402
+ /** x-rap-param 的 api 入参:去协议、保留 `//host/path`(不含 query) */
5403
+ const rapApiOf = (spec) => {
5404
+ const url = new URL(spec.url);
5405
+ return `//${url.host}${url.pathname}`;
5406
+ };
5407
+ /**
5408
+ * 注入 x-s / x-s-common / x-t / x-xray-traceid 四个签名头。
5409
+ *
5410
+ * `x-xray-traceid` 是真实浏览器每次请求都带的追踪头(见 noteComments 的抓包);
5411
+ * 早期只发前三个,`comment/page` 这类接口会因此被判为非法请求,返回 HTTP 406。
5412
+ * 所有平台签名器共用本 helper,因此补上后对全部端点生效。
5413
+ */
5347
5414
  const signHeaders = (spec, ctx, xs) => {
5348
- const headers = new AmagiHeaders(spec.headers).set("x-s", xs).set("x-s-common", generateXSCommon(ctx.cookie)).set("x-t", String(generateXT()));
5415
+ const headers = new AmagiHeaders(spec.headers).set("x-s", xs).set("x-s-common", generateXSCommon(ctx.cookie)).set("x-t", String(generateXT())).set("x-xray-traceid", generateXrayTraceid());
5349
5416
  return {
5350
5417
  ...spec,
5351
5418
  headers: headers.toJSON()
@@ -5356,9 +5423,9 @@ const xhsPostSigner = (spec, ctx) => {
5356
5423
  const xs = generateXSPost(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", spec.body ?? {});
5357
5424
  return signHeaders(spec, ctx, xs);
5358
5425
  };
5359
- /** GET 签名器:x-s = signXsGet(apiPath, a1, 'xhs-pc-web') */
5426
+ /** GET 签名器:x-s = signXsGet(apiPath, a1, 'xhs-pc-web', signParams) */
5360
5427
  const xhsGetSigner = (spec, ctx) => {
5361
- const xs = generateXSGet(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web");
5428
+ const xs = generateXSGet(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", signParamsOf(spec));
5362
5429
  return signHeaders(spec, ctx, xs);
5363
5430
  };
5364
5431
  /** GET + x-b3-traceid(userNoteList 专用) */
@@ -5370,11 +5437,44 @@ const xhsGetTraceSigner = async (spec, ctx) => {
5370
5437
  headers: headers.toJSON()
5371
5438
  };
5372
5439
  };
5440
+ /** POST + x-rap-param(feed / 搜索 / 发布类接口的额外校验) */
5441
+ const xhsPostRapSigner = async (spec, ctx) => {
5442
+ const signed = await xhsPostSigner(spec, ctx);
5443
+ const rap = generateXRapParam(rapApiOf(spec), spec.body ?? {});
5444
+ const headers = new AmagiHeaders(signed.headers).set("x-rap-param", rap);
5445
+ return {
5446
+ ...signed,
5447
+ headers: headers.toJSON()
5448
+ };
5449
+ };
5450
+ /** XYW GET 签名器:x-s = signXyw('GET', apiPath, a1, 'xhs-pc-web', signParams),绕过数据接口 406 */
5451
+ const xhsGetXywSigner = (spec, ctx) => {
5452
+ const xs = generateXSGetXyw(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", signParamsOf(spec));
5453
+ return signHeaders(spec, ctx, xs);
5454
+ };
5455
+ /** XYW POST 签名器:x-s = signXyw('POST', apiPath, a1, 'xhs-pc-web', body) */
5456
+ const xhsPostXywSigner = (spec, ctx) => {
5457
+ const xs = generateXSPostXyw(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", spec.body ?? {});
5458
+ return signHeaders(spec, ctx, xs);
5459
+ };
5460
+ /** XYW GET + x-b3-traceid(userNoteList 专用,2026-03 之后) */
5461
+ const xhsGetXywTraceSigner = async (spec, ctx) => {
5462
+ const signed = await xhsGetXywSigner(spec, ctx);
5463
+ const headers = new AmagiHeaders(signed.headers).set("x-b3-traceid", generateXB3Traceid());
5464
+ return {
5465
+ ...signed,
5466
+ headers: headers.toJSON()
5467
+ };
5468
+ };
5373
5469
  /** 平台签名器表,交给 runtime 的 `signers` 查名 */
5374
5470
  const createXiaohongshuSigners = () => ({
5375
5471
  "xhs-post": xhsPostSigner,
5376
5472
  "xhs-get": xhsGetSigner,
5377
- "xhs-get-trace": xhsGetTraceSigner
5473
+ "xhs-get-trace": xhsGetTraceSigner,
5474
+ "xhs-post-rap": xhsPostRapSigner,
5475
+ "xhs-get-xyw": xhsGetXywSigner,
5476
+ "xhs-post-xyw": xhsPostXywSigner,
5477
+ "xhs-get-xyw-trace": xhsGetXywTraceSigner
5378
5478
  });
5379
5479
  //#endregion
5380
5480
  //#region src/runtime/events.ts
@@ -7383,7 +7483,7 @@ var DouyinAPI$1 = class {
7383
7483
  keyword: data.query,
7384
7484
  list_type: "single",
7385
7485
  need_filter_settings: "1",
7386
- offset: "0",
7486
+ offset: String(data.offset ?? 0),
7387
7487
  pc_libra_divert: "Windows",
7388
7488
  pc_search_top_1_params: "{\"enable_ai_search_top_1\":1}",
7389
7489
  query_correct_type: "1",
@@ -7411,7 +7511,7 @@ var DouyinAPI$1 = class {
7411
7511
  keyword: data.query,
7412
7512
  list_type: "single",
7413
7513
  need_filter_settings: "1",
7414
- offset: "0",
7514
+ offset: String(data.offset ?? 0),
7415
7515
  pc_libra_divert: "Windows",
7416
7516
  pc_search_top_1_params: "{\"enable_ai_search_top_1\":1}",
7417
7517
  query_correct_type: "1",
@@ -7438,7 +7538,7 @@ var DouyinAPI$1 = class {
7438
7538
  keyword: data.query,
7439
7539
  list_type: "",
7440
7540
  need_filter_settings: "1",
7441
- offset: "0",
7541
+ offset: String(data.offset ?? 0),
7442
7542
  pc_libra_divert: "Windows",
7443
7543
  pc_search_top_1_params: "{\"enable_ai_search_top_1\":1}",
7444
7544
  query_correct_type: "1",
@@ -8281,7 +8381,8 @@ const search = defineEndpoint({
8281
8381
  "video"
8282
8382
  ]).default("general").optional().describe("搜索类型,默认综合搜索"),
8283
8383
  number: zod.default.coerce.number().int().min(1).optional().describe("目标条数,默认 15"),
8284
- search_id: zod.default.string().optional().describe("翻页游标,一般不用传")
8384
+ search_id: zod.default.string().optional().describe("翻页游标,一般不用传"),
8385
+ offset: zod.default.coerce.number().int().min(0).optional().describe("翻页偏移,一般不用传")
8285
8386
  }),
8286
8387
  build: (p, ctx) => {
8287
8388
  const searchType = p.type ?? "general";
@@ -8292,7 +8393,8 @@ const search = defineEndpoint({
8292
8393
  query: p.query,
8293
8394
  type: searchType,
8294
8395
  number: p.number,
8295
- search_id: p.search_id
8396
+ search_id: p.search_id,
8397
+ offset: p.offset
8296
8398
  }),
8297
8399
  headers: withDouyinReferer(ctx, {
8298
8400
  kind: "search",
@@ -8330,9 +8432,13 @@ const search = defineEndpoint({
8330
8432
  nextParams: (params, page) => {
8331
8433
  const p = page;
8332
8434
  const nextSearchId = (typeof p.rid === "string" && p.rid.length > 0 ? p.rid : void 0) ?? (typeof p.log_pb?.impr_id === "string" ? p.log_pb.impr_id : void 0) ?? params.search_id;
8435
+ const currentOffset = params.offset ?? 0;
8436
+ const items = Array.isArray(page && page.user_list) ? page.user_list : page.data ?? [];
8437
+ const nextOffset = typeof p.cursor === "number" && p.cursor > currentOffset ? p.cursor : currentOffset + items.length;
8333
8438
  return {
8334
8439
  ...params,
8335
- search_id: nextSearchId
8440
+ search_id: nextSearchId,
8441
+ offset: nextOffset
8336
8442
  };
8337
8443
  }
8338
8444
  },
@@ -11957,8 +12063,15 @@ const SEARCH_NOTE_TYPE = {
11957
12063
  VIDEO: 1,
11958
12064
  IMAGE: 2
11959
12065
  };
11960
- /** 构建查询字符串:跳过 null / undefined,其余 URL 编码 */
11961
- const buildQueryString$2 = (params) => Object.entries(params).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join("&");
12066
+ /**
12067
+ * 构建查询字符串:跳过 null / undefined。
12068
+ *
12069
+ * **编码规则必须与 `@ikenxuan/xhshow-ts` 的签名内部编码完全一致**:只把值里的
12070
+ * `=` 转成 `%3D`,其余字符(含 `,`)原样保留。小红书对 GET 请求按「路径 + 这套
12071
+ * 编码的 query」计算 x-s,若这里用 `encodeURIComponent`(会把 `,` 转成 `%2C`),
12072
+ * 发出去的 query 与被签名的内容不一致,平台返回 HTTP 406。
12073
+ */
12074
+ const buildQueryString$2 = (params) => Object.entries(params).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${String(value).replace(/=/g, "%3D")}`).join("&");
11962
12075
  /** 首页推荐(POST) */
11963
12076
  const homeFeed$1 = (data = {}) => ({
11964
12077
  apiPath: "/api/sns/web/v1/homefeed",
@@ -11998,6 +12111,7 @@ const noteComments$1 = (data) => {
11998
12111
  const params = {
11999
12112
  note_id: data.note_id,
12000
12113
  cursor: data.cursor ?? "",
12114
+ top_comment_id: "",
12001
12115
  image_formats: [
12002
12116
  "jpg",
12003
12117
  "webp",
@@ -12007,7 +12121,8 @@ const noteComments$1 = (data) => {
12007
12121
  };
12008
12122
  return {
12009
12123
  apiPath: "/api/sns/web/v2/comment/page",
12010
- Url: `https://edith.xiaohongshu.com/api/sns/web/v2/comment/page?${buildQueryString$2(params)}`
12124
+ Url: `https://edith.xiaohongshu.com/api/sns/web/v2/comment/page?${buildQueryString$2(params)}`,
12125
+ signParams: params
12011
12126
  };
12012
12127
  };
12013
12128
  /** 用户信息(GET,请求的是 HTML 页,由 judge / decode 层处理) */
@@ -12030,7 +12145,8 @@ const userNoteList$1 = (data) => {
12030
12145
  };
12031
12146
  return {
12032
12147
  apiPath: "/api/sns/web/v1/user_posted",
12033
- Url: `https://edith.xiaohongshu.com/api/sns/web/v1/user_posted?${buildQueryString$2(params)}`
12148
+ Url: `https://edith.xiaohongshu.com/api/sns/web/v1/user_posted?${buildQueryString$2(params)}`,
12149
+ signParams: params
12034
12150
  };
12035
12151
  };
12036
12152
  /** 表情列表(GET,无参数) */
@@ -12156,7 +12272,7 @@ const homeFeed = defineEndpoint({
12156
12272
  signPath: apiPath
12157
12273
  };
12158
12274
  },
12159
- sign: "xhs-post",
12275
+ sign: "xhs-post-rap",
12160
12276
  response: type()
12161
12277
  });
12162
12278
  //#endregion
@@ -12184,14 +12300,15 @@ const noteComments = defineEndpoint({
12184
12300
  number: zod.default.coerce.number().int().min(1).max(500).optional().describe("目标条数,默认一页")
12185
12301
  }),
12186
12302
  build: (p) => {
12187
- const { Url, apiPath } = noteComments$1(p);
12303
+ const { Url, apiPath, signParams } = noteComments$1(p);
12188
12304
  return {
12189
12305
  method: "GET",
12190
12306
  url: Url,
12191
- signPath: apiPath
12307
+ signPath: apiPath,
12308
+ extra: { signParams }
12192
12309
  };
12193
12310
  },
12194
- sign: "xhs-get",
12311
+ sign: "xhs-get-trace",
12195
12312
  paginate: {
12196
12313
  maxPageSize: 50,
12197
12314
  items: (page) => page.data?.comments ?? [],
@@ -12241,7 +12358,7 @@ const noteDetail = defineEndpoint({
12241
12358
  signPath: apiPath
12242
12359
  };
12243
12360
  },
12244
- sign: "xhs-post",
12361
+ sign: "xhs-post-rap",
12245
12362
  response: type()
12246
12363
  });
12247
12364
  //#endregion
@@ -12273,16 +12390,17 @@ const searchNotes = defineEndpoint({
12273
12390
  signPath: apiPath
12274
12391
  };
12275
12392
  },
12276
- sign: "xhs-post",
12393
+ sign: "xhs-post-rap",
12277
12394
  response: type()
12278
12395
  });
12279
12396
  //#endregion
12280
12397
  //#region src/platforms/xiaohongshu/endpoints/userNoteList.ts
12281
12398
  /**
12282
- * 用户笔记列表(GET + x-b3-traceid)。
12399
+ * 用户笔记列表(GET + x-b3-traceid,XYW_ 签名)。
12283
12400
  *
12284
- * 这个端点额外带 `x-b3-traceid` 头,因此单独用一个签名器
12285
- * `'xhs-get-trace'`(GET 签名 + traceid),而不是给所有 GET 都加。
12401
+ * 这个端点额外带 `x-b3-traceid` 头,且属于数据获取类接口 —— 自 2026-03 起传统
12402
+ * XYS_ 签名会被平台以 HTTP 406 拒绝,因此用 `'xhs-get-xyw-trace'`
12403
+ * (XYW_ GET 签名 + traceid),而不是给所有 GET 都换。
12286
12404
  */
12287
12405
  const userNoteList = defineEndpoint({
12288
12406
  name: "xiaohongshu.userNoteList",
@@ -12293,18 +12411,20 @@ const userNoteList = defineEndpoint({
12293
12411
  },
12294
12412
  params: zod.default.object({
12295
12413
  user_id: zod.default.string().min(1, { error: "user_id 不能为空" }).describe("用户 ID"),
12414
+ xsec_token: zod.default.string().min(1, { error: "xsec_token 不能为空" }).describe("反爬令牌,随笔记分享链接下发"),
12296
12415
  cursor: zod.default.string().optional().describe("翻页游标;传上一页最后一条的 ID,首页不传"),
12297
12416
  num: zod.default.coerce.number().int().min(1).max(100).optional().describe("单次请求的笔记条数,默认 30")
12298
12417
  }),
12299
12418
  build: (p) => {
12300
- const { Url, apiPath } = userNoteList$1(p);
12419
+ const { Url, apiPath, signParams } = userNoteList$1(p);
12301
12420
  return {
12302
12421
  method: "GET",
12303
12422
  url: Url,
12304
- signPath: apiPath
12423
+ signPath: apiPath,
12424
+ extra: { signParams }
12305
12425
  };
12306
12426
  },
12307
- sign: "xhs-get-trace",
12427
+ sign: "xhs-get-xyw-trace",
12308
12428
  response: type()
12309
12429
  });
12310
12430
  //#endregion
@@ -14155,6 +14275,21 @@ const RESPONSE_SCHEMAS = {
14155
14275
  "success"
14156
14276
  ]
14157
14277
  },
14278
+ "xiaohongshu_noteComments": {
14279
+ "type": "object",
14280
+ "properties": {
14281
+ "code": { "type": "number" },
14282
+ "data": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Data" },
14283
+ "msg": { "type": "string" },
14284
+ "success": { "type": "boolean" }
14285
+ },
14286
+ "required": [
14287
+ "code",
14288
+ "data",
14289
+ "msg",
14290
+ "success"
14291
+ ]
14292
+ },
14158
14293
  "xiaohongshu_noteDetail": {
14159
14294
  "type": "object",
14160
14295
  "properties": {
@@ -52884,6 +53019,212 @@ const RESPONSE_SCHEMAS = {
52884
53019
  "properties": { "capa": { "$ref": "#/components/schemas/xiaohongshu_homeFeed.HomeFeed_V0.Capa" } },
52885
53020
  "required": ["capa"]
52886
53021
  },
53022
+ "xiaohongshu_noteComments.NoteComments_V0.AtUser": {
53023
+ "type": "object",
53024
+ "properties": {
53025
+ "ai_agent": { "type": "boolean" },
53026
+ "nickname": { "type": "string" },
53027
+ "user_id": { "type": "string" },
53028
+ "xsec_token": { "type": "string" }
53029
+ },
53030
+ "required": [
53031
+ "ai_agent",
53032
+ "nickname",
53033
+ "user_id",
53034
+ "xsec_token"
53035
+ ]
53036
+ },
53037
+ "xiaohongshu_noteComments.NoteComments_V0.AudioInfo": {
53038
+ "type": "object",
53039
+ "properties": {
53040
+ "asr_text": { "type": "string" },
53041
+ "audio_id": { "type": "string" },
53042
+ "duration": { "type": "number" },
53043
+ "play_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.PlayInfo" },
53044
+ "tag_text": { "type": "string" }
53045
+ },
53046
+ "required": [
53047
+ "asr_text",
53048
+ "audio_id",
53049
+ "duration",
53050
+ "play_info",
53051
+ "tag_text"
53052
+ ]
53053
+ },
53054
+ "xiaohongshu_noteComments.NoteComments_V0.Comment": {
53055
+ "type": "object",
53056
+ "properties": {
53057
+ "at_users": {
53058
+ "type": "array",
53059
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.AtUser" }
53060
+ },
53061
+ "audio_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.AudioInfo" },
53062
+ "content": { "type": "string" },
53063
+ "create_time": { "type": "number" },
53064
+ "id": { "type": "string" },
53065
+ "invalid": { "type": "boolean" },
53066
+ "ip_location": { "type": "string" },
53067
+ "like_count": { "type": "string" },
53068
+ "liked": { "type": "boolean" },
53069
+ "note_id": { "type": "string" },
53070
+ "pictures": {
53071
+ "type": "array",
53072
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Picture" }
53073
+ },
53074
+ "show_tags": {
53075
+ "type": "array",
53076
+ "items": { "type": "string" }
53077
+ },
53078
+ "status": { "type": "number" },
53079
+ "sub_comment_count": { "type": "string" },
53080
+ "sub_comment_cursor": { "type": "string" },
53081
+ "sub_comment_has_more": { "type": "boolean" },
53082
+ "sub_comments": {
53083
+ "type": "array",
53084
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.SubComment" }
53085
+ },
53086
+ "user_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.UserInfo" }
53087
+ },
53088
+ "required": [
53089
+ "at_users",
53090
+ "content",
53091
+ "create_time",
53092
+ "id",
53093
+ "invalid",
53094
+ "like_count",
53095
+ "liked",
53096
+ "note_id",
53097
+ "show_tags",
53098
+ "status",
53099
+ "sub_comment_count",
53100
+ "sub_comment_cursor",
53101
+ "sub_comment_has_more",
53102
+ "sub_comments",
53103
+ "user_info"
53104
+ ]
53105
+ },
53106
+ "xiaohongshu_noteComments.NoteComments_V0.Data": {
53107
+ "type": "object",
53108
+ "properties": {
53109
+ "comments": {
53110
+ "type": "array",
53111
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Comment" }
53112
+ },
53113
+ "cursor": { "type": "string" },
53114
+ "has_more": { "type": "boolean" },
53115
+ "time": { "type": "number" },
53116
+ "user_id": { "type": "string" },
53117
+ "xsec_token": { "type": "string" }
53118
+ },
53119
+ "required": [
53120
+ "comments",
53121
+ "cursor",
53122
+ "has_more",
53123
+ "time",
53124
+ "user_id",
53125
+ "xsec_token"
53126
+ ]
53127
+ },
53128
+ "xiaohongshu_noteComments.NoteComments_V0.InfoList": {
53129
+ "type": "object",
53130
+ "properties": {
53131
+ "image_scene": { "type": "string" },
53132
+ "url": { "type": "string" }
53133
+ },
53134
+ "required": ["image_scene", "url"]
53135
+ },
53136
+ "xiaohongshu_noteComments.NoteComments_V0.Picture": {
53137
+ "type": "object",
53138
+ "properties": {
53139
+ "height": { "type": "number" },
53140
+ "info_list": {
53141
+ "type": "array",
53142
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.InfoList" }
53143
+ },
53144
+ "url_default": { "type": "string" },
53145
+ "url_pre": { "type": "string" },
53146
+ "width": { "type": "number" }
53147
+ },
53148
+ "required": [
53149
+ "height",
53150
+ "info_list",
53151
+ "url_default",
53152
+ "url_pre",
53153
+ "width"
53154
+ ]
53155
+ },
53156
+ "xiaohongshu_noteComments.NoteComments_V0.PlayInfo": {
53157
+ "type": "object",
53158
+ "properties": { "url": { "type": "string" } },
53159
+ "required": ["url"]
53160
+ },
53161
+ "xiaohongshu_noteComments.NoteComments_V0.SubComment": {
53162
+ "type": "object",
53163
+ "properties": {
53164
+ "at_users": {
53165
+ "type": "array",
53166
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.AtUser" }
53167
+ },
53168
+ "content": { "type": "string" },
53169
+ "create_time": { "type": "number" },
53170
+ "id": { "type": "string" },
53171
+ "invalid": { "type": "boolean" },
53172
+ "ip_location": { "type": "string" },
53173
+ "like_count": { "type": "string" },
53174
+ "liked": { "type": "boolean" },
53175
+ "note_id": { "type": "string" },
53176
+ "pictures": {
53177
+ "type": "array",
53178
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Picture" }
53179
+ },
53180
+ "show_tags": {
53181
+ "type": "array",
53182
+ "items": { "type": "string" }
53183
+ },
53184
+ "status": { "type": "number" },
53185
+ "target_comment": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.TargetComment" },
53186
+ "user_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.UserInfo" }
53187
+ },
53188
+ "required": [
53189
+ "at_users",
53190
+ "content",
53191
+ "create_time",
53192
+ "id",
53193
+ "invalid",
53194
+ "like_count",
53195
+ "liked",
53196
+ "note_id",
53197
+ "show_tags",
53198
+ "status",
53199
+ "target_comment",
53200
+ "user_info"
53201
+ ]
53202
+ },
53203
+ "xiaohongshu_noteComments.NoteComments_V0.TargetComment": {
53204
+ "type": "object",
53205
+ "properties": {
53206
+ "id": { "type": "string" },
53207
+ "user_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.UserInfo" }
53208
+ },
53209
+ "required": ["id", "user_info"]
53210
+ },
53211
+ "xiaohongshu_noteComments.NoteComments_V0.UserInfo": {
53212
+ "type": "object",
53213
+ "properties": {
53214
+ "ai_agent": { "type": "boolean" },
53215
+ "image": { "type": "string" },
53216
+ "nickname": { "type": "string" },
53217
+ "user_id": { "type": "string" },
53218
+ "xsec_token": { "type": "string" }
53219
+ },
53220
+ "required": [
53221
+ "ai_agent",
53222
+ "image",
53223
+ "nickname",
53224
+ "user_id",
53225
+ "xsec_token"
53226
+ ]
53227
+ },
52887
53228
  "xiaohongshu_noteDetail.NoteDetail_V0.Data": {
52888
53229
  "type": "object",
52889
53230
  "properties": {
@@ -53679,7 +54020,7 @@ const buildOpenApiSpec = (options = {}) => {
53679
54020
  openapi: "3.1.0",
53680
54021
  info: {
53681
54022
  title: "amagi HTTP API",
53682
- version: options.version ?? "7.0.0-beta.1",
54023
+ version: options.version ?? "7.0.0-beta.2",
53683
54024
  description: [
53684
54025
  "由端点注册表派生的规范 —— 手写的那份已经漂移,这份不会(`gen-openapi --check` 进 CI)。",
53685
54026
  "",
@@ -56502,7 +56843,7 @@ let DynamicType = /* @__PURE__ */ function(DynamicType) {
56502
56843
  * 构建后使用 __VERSION__,开发环境从 package.json 读取
56503
56844
  */
56504
56845
  const getVersion = () => {
56505
- return "7.0.0-beta.1";
56846
+ return "7.0.0-beta.2";
56506
56847
  };
56507
56848
  const VERSION = getVersion();
56508
56849
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikenxuan/amagi",
3
- "version": "7.0.0-beta.1",
3
+ "version": "7.0.0-beta.2",
4
4
  "description": "抖音、B站的 web 端相关数据接口基于 Node.js 的实现",
5
5
  "keywords": [
6
6
  "api",
@@ -67,12 +67,12 @@
67
67
  "registry": "https://registry.npmjs.org"
68
68
  },
69
69
  "dependencies": {
70
- "@ikenxuan/xhshow-ts": "^1.0.6",
70
+ "@ikenxuan/xhshow-ts": "^1.1.0",
71
71
  "axios": "^1.19.0",
72
72
  "chalk": "6.0.0",
73
73
  "express": "^5.2.1",
74
74
  "protobufjs": "8.7.1",
75
75
  "zod": "4.4.3"
76
76
  },
77
- "timestamp": "2026-09-19T06:33:26.452Z"
77
+ "timestamp": "2026-09-20T16:10:24.326Z"
78
78
  }