@jiangtaste/baiwei-sdk 1.0.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 (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +360 -0
  3. package/dist/core/BaiweiClient.d.ts +38 -0
  4. package/dist/core/BaiweiClient.js +94 -0
  5. package/dist/core/BaiweiSession.d.ts +56 -0
  6. package/dist/core/BaiweiSession.js +229 -0
  7. package/dist/core/Client.d.ts +74 -0
  8. package/dist/core/Client.js +127 -0
  9. package/dist/core/MessageAssembler.d.ts +17 -0
  10. package/dist/core/MessageAssembler.js +76 -0
  11. package/dist/core/PendingRequestStore.d.ts +18 -0
  12. package/dist/core/PendingRequestStore.js +33 -0
  13. package/dist/core/Session.d.ts +43 -0
  14. package/dist/core/Session.js +330 -0
  15. package/dist/core/SessionConnector.d.ts +14 -0
  16. package/dist/core/SessionConnector.js +62 -0
  17. package/dist/index.d.ts +11 -0
  18. package/dist/index.js +27 -0
  19. package/dist/services/BaseService.d.ts +11 -0
  20. package/dist/services/BaseService.js +17 -0
  21. package/dist/services/ControlService.d.ts +33 -0
  22. package/dist/services/ControlService.js +67 -0
  23. package/dist/services/DeviceService.d.ts +26 -0
  24. package/dist/services/DeviceService.js +51 -0
  25. package/dist/services/GatewayService.d.ts +11 -0
  26. package/dist/services/GatewayService.js +33 -0
  27. package/dist/services/RoomService.d.ts +11 -0
  28. package/dist/services/RoomService.js +27 -0
  29. package/dist/services/SceneService.d.ts +12 -0
  30. package/dist/services/SceneService.js +39 -0
  31. package/dist/services/UserService.d.ts +21 -0
  32. package/dist/services/UserService.js +70 -0
  33. package/dist/transport/TcpClient.d.ts +38 -0
  34. package/dist/transport/TcpClient.js +315 -0
  35. package/dist/types/device-catalog.d.ts +42 -0
  36. package/dist/types/device-catalog.js +16 -0
  37. package/dist/types/device-state.d.ts +56 -0
  38. package/dist/types/device-state.js +2 -0
  39. package/dist/types/index.d.ts +8 -0
  40. package/dist/types/index.js +24 -0
  41. package/dist/types/messages.d.ts +53 -0
  42. package/dist/types/messages.js +32 -0
  43. package/dist/types/options.d.ts +27 -0
  44. package/dist/types/options.js +7 -0
  45. package/dist/types/room.d.ts +9 -0
  46. package/dist/types/room.js +2 -0
  47. package/dist/types/scene.d.ts +22 -0
  48. package/dist/types/scene.js +2 -0
  49. package/dist/types/user.d.ts +17 -0
  50. package/dist/types/user.js +2 -0
  51. package/dist/types.d.ts +212 -0
  52. package/dist/types.js +50 -0
  53. package/dist/utils/IdGenerator.d.ts +19 -0
  54. package/dist/utils/IdGenerator.js +49 -0
  55. package/dist/utils/MessageIdGenerator.d.ts +4 -0
  56. package/dist/utils/MessageIdGenerator.js +12 -0
  57. package/dist/utils/logger.d.ts +33 -0
  58. package/dist/utils/logger.js +115 -0
  59. package/dist/utils/time.d.ts +2 -0
  60. package/dist/utils/time.js +14 -0
  61. package/package.json +45 -0
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.maskSensitive = maskSensitive;
4
+ exports.createLogger = createLogger;
5
+ const DEFAULT_SENSITIVE_KEYS = [
6
+ "token",
7
+ "password",
8
+ "pwd",
9
+ "authorization",
10
+ "cookie",
11
+ "secret",
12
+ "apikey",
13
+ "api_key",
14
+ ];
15
+ /**
16
+ * 对日志中的敏感字段做浅/深层脱敏。
17
+ * 兼容普通对象和 JSON 字符串两种输入。
18
+ */
19
+ function maskSensitive(value, keys = DEFAULT_SENSITIVE_KEYS) {
20
+ if (value === null || value === undefined)
21
+ return value;
22
+ // 1) value 是 JSON string:解析 -> 脱敏 -> 再 stringify 回 string
23
+ if (typeof value === "string") {
24
+ const s = value.trim();
25
+ try {
26
+ const parsed = JSON.parse(s);
27
+ const masked = maskSensitive(parsed, keys);
28
+ return JSON.stringify(masked);
29
+ }
30
+ catch {
31
+ // 解析失败就当普通字符串,不处理
32
+ return value;
33
+ }
34
+ }
35
+ // 2) 基础类型不处理
36
+ const t = typeof value;
37
+ if (t === "number" || t === "boolean" || t === "bigint")
38
+ return value;
39
+ // 3) 对象/数组:走 replacer 脱敏(注意 replacer 的 v 也是 unknown)
40
+ try {
41
+ const json = JSON.stringify(value, (k, v) => {
42
+ const key = String(k ?? "").toLowerCase();
43
+ if (keys.some((x) => key.includes(x)))
44
+ return "***";
45
+ return v; // ✅ replacer 必须返回 any-ish(JSON.stringify 的签名如此)
46
+ });
47
+ return JSON.parse(json);
48
+ }
49
+ catch {
50
+ return value;
51
+ }
52
+ }
53
+ /**
54
+ * 统一拿到一个可用的 logger:
55
+ * - 默认使用 console
56
+ * - 返回的 logger 保证 debug/info/warn/error 都是函数
57
+ * - 默认:debug 不脱敏,info/warn/error 脱敏
58
+ * - 当不传入 logger 时:会在日志前自动加时间戳与可选前缀
59
+ */
60
+ function createLogger(input, opts = {}) {
61
+ const base = input ?? console;
62
+ const maskKeys = opts.maskKeys ?? DEFAULT_SENSITIVE_KEYS;
63
+ const maskDebug = opts.maskDebug ?? false;
64
+ // 当用户不传 logger 时,默认开启时间戳;传了 logger 则默认不强加格式(除非显式打开)
65
+ const shouldDecorate = input === undefined;
66
+ const withTimestamp = opts.withTimestamp ?? shouldDecorate;
67
+ const prefix = opts.prefix?.trim();
68
+ const formatTime = opts.formatTime ?? ((d) => d.toISOString());
69
+ const buildHeader = () => {
70
+ const parts = [];
71
+ if (withTimestamp)
72
+ parts.push(formatTime(new Date()));
73
+ if (prefix)
74
+ parts.push(prefix);
75
+ if (parts.length === 0)
76
+ return "";
77
+ return `[${parts.join("][")}]`;
78
+ };
79
+ const decorateArgs = (args) => {
80
+ const header = buildHeader();
81
+ if (!header)
82
+ return args;
83
+ // 如果第一个参数是字符串,拼接更自然;否则把 header 作为第一个参数插入
84
+ if (typeof args[0] === "string") {
85
+ const [first, ...rest] = args;
86
+ return [`${header} ${first}`, ...rest];
87
+ }
88
+ return [header, ...args];
89
+ };
90
+ // 单个日志方法抛错时不影响业务主流程。
91
+ const safeFn = (fn) => (...args) => {
92
+ try {
93
+ (fn ?? console.log)(...args);
94
+ }
95
+ catch {
96
+ // ignore
97
+ }
98
+ };
99
+ const mapArgs = (args, shouldMask) => {
100
+ const decorated = shouldDecorate ? decorateArgs(args) : args;
101
+ if (!shouldMask)
102
+ return decorated;
103
+ return decorated.map((a) => maskSensitive(a, maskKeys));
104
+ };
105
+ const debug = safeFn(base.debug ?? console.debug);
106
+ const info = safeFn(base.info ?? console.info);
107
+ const warn = safeFn(base.warn ?? console.warn);
108
+ const error = safeFn(base.error ?? console.error);
109
+ return {
110
+ debug: (...args) => debug(...mapArgs(args, maskDebug)),
111
+ info: (...args) => info(...mapArgs(args, true)),
112
+ warn: (...args) => warn(...mapArgs(args, true)),
113
+ error: (...args) => error(...mapArgs(args, true)),
114
+ };
115
+ }
@@ -0,0 +1,2 @@
1
+ /** 把时间格式化为 `YYYY-MM-DD HH:mm:ss`,便于日志或调试输出。 */
2
+ export declare function formatTime(date?: Date): string;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatTime = formatTime;
4
+ /** 把时间格式化为 `YYYY-MM-DD HH:mm:ss`,便于日志或调试输出。 */
5
+ function formatTime(date = new Date()) {
6
+ const pad = (n) => n.toString().padStart(2, "0");
7
+ const y = date.getFullYear();
8
+ const m = pad(date.getMonth() + 1);
9
+ const d = pad(date.getDate());
10
+ const hh = pad(date.getHours());
11
+ const mm = pad(date.getMinutes());
12
+ const ss = pad(date.getSeconds());
13
+ return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
14
+ }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@jiangtaste/baiwei-sdk",
3
+ "version": "1.0.0",
4
+ "description": "面向百微智能网关的 SDK",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "require": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "sideEffects": false,
19
+ "scripts": {
20
+ "dev": "ts-node -P examples/tsconfig.json examples/debug.ts",
21
+ "debug": "ts-node -P examples/tsconfig.json examples/debug.ts",
22
+ "build": "tsc",
23
+ "start": "node dist/index.js",
24
+ "prepare": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "baiwei",
28
+ "iot",
29
+ "gateway",
30
+ "tcp",
31
+ "smart-home",
32
+ "zigbee"
33
+ ],
34
+ "author": "jiangtaste",
35
+ "license": "MIT",
36
+ "type": "commonjs",
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "^24.13.1",
42
+ "ts-node": "^10.9.2",
43
+ "typescript": "^5.9.3"
44
+ }
45
+ }