@robono/server 0.12.1 → 0.13.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 (48) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +76 -0
  3. package/SBOM.spdx.json +8 -8
  4. package/dist/calling.d.ts +58 -0
  5. package/dist/calling.d.ts.map +1 -1
  6. package/dist/calling.js +36 -2
  7. package/dist/calling.js.map +1 -1
  8. package/dist/client.d.ts +3 -0
  9. package/dist/client.d.ts.map +1 -1
  10. package/dist/client.js +5 -0
  11. package/dist/client.js.map +1 -1
  12. package/dist/index.d.ts +9 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +6 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/location-chat.d.ts +15 -0
  17. package/dist/location-chat.d.ts.map +1 -0
  18. package/dist/location-chat.js +18 -0
  19. package/dist/location-chat.js.map +1 -0
  20. package/dist/location.d.ts +36 -0
  21. package/dist/location.d.ts.map +1 -0
  22. package/dist/location.js +93 -0
  23. package/dist/location.js.map +1 -0
  24. package/dist/managed-media.d.ts +31 -0
  25. package/dist/managed-media.d.ts.map +1 -0
  26. package/dist/managed-media.js +40 -0
  27. package/dist/managed-media.js.map +1 -0
  28. package/dist/messaging-media.d.ts +78 -0
  29. package/dist/messaging-media.d.ts.map +1 -0
  30. package/dist/messaging-media.js +110 -0
  31. package/dist/messaging-media.js.map +1 -0
  32. package/dist/messaging-transforms.d.ts +18 -0
  33. package/dist/messaging-transforms.d.ts.map +1 -0
  34. package/dist/messaging-transforms.js +58 -0
  35. package/dist/messaging-transforms.js.map +1 -0
  36. package/dist/messaging.d.ts +83 -0
  37. package/dist/messaging.d.ts.map +1 -0
  38. package/dist/messaging.js +142 -0
  39. package/dist/messaging.js.map +1 -0
  40. package/dist/push.d.ts.map +1 -1
  41. package/dist/push.js +10 -1
  42. package/dist/push.js.map +1 -1
  43. package/dist/types.d.ts +65 -4
  44. package/dist/types.d.ts.map +1 -1
  45. package/dist/webhooks.d.ts.map +1 -1
  46. package/dist/webhooks.js +29 -2
  47. package/dist/webhooks.js.map +1 -1
  48. package/package.json +1 -1
@@ -0,0 +1,15 @@
1
+ import { type MessagingBackendOptions } from "./messaging.js";
2
+ /** Connect an existing accepted Bridge conversation to managed location sharing. */
3
+ export declare class RobonoLocationChatBackend {
4
+ private transport;
5
+ constructor(options: MessagingBackendOptions);
6
+ request(actor: string, operation: string, input?: Record<string, unknown>): Promise<any>;
7
+ setPermission(input: {
8
+ actor: string;
9
+ conversationId: string;
10
+ canSend: boolean;
11
+ canReceive: boolean;
12
+ revision: number;
13
+ }): Promise<any>;
14
+ }
15
+ //# sourceMappingURL=location-chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"location-chat.d.ts","sourceRoot":"","sources":["../src/location-chat.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AACxB,oFAAoF;AACpF,qBAAa,yBAAyB;IACpC,OAAO,CAAC,SAAS,CAAyB;gBAC9B,OAAO,EAAE,uBAAuB;IAM5C,OAAO,CACL,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAIrC,aAAa,CACX,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,OAAO,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;KAClB;CAIJ"}
@@ -0,0 +1,18 @@
1
+ import { RobonoMessagingBackend, } from "./messaging.js";
2
+ /** Connect an existing accepted Bridge conversation to managed location sharing. */
3
+ export class RobonoLocationChatBackend {
4
+ transport;
5
+ constructor(options) {
6
+ this.transport = new RobonoMessagingBackend({
7
+ ...options,
8
+ baseUrl: options.baseUrl ?? "https://api.robono.com/v1/location/chat",
9
+ });
10
+ }
11
+ request(actor, operation, input = {}) {
12
+ return this.transport.request(operation, { ...input, actor });
13
+ }
14
+ setPermission(input) {
15
+ return this.request(input.actor, "permission", input);
16
+ }
17
+ }
18
+ //# sourceMappingURL=location-chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"location-chat.js","sourceRoot":"","sources":["../src/location-chat.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,oFAAoF;AACpF,MAAM,OAAO,yBAAyB;IAC5B,SAAS,CAAyB;IAC1C,YAAY,OAAgC;QAC1C,IAAI,CAAC,SAAS,GAAG,IAAI,sBAAsB,CAAC;YAC1C,GAAG,OAAO;YACV,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,yCAAyC;SACtE,CAAC,CAAC;IACL,CAAC;IACD,OAAO,CACL,KAAa,EACb,SAAiB,EACjB,QAAiC,EAAE;QAEnC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,aAAa,CACX,KAMC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;CACF"}
@@ -0,0 +1,36 @@
1
+ import { type MessagingBackendOptions } from "./messaging.js";
2
+ export interface LocationGrantInput {
3
+ subjectId: string;
4
+ viewerAppId: string;
5
+ viewerId: string;
6
+ allowed: boolean;
7
+ allowOngoing: boolean;
8
+ expiresAt: string;
9
+ revision: number;
10
+ connectionId?: string;
11
+ }
12
+ /** Provider keys stay inside Robono. Only the host's authenticated server uses this SDK. */
13
+ export declare class RobonoLocationBackend {
14
+ private transport;
15
+ constructor(options: MessagingBackendOptions);
16
+ request(operation: string, input?: Record<string, unknown>): Promise<any>;
17
+ settings(): Promise<any>;
18
+ setGrant(input: LocationGrantInput): Promise<any>;
19
+ approveGrant(input: {
20
+ grantId: string;
21
+ allowed: boolean;
22
+ revision: number;
23
+ }): Promise<any>;
24
+ eraseLocationUser(userId: string): Promise<any>;
25
+ }
26
+ export declare function createLocationBackendAdapter(options: {
27
+ robono: RobonoLocationBackend;
28
+ authenticate: (request: Request) => Promise<string | null>;
29
+ authorize: (context: {
30
+ actorId: string;
31
+ operation: string;
32
+ input: Record<string, unknown>;
33
+ request: Request;
34
+ }) => Promise<boolean>;
35
+ }): (request: Request) => Promise<Response>;
36
+ //# sourceMappingURL=location.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"location.d.ts","sourceRoot":"","sources":["../src/location.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AACD,4FAA4F;AAC5F,qBAAa,qBAAqB;IAChC,OAAO,CAAC,SAAS,CAAyB;gBAC9B,OAAO,EAAE,uBAAuB;IAM5C,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAG9D,QAAQ;IAGR,QAAQ,CAAC,KAAK,EAAE,kBAAkB;IAGlC,YAAY,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAG3E,iBAAiB,CAAC,MAAM,EAAE,MAAM;CAGjC;AACD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE;IACP,MAAM,EAAE,qBAAqB,CAAC;IAC9B,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3D,SAAS,EAAE,CACT,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,EAAE,OAAO,CAAC;KAClB,KACE,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB,IAEa,SAAS,OAAO,uBAwE/B"}
@@ -0,0 +1,93 @@
1
+ import { RobonoMessagingBackend, } from "./messaging.js";
2
+ import { RobonoError } from "./errors.js";
3
+ /** Provider keys stay inside Robono. Only the host's authenticated server uses this SDK. */
4
+ export class RobonoLocationBackend {
5
+ transport;
6
+ constructor(options) {
7
+ this.transport = new RobonoMessagingBackend({
8
+ ...options,
9
+ baseUrl: options.baseUrl ?? "https://api.robono.com/v1/location",
10
+ });
11
+ }
12
+ request(operation, input = {}) {
13
+ return this.transport.request(operation, input);
14
+ }
15
+ settings() {
16
+ return this.request("settings");
17
+ }
18
+ setGrant(input) {
19
+ return this.request("grant", input);
20
+ }
21
+ approveGrant(input) {
22
+ return this.request("approve", input);
23
+ }
24
+ eraseLocationUser(userId) {
25
+ return this.request("erase-user", { userId });
26
+ }
27
+ }
28
+ export function createLocationBackendAdapter(options) {
29
+ return async (request) => {
30
+ const reply = (body, status = 200, headers = {}) => new Response(JSON.stringify(body), {
31
+ status,
32
+ headers: {
33
+ "content-type": "application/json",
34
+ "cache-control": "no-store",
35
+ ...headers,
36
+ },
37
+ });
38
+ if (request.method !== "POST") {
39
+ return reply({ error: { code: "method_not_allowed" } }, 405);
40
+ }
41
+ try {
42
+ const actor = await options.authenticate(request);
43
+ if (!actor) {
44
+ return reply({ error: { code: "authentication_required" } }, 401);
45
+ }
46
+ const raw = await request.text();
47
+ if (raw.length > 16000) {
48
+ return reply({ error: { code: "request_too_large" } }, 413);
49
+ }
50
+ let body;
51
+ try {
52
+ body = JSON.parse(raw);
53
+ if (!body || Array.isArray(body) || typeof body !== "object") {
54
+ throw Error();
55
+ }
56
+ }
57
+ catch {
58
+ return reply({ error: { code: "invalid_request" } }, 422);
59
+ }
60
+ const operation = String(body.operation ?? "");
61
+ if (![
62
+ "settings",
63
+ "start",
64
+ "update",
65
+ "view",
66
+ "list",
67
+ "stop",
68
+ "fence",
69
+ "fences",
70
+ "events",
71
+ "history",
72
+ "address",
73
+ "directions",
74
+ "map-open", "motion-status", "motion-permission", "motion",
75
+ ].includes(operation))
76
+ return reply({ error: { code: "operation_not_allowed" } }, 403);
77
+ const input = { ...body, actor };
78
+ delete input.operation;
79
+ if (!await options.authorize({ actorId: actor, operation, input, request }))
80
+ return reply({ error: { code: "operation_not_allowed" } }, 403);
81
+ return reply(await options.robono.request(operation, input));
82
+ }
83
+ catch (e) {
84
+ if (e instanceof RobonoError) {
85
+ return reply({ error: { code: e.code, message: e.message } }, e.status ?? 503, e.retryAfterMs
86
+ ? { "retry-after": String(Math.ceil(e.retryAfterMs / 1000)) }
87
+ : {});
88
+ }
89
+ return reply({ error: { code: "location_unavailable" } }, 503);
90
+ }
91
+ };
92
+ }
93
+ //# sourceMappingURL=location.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"location.js","sourceRoot":"","sources":["../src/location.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { MessagingPrivateStorage, MessagingStoredMedia } from './messaging-media.js';
2
+ /** Robono-hosted private attachments. Keep this client on your authenticated backend. */
3
+ export declare class RobonoManagedMedia implements MessagingPrivateStorage {
4
+ private options;
5
+ private url;
6
+ constructor(options: {
7
+ apiKey: string;
8
+ baseUrl?: string;
9
+ fetch?: typeof fetch;
10
+ });
11
+ private request;
12
+ prepare(input: Parameters<MessagingPrivateStorage['prepare']>[0]): ReturnType<MessagingPrivateStorage['prepare']>;
13
+ complete(input: Parameters<MessagingPrivateStorage['complete']>[0]): ReturnType<MessagingPrivateStorage['complete']>;
14
+ download(input: Parameters<MessagingPrivateStorage['download']>[0]): ReturnType<MessagingPrivateStorage['download']>;
15
+ authorizeDownload(input: {
16
+ actorId: string;
17
+ conversationId: string;
18
+ messageId: string;
19
+ }): Promise<{
20
+ url: string;
21
+ headers?: Record<string, string>;
22
+ media: MessagingStoredMedia;
23
+ }>;
24
+ discard(input: Parameters<MessagingPrivateStorage['discard']>[0]): Promise<void>;
25
+ resolve(input: {
26
+ actorId: string;
27
+ conversationId: string;
28
+ assetId: string;
29
+ }): Promise<MessagingStoredMedia | null>;
30
+ }
31
+ //# sourceMappingURL=managed-media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-media.d.ts","sourceRoot":"","sources":["../src/managed-media.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,uBAAuB,EAAC,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AACvF,yFAAyF;AACzF,qBAAa,kBAAmB,YAAW,uBAAuB;IAErD,OAAO,CAAC,OAAO;IAD3B,OAAO,CAAC,GAAG,CAAQ;gBACC,OAAO,EAAC;QAAC,MAAM,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAC;QAAA,KAAK,CAAC,EAAC,OAAO,KAAK,CAAA;KAAC;YAKjE,OAAO;IAMrB,OAAO,CAAC,KAAK,EAAC,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAE,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACzG,QAAQ,CAAC,KAAK,EAAC,UAAU,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAE,UAAU,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAKxH,QAAQ,CAAC,KAAK,EAAC,UAAU,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAE,UAAU,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAClH,iBAAiB,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,cAAc,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAA;KAAC,GAAE,OAAO,CAAC;QAAC,GAAG,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;QAAA,KAAK,EAAC,oBAAoB,CAAA;KAAC,CAAC;IAC1J,OAAO,CAAC,KAAK,EAAC,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,cAAc,EAAC,MAAM,CAAC;QAAA,OAAO,EAAC,MAAM,CAAA;KAAC,GAAE,OAAO,CAAC,oBAAoB,GAAC,IAAI,CAAC;CAG7G"}
@@ -0,0 +1,40 @@
1
+ import { RobonoError } from './errors.js';
2
+ /** Robono-hosted private attachments. Keep this client on your authenticated backend. */
3
+ export class RobonoManagedMedia {
4
+ options;
5
+ url;
6
+ constructor(options) {
7
+ this.options = options;
8
+ const url = new URL(options.baseUrl ?? 'https://api.robono.com/v1/messaging/media');
9
+ if (url.protocol !== 'https:' || url.username || url.password || !options.apiKey.trim())
10
+ throw Error('Use an HTTPS endpoint and a server API key.');
11
+ this.url = url.href;
12
+ }
13
+ async request(operation, input) {
14
+ const response = await (this.options.fetch ?? fetch)(this.url, { method: 'POST', redirect: 'error', signal: AbortSignal.timeout(operation === 'complete' ? 120000 : 15000), headers: { authorization: `Bearer ${this.options.apiKey}`, 'content-type': 'application/json' }, body: JSON.stringify({ ...input, operation }) });
15
+ const data = await response.json().catch(() => null);
16
+ if (!response.ok)
17
+ throw new RobonoError(data?.error?.message ?? 'Attachment request failed.', { status: response.status, code: data?.error?.code ?? 'media_unavailable', retryable: response.status === 429 || response.status >= 500 });
18
+ return data;
19
+ }
20
+ prepare(input) { return this.request('prepare', input); }
21
+ async complete(input) {
22
+ const result = await this.request('complete', input);
23
+ // The verified kind is returned by Robono, never inferred from the phone's request.
24
+ return { kind: result.kind, media: result.media };
25
+ }
26
+ download(input) { return this.request('download', input); }
27
+ authorizeDownload(input) { return this.request('download', input); }
28
+ async discard(input) { await this.request('discard', input); }
29
+ async resolve(input) {
30
+ try {
31
+ return (await this.request('resolve', input)).media;
32
+ }
33
+ catch (e) {
34
+ if (e instanceof RobonoError && e.status === 404)
35
+ return null;
36
+ throw e;
37
+ }
38
+ }
39
+ }
40
+ //# sourceMappingURL=managed-media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-media.js","sourceRoot":"","sources":["../src/managed-media.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AAExC,yFAAyF;AACzF,MAAM,OAAO,kBAAkB;IAEV;IADZ,GAAG,CAAQ;IACnB,YAAoB,OAA2D;QAA3D,YAAO,GAAP,OAAO,CAAoD;QAC9E,MAAM,GAAG,GAAC,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,IAAE,2CAA2C,CAAC,CAAC;QAChF,IAAG,GAAG,CAAC,QAAQ,KAAG,QAAQ,IAAE,GAAG,CAAC,QAAQ,IAAE,GAAG,CAAC,QAAQ,IAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;YAAC,MAAM,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC1I,IAAI,CAAC,GAAG,GAAC,GAAG,CAAC,IAAI,CAAC;IACnB,CAAC;IACO,KAAK,CAAC,OAAO,CAAC,SAAgB,EAAC,KAAY;QAClD,MAAM,QAAQ,GAAC,MAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAC,EAAC,MAAM,EAAC,MAAM,EAAC,QAAQ,EAAC,OAAO,EAAC,MAAM,EAAC,WAAW,CAAC,OAAO,CAAC,SAAS,KAAG,UAAU,CAAA,CAAC,CAAA,MAAM,CAAA,CAAC,CAAA,KAAK,CAAC,EAAC,OAAO,EAAC,EAAC,aAAa,EAAC,UAAU,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAC,cAAc,EAAC,kBAAkB,EAAC,EAAC,IAAI,EAAC,IAAI,CAAC,SAAS,CAAC,EAAC,GAAG,KAAK,EAAC,SAAS,EAAC,CAAC,EAAC,CAAC,CAAC;QAC/R,MAAM,IAAI,GAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAE,EAAE,CAAA,IAAI,CAAC,CAAC;QACjD,IAAG,CAAC,QAAQ,CAAC,EAAE;YAAC,MAAM,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,IAAE,4BAA4B,EAAC,EAAC,MAAM,EAAC,QAAQ,CAAC,MAAM,EAAC,IAAI,EAAC,IAAI,EAAE,KAAK,EAAE,IAAI,IAAE,mBAAmB,EAAC,SAAS,EAAC,QAAQ,CAAC,MAAM,KAAG,GAAG,IAAE,QAAQ,CAAC,MAAM,IAAE,GAAG,EAAC,CAAC,CAAC;QACrN,OAAO,IAAI,CAAC;IACb,CAAC;IACD,OAAO,CAAC,KAAuD,IAAiD,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAC,KAAK,CAAC,CAAC,CAAA,CAAC;IACtJ,KAAK,CAAC,QAAQ,CAAC,KAAwD;QACtE,MAAM,MAAM,GAAC,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,EAAC,KAAK,CAAC,CAAC;QAClD,oFAAoF;QACpF,OAAO,EAAC,IAAI,EAAC,MAAM,CAAC,IAAI,EAAC,KAAK,EAAC,MAAM,CAAC,KAAK,EAAC,CAAC;IAC9C,CAAC;IACD,QAAQ,CAAC,KAAwD,IAAkD,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAC,KAAK,CAAC,CAAC,CAAA,CAAC;IAC1J,iBAAiB,CAAC,KAA6D,IAAkF,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAC,KAAK,CAAC,CAAC,CAAA,CAAC;IACxM,KAAK,CAAC,OAAO,CAAC,KAAuD,IAAE,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAC,KAAK,CAAC,CAAC,CAAA,CAAC;IAC5G,KAAK,CAAC,OAAO,CAAC,KAA2D;QACxE,IAAG,CAAC;YAAA,OAAM,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,EAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAAA,CAAC;QAAA,OAAM,CAAC,EAAC,CAAC;YAAA,IAAG,CAAC,YAAY,WAAW,IAAE,CAAC,CAAC,MAAM,KAAG,GAAG;gBAAC,OAAO,IAAI,CAAC;YAAA,MAAM,CAAC,CAAC;QAAA,CAAC;IAClI,CAAC;CACD"}
@@ -0,0 +1,78 @@
1
+ import type { RobonoMessagingBackend } from './messaging.js';
2
+ export interface MessagingStoredMedia {
3
+ assetId: string;
4
+ mimeType: string;
5
+ fileName: string;
6
+ byteSize: number;
7
+ durationMs?: number;
8
+ }
9
+ export interface MessagingUploadFile {
10
+ mimeType: string;
11
+ fileName: string;
12
+ byteSize: number;
13
+ durationMs?: number;
14
+ }
15
+ export type MessagingMediaKind = 'voice' | 'image' | 'video' | 'document';
16
+ export interface MessagingStorageContext {
17
+ actorId: string;
18
+ uploadId: string;
19
+ conversationId: string;
20
+ }
21
+ export interface MessagingPrivateStorage {
22
+ /** Optional combined operation for managed storage. MUST check current membership,
23
+ * blocks, message visibility/expiry and asset ownership before issuing a URL.
24
+ * Return authoritative metadata; never trust a phone-supplied asset ID. */
25
+ authorizeDownload?(input: {
26
+ actorId: string;
27
+ conversationId: string;
28
+ messageId: string;
29
+ }): Promise<{
30
+ url: string;
31
+ headers?: Record<string, string>;
32
+ media: MessagingStoredMedia;
33
+ }>;
34
+ /** Persist actor/conversation/kind/file against uploadId before returning a short-lived PUT URL. Repeated prepare must return the same upload. */
35
+ prepare(input: MessagingStorageContext & {
36
+ kind: MessagingMediaKind;
37
+ file: MessagingUploadFile;
38
+ }): Promise<{
39
+ url: string;
40
+ headers?: Record<string, string>;
41
+ } | {
42
+ media: MessagingStoredMedia;
43
+ }>;
44
+ /** Verify OWNERSHIP and ACTUAL stored bytes/type/duration; return the original persisted kind, not a phone-supplied value. Idempotent. */
45
+ complete(input: MessagingStorageContext): Promise<{
46
+ kind: MessagingMediaKind;
47
+ media: MessagingStoredMedia;
48
+ }>;
49
+ /** Resolve only this authorized message's asset to a short-lived private download URL. */
50
+ download(input: {
51
+ actorId: string;
52
+ conversationId: string;
53
+ messageId: string;
54
+ media: MessagingStoredMedia;
55
+ }): Promise<{
56
+ url: string;
57
+ headers?: Record<string, string>;
58
+ }>;
59
+ /** Only discard this actor's uncommitted/unreferenced upload. Must tolerate racing or repeated requests. */
60
+ discard(input: {
61
+ actorId: string;
62
+ uploadId: string;
63
+ }): Promise<void>;
64
+ }
65
+ /** Mount on YOUR backend. No native code or storage-provider credentials are supplied by the phone. */
66
+ export declare function createMessagingMediaBackendAdapter(options: {
67
+ robono: RobonoMessagingBackend;
68
+ authenticate: (request: Request) => Promise<string | null>;
69
+ authorize: (input: {
70
+ actorId: string;
71
+ operation: string;
72
+ conversationId?: string;
73
+ uploadId?: string;
74
+ request: Request;
75
+ }) => Promise<boolean>;
76
+ storage: MessagingPrivateStorage;
77
+ }): (request: Request) => Promise<Response>;
78
+ //# sourceMappingURL=messaging-media.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging-media.d.ts","sourceRoot":"","sources":["../src/messaging-media.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,gBAAgB,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IAAE,OAAO,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,UAAU,CAAC,EAAC,MAAM,CAAA;CAAC;AACzH,MAAM,WAAW,mBAAmB;IAAE,QAAQ,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,UAAU,CAAC,EAAC,MAAM,CAAA;CAAC;AACzG,MAAM,MAAM,kBAAkB,GAAC,OAAO,GAAC,OAAO,GAAC,OAAO,GAAC,UAAU,CAAC;AAClE,MAAM,WAAW,uBAAuB;IAAE,OAAO,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,cAAc,EAAC,MAAM,CAAA;CAAC;AAC/F,MAAM,WAAW,uBAAuB;IACtC;;+EAE2E;IAC3E,iBAAiB,CAAC,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,cAAc,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAA;KAAC,GAAE,OAAO,CAAC;QAAC,GAAG,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;QAAA,KAAK,EAAC,oBAAoB,CAAA;KAAC,CAAC,CAAC;IAClK,kJAAkJ;IAClJ,OAAO,CAAC,KAAK,EAAC,uBAAuB,GAAC;QAAC,IAAI,EAAC,kBAAkB,CAAC;QAAA,IAAI,EAAC,mBAAmB,CAAA;KAAC,GAAE,OAAO,CAAC;QAAC,GAAG,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAA;KAAC,GAAC;QAAC,KAAK,EAAC,oBAAoB,CAAA;KAAC,CAAC,CAAC;IAC5K,0IAA0I;IAC1I,QAAQ,CAAC,KAAK,EAAC,uBAAuB,GAAE,OAAO,CAAC;QAAC,IAAI,EAAC,kBAAkB,CAAC;QAAA,KAAK,EAAC,oBAAoB,CAAA;KAAC,CAAC,CAAC;IACtG,0FAA0F;IAC1F,QAAQ,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,cAAc,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAC;QAAA,KAAK,EAAC,oBAAoB,CAAA;KAAC,GAAE,OAAO,CAAC;QAAC,GAAG,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAA;KAAC,CAAC,CAAC;IACxJ,4GAA4G;IAC5G,OAAO,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,QAAQ,EAAC,MAAM,CAAA;KAAC,GAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAgBD,uGAAuG;AACvG,wBAAgB,kCAAkC,CAAC,OAAO,EAAC;IAC1D,MAAM,EAAC,sBAAsB,CAAC;IAC9B,YAAY,EAAC,CAAC,OAAO,EAAC,OAAO,KAAG,OAAO,CAAC,MAAM,GAAC,IAAI,CAAC,CAAC;IACrD,SAAS,EAAC,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAC;QAAA,cAAc,CAAC,EAAC,MAAM,CAAC;QAAA,QAAQ,CAAC,EAAC,MAAM,CAAC;QAAA,OAAO,EAAC,OAAO,CAAA;KAAC,KAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9H,OAAO,EAAC,uBAAuB,CAAC;CAChC,IACa,SAAQ,OAAO,uBA0C5B"}
@@ -0,0 +1,110 @@
1
+ import { RobonoError } from './errors.js';
2
+ function object(value) { if (!value || typeof value !== 'object' || Array.isArray(value))
3
+ throw new RobonoError('Invalid media request.', { status: 422, code: 'invalid_media_request' }); return value; }
4
+ function id(value) { if (typeof value !== 'string' || !value.trim() || value.length > 200 || value.trim() !== value || /[\u0000-\u001f\u007f]/.test(value))
5
+ throw new RobonoError('Invalid identifier.', { status: 422, code: 'invalid_media_request' }); return value; }
6
+ function policy(settings, kind, media) {
7
+ const mime = media.mimeType;
8
+ if (!settings?.enabled || !settings.features?.[kind])
9
+ throw new RobonoError('This attachment type is unavailable.', { status: 403, code: 'message_kind_disabled' });
10
+ if (typeof mime !== 'string' || !/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/.test(mime) ||
11
+ (kind === 'document' ? /^(audio|image|video)\//.test(mime) : !mime.startsWith(kind === 'voice' ? 'audio/' : kind + '/')))
12
+ throw new RobonoError('The file format is not allowed.', { status: 422, code: 'attachment_format_not_allowed' });
13
+ const limit = settings.attachments?.[kind];
14
+ if (kind !== 'voice' && (!limit || !Array.isArray(limit.allowedMimeTypes) || !limit.allowedMimeTypes.includes(mime)))
15
+ throw new RobonoError('The file format is not allowed.', { status: 422, code: 'attachment_format_not_allowed' });
16
+ if (!Number.isSafeInteger(media.byteSize) || media.byteSize < 1 || media.byteSize > Math.min(104857600, limit?.maxFileBytes ?? 104857600))
17
+ throw new RobonoError('The file is too large or empty.', { status: 422, code: 'attachment_size_exceeded' });
18
+ if (typeof media.fileName !== 'string' || !media.fileName.trim() || media.fileName.length > 240 || /[\u0000-\u001f\u007f]/.test(media.fileName))
19
+ throw new RobonoError('Invalid file name.', { status: 422, code: 'invalid_media_request' });
20
+ const max = kind === 'voice' ? settings.voice?.maxDurationSeconds ?? 60 : kind === 'video' ? limit.maxDurationSeconds : null;
21
+ if (max !== null && (!Number.isSafeInteger(media.durationMs) || media.durationMs < 1 || media.durationMs > max * 1000))
22
+ throw new RobonoError(`The recording can be up to ${max} seconds.`, { status: 422, code: kind === 'voice' ? 'voice_duration_exceeded' : 'video_duration_exceeded' });
23
+ }
24
+ function planUrl(plan) { const url = new URL(plan.url); if (url.protocol !== 'https:' || url.username || url.password)
25
+ throw Error('Storage must return a private HTTPS transfer URL.'); return plan; }
26
+ /** Mount on YOUR backend. No native code or storage-provider credentials are supplied by the phone. */
27
+ export function createMessagingMediaBackendAdapter(options) {
28
+ return async (request) => {
29
+ const respond = (data, status = 200) => new Response(JSON.stringify(data), { status, headers: { 'content-type': 'application/json', 'cache-control': 'no-store' } });
30
+ if (request.method !== 'POST')
31
+ return respond({ error: { code: 'method_not_allowed' } }, 405);
32
+ try {
33
+ const actorId = await options.authenticate(request);
34
+ if (!actorId)
35
+ return respond({ error: { code: 'authentication_required' } }, 401);
36
+ const raw = await request.text();
37
+ if (raw.length > 20000)
38
+ return respond({ error: { code: 'request_too_large' } }, 413);
39
+ let input;
40
+ try {
41
+ input = object(JSON.parse(raw));
42
+ }
43
+ catch {
44
+ return respond({ error: { code: 'invalid_media_request' } }, 422);
45
+ }
46
+ const operation = input.operation;
47
+ if (!['prepare', 'complete', 'download', 'discard'].includes(operation))
48
+ return respond({ error: { code: 'operation_not_allowed' } }, 403);
49
+ const uploadId = operation !== 'download' ? id(input.uploadId) : undefined;
50
+ const conversationId = operation !== 'discard' ? id(input.conversationId) : undefined;
51
+ if (!await options.authorize({ actorId, operation, ...(uploadId ? { uploadId } : {}), ...(conversationId ? { conversationId } : {}), request }))
52
+ return respond({ error: { code: 'operation_not_allowed' } }, 403);
53
+ if (operation === 'discard') {
54
+ await options.storage.discard({ actorId, uploadId: uploadId });
55
+ return respond({ ok: true });
56
+ }
57
+ let messageId;
58
+ if (operation === 'download') {
59
+ messageId = id(input.messageId);
60
+ if (!/^\d{1,19}$/.test(messageId) || BigInt(messageId) < 1n || BigInt(messageId) >= 9223372036854775807n)
61
+ return respond({ error: { code: 'invalid_media_request' } }, 422);
62
+ // Managed storage performs the authoritative checks in the same request that
63
+ // resolves the asset. Custom storage retains the list-before-download path.
64
+ if (options.storage.authorizeDownload) {
65
+ const plan = await options.storage.authorizeDownload({ actorId, conversationId: conversationId, messageId });
66
+ id(plan.media.assetId);
67
+ return respond(planUrl(plan));
68
+ }
69
+ }
70
+ // Authoritative membership/block checks and the latest policy, before touching storage.
71
+ const page = await options.robono.request('list', { actorId, conversationId, limit: 1, ...(messageId ? { before: (BigInt(messageId) + 1n).toString() } : {}) });
72
+ const context = { actorId, uploadId: uploadId, conversationId: conversationId };
73
+ if (operation === 'prepare') {
74
+ if (!['voice', 'image', 'video', 'document'].includes(input.kind))
75
+ return respond({ error: { code: 'invalid_media_request' } }, 422);
76
+ const file = object(input.file);
77
+ policy(page.settings, input.kind, file);
78
+ const plan = await options.storage.prepare({ ...context, kind: input.kind, file });
79
+ if ('media' in plan) {
80
+ id(plan.media.assetId);
81
+ policy(page.settings, input.kind, plan.media);
82
+ return respond({ media: plan.media });
83
+ }
84
+ return respond(planUrl(plan));
85
+ }
86
+ if (operation === 'complete') {
87
+ const result = await options.storage.complete(context);
88
+ try {
89
+ id(result.media.assetId);
90
+ policy(page.settings, result.kind, result.media);
91
+ }
92
+ catch (e) {
93
+ await options.storage.discard({ actorId, uploadId: uploadId });
94
+ throw e;
95
+ }
96
+ return respond({ media: result.media });
97
+ }
98
+ const message = page.messages?.find((m) => m.id === messageId);
99
+ if (!message?.media)
100
+ return respond({ error: { code: 'message_not_found' } }, 404);
101
+ return respond({ ...planUrl(await options.storage.download({ actorId, conversationId: conversationId, messageId: messageId, media: message.media })), media: message.media });
102
+ }
103
+ catch (e) {
104
+ if (e instanceof RobonoError)
105
+ return respond({ error: { code: e.code, message: e.message } }, e.status ?? 503);
106
+ return respond({ error: { code: 'media_unavailable', message: 'Media is temporarily unavailable. Try again.' } }, 503);
107
+ }
108
+ };
109
+ }
110
+ //# sourceMappingURL=messaging-media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging-media.js","sourceRoot":"","sources":["../src/messaging-media.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { RobonoMessagingBackend } from './messaging.js';
2
+ import type { MessagingPrivateStorage } from './messaging-media.js';
3
+ import type { RobonoServer } from './client.js';
4
+ /** On-demand language tools. A client sends only a message ID, never arbitrary source URLs or text. */
5
+ export declare function createMessagingTransformBackendAdapter(options: {
6
+ robono: RobonoMessagingBackend;
7
+ speech: Pick<RobonoServer['transforms'], 'speech'>;
8
+ storage: Pick<MessagingPrivateStorage, 'download'>;
9
+ authenticate(request: Request): Promise<string | null>;
10
+ authorize(input: {
11
+ actorId: string;
12
+ conversationId: string;
13
+ messageId: string;
14
+ operation: 'transcript' | 'translation';
15
+ request: Request;
16
+ }): Promise<boolean>;
17
+ }): (request: Request) => Promise<Response>;
18
+ //# sourceMappingURL=messaging-transforms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging-transforms.d.ts","sourceRoot":"","sources":["../src/messaging-transforms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAG9C,uGAAuG;AACvG,wBAAgB,sCAAsC,CAAC,OAAO,EAAC;IAC9D,MAAM,EAAC,sBAAsB,CAAC;IAAA,MAAM,EAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,EAAC,QAAQ,CAAC,CAAC;IAC/E,OAAO,EAAC,IAAI,CAAC,uBAAuB,EAAC,UAAU,CAAC,CAAC;IACjD,YAAY,CAAC,OAAO,EAAC,OAAO,GAAE,OAAO,CAAC,MAAM,GAAC,IAAI,CAAC,CAAC;IACnD,SAAS,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,cAAc,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,YAAY,GAAC,aAAa,CAAC;QAAA,OAAO,EAAC,OAAO,CAAA;KAAC,GAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/I,IACa,SAAQ,OAAO,uBA6B5B"}
@@ -0,0 +1,58 @@
1
+ import { RobonoError } from './errors.js';
2
+ /** On-demand language tools. A client sends only a message ID, never arbitrary source URLs or text. */
3
+ export function createMessagingTransformBackendAdapter(options) {
4
+ return async (request) => {
5
+ const reply = (body, status = 200, headers = {}) => new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json', 'cache-control': 'no-store', ...headers } });
6
+ if (request.method !== 'POST')
7
+ return reply({ error: { code: 'method_not_allowed' } }, 405);
8
+ try {
9
+ const actorId = await options.authenticate(request);
10
+ if (!actorId)
11
+ return reply({ error: { code: 'authentication_required' } }, 401);
12
+ const raw = await request.text();
13
+ if (raw.length > 2000)
14
+ return reply({ error: { code: 'request_too_large' } }, 413);
15
+ let input;
16
+ try {
17
+ input = JSON.parse(raw);
18
+ }
19
+ catch {
20
+ return reply({ error: { code: 'invalid_transform' } }, 422);
21
+ }
22
+ if (!input || !['transcript', 'translation'].includes(input.operation) || typeof input.conversationId !== 'string' || !/^[0-9a-f-]{36}$/i.test(input.conversationId) || typeof input.messageId !== 'string' || !/^\d{1,19}$/.test(input.messageId) || BigInt(input.messageId) < 1n || BigInt(input.messageId) > 9223372036854775807n || input.operation === 'translation' && (typeof input.language !== 'string' || !/^[a-z]{2,3}(?:-[a-z0-9]{2,8}){0,2}$/i.test(input.language)))
23
+ return reply({ error: { code: 'invalid_transform' } }, 422);
24
+ const context = { actorId, conversationId: input.conversationId, messageId: input.messageId, operation: input.operation, request };
25
+ if (!await options.authorize(context))
26
+ return reply({ error: { code: 'operation_not_allowed' } }, 403);
27
+ const read = () => options.robono.request('list', { actorId, conversationId: input.conversationId, limit: 1, messageIds: [input.messageId] });
28
+ const page = await read(), message = page.messages?.find((m) => m.id === input.messageId), flag = input.operation === 'transcript' ? 'transcription' : 'translation';
29
+ const permitted = (p) => p.settings?.enabled && p.settings.features?.[flag] === true;
30
+ if (!permitted(page) || !message || message.deleted || input.operation === 'transcript' && message.kind !== 'voice' || !['voice', 'text'].includes(message.kind))
31
+ return reply({ error: { code: 'transform_unavailable' } }, 403);
32
+ const source = message.kind === 'text' ? { type: 'text', text: message.text } : await (async () => {
33
+ const plan = await options.storage.download({ actorId, conversationId: input.conversationId, messageId: message.id, media: message.media });
34
+ const url = new URL(plan.url);
35
+ if (url.protocol !== 'https:' || url.username || url.password || Object.keys(plan.headers ?? {}).length)
36
+ throw Error('Provide a short-lived signed HTTPS audio URL for speech processing.');
37
+ return { type: 'audio', source_url: plan.url, mime_type: message.media.mimeType };
38
+ })();
39
+ const language = input.operation === 'translation' ? input.language : undefined;
40
+ const key = `messaging:${input.conversationId}:${message.id}:${input.operation}:${language ?? 'auto'}`;
41
+ const result = await options.speech.speech({ external_request_id: key, input: source, outputs: [input.operation === 'transcript' ? 'transcript' : 'translated_text'], ...(language ? { target_language: language } : {}) }, { idempotencyKey: key });
42
+ // A block, removal or retention change during processing must not reveal text.
43
+ const current = await read();
44
+ if (!permitted(current) || !current.messages?.some((m) => m.id === message.id && !m.deleted) || !await options.authorize(context))
45
+ return reply({ error: { code: 'transform_unavailable' } }, 403);
46
+ const artifact = input.operation === 'transcript' ? result.artifacts.transcript : result.artifacts.translated_text;
47
+ if (!artifact || typeof artifact.text !== 'string')
48
+ throw Error('Speech result unavailable');
49
+ return reply({ messageId: message.id, text: artifact.text, language: artifact.target_language ?? artifact.language, kind: input.operation });
50
+ }
51
+ catch (e) {
52
+ if (e instanceof RobonoError)
53
+ return reply({ error: { code: e.code, message: e.message } }, e.status ?? 503, e.retryAfterMs ? { 'retry-after': String(Math.ceil(e.retryAfterMs / 1000)) } : {});
54
+ return reply({ error: { code: 'transform_unavailable', message: 'This message could not be converted. Try again.' } }, 503);
55
+ }
56
+ };
57
+ }
58
+ //# sourceMappingURL=messaging-transforms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messaging-transforms.js","sourceRoot":"","sources":["../src/messaging-transforms.ts"],"names":[],"mappings":"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"}