spectrum-ts 4.0.0 → 4.2.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 (35) hide show
  1. package/dist/{attachment-CEpGtZLm.d.ts → attachment-CnivEhr6.d.ts} +1 -1
  2. package/dist/{authoring-CP3vRza8.d.ts → authoring-b9AhXgPI.d.ts} +2 -2
  3. package/dist/authoring.d.ts +3 -3
  4. package/dist/authoring.js +3 -3
  5. package/dist/{chunk-PV4AVMNN.js → chunk-ARL2NOBO.js} +4 -4
  6. package/dist/{chunk-OGTHPDG7.js → chunk-B52VPQO3.js} +69 -29
  7. package/dist/{chunk-5VCWWPFW.js → chunk-DMPDLSFU.js} +8 -4
  8. package/dist/{chunk-57NECZQZ.js → chunk-N6THJDZV.js} +6 -4
  9. package/dist/{chunk-W5HNZ7YT.js → chunk-NLMQ75LH.js} +33 -76
  10. package/dist/{chunk-VEF6FUE7.js → chunk-WXLQNANA.js} +4 -1
  11. package/dist/elysia.d.ts +94 -0
  12. package/dist/elysia.js +15 -0
  13. package/dist/express.d.ts +62 -0
  14. package/dist/express.js +19 -0
  15. package/dist/hono.d.ts +64 -0
  16. package/dist/hono.js +11 -0
  17. package/dist/index.d.ts +33 -18
  18. package/dist/index.js +428 -36
  19. package/dist/providers/imessage/index.d.ts +10 -32
  20. package/dist/providers/imessage/index.js +7 -6
  21. package/dist/providers/index.d.ts +4 -4
  22. package/dist/providers/index.js +16 -16
  23. package/dist/providers/slack/index.d.ts +1 -1
  24. package/dist/providers/slack/index.js +2 -2
  25. package/dist/providers/telegram/index.d.ts +2 -2
  26. package/dist/providers/telegram/index.js +3 -3
  27. package/dist/providers/terminal/index.d.ts +1 -1
  28. package/dist/providers/terminal/index.js +3 -3
  29. package/dist/providers/whatsapp-business/index.d.ts +1 -1
  30. package/dist/providers/whatsapp-business/index.js +4 -4
  31. package/dist/read-C4uvozGX.d.ts +53 -0
  32. package/dist/{types-Be0T6E0e.d.ts → types-CyfLJXgu.d.ts} +26 -1
  33. package/dist/{types-CDYXH2R7.d.ts → types-ZgFTj5hJ.d.ts} +11 -6
  34. package/package.json +25 -1
  35. package/dist/photo-content-BJKnqgN-.d.ts +0 -13
