@clowder-ai/connector-feishu 0.0.0-stage → 0.1.0-alpha.8

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 (78) hide show
  1. package/README.en.md +54 -0
  2. package/README.md +25 -2
  3. package/assets/icon.svg +3 -0
  4. package/dist/FeishuAdapter.d.ts +250 -0
  5. package/dist/FeishuAdapter.d.ts.map +1 -0
  6. package/dist/FeishuAdapter.js +845 -0
  7. package/dist/FeishuAdapter.js.map +1 -0
  8. package/dist/FeishuQrBindClient.d.ts +23 -0
  9. package/dist/FeishuQrBindClient.d.ts.map +1 -0
  10. package/dist/FeishuQrBindClient.js +97 -0
  11. package/dist/FeishuQrBindClient.js.map +1 -0
  12. package/dist/FeishuTokenManager.d.ts +15 -0
  13. package/dist/FeishuTokenManager.d.ts.map +1 -0
  14. package/dist/FeishuTokenManager.js +35 -0
  15. package/dist/FeishuTokenManager.js.map +1 -0
  16. package/dist/command-ingress.d.ts +10 -0
  17. package/dist/command-ingress.d.ts.map +1 -0
  18. package/dist/command-ingress.js +15 -0
  19. package/dist/command-ingress.js.map +1 -0
  20. package/dist/execution-status.d.ts +27 -0
  21. package/dist/execution-status.d.ts.map +1 -0
  22. package/dist/execution-status.js +48 -0
  23. package/dist/execution-status.js.map +1 -0
  24. package/dist/feishu-card-formatter.d.ts +18 -0
  25. package/dist/feishu-card-formatter.d.ts.map +1 -0
  26. package/dist/feishu-card-formatter.js +58 -0
  27. package/dist/feishu-card-formatter.js.map +1 -0
  28. package/dist/inbound-download.d.ts +13 -0
  29. package/dist/inbound-download.d.ts.map +1 -0
  30. package/dist/inbound-download.js +70 -0
  31. package/dist/inbound-download.js.map +1 -0
  32. package/dist/inbound-media-source.d.ts +25 -0
  33. package/dist/inbound-media-source.d.ts.map +1 -0
  34. package/dist/inbound-media-source.js +111 -0
  35. package/dist/inbound-media-source.js.map +1 -0
  36. package/dist/index.d.ts +9 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +5 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/lifecycle-action.d.ts +30 -0
  41. package/dist/lifecycle-action.d.ts.map +1 -0
  42. package/dist/lifecycle-action.js +457 -0
  43. package/dist/lifecycle-action.js.map +1 -0
  44. package/dist/materialize-media.d.ts +7 -0
  45. package/dist/materialize-media.d.ts.map +1 -0
  46. package/dist/materialize-media.js +35 -0
  47. package/dist/materialize-media.js.map +1 -0
  48. package/dist/media-notice.d.ts +6 -0
  49. package/dist/media-notice.d.ts.map +1 -0
  50. package/dist/media-notice.js +50 -0
  51. package/dist/media-notice.js.map +1 -0
  52. package/dist/plugin-entrypoint.d.ts +9 -0
  53. package/dist/plugin-entrypoint.d.ts.map +1 -0
  54. package/dist/plugin-entrypoint.js +347 -0
  55. package/dist/plugin-entrypoint.js.map +1 -0
  56. package/dist/reply-sender-map.d.ts +10 -0
  57. package/dist/reply-sender-map.d.ts.map +1 -0
  58. package/dist/reply-sender-map.js +123 -0
  59. package/dist/reply-sender-map.js.map +1 -0
  60. package/dist/runtime.d.ts +190 -0
  61. package/dist/runtime.d.ts.map +1 -0
  62. package/dist/runtime.js +580 -0
  63. package/dist/runtime.js.map +1 -0
  64. package/dist/settings.d.ts +20 -0
  65. package/dist/settings.d.ts.map +1 -0
  66. package/dist/settings.js +35 -0
  67. package/dist/settings.js.map +1 -0
  68. package/dist/thread-mappings.d.ts +46 -0
  69. package/dist/thread-mappings.d.ts.map +1 -0
  70. package/dist/thread-mappings.js +62 -0
  71. package/dist/thread-mappings.js.map +1 -0
  72. package/dist/types.d.ts +54 -0
  73. package/dist/types.d.ts.map +1 -0
  74. package/dist/types.js +7 -0
  75. package/dist/types.js.map +1 -0
  76. package/npm-shrinkwrap.json +979 -0
  77. package/package.json +58 -4
  78. package/plugin.yaml +128 -0
