@spectrum-ts/core 6.1.1 → 8.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.
@@ -1,4 +1,4 @@
1
- import { $t as groupSchema, Bt as asPollOption, Dn as buildPhotoAction, En as PhotoInput, H as ProviderMessageRecord, K as ManagedStream, Nt as asRead, On as photoActionSchema, St as asText, Tt as asRichlink, Wt as asMarkdown, Zt as asGroup, cn as reactionSchema, gt as asVoice, ln as asCustom, on as asReaction, r as asAttachment, yn as asContact, zt as asPoll } from "./attachment-CQh4PQGl.js";
1
+ import { $t as groupSchema, Bt as asPollOption, Dn as buildPhotoAction, En as PhotoInput, H as ProviderMessageRecord, K as ManagedStream, Nt as asRead, On as photoActionSchema, St as asText, Tt as asRichlink, Wt as asMarkdown, Zt as asGroup, cn as reactionSchema, gt as asVoice, ln as asCustom, on as asReaction, r as asAttachment, yn as asContact, zt as asPoll } from "./attachment-ByH1Espb.js";
2
2
  import z from "zod";
3
3
  import { LogAttrs, LogAttrs as LogAttrs$1, LogLevel, PhotonLogger, createLogger, sanitizeEmail, sanitizeErrorMessage, sanitizePhone, setLogLevel } from "@photon-ai/otel";
4
4
  import { Token } from "marked";
package/dist/authoring.js CHANGED
@@ -1,4 +1,4 @@
1
- import { D as asGroup, E as markdownSchema, H as buildPhotoAction, I as asCustom, K as attachmentSchema, N as textSchema, R as asContact, U as photoActionSchema, W as asAttachment, _ as asReaction, b as asPoll, d as asVoice, h as asRead, i as stream, j as asText, k as groupSchema, l as renderInlineTokens, o as errorAttrs, p as asRichlink, w as asMarkdown, x as asPollOption, y as reactionSchema } from "./stream-BLWs7NJ5.js";
1
+ import { D as asGroup, E as markdownSchema, H as buildPhotoAction, I as asCustom, K as attachmentSchema, N as textSchema, R as asContact, U as photoActionSchema, W as asAttachment, _ as asReaction, b as asPoll, d as asVoice, h as asRead, i as stream, j as asText, k as groupSchema, l as renderInlineTokens, o as errorAttrs, p as asRichlink, w as asMarkdown, x as asPollOption, y as reactionSchema } from "./stream-Cz0pdWd1.js";
2
2
  import z from "zod";
3
3
  import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
