spectrum-ts 4.1.0 → 5.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 (46) hide show
  1. package/README.md +29 -67
  2. package/dist/authoring.d.ts +1 -6
  3. package/dist/authoring.js +2 -36
  4. package/dist/elysia.d.ts +1 -0
  5. package/dist/elysia.js +2 -0
  6. package/dist/express.d.ts +1 -0
  7. package/dist/express.js +2 -0
  8. package/dist/hono.d.ts +1 -0
  9. package/dist/hono.js +2 -0
  10. package/dist/index.d.ts +1 -2837
  11. package/dist/index.js +2 -3373
  12. package/dist/manifest.json +5 -5
  13. package/dist/providers/imessage/index.d.ts +1 -222
  14. package/dist/providers/imessage/index.js +2 -25
  15. package/dist/providers/index.d.ts +6 -19
  16. package/dist/providers/index.js +6 -34
  17. package/dist/providers/slack/index.d.ts +1 -46
  18. package/dist/providers/slack/index.js +2 -11
  19. package/dist/providers/telegram/index.d.ts +1 -45
  20. package/dist/providers/telegram/index.js +2 -13
  21. package/dist/providers/terminal/index.d.ts +1 -119
  22. package/dist/providers/terminal/index.js +2 -13
  23. package/dist/providers/whatsapp-business/index.d.ts +1 -27
  24. package/dist/providers/whatsapp-business/index.js +2 -14
  25. package/package.json +23 -26
  26. package/dist/attachment-CnivEhr6.d.ts +0 -29
  27. package/dist/authoring-b9AhXgPI.d.ts +0 -304
  28. package/dist/chunk-2D27WW5B.js +0 -63
  29. package/dist/chunk-34FQGGD7.js +0 -34
  30. package/dist/chunk-3GEJYGZK.js +0 -84
  31. package/dist/chunk-3KWFP4L2.js +0 -864
  32. package/dist/chunk-5XEFJBN2.js +0 -197
  33. package/dist/chunk-6UZFVXQF.js +0 -374
  34. package/dist/chunk-A37PM5N2.js +0 -91
  35. package/dist/chunk-B52VPQO3.js +0 -1379
  36. package/dist/chunk-DMT6BFJV.js +0 -2980
  37. package/dist/chunk-FAIFTUV2.js +0 -139
  38. package/dist/chunk-IM5ADDZS.js +0 -887
  39. package/dist/chunk-LZXPLXZF.js +0 -35
  40. package/dist/chunk-U3QQ56YZ.js +0 -929
  41. package/dist/chunk-UXAKIXVM.js +0 -409
  42. package/dist/chunk-WXLQNANA.js +0 -539
  43. package/dist/chunk-ZR3TKZMT.js +0 -129
  44. package/dist/read-C4uvozGX.d.ts +0 -53
  45. package/dist/types-BIta6Kxi.d.ts +0 -82
  46. package/dist/types-CyfLJXgu.d.ts +0 -1530