@@ -0,0 +1,123 @@
1
+ const KEY_PREFIX = 'reply-sender:';
2
+ const ENTRY_TTL_MS = 24 * 60 * 60 * 1000;
3
+ const SWEEP_EVERY_RECORDS = 50;
4
+ const ENTRY_CAP = 2000;
5
+ function object(value) {
6
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
7
+ }
8
+ function errorName(error) {
9
+ return error instanceof Error ? error.name : 'unknown';
10
+ }
11
+ function parseEntry(value) {
12
+ if (typeof value !== 'string')
13
+ return undefined;
14
+ let parsed;
15
+ try {
16
+ parsed = JSON.parse(value);
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ if (!object(parsed) || parsed.version !== 1 || typeof parsed.storedAt !== 'number')
22
+ return undefined;
23
+ const candidate = parsed.sender;
24
+ if (!object(candidate) || typeof candidate.id !== 'string' || candidate.id.length === 0)
25
+ return undefined;
26
+ return {
27
+ version: 1,
28
+ storedAt: parsed.storedAt,
29
+ sender: {
30
+ id: candidate.id,
31
+ ...(typeof candidate.name === 'string' ? { name: candidate.name } : {}),
32
+ },
33
+ };
34
+ }
35
+ export function createReplySenderMap(context) {
36
+ let recordedSinceSweep = 0;
37
+ let sweepInFlight = false;
38
+ const sweep = async () => {
39
+ let listed;
40
+ try {
41
+ listed = await context.storage.list();
42
+ }
43
+ catch (error) {
44
+ context.log('warn', 'Connector reply-sender mapping sweep failed', { errorName: errorName(error) });
45
+ return;
46
+ }
47
+ const now = Date.now();
48
+ const live = [];
49
+ for (const [key, item] of Object.entries(listed)) {
50
+ if (!key.startsWith(KEY_PREFIX))
51
+ continue;
52
+ const entry = parseEntry(item?.value);
53
+ if (entry === undefined || entry.storedAt + ENTRY_TTL_MS < now) {
54
+ await context.storage.delete(key).catch(() => undefined);
55
+ continue;
56
+ }
57
+ live.push({ key, storedAt: entry.storedAt });
58
+ }
59
+ live.sort((a, b) => a.storedAt - b.storedAt);
60
+ let overflow = live.length - (ENTRY_CAP - 1);
61
+ for (let index = 0; overflow > 0 && index < live.length; index += 1, overflow -= 1) {
62
+ await context.storage.delete(live[index].key).catch(() => undefined);
63
+ }
64
+ };
65
+ // Sweep single-flight in the background: recording stays on the inbound
66
+ // hot path and overlapping bursts never stack sweeps. sweep() already
67
+ // swallows and logs its own storage failures. context.log is intentionally
68
+ // NOT used here: log() runs assertActive() and throws
69
+ // FeatureContextRevokedError after stop/revoke, so a sweep racing feature
70
+ // shutdown would turn into an unhandled rejection; console.warn is the
71
+ // reviewer-sanctioned exception that stays callable past revocation.
72
+ const sweepInBackground = () => {
73
+ if (sweepInFlight)
74
+ return;
75
+ sweepInFlight = true;
76
+ void sweep()
77
+ .catch((error) => {
78
+ console.warn('Connector reply-sender mapping sweep failed', { errorName: errorName(error) });
79
+ })
80
+ .finally(() => {
81
+ sweepInFlight = false;
82
+ });
83
+ };
84
+ return {
85
+ async record(hostMessageId, replySender) {
86
+ const now = Date.now();
87
+ try {
88
+ await context.storage.set(`${KEY_PREFIX}${hostMessageId}`, JSON.stringify({ version: 1, sender: replySender, storedAt: now }));
89
+ }
90
+ catch (error) {
91
+ context.log('warn', 'Connector reply-sender mapping record failed', { errorName: errorName(error) });
92
+ return;
93
+ }
94
+ recordedSinceSweep += 1;
95
+ if (recordedSinceSweep < SWEEP_EVERY_RECORDS)
96
+ return;
97
+ recordedSinceSweep = 0;
98
+ sweepInBackground();
99
+ },
100
+ async resolve(hostMessageId) {
101
+ if (hostMessageId === undefined)
102
+ return undefined;
103
+ const key = `${KEY_PREFIX}${hostMessageId}`;
104
+ let stored;
105
+ try {
106
+ stored = await context.storage.get(key);
107
+ }
108
+ catch (error) {
109
+ context.log('warn', 'Connector reply-sender mapping lookup failed', { errorName: errorName(error) });
110
+ return undefined;
111
+ }
112
+ const entry = parseEntry(stored?.value);
113
+ if (entry === undefined)
114
+ return undefined;
115
+ if (entry.storedAt + ENTRY_TTL_MS < Date.now()) {
116
+ await context.storage.delete(key).catch(() => undefined);
117
+ return undefined;
118
+ }
119
+ return entry.sender;
120
+ },
121
+ };
122
+ }
123
+ //# sourceMappingURL=reply-sender-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reply-sender-map.js","sourceRoot":"","sources":["../src/reply-sender-map.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,190 @@
1
+ import * as lark from '@larksuiteoapi/node-sdk';
2
+ import { FeishuAdapter, type FeishuAdapterOptions } from './FeishuAdapter.js';
3
+ import { FeishuTokenManager } from './FeishuTokenManager.js';
4
+ import type { ConnectorLogger } from './types.js';
5
+ export interface FeishuRuntimeConfig {
6
+ readonly appId: string;
7
+ readonly appSecret: string;
8
+ readonly connectionMode: 'webhook' | 'websocket';
9
+ readonly verificationToken?: string;
10
+ readonly groupBotMentionsJson?: string;
11
+ }
12
+ export interface FeishuWebhookInput {
13
+ readonly body?: unknown;
14
+ }
15
+ export type FeishuWebhookResult = Readonly<{
16
+ kind: 'challenge';
17
+ response: Readonly<{
18
+ challenge: string;
19
+ }>;
20
+ }> | Readonly<{
21
+ kind: 'processed';
22
+ messageId: string;
23
+ }> | Readonly<{
24
+ kind: 'skipped';
25
+ reason: string;
26
+ }> | Readonly<{
27
+ kind: 'error';
28
+ status: number;
29
+ message: string;
30
+ }>;
31
+ export interface FeishuHostInboundMessage {
32
+ readonly externalConversationId: string;
33
+ readonly providerMessageId: string;
34
+ /** Provider sender identity for admission; independent of group reply attribution. */
35
+ readonly externalSenderId?: string;
36
+ readonly text: string;
37
+ readonly attachments?: readonly Readonly<{
38
+ type: 'image' | 'file' | 'audio';
39
+ platformKey: string;
40
+ fileName?: string;
41
+ duration?: number;
42
+ }>[];
43
+ readonly sender?: Readonly<{
44
+ id: string;
45
+ name?: string;
46
+ }>;
47
+ readonly conversation: Readonly<{
48
+ type: 'direct' | 'group';
49
+ title?: string;
50
+ }>;
51
+ }
52
+ export interface FeishuRuntimeHost {
53
+ deliver(message: FeishuHostInboundMessage): Promise<void>;
54
+ }
55
+ export interface FeishuRuntimeAdapter {
56
+ readonly connectorId: string;
57
+ isVerificationChallenge: FeishuAdapter['isVerificationChallenge'];
58
+ verifyEventToken: FeishuAdapter['verifyEventToken'];
59
+ parseEvent: FeishuAdapter['parseEvent'];
60
+ parseCardAction: FeishuAdapter['parseCardAction'];
61
+ resolveSenderName: FeishuAdapter['resolveSenderName'];
62
+ resolveSenderNameFromChat: FeishuAdapter['resolveSenderNameFromChat'];
63
+ resolveChatName: FeishuAdapter['resolveChatName'];
64
+ resolveChatType: FeishuAdapter['resolveChatType'];
65
+ setBotOpenId: FeishuAdapter['setBotOpenId'];
66
+ sendFormattedReply: FeishuAdapter['sendFormattedReply'];
67
+ sendMedia: FeishuAdapter['sendMedia'];
68
+ sendReply: FeishuAdapter['sendReply'];
69
+ _injectTokenManager?(manager: FeishuTokenManager): void;
70
+ }
71
+ interface FeishuWsClient {
72
+ start(options: {
73
+ eventDispatcher: lark.EventDispatcher;
74
+ }): Promise<void>;
75
+ close(options?: {
76
+ force?: boolean;
77
+ }): void;
78
+ }
79
+ /** SDK internals the teardown guard needs (verified against @larksuiteoapi/node-sdk 1.59.0). */
80
+ interface LarkWsInternals {
81
+ start(options: {
82
+ eventDispatcher: lark.EventDispatcher;
83
+ }): Promise<void>;
84
+ close(options?: {
85
+ force?: boolean;
86
+ }): void;
87
+ pingLoop(): void;
88
+ /**
89
+ * Instance flag the SDK sets true while a connect attempt is in flight and
90
+ * false once it settles (es/index.js reConnect finally, ~line 85412). With
91
+ * `autoReconnect: false` a failed attempt logs 'connect failed' and returns
92
+ * without touching the registered socket, so this flag is the observable
93
+ * termination signal for fail-fast start.
94
+ */
95
+ isConnecting?: boolean;
96
+ wsConfig: {
97
+ getWSInstance(): unknown;
98
+ setWSInstance(ws: unknown): void;
99
+ };
100
+ }
101
+ export interface PausableLarkWsClientHooks {
102
+ /**
103
+ * Invoked when the open socket emits 'close' without a stop() in flight.
104
+ * The lark SDK cannot be trusted to surface this itself: with
105
+ * `autoReconnect: false` its close handler returns before clearing the
106
+ * registered socket (es/index.js ~85422), leaving a dead socket in the
107
+ * registry with no callback. Reconnect supervision therefore lives here.
108
+ */
109
+ readonly onClose?: () => void;
110
+ }
111
+ /**
112
+ * F2/F3: the lark WSClient cannot cancel a connection that is still
113
+ * handshaking — `close()` only touches the socket registered after 'open',
114
+ * so a stop() landing pre-open would leave an authenticated socket that
115
+ * starts pingLoop and self-reconnects forever (an orphan nobody can kill).
116
+ *
117
+ * This facade makes teardown deterministic:
118
+ * - `close()` terminates the current socket AND installs a birth guard that
119
+ * terminates any socket the SDK opens afterwards, plus a pingLoop no-op so
120
+ * a late 'open' cannot restart the ping timer.
121
+ * - `start()` does not settle until the SDK has registered an open socket
122
+ * (lark `WSClient.start()` resolves in the same tick it kicks off
123
+ * `reConnect(true)`, so without this the runtime would report `running`
124
+ * before anything is connected), or aborts on stop/timeout/SDK give-up.
125
+ * - after `start()` settles, the open socket's 'close' event drives the
126
+ * optional `onClose` hook (suppressed when `close()` initiated it), so the
127
+ * runtime can drop out of 'running' and schedule a reconnect instead of
128
+ * reporting a dead connection as live.
129
+ *
130
+ * `autoReconnect: false` is deliberate: SDK-owned reconnection was the F2
131
+ * revival mechanism. Reconnect supervision belongs to the Host lifecycle.
132
+ */
133
+ export declare class PausableLarkWsClient implements FeishuWsClient {
134
+ private readonly inner;
135
+ private readonly hooks;
136
+ private stopped;
137
+ constructor(appId: string, appSecret: string, inner?: LarkWsInternals, hooks?: PausableLarkWsClientHooks);
138
+ start(options: {
139
+ eventDispatcher: lark.EventDispatcher;
140
+ }): Promise<void>;
141
+ private watchSocketClose;
142
+ close(): void;
143
+ }
144
+ export interface FeishuConnectorRuntime<Adapter extends FeishuRuntimeAdapter = FeishuAdapter> {
145
+ readonly outbound: Adapter;
146
+ start(): Promise<void>;
147
+ stop(): Promise<void>;
148
+ handleWebhook(input: FeishuWebhookInput): Promise<FeishuWebhookResult>;
149
+ /** Rebuild the provider connection in-process with new credentials and start ingress. */
150
+ connect(config: Readonly<{
151
+ appId: string;
152
+ appSecret: string;
153
+ connectionMode: 'webhook' | 'websocket';
154
+ }>): Promise<void>;
155
+ /** Close the in-process ingress (WebSocket/reconnect timers); configuration values untouched. */
156
+ disconnect(): Promise<void>;
157
+ /** True when the provider ingress is live (webhook mode armed counts as connected once started). */
158
+ isConnected(): boolean;
159
+ /**
160
+ * Live connection facts for the `feishu.test` operation. The activation-time
161
+ * config/secrets snapshot goes stale once `connect()` adopts QR credentials
162
+ * in-process, so readiness must be derived from runtime state only.
163
+ */
164
+ status(): {
165
+ connectionMode: 'webhook' | 'websocket';
166
+ hasVerificationToken: boolean;
167
+ connected: boolean;
168
+ };
169
+ }
170
+ export interface FeishuConnectorRuntimeOptions<Adapter extends FeishuRuntimeAdapter = FeishuAdapter> {
171
+ readonly config: FeishuRuntimeConfig;
172
+ readonly host: FeishuRuntimeHost;
173
+ readonly logger: ConnectorLogger;
174
+ readonly fetchFn?: typeof fetch;
175
+ readonly createAdapter?: (appId: string, appSecret: string, logger: ConnectorLogger, options: FeishuAdapterOptions) => Adapter;
176
+ readonly createWsClient?: (config: Readonly<{
177
+ appId: string;
178
+ appSecret: string;
179
+ /** Unexpected-close notification; see PausableLarkWsClientHooks. */
180
+ onClose?: () => void;
181
+ }>) => FeishuWsClient;
182
+ /** Base delay of the reconnect backoff (default 5s); doubles per attempt. */
183
+ readonly reconnectDelayMs?: number;
184
+ /** Cap of the reconnect backoff (default 60s). */
185
+ readonly reconnectMaxDelayMs?: number;
186
+ }
187
+ export declare function requireFeishuWebhookInput(candidate: unknown): FeishuWebhookInput;
188
+ export declare function createFeishuConnectorRuntime<Adapter extends FeishuRuntimeAdapter = FeishuAdapter>(options: FeishuConnectorRuntimeOptions<Adapter>): FeishuConnectorRuntime<Adapter>;
189
+ export {};
190
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}