@yu_robotics/remote-cli-router 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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/bin/remote-cli-router.js +2 -0
  4. package/dist/binding/BindingManager.d.ts +62 -0
  5. package/dist/binding/BindingManager.d.ts.map +1 -0
  6. package/dist/binding/BindingManager.js +119 -0
  7. package/dist/binding/BindingManager.js.map +1 -0
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +32 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/config.d.ts +19 -0
  13. package/dist/commands/config.d.ts.map +1 -0
  14. package/dist/commands/config.js +206 -0
  15. package/dist/commands/config.js.map +1 -0
  16. package/dist/commands/start.d.ts +5 -0
  17. package/dist/commands/start.d.ts.map +1 -0
  18. package/dist/commands/start.js +65 -0
  19. package/dist/commands/start.js.map +1 -0
  20. package/dist/commands/status.d.ts +5 -0
  21. package/dist/commands/status.d.ts.map +1 -0
  22. package/dist/commands/status.js +103 -0
  23. package/dist/commands/status.js.map +1 -0
  24. package/dist/commands/stop.d.ts +5 -0
  25. package/dist/commands/stop.d.ts.map +1 -0
  26. package/dist/commands/stop.js +56 -0
  27. package/dist/commands/stop.js.map +1 -0
  28. package/dist/config/ConfigManager.d.ts +46 -0
  29. package/dist/config/ConfigManager.d.ts.map +1 -0
  30. package/dist/config/ConfigManager.js +101 -0
  31. package/dist/config/ConfigManager.js.map +1 -0
  32. package/dist/feishu/FeishuClient.d.ts +46 -0
  33. package/dist/feishu/FeishuClient.d.ts.map +1 -0
  34. package/dist/feishu/FeishuClient.js +130 -0
  35. package/dist/feishu/FeishuClient.js.map +1 -0
  36. package/dist/feishu/FeishuLongConnHandler.d.ts +149 -0
  37. package/dist/feishu/FeishuLongConnHandler.d.ts.map +1 -0
  38. package/dist/feishu/FeishuLongConnHandler.js +632 -0
  39. package/dist/feishu/FeishuLongConnHandler.js.map +1 -0
  40. package/dist/server.d.ts +80 -0
  41. package/dist/server.d.ts.map +1 -0
  42. package/dist/server.js +533 -0
  43. package/dist/server.js.map +1 -0
  44. package/dist/storage/JsonStore.d.ts +90 -0
  45. package/dist/storage/JsonStore.d.ts.map +1 -0
  46. package/dist/storage/JsonStore.js +215 -0
  47. package/dist/storage/JsonStore.js.map +1 -0
  48. package/dist/storage/MemoryStore.d.ts +69 -0
  49. package/dist/storage/MemoryStore.d.ts.map +1 -0
  50. package/dist/storage/MemoryStore.js +117 -0
  51. package/dist/storage/MemoryStore.js.map +1 -0
  52. package/dist/types/config.d.ts +53 -0
  53. package/dist/types/config.d.ts.map +1 -0
  54. package/dist/types/config.js +31 -0
  55. package/dist/types/config.js.map +1 -0
  56. package/dist/types/index.d.ts +93 -0
  57. package/dist/types/index.d.ts.map +1 -0
  58. package/dist/types/index.js +18 -0
  59. package/dist/types/index.js.map +1 -0
  60. package/dist/utils/PidManager.d.ts +28 -0
  61. package/dist/utils/PidManager.d.ts.map +1 -0
  62. package/dist/utils/PidManager.js +90 -0
  63. package/dist/utils/PidManager.js.map +1 -0
  64. package/dist/utils/ToolFormatter.d.ts +41 -0
  65. package/dist/utils/ToolFormatter.d.ts.map +1 -0
  66. package/dist/utils/ToolFormatter.js +273 -0
  67. package/dist/utils/ToolFormatter.js.map +1 -0
  68. package/dist/websocket/ConnectionHub.d.ts +73 -0
  69. package/dist/websocket/ConnectionHub.d.ts.map +1 -0
  70. package/dist/websocket/ConnectionHub.js +177 -0
  71. package/dist/websocket/ConnectionHub.js.map +1 -0
  72. package/package.json +70 -0