@@ -0,0 +1,62 @@
1
+ import { Router } from 'express';
2
+ import { W as WebhookHandler } from './types-ZgFTj5hJ.js';
3
+ export { M as Message, S as Space } from './types-CyfLJXgu.js';
4
+ import 'hotscript';
5
+ import 'zod';
6
+
7
+ /**
8
+ * The minimal structural surface of a Spectrum instance the plugin needs. Kept
9
+ * structural (rather than importing the generic `SpectrumInstance<Providers>`)
10
+ * so the plugin stays decoupled from provider typing; a real instance is
11
+ * assignable via its raw (`{ body, headers }`) webhook overload.
12
+ */
13
+ interface WebhookReceiver {
14
+ webhook(request: {
15
+ body: Uint8Array | ArrayBuffer;
16
+ headers?: Record<string, string>;
17
+ }, handler: WebhookHandler): Promise<{
18
+ body: Uint8Array;
19
+ headers: Record<string, string>;
20
+ status: number;
21
+ }>;
22
+ }
23
+ interface SpectrumPluginOptions {
24
+ /** The Spectrum instance returned by `await Spectrum({...})`. */
25
+ app: WebhookReceiver;
26
+ /**
27
+ * Invoked once per inbound message, fire-and-forget after the response — the
28
+ * same `(space, message)` contract as `app.webhook(request, handler)`. Covers
29
+ * both native Spectrum webhooks and fusor webhooks identically.
30
+ */
31
+ onMessage: WebhookHandler;
32
+ /**
33
+ * Route the webhook is mounted on.
34
+ *
35
+ * @default "/spectrum/webhook"
36
+ */
37
+ path?: string;
38
+ }
39
+ /**
40
+ * Mount a Spectrum webhook endpoint on an Express app.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * import express from "express";
45
+ * import { Spectrum } from "spectrum-ts";
46
+ * import { spectrum } from "spectrum-ts/express";
47
+ *
48
+ * const app = await Spectrum({ ..., webhookSecret: process.env.SPECTRUM_WEBHOOK_SECRET });
49
+ *
50
+ * const server = express();
51
+ * server.use(spectrum({ // mount before any global express.json()
52
+ * app,
53
+ * onMessage: async (space, message) => {
54
+ * if (message.content.type === "text") await space.send(`echo: ${message.content.text}`);
55
+ * },
56
+ * }));
57
+ * server.listen(3000);
58
+ * ```
59
+ */
60
+ declare function spectrum(options: SpectrumPluginOptions): Router;
61
+
62
+ export { type SpectrumPluginOptions, WebhookHandler, spectrum };
@@ -0,0 +1,19 @@
1
+ import { createRequire as __spectrumCreateRequire } from "node:module"; const require = __spectrumCreateRequire(import.meta.url);
2
+
3
+ // src/express.ts
4
+ import express from "express";
5
+ function spectrum(options) {
6
+ const { app, onMessage, path = "/spectrum/webhook" } = options;
7
+ const router = express.Router();
8
+ router.post(path, express.raw({ type: "*/*" }), async (req, res) => {
9
+ const result = await app.webhook(
10
+ { body: req.body, headers: req.headers },
11
+ onMessage
12
+ );
13
+ res.status(result.status).set(result.headers).send(Buffer.from(result.body));
14
+ });
15
+ return router;
16
+ }
17
+ export {
18
+ spectrum
19
+ };
package/dist/hono.d.ts ADDED
@@ -0,0 +1,64 @@
1
+ import * as hono_hono_base from 'hono/hono-base';
2
+ import * as hono_utils_http_status from 'hono/utils/http-status';
3
+ import * as hono_types from 'hono/types';
4
+ import { W as WebhookHandler } from './types-ZgFTj5hJ.js';
5
+ export { M as Message, S as Space } from './types-CyfLJXgu.js';
6
+ import 'hotscript';
7
+ import 'zod';
8
+
9
+ /**
10
+ * The minimal structural surface of a Spectrum instance the plugin needs. Kept
11
+ * structural (rather than importing the generic `SpectrumInstance<Providers>`)
12
+ * so the plugin stays decoupled from provider typing; a real instance is
13
+ * assignable via its Web `Request` webhook overload.
14
+ */
15
+ interface WebhookReceiver {
16
+ webhook(request: Request, handler: WebhookHandler): Promise<Response>;
17
+ }
18
+ interface SpectrumPluginOptions {
19
+ /** The Spectrum instance returned by `await Spectrum({...})`. */
20
+ app: WebhookReceiver;
21
+ /**
22
+ * Invoked once per inbound message, fire-and-forget after the response — the
23
+ * same `(space, message)` contract as `app.webhook(request, handler)`. Covers
24
+ * both native Spectrum webhooks and fusor webhooks identically.
25
+ */
26
+ onMessage: WebhookHandler;
27
+ /**
28
+ * Route the webhook is mounted on.
29
+ *
30
+ * @default "/spectrum/webhook"
31
+ */
32
+ path?: string;
33
+ }
34
+ /**
35
+ * Mount a Spectrum webhook endpoint on a Hono app.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * import { Hono } from "hono";
40
+ * import { Spectrum } from "spectrum-ts";
41
+ * import { spectrum } from "spectrum-ts/hono";
42
+ *
43
+ * const app = await Spectrum({ ..., webhookSecret: process.env.SPECTRUM_WEBHOOK_SECRET });
44
+ *
45
+ * const server = new Hono().route("/", spectrum({
46
+ * app,
47
+ * onMessage: async (space, message) => {
48
+ * if (message.content.type === "text") await space.send(`echo: ${message.content.text}`);
49
+ * },
50
+ * }));
51
+ * ```
52
+ */
53
+ declare function spectrum(options: SpectrumPluginOptions): hono_hono_base.HonoBase<hono_types.BlankEnv, {
54
+ [x: string]: {
55
+ $post: {
56
+ input: {};
57
+ output: {};
58
+ outputFormat: string;
59
+ status: hono_utils_http_status.StatusCode;
60
+ };
61
+ };
62
+ }, "/", string>;
63
+
64
+ export { type SpectrumPluginOptions, WebhookHandler, spectrum };
package/dist/hono.js ADDED
@@ -0,0 +1,11 @@
1
+ import { createRequire as __spectrumCreateRequire } from "node:module"; const require = __spectrumCreateRequire(import.meta.url);
2
+
3
+ // src/hono.ts
4
+ import { Hono } from "hono";
5
+ function spectrum(options) {
6
+ const { app, onMessage, path = "/spectrum/webhook" } = options;
7
+ return new Hono().post(path, (c) => app.webhook(c.req.raw, onMessage));
8
+ }
9
+ export {
10
+ spectrum
11
+ };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,13 @@
1
- export { A as Attachment, a as AttachmentInput, b as attachment } from './attachment-CEpGtZLm.js';
1
+ export { A as Attachment, a as AttachmentInput, b as attachment } from './attachment-CnivEhr6.js';
2
2
  import z__default from 'zod';