@@ -1,409 +0,0 @@
1
- import { createRequire as __spectrumCreateRequire } from "node:module"; const require = __spectrumCreateRequire(import.meta.url);
2
-
3
- // src/content/attachment.ts
4
- import { randomUUID } from "crypto";
5
- import { createReadStream } from "fs";
6
- import { readFile, stat } from "fs/promises";
7
- import { basename } from "path";
8
- import { Readable } from "stream";
9
- import { lookup as lookupMimeType } from "mime-types";
10
- import z2 from "zod";
11
-
12
- // src/utils/io.ts
13
- import z from "zod";
14
- var readSchema = z.function({
15
- input: [],
16
- output: z.promise(z.instanceof(Buffer))
17
- });
18
- var streamSchema = z.function({
19
- input: [],
20
- output: z.promise(z.instanceof(ReadableStream))
21
- });
22
- var bufferToStream = (buf) => new ReadableStream({
23
- start(controller) {
24
- controller.enqueue(buf);
25
- controller.close();
26
- }
27
- });
28
- var DEFAULT_FETCH_TIMEOUT_MS = 1e4;
29
- var fetchUrlBytes = async (url, options) => {
30
- const controller = new AbortController();
31
- const timer = setTimeout(
32
- () => controller.abort(),
33
- options?.timeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS
34
- );
35
- try {
36
- const res = await fetch(url, {
37
- signal: controller.signal,
38
- headers: options?.headers
39
- });
40
- if (!res.ok) {
41
- throw new Error(`URL fetch ${url.toString()} returned ${res.status}`);
42
- }
43
- const data = Buffer.from(await res.arrayBuffer());
44
- const mimeType = res.headers.get("content-type") ?? void 0;
45
- return { data, mimeType };
46
- } finally {
47
- clearTimeout(timer);
48
- }
49
- };
50
-
51
- // src/content/attachment.ts
52
- var DEFAULT_ATTACHMENT_NAME = "attachment";
53
- var attachmentSchema = z2.object({
54
- type: z2.literal("attachment"),
55
- id: z2.string().nonempty(),
56
- name: z2.string().nonempty(),
57
- mimeType: z2.string().nonempty(),
58
- size: z2.number().int().nonnegative().optional(),
59
- read: readSchema,
60
- stream: streamSchema
61
- });
62
- var resolveAttachmentName = (input, name) => {
63
- if (name) {
64
- return name;
65
- }
66
- if (input instanceof URL) {
67
- return basename(input.pathname) || DEFAULT_ATTACHMENT_NAME;
68
- }
69
- if (typeof input === "string") {
70
- return basename(input);
71
- }
72
- return DEFAULT_ATTACHMENT_NAME;
73
- };
74
- var resolveAttachmentMimeType = (name, mimeType) => {
75
- if (mimeType) {
76
- return mimeType;
77
- }
78
- const resolvedMimeType = lookupMimeType(name);
79
- if (!resolvedMimeType) {
80
- throw new Error(
81
- `Unable to resolve MIME type for attachment "${name}". Pass options.mimeType explicitly.`
82
- );
83
- }
84
- return resolvedMimeType;
85
- };
86
- var asAttachment = (input) => {
87
- let cached;
88
- const read = () => {
89
- cached ??= input.read().catch((err) => {
90
- cached = void 0;
91
- throw err;
92
- });
93
- return cached;
94
- };
95
- const stream = input.stream ?? (async () => bufferToStream(await read()));
96
- return attachmentSchema.parse({
97
- type: "attachment",
98
- id: input.id ?? randomUUID(),
99
- name: input.name,
100
- mimeType: input.mimeType,
101
- size: input.size,
102
- read,
103
- stream
104
- });
105
- };
106
- function attachment(input, options) {
107
- return {
108
- build: async () => {
109
- const id = options?.id;
110
- const name = resolveAttachmentName(input, options?.name);
111
- const mimeType = resolveAttachmentMimeType(name, options?.mimeType);
112
- if (input instanceof URL) {
113
- return asAttachment({
114
- id,
115
- name,
116
- mimeType,
117
- read: async () => (await fetchUrlBytes(input)).data
118
- });
119
- }
120
- if (typeof input === "string") {
121
- const stats = await stat(input);
122
- return asAttachment({
123
- id,
124
- name,
125
- mimeType,
126
- size: stats.size,
127
- read: () => readFile(input),
128
- stream: async () => Readable.toWeb(
129
- createReadStream(input)
130
- )
131
- });
132
- }
133
- return asAttachment({
134
- id,
135
- name,
136
- mimeType,
137
- size: input.byteLength,
138
- read: async () => input,
139
- stream: async () => bufferToStream(input)
140
- });
141
- }
142
- };
143
- }
144
-
145
- // src/content/custom.ts
146
- import z3 from "zod";
147
- var customSchema = z3.object({
148
- type: z3.literal("custom"),
149
- raw: z3.unknown()
150
- });
151
- var asCustom = (raw) => customSchema.parse({ type: "custom", raw });
152
- function custom(raw) {
153
- return {
154
- build: async () => asCustom(raw)
155
- };
156
- }
157
-
158
- // src/content/text.ts
159
- import z5 from "zod";
160
-
161
- // src/content/stream-text.ts
162
- import z4 from "zod";
163
- var streamTextSchema = z4.object({
164
- type: z4.literal("streamText"),
165
- // A single-consumption producer of normalized text deltas. The builder
166
- // closes over the normalized source; the platform driver calls it once.
167
- // Kept opaque to Zod via `z.custom` (same approach as `attachment.read`).
168
- stream: z4.custom(
169
- (v) => typeof v === "function",
170
- {
171
- message: "streamText.stream must be a function returning AsyncIterable<string>"
172
- }
173
- ),
174
- // How platforms should interpret the accumulated text; absent = plain.
175
- format: z4.enum(["plain", "markdown"]).optional()
176
- });
177
- var asRecord = (value) => typeof value === "object" && value !== null ? value : void 0;
178
- var SKIP_EVENT_TYPES = /* @__PURE__ */ new Set([
179
- "message_start",
180
- "message_delta",
181
- "message_stop",
182
- "content_block_start",
183
- "content_block_stop",
184
- "ping"
185
- ]);
186
- var fromOpenAIResponses = (obj) => {
187
- const type = obj.type;
188
- if (typeof type !== "string" || !type.startsWith("response.")) {
189
- return;
190
- }
191
- if (type === "response.output_text.delta" && typeof obj.delta === "string") {
192
- return obj.delta;
193
- }
194
- return null;
195
- };
196
- var fromAnthropicDelta = (obj) => {
197
- if (obj.type !== "content_block_delta") {
198
- return;
199
- }
200
- const delta = asRecord(obj.delta);
201
- if (delta?.type === "text_delta" && typeof delta.text === "string") {
202
- return delta.text;
203
- }
204
- return null;
205
- };
206
- var fromAiSdkPart = (obj) => {
207
- if (obj.type !== "text-delta") {
208
- return;
209
- }
210
- if (typeof obj.textDelta === "string") {
211
- return obj.textDelta;
212
- }
213
- return typeof obj.text === "string" ? obj.text : null;
214
- };
215
- var fromOpenAIChat = (obj) => {
216
- if (!Array.isArray(obj.choices)) {
217
- return;
218
- }
219
- const delta = asRecord(asRecord(obj.choices[0])?.delta);
220
- const content = delta?.content;
221
- return typeof content === "string" ? content : null;
222
- };
223
- var fromControlEvent = (obj) => typeof obj.type === "string" && SKIP_EVENT_TYPES.has(obj.type) ? null : void 0;
224
- var OBJECT_EXTRACTORS = [
225
- fromOpenAIResponses,
226
- fromAnthropicDelta,
227
- fromAiSdkPart,
228
- fromOpenAIChat,
229
- fromControlEvent
230
- ];
231
- var defaultExtract = (chunk) => {
232
- if (typeof chunk === "string") {
233
- return chunk;
234
- }
235
- const record = asRecord(chunk);
236
- if (!record) {
237
- throw new Error(
238
- `text stream: cannot extract a text delta from a ${typeof chunk} chunk. Pass { extract } to map your stream's chunks to text.`
239
- );
240
- }
241
- for (const extractor of OBJECT_EXTRACTORS) {
242
- const result = extractor(record);
243
- if (result !== void 0) {
244
- return result;
245
- }
246
- }
247
- throw new Error(
248
- `text stream: unrecognized chunk shape (type=${String(record.type)}). Pass an { extract } function to map your provider's chunk to a text delta.`
249
- );
250
- };
251
- var isReadableStream = (value) => typeof value?.getReader === "function";
252
- var isAsyncIterable = (value) => typeof value?.[Symbol.asyncIterator] === "function";
253
- async function* readableToAsync(source) {
254
- if (isAsyncIterable(source)) {
255
- yield* source;
256
- return;
257
- }
258
- const reader = source.getReader();
259
- try {
260
- while (true) {
261
- const { done, value } = await reader.read();
262
- if (done) {
263
- return;
264
- }
265
- yield value;
266
- }
267
- } finally {
268
- reader.releaseLock();
269
- }
270
- }
271
- var resolveChunkIterable = (source) => {
272
- const textStream = source.textStream;
273
- if (textStream != null) {
274
- if (isReadableStream(textStream)) {
275
- return readableToAsync(textStream);
276
- }
277
- if (isAsyncIterable(textStream)) {
278
- return textStream;
279
- }
280
- throw new Error(
281
- "text stream: `.textStream` must be an AsyncIterable or a ReadableStream."
282
- );
283
- }
284
- if (isReadableStream(source)) {
285
- return readableToAsync(source);
286
- }
287
- if (isAsyncIterable(source)) {
288
- return source;
289
- }
290
- throw new Error(
291
- "text stream: source must be an AsyncIterable, a ReadableStream, or an object with a `.textStream` (e.g. the AI SDK streamText() result)."
292
- );
293
- };
294
- var StreamConsumedError = class extends Error {
295
- constructor() {
296
- super(
297
- "text stream: this source has already been consumed \u2014 a stream can only be sent once."
298
- );
299
- this.name = "StreamConsumedError";
300
- }
301
- };
302
- var normalize = (source, options) => {
303
- const extract = options?.extract ? options.extract : defaultExtract;
304
- let consumed = false;
305
- return async function* normalized() {
306
- if (consumed) {
307
- throw new StreamConsumedError();
308
- }
309
- consumed = true;
310
- for await (const chunk of resolveChunkIterable(source)) {
311
- const delta = extract(chunk);
312
- if (delta) {
313
- yield delta;
314
- }
315
- }
316
- };
317
- };
318
- var asStreamText = (input) => streamTextSchema.parse({
319
- type: "streamText",
320
- stream: input.stream,
321
- ...input.format ? { format: input.format } : {}
322
- });
323
- var drainStreamText = async (content) => {
324
- let full = "";
325
- for await (const delta of content.stream()) {
326
- full += delta;
327
- }
328
- return full;
329
- };
330
- var streamTextBuilder = (kind, source, options) => {
331
- if (typeof source.build === "function") {
332
- throw new Error(
333
- `${kind}(): pass the stream source itself (an AsyncIterable, a ReadableStream, or an SDK result with .textStream), not another content builder.`
334
- );
335
- }
336
- return {
337
- build: async () => asStreamText({
338
- stream: normalize(source, options),
339
- format: kind === "markdown" ? "markdown" : void 0
340
- })
341
- };
342
- };
343
-
344
- // src/content/text.ts
345
- var textSchema = z5.object({
346
- type: z5.literal("text"),
347
- text: z5.string().nonempty()
348
- });
349
- var asText = (text2) => textSchema.parse({ type: "text", text: text2 });
350
- function text(source, options) {
351
- if (typeof source === "string") {
352
- return { build: async () => asText(source) };
353
- }
354
- return streamTextBuilder("text", source, options);
355
- }
356
-
357
- // src/content/resolve.ts
358
- var resolveContents = (items) => Promise.all(
359
- items.map((c) => typeof c === "string" ? text(c).build() : c.build())
360
- );
361
-
362
- // src/content/reaction.ts
363
- import z6 from "zod";
364
- var isMessage = (v) => typeof v === "object" && v !== null && "id" in v && "content" in v;
365
- var reactionSchema = z6.object({
366
- type: z6.literal("reaction"),
367
- emoji: z6.string().min(1),
368
- target: z6.custom(isMessage, {
369
- message: "reaction target must be a Message"
370
- })
371
- });
372
- var asReaction = (input) => reactionSchema.parse({ type: "reaction", ...input });
373
- function reaction(emoji, target) {
374
- return {
375
- build: async () => {
376
- if (!target) {
377
- throw new Error(
378
- "reaction() target is undefined \u2014 the targeted message was never sent (space.send resolves undefined when a platform skips unsupported content)"
379
- );
380
- }
381
- if (target.content.type === "reaction") {
382
- throw new Error('reaction() cannot target "reaction" content');
383
- }
384
- return asReaction({ emoji, target });
385
- }
386
- };
387
- }
388
-
389
- export {
390
- readSchema,
391
- streamSchema,
392
- bufferToStream,
393
- fetchUrlBytes,
394
- attachmentSchema,
395
- asAttachment,
396
- attachment,
397
- asCustom,
398
- custom,
399
- StreamConsumedError,
400
- drainStreamText,
401
- streamTextBuilder,
402
- textSchema,
403
- asText,
404
- text,
405
- resolveContents,
406
- reactionSchema,
407
- asReaction,
408
- reaction
409
- };