@krischoichoi/channel-dingtalk 0.6.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/README.md +139 -0
- package/lib/adapter.d.ts +123 -0
- package/lib/adapter.d.ts.map +1 -0
- package/lib/adapter.js +355 -0
- package/lib/adapter.js.map +1 -0
- package/lib/ai-card.d.ts +64 -0
- package/lib/ai-card.d.ts.map +1 -0
- package/lib/ai-card.js +150 -0
- package/lib/ai-card.js.map +1 -0
- package/lib/auth/device-registration.d.ts +18 -0
- package/lib/auth/device-registration.d.ts.map +1 -0
- package/lib/auth/device-registration.js +147 -0
- package/lib/auth/device-registration.js.map +1 -0
- package/lib/config.d.ts +119 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +75 -0
- package/lib/config.js.map +1 -0
- package/lib/definition.d.ts +53 -0
- package/lib/definition.d.ts.map +1 -0
- package/lib/definition.js +227 -0
- package/lib/definition.js.map +1 -0
- package/lib/image-hydrator.d.ts +213 -0
- package/lib/image-hydrator.d.ts.map +1 -0
- package/lib/image-hydrator.js +244 -0
- package/lib/image-hydrator.js.map +1 -0
- package/lib/inbound.d.ts +38 -0
- package/lib/inbound.d.ts.map +1 -0
- package/lib/inbound.js +158 -0
- package/lib/inbound.js.map +1 -0
- package/lib/index.d.ts +49 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +123 -0
- package/lib/index.js.map +1 -0
- package/lib/manifest.d.ts +23 -0
- package/lib/manifest.d.ts.map +1 -0
- package/lib/manifest.js +34 -0
- package/lib/manifest.js.map +1 -0
- package/lib/mapper.d.ts +36 -0
- package/lib/mapper.d.ts.map +1 -0
- package/lib/mapper.js +175 -0
- package/lib/mapper.js.map +1 -0
- package/lib/media-mime.d.ts +14 -0
- package/lib/media-mime.d.ts.map +1 -0
- package/lib/media-mime.js +32 -0
- package/lib/media-mime.js.map +1 -0
- package/lib/official-upstream.d.ts +143 -0
- package/lib/official-upstream.d.ts.map +1 -0
- package/lib/official-upstream.js +425 -0
- package/lib/official-upstream.js.map +1 -0
- package/lib/openapi-port.d.ts +190 -0
- package/lib/openapi-port.d.ts.map +1 -0
- package/lib/openapi-port.js +2 -0
- package/lib/openapi-port.js.map +1 -0
- package/lib/outbound.d.ts +69 -0
- package/lib/outbound.d.ts.map +1 -0
- package/lib/outbound.js +148 -0
- package/lib/outbound.js.map +1 -0
- package/lib/stream-upstream.d.ts +77 -0
- package/lib/stream-upstream.d.ts.map +1 -0
- package/lib/stream-upstream.js +303 -0
- package/lib/stream-upstream.js.map +1 -0
- package/lib/transport.d.ts +37 -0
- package/lib/transport.d.ts.map +1 -0
- package/lib/transport.js +73 -0
- package/lib/transport.js.map +1 -0
- package/lib/upstream.d.ts +60 -0
- package/lib/upstream.d.ts.map +1 -0
- package/lib/upstream.js +61 -0
- package/lib/upstream.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface HttpRequestInit {
|
|
2
|
+
method?: string;
|
|
3
|
+
body?: unknown;
|
|
4
|
+
headers?: Record<string, string>;
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
/**
|
|
7
|
+
* Raw binary body (media upload). When set, `body` is ignored and `raw` is
|
|
8
|
+
* sent verbatim with `contentType` (default `application/octet-stream`).
|
|
9
|
+
*/
|
|
10
|
+
raw?: Uint8Array | string;
|
|
11
|
+
/** Content-Type to send alongside a `raw` binary body. */
|
|
12
|
+
contentType?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Response decoding. `'json'` (default) parses the response body as JSON;
|
|
15
|
+
* `'arraybuffer'` returns the raw bytes as a `Uint8Array` (media download,
|
|
16
|
+
* where the body is binary and not JSON).
|
|
17
|
+
*/
|
|
18
|
+
responseType?: 'json' | 'arraybuffer';
|
|
19
|
+
}
|
|
20
|
+
export interface HttpTransport {
|
|
21
|
+
request(path: string, init?: HttpRequestInit, signal?: AbortSignal): Promise<unknown>;
|
|
22
|
+
}
|
|
23
|
+
export interface FetchTransportOptions {
|
|
24
|
+
/** Request timeout; overridden per-request by `init.timeoutMs`. */
|
|
25
|
+
timeoutMs: number;
|
|
26
|
+
/** Injectable fetch (tests). */
|
|
27
|
+
fetchImpl?: typeof fetch;
|
|
28
|
+
}
|
|
29
|
+
/** Default transport backed by the standard `fetch`. */
|
|
30
|
+
export declare class FetchTransport implements HttpTransport {
|
|
31
|
+
private readonly timeoutMs;
|
|
32
|
+
private readonly fetchImpl;
|
|
33
|
+
constructor(baseUrl: string, options: FetchTransportOptions);
|
|
34
|
+
private readonly baseUrl;
|
|
35
|
+
request(path: string, init?: HttpRequestInit, signal?: AbortSignal): Promise<unknown>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,GAAG,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;CACvC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvF;AAED,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,wDAAwD;AACxD,qBAAa,cAAe,YAAW,aAAa;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB;IAM3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAE3B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CAwDhG"}
|
package/lib/transport.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP transport boundary.
|
|
3
|
+
*
|
|
4
|
+
* The transport is the single injection point for tests: the adapter is built
|
|
5
|
+
* against `HttpTransport`, and a fake transport replaces the network without
|
|
6
|
+
* touching driver logic. Timeouts abort the underlying fetch; an external
|
|
7
|
+
* `signal` is combined with the request timeout.
|
|
8
|
+
*/
|
|
9
|
+
import { ChannelError } from '@krischoichoi/channel-core';
|
|
10
|
+
/** Default transport backed by the standard `fetch`. */
|
|
11
|
+
export class FetchTransport {
|
|
12
|
+
timeoutMs;
|
|
13
|
+
fetchImpl;
|
|
14
|
+
constructor(baseUrl, options) {
|
|
15
|
+
this.baseUrl = baseUrl.replace(/\/+$/, '');
|
|
16
|
+
this.timeoutMs = options.timeoutMs;
|
|
17
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
18
|
+
}
|
|
19
|
+
baseUrl;
|
|
20
|
+
async request(path, init = {}, signal) {
|
|
21
|
+
const controller = new AbortController();
|
|
22
|
+
const timeoutMs = init.timeoutMs ?? this.timeoutMs;
|
|
23
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
24
|
+
const onOuterAbort = () => controller.abort();
|
|
25
|
+
signal?.addEventListener('abort', onOuterAbort, { once: true });
|
|
26
|
+
try {
|
|
27
|
+
const url = /^https?:\/\//i.test(path) ? path : `${this.baseUrl}${path}`;
|
|
28
|
+
const headers = { ...init.headers };
|
|
29
|
+
// `FormData` is passed through untouched so fetch creates the multipart
|
|
30
|
+
// boundary. JSON and legacy raw bytes retain their existing paths.
|
|
31
|
+
const body = init.raw !== undefined
|
|
32
|
+
? (typeof init.raw === 'string' ? init.raw : new Uint8Array(init.raw.buffer, init.raw.byteOffset, init.raw.byteLength))
|
|
33
|
+
: init.body instanceof FormData
|
|
34
|
+
? init.body
|
|
35
|
+
: init.body !== undefined
|
|
36
|
+
? JSON.stringify(init.body)
|
|
37
|
+
: undefined;
|
|
38
|
+
if (init.raw !== undefined) {
|
|
39
|
+
headers['content-type'] = init.contentType ?? 'application/octet-stream';
|
|
40
|
+
}
|
|
41
|
+
else if (init.body !== undefined && !(init.body instanceof FormData)) {
|
|
42
|
+
headers['content-type'] = headers['content-type'] ?? 'application/json';
|
|
43
|
+
}
|
|
44
|
+
const response = await this.fetchImpl(url, {
|
|
45
|
+
method: init.method ?? 'GET',
|
|
46
|
+
headers,
|
|
47
|
+
body,
|
|
48
|
+
signal: controller.signal,
|
|
49
|
+
});
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
const detail = (await response.text()).replace(/\s+/g, ' ').slice(0, 500);
|
|
52
|
+
throw new ChannelError('CHANNEL_ERROR', `dingtalk http ${response.status} on ${path}${detail ? `: ${detail}` : ''}`);
|
|
53
|
+
}
|
|
54
|
+
if (init.responseType === 'arraybuffer') {
|
|
55
|
+
const buffer = await response.arrayBuffer();
|
|
56
|
+
return new Uint8Array(buffer);
|
|
57
|
+
}
|
|
58
|
+
const text = await response.text();
|
|
59
|
+
return text ? JSON.parse(text) : undefined;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof ChannelError)
|
|
63
|
+
throw error;
|
|
64
|
+
const aborted = error?.name === 'AbortError' || controller.signal.aborted;
|
|
65
|
+
throw new ChannelError('CHANNEL_ERROR', aborted ? `dingtalk http aborted on ${path}` : `dingtalk http failed on ${path}`, { cause: error });
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
clearTimeout(timer);
|
|
69
|
+
signal?.removeEventListener('abort', onOuterAbort);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DingTalk HTTP upstream driver — the only module that knows the HTTP
|
|
3
|
+
* endpoints (self-hosted gateway protocol).
|
|
4
|
+
*
|
|
5
|
+
* Two drivers implement the shared `DingTalkUpstream` interface:
|
|
6
|
+
* - `HttpDingTalkUpstream` (this file) — long-poll inbound + HTTP outbound
|
|
7
|
+
* against the self-hosted gateway. The gateway owns platform credentials;
|
|
8
|
+
* the adapter never sees or logs them (architecture §21 / red line 3).
|
|
9
|
+
* - `DingTalkStreamUpstream` (stream-upstream.ts) — inbound via the official
|
|
10
|
+
* `dingtalk-stream` SDK; outbound delegates to a separately injected driver.
|
|
11
|
+
* - `DingTalkOpenApiPortImpl` (official-upstream.ts) — SDK-mode outbound via
|
|
12
|
+
* the message-scoped webhook, AI Card OpenAPI, and proactive/media OAPI.
|
|
13
|
+
*
|
|
14
|
+
* Endpoints (protocol-level, self-hosted gateway):
|
|
15
|
+
* - GET /stream — long-poll for inbound payloads
|
|
16
|
+
* - POST /message/send — plain text message (non-streaming fallback)
|
|
17
|
+
* - POST /card/create — create an AI Card with initial content
|
|
18
|
+
* - POST /card/update — update the card body (status 'update')
|
|
19
|
+
* - POST /card/finish — finalize the card (status 'finished')
|
|
20
|
+
* - POST /card/fail — mark the card failed (status 'failed')
|
|
21
|
+
*/
|
|
22
|
+
import type { ChannelTarget } from '@krischoichoi/channel-core';
|
|
23
|
+
import type { HttpTransport } from './transport.js';
|
|
24
|
+
/** Card create response: the gateway-issued card id. */
|
|
25
|
+
export interface CardCreateResult {
|
|
26
|
+
cardId: string;
|
|
27
|
+
}
|
|
28
|
+
export interface DingTalkUpstream {
|
|
29
|
+
/**
|
|
30
|
+
* Long-poll for inbound messages until `signal` aborts. Each raw message is
|
|
31
|
+
* passed to `onMessage` as received (unstructured — the mapper owns shape).
|
|
32
|
+
*/
|
|
33
|
+
receive(signal: AbortSignal, onMessage: (raw: unknown) => void): Promise<void>;
|
|
34
|
+
/** Send a plain text message (buffered fallback). */
|
|
35
|
+
sendText(target: ChannelTarget, text: string): Promise<unknown>;
|
|
36
|
+
/** Create an AI Card in the given conversation with initial content. */
|
|
37
|
+
createCard(target: ChannelTarget, text: string): Promise<CardCreateResult>;
|
|
38
|
+
/** Update an AI Card's body text. */
|
|
39
|
+
updateCard(cardId: string, text: string): Promise<unknown>;
|
|
40
|
+
/** Finalize an AI Card. */
|
|
41
|
+
finishCard(cardId: string, text?: string): Promise<unknown>;
|
|
42
|
+
/** Mark an AI Card as failed, optionally with a reason. */
|
|
43
|
+
failCard(cardId: string, reason?: string): Promise<unknown>;
|
|
44
|
+
}
|
|
45
|
+
export interface HttpDingTalkUpstreamOptions {
|
|
46
|
+
transport: HttpTransport;
|
|
47
|
+
longPollTimeoutMs: number;
|
|
48
|
+
}
|
|
49
|
+
/** HTTP implementation over a self-hosted dingtalk gateway. */
|
|
50
|
+
export declare class HttpDingTalkUpstream implements DingTalkUpstream {
|
|
51
|
+
private readonly options;
|
|
52
|
+
constructor(options: HttpDingTalkUpstreamOptions);
|
|
53
|
+
receive(signal: AbortSignal, onMessage: (raw: unknown) => void): Promise<void>;
|
|
54
|
+
sendText(target: ChannelTarget, text: string): Promise<unknown>;
|
|
55
|
+
createCard(target: ChannelTarget, text: string): Promise<CardCreateResult>;
|
|
56
|
+
updateCard(cardId: string, text: string): Promise<unknown>;
|
|
57
|
+
finishCard(cardId: string): Promise<unknown>;
|
|
58
|
+
failCard(cardId: string, reason?: string): Promise<unknown>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=upstream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstream.d.ts","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,OAAO,CACL,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,GAChC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhE,wEAAwE;IACxE,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE3E,qCAAqC;IACrC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3D,2BAA2B;IAC3B,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5D,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,aAAa,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,+DAA+D;AAC/D,qBAAa,oBAAqB,YAAW,gBAAgB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,2BAA2B;IAE3D,OAAO,CACX,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,GAChC,OAAO,CAAC,IAAI,CAAC;IAqBhB,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO/D,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAY1E,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO1D,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO5C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAM5D"}
|
package/lib/upstream.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** HTTP implementation over a self-hosted dingtalk gateway. */
|
|
2
|
+
export class HttpDingTalkUpstream {
|
|
3
|
+
options;
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.options = options;
|
|
6
|
+
}
|
|
7
|
+
async receive(signal, onMessage) {
|
|
8
|
+
while (!signal.aborted) {
|
|
9
|
+
let raw;
|
|
10
|
+
try {
|
|
11
|
+
raw = await this.options.transport.request('/stream', { timeoutMs: this.options.longPollTimeoutMs }, signal);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
// Abort-driven teardown exits gracefully; other failures propagate to
|
|
15
|
+
// the adapter, which owns reconnect/backoff.
|
|
16
|
+
if (signal.aborted)
|
|
17
|
+
return;
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
20
|
+
if (raw && typeof raw === 'object' && !signal.aborted) {
|
|
21
|
+
onMessage(raw);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
sendText(target, text) {
|
|
26
|
+
return this.options.transport.request('/message/send', {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
body: { to: target.conversationId, type: 'text', content: text },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
createCard(target, text) {
|
|
32
|
+
return this.options.transport
|
|
33
|
+
.request('/card/create', {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
body: { conversationId: target.conversationId, text },
|
|
36
|
+
})
|
|
37
|
+
.then((raw) => {
|
|
38
|
+
const payload = raw;
|
|
39
|
+
return { cardId: payload.cardId ?? '' };
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
updateCard(cardId, text) {
|
|
43
|
+
return this.options.transport.request('/card/update', {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
body: { cardId, text },
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
finishCard(cardId) {
|
|
49
|
+
return this.options.transport.request('/card/finish', {
|
|
50
|
+
method: 'POST',
|
|
51
|
+
body: { cardId },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
failCard(cardId, reason) {
|
|
55
|
+
return this.options.transport.request('/card/fail', {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
body: { cardId, reason },
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=upstream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upstream.js","sourceRoot":"","sources":["../src/upstream.ts"],"names":[],"mappings":"AA4DA,+DAA+D;AAC/D,MAAM,OAAO,oBAAoB;IACF;IAA7B,YAA6B,OAAoC;QAApC,YAAO,GAAP,OAAO,CAA6B;IAAG,CAAC;IAErE,KAAK,CAAC,OAAO,CACX,MAAmB,EACnB,SAAiC;QAEjC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,IAAI,GAAY,CAAC;YACjB,IAAI,CAAC;gBACH,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CACxC,SAAS,EACT,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAC7C,MAAM,CACP,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,sEAAsE;gBACtE,6CAA6C;gBAC7C,IAAI,MAAM,CAAC,OAAO;oBAAE,OAAO;gBAC3B,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACtD,SAAS,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,MAAqB,EAAE,IAAY;QAC1C,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE;YACrD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;SACjE,CAAC,CAAC;IACL,CAAC;IAED,UAAU,CAAC,MAAqB,EAAE,IAAY;QAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS;aAC1B,OAAO,CAAC,cAAc,EAAE;YACvB,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,IAAI,EAAE;SACtD,CAAC;aACD,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YACZ,MAAM,OAAO,GAAG,GAAgC,CAAC;YACjD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC1C,CAAC,CAAC,CAAC;IACP,CAAC;IAED,UAAU,CAAC,MAAc,EAAE,IAAY;QACrC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;SACvB,CAAC,CAAC;IACL,CAAC;IAED,UAAU,CAAC,MAAc;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,EAAE,MAAM,EAAE;SACjB,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,MAAc,EAAE,MAAe;QACtC,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE;YAClD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;SACzB,CAAC,CAAC;IACL,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@krischoichoi/channel-dingtalk",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/krischoichoi/dsh-channels.git"
|
|
7
|
+
},
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"description": "DingTalk channel adapter for DeepSeek Harness (AI Card streaming, edit strategy)",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"main": "./lib/index.js",
|
|
14
|
+
"types": "./lib/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./lib/index.d.ts",
|
|
18
|
+
"default": "./lib/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./package.json": "./package.json"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"lib"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.json",
|
|
27
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
28
|
+
"test": "vitest run --passWithNoTests",
|
|
29
|
+
"clean": "rimraf lib"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@deepseek-ai/cordis": "^4.0.4",
|
|
33
|
+
"@deepseek-ai/dsh-credentials": "0.2.0-rc.2",
|
|
34
|
+
"@deepseek-ai/dsh-settings": "0.2.0-rc.2",
|
|
35
|
+
"@deepseek-ai/schemastery": "~3.18.4",
|
|
36
|
+
"@krischoichoi/channel-control": "workspace:*",
|
|
37
|
+
"@krischoichoi/channel-core": "workspace:*",
|
|
38
|
+
"dingtalk-stream": "2.1.5",
|
|
39
|
+
"zod": "^4.4.3"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@krischoichoi/channel-testkit": "workspace:*",
|
|
43
|
+
"rimraf": "^6.0.0"
|
|
44
|
+
},
|
|
45
|
+
"license": "MIT"
|
|
46
|
+
}
|