3
- import { P as PhotoInput } from './photo-content-BJKnqgN-.js';
4
- import { C as ContentBuilder, M as Message, U as User, e as Space, h as ContentInput, i as Content, g as ProviderMessage, E as EventProducer, j as SpaceActionFn, k as MessageActionFn, I as InstanceActionFn, l as CreateClientContext, c as Store, a as PlatformDef, P as Platform, m as PlatformProviderConfig, n as SpectrumLike, o as CustomEventStreams, A as AgentSender, b as ProjectData } from './types-Be0T6E0e.js';
5
- export { p as AnyPlatformDef, B as Broadcaster, q as CloudPlatform, D as DedicatedTokenData, F as FusorTokenData, r as ImessageInfoData, s as ManagedStream, t as PlatformInstance, u as PlatformMessage, v as PlatformRuntime, w as PlatformSpace, x as PlatformStatus, y as PlatformUser, z as PlatformsData, G as ProjectProfile, R as Reaction, H as ReactionBuilder, S as SchemaMessage, J as SharedTokenData, K as SlackTeamMeta, L as SlackTokenData, N as SpaceNamespace, O as SpectrumCloudError, Q as SubscriptionData, T as SubscriptionStatus, V as TokenData, W as broadcast, X as cloud, Y as mergeStreams, Z as reaction, _ as stream } from './types-Be0T6E0e.js';
6
- import { S as StreamTextSource, T as TextStreamOptions, C as ContactInput, a as Contact } from './authoring-CP3vRza8.js';
7
- export { b as ContactAddress, c as ContactDetails, d as ContactEmail, e as ContactName, f as ContactOrg, g as ContactPhone, D as DeltaExtractor, G as Group, P as Poll, h as PollChoice, i as PollChoiceInput, j as PollOption, R as Richlink, k as StreamText, V as Voice, l as contact, m as custom, n as group, o as option, p as poll, r as richlink, t as text, v as voice } from './authoring-CP3vRza8.js';
8
- import { a as FusorVerify, F as FusorClient, b as FusorMessages, W as WebhookHandler, c as WebhookRawRequest, d as WebhookRawResult } from './types-CDYXH2R7.js';
9
- export { e as FusorEvent, f as FusorMessagesCtx, g as FusorMessagesReturn, h as FusorReply, i as FusorRespond, j as FusorVerifyRequest, k as fusorEvent, l as isFusorEvent } from './types-CDYXH2R7.js';
3
+ import { P as PhotoInput } from './read-C4uvozGX.js';
4
+ export { R as Read, r as read } from './read-C4uvozGX.js';
5
+ import { C as ContentBuilder, M as Message, U as User, S as Space, h as ContentInput, i as Content, g as ProviderMessage, E as EventProducer, j as SpaceActionFn, k as MessageActionFn, I as InstanceActionFn, l as CreateClientContext, d as Store, b as PlatformDef, P as Platform, m as PlatformProviderConfig, n as SpectrumLike, o as CustomEventStreams, A as AgentSender, c as ProjectData } from './types-CyfLJXgu.js';
6
+ export { p as AnyPlatformDef, B as Broadcaster, q as CloudPlatform, D as DedicatedTokenData, F as FusorTokenData, r as ImessageInfoData, s as ManagedStream, t as PlatformInstance, u as PlatformMessage, v as PlatformRuntime, w as PlatformSpace, x as PlatformStatus, y as PlatformUser, z as PlatformsData, G as ProjectProfile, R as Reaction, H as ReactionBuilder, a as SchemaMessage, J as SharedTokenData, K as SlackTeamMeta, L as SlackTokenData, N as SpaceNamespace, O as SpectrumCloudError, Q as SubscriptionData, T as SubscriptionStatus, V as TokenData, W as broadcast, X as cloud, Y as mergeStreams, Z as reaction, _ as stream } from './types-CyfLJXgu.js';
7
+ import { S as StreamTextSource, T as TextStreamOptions, C as ContactInput, a as Contact } from './authoring-b9AhXgPI.js';
8
+ export { b as ContactAddress, c as ContactDetails, d as ContactEmail, e as ContactName, f as ContactOrg, g as ContactPhone, D as DeltaExtractor, G as Group, P as Poll, h as PollChoice, i as PollChoiceInput, j as PollOption, R as Richlink, k as StreamText, V as Voice, l as contact, m as custom, n as group, o as option, p as poll, r as richlink, t as text, v as voice } from './authoring-b9AhXgPI.js';
9
+ import { a as FusorVerify, F as FusorClient, b as FusorMessages, W as WebhookHandler, c as WebhookRawRequest, d as WebhookRawResult } from './types-ZgFTj5hJ.js';
10
+ export { e as FusorEvent, f as FusorMessagesCtx, g as FusorMessagesReturn, h as FusorReply, i as FusorRespond, j as FusorVerifyRequest, k as fusorEvent, l as isFusorEvent } from './types-ZgFTj5hJ.js';
10
11
  import 'hotscript';
