@msg91comm/m91 0.0.0-stage → 1.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 (100) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/LICENSE +21 -0
  3. package/README.md +647 -2
  4. package/dist/src/client.d.ts +165 -0
  5. package/dist/src/client.d.ts.map +1 -0
  6. package/dist/src/client.js +221 -0
  7. package/dist/src/client.js.map +1 -0
  8. package/dist/src/exceptions.d.ts +114 -0
  9. package/dist/src/exceptions.d.ts.map +1 -0
  10. package/dist/src/exceptions.js +199 -0
  11. package/dist/src/exceptions.js.map +1 -0
  12. package/dist/src/http.d.ts +71 -0
  13. package/dist/src/http.d.ts.map +1 -0
  14. package/dist/src/http.js +150 -0
  15. package/dist/src/http.js.map +1 -0
  16. package/dist/src/index.d.ts +49 -0
  17. package/dist/src/index.d.ts.map +1 -0
  18. package/dist/src/index.js +45 -0
  19. package/dist/src/index.js.map +1 -0
  20. package/dist/src/integrations/claude-agent-sdk.d.ts +63 -0
  21. package/dist/src/integrations/claude-agent-sdk.d.ts.map +1 -0
  22. package/dist/src/integrations/claude-agent-sdk.js +109 -0
  23. package/dist/src/integrations/claude-agent-sdk.js.map +1 -0
  24. package/dist/src/integrations/google-adk.d.ts +47 -0
  25. package/dist/src/integrations/google-adk.d.ts.map +1 -0
  26. package/dist/src/integrations/google-adk.js +84 -0
  27. package/dist/src/integrations/google-adk.js.map +1 -0
  28. package/dist/src/integrations/index.d.ts +26 -0
  29. package/dist/src/integrations/index.d.ts.map +1 -0
  30. package/dist/src/integrations/index.js +25 -0
  31. package/dist/src/integrations/index.js.map +1 -0
  32. package/dist/src/integrations/langchain.d.ts +94 -0
  33. package/dist/src/integrations/langchain.d.ts.map +1 -0
  34. package/dist/src/integrations/langchain.js +129 -0
  35. package/dist/src/integrations/langchain.js.map +1 -0
  36. package/dist/src/integrations/langgraph.d.ts +79 -0
  37. package/dist/src/integrations/langgraph.d.ts.map +1 -0
  38. package/dist/src/integrations/langgraph.js +114 -0
  39. package/dist/src/integrations/langgraph.js.map +1 -0
  40. package/dist/src/integrations/mastra.d.ts +75 -0
  41. package/dist/src/integrations/mastra.d.ts.map +1 -0
  42. package/dist/src/integrations/mastra.js +109 -0
  43. package/dist/src/integrations/mastra.js.map +1 -0
  44. package/dist/src/integrations/openai-agents.d.ts +61 -0
  45. package/dist/src/integrations/openai-agents.d.ts.map +1 -0
  46. package/dist/src/integrations/openai-agents.js +127 -0
  47. package/dist/src/integrations/openai-agents.js.map +1 -0
  48. package/dist/src/integrations/specs.d.ts +173 -0
  49. package/dist/src/integrations/specs.d.ts.map +1 -0
  50. package/dist/src/integrations/specs.js +217 -0
  51. package/dist/src/integrations/specs.js.map +1 -0
  52. package/dist/src/integrations/vercel-ai.d.ts +74 -0
  53. package/dist/src/integrations/vercel-ai.d.ts.map +1 -0
  54. package/dist/src/integrations/vercel-ai.js +102 -0
  55. package/dist/src/integrations/vercel-ai.js.map +1 -0
  56. package/dist/src/integrations/zod-shapes.d.ts +19 -0
  57. package/dist/src/integrations/zod-shapes.d.ts.map +1 -0
  58. package/dist/src/integrations/zod-shapes.js +44 -0
  59. package/dist/src/integrations/zod-shapes.js.map +1 -0
  60. package/dist/src/models.d.ts +274 -0
  61. package/dist/src/models.d.ts.map +1 -0
  62. package/dist/src/models.js +383 -0
  63. package/dist/src/models.js.map +1 -0
  64. package/dist/src/platform.d.ts +176 -0
  65. package/dist/src/platform.d.ts.map +1 -0
  66. package/dist/src/platform.js +286 -0
  67. package/dist/src/platform.js.map +1 -0
  68. package/dist/src/url-builder.d.ts +65 -0
  69. package/dist/src/url-builder.d.ts.map +1 -0
  70. package/dist/src/url-builder.js +167 -0
  71. package/dist/src/url-builder.js.map +1 -0
  72. package/examples/approval-gate.ts +35 -0
  73. package/examples/basic-alert.ts +53 -0
  74. package/examples/claude-agent-sdk.ts +23 -0
  75. package/examples/deep-agents.ts +31 -0
  76. package/examples/google-adk.ts +39 -0
  77. package/examples/langchain-agent.ts +65 -0
  78. package/examples/langgraph-hitl.ts +70 -0
  79. package/examples/mastra.ts +41 -0
  80. package/examples/openai-agents.ts +33 -0
  81. package/examples/vercel-ai-agent.ts +34 -0
  82. package/examples/webhook-urls.ts +44 -0
  83. package/package.json +135 -4
  84. package/src/client.ts +324 -0
  85. package/src/exceptions.ts +229 -0
  86. package/src/http.ts +174 -0
  87. package/src/index.ts +91 -0
  88. package/src/integrations/claude-agent-sdk.ts +158 -0
  89. package/src/integrations/google-adk.ts +122 -0
  90. package/src/integrations/index.ts +27 -0
  91. package/src/integrations/langchain.ts +207 -0
  92. package/src/integrations/langgraph.ts +142 -0
  93. package/src/integrations/mastra.ts +178 -0
  94. package/src/integrations/openai-agents.ts +173 -0
  95. package/src/integrations/specs.ts +328 -0
  96. package/src/integrations/vercel-ai.ts +151 -0
  97. package/src/integrations/zod-shapes.ts +55 -0
  98. package/src/models.ts +660 -0
  99. package/src/platform.ts +343 -0
  100. package/src/url-builder.ts +225 -0