4
4
  import { join } from "node:path";
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as FusorTokenData, A as isFusorEvent, An as AppLayout, At as Rename, B as PlatformUser, C as FusorVerify, Cn as Avatar, Ct as text, D as WebhookRawResult, Dt as resolveContents, E as WebhookRawRequest, Et as richlink, F as PlatformInstance, Ft as Poll, G as Broadcaster, Gt as markdown, Ht as poll, I as PlatformMessage, It as PollChoice, J as mergeStreams, Jt as StreamTextSource, K as ManagedStream, Kt as DeltaExtractor, L as PlatformProviderConfig, Lt as PollChoiceInput, M as EventProducer, Mn as app, Mt as Read, N as Platform, Nn as appLayoutSchema, O as FusorEvent, Ot as Reply, P as PlatformDef, Pt as read, Q as DedicatedTokenData, Qt as group, R as PlatformRuntime, Rt as PollOption, S as FusorRespond, Sn as User, T as WebhookHandler, Tn as avatar, U as SchemaMessage, Ut as Markdown, V as ProviderMessage, Vt as option, W as SpaceNamespace, X as Store, Xt as Group, Y as stream, Yt as TextStreamOptions, Z as CloudPlatform, _ as FusorClient, _n as ContactOrg, _t as voice, a as Content, an as ReactionBuilder, at as SharedTokenData, b as FusorMessagesReturn, bn as contact, bt as Typing, c as fromVCard, ct as SpectrumCloudError, d as UnsupportedKind, dn as Contact, dt as TokenData, en as Edit, et as ImessageInfoData, f as Spectrum, fn as ContactAddress, ft as cloud, g as isFusorClient, gn as ContactName, h as fusor, hn as ContactInput, ht as Voice, i as attachment, in as Reaction, it as ProjectProfile, j as AnyPlatformDef, jn as AppUrl, jt as rename, k as fusorEvent, kn as App, kt as reply, l as toVCard, lt as SubscriptionData, m as definePlatform, mn as ContactEmail, mt as EmojiKey, n as AttachmentInput, nn as Message, nt as PlatformsData, o as ContentBuilder, ot as SlackTeamMeta, p as SpectrumInstance, pn as ContactDetails, pt as Emoji, q as broadcast, qt as StreamText, rn as Space, rt as ProjectData, s as ContentInput, sn as reaction, st as SlackTokenData, t as Attachment, tn as edit, tt as PlatformStatus, u as UnsupportedError, un as custom, ut as SubscriptionStatus, v as FusorMessages, vn as ContactPhone, vt as Unsend, w as FusorVerifyRequest, wn as AvatarInput, wt as Richlink, x as FusorReply, xn as AgentSender, xt as typing, y as FusorMessagesCtx, yt as unsend, z as PlatformSpace } from "./attachment-CQh4PQGl.js";
1
+ import { $ as FusorTokenData, A as isFusorEvent, An as AppLayout, At as Rename, B as PlatformUser, C as FusorVerify, Cn as Avatar, Ct as text, D as WebhookRawResult, Dt as resolveContents, E as WebhookRawRequest, Et as richlink, F as PlatformInstance, Ft as Poll, G as Broadcaster, Gt as markdown, Ht as poll, I as PlatformMessage, It as PollChoice, J as mergeStreams, Jt as StreamTextSource, K as ManagedStream, Kt as DeltaExtractor, L as PlatformProviderConfig, Lt as PollChoiceInput, M as EventProducer, Mn as app, Mt as Read, N as Platform, Nn as appLayoutSchema, O as FusorEvent, Ot as Reply, P as PlatformDef, Pt as read, Q as DedicatedTokenData, Qt as group, R as PlatformRuntime, Rt as PollOption, S as FusorRespond, Sn as User, T as WebhookHandler, Tn as avatar, U as SchemaMessage, Ut as Markdown, V as ProviderMessage, Vt as option, W as SpaceNamespace, X as Store, Xt as Group, Y as stream, Yt as TextStreamOptions, Z as CloudPlatform, _ as FusorClient, _n as ContactOrg, _t as voice, a as Content, an as ReactionBuilder, at as SharedTokenData, b as FusorMessagesReturn, bn as contact, bt as Typing, c as fromVCard, ct as SpectrumCloudError, d as UnsupportedKind, dn as Contact, dt as TokenData, en as Edit, et as ImessageInfoData, f as Spectrum, fn as ContactAddress, ft as cloud, g as isFusorClient, gn as ContactName, h as fusor, hn as ContactInput, ht as Voice, i as attachment, in as Reaction, it as ProjectProfile, j as AnyPlatformDef, jn as AppUrl, jt as rename, k as fusorEvent, kn as App, kt as reply, l as toVCard, lt as SubscriptionData, m as definePlatform, mn as ContactEmail, mt as EmojiKey, n as AttachmentInput, nn as Message, nt as PlatformsData, o as ContentBuilder, ot as SlackTeamMeta, p as SpectrumInstance, pn as ContactDetails, pt as Emoji, q as broadcast, qt as StreamText, rn as Space, rt as ProjectData, s as ContentInput, sn as reaction, st as SlackTokenData, t as Attachment, tn as edit, tt as PlatformStatus, u as UnsupportedError, un as custom, ut as SubscriptionStatus, v as FusorMessages, vn as ContactPhone, vt as Unsend, w as FusorVerifyRequest, wn as AvatarInput, wt as Richlink, x as FusorReply, xn as AgentSender, xt as typing, y as FusorMessagesCtx, yt as unsend, z as PlatformSpace } from "./attachment-ByH1Espb.js";
2
2
  export { type AgentSender, type AnyPlatformDef, type App, type AppLayout, type AppUrl, type Attachment, type AttachmentInput, type Avatar, type AvatarInput, type Broadcaster, type CloudPlatform, type Contact, type ContactAddress, type ContactDetails, type ContactEmail, type ContactInput, type ContactName, type ContactOrg, type ContactPhone, type Content, type ContentBuilder, type ContentInput, type DedicatedTokenData, type DeltaExtractor, type Edit, Emoji, type EmojiKey, type EventProducer, type FusorClient, type FusorEvent, type FusorMessages, type FusorMessagesCtx, type FusorMessagesReturn, type FusorReply, type FusorRespond, type FusorTokenData, type FusorVerify, type FusorVerifyRequest, type Group, type ImessageInfoData, type ManagedStream, type Markdown, type Message, type Platform, type PlatformDef, type PlatformInstance, type PlatformMessage, type PlatformProviderConfig, type PlatformRuntime, type PlatformSpace, type PlatformStatus, type PlatformUser, type PlatformsData, type Poll, type PollChoice, type PollChoiceInput, type PollOption, type ProjectData, type ProjectProfile, type ProviderMessage, type Reaction, type ReactionBuilder, type Read, type Rename, type Reply, type Richlink, type SchemaMessage, type SharedTokenData, type SlackTeamMeta, type SlackTokenData, type Space, type SpaceNamespace, Spectrum, SpectrumCloudError, type SpectrumInstance, type Store, type StreamText, type StreamTextSource, type SubscriptionData, type SubscriptionStatus, type TextStreamOptions, type TokenData, type Typing, type Unsend, UnsupportedError, type UnsupportedKind, type User, type Voice, type WebhookHandler, type WebhookRawRequest, type WebhookRawResult, app, appLayoutSchema, attachment, avatar, broadcast, cloud, contact, custom, definePlatform, edit, fromVCard, fusor, fusorEvent, group, isFusorClient, isFusorEvent, markdown, mergeStreams, option, poll, reaction, read, rename, reply, resolveContents, richlink, stream, text, toVCard, typing, unsend, voice };