11
12
  import 'vcf';
12
13
 
@@ -67,7 +68,7 @@ declare function avatar(input: Buffer, options: {
67
68
  * (no new message id is produced; the existing message mutates in place).
68
69
  *
69
70
  * Edit cannot wrap `edit`, `reply`, `reaction`, `group`, `typing`, `rename`,
70
- * `avatar`, or `unsend` content.
71
+ * `avatar`, `unsend`, or `read` content.
71
72
  */
72
73
  declare const editSchema: z__default.ZodObject<{
73
74
  type: z__default.ZodLiteral<"edit">;
@@ -427,7 +428,7 @@ declare function rename(displayName: string): ContentBuilder;
427
428
  * `reply` like any other content type and route to a threaded send.
428
429
  *
429
430
  * Reply cannot wrap `reply`, `edit`, `reaction`, `group`, `typing`,
430
- * `rename`, `avatar`, or `unsend` content.
431
+ * `rename`, `avatar`, `unsend`, or `read` content.
431
432
  */
432
433
  declare const replySchema: z__default.ZodObject<{
433
434
  type: z__default.ZodLiteral<"reply">;
@@ -2756,12 +2757,23 @@ type SpectrumInstance<Providers extends PlatformProviderConfig[] = PlatformProvi
2756
2757
  edit(message: Message, newContent: ContentInput): Promise<void>;
2757
2758
  responding<T>(space: Space, fn: () => T | Promise<T>): Promise<T>;
2758
2759
  /**
2759
- * Handle one inbound fusor webhook delivery. Call this from your HTTP
2760
- * server's POST route — it verifies, decodes, routes to the matching
2761
- * provider's verify + message pipeline, and returns the HTTP response fusor
2762
- * relays back to the platform: the platform's `respond()` reply (including
2763
- * protocol echoes like Slack `url_verification`), computed synchronously and
2764
- * returned immediately.
2760
+ * Handle one inbound webhook delivery. Call this from your HTTP server's
2761
+ * POST route — it auto-detects which of the two Spectrum webhook formats the
2762
+ * request carries and routes accordingly:
2763
+ *
2764
+ * - **Native Spectrum webhook** (the body is normalized JSON): Spectrum Cloud
2765
+ * POSTs already-normalized, HMAC-signed JSON. The signature is verified
2766
+ * against `Spectrum({ webhookSecret })` (a bad signature → 401), the slim
2767
+ * payload is deserialized into `[space, message]`, and a `200` is returned.
2768
+ * Works without any fusor provider configured.
2769
+ * - **Fusor webhook** (the body is a protobuf envelope): a protobuf wrapping a
2770
+ * raw provider request is decoded and routed to the matching provider's
2771
+ * verify + message pipeline; the HTTP response is that platform's
2772
+ * `respond()` reply (including protocol echoes like Slack
2773
+ * `url_verification`), computed synchronously and returned immediately.
2774
+ *
2775
+ * Detection is by payload shape, not headers — Spectrum signs both kinds with
2776
+ * `X-Spectrum-Signature`, so the header can't discriminate.
2765
2777
  *
2766
2778
  * `handler` is invoked once per resolved message **fire-and-forget** — it is
2767
2779
  * dispatched after the response is computed and is NOT awaited, so its
@@ -2771,8 +2783,9 @@ type SpectrumInstance<Providers extends PlatformProviderConfig[] = PlatformProvi
2771
2783
  * and process in a separate worker).
2772
2784
  *
2773
2785
  * Stateless and request-scoped: it does NOT feed `spectrum.messages`, and it
2774
- * never opens the gRPC stream. fusor delivers at-least-once, so `handler`
2775
- * should dedupe on `message`/the event id for exactly-once side effects.
2786
+ * never opens the streaming connection. Both formats deliver at-least-once,
2787
+ * so `handler` should dedupe on `message`/the event id for exactly-once side
2788
+ * effects.
2776
2789
  */
2777
2790
  webhook(request: Request, handler: WebhookHandler): Promise<Response>;
2778
2791
  webhook(request: WebhookRawRequest, handler: WebhookHandler): Promise<WebhookRawResult>;
@@ -2799,6 +2812,7 @@ declare function Spectrum<const Providers extends PlatformProviderConfig[]>(opti
2799
2812
  providers: [...Providers];
2800
2813
  options?: SpectrumOptions;
2801
2814
  telemetry?: boolean;
2815
+ webhookSecret?: string;
2802
2816
  }): Promise<SpectrumInstance<Providers> & {
2803
2817
  readonly config: ProjectData;
2804
2818
  }>;
@@ -2808,6 +2822,7 @@ declare function Spectrum<const Providers extends PlatformProviderConfig[]>(opti
2808
2822
  providers: [...Providers];
2809
2823
  options?: SpectrumOptions;
2810
2824
  telemetry?: boolean;
2825
+ webhookSecret?: string;
2811
2826
  }): Promise<SpectrumInstance<Providers>>;
2812
2827
 
2813
2828
  type UnsupportedKind = "content" | "action";