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

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.
@@ -7,7 +7,7 @@ import protobuf from "protobufjs";
7
7
  import axios, { AxiosError, AxiosHeaders, mergeConfig } from "axios";
8
8
  import { EventEmitter } from "node:events";
9
9
  import crypto, { createCipheriv, createHash, randomBytes, randomUUID } from "node:crypto";
10
- import { CryptoConfig, FingerprintGenerator, Xhshow } from "@ikenxuan/xhshow-ts";
10
+ import { CryptoConfig, FingerprintGenerator, Xhshow, xRapParam } from "@ikenxuan/xhshow-ts";
11
11
  //#region src/platforms/bilibili/api.ts
12
12
  /** B站 API URL 构建类(所有方法只拼 URL,不发起请求) */
13
13
  var BilibiliAPI$1 = class {
@@ -5088,7 +5088,7 @@ const xiaohongshuJudge = (raw, http) => {
5088
5088
  const createXiaohongshuCryptoConfig = () => new CryptoConfig().withOverrides({
5089
5089
  DATA_WEB_BUILD: "6.12.3",
5090
5090
  SIGNATURE_DATA_TEMPLATE: {
5091
- x0: "4.3.5",
5091
+ x0: "4.4.3",
5092
5092
  x1: "xhs-pc-web",
5093
5093
  x2: "Windows",
5094
5094
  x3: "",
@@ -5268,10 +5268,18 @@ const createXiaohongshuGuestCookie$1 = async (send, requestConfig) => {
5268
5268
  * 小红书签名算法。
5269
5269
  *
5270
5270
  * 包装 `@ikenxuan/xhshow-ts` 的 `Xhshow` 实例,提供 GET / POST / X-S-Common /
5271
- * X-T / X-B3-Traceid / 搜索 ID 的生成函数。a1 从 cookie 取值的逻辑用
5272
- * `contracts/cookie.ts` 的 `getCookieValue`。
5271
+ * X-T / X-B3-Traceid / X-Xray-Traceid / X-Rap-Param / 搜索 ID / 搜索 request_id
5272
+ * 的生成函数。a1 从 cookie 取值的逻辑用 `contracts/cookie.ts` 的 `getCookieValue`。
5273
5273
  *
5274
5274
  * `Xhshow` 实例是模块级单例,行为与性能无额外开销。
5275
+ *
5276
+ * 上游 2026-02 之后的新协议由这里落地:
5277
+ * - **XYW_ 格式**(`generateXSGetXyw` / `generateXSPostXyw`):数据获取类接口
5278
+ * (`user_posted`、`user/otherinfo` 等)自 2026-03 起以 HTTP 406 拒绝传统 XYS_
5279
+ * 格式,改用基于 AES-128-CBC 的 XYW_ 签名。x-s 值以 `XYW_` 开头。
5280
+ * - **x-rap-param**(`generateXRapParam`):feed / 搜索 / 发布类接口的额外校验头。
5281
+ * - **x-xray-traceid**(`generateXrayTraceid`):追踪头,随现代浏览器每次请求下发。
5282
+ * - **search request_id**(`getSearchRequestId`):搜索接口所需的 `{random}-{ts_ms}`。
5275
5283
  */
5276
5284
  /** 模块级 Xhshow 单例 */
5277
5285
  const client = new Xhshow(createXiaohongshuCryptoConfig());
@@ -5294,6 +5302,34 @@ const generateXSGet = (path, a1Cookie, clientType = "xhs-pc-web", params = {}) =
5294
5302
  */
5295
5303
  const generateXSPost = (path, a1Cookie, clientType = "xhs-pc-web", body = {}) => client.signXsPost(path, a1Cookie, clientType, body);
5296
5304
  /**
5305
+ * 生成 GET 请求的 XYW_ 格式 X-S 签名(AES-128-CBC)。
5306
+ *
5307
+ * 数据获取类接口(`user_posted` 等)自 2026-03 起以 HTTP 406 拒绝 XYS_ 格式,
5308
+ * 需改用本函数。返回值以 `XYW_` 开头,走独立于 `signXsGet` 的加密路径。
5309
+ * @param path - API 路径,如 `/api/sns/web/v1/user_posted`
5310
+ * @param a1Cookie - a1 cookie 值
5311
+ * @param clientType - 客户端类型,默认 `'xhs-pc-web'`
5312
+ * @param params - 查询参数对象
5313
+ * @returns XYW_ 格式 X-S 签名
5314
+ */
5315
+ const generateXSGetXyw = (path, a1Cookie, clientType = "xhs-pc-web", params = {}) => client.signXyw("GET", path, a1Cookie, clientType, params);
5316
+ /**
5317
+ * 生成 POST 请求的 XYW_ 格式 X-S 签名(AES-128-CBC)。
5318
+ * @param path - API 路径
5319
+ * @param a1Cookie - a1 cookie 值
5320
+ * @param clientType - 客户端类型,默认 `'xhs-pc-web'`
5321
+ * @param body - 请求体对象
5322
+ * @returns XYW_ 格式 X-S 签名
5323
+ */
5324
+ const generateXSPostXyw = (path, a1Cookie, clientType = "xhs-pc-web", body = {}) => client.signXyw("POST", path, a1Cookie, clientType, body);
5325
+ /**
5326
+ * 生成 X-Rap-Param 请求头(feed / 搜索 / 发布类接口的额外校验)。
5327
+ * @param api - 请求 API,形如 `//edith.xiaohongshu.com/api/sns/web/v1/feed`(含 host、去协议)
5328
+ * @param body - 请求体对象(GET 传空对象)
5329
+ * @returns Base64 编码的 x-rap-param 字符串
5330
+ */
5331
+ const generateXRapParam = (api, body = {}) => xRapParam(api, body);
5332
+ /**
5297
5333
  * 生成 X-S-Common 参数。
5298
5334
  * @param cookies - cookie 字符串
5299
5335
  * @returns Base64 编码的随机字符串
@@ -5310,26 +5346,40 @@ const generateXT = () => client.getXT();
5310
5346
  */
5311
5347
  const generateXB3Traceid = () => client.getB3TraceId();
5312
5348
  /**
5349
+ * 生成 X-Xray-Traceid。
5350
+ *
5351
+ * 32 位字符(16 位时间戳+序列 + 16 位随机),随现代浏览器每次请求下发。
5352
+ * @returns X-Xray-Traceid 字符串
5353
+ */
5354
+ const generateXrayTraceid = () => client.getXrayTraceId();
5355
+ /**
5313
5356
  * 生成搜索 ID。
5314
5357
  *
5315
- * 实现为 `(BigInt(Date.now()) << 64n) + BigInt(Math.floor(Math.random() * 2147483646)).toString(36)`。
5316
- * 注意:BigInt 与 string 相加,结果是十进制拼 base36 后缀而非预期的位运算结果 ——
5317
- * 这里保持该行为不变。
5358
+ * 交由上游 `client.getSearchId()`:base36 编码的 `(timestamp_ms << 64) + random`。
5359
+ * 旧的本地实现把 BigInt 与 string 相加,得到「十进制拼 base36 后缀」而非预期的
5360
+ * 位运算结果 —— 上游修正后此处直接复用,不再自行拼装。
5318
5361
  * @returns 搜索 ID 字符串
5319
5362
  */
5320
- const getSearchId = () => (BigInt(Date.now()) << 64n) + BigInt(Math.floor(Math.random() * 2147483646)).toString(36);
5363
+ const getSearchId = () => client.getSearchId();
5321
5364
  //#endregion
5322
5365
  //#region src/platforms/xiaohongshu/sign/signers.ts
5323
5366
  /**
5324
5367
  * 小红书签名器表。
5325
5368
  *
5326
- * 三个签名器:
5369
+ * XYS_(传统)路径:
5327
5370
  * - `'xhs-post'`:POST 请求,`x-s` 用 `signXsPost` 对 body 签名
5328
5371
  * - `'xhs-get'`:GET 请求,`x-s` 用 `signXsGet` 对 query 签名
5329
5372
  * - `'xhs-get-trace'`:GET + `x-b3-traceid`(userNoteList 专用)
5373
+ * - `'xhs-post-rap'`:POST + `x-rap-param`(feed / 搜索 / 发布类接口的额外校验)
5374
+ *
5375
+ * XYW_(2026-03 之后)路径 —— 数据获取类接口以 HTTP 406 拒绝 XYS_,`x-s` 改用
5376
+ * 以 `XYW_` 开头的 AES-128-CBC 签名:
5377
+ * - `'xhs-get-xyw'`:GET,`x-s` 用 `signXyw`
5378
+ * - `'xhs-post-xyw'`:POST,`x-s` 用 `signXyw`
5379
+ * - `'xhs-get-xyw-trace'`:GET XYW + `x-b3-traceid`(userNoteList 专用)
5330
5380
  *
5331
5381
  * 签名路径取自 `spec.signPath`(build 里填 `apiPath`),不是 `spec.url`:
5332
- * 小红书签名只用接口路径,与完整 URL 无关。
5382
+ * 小红书签名只用接口路径,与完整 URL 无关。x-rap-param 例外,它要 host + path。
5333
5383
  *
5334
5384
  * 签名输入:a1 取自 cookie,POST 签名含 body,GET 签名含 query。
5335
5385
  */
@@ -5337,9 +5387,26 @@ const getSearchId = () => (BigInt(Date.now()) << 64n) + BigInt(Math.floor(Math.r
5337
5387
  const a1Of = (cookie) => getCookieValue(cookie, "a1") ?? "";
5338
5388
  /** 签名路径:优先 `spec.signPath`(build 填的 apiPath),缺省取 URL 的 pathname */
5339
5389
  const apiPathOf = (spec) => spec.signPath ?? new URL(spec.url).pathname;
5340
- /** 注入 x-s / x-s-common / x-t 三个签名头 */
5390
+ /**
5391
+ * 取签名用的 query 参数:GET 端点在 `build` 里把原始 params 放进 `extra.signParams`。
5392
+ * 小红书 GET 的 x-s 必须覆盖 query(路径 + 参数),只签路径会被判非法请求返回 406。
5393
+ * 无参数端点(emojiList / userProfile)返回空对象,签名退化为只签路径,行为不变。
5394
+ */
5395
+ const signParamsOf = (spec) => spec.extra?.signParams ?? {};
5396
+ /** x-rap-param 的 api 入参:去协议、保留 `//host/path`(不含 query) */
5397
+ const rapApiOf = (spec) => {
5398
+ const url = new URL(spec.url);
5399
+ return `//${url.host}${url.pathname}`;
5400
+ };
5401
+ /**
5402
+ * 注入 x-s / x-s-common / x-t / x-xray-traceid 四个签名头。
5403
+ *
5404
+ * `x-xray-traceid` 是真实浏览器每次请求都带的追踪头(见 noteComments 的抓包);
5405
+ * 早期只发前三个,`comment/page` 这类接口会因此被判为非法请求,返回 HTTP 406。
5406
+ * 所有平台签名器共用本 helper,因此补上后对全部端点生效。
5407
+ */
5341
5408
  const signHeaders = (spec, ctx, xs) => {
5342
- const headers = new AmagiHeaders(spec.headers).set("x-s", xs).set("x-s-common", generateXSCommon(ctx.cookie)).set("x-t", String(generateXT()));
5409
+ 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());
5343
5410
  return {
5344
5411
  ...spec,
5345
5412
  headers: headers.toJSON()
@@ -5350,9 +5417,9 @@ const xhsPostSigner = (spec, ctx) => {
5350
5417
  const xs = generateXSPost(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", spec.body ?? {});
5351
5418
  return signHeaders(spec, ctx, xs);
5352
5419
  };
5353
- /** GET 签名器:x-s = signXsGet(apiPath, a1, 'xhs-pc-web') */
5420
+ /** GET 签名器:x-s = signXsGet(apiPath, a1, 'xhs-pc-web', signParams) */
5354
5421
  const xhsGetSigner = (spec, ctx) => {
5355
- const xs = generateXSGet(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web");
5422
+ const xs = generateXSGet(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", signParamsOf(spec));
5356
5423
  return signHeaders(spec, ctx, xs);
5357
5424
  };
5358
5425
  /** GET + x-b3-traceid(userNoteList 专用) */
@@ -5364,11 +5431,44 @@ const xhsGetTraceSigner = async (spec, ctx) => {
5364
5431
  headers: headers.toJSON()
5365
5432
  };
5366
5433
  };
5434
+ /** POST + x-rap-param(feed / 搜索 / 发布类接口的额外校验) */
5435
+ const xhsPostRapSigner = async (spec, ctx) => {
5436
+ const signed = await xhsPostSigner(spec, ctx);
5437
+ const rap = generateXRapParam(rapApiOf(spec), spec.body ?? {});
5438
+ const headers = new AmagiHeaders(signed.headers).set("x-rap-param", rap);
5439
+ return {
5440
+ ...signed,
5441
+ headers: headers.toJSON()
5442
+ };
5443
+ };
5444
+ /** XYW GET 签名器:x-s = signXyw('GET', apiPath, a1, 'xhs-pc-web', signParams),绕过数据接口 406 */
5445
+ const xhsGetXywSigner = (spec, ctx) => {
5446
+ const xs = generateXSGetXyw(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", signParamsOf(spec));
5447
+ return signHeaders(spec, ctx, xs);
5448
+ };
5449
+ /** XYW POST 签名器:x-s = signXyw('POST', apiPath, a1, 'xhs-pc-web', body) */
5450
+ const xhsPostXywSigner = (spec, ctx) => {
5451
+ const xs = generateXSPostXyw(apiPathOf(spec), a1Of(ctx.cookie), "xhs-pc-web", spec.body ?? {});
5452
+ return signHeaders(spec, ctx, xs);
5453
+ };
5454
+ /** XYW GET + x-b3-traceid(userNoteList 专用,2026-03 之后) */
5455
+ const xhsGetXywTraceSigner = async (spec, ctx) => {
5456
+ const signed = await xhsGetXywSigner(spec, ctx);
5457
+ const headers = new AmagiHeaders(signed.headers).set("x-b3-traceid", generateXB3Traceid());
5458
+ return {
5459
+ ...signed,
5460
+ headers: headers.toJSON()
5461
+ };
5462
+ };
5367
5463
  /** 平台签名器表,交给 runtime 的 `signers` 查名 */
5368
5464
  const createXiaohongshuSigners = () => ({
5369
5465
  "xhs-post": xhsPostSigner,
5370
5466
  "xhs-get": xhsGetSigner,
5371
- "xhs-get-trace": xhsGetTraceSigner
5467
+ "xhs-get-trace": xhsGetTraceSigner,
5468
+ "xhs-post-rap": xhsPostRapSigner,
5469
+ "xhs-get-xyw": xhsGetXywSigner,
5470
+ "xhs-post-xyw": xhsPostXywSigner,
5471
+ "xhs-get-xyw-trace": xhsGetXywTraceSigner
5372
5472
  });
5373
5473
  //#endregion
5374
5474
  //#region src/runtime/events.ts
@@ -7377,7 +7477,7 @@ var DouyinAPI$1 = class {
7377
7477
  keyword: data.query,
7378
7478
  list_type: "single",
7379
7479
  need_filter_settings: "1",
7380
- offset: "0",
7480
+ offset: String(data.offset ?? 0),
7381
7481
  pc_libra_divert: "Windows",
7382
7482
  pc_search_top_1_params: "{\"enable_ai_search_top_1\":1}",
7383
7483
  query_correct_type: "1",
@@ -7405,7 +7505,7 @@ var DouyinAPI$1 = class {
7405
7505
  keyword: data.query,
7406
7506
  list_type: "single",
7407
7507
  need_filter_settings: "1",
7408
- offset: "0",
7508
+ offset: String(data.offset ?? 0),
7409
7509
  pc_libra_divert: "Windows",
7410
7510
  pc_search_top_1_params: "{\"enable_ai_search_top_1\":1}",
7411
7511
  query_correct_type: "1",
@@ -7432,7 +7532,7 @@ var DouyinAPI$1 = class {
7432
7532
  keyword: data.query,
7433
7533
  list_type: "",
7434
7534
  need_filter_settings: "1",
7435
- offset: "0",
7535
+ offset: String(data.offset ?? 0),
7436
7536
  pc_libra_divert: "Windows",
7437
7537
  pc_search_top_1_params: "{\"enable_ai_search_top_1\":1}",
7438
7538
  query_correct_type: "1",
@@ -8275,7 +8375,8 @@ const search = defineEndpoint({
8275
8375
  "video"
8276
8376
  ]).default("general").optional().describe("搜索类型,默认综合搜索"),
8277
8377
  number: zod.coerce.number().int().min(1).optional().describe("目标条数,默认 15"),
8278
- search_id: zod.string().optional().describe("翻页游标,一般不用传")
8378
+ search_id: zod.string().optional().describe("翻页游标,一般不用传"),
8379
+ offset: zod.coerce.number().int().min(0).optional().describe("翻页偏移,一般不用传")
8279
8380
  }),
8280
8381
  build: (p, ctx) => {
8281
8382
  const searchType = p.type ?? "general";
@@ -8286,7 +8387,8 @@ const search = defineEndpoint({
8286
8387
  query: p.query,
8287
8388
  type: searchType,
8288
8389
  number: p.number,
8289
- search_id: p.search_id
8390
+ search_id: p.search_id,
8391
+ offset: p.offset
8290
8392
  }),
8291
8393
  headers: withDouyinReferer(ctx, {
8292
8394
  kind: "search",
@@ -8324,9 +8426,13 @@ const search = defineEndpoint({
8324
8426
  nextParams: (params, page) => {
8325
8427
  const p = page;
8326
8428
  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;
8429
+ const currentOffset = params.offset ?? 0;
8430
+ const items = Array.isArray(page && page.user_list) ? page.user_list : page.data ?? [];
8431
+ const nextOffset = typeof p.cursor === "number" && p.cursor > currentOffset ? p.cursor : currentOffset + items.length;
8327
8432
  return {
8328
8433
  ...params,
8329
- search_id: nextSearchId
8434
+ search_id: nextSearchId,
8435
+ offset: nextOffset
8330
8436
  };
8331
8437
  }
8332
8438
  },
@@ -11951,8 +12057,15 @@ const SEARCH_NOTE_TYPE = {
11951
12057
  VIDEO: 1,
11952
12058
  IMAGE: 2
11953
12059
  };
11954
- /** 构建查询字符串:跳过 null / undefined,其余 URL 编码 */
11955
- const buildQueryString$2 = (params) => Object.entries(params).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join("&");
12060
+ /**
12061
+ * 构建查询字符串:跳过 null / undefined。
12062
+ *
12063
+ * **编码规则必须与 `@ikenxuan/xhshow-ts` 的签名内部编码完全一致**:只把值里的
12064
+ * `=` 转成 `%3D`,其余字符(含 `,`)原样保留。小红书对 GET 请求按「路径 + 这套
12065
+ * 编码的 query」计算 x-s,若这里用 `encodeURIComponent`(会把 `,` 转成 `%2C`),
12066
+ * 发出去的 query 与被签名的内容不一致,平台返回 HTTP 406。
12067
+ */
12068
+ const buildQueryString$2 = (params) => Object.entries(params).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}=${String(value).replace(/=/g, "%3D")}`).join("&");
11956
12069
  /** 首页推荐(POST) */
11957
12070
  const homeFeed$1 = (data = {}) => ({
11958
12071
  apiPath: "/api/sns/web/v1/homefeed",
@@ -11992,6 +12105,7 @@ const noteComments$1 = (data) => {
11992
12105
  const params = {
11993
12106
  note_id: data.note_id,
11994
12107
  cursor: data.cursor ?? "",
12108
+ top_comment_id: "",
11995
12109
  image_formats: [
11996
12110
  "jpg",
11997
12111
  "webp",
@@ -12001,7 +12115,8 @@ const noteComments$1 = (data) => {
12001
12115
  };
12002
12116
  return {
12003
12117
  apiPath: "/api/sns/web/v2/comment/page",
12004
- Url: `https://edith.xiaohongshu.com/api/sns/web/v2/comment/page?${buildQueryString$2(params)}`
12118
+ Url: `https://edith.xiaohongshu.com/api/sns/web/v2/comment/page?${buildQueryString$2(params)}`,
12119
+ signParams: params
12005
12120
  };
12006
12121
  };
12007
12122
  /** 用户信息(GET,请求的是 HTML 页,由 judge / decode 层处理) */
@@ -12024,7 +12139,8 @@ const userNoteList$1 = (data) => {
12024
12139
  };
12025
12140
  return {
12026
12141
  apiPath: "/api/sns/web/v1/user_posted",
12027
- Url: `https://edith.xiaohongshu.com/api/sns/web/v1/user_posted?${buildQueryString$2(params)}`
12142
+ Url: `https://edith.xiaohongshu.com/api/sns/web/v1/user_posted?${buildQueryString$2(params)}`,
12143
+ signParams: params
12028
12144
  };
12029
12145
  };
12030
12146
  /** 表情列表(GET,无参数) */
@@ -12150,7 +12266,7 @@ const homeFeed = defineEndpoint({
12150
12266
  signPath: apiPath
12151
12267
  };
12152
12268
  },
12153
- sign: "xhs-post",
12269
+ sign: "xhs-post-rap",
12154
12270
  response: type()
12155
12271
  });
12156
12272
  //#endregion
@@ -12178,14 +12294,15 @@ const noteComments = defineEndpoint({
12178
12294
  number: zod.coerce.number().int().min(1).max(500).optional().describe("目标条数,默认一页")
12179
12295
  }),
12180
12296
  build: (p) => {
12181
- const { Url, apiPath } = noteComments$1(p);
12297
+ const { Url, apiPath, signParams } = noteComments$1(p);
12182
12298
  return {
12183
12299
  method: "GET",
12184
12300
  url: Url,
12185
- signPath: apiPath
12301
+ signPath: apiPath,
12302
+ extra: { signParams }
12186
12303
  };
12187
12304
  },
12188
- sign: "xhs-get",
12305
+ sign: "xhs-get-trace",
12189
12306
  paginate: {
12190
12307
  maxPageSize: 50,
12191
12308
  items: (page) => page.data?.comments ?? [],
@@ -12235,7 +12352,7 @@ const noteDetail = defineEndpoint({
12235
12352
  signPath: apiPath
12236
12353
  };
12237
12354
  },
12238
- sign: "xhs-post",
12355
+ sign: "xhs-post-rap",
12239
12356
  response: type()
12240
12357
  });
12241
12358
  //#endregion
@@ -12267,16 +12384,17 @@ const searchNotes = defineEndpoint({
12267
12384
  signPath: apiPath
12268
12385
  };
12269
12386
  },
12270
- sign: "xhs-post",
12387
+ sign: "xhs-post-rap",
12271
12388
  response: type()
12272
12389
  });
12273
12390
  //#endregion
12274
12391
  //#region src/platforms/xiaohongshu/endpoints/userNoteList.ts
12275
12392
  /**
12276
- * 用户笔记列表(GET + x-b3-traceid)。
12393
+ * 用户笔记列表(GET + x-b3-traceid,XYW_ 签名)。
12277
12394
  *
12278
- * 这个端点额外带 `x-b3-traceid` 头,因此单独用一个签名器
12279
- * `'xhs-get-trace'`(GET 签名 + traceid),而不是给所有 GET 都加。
12395
+ * 这个端点额外带 `x-b3-traceid` 头,且属于数据获取类接口 —— 自 2026-03 起传统
12396
+ * XYS_ 签名会被平台以 HTTP 406 拒绝,因此用 `'xhs-get-xyw-trace'`
12397
+ * (XYW_ GET 签名 + traceid),而不是给所有 GET 都换。
12280
12398
  */
12281
12399
  const userNoteList = defineEndpoint({
12282
12400
  name: "xiaohongshu.userNoteList",
@@ -12287,18 +12405,20 @@ const userNoteList = defineEndpoint({
12287
12405
  },
12288
12406
  params: zod.object({
12289
12407
  user_id: zod.string().min(1, { error: "user_id 不能为空" }).describe("用户 ID"),
12408
+ xsec_token: zod.string().min(1, { error: "xsec_token 不能为空" }).describe("反爬令牌,随笔记分享链接下发"),
12290
12409
  cursor: zod.string().optional().describe("翻页游标;传上一页最后一条的 ID,首页不传"),
12291
12410
  num: zod.coerce.number().int().min(1).max(100).optional().describe("单次请求的笔记条数,默认 30")
12292
12411
  }),
12293
12412
  build: (p) => {
12294
- const { Url, apiPath } = userNoteList$1(p);
12413
+ const { Url, apiPath, signParams } = userNoteList$1(p);
12295
12414
  return {
12296
12415
  method: "GET",
12297
12416
  url: Url,
12298
- signPath: apiPath
12417
+ signPath: apiPath,
12418
+ extra: { signParams }
12299
12419
  };
12300
12420
  },
12301
- sign: "xhs-get-trace",
12421
+ sign: "xhs-get-xyw-trace",
12302
12422
  response: type()
12303
12423
  });
12304
12424
  //#endregion
@@ -14149,6 +14269,21 @@ const RESPONSE_SCHEMAS = {
14149
14269
  "success"
14150
14270
  ]
14151
14271
  },
14272
+ "xiaohongshu_noteComments": {
14273
+ "type": "object",
14274
+ "properties": {
14275
+ "code": { "type": "number" },
14276
+ "data": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Data" },
14277
+ "msg": { "type": "string" },
14278
+ "success": { "type": "boolean" }
14279
+ },
14280
+ "required": [
14281
+ "code",
14282
+ "data",
14283
+ "msg",
14284
+ "success"
14285
+ ]
14286
+ },
14152
14287
  "xiaohongshu_noteDetail": {
14153
14288
  "type": "object",
14154
14289
  "properties": {
@@ -52878,6 +53013,212 @@ const RESPONSE_SCHEMAS = {
52878
53013
  "properties": { "capa": { "$ref": "#/components/schemas/xiaohongshu_homeFeed.HomeFeed_V0.Capa" } },
52879
53014
  "required": ["capa"]
52880
53015
  },
53016
+ "xiaohongshu_noteComments.NoteComments_V0.AtUser": {
53017
+ "type": "object",
53018
+ "properties": {
53019
+ "ai_agent": { "type": "boolean" },
53020
+ "nickname": { "type": "string" },
53021
+ "user_id": { "type": "string" },
53022
+ "xsec_token": { "type": "string" }
53023
+ },
53024
+ "required": [
53025
+ "ai_agent",
53026
+ "nickname",
53027
+ "user_id",
53028
+ "xsec_token"
53029
+ ]
53030
+ },
53031
+ "xiaohongshu_noteComments.NoteComments_V0.AudioInfo": {
53032
+ "type": "object",
53033
+ "properties": {
53034
+ "asr_text": { "type": "string" },
53035
+ "audio_id": { "type": "string" },
53036
+ "duration": { "type": "number" },
53037
+ "play_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.PlayInfo" },
53038
+ "tag_text": { "type": "string" }
53039
+ },
53040
+ "required": [
53041
+ "asr_text",
53042
+ "audio_id",
53043
+ "duration",
53044
+ "play_info",
53045
+ "tag_text"
53046
+ ]
53047
+ },
53048
+ "xiaohongshu_noteComments.NoteComments_V0.Comment": {
53049
+ "type": "object",
53050
+ "properties": {
53051
+ "at_users": {
53052
+ "type": "array",
53053
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.AtUser" }
53054
+ },
53055
+ "audio_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.AudioInfo" },
53056
+ "content": { "type": "string" },
53057
+ "create_time": { "type": "number" },
53058
+ "id": { "type": "string" },
53059
+ "invalid": { "type": "boolean" },
53060
+ "ip_location": { "type": "string" },
53061
+ "like_count": { "type": "string" },
53062
+ "liked": { "type": "boolean" },
53063
+ "note_id": { "type": "string" },
53064
+ "pictures": {
53065
+ "type": "array",
53066
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Picture" }
53067
+ },
53068
+ "show_tags": {
53069
+ "type": "array",
53070
+ "items": { "type": "string" }
53071
+ },
53072
+ "status": { "type": "number" },
53073
+ "sub_comment_count": { "type": "string" },
53074
+ "sub_comment_cursor": { "type": "string" },
53075
+ "sub_comment_has_more": { "type": "boolean" },
53076
+ "sub_comments": {
53077
+ "type": "array",
53078
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.SubComment" }
53079
+ },
53080
+ "user_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.UserInfo" }
53081
+ },
53082
+ "required": [
53083
+ "at_users",
53084
+ "content",
53085
+ "create_time",
53086
+ "id",
53087
+ "invalid",
53088
+ "like_count",
53089
+ "liked",
53090
+ "note_id",
53091
+ "show_tags",
53092
+ "status",
53093
+ "sub_comment_count",
53094
+ "sub_comment_cursor",
53095
+ "sub_comment_has_more",
53096
+ "sub_comments",
53097
+ "user_info"
53098
+ ]
53099
+ },
53100
+ "xiaohongshu_noteComments.NoteComments_V0.Data": {
53101
+ "type": "object",
53102
+ "properties": {
53103
+ "comments": {
53104
+ "type": "array",
53105
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Comment" }
53106
+ },
53107
+ "cursor": { "type": "string" },
53108
+ "has_more": { "type": "boolean" },
53109
+ "time": { "type": "number" },
53110
+ "user_id": { "type": "string" },
53111
+ "xsec_token": { "type": "string" }
53112
+ },
53113
+ "required": [
53114
+ "comments",
53115
+ "cursor",
53116
+ "has_more",
53117
+ "time",
53118
+ "user_id",
53119
+ "xsec_token"
53120
+ ]
53121
+ },
53122
+ "xiaohongshu_noteComments.NoteComments_V0.InfoList": {
53123
+ "type": "object",
53124
+ "properties": {
53125
+ "image_scene": { "type": "string" },
53126
+ "url": { "type": "string" }
53127
+ },
53128
+ "required": ["image_scene", "url"]
53129
+ },
53130
+ "xiaohongshu_noteComments.NoteComments_V0.Picture": {
53131
+ "type": "object",
53132
+ "properties": {
53133
+ "height": { "type": "number" },
53134
+ "info_list": {
53135
+ "type": "array",
53136
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.InfoList" }
53137
+ },
53138
+ "url_default": { "type": "string" },
53139
+ "url_pre": { "type": "string" },
53140
+ "width": { "type": "number" }
53141
+ },
53142
+ "required": [
53143
+ "height",
53144
+ "info_list",
53145
+ "url_default",
53146
+ "url_pre",
53147
+ "width"
53148
+ ]
53149
+ },
53150
+ "xiaohongshu_noteComments.NoteComments_V0.PlayInfo": {
53151
+ "type": "object",
53152
+ "properties": { "url": { "type": "string" } },
53153
+ "required": ["url"]
53154
+ },
53155
+ "xiaohongshu_noteComments.NoteComments_V0.SubComment": {
53156
+ "type": "object",
53157
+ "properties": {
53158
+ "at_users": {
53159
+ "type": "array",
53160
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.AtUser" }
53161
+ },
53162
+ "content": { "type": "string" },
53163
+ "create_time": { "type": "number" },
53164
+ "id": { "type": "string" },
53165
+ "invalid": { "type": "boolean" },
53166
+ "ip_location": { "type": "string" },
53167
+ "like_count": { "type": "string" },
53168
+ "liked": { "type": "boolean" },
53169
+ "note_id": { "type": "string" },
53170
+ "pictures": {
53171
+ "type": "array",
53172
+ "items": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.Picture" }
53173
+ },
53174
+ "show_tags": {
53175
+ "type": "array",
53176
+ "items": { "type": "string" }
53177
+ },
53178
+ "status": { "type": "number" },
53179
+ "target_comment": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.TargetComment" },
53180
+ "user_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.UserInfo" }
53181
+ },
53182
+ "required": [
53183
+ "at_users",
53184
+ "content",
53185
+ "create_time",
53186
+ "id",
53187
+ "invalid",
53188
+ "like_count",
53189
+ "liked",
53190
+ "note_id",
53191
+ "show_tags",
53192
+ "status",
53193
+ "target_comment",
53194
+ "user_info"
53195
+ ]
53196
+ },
53197
+ "xiaohongshu_noteComments.NoteComments_V0.TargetComment": {
53198
+ "type": "object",
53199
+ "properties": {
53200
+ "id": { "type": "string" },
53201
+ "user_info": { "$ref": "#/components/schemas/xiaohongshu_noteComments.NoteComments_V0.UserInfo" }
53202
+ },
53203
+ "required": ["id", "user_info"]
53204
+ },
53205
+ "xiaohongshu_noteComments.NoteComments_V0.UserInfo": {
53206
+ "type": "object",
53207
+ "properties": {
53208
+ "ai_agent": { "type": "boolean" },
53209
+ "image": { "type": "string" },
53210
+ "nickname": { "type": "string" },
53211
+ "user_id": { "type": "string" },
53212
+ "xsec_token": { "type": "string" }
53213
+ },
53214
+ "required": [
53215
+ "ai_agent",
53216
+ "image",
53217
+ "nickname",
53218
+ "user_id",
53219
+ "xsec_token"
53220
+ ]
53221
+ },
52881
53222
  "xiaohongshu_noteDetail.NoteDetail_V0.Data": {
52882
53223
  "type": "object",
52883
53224
  "properties": {
@@ -53673,7 +54014,7 @@ const buildOpenApiSpec = (options = {}) => {
53673
54014
  openapi: "3.1.0",
53674
54015
  info: {
53675
54016
  title: "amagi HTTP API",
53676
- version: options.version ?? "7.0.0-beta.1",
54017
+ version: options.version ?? "7.0.0-beta.3",
53677
54018
  description: [
53678
54019
  "由端点注册表派生的规范 —— 手写的那份已经漂移,这份不会(`gen-openapi --check` 进 CI)。",
53679
54020
  "",
@@ -56496,7 +56837,7 @@ let DynamicType = /* @__PURE__ */ function(DynamicType) {
56496
56837
  * 构建后使用 __VERSION__,开发环境从 package.json 读取
56497
56838
  */
56498
56839
  const getVersion = () => {
56499
- return "7.0.0-beta.1";
56840
+ return "7.0.0-beta.3";
56500
56841
  };
56501
56842
  const VERSION = getVersion();
56502
56843
  /**