@@ -0,0 +1,90 @@
1
+ import { BindingCode, UserBinding } from '../types';
2
+ /**
3
+ * JSON file-based storage for bindings
4
+ * Persists data across router restarts
5
+ */
6
+ export declare class JsonStore {
7
+ private storePath;
8
+ private data;
9
+ private saveTimer;
10
+ private readonly SAVE_DELAY;
11
+ constructor(storePath?: string);
12
+ /**
13
+ * Initialize store by loading data from disk
14
+ */
15
+ initialize(): Promise<void>;
16
+ /**
17
+ * Store binding code with expiration
18
+ * @param code Binding code
19
+ * @param bindingCode Binding code object
20
+ */
21
+ setBindingCode(code: string, bindingCode: BindingCode): Promise<void>;
22
+ /**
23
+ * Get binding code
24
+ * @param code Binding code
25
+ * @returns Binding code object or null if not found/expired
26
+ */
27
+ getBindingCode(code: string): BindingCode | null;
28
+ /**
29
+ * Delete binding code
30
+ * @param code Binding code
31
+ */
32
+ deleteBindingCode(code: string): Promise<void>;
33
+ /**
34
+ * Set user binding
35
+ * @param openId Feishu user open_id
36
+ * @param binding User binding object
37
+ */
38
+ setUserBinding(openId: string, binding: UserBinding): Promise<void>;
39
+ /**
40
+ * Get user binding
41
+ * @param openId Feishu user open_id
42
+ * @returns User binding or null if not found
43
+ */
44
+ getUserBinding(openId: string): UserBinding | null;
45
+ /**
46
+ * Get device binding
47
+ * @param deviceId Device unique identifier
48
+ * @returns User binding or null if not found
49
+ */
50
+ getDeviceBinding(deviceId: string): UserBinding | null;
51
+ /**
52
+ * Delete user binding
53
+ * @param openId Feishu user open_id
54
+ */
55
+ deleteUserBinding(openId: string): Promise<void>;
56
+ /**
57
+ * Update user last active time
58
+ * @param openId Feishu user open_id
59
+ */
60
+ updateLastActive(openId: string): Promise<void>;
61
+ /**
62
+ * Clean up expired binding codes
63
+ */
64
+ private cleanupExpiredBindingCodes;
65
+ /**
66
+ * Schedule a save operation (debounced)
67
+ */
68
+ private scheduleSave;
69
+ /**
70
+ * Save data to disk
71
+ */
72
+ private save;
73
+ /**
74
+ * Force immediate save (for graceful shutdown)
75
+ */
76
+ flush(): Promise<void>;
77
+ /**
78
+ * Clear all data
79
+ */
80
+ clear(): Promise<void>;
81
+ /**
82
+ * Get statistics
83
+ */
84
+ getStats(): {
85
+ bindingCodes: number;
86
+ userBindings: number;
87
+ deviceBindings: number;
88
+ };
89
+ }
90
+ //# sourceMappingURL=JsonStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonStore.d.ts","sourceRoot":"","sources":["../../src/storage/JsonStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAWpD;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,IAAI,CAAY;IACxB,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;gBAEvB,SAAS,CAAC,EAAE,MAAM;IAS9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBjC;;;;OAIG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3E;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAiBhD;;;OAGG;IACG,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpD;;;;OAIG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzE;;;;OAIG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAIlD;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAItD;;;OAGG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAStD;;;OAGG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrD;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAgBlC;;OAEG;YACW,YAAY;IAa1B;;OAEG;YACW,IAAI;IASlB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B;;OAEG;IACH,QAAQ,IAAI;QACV,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;KACxB;CAOF"}
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.JsonStore = void 0;
7
+ const promises_1 = __importDefault(require("fs/promises"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ /**
11
+ * JSON file-based storage for bindings
12
+ * Persists data across router restarts
13
+ */
14
+ class JsonStore {
15
+ storePath;
16
+ data;
17
+ saveTimer = null;
18
+ SAVE_DELAY = 1000; // Debounce saves by 1 second
19
+ constructor(storePath) {
20
+ this.storePath = storePath || path_1.default.join(os_1.default.homedir(), '.remote-cli-router', 'bindings.json');
21
+ this.data = {
22
+ bindingCodes: {},
23
+ userBindings: {},
24
+ deviceBindings: {},
25
+ };
26
+ }
27
+ /**
28
+ * Initialize store by loading data from disk
29
+ */
30
+ async initialize() {
31
+ try {
32
+ // Ensure directory exists
33
+ await promises_1.default.mkdir(path_1.default.dirname(this.storePath), { recursive: true });
34
+ // Try to load existing data
35
+ try {
36
+ const content = await promises_1.default.readFile(this.storePath, 'utf-8');
37
+ this.data = JSON.parse(content);
38
+ // Clean up expired binding codes on startup
39
+ this.cleanupExpiredBindingCodes();
40
+ }
41
+ catch (error) {
42
+ // File doesn't exist or is invalid, start with empty data
43
+ if (error.code !== 'ENOENT') {
44
+ console.warn('Failed to load bindings data, starting fresh:', error.message);
45
+ }
46
+ await this.save();
47
+ }
48
+ }
49
+ catch (error) {
50
+ console.error('Failed to initialize JSON store:', error);
51
+ throw error;
52
+ }
53
+ }
54
+ /**
55
+ * Store binding code with expiration
56
+ * @param code Binding code
57
+ * @param bindingCode Binding code object
58
+ */
59
+ async setBindingCode(code, bindingCode) {
60
+ this.data.bindingCodes[code] = bindingCode;
61
+ await this.scheduleSave();
62
+ }
63
+ /**
64
+ * Get binding code
65
+ * @param code Binding code
66
+ * @returns Binding code object or null if not found/expired
67
+ */
68
+ getBindingCode(code) {
69
+ const bindingCode = this.data.bindingCodes[code];
70
+ if (!bindingCode) {
71
+ return null;
72
+ }
73
+ // Check if expired
74
+ if (Date.now() > bindingCode.expiresAt) {
75
+ delete this.data.bindingCodes[code];
76
+ this.scheduleSave();
77
+ return null;
78
+ }
79
+ return bindingCode;
80
+ }
81
+ /**
82
+ * Delete binding code
83
+ * @param code Binding code
84
+ */
85
+ async deleteBindingCode(code) {
86
+ delete this.data.bindingCodes[code];
87
+ await this.scheduleSave();
88
+ }
89
+ /**
90
+ * Set user binding
91
+ * @param openId Feishu user open_id
92
+ * @param binding User binding object
93
+ */
94
+ async setUserBinding(openId, binding) {
95
+ this.data.userBindings[openId] = binding;
96
+ this.data.deviceBindings[binding.deviceId] = binding;
97
+ await this.scheduleSave();
98
+ }
99
+ /**
100
+ * Get user binding
101
+ * @param openId Feishu user open_id
102
+ * @returns User binding or null if not found
103
+ */
104
+ getUserBinding(openId) {
105
+ return this.data.userBindings[openId] || null;
106
+ }
107
+ /**
108
+ * Get device binding
109
+ * @param deviceId Device unique identifier
110
+ * @returns User binding or null if not found
111
+ */
112
+ getDeviceBinding(deviceId) {
113
+ return this.data.deviceBindings[deviceId] || null;
114
+ }
115
+ /**
116
+ * Delete user binding
117
+ * @param openId Feishu user open_id
118
+ */
119
+ async deleteUserBinding(openId) {
120
+ const binding = this.data.userBindings[openId];
121
+ if (binding) {
122
+ delete this.data.userBindings[openId];
123
+ delete this.data.deviceBindings[binding.deviceId];
124
+ await this.scheduleSave();
125
+ }
126
+ }
127
+ /**
128
+ * Update user last active time
129
+ * @param openId Feishu user open_id
130
+ */
131
+ async updateLastActive(openId) {
132
+ const binding = this.data.userBindings[openId];
133
+ if (binding) {
134
+ binding.lastActiveAt = Date.now();
135
+ this.data.userBindings[openId] = binding;
136
+ this.data.deviceBindings[binding.deviceId] = binding;
137
+ await this.scheduleSave();
138
+ }
139
+ }
140
+ /**
141
+ * Clean up expired binding codes
142
+ */
143
+ cleanupExpiredBindingCodes() {
144
+ const now = Date.now();
145
+ let hasChanges = false;
146
+ for (const [code, bindingCode] of Object.entries(this.data.bindingCodes)) {
147
+ if (now > bindingCode.expiresAt) {
148
+ delete this.data.bindingCodes[code];
149
+ hasChanges = true;
150
+ }
151
+ }
152
+ if (hasChanges) {
153
+ this.scheduleSave();
154
+ }
155
+ }
156
+ /**
157
+ * Schedule a save operation (debounced)
158
+ */
159
+ async scheduleSave() {
160
+ if (this.saveTimer) {
161
+ clearTimeout(this.saveTimer);
162
+ }
163
+ return new Promise((resolve) => {
164
+ this.saveTimer = setTimeout(async () => {
165
+ await this.save();
166
+ resolve();
167
+ }, this.SAVE_DELAY);
168
+ });
169
+ }
170
+ /**
171
+ * Save data to disk
172
+ */
173
+ async save() {
174
+ try {
175
+ const content = JSON.stringify(this.data, null, 2);
176
+ await promises_1.default.writeFile(this.storePath, content, 'utf-8');
177
+ }
178
+ catch (error) {
179
+ console.error('Failed to save bindings data:', error);
180
+ }
181
+ }
182
+ /**
183
+ * Force immediate save (for graceful shutdown)
184
+ */
185
+ async flush() {
186
+ if (this.saveTimer) {
187
+ clearTimeout(this.saveTimer);
188
+ this.saveTimer = null;
189
+ }
190
+ await this.save();
191
+ }
192
+ /**
193
+ * Clear all data
194
+ */
195
+ async clear() {
196
+ this.data = {
197
+ bindingCodes: {},
198
+ userBindings: {},
199
+ deviceBindings: {},
200
+ };
201
+ await this.save();
202
+ }
203
+ /**
204
+ * Get statistics
205
+ */
206
+ getStats() {
207
+ return {
208
+ bindingCodes: Object.keys(this.data.bindingCodes).length,
209
+ userBindings: Object.keys(this.data.userBindings).length,
210
+ deviceBindings: Object.keys(this.data.deviceBindings).length,
211
+ };
212
+ }
213
+ }
214
+ exports.JsonStore = JsonStore;
215
+ //# sourceMappingURL=JsonStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonStore.js","sourceRoot":"","sources":["../../src/storage/JsonStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import { BindingCode, UserBinding } from '../types';
2
+ /**
3
+ * In-memory storage for bindings
4
+ * Replaces Redis for low-concurrency scenarios
5
+ */
6
+ export declare class MemoryStore {
7
+ private bindingCodes;
8
+ private userBindings;
9
+ private deviceBindings;
10
+ /**
11
+ * Store binding code with expiration
12
+ * @param code Binding code
13
+ * @param bindingCode Binding code object
14
+ * @param ttlSeconds Time to live in seconds
15
+ */
16
+ setBindingCode(code: string, bindingCode: BindingCode, ttlSeconds: number): void;
17
+ /**
18
+ * Get binding code
19
+ * @param code Binding code
20
+ * @returns Binding code object or null if not found/expired
21
+ */
22
+ getBindingCode(code: string): BindingCode | null;
23
+ /**
24
+ * Delete binding code
25
+ * @param code Binding code
26
+ */
27
+ deleteBindingCode(code: string): void;
28
+ /**
29
+ * Set user binding
30
+ * @param openId Feishu user open_id
31
+ * @param binding User binding object
32
+ */
33
+ setUserBinding(openId: string, binding: UserBinding): void;
34
+ /**
35
+ * Get user binding
36
+ * @param openId Feishu user open_id
37
+ * @returns User binding or null if not found
38
+ */
39
+ getUserBinding(openId: string): UserBinding | null;
40
+ /**
41
+ * Get device binding
42
+ * @param deviceId Device unique identifier
43
+ * @returns User binding or null if not found
44
+ */
45
+ getDeviceBinding(deviceId: string): UserBinding | null;
46
+ /**
47
+ * Delete user binding
48
+ * @param openId Feishu user open_id
49
+ */
50
+ deleteUserBinding(openId: string): void;
51
+ /**
52
+ * Update user last active time
53
+ * @param openId Feishu user open_id
54
+ */
55
+ updateLastActive(openId: string): void;
56
+ /**
57
+ * Clear all data
58
+ */
59
+ clear(): void;
60
+ /**
61
+ * Get statistics
62
+ */
63
+ getStats(): {
64
+ bindingCodes: number;
65
+ userBindings: number;
66
+ deviceBindings: number;
67
+ };
68
+ }
69
+ //# sourceMappingURL=MemoryStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryStore.d.ts","sourceRoot":"","sources":["../../src/storage/MemoryStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEpD;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,cAAc,CAAuC;IAE7D;;;;;OAKG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAShF;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAgBhD;;;OAGG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIrC;;;;OAIG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAK1D;;;;OAIG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAIlD;;;;OAIG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAItD;;;OAGG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQvC;;;OAGG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAStC;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,QAAQ,IAAI;QACV,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;KACxB;CAOF"}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MemoryStore = void 0;
4
+ /**
5
+ * In-memory storage for bindings
6
+ * Replaces Redis for low-concurrency scenarios
7
+ */
8
+ class MemoryStore {
9
+ bindingCodes = new Map();
10
+ userBindings = new Map();
11
+ deviceBindings = new Map();
12
+ /**
13
+ * Store binding code with expiration
14
+ * @param code Binding code
15
+ * @param bindingCode Binding code object
16
+ * @param ttlSeconds Time to live in seconds
17
+ */
18
+ setBindingCode(code, bindingCode, ttlSeconds) {
19
+ this.bindingCodes.set(code, bindingCode);
20
+ // Auto-expire after TTL
21
+ setTimeout(() => {
22
+ this.bindingCodes.delete(code);
23
+ }, ttlSeconds * 1000);
24
+ }
25
+ /**
26
+ * Get binding code
27
+ * @param code Binding code
28
+ * @returns Binding code object or null if not found/expired
29
+ */
30
+ getBindingCode(code) {
31
+ const bindingCode = this.bindingCodes.get(code);
32
+ if (!bindingCode) {
33
+ return null;
34
+ }
35
+ // Check if expired
36
+ if (Date.now() > bindingCode.expiresAt) {
37
+ this.bindingCodes.delete(code);
38
+ return null;
39
+ }
40
+ return bindingCode;
41
+ }
42
+ /**
43
+ * Delete binding code
44
+ * @param code Binding code
45
+ */
46
+ deleteBindingCode(code) {
47
+ this.bindingCodes.delete(code);
48
+ }
49
+ /**
50
+ * Set user binding
51
+ * @param openId Feishu user open_id
52
+ * @param binding User binding object
53
+ */
54
+ setUserBinding(openId, binding) {
55
+ this.userBindings.set(openId, binding);
56
+ this.deviceBindings.set(binding.deviceId, binding);
57
+ }
58
+ /**
59
+ * Get user binding
60
+ * @param openId Feishu user open_id
61
+ * @returns User binding or null if not found
62
+ */
63
+ getUserBinding(openId) {
64
+ return this.userBindings.get(openId) || null;
65
+ }
66
+ /**
67
+ * Get device binding
68
+ * @param deviceId Device unique identifier
69
+ * @returns User binding or null if not found
70
+ */
71
+ getDeviceBinding(deviceId) {
72
+ return this.deviceBindings.get(deviceId) || null;
73
+ }
74
+ /**
75
+ * Delete user binding
76
+ * @param openId Feishu user open_id
77
+ */
78
+ deleteUserBinding(openId) {
79
+ const binding = this.userBindings.get(openId);
80
+ if (binding) {
81
+ this.userBindings.delete(openId);
82
+ this.deviceBindings.delete(binding.deviceId);
83
+ }
84
+ }
85
+ /**
86
+ * Update user last active time
87
+ * @param openId Feishu user open_id
88
+ */
89
+ updateLastActive(openId) {
90
+ const binding = this.userBindings.get(openId);
91
+ if (binding) {
92
+ binding.lastActiveAt = Date.now();
93
+ this.userBindings.set(openId, binding);
94
+ this.deviceBindings.set(binding.deviceId, binding);
95
+ }
96
+ }
97
+ /**
98
+ * Clear all data
99
+ */
100
+ clear() {
101
+ this.bindingCodes.clear();
102
+ this.userBindings.clear();
103
+ this.deviceBindings.clear();
104
+ }
105
+ /**
106
+ * Get statistics
107
+ */
108
+ getStats() {
109
+ return {
110
+ bindingCodes: this.bindingCodes.size,
111
+ userBindings: this.userBindings.size,
112
+ deviceBindings: this.deviceBindings.size,
113
+ };
114
+ }
115
+ }
116
+ exports.MemoryStore = MemoryStore;
117
+ //# sourceMappingURL=MemoryStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryStore.js","sourceRoot":"","sources":["../../src/storage/MemoryStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Router server configuration types
3
+ */
4
+ export interface RouterConfig {
5
+ server: ServerConfig;
6
+ feishu: FeishuConfig;
7
+ websocket: WebSocketConfig;
8
+ security: SecurityConfig;
9
+ }
10
+ export interface ServerConfig {
11
+ port: number;
12
+ host: string;
13
+ nodeEnv: 'development' | 'production';
14
+ }
15
+ export interface FeishuConfig {
16
+ appId: string;
17
+ appSecret: string;
18
+ encryptKey?: string;
19
+ verificationToken?: string;
20
+ }
21
+ export interface WebSocketConfig {
22
+ heartbeatInterval: number;
23
+ reconnectDelay: number;
24
+ }
25
+ export interface SecurityConfig {
26
+ bindingCodeExpiry: number;
27
+ maxBindingAttempts: number;
28
+ }
29
+ /**
30
+ * Default configuration values
31
+ */
32
+ export declare const DEFAULT_CONFIG: {
33
+ server: {
34
+ port: number;
35
+ host: string;
36
+ nodeEnv: "production";
37
+ };
38
+ feishu: {
39
+ appId: string;
40
+ appSecret: string;
41
+ encryptKey: string;
42
+ verificationToken: string;
43
+ };
44
+ websocket: {
45
+ heartbeatInterval: number;
46
+ reconnectDelay: number;
47
+ };
48
+ security: {
49
+ bindingCodeExpiry: number;
50
+ maxBindingAttempts: number;
51
+ };
52
+ };
53
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,aAAa,GAAG,YAAY,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;CAoB1B,CAAC"}
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ /**
3
+ * Router server configuration types
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_CONFIG = void 0;
7
+ /**
8
+ * Default configuration values
9
+ */
10
+ exports.DEFAULT_CONFIG = {
11
+ server: {
12
+ port: 3000,
13
+ host: '0.0.0.0',
14
+ nodeEnv: 'production',
15
+ },
16
+ feishu: {
17
+ appId: '',
18
+ appSecret: '',
19
+ encryptKey: '',
20
+ verificationToken: '',
21
+ },
22
+ websocket: {
23
+ heartbeatInterval: 15000,
24
+ reconnectDelay: 5000,
25
+ },
26
+ security: {
27
+ bindingCodeExpiry: 300000, // 5 minutes
28
+ maxBindingAttempts: 5,
29
+ },
30
+ };
31
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAgCH;;GAEG;AACU,QAAA,cAAc,GAAG;IAC5B,MAAM,EAAE;QACN,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,YAAqB;KAC/B;IACD,MAAM,EAAE;QACN,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,EAAE;QACd,iBAAiB,EAAE,EAAE;KACtB;IACD,SAAS,EAAE;QACT,iBAAiB,EAAE,KAAK;QACxB,cAAc,EAAE,IAAI;KACrB;IACD,QAAQ,EAAE;QACR,iBAAiB,EAAE,MAAM,EAAE,YAAY;QACvC,kBAAkB,EAAE,CAAC;KACtB;CACF,CAAC"}