package/dist/index.js CHANGED
@@ -1,8 +1,56 @@
1
- import { A as resolveContents, B as fromVCard, C as poll, F as drainStreamText, G as attachment, H as buildPhotoAction, I as asCustom, J as fetchLinkMetadata, L as custom, M as text, O as group, P as StreamConsumedError, R as asContact, S as option, T as markdown, U as photoActionSchema, V as toVCard, W as asAttachment, a as contentAttrs, c as markdownToPlainText, f as voice, g as read, i as stream, j as asText, m as richlink, n as createAsyncQueue, o as errorAttrs, p as asRichlink, q as fetchImage, r as mergeStreams, s as senderAttrs, t as broadcast, u as classifyIdentifier, v as reaction, w as asMarkdown, z as contact } from "./stream-BLWs7NJ5.js";
1
+ import { A as resolveContents, B as fromVCard, C as poll, F as drainStreamText, G as attachment, H as buildPhotoAction, I as asCustom, L as custom, M as text, O as group, P as StreamConsumedError, R as asContact, S as option, T as markdown, U as photoActionSchema, V as toVCard, W as asAttachment, a as contentAttrs, c as markdownToPlainText, f as voice, g as read, i as stream, j as asText, m as richlink, n as createAsyncQueue, o as errorAttrs, q as fetchUrlBytes, r as mergeStreams, s as senderAttrs, t as broadcast, u as classifyIdentifier, v as reaction, w as asMarkdown, z as contact } from "./stream-Cz0pdWd1.js";
2
2
  import z from "zod";
3
+ import ogs from "open-graph-scraper";
3
4
  import { createHmac, timingSafeEqual } from "node:crypto";
4
5
  import { createLogger, setLogLevel, setupOtel, withSpan } from "@photon-ai/otel";
5
6
  import { RawInboundEvent } from "@photon-ai/proto/photon/fusor/v1/inbound";
7
+ //#region src/utils/link-metadata.ts
8
+ const DEFAULT_TIMEOUT_MS = 5e3;
9
+ const USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15 spectrum-ts/richlink";
10
+ const normaliseImageUrl = (raw, base) => {
11
+ try {
12
+ return new URL(raw, base).toString();
13
+ } catch {
14
+ return;
15
+ }
16
+ };
17
+ const cleanString = (v) => {
18
+ if (typeof v !== "string") return;
19
+ const trimmed = v.trim();
20
+ return trimmed.length > 0 ? trimmed : void 0;
21
+ };
22
+ const fetchLinkMetadata = async (url) => {
23
+ try {
24
+ const result = await ogs({
25
+ url,
26
+ timeout: DEFAULT_TIMEOUT_MS,
27
+ fetchOptions: { headers: { "User-Agent": USER_AGENT } }
28
+ });
29
+ if (result.error) return {};
30
+ const { ogTitle, ogDescription, ogImage, ogSiteName, twitterTitle, twitterDescription, twitterImage } = result.result;
31
+ const title = cleanString(ogTitle) ?? cleanString(twitterTitle);
32
+ const summary = cleanString(ogDescription) ?? cleanString(twitterDescription);
33
+ const siteName = cleanString(ogSiteName);
34
+ const imageCandidate = ogImage?.[0] ?? twitterImage?.[0];
35
+ const resolved = imageCandidate ? normaliseImageUrl(imageCandidate.url, url) : void 0;
36
+ return {
37
+ title,
38
+ summary,
39
+ siteName,
40
+ image: imageCandidate && resolved ? {
41
+ url: resolved,
42
+ mimeType: "type" in imageCandidate && typeof imageCandidate.type === "string" ? imageCandidate.type : void 0
43
+ } : void 0
44
+ };
45
+ } catch {
46
+ return {};
47
+ }
48
+ };
49
+ const fetchImage = (url) => fetchUrlBytes(new URL(url), {
50
+ timeoutMs: DEFAULT_TIMEOUT_MS,
51
+ headers: { "User-Agent": USER_AGENT }
52
+ });
53
+ //#endregion
6
54
  //#region src/content/app.ts
7
55
  /**
8
56
  * Visible layout of an app card. Mirrors Apple's `MSMessageTemplateLayout`
@@ -2994,7 +3042,7 @@ function definePlatform(name, rawDef) {
2994
3042
  }
2995
3043
  //#endregion
2996
3044
  //#region src/build-env.ts
2997
- const SPECTRUM_SDK_VERSION = "6.1.1";
3045
+ const SPECTRUM_SDK_VERSION = "8.0.0";
2998
3046
  //#endregion
2999
3047
  //#region src/utils/provider-packages.ts
3000
3048
  const OFFICIAL_PROVIDER_PACKAGES = {
@@ -3744,7 +3792,10 @@ const mapContent = (content, platform, spaceRef, ctx) => {
3744
3792
  type: "text",
3745
3793
  text: asString(raw.text)
3746
3794
  };
3747
- case "richlink": return asRichlink({ url: asString(raw.url) });
3795
+ case "richlink": return {
3796
+ type: "text",
3797
+ text: asString(raw.url)
3798
+ };
3748
3799
  case "contact": return deserializeContact(raw);
3749
3800
  case "reaction": return deserializeReaction(raw, spaceRef);
3750
3801
  case "group": return deserializeGroup(raw, platform, spaceRef, ctx);
@@ -1,5 +1,4 @@
1
1
  import z from "zod";
2
- import ogs from "open-graph-scraper";
3
2
  import { randomUUID } from "node:crypto";
4
3
  import { createReadStream } from "node:fs";
5
4
  import { readFile, stat } from "node:fs/promises";
@@ -47,53 +46,6 @@ const fetchUrlBytes = async (url, options) => {
47
46
  }
48
47
  };
49
48
  //#endregion
50
- //#region src/utils/link-metadata.ts
51
- const DEFAULT_TIMEOUT_MS = 5e3;
52
- const USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15 spectrum-ts/richlink";
53
- const normaliseImageUrl = (raw, base) => {
54
- try {
55
- return new URL(raw, base).toString();
56
- } catch {
57
- return;
58
- }
59
- };
60
- const cleanString = (v) => {
61
- if (typeof v !== "string") return;
62
- const trimmed = v.trim();
63
- return trimmed.length > 0 ? trimmed : void 0;
64
- };
65
- const fetchLinkMetadata = async (url) => {
66
- try {
67
- const result = await ogs({
68
- url,
69
- timeout: DEFAULT_TIMEOUT_MS,
70
- fetchOptions: { headers: { "User-Agent": USER_AGENT } }
71
- });
72
- if (result.error) return {};
73
- const { ogTitle, ogDescription, ogImage, ogSiteName, twitterTitle, twitterDescription, twitterImage } = result.result;
74
- const title = cleanString(ogTitle) ?? cleanString(twitterTitle);
75
- const summary = cleanString(ogDescription) ?? cleanString(twitterDescription);
76
- const siteName = cleanString(ogSiteName);
77
- const imageCandidate = ogImage?.[0] ?? twitterImage?.[0];
78
- const resolved = imageCandidate ? normaliseImageUrl(imageCandidate.url, url) : void 0;
79
- return {
80
- title,
81
- summary,
82
- siteName,
83
- image: imageCandidate && resolved ? {
84
- url: resolved,
85
- mimeType: "type" in imageCandidate && typeof imageCandidate.type === "string" ? imageCandidate.type : void 0
86
- } : void 0
87
- };
88
- } catch {
89
- return {};
90
- }
91
- };
92
- const fetchImage = (url) => fetchUrlBytes(new URL(url), {
93
- timeoutMs: DEFAULT_TIMEOUT_MS,
94
- headers: { "User-Agent": USER_AGENT }
95
- });
96
- //#endregion
97
49
  //#region src/content/attachment.ts
98
50
  const DEFAULT_ATTACHMENT_NAME = "attachment";
99
51
  const attachmentSchema = z.object({
@@ -916,67 +868,24 @@ function read(target) {
916
868
  }
917
869
  //#endregion
918
870
  //#region src/content/richlink.ts
919
- const richlinkCoverSchema = z.object({
920
- mimeType: z.string().min(1).optional(),
921
- read: readSchema$1,
922
- stream: streamSchema
923
- });
924
- const optionalStringAccessor = z.function({
925
- input: [],
926
- output: z.promise(z.string().min(1).optional())
927
- });
928
- const coverAccessor = z.function({
929
- input: [],
930
- output: z.promise(richlinkCoverSchema.optional())
931
- });
932
- const richlinkSchema = z.object({
933
- type: z.literal("richlink"),
934
- url: z.url(),
935
- title: optionalStringAccessor,
936
- summary: optionalStringAccessor,
937
- cover: coverAccessor
938
- });
939
- const memoize = (factory) => {
940
- let cached;
941
- return () => {
942
- cached ??= factory();
943
- return cached;
944
- };
945
- };
946
- const buildCover = (image) => {
947
- const read = memoize(() => fetchImage(image.url).then((r) => r.data).catch(() => Buffer.alloc(0)));
948
- return {
949
- mimeType: image.mimeType,
950
- read,
951
- stream: async () => bufferToStream(await read())
952
- };
953
- };
954
871
  /**
955
- * Construct a `richlink` content value.
872
+ * A URL the platform should render as a rich link preview.
956
873
  *
957
- * Accessors (`title`, `summary`, `cover`) are async and lazy: the first call
958
- * issues a single network request to the URL; subsequent calls share the
959
- * cached result. Network / parse failures resolve to `undefined` and are
960
- * cached no retries. Callers who only need `title` / `summary` never
961
- * trigger an image download; calling `cover.read()` triggers one additional
962
- * request to fetch the image bytes.
874
+ * Outbound-only by design: inbound messages always surface as `text` content
875
+ * a URL received from a platform arrives as plain text, never as `richlink`, so
876
+ * no metadata is fetched on the inbound path. On outbound, each platform asks
877
+ * its native client to render the preview (remote iMessage: `enableLinkPreview`;
878
+ * Telegram: auto-unfurls the bare URL), so the framework carries only the URL
879
+ * and fetches nothing itself.
963
880
  */
964
- const asRichlink = (input) => {
965
- const getMetadata = memoize(() => fetchLinkMetadata(input.url));
966
- const getCover = memoize(async () => {
967
- const { image } = await getMetadata();
968
- return image ? buildCover(image) : void 0;
969
- });
970
- const title = async () => (await getMetadata()).title;
971
- const summary = async () => (await getMetadata()).summary;
972
- return richlinkSchema.parse({
973
- type: "richlink",
974
- url: input.url,
975
- title,
976
- summary,
977
- cover: getCover
978
- });
979
- };
881
+ const richlinkSchema = z.object({
882
+ type: z.literal("richlink"),
883
+ url: z.url()
884
+ });
885
+ const asRichlink = (input) => richlinkSchema.parse({
886
+ type: "richlink",
887
+ url: input.url
888
+ });
980
889
  function richlink(url) {
981
890
  return { build: async () => asRichlink({ url }) };
982
891
  }
@@ -1486,4 +1395,4 @@ function broadcast(source) {
1486
1395
  };
1487
1396
  }
1488
1397
  //#endregion
1489
- export { resolveContents as A, fromVCard as B, poll as C, asGroup as D, markdownSchema as E, drainStreamText as F, attachment as G, buildPhotoAction as H, asCustom as I, fetchLinkMetadata as J, attachmentSchema as K, custom as L, text as M, textSchema as N, group as O, StreamConsumedError as P, asContact as R, option as S, markdown as T, photoActionSchema as U, toVCard as V, asAttachment as W, asReaction as _, contentAttrs as a, asPoll as b, markdownToPlainText as c, asVoice as d, voice as f, read as g, asRead as h, stream as i, asText as j, groupSchema as k, renderInlineTokens as l, richlink as m, createAsyncQueue as n, errorAttrs as o, asRichlink as p, fetchImage as q, mergeStreams as r, senderAttrs as s, broadcast as t, classifyIdentifier as u, reaction as v, asMarkdown as w, asPollOption as x, reactionSchema as y, contact as z };
1398
+ export { resolveContents as A, fromVCard as B, poll as C, asGroup as D, markdownSchema as E, drainStreamText as F, attachment as G, buildPhotoAction as H, asCustom as I, attachmentSchema as K, custom as L, text as M, textSchema as N, group as O, StreamConsumedError as P, asContact as R, option as S, markdown as T, photoActionSchema as U, toVCard as V, asAttachment as W, asReaction as _, contentAttrs as a, asPoll as b, markdownToPlainText as c, asVoice as d, voice as f, read as g, asRead as h, stream as i, asText as j, groupSchema as k, renderInlineTokens as l, richlink as m, createAsyncQueue as n, errorAttrs as o, asRichlink as p, fetchUrlBytes as q, mergeStreams as r, senderAttrs as s, broadcast as t, classifyIdentifier as u, reaction as v, asMarkdown as w, asPollOption as x, reactionSchema as y, contact as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-ts/core",
3
- "version": "6.1.1",
3
+ "version": "8.0.0",
4
4
  "description": "The spectrum-ts runtime — Spectrum, content builders, fusor, and the provider authoring API.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,18 +26,6 @@
26
26
  "./authoring": {
27
27
  "types": "./dist/authoring.d.ts",
28
28
  "default": "./dist/authoring.js"
29
- },
30
- "./elysia": {
31
- "types": "./dist/elysia.d.ts",
32
- "default": "./dist/elysia.js"
33
- },
34
- "./express": {
35
- "types": "./dist/express.d.ts",
36
- "default": "./dist/express.js"
37
- },
38
- "./hono": {
39
- "types": "./dist/hono.d.ts",
40
- "default": "./dist/hono.js"
41
29
  }
42
30
  },
43
31
  "publishConfig": {
@@ -54,24 +42,12 @@
54
42
  "zod": "^4.2.1"
55
43
  },
56
44
  "peerDependencies": {
57
- "elysia": "^1",
58
- "express": "^4 || ^5",
59
45
  "ffmpeg-static": "^5",
60
- "hono": "^4",
61
46
  "typescript": "^5 || ^6.0.0"
62
47
  },
63
48
  "peerDependenciesMeta": {
64
- "elysia": {
65
- "optional": true
66
- },
67
- "express": {
68
- "optional": true
69
- },
70
49
  "ffmpeg-static": {
71
50
  "optional": true
72
- },
73
- "hono": {
74
- "optional": true
75
51
  }
76
52
  },
77
53
  "license": "MIT"
package/dist/elysia.d.ts DELETED
@@ -1,92 +0,0 @@
1
- import { T as WebhookHandler, nn as Message, rn as Space } from "./attachment-CQh4PQGl.js";
2
- import { Elysia } from "elysia";
3
-
4
- //#region src/elysia.d.ts
5
- /**
6
- * The minimal structural surface of a Spectrum instance the plugin needs. Kept
7
- * structural (rather than importing the generic `SpectrumInstance<Providers>`)
8
- * so the plugin stays decoupled from provider typing; a real instance is
9
- * assignable via its Web `Request` webhook overload.
10
- */
11
- interface WebhookReceiver {
12
- webhook(request: Request, handler: WebhookHandler): Promise<Response>;
13
- }
14
- interface SpectrumPluginOptions {
15
- /** The Spectrum instance returned by `await Spectrum({...})`. */
16
- app: WebhookReceiver;
17
- /**
18
- * Invoked once per inbound message, fire-and-forget after the response — the
19
- * same `(space, message)` contract as `app.webhook(request, handler)`. Covers
20
- * both native Spectrum webhooks and fusor webhooks identically.
21
- */
22
- onMessage: WebhookHandler;
23
- /**
24
- * Route the webhook is mounted on.
25
- *
26
- * @default "/spectrum/webhook"
27
- */
28
- path?: string;
29
- }
30
- /**
31
- * Mount a Spectrum webhook endpoint on an Elysia app.
32
- *
33
- * @example
34
- * ```ts
35
- * import { Elysia } from "elysia";
36
- * import { Spectrum } from "spectrum-ts";
37
- * import { spectrum } from "spectrum-ts/elysia";
38
- *
39
- * const app = await Spectrum({ ..., webhookSecret: process.env.SPECTRUM_WEBHOOK_SECRET });
40
- *
41
- * new Elysia()
42
- * .use(spectrum({
43
- * app,
44
- * onMessage: async (space, message) => {
45
- * if (message.content.type === "text") await space.send(`echo: ${message.content.text}`);
46
- * },
47
- * }))
48
- * .listen(3000);
49
- * ```
50
- */
51
- declare function spectrum(options: SpectrumPluginOptions): Elysia<"", {
52
- decorator: {};
53
- store: {};
54
- derive: {};
55
- resolve: {};
56
- }, {
57
- typebox: {};
58
- error: {};
59
- }, {
60
- schema: {};
61
- standaloneSchema: {};
62
- macro: {};
63
- macroFn: {};
64
- parser: {};
65
- response: {};
66
- }, {
67
- [x: string]: {
68
- post: {
69
- body: unknown;
70
- params: {};
71
- query: unknown;
72
- headers: unknown;
73
- response: {
74
- 200: Response;
75
- };
76
- };
77
- };
78
- }, {
79
- derive: {};
80
- resolve: {};
81
- schema: {};
82
- standaloneSchema: {};
83
- response: {};
84
- }, {
85
- derive: {};
86
- resolve: {};
87
- schema: {};
88
- standaloneSchema: {};
89
- response: {};
90
- }>;
91
- //#endregion
92
- export { type Message, type Space, SpectrumPluginOptions, type WebhookHandler, spectrum };
package/dist/elysia.js DELETED
@@ -1,32 +0,0 @@
1
- import { Elysia } from "elysia";
2
- //#region src/elysia.ts
3
- /**
4
- * Mount a Spectrum webhook endpoint on an Elysia app.
5
- *
6
- * @example
7
- * ```ts
8
- * import { Elysia } from "elysia";
9
- * import { Spectrum } from "spectrum-ts";
10
- * import { spectrum } from "spectrum-ts/elysia";
11
- *
12
- * const app = await Spectrum({ ..., webhookSecret: process.env.SPECTRUM_WEBHOOK_SECRET });
13
- *
14
- * new Elysia()
15
- * .use(spectrum({
16
- * app,
17
- * onMessage: async (space, message) => {
18
- * if (message.content.type === "text") await space.send(`echo: ${message.content.text}`);
19
- * },
20
- * }))
21
- * .listen(3000);
22
- * ```
23
- */
24
- function spectrum(options) {
25
- const { app, onMessage, path = "/spectrum/webhook" } = options;
26
- return new Elysia({
27
- name: "spectrum-webhook",
28
- seed: path
29
- }).post(path, ({ request }) => app.webhook(request, onMessage), { parse: "none" });
30
- }
31
- //#endregion
32
- export { spectrum };
package/dist/express.d.ts DELETED
@@ -1,60 +0,0 @@
1
- import { T as WebhookHandler, nn as Message, rn as Space } from "./attachment-CQh4PQGl.js";
2
- import { Router } from "express";
3
-
4
- //#region src/express.d.ts
5
- /**
6
- * The minimal structural surface of a Spectrum instance the plugin needs. Kept
7
- * structural (rather than importing the generic `SpectrumInstance<Providers>`)
8
- * so the plugin stays decoupled from provider typing; a real instance is
9
- * assignable via its raw (`{ body, headers }`) webhook overload.
10
- */
11
- interface WebhookReceiver {
12
- webhook(request: {
13
- body: Uint8Array | ArrayBuffer;
14
- headers?: Record<string, string>;
15
- }, handler: WebhookHandler): Promise<{
16
- body: Uint8Array;
17
- headers: Record<string, string>;
18
- status: number;
19
- }>;
20
- }
21
- interface SpectrumPluginOptions {
22
- /** The Spectrum instance returned by `await Spectrum({...})`. */
23
- app: WebhookReceiver;
24
- /**
25
- * Invoked once per inbound message, fire-and-forget after the response — the
26
- * same `(space, message)` contract as `app.webhook(request, handler)`. Covers
27
- * both native Spectrum webhooks and fusor webhooks identically.
28
- */
29
- onMessage: WebhookHandler;
30
- /**
31
- * Route the webhook is mounted on.
32
- *
33
- * @default "/spectrum/webhook"
34
- */
35
- path?: string;
36
- }
37
- /**
38
- * Mount a Spectrum webhook endpoint on an Express app.
39
- *
40
- * @example
41
- * ```ts
42
- * import express from "express";
43
- * import { Spectrum } from "spectrum-ts";
44
- * import { spectrum } from "spectrum-ts/express";
45
- *
46
- * const app = await Spectrum({ ..., webhookSecret: process.env.SPECTRUM_WEBHOOK_SECRET });
47
- *
48
- * const server = express();
49
- * server.use(spectrum({ // mount before any global express.json()
50
- * app,
51
- * onMessage: async (space, message) => {
52
- * if (message.content.type === "text") await space.send(`echo: ${message.content.text}`);
53
- * },
54
- * }));
55
- * server.listen(3000);
56
- * ```
57
- */
58
- declare function spectrum(options: SpectrumPluginOptions): Router;
59
- //#endregion
60
- export { type Message, type Space, SpectrumPluginOptions, type WebhookHandler, spectrum };
package/dist/express.js DELETED
@@ -1,37 +0,0 @@
1
- import express from "express";
2
- //#region src/express.ts
3
- /**
4
- * Mount a Spectrum webhook endpoint on an Express app.
5
- *
6
- * @example
7
- * ```ts
8
- * import express from "express";
9
- * import { Spectrum } from "spectrum-ts";
10
- * import { spectrum } from "spectrum-ts/express";
11
- *
12
- * const app = await Spectrum({ ..., webhookSecret: process.env.SPECTRUM_WEBHOOK_SECRET });
13
- *
14
- * const server = express();
15
- * server.use(spectrum({ // mount before any global express.json()
16
- * app,
17
- * onMessage: async (space, message) => {
18
- * if (message.content.type === "text") await space.send(`echo: ${message.content.text}`);
19
- * },
20
- * }));
21
- * server.listen(3000);
22
- * ```
23
- */
24
- function spectrum(options) {
25
- const { app, onMessage, path = "/spectrum/webhook" } = options;
26
- const router = express.Router();
27
- router.post(path, express.raw({ type: "*/*" }), async (req, res) => {
28
- const result = await app.webhook({
29
- body: req.body,
30
- headers: req.headers
31
- }, onMessage);
32
- res.status(result.status).set(result.headers).send(Buffer.from(result.body));
33
- });
34
- return router;
35
- }
36
- //#endregion
37
- export { spectrum };
package/dist/hono.d.ts DELETED
@@ -1,59 +0,0 @@
1
- import { T as WebhookHandler, nn as Message, rn as Space } from "./attachment-CQh4PQGl.js";
2
-
3
- //#region src/hono.d.ts
4
- /**
5
- * The minimal structural surface of a Spectrum instance the plugin needs. Kept
6
- * structural (rather than importing the generic `SpectrumInstance<Providers>`)
7
- * so the plugin stays decoupled from provider typing; a real instance is
8
- * assignable via its Web `Request` webhook overload.
9
- */
10
- interface WebhookReceiver {
11
- webhook(request: Request, handler: WebhookHandler): Promise<Response>;
12
- }
13
- interface SpectrumPluginOptions {
14
- /** The Spectrum instance returned by `await Spectrum({...})`. */
15
- app: WebhookReceiver;
16
- /**
17
- * Invoked once per inbound message, fire-and-forget after the response — the
18
- * same `(space, message)` contract as `app.webhook(request, handler)`. Covers
19
- * both native Spectrum webhooks and fusor webhooks identically.
20
- */
21
- onMessage: WebhookHandler;
22
- /**
23
- * Route the webhook is mounted on.
24
- *
25
- * @default "/spectrum/webhook"
26
- */
27
- path?: string;
28
- }
29
- /**
30
- * Mount a Spectrum webhook endpoint on a Hono app.
31
- *
32
- * @example
33
- * ```ts
34
- * import { Hono } from "hono";
35
- * import { Spectrum } from "spectrum-ts";
36
- * import { spectrum } from "spectrum-ts/hono";
37
- *
38
- * const app = await Spectrum({ ..., webhookSecret: process.env.SPECTRUM_WEBHOOK_SECRET });
39
- *
40
- * const server = new Hono().route("/", spectrum({
41
- * app,
42
- * onMessage: async (space, message) => {
43
- * if (message.content.type === "text") await space.send(`echo: ${message.content.text}`);
44
- * },
45
- * }));
46
- * ```
47
- */
48
- declare function spectrum(options: SpectrumPluginOptions): import("hono/hono-base").HonoBase<import("hono/types").BlankEnv, {
49
- [x: string]: {
50
- $post: {
51
- input: {};
52
- output: {};
53
- outputFormat: string;
54
- status: import("hono/utils/http-status").StatusCode;
55
- };
56
- };
57
- }, "/", string>;
58
- //#endregion
59
- export { type Message, type Space, SpectrumPluginOptions, type WebhookHandler, spectrum };
package/dist/hono.js DELETED
@@ -1,27 +0,0 @@
1
- import { Hono } from "hono";
2
- //#region src/hono.ts
3
- /**
4
- * Mount a Spectrum webhook endpoint on a Hono app.
5
- *
6
- * @example
7
- * ```ts
8
- * import { Hono } from "hono";
9
- * import { Spectrum } from "spectrum-ts";
10
- * import { spectrum } from "spectrum-ts/hono";
11
- *
12
- * const app = await Spectrum({ ..., webhookSecret: process.env.SPECTRUM_WEBHOOK_SECRET });
13
- *
14
- * const server = new Hono().route("/", spectrum({
15
- * app,
16
- * onMessage: async (space, message) => {
17
- * if (message.content.type === "text") await space.send(`echo: ${message.content.text}`);
18
- * },
19
- * }));
20
- * ```
21
- */
22
- function spectrum(options) {
23
- const { app, onMessage, path = "/spectrum/webhook" } = options;
24
- return new Hono().post(path, (c) => app.webhook(c.req.raw, onMessage));
25
- }
26
- //#endregion
27
- export { spectrum };