@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.
Files changed (70) hide show
  1. package/README.md +139 -0
  2. package/lib/adapter.d.ts +123 -0
  3. package/lib/adapter.d.ts.map +1 -0
  4. package/lib/adapter.js +355 -0
  5. package/lib/adapter.js.map +1 -0
  6. package/lib/ai-card.d.ts +64 -0
  7. package/lib/ai-card.d.ts.map +1 -0
  8. package/lib/ai-card.js +150 -0
  9. package/lib/ai-card.js.map +1 -0
  10. package/lib/auth/device-registration.d.ts +18 -0
  11. package/lib/auth/device-registration.d.ts.map +1 -0
  12. package/lib/auth/device-registration.js +147 -0
  13. package/lib/auth/device-registration.js.map +1 -0
  14. package/lib/config.d.ts +119 -0
  15. package/lib/config.d.ts.map +1 -0
  16. package/lib/config.js +75 -0
  17. package/lib/config.js.map +1 -0
  18. package/lib/definition.d.ts +53 -0
  19. package/lib/definition.d.ts.map +1 -0
  20. package/lib/definition.js +227 -0
  21. package/lib/definition.js.map +1 -0
  22. package/lib/image-hydrator.d.ts +213 -0
  23. package/lib/image-hydrator.d.ts.map +1 -0
  24. package/lib/image-hydrator.js +244 -0
  25. package/lib/image-hydrator.js.map +1 -0
  26. package/lib/inbound.d.ts +38 -0
  27. package/lib/inbound.d.ts.map +1 -0
  28. package/lib/inbound.js +158 -0
  29. package/lib/inbound.js.map +1 -0
  30. package/lib/index.d.ts +49 -0
  31. package/lib/index.d.ts.map +1 -0
  32. package/lib/index.js +123 -0
  33. package/lib/index.js.map +1 -0
  34. package/lib/manifest.d.ts +23 -0
  35. package/lib/manifest.d.ts.map +1 -0
  36. package/lib/manifest.js +34 -0
  37. package/lib/manifest.js.map +1 -0
  38. package/lib/mapper.d.ts +36 -0
  39. package/lib/mapper.d.ts.map +1 -0
  40. package/lib/mapper.js +175 -0
  41. package/lib/mapper.js.map +1 -0
  42. package/lib/media-mime.d.ts +14 -0
  43. package/lib/media-mime.d.ts.map +1 -0
  44. package/lib/media-mime.js +32 -0
  45. package/lib/media-mime.js.map +1 -0
  46. package/lib/official-upstream.d.ts +143 -0
  47. package/lib/official-upstream.d.ts.map +1 -0
  48. package/lib/official-upstream.js +425 -0
  49. package/lib/official-upstream.js.map +1 -0
  50. package/lib/openapi-port.d.ts +190 -0
  51. package/lib/openapi-port.d.ts.map +1 -0
  52. package/lib/openapi-port.js +2 -0
  53. package/lib/openapi-port.js.map +1 -0
  54. package/lib/outbound.d.ts +69 -0
  55. package/lib/outbound.d.ts.map +1 -0
  56. package/lib/outbound.js +148 -0
  57. package/lib/outbound.js.map +1 -0
  58. package/lib/stream-upstream.d.ts +77 -0
  59. package/lib/stream-upstream.d.ts.map +1 -0
  60. package/lib/stream-upstream.js +303 -0
  61. package/lib/stream-upstream.js.map +1 -0
  62. package/lib/transport.d.ts +37 -0
  63. package/lib/transport.d.ts.map +1 -0
  64. package/lib/transport.js +73 -0
  65. package/lib/transport.js.map +1 -0
  66. package/lib/upstream.d.ts +60 -0
  67. package/lib/upstream.d.ts.map +1 -0
  68. package/lib/upstream.js +61 -0
  69. package/lib/upstream.js.map +1 -0
  70. package/package.json +46 -0
@@ -0,0 +1,53 @@
1
+ /**
2
+ * DingTalkChannelDefinition — the universal Control Plane spec for DingTalk.
3
+ *
4
+ * Advertises the channel's setup surface (AppKey as a plain text field, the
5
+ * AppSecret as a credentialed secret field pointing at
6
+ * `DSH_CHANNEL_DINGTALK_MAIN_CLIENT_SECRET`), reports configured state by
7
+ * combining config + the credentials seam, persists non-secret config patches
8
+ * into an internal snapshot, and builds the adapter — resolving SDK-mode
9
+ * credentials through the injected credentials seam and injecting them as
10
+ * `deps.clientSecret` (mirrors channel-qq deps.appSecret).
11
+ *
12
+ * The view is fully offline-testable: pass a fake credentials seam and fake
13
+ * transport/sdkClient via deps. No secret value ever leaves the seam.
14
+ */
15
+ import { type ChannelDefinition } from '@krischoichoi/channel-control';
16
+ import type { DingTalkConfig } from './config.js';
17
+ import { type DingTalkAdapterDeps } from './adapter.js';
18
+ /** Structural credential seam (matches the channel-control CredentialSeam). */
19
+ export interface DingTalkCredentialSeam {
20
+ resolve(ref: string): Promise<{
21
+ value: string;
22
+ source: string;
23
+ } | undefined>;
24
+ describe(ref: string): Promise<{
25
+ configured: boolean;
26
+ writable: boolean;
27
+ source?: string;
28
+ }>;
29
+ set(ref: string, value: string): Promise<void>;
30
+ }
31
+ export interface DingTalkDefinitionOptions {
32
+ config: DingTalkConfig;
33
+ deps: DingTalkAdapterDeps;
34
+ /** The injected ctx.credentials seam (never the secret values themselves). */
35
+ credentials: DingTalkCredentialSeam;
36
+ /** Durable store for the non-secret setup field when the host provides one. */
37
+ persistSetup?: (patch: {
38
+ upstream: Pick<DingTalkConfig['upstream'], 'clientId'>;
39
+ }) => Promise<void>;
40
+ /** Durable store for the enabled intent (doc §21) when the host provides one. */
41
+ persistEnabled?: (enabled: boolean) => Promise<void>;
42
+ /** Reconcile the runtime after device registration writes new credentials. */
43
+ onAuthCompleted?: () => Promise<void>;
44
+ }
45
+ /**
46
+ * Official DingTalk developer console (open-dev) — one-step entry to the app
47
+ * list, not the marketing homepage. When the app's clientId is known the link
48
+ * deep-links to that app (`#/app?clientId=`), mirroring openclaw-toolkit.
49
+ */
50
+ export declare const DINGTALK_OPEN_PLATFORM_URL = "https://open-dev.dingtalk.com";
51
+ export declare function dingtalkConsoleUrl(clientId: string | undefined): string;
52
+ export declare function createDingTalkDefinition(options: DingTalkDefinitionOptions): ChannelDefinition;
53
+ //# sourceMappingURL=definition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,KAAK,iBAAiB,EAIvB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAAE,cAAc,EAA0B,MAAM,aAAa,CAAC;AAE1E,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAOzE,+EAA+E;AAC/E,MAAM,WAAW,sBAAsB;IACrC,OAAO,CACL,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IAC1D,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5F,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,cAAc,CAAC;IACvB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,8EAA8E;IAC9E,WAAW,EAAE,sBAAsB,CAAC;IACpC,+EAA+E;IAC/E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpG,iFAAiF;IACjF,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,8EAA8E;IAC9E,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAeD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,kCAAkC,CAAC;AAE1E,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKvE;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,iBAAiB,CAiI9F"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * DingTalkChannelDefinition — the universal Control Plane spec for DingTalk.
3
+ *
4
+ * Advertises the channel's setup surface (AppKey as a plain text field, the
5
+ * AppSecret as a credentialed secret field pointing at
6
+ * `DSH_CHANNEL_DINGTALK_MAIN_CLIENT_SECRET`), reports configured state by
7
+ * combining config + the credentials seam, persists non-secret config patches
8
+ * into an internal snapshot, and builds the adapter — resolving SDK-mode
9
+ * credentials through the injected credentials seam and injecting them as
10
+ * `deps.clientSecret` (mirrors channel-qq deps.appSecret).
11
+ *
12
+ * The view is fully offline-testable: pass a fake credentials seam and fake
13
+ * transport/sdkClient via deps. No secret value ever leaves the seam.
14
+ */
15
+ import {} from '@krischoichoi/channel-control';
16
+ import { ControlError } from '@krischoichoi/channel-control';
17
+ import { DINGTALK_CLIENT_SECRET_REF } from './config.js';
18
+ import { DingTalkAdapter } from './adapter.js';
19
+ import { resolveVolatileConfig } from '@krischoichoi/channel-core';
20
+ import { beginDingTalkDeviceAuth, pollDingTalkDeviceAuth, } from './auth/device-registration.js';
21
+ /** Non-secret config keys accepted by saveConfig (deep-merged sub-objects). */
22
+ const SAVABLE_KEYS = [
23
+ 'baseUrl',
24
+ 'timeoutMs',
25
+ 'longPollTimeoutMs',
26
+ 'reconnect',
27
+ 'dedup',
28
+ 'card',
29
+ 'accountId',
30
+ 'upstream.mode',
31
+ 'upstream.clientId',
32
+ ];
33
+ /**
34
+ * Official DingTalk developer console (open-dev) — one-step entry to the app
35
+ * list, not the marketing homepage. When the app's clientId is known the link
36
+ * deep-links to that app (`#/app?clientId=`), mirroring openclaw-toolkit.
37
+ */
38
+ export const DINGTALK_OPEN_PLATFORM_URL = 'https://open-dev.dingtalk.com';
39
+ export function dingtalkConsoleUrl(clientId) {
40
+ const id = clientId?.trim();
41
+ return id
42
+ ? `${DINGTALK_OPEN_PLATFORM_URL}/#/app?clientId=${encodeURIComponent(id)}`
43
+ : `${DINGTALK_OPEN_PLATFORM_URL}/#/app`;
44
+ }
45
+ export function createDingTalkDefinition(options) {
46
+ const { config, deps, credentials } = options;
47
+ // Internal mutable snapshot that saveConfig patches and createAdapter reads,
48
+ // so the control plane can persist changes without rewriting plugin config.
49
+ const state = cloneConfig(config);
50
+ const clientSecretRef = () => state.upstream.clientSecretRef ?? DINGTALK_CLIENT_SECRET_REF;
51
+ const setup = {
52
+ fields: [
53
+ { name: 'clientId', kind: 'text', secret: false, configured: Boolean(state.upstream.clientId), writable: true },
54
+ { name: 'clientSecret', kind: 'secret', secret: true, configured: false, writable: true, ref: clientSecretRef() },
55
+ ],
56
+ authMethods: ['device', 'credentials'],
57
+ setupUrl: dingtalkConsoleUrl(state.upstream.clientId),
58
+ };
59
+ const refreshSetup = () => {
60
+ setup.fields = [
61
+ { name: 'clientId', kind: 'text', secret: false, configured: Boolean(state.upstream.clientId), writable: true },
62
+ { name: 'clientSecret', kind: 'secret', secret: true, configured: false, writable: true, ref: clientSecretRef() },
63
+ ];
64
+ setup.setupUrl = dingtalkConsoleUrl(state.upstream.clientId);
65
+ };
66
+ const saveConfig = async (patch) => {
67
+ applyPatch(state, patch);
68
+ refreshSetup();
69
+ if (patch.clientId !== undefined || isPlainObject(patch.upstream) && patch.upstream.clientId !== undefined) {
70
+ await options.persistSetup?.({ upstream: { clientId: state.upstream.clientId } });
71
+ }
72
+ };
73
+ return {
74
+ id: 'dingtalk',
75
+ get enabled() {
76
+ return state.enabled;
77
+ },
78
+ async setEnabled(enabled) {
79
+ state.enabled = enabled;
80
+ await options.persistEnabled?.(enabled);
81
+ },
82
+ setup,
83
+ async getConfiguredState() {
84
+ if (state.upstream.mode === 'gateway') {
85
+ const baseUrlConfigured = Boolean(state.baseUrl);
86
+ const fields = {
87
+ clientId: { configured: false, writable: true },
88
+ clientSecret: { configured: false, writable: true },
89
+ baseUrl: { configured: baseUrlConfigured, writable: true },
90
+ };
91
+ return { configured: baseUrlConfigured, fields };
92
+ }
93
+ // SDK mode: configured when clientId is set and the secret credential is configured.
94
+ const clientIdConfigured = Boolean(state.upstream.clientId);
95
+ const secretDescribed = await credentials.describe(clientSecretRef());
96
+ const fields = {
97
+ clientId: { configured: clientIdConfigured, writable: true, value: state.upstream.clientId },
98
+ clientSecret: {
99
+ configured: secretDescribed.configured,
100
+ writable: secretDescribed.writable,
101
+ source: secretDescribed.source,
102
+ },
103
+ };
104
+ return { configured: clientIdConfigured && secretDescribed.configured, fields };
105
+ },
106
+ saveConfig,
107
+ async beginAuth(input) {
108
+ if (input.method !== 'device') {
109
+ throw new ControlError('AUTH_NOT_SUPPORTED', 'dingtalk supports device authorization or credentials setup');
110
+ }
111
+ return beginDingTalkDeviceAuth({
112
+ baseUrl: process.env.DINGTALK_REGISTRATION_BASE_URL,
113
+ source: process.env.DINGTALK_REGISTRATION_SOURCE,
114
+ });
115
+ },
116
+ async pollAuth(session) {
117
+ const result = await pollDingTalkDeviceAuth(session);
118
+ if (result.credentials) {
119
+ await credentials.set(clientSecretRef(), result.credentials.clientSecret);
120
+ await saveConfig({ clientId: result.credentials.clientId });
121
+ await options.onAuthCompleted?.();
122
+ }
123
+ return result.status;
124
+ },
125
+ snapshotConfig: () => cloneConfig(state),
126
+ async restoreConfig(saved) {
127
+ const restored = cloneConfig(saved);
128
+ Object.assign(state, restored);
129
+ state.reconnect = restored.reconnect;
130
+ state.dedup = restored.dedup;
131
+ state.card = restored.card;
132
+ state.upstream = restored.upstream;
133
+ refreshSetup();
134
+ await options.persistSetup?.({ upstream: { clientId: state.upstream.clientId } });
135
+ },
136
+ async createAdapter() {
137
+ let resolvedSecret;
138
+ if (state.upstream.mode === 'sdk') {
139
+ const ref = clientSecretRef();
140
+ const credential = await credentials.resolve(ref);
141
+ resolvedSecret = credential?.value;
142
+ if (!resolvedSecret) {
143
+ throw new Error(`dingtalk credential "${ref}" is not configured`);
144
+ }
145
+ }
146
+ const adapterDeps = resolvedSecret ? { ...deps, clientSecret: resolvedSecret } : deps;
147
+ return new DingTalkAdapter(state, adapterDeps);
148
+ },
149
+ autoStart: true,
150
+ // The official robot callback supplies `isInAtList`; the stream upstream
151
+ // validates and forwards it as `message.activation.mentionedBot`.
152
+ access: {
153
+ directMessages: true,
154
+ groups: true,
155
+ mentions: true,
156
+ ownerDiscovery: 'claim',
157
+ identityLabels: { user: 'DingTalk Sender ID', group: 'DingTalk Conversation ID' },
158
+ defaults: { requireMention: true },
159
+ },
160
+ };
161
+ }
162
+ function cloneConfig(config) {
163
+ // Harness 0.2.0: volatile fields arrive as `Volatile<T>` handles; unwrap
164
+ // them once so the snapshot (and everything reading it) sees plain values.
165
+ const plain = resolveVolatileConfig(config);
166
+ return {
167
+ ...plain,
168
+ reconnect: { ...plain.reconnect },
169
+ dedup: { ...plain.dedup },
170
+ card: { ...plain.card },
171
+ upstream: { ...plain.upstream },
172
+ };
173
+ }
174
+ /**
175
+ * Deep-merge a non-secret config patch into a mutable snapshot. Accepts both
176
+ * the flat dotted form (`upstream.mode`) and the nested object form
177
+ * (`upstream: { mode }`); sub-objects (reconnect/dedup/card/upstream) are
178
+ * merged shallowly so a partial patch updates only the supplied keys. Secret
179
+ * values are intentionally never accepted here.
180
+ */
181
+ function applyPatch(state, patch) {
182
+ for (const key of Object.keys(patch)) {
183
+ const value = patch[key];
184
+ if (value === undefined)
185
+ continue;
186
+ if (key === 'reconnect' && isPlainObject(value)) {
187
+ Object.assign(state.reconnect, value);
188
+ }
189
+ else if (key === 'dedup' && isPlainObject(value)) {
190
+ Object.assign(state.dedup, value);
191
+ }
192
+ else if (key === 'card' && isPlainObject(value)) {
193
+ Object.assign(state.card, value);
194
+ }
195
+ else if (key === 'upstream' && isPlainObject(value)) {
196
+ mergeUpstream(state.upstream, value);
197
+ }
198
+ else if (key === 'upstream.mode' && (value === 'sdk' || value === 'gateway')) {
199
+ state.upstream.mode = value;
200
+ }
201
+ else if (key === 'upstream.clientId' && typeof value === 'string') {
202
+ state.upstream.clientId = value;
203
+ }
204
+ else if (key === 'clientId' && typeof value === 'string') {
205
+ // Web setup fields use a flat, user-facing name; the runtime config
206
+ // keeps the value under upstream.
207
+ state.upstream.clientId = value;
208
+ }
209
+ else if (SAVABLE_KEYS.includes(key)) {
210
+ state[key] = value;
211
+ }
212
+ // Unknown / secret keys are silently ignored (the control plane rejects
213
+ // secret field names before reaching us; this is a final safety net).
214
+ }
215
+ }
216
+ function mergeUpstream(upstream, patch) {
217
+ if (patch.mode !== undefined)
218
+ upstream.mode = patch.mode;
219
+ if (patch.clientId !== undefined)
220
+ upstream.clientId = patch.clientId;
221
+ if (patch.clientSecretRef !== undefined)
222
+ upstream.clientSecretRef = patch.clientSecretRef;
223
+ }
224
+ function isPlainObject(value) {
225
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
226
+ }
227
+ //# sourceMappingURL=definition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition.js","sourceRoot":"","sources":["../src/definition.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,213 @@
1
+ /**
2
+ * DingTalk inbound image/file/media hydration.
3
+ *
4
+ * After the pure mapper (`mapInbound`) produces the stable `MessageReceived`
5
+ * shape, this module walks the binary parts and turns a genuine `http(s)`
6
+ * locator into trusted bytes on the part itself:
7
+ *
8
+ * ```text
9
+ * ImagePart.url (real http(s) URL)
10
+ * -> SecureRemoteMediaFetcher.fetchBounded()
11
+ * -> ImagePart.localData + mimeType
12
+ * -> existing Harness saveImage()/ImageBlock path (host owns that)
13
+ * ```
14
+ *
15
+ * Audio/video parts (`hydrateMedia`) follow the identical
16
+ * URL-or-opaque rule: a genuine http(s) URL is fetched through the secure
17
+ * fetcher; an opaque handle (downloadCode / mediaId) is moved to
18
+ * `resourceRef` and resolved through the official DingTalk OpenAPI port —
19
+ * `POST /v1.0/robot/messageFiles/download { downloadCode, robotCode }` returns
20
+ * a `downloadUrl`, which is then fetched as bounded bytes (the same seam the
21
+ * official connector oracle `@dingtalk-real-ai/dingtalk-connector@0.8.24`
22
+ * uses for voice/video).
23
+ *
24
+ * This module performs NO platform-protocol implementation. It only calls the
25
+ * shared secure host boundary (`@krischoichoi/channel-core` `SecureRemoteMediaFetcher`)
26
+ * — it never re-implements DingTalk download logic.
27
+ *
28
+ * Failure handling: a download failure never blocks text
29
+ * delivery. On failure we KEEP the original locator, stamp a stable
30
+ * de-identified `ingressFailure` code on the part (mapped through the core
31
+ * `toIngressFailureCode` seam) and let the message continue to emit unaltered.
32
+ *
33
+ * mediaId/opaque handle handling: DingTalk modern robot picture
34
+ * messages deliver a real `picture.url` (see `stream-upstream.ts` →
35
+ * `picUrl`), so the common ingress is the URL path above. If a part carries
36
+ * an opaque locator instead (a `mediaId` that is not a genuine http(s) URL),
37
+ * we move it to `resourceRef` and do NOT attempt a generic fetch — resolving
38
+ * an opaque handle is exclusively the platform upstream job and is left to
39
+ * the `DingTalkOpenApiPort.resolveMedia(...)` milestone (§32A). We never
40
+ * invent an HTTP downloader for a mediaId.
41
+ */
42
+ import type { MessagePart } from '@krischoichoi/channel-core';
43
+ import { SecureRemoteMediaFetcher, type BinaryIngressFailureCode, type FetchBoundedResult } from '@krischoichoi/channel-core';
44
+ import type { MediaResolverLike } from './openapi-port.js';
45
+ /** Default hard byte cap for a downloaded image (20 MiB). */
46
+ export declare const IMAGE_MAX_BYTES: number;
47
+ /** Default read-idle timeout (no body chunk for N ms -> fail). */
48
+ export declare const IMAGE_IDLE_TIMEOUT_MS = 15000;
49
+ /**
50
+ * One image part locator classified by the hydrator. A genuine http(s) URL is
51
+ * fetched; an opaque locator (e.g. a bare mediaId) is deferred to the OpenAPI
52
+ * resolution path and never fetched.
53
+ */
54
+ export interface ResolvedImageLocator {
55
+ kind: 'http-url' | 'opaque';
56
+ /** Part array index (for diagnostics). */
57
+ index: number;
58
+ /** The locator string that will be fetched / deferred. */
59
+ locator: string;
60
+ }
61
+ /**
62
+ * Identify the http(s)-fetchable image parts in a message content. Opaque
63
+ * (non-http) locators are surfaced separately so the ingestion policy can
64
+ * route them to `resourceRef`.
65
+ */
66
+ export declare function findFetchableImages(parts: readonly MessagePart[]): ResolvedImageLocator[];
67
+ /**
68
+ * Structural sub-surface of `SecureRemoteMediaFetcher` the hydrator depends
69
+ * on — lets tests inject a plain fake fetcher without a real global `fetch`.
70
+ */
71
+ export interface RemoteMediaFetchLike {
72
+ fetchBounded(url: string, options: {
73
+ maxBytes: number;
74
+ idleTimeoutMs?: number;
75
+ timeoutMs?: number;
76
+ allowHttp?: boolean;
77
+ signal?: AbortSignal;
78
+ }): Promise<FetchBoundedResult>;
79
+ }
80
+ /** Options for one hydration pass over a message content parts. */
81
+ export interface HydrateImagesOptions {
82
+ /**
83
+ * The secure remote media fetcher. Injectable for offline tests; defaults to
84
+ * a real `SecureRemoteMediaFetcher` bound to the global `fetch`.
85
+ */
86
+ secureFetch?: SecureRemoteMediaFetcher | RemoteMediaFetchLike;
87
+ /** Abort signal threaded from the adapter context for prompt teardown. */
88
+ signal?: AbortSignal;
89
+ /** Hard byte cap per image (default 20 MiB). */
90
+ maxBytes?: number;
91
+ /** Read-idle timeout ms (default 15s). */
92
+ idleTimeoutMs?: number;
93
+ /**
94
+ * DingTalk OpenAPI media resolver used to turn an opaque image handle
95
+ * (picMediaId / downloadCode) into trusted bytes. Injectable for
96
+ * offline tests; when absent, opaque handles stay on `resourceRef` and are
97
+ * left unresolved (the message still delivers, as a text placeholder).
98
+ */
99
+ resolveMedia?: MediaResolverLike;
100
+ /**
101
+ * Per-message download context from the inbound callback (official schema):
102
+ * the `downloadCode` (and `robotCode`) the official
103
+ * `/v1.0/robot/messageFiles/download` API needs. Transient upstream state —
104
+ * never persisted into core parts.
105
+ */
106
+ downloadContext?: {
107
+ downloadCode?: string;
108
+ robotCode?: string;
109
+ };
110
+ /** Diagnostic callback; receives the original error without changing delivery. */
111
+ onFailure?: (error: unknown, part: MessagePart) => void;
112
+ }
113
+ /**
114
+ * Hydrate image parts in place: mutate `parts` so every image with a genuine
115
+ * http(s) URL carries `localData` + `mimeType` (preferring the fetcher MIME
116
+ * type) on success, and `ingressFailure` on failure. Opaque locators are
117
+ * moved to `resourceRef` and left unresolved (OpenAPI milestone).
118
+ *
119
+ * This never throws and never blocks text delivery — any image failure only
120
+ * annotates the part.
121
+ */
122
+ export declare function hydrateImages(parts: MessagePart[], options?: HydrateImagesOptions): Promise<void>;
123
+ /** Default hard byte cap for a downloaded generic file (50 MiB). */
124
+ export declare const FILE_MAX_BYTES: number;
125
+ /**
126
+ * Options for one generic-file hydration pass.
127
+ * @extends HydrateImagesOptions
128
+ */
129
+ export interface HydrateFilesOptions {
130
+ /**
131
+ * The secure remote media fetcher used for genuine http(s) file URLs.
132
+ * Injectable for offline tests; defaults to a real `SecureRemoteMediaFetcher`.
133
+ */
134
+ secureFetch?: SecureRemoteMediaFetcher | RemoteMediaFetchLike;
135
+ /**
136
+ * The OpenAPI media resolver used to turn an opaque file mediaId into trusted
137
+ * bytes. Injectable for offline tests. When absent, opaque file
138
+ * handles are deferred to `resourceRef` and left unresolved.
139
+ */
140
+ resolveMedia?: MediaResolverLike;
141
+ /** Abort signal threaded from the adapter context for prompt teardown. */
142
+ signal?: AbortSignal;
143
+ /** Hard byte cap per file (default 50 MiB). */
144
+ maxBytes?: number;
145
+ /** Read-idle timeout ms (default 15s). */
146
+ idleTimeoutMs?: number;
147
+ /**
148
+ * Per-message download context (official schema): `downloadCode` +
149
+ * `robotCode` for the official /v1.0/robot/messageFiles/download API.
150
+ * Transient upstream state — never persisted onto core parts.
151
+ */
152
+ downloadContext?: {
153
+ downloadCode?: string;
154
+ robotCode?: string;
155
+ };
156
+ }
157
+ /**
158
+ * Hydrate generic file parts in place:
159
+ * - http(s) url -> SecureRemoteMediaFetcher -> `localData` + `mimeType` + `size`
160
+ * - opaque mediaId -> move to `resourceRef` -> `resolveMedia` -> `localData`
161
+ * On failure the original locator is kept and a stable `ingressFailure` is
162
+ * stamped — this never throws and never blocks text delivery.
163
+ */
164
+ export declare function hydrateFiles(parts: MessagePart[], options?: HydrateFilesOptions): Promise<void>;
165
+ /** Default hard byte cap for a downloaded audio/video resource (100 MiB). */
166
+ export declare const MEDIA_MAX_BYTES: number;
167
+ /**
168
+ * Options for one audio/video hydration pass.
169
+ * @extends HydrateFilesOptions
170
+ */
171
+ export interface HydrateMediaOptions {
172
+ /**
173
+ * The secure remote media fetcher used for genuine http(s) audio/video URLs.
174
+ * Injectable for offline tests; defaults to a real `SecureRemoteMediaFetcher`.
175
+ */
176
+ secureFetch?: SecureRemoteMediaFetcher | RemoteMediaFetchLike;
177
+ /**
178
+ * The OpenAPI media resolver used to turn an opaque audio/video handle
179
+ * (downloadCode / mediaId) into trusted bytes. Injectable for
180
+ * offline tests. When absent, opaque handles stay on `resourceRef`.
181
+ */
182
+ resolveMedia?: MediaResolverLike;
183
+ /** Abort signal threaded from the adapter context for prompt teardown. */
184
+ signal?: AbortSignal;
185
+ /** Hard byte cap per audio/video resource (default 100 MiB). */
186
+ maxBytes?: number;
187
+ /** Read-idle timeout ms (default 15s). */
188
+ idleTimeoutMs?: number;
189
+ /**
190
+ * Per-message download context (official schema): `downloadCode` +
191
+ * `robotCode` for the official /v1.0/robot/messageFiles/download API.
192
+ * Transient upstream state — never persisted onto core parts.
193
+ */
194
+ downloadContext?: {
195
+ downloadCode?: string;
196
+ robotCode?: string;
197
+ };
198
+ }
199
+ /**
200
+ * Hydrate audio/video parts in place. Audio/video follow the
201
+ * exact same URL-or-opaque resolution as image/file:
202
+ * - http(s) url -> SecureRemoteMediaFetcher -> `localData` + `mimeType` + `size`
203
+ * - opaque handle -> move to `resourceRef` -> `resolveMedia` (official
204
+ * `messageFiles/download` seam) -> `localData`
205
+ * The apply step delegates to core `applyHydrationResult`, so success clears
206
+ * `ingressFailure`, failures write ONLY a stable `ingressFailure` (never
207
+ * fabricating bytes), and this never throws / never blocks text delivery.
208
+ */
209
+ export declare function hydrateMedia(parts: MessagePart[], options?: HydrateMediaOptions): Promise<void>;
210
+ /** Convenience factory returning a real secure fetcher bound to global fetch. */
211
+ export declare function defaultSecureFetcher(): SecureRemoteMediaFetcher;
212
+ export type { BinaryIngressFailureCode };
213
+ //# sourceMappingURL=image-hydrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-hydrator.d.ts","sourceRoot":"","sources":["../src/image-hydrator.ts"],"names":[],"mappings":"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"}