@@ -0,0 +1,383 @@
1
+ /**
2
+ * Every shape the API returns, plus the local validation that stops a doomed
3
+ * request before it leaves the process.
4
+ *
5
+ * Two rules govern this file:
6
+ *
7
+ * - **Parse defensively.** The server omits a field rather than sending it
8
+ * false or zero — `deduplicated`, `noDevice`, `pending`, `reopened` and
9
+ * `message` are present only when they have something to say.
10
+ * - **Emit exactly.** Every request schema server-side is `.strict()`: an
11
+ * unknown field is a 400, and so is `null` where a string was declared. So
12
+ * `buildAlertPayload` *omits* what the caller left unset.
13
+ */
14
+ import { M91ValidationError } from './exceptions.js';
15
+ export const SEVERITIES = ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'];
16
+ export const EFFECTS = ['SHARED', 'PERSONAL'];
17
+ /** Severities that place a voice call after 45s with no answer. */
18
+ export const ESCALATING_SEVERITIES = ['HIGH', 'CRITICAL'];
19
+ export const TITLE_MIN = 5;
20
+ export const TITLE_MAX = 2000;
21
+ export const DESCRIPTION_MAX = 2000;
22
+ export const CUSTOM_ID_MAX = 200;
23
+ export const LABEL_MAX = 24;
24
+ export const ATTACHMENT_URL_MAX = 2000;
25
+ const CALLBACK_URL_MAX = 2000;
26
+ const MAX_RESPONSE_OPTIONS = 20;
27
+ export const MAX_LINK_RESPONSE_OPTIONS = 6;
28
+ export const CHANNEL_NAME_MAX = 80;
29
+ export const MAX_MEMBERS_PER_CALL = 500;
30
+ /** Mirrors `validation/common.js` — digits only, country code included, no `+`. */
31
+ const PHONE_RE = /^\d{8,15}$/;
32
+ /** The only two things an option may ask somebody to supply. */
33
+ export const COLLECTABLE = ['note', 'attachment'];
34
+ const asRaw = (value) => (value && typeof value === 'object' ? value : {});
35
+ const str = (value) => (value === null || value === undefined ? null : String(value));
36
+ const num = (value) => (Number.isFinite(Number(value)) ? Number(value) : 0);
37
+ const arr = (value) => (Array.isArray(value) ? value : []);
38
+ function parseOptions(value) {
39
+ return arr(value).map((o) => {
40
+ const raw = asRaw(o);
41
+ const option = {
42
+ label: String(raw.label ?? ''),
43
+ effect: raw.effect ?? 'SHARED',
44
+ };
45
+ // Absent means "asks for nothing", and the server omits the key then — so
46
+ // these are only set when they are real, matching what goes out.
47
+ const required = arr(raw.required).map(String);
48
+ const optional = arr(raw.optional).map(String);
49
+ if (required.length)
50
+ option.required = required;
51
+ if (optional.length)
52
+ option.optional = optional;
53
+ return option;
54
+ });
55
+ }
56
+ export function parseDecision(value) {
57
+ if (!value || typeof value !== 'object')
58
+ return null;
59
+ const raw = asRaw(value);
60
+ return {
61
+ label: str(raw.label),
62
+ effect: String(raw.effect ?? 'SHARED'),
63
+ at: str(raw.at),
64
+ by: str(raw.by),
65
+ };
66
+ }
67
+ export function parseAlertResponse(value) {
68
+ const raw = asRaw(value);
69
+ const delivered = num(raw.delivered);
70
+ const deduplicated = raw.deduplicated === true;
71
+ return {
72
+ id: String(raw._id ?? raw.id ?? ''),
73
+ channelId: str(raw.channelId),
74
+ channelName: str(raw.channelName),
75
+ status: raw.status ?? 'OPEN',
76
+ severity: raw.severity ?? 'MEDIUM',
77
+ customId: str(raw.customId),
78
+ isAutoClose: raw.isAutoClose === true,
79
+ responseOptions: parseOptions(raw.responseOptions),
80
+ delivered,
81
+ createdAt: str(raw.createdAt),
82
+ deduplicated,
83
+ reopened: raw.reopened === true,
84
+ unregistered: arr(raw.unregistered).map(String),
85
+ noDevice: num(raw.noDevice),
86
+ pending: num(raw.pending),
87
+ message: str(raw.message),
88
+ actuallyReachedSomeone: deduplicated || delivered > 0,
89
+ raw,
90
+ };
91
+ }
92
+ /** A sender's attachments arrive as bare strings; a responder's as objects. */
93
+ export function parseAttachment(value) {
94
+ if (typeof value === 'string')
95
+ return { url: value, name: null, type: null, size: null };
96
+ const raw = asRaw(value);
97
+ return {
98
+ url: String(raw.url ?? ''),
99
+ name: str(raw.name),
100
+ type: str(raw.type),
101
+ size: raw.size === undefined || raw.size === null ? null : num(raw.size),
102
+ };
103
+ }
104
+ export function parseResponse(value) {
105
+ const raw = asRaw(value);
106
+ return {
107
+ label: str(raw.label),
108
+ effect: String(raw.effect ?? 'PERSONAL'),
109
+ optionIndex: raw.optionIndex === undefined || raw.optionIndex === null ? null : num(raw.optionIndex),
110
+ at: str(raw.at),
111
+ by: str(raw.by),
112
+ note: str(raw.note),
113
+ attachments: arr(raw.attachments).map(parseAttachment),
114
+ };
115
+ }
116
+ export function parseAlertDetail(value) {
117
+ const raw = asRaw(value);
118
+ const decision = parseDecision(raw.decision);
119
+ const status = raw.status ?? 'OPEN';
120
+ return {
121
+ id: String(raw._id ?? raw.id ?? ''),
122
+ customId: str(raw.customId),
123
+ status,
124
+ severity: raw.severity ?? 'MEDIUM',
125
+ title: str(raw.title),
126
+ isAutoClose: raw.isAutoClose === true,
127
+ reopenCount: num(raw.reopenCount),
128
+ responseOptions: parseOptions(raw.responseOptions),
129
+ responses: arr(raw.responses).map(parseResponse),
130
+ attachments: arr(raw.attachments).map(parseAttachment),
131
+ pending: num(raw.pending),
132
+ decision,
133
+ resolvedAt: str(raw.resolvedAt),
134
+ createdAt: str(raw.createdAt),
135
+ isDecided: decision !== null,
136
+ isClosed: status === 'RESOLVED',
137
+ raw,
138
+ };
139
+ }
140
+ export function parseChannelInfo(value) {
141
+ const raw = asRaw(value);
142
+ const channel = asRaw(raw.channel);
143
+ const sender = asRaw(raw.sender);
144
+ return {
145
+ id: String(channel.id ?? ''),
146
+ name: String(channel.name ?? ''),
147
+ visibility: String(channel.visibility ?? 'PRIVATE'),
148
+ senderLabel: str(sender.label),
149
+ senderId: str(sender.id),
150
+ };
151
+ }
152
+ export function parseApiKeyInfo(value) {
153
+ const raw = asRaw(value);
154
+ const key = asRaw(raw.key);
155
+ const owner = asRaw(raw.owner);
156
+ return {
157
+ keyId: String(key._id ?? key.id ?? ''),
158
+ prefix: str(key.prefix),
159
+ label: str(key.label),
160
+ createdAt: str(key.createdAt),
161
+ ownerPhone: str(owner.phone),
162
+ };
163
+ }
164
+ export function parseRecipient(value) {
165
+ const raw = asRaw(value);
166
+ const state = raw.state ?? 'pending';
167
+ return {
168
+ phone: String(raw.phone ?? ''),
169
+ state,
170
+ reachable: raw.reachable === undefined ? state === 'accepted' : raw.reachable === true,
171
+ };
172
+ }
173
+ export function parseProvisionedChannel(value) {
174
+ const raw = asRaw(value);
175
+ return {
176
+ id: String(raw._id ?? raw.id ?? ''),
177
+ name: String(raw.name ?? ''),
178
+ sendLink: str(raw.sendLink),
179
+ };
180
+ }
181
+ export function parseInviteResult(value) {
182
+ const raw = asRaw(value);
183
+ return {
184
+ invited: arr(raw.invited).map(String),
185
+ already: arr(raw.already).map(String),
186
+ pending: arr(raw.pending).map(String),
187
+ declined: arr(raw.declined).map(String),
188
+ raw,
189
+ };
190
+ }
191
+ /** True when this decision is the approval, compared case-insensitively.
192
+ *
193
+ * A missing label is not an approval. The server can hand back `label: null`,
194
+ * and treating an unknown answer as a yes is the wrong way to be wrong about a
195
+ * payment. */
196
+ export function isApproved(decision, approveLabel = 'Approve') {
197
+ if (!decision?.label)
198
+ return false;
199
+ return collapse(decision.label).toLowerCase() === collapse(approveLabel).toLowerCase();
200
+ }
201
+ // ── outbound ──────────────────────────────────────────────────────────────────
202
+ /**
203
+ * Trim and collapse runs of whitespace, as `validateRequest` does server-side.
204
+ * Done here too so a length check measures the string the server will measure.
205
+ */
206
+ export function collapse(value) {
207
+ return String(value).replace(/\s+/g, ' ').trim();
208
+ }
209
+ /**
210
+ * Validate an alert locally and render the JSON body the server accepts.
211
+ *
212
+ * Every limit checked here is one the server enforces. Checking twice is not
213
+ * duplication for its own sake: a 400 costs a round trip, and the caller is
214
+ * often a cron or an agent that will simply do it again.
215
+ */
216
+ export function buildAlertPayload(title, fields = {}, maxOptions = MAX_RESPONSE_OPTIONS) {
217
+ const cleanTitle = collapse(title ?? '');
218
+ if (!cleanTitle)
219
+ throw new M91ValidationError('title is required');
220
+ if (cleanTitle.length < TITLE_MIN) {
221
+ throw new M91ValidationError(`title must be at least ${TITLE_MIN} characters, got ${cleanTitle.length}`);
222
+ }
223
+ if (cleanTitle.length > TITLE_MAX) {
224
+ throw new M91ValidationError(`title must be ${TITLE_MAX} characters or fewer, got ${cleanTitle.length}`);
225
+ }
226
+ const severity = checkSeverity(fields.severity ?? 'MEDIUM');
227
+ const payload = { title: cleanTitle, severity };
228
+ if (fields.other !== undefined && fields.other !== null) {
229
+ payload.other = Boolean(fields.other);
230
+ }
231
+ /*
232
+ * URLs, never bytes.
233
+ *
234
+ * The server takes links and not multipart, because every automation a send
235
+ * link is pasted into — viasocket, Zapier, Make, a spreadsheet — has a URL
236
+ * field and little else. Checked here so a typo costs nothing: a cron that
237
+ * gets a 400 will simply send it again.
238
+ */
239
+ if (fields.attachments?.length) {
240
+ const urls = [];
241
+ for (const item of fields.attachments) {
242
+ const url = collapse(String(item ?? ''));
243
+ if (!url)
244
+ continue;
245
+ if (url.length > ATTACHMENT_URL_MAX) {
246
+ throw new M91ValidationError(`attachment URL must be ${ATTACHMENT_URL_MAX} characters or fewer, got ${url.length}`);
247
+ }
248
+ if (!/^https:\/\//i.test(url)) {
249
+ throw new M91ValidationError(`attachment must be an https link, got ${JSON.stringify(url)}`);
250
+ }
251
+ urls.push(url);
252
+ }
253
+ if (urls.length)
254
+ payload.attachments = urls;
255
+ }
256
+ if (fields.callbackUrl !== undefined && fields.callbackUrl !== null) {
257
+ const callbackUrl = collapse(fields.callbackUrl);
258
+ if (callbackUrl.length > CALLBACK_URL_MAX) {
259
+ throw new M91ValidationError(`callbackUrl must be ${CALLBACK_URL_MAX} characters or fewer, got ${callbackUrl.length}`);
260
+ }
261
+ if (callbackUrl)
262
+ payload.callbackUrl = callbackUrl;
263
+ }
264
+ if (fields.description !== undefined && fields.description !== null) {
265
+ const description = collapse(fields.description);
266
+ if (description.length > DESCRIPTION_MAX) {
267
+ throw new M91ValidationError(`description must be ${DESCRIPTION_MAX} characters or fewer, got ${description.length}`);
268
+ }
269
+ payload.description = description;
270
+ }
271
+ if (fields.customId !== undefined && fields.customId !== null) {
272
+ const customId = collapse(String(fields.customId));
273
+ if (!customId)
274
+ throw new M91ValidationError('customId cannot be empty — omit it instead');
275
+ if (customId.length > CUSTOM_ID_MAX) {
276
+ throw new M91ValidationError(`customId must be ${CUSTOM_ID_MAX} characters or fewer, got ${customId.length}`);
277
+ }
278
+ payload.customId = customId;
279
+ }
280
+ // Always sent, never omitted. The default is false on both sides, but an
281
+ // explicit false is what lets a code review of the call site tell "stays open
282
+ // until somebody closes it" from "nobody thought about it".
283
+ payload.isAutoClose = fields.isAutoClose === true;
284
+ if (fields.responseOptions !== undefined) {
285
+ payload.responseOptions = checkOptions(normalizeOptions(fields.responseOptions), maxOptions);
286
+ }
287
+ return payload;
288
+ }
289
+ export function normalizeOptions(options) {
290
+ return options.map((option) => {
291
+ const raw = typeof option === 'string' ? { label: option } : option;
292
+ const label = collapse(raw?.label ?? '');
293
+ if (!label)
294
+ throw new M91ValidationError('response option label cannot be empty');
295
+ if (label.length > LABEL_MAX) {
296
+ throw new M91ValidationError(`response option label must be ${LABEL_MAX} characters or fewer, got ${label.length}: '${label}'`);
297
+ }
298
+ const effect = raw.effect ?? 'SHARED';
299
+ if (!EFFECTS.includes(effect)) {
300
+ throw new M91ValidationError(`effect must be SHARED or PERSONAL, got '${effect}'`);
301
+ }
302
+ const built = { label, effect };
303
+ const required = collectFields(raw.required, 'required');
304
+ const optional = collectFields(raw.optional, 'optional');
305
+ const both = required.filter((f) => optional.includes(f));
306
+ if (both.length) {
307
+ // The server takes the stricter of the two, so this is a statement the
308
+ // sender did not mean. Saying so beats silently picking one.
309
+ throw new M91ValidationError(`${both.join(', ')} cannot be both required and optional`);
310
+ }
311
+ /*
312
+ * Only what was set. A field in NEITHER list is not rendered at all, which
313
+ * is what stops an option configured for a photo putting an unwanted note
314
+ * box in front of somebody at 3am.
315
+ */
316
+ if (required.length)
317
+ built.required = required;
318
+ if (optional.length)
319
+ built.optional = optional;
320
+ return built;
321
+ });
322
+ }
323
+ /**
324
+ * Normalise and check a `required` / `optional` list.
325
+ *
326
+ * Checked here because the server's enum error — "must be note or
327
+ * attachment" — arrives after a round trip, and the caller is usually a cron
328
+ * or an agent that will just send it again.
329
+ */
330
+ function collectFields(value, which) {
331
+ if (!value)
332
+ return [];
333
+ const items = Array.isArray(value) ? value : [value];
334
+ const out = [];
335
+ for (const item of items) {
336
+ const name = collapse(String(item ?? '')).toLowerCase();
337
+ if (!COLLECTABLE.includes(name)) {
338
+ throw new M91ValidationError(`${which} must contain only ${COLLECTABLE.join(' or ')}, got ${JSON.stringify(item)}`);
339
+ }
340
+ if (!out.includes(name))
341
+ out.push(name);
342
+ }
343
+ return out;
344
+ }
345
+ function checkOptions(options, maxOptions) {
346
+ if (options.length > maxOptions) {
347
+ throw new M91ValidationError(`cannot offer more than ${maxOptions} response options, got ${options.length}`);
348
+ }
349
+ const seen = new Set();
350
+ for (const option of options) {
351
+ const key = option.label.toLowerCase();
352
+ // The server rejects this too. Two buttons reading the same thing with
353
+ // different effects is an alert nobody can answer correctly at 3am.
354
+ if (seen.has(key)) {
355
+ throw new M91ValidationError(`cannot repeat the same response label twice: '${option.label}'`);
356
+ }
357
+ seen.add(key);
358
+ }
359
+ return options;
360
+ }
361
+ export function checkSeverity(severity) {
362
+ const value = String(severity).toUpperCase();
363
+ if (!SEVERITIES.includes(value)) {
364
+ throw new M91ValidationError(`severity must be one of: ${SEVERITIES.join(', ')}, got '${severity}'`);
365
+ }
366
+ return value;
367
+ }
368
+ /**
369
+ * Digits only, 8–15, country code included, no `+` and no spaces.
370
+ * The `+` is the one everybody gets wrong, so it gets its own message.
371
+ */
372
+ export function validatePhone(phone) {
373
+ const raw = String(phone ?? '').trim();
374
+ if (raw.startsWith('+')) {
375
+ throw new M91ValidationError(`phone must not start with '+': send digits only, e.g. '${raw.slice(1)}' not '${raw}'`);
376
+ }
377
+ if (!PHONE_RE.test(raw)) {
378
+ throw new M91ValidationError(`phone must be 8-15 digits including the country code, with no '+' or spaces ` +
379
+ `(e.g. 919876543210), got '${phone}'`);
380
+ }
381
+ return raw;
382
+ }
383
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/models.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * The API-key client: alerting **one person, by phone number**.
3
+ *
4
+ * The narrowness is the point, and worth understanding before reaching for
5
+ * this. A team is already solved — somebody creates the channel in the app and
6
+ * the integration posts to its send link. What a link cannot do is address a
7
+ * person a platform is discovering at runtime: a CRM signing up its
8
+ * five-thousandth salesman cannot mint and store five thousand bearer
9
+ * credentials, each able to wake somebody through Do Not Disturb, sitting in a
10
+ * user table with no rotation. So for one person, the secret is one header and
11
+ * the address is a phone number.
12
+ *
13
+ * **An API key cannot alert a team channel.** It can *provision* one — create
14
+ * it, staff it, read its send link — because that is the same authority its
15
+ * owner has in the app. Raising the alert is still the send link's job. A
16
+ * leaked key can rename or restaff a channel; it cannot ring a single phone in
17
+ * it, and that split is the entire reason the two capabilities sit on two
18
+ * credentials.
19
+ */
20
+ import { type TransportOptions } from './http.js';
21
+ import { type AlertDetail, type AlertResponse, type ApiKeyInfo, type InviteResult, type ProvisionedChannel, type Recipient } from './models.js';
22
+ import { type SendOptions } from './client.js';
23
+ export declare const DEFAULT_BASE_URL = "https://m91-api.msg91.com";
24
+ export declare const API_KEY_PREFIX = "m91sk_";
25
+ export interface PlatformOptions extends TransportOptions {
26
+ baseUrl?: string;
27
+ /**
28
+ * Throw `M91DeliveryError` when an alert reaches nobody. On by default, for
29
+ * the same reason as on `M91Client` — and it bites harder here. A direct
30
+ * alert has a roster of exactly one, so one stale device token is the
31
+ * difference between waking somebody and waking nobody, and the API still
32
+ * answers 201.
33
+ */
34
+ throwOnZeroDelivery?: boolean;
35
+ }
36
+ /** Invite people, alert them one at a time, and provision team channels. */
37
+ export declare class M91Platform {
38
+ readonly baseUrl: string;
39
+ readonly throwOnZeroDelivery: boolean;
40
+ private readonly apiKey;
41
+ private readonly http;
42
+ constructor(apiKey: string, options?: PlatformOptions);
43
+ /** The key is a live credential that can wake people. Only its prefix. */
44
+ toString(): string;
45
+ private url;
46
+ /**
47
+ * Check the key works, and see which key it is. **Alerts nobody.**
48
+ *
49
+ * The only route on this surface that is safe to call just to find out
50
+ * whether a credential works — everything else writes something or needs an
51
+ * id that already exists. On an alerting product, "test the connection" must
52
+ * never mean "wake somebody", so do not verify a key by sending an alert.
53
+ *
54
+ * A revoked key never reaches this route, so a success means *live*, not
55
+ * merely well-formed.
56
+ *
57
+ * Note what it does **not** prove: a perfectly good key with nobody accepted
58
+ * behind it still alerts nobody. Invite a real number and check the state
59
+ * before you believe the integration works.
60
+ */
61
+ verify(): Promise<ApiKeyInfo>;
62
+ /**
63
+ * Invite somebody to accept direct alerts. **Idempotent.**
64
+ *
65
+ * Keyed on the phone number, so calling it on every login is safe and is the
66
+ * intended usage — retries cannot produce a second channel.
67
+ *
68
+ * The returned `state` needs different handling in each case, and the
69
+ * important one is that only `accepted` can actually be woken. A `pending`
70
+ * recipient has been asked and has not answered: nag them in your own UI, do
71
+ * not re-invite them in a loop. `declined` is terminal — no API re-invites a
72
+ * declined number, and only they can undo it from their own app.
73
+ *
74
+ * Inviting is deliberately separate from alerting: **an alert must never be
75
+ * what invites somebody**, because an invited person is not an M91 user yet
76
+ * and the urgent thing would arrive as an ordinary message that does not
77
+ * pierce Do Not Disturb, does not repeat and does not escalate.
78
+ *
79
+ * `label` is **the name the person sees on the alert**, not a name for the
80
+ * person. It is the only thing on their screen saying where the alert came
81
+ * from, so it should be your product — "Acme CRM", not "Priya" and not an id.
82
+ * Woken at 3am, "Acme CRM" answers the question they have and their own name
83
+ * does not.
84
+ *
85
+ * Two things follow, and both bite: it defaults to `"Direct alerts"` when
86
+ * omitted, and **every invite overwrites it**. Since this call belongs in
87
+ * your login handler, omitting the label on the second login resets a good
88
+ * name back to the default. Pass the same constant every time.
89
+ */
90
+ inviteRecipient(phone: string, label?: string): Promise<Recipient>;
91
+ /**
92
+ * Stop alerting somebody. `true` when they are no longer a recipient.
93
+ *
94
+ * Worth wiring to whatever your system calls offboarding. Nothing in an
95
+ * integration is as routinely forgotten, and forgetting it means somebody who
96
+ * left the company is still woken at 3am.
97
+ */
98
+ removeRecipient(phone: string): Promise<boolean>;
99
+ /**
100
+ * Wake one person. They must have been invited **and have accepted**.
101
+ *
102
+ * Alerting a number nobody invited throws `M91NotFoundError`, never a silent
103
+ * invitation.
104
+ *
105
+ * A direct alert *is* a channel with one member, so responses, escalation,
106
+ * deduplication and the consent gate behave exactly as they do for a team —
107
+ * there is no second implementation to keep in step.
108
+ */
109
+ alertPerson(phone: string, title: string, options?: SendOptions): Promise<AlertResponse>;
110
+ /**
111
+ * Read back what one person decided. `null` if there is no such alert.
112
+ * `alertId` is the `customId` you invented or the `_id` a send returned.
113
+ */
114
+ getAlert(alertId: string, phone: string): Promise<AlertDetail | null>;
115
+ /**
116
+ * Close one person's alert.
117
+ *
118
+ * **404 and 403 are success**, as on the send link: "no such alert" and
119
+ * "already resolved" both mean it is not open, which is what was asked for.
120
+ */
121
+ closeAlert(phone: string, options: {
122
+ customId?: string;
123
+ alertId?: string;
124
+ }): Promise<boolean>;
125
+ /**
126
+ * Create a team channel and get back the send link that alerts it.
127
+ *
128
+ * **Not idempotent, and deliberately takes no id of your own to make it so.**
129
+ * Calling this twice makes two channels. Store the returned `id` and
130
+ * `sendLink` against your own team the moment you get them — a lost response
131
+ * is an orphaned channel, not something to retry.
132
+ *
133
+ * `alertOwner: false` skips adding the key's owner as a member: a platform
134
+ * minting one channel per customer team has no reason for its own account to
135
+ * be paged for every one of them. They stay the owner either way.
136
+ */
137
+ /**
138
+ * Every team channel this key can raise an alert on.
139
+ *
140
+ * The missing half of {@link createChannel}, which is **not idempotent**: a
141
+ * platform that lost the response to a create had an orphaned channel and no
142
+ * way to find it. Now it can read back what it already has.
143
+ *
144
+ * **Scoped by send access, not by ownership.** Every row carries a
145
+ * `sendLink`, so the list answers "what can I alert?" — which includes a
146
+ * channel whose owner granted this person send access, not only the ones they
147
+ * created. Creating a channel grants its owner send access too, so owned
148
+ * channels are a subset of this rather than a separate case.
149
+ *
150
+ * Channels they merely joined stay absent: being a member means you get
151
+ * woken, not that you may wake others. Archived channels are left out, since
152
+ * a link that cannot alert anybody is worse than no link.
153
+ */
154
+ listChannels(): Promise<ProvisionedChannel[]>;
155
+ createChannel(name: string, alertOwner?: boolean): Promise<ProvisionedChannel>;
156
+ /**
157
+ * Invite people into a team channel. Up to 500 per call.
158
+ *
159
+ * Adding somebody to the roster is not the same as being able to alert them:
160
+ * they are invited, and an invitation is theirs to accept.
161
+ */
162
+ addMembers(channelId: string, phones: string[]): Promise<InviteResult>;
163
+ /** Take somebody off a team channel's roster. */
164
+ removeMember(channelId: string, phone: string): Promise<boolean>;
165
+ /** Already-not-there is the state the caller asked for. */
166
+ private tolerateMissing;
167
+ }
168
+ /**
169
+ * An API key is told apart from a mobile JWT by its prefix, server-side. So a
170
+ * key without it never reaches the key verifier at all, and comes back as a
171
+ * bare 401 that looks like revocation. Checked here to say what is actually
172
+ * wrong.
173
+ */
174
+ export declare function checkApiKey(apiKey: string): string;
175
+ export declare function checkPhones(phones: string[]): string[];
176
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/platform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,UAAU,EAEf,KAAK,YAAY,EAEjB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EAUf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,aAAa,CAAC;AAE9D,eAAO,MAAM,gBAAgB,8BAA8B,CAAC;AAC5D,eAAO,MAAM,cAAc,WAAW,CAAC;AAEvC,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,4EAA4E;AAC5E,qBAAa,WAAW;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;gBAErB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB;IAUzD,0EAA0E;IAC1E,QAAQ,IAAI,MAAM;IAIlB,OAAO,CAAC,GAAG;IAIX;;;;;;;;;;;;;;OAcG;IACG,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC;IAInC;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAMxE;;;;;;OAMG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOtD;;;;;;;;;OASG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,aAAa,CAAC;IAclG;;;OAGG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAc3E;;;;;OAKG;IACG,UAAU,CACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/C,OAAO,CAAC,OAAO,CAAC;IAwBnB;;;;;;;;;;;OAWG;IACH;;;;;;;;;;;;;;;;OAgBG;IACG,YAAY,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAK7C,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,UAAO,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiBjF;;;;;OAKG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAU5E,iDAAiD;IAC3C,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAStE,2DAA2D;YAC7C,eAAe;CAS9B;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAStD"}