@rei-standard/amsg-client 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -36,7 +36,6 @@ module.exports = __toCommonJS(src_exports);
36
36
  var import_amsg_shared = require("@rei-standard/amsg-shared");
37
37
  var import_amsg_shared2 = require("@rei-standard/amsg-shared");
38
38
  var TEXT_ENCODER = new TextEncoder();
39
- var AVATAR_URL_MAX_LENGTH = 2048;
40
39
  function makeLocalError(code, message, details) {
41
40
  const err = new Error(`[rei-standard-amsg-client] ${message}`);
42
41
  err.code = code;
@@ -597,16 +596,7 @@ var ReiClient = class {
597
596
  */
598
597
  _sanitizeAvatarUrl(target) {
599
598
  if (!target || typeof target !== "object") return false;
600
- const value = target.avatarUrl;
601
- if (value === void 0 || value === null) return false;
602
- let reason = null;
603
- if (typeof value !== "string") {
604
- reason = "avatarUrl \u5FC5\u987B\u662F\u5B57\u7B26\u4E32";
605
- } else if (/^data:/i.test(value)) {
606
- reason = "\u5934\u50CF\u4E0D\u652F\u6301\u4F20\u5165 data: URI\uFF0C\u8BF7\u6539\u4E3A\u516C\u7F51\u53EF\u8BBF\u95EE\u7684 https:// \u56FE\u7247 URL";
607
- } else if (value.length > AVATAR_URL_MAX_LENGTH) {
608
- reason = `\u5934\u50CF URL \u957F\u5EA6 ${value.length} \u5B57\u7B26\u8D85\u8FC7 ${AVATAR_URL_MAX_LENGTH} \u4E0A\u9650\uFF0C\u8BF7\u6539\u4E3A\u66F4\u77ED\u7684\u56FE\u7247 URL`;
609
- }
599
+ const reason = (0, import_amsg_shared.validateAvatarUrl)(target.avatarUrl);
610
600
  if (reason) {
611
601
  console.warn("[rei-standard-amsg-client] avatarUrl \u4E0D\u5408\u6CD5\uFF0C\u5DF2\u7F6E\u7A7A\uFF1A", reason);
612
602
  target.avatarUrl = null;
@@ -695,7 +685,8 @@ var ReiClient = class {
695
685
  err.status = res.status;
696
686
  throw err;
697
687
  }
698
- const contentType = res.headers.get("content-type") || "";
688
+ const rawContentType = res.headers.get("content-type");
689
+ const contentType = rawContentType || "";
699
690
  const kind = classifyContentType(contentType);
700
691
  if (kind === "sse") {
701
692
  if (!res.body) throw new Error("Response body is null");
@@ -705,7 +696,7 @@ var ReiClient = class {
705
696
  responseMeta: {
706
697
  status: res.status,
707
698
  contentEncoding: res.headers.get("content-encoding"),
708
- contentType: res.headers.get("content-type")
699
+ contentType: rawContentType
709
700
  }
710
701
  });
711
702
  return { kind: "sse" };
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { base64UrlToBytes } from '@rei-standard/amsg-shared';
1
+ import { base64UrlToBytes, validateAvatarUrl } from '@rei-standard/amsg-shared';
2
2
  export { MESSAGE_KIND, MESSAGE_TYPE, PUSH_SOURCE, buildContentPush, buildErrorPush, buildReasoningPush, buildToolRequestPush, isContentPush, isErrorPush, isReasoningPush, isToolRequestPush } from '@rei-standard/amsg-shared';
3
3
 
4
4
  /**
@@ -231,14 +231,6 @@ const TEXT_ENCODER = new TextEncoder();
231
231
  * @property {number} [status] - `res.status`. First call only.
232
232
  */
233
233
 
234
- /**
235
- * Max length of `avatarUrl` accepted by local preflight (2 KB). Mirrors
236
- * `@rei-standard/amsg-instant` / `@rei-standard/amsg-server` server-side
237
- * limits — kept in lockstep on purpose so client-side rejects match what
238
- * the server would reject.
239
- */
240
- const AVATAR_URL_MAX_LENGTH = 2048;
241
-
242
234
  function makeLocalError(code, message, details) {
243
235
  const err = new Error(`[rei-standard-amsg-client] ${message}`);
244
236
  err.code = code;
@@ -991,16 +983,7 @@ class ReiClient {
991
983
  */
992
984
  _sanitizeAvatarUrl(target) {
993
985
  if (!target || typeof target !== 'object') return false;
994
- const value = target.avatarUrl;
995
- if (value === undefined || value === null) return false;
996
- let reason = null;
997
- if (typeof value !== 'string') {
998
- reason = 'avatarUrl 必须是字符串';
999
- } else if (/^data:/i.test(value)) {
1000
- reason = '头像不支持传入 data: URI,请改为公网可访问的 https:// 图片 URL';
1001
- } else if (value.length > AVATAR_URL_MAX_LENGTH) {
1002
- reason = `头像 URL 长度 ${value.length} 字符超过 ${AVATAR_URL_MAX_LENGTH} 上限,请改为更短的图片 URL`;
1003
- }
986
+ const reason = validateAvatarUrl(target.avatarUrl);
1004
987
  if (reason) {
1005
988
  console.warn('[rei-standard-amsg-client] avatarUrl 不合法,已置空:', reason);
1006
989
  target.avatarUrl = null;
@@ -1105,7 +1088,8 @@ class ReiClient {
1105
1088
  throw err;
1106
1089
  }
1107
1090
 
1108
- const contentType = res.headers.get('content-type') || '';
1091
+ const rawContentType = res.headers.get('content-type');
1092
+ const contentType = rawContentType || '';
1109
1093
  const kind = classifyContentType(contentType);
1110
1094
  if (kind === 'sse') {
1111
1095
  if (!res.body) throw new Error('Response body is null');
@@ -1115,7 +1099,7 @@ class ReiClient {
1115
1099
  responseMeta: {
1116
1100
  status: res.status,
1117
1101
  contentEncoding: res.headers.get('content-encoding'),
1118
- contentType: res.headers.get('content-type'),
1102
+ contentType: rawContentType,
1119
1103
  },
1120
1104
  });
1121
1105
  return { kind: 'sse' };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { base64UrlToBytes } from '@rei-standard/amsg-shared';
1
+ import { base64UrlToBytes, validateAvatarUrl } from '@rei-standard/amsg-shared';
2
2
  export { MESSAGE_KIND, MESSAGE_TYPE, PUSH_SOURCE, buildContentPush, buildErrorPush, buildReasoningPush, buildToolRequestPush, isContentPush, isErrorPush, isReasoningPush, isToolRequestPush } from '@rei-standard/amsg-shared';
3
3
 
4
4
  /**
@@ -231,14 +231,6 @@ const TEXT_ENCODER = new TextEncoder();
231
231
  * @property {number} [status] - `res.status`. First call only.
232
232
  */
233
233
 
234
- /**
235
- * Max length of `avatarUrl` accepted by local preflight (2 KB). Mirrors
236
- * `@rei-standard/amsg-instant` / `@rei-standard/amsg-server` server-side
237
- * limits — kept in lockstep on purpose so client-side rejects match what
238
- * the server would reject.
239
- */
240
- const AVATAR_URL_MAX_LENGTH = 2048;
241
-
242
234
  function makeLocalError(code, message, details) {
243
235
  const err = new Error(`[rei-standard-amsg-client] ${message}`);
244
236
  err.code = code;
@@ -991,16 +983,7 @@ class ReiClient {
991
983
  */
992
984
  _sanitizeAvatarUrl(target) {
993
985
  if (!target || typeof target !== 'object') return false;
994
- const value = target.avatarUrl;
995
- if (value === undefined || value === null) return false;
996
- let reason = null;
997
- if (typeof value !== 'string') {
998
- reason = 'avatarUrl 必须是字符串';
999
- } else if (/^data:/i.test(value)) {
1000
- reason = '头像不支持传入 data: URI,请改为公网可访问的 https:// 图片 URL';
1001
- } else if (value.length > AVATAR_URL_MAX_LENGTH) {
1002
- reason = `头像 URL 长度 ${value.length} 字符超过 ${AVATAR_URL_MAX_LENGTH} 上限,请改为更短的图片 URL`;
1003
- }
986
+ const reason = validateAvatarUrl(target.avatarUrl);
1004
987
  if (reason) {
1005
988
  console.warn('[rei-standard-amsg-client] avatarUrl 不合法,已置空:', reason);
1006
989
  target.avatarUrl = null;
@@ -1105,7 +1088,8 @@ class ReiClient {
1105
1088
  throw err;
1106
1089
  }
1107
1090
 
1108
- const contentType = res.headers.get('content-type') || '';
1091
+ const rawContentType = res.headers.get('content-type');
1092
+ const contentType = rawContentType || '';
1109
1093
  const kind = classifyContentType(contentType);
1110
1094
  if (kind === 'sse') {
1111
1095
  if (!res.body) throw new Error('Response body is null');
@@ -1115,7 +1099,7 @@ class ReiClient {
1115
1099
  responseMeta: {
1116
1100
  status: res.status,
1117
1101
  contentEncoding: res.headers.get('content-encoding'),
1118
- contentType: res.headers.get('content-type'),
1102
+ contentType: rawContentType,
1119
1103
  },
1120
1104
  });
1121
1105
  return { kind: 'sse' };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.js
2
- import { base64UrlToBytes } from "@rei-standard/amsg-shared";
2
+ import { base64UrlToBytes, validateAvatarUrl } from "@rei-standard/amsg-shared";
3
3
  import {
4
4
  MESSAGE_KIND,
5
5
  MESSAGE_TYPE,
@@ -14,7 +14,6 @@ import {
14
14
  isErrorPush
15
15
  } from "@rei-standard/amsg-shared";
16
16
  var TEXT_ENCODER = new TextEncoder();
17
- var AVATAR_URL_MAX_LENGTH = 2048;
18
17
  function makeLocalError(code, message, details) {
19
18
  const err = new Error(`[rei-standard-amsg-client] ${message}`);
20
19
  err.code = code;
@@ -575,16 +574,7 @@ var ReiClient = class {
575
574
  */
576
575
  _sanitizeAvatarUrl(target) {
577
576
  if (!target || typeof target !== "object") return false;
578
- const value = target.avatarUrl;
579
- if (value === void 0 || value === null) return false;
580
- let reason = null;
581
- if (typeof value !== "string") {
582
- reason = "avatarUrl \u5FC5\u987B\u662F\u5B57\u7B26\u4E32";
583
- } else if (/^data:/i.test(value)) {
584
- reason = "\u5934\u50CF\u4E0D\u652F\u6301\u4F20\u5165 data: URI\uFF0C\u8BF7\u6539\u4E3A\u516C\u7F51\u53EF\u8BBF\u95EE\u7684 https:// \u56FE\u7247 URL";
585
- } else if (value.length > AVATAR_URL_MAX_LENGTH) {
586
- reason = `\u5934\u50CF URL \u957F\u5EA6 ${value.length} \u5B57\u7B26\u8D85\u8FC7 ${AVATAR_URL_MAX_LENGTH} \u4E0A\u9650\uFF0C\u8BF7\u6539\u4E3A\u66F4\u77ED\u7684\u56FE\u7247 URL`;
587
- }
577
+ const reason = validateAvatarUrl(target.avatarUrl);
588
578
  if (reason) {
589
579
  console.warn("[rei-standard-amsg-client] avatarUrl \u4E0D\u5408\u6CD5\uFF0C\u5DF2\u7F6E\u7A7A\uFF1A", reason);
590
580
  target.avatarUrl = null;
@@ -673,7 +663,8 @@ var ReiClient = class {
673
663
  err.status = res.status;
674
664
  throw err;
675
665
  }
676
- const contentType = res.headers.get("content-type") || "";
666
+ const rawContentType = res.headers.get("content-type");
667
+ const contentType = rawContentType || "";
677
668
  const kind = classifyContentType(contentType);
678
669
  if (kind === "sse") {
679
670
  if (!res.body) throw new Error("Response body is null");
@@ -683,7 +674,7 @@ var ReiClient = class {
683
674
  responseMeta: {
684
675
  status: res.status,
685
676
  contentEncoding: res.headers.get("content-encoding"),
686
- contentType: res.headers.get("content-type")
677
+ contentType: rawContentType
687
678
  }
688
679
  });
689
680
  return { kind: "sse" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rei-standard/amsg-client",
3
- "version": "2.7.0",
3
+ "version": "2.8.0",
4
4
  "description": "ReiStandard Active Messaging browser client SDK — also re-exports shared push types, builders, and guards from @rei-standard/amsg-shared",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,7 +33,7 @@
33
33
  "node": ">=20"
34
34
  },
35
35
  "dependencies": {
36
- "@rei-standard/amsg-shared": "0.2.0"
36
+ "@rei-standard/amsg-shared": "^0.3.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "tsup": "^8.0.0",