@msg91comm/m91 0.0.0-stage → 1.1.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 (70) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/LICENSE +21 -0
  3. package/README.md +425 -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/index.d.ts +22 -0
  21. package/dist/src/integrations/index.d.ts.map +1 -0
  22. package/dist/src/integrations/index.js +21 -0
  23. package/dist/src/integrations/index.js.map +1 -0
  24. package/dist/src/integrations/langchain.d.ts +43 -0
  25. package/dist/src/integrations/langchain.d.ts.map +1 -0
  26. package/dist/src/integrations/langchain.js +75 -0
  27. package/dist/src/integrations/langchain.js.map +1 -0
  28. package/dist/src/integrations/langgraph.d.ts +79 -0
  29. package/dist/src/integrations/langgraph.d.ts.map +1 -0
  30. package/dist/src/integrations/langgraph.js +114 -0
  31. package/dist/src/integrations/langgraph.js.map +1 -0
  32. package/dist/src/integrations/specs.d.ts +131 -0
  33. package/dist/src/integrations/specs.d.ts.map +1 -0
  34. package/dist/src/integrations/specs.js +156 -0
  35. package/dist/src/integrations/specs.js.map +1 -0
  36. package/dist/src/integrations/vercel-ai.d.ts +36 -0
  37. package/dist/src/integrations/vercel-ai.d.ts.map +1 -0
  38. package/dist/src/integrations/vercel-ai.js +67 -0
  39. package/dist/src/integrations/vercel-ai.js.map +1 -0
  40. package/dist/src/models.d.ts +274 -0
  41. package/dist/src/models.d.ts.map +1 -0
  42. package/dist/src/models.js +383 -0
  43. package/dist/src/models.js.map +1 -0
  44. package/dist/src/platform.d.ts +176 -0
  45. package/dist/src/platform.d.ts.map +1 -0
  46. package/dist/src/platform.js +286 -0
  47. package/dist/src/platform.js.map +1 -0
  48. package/dist/src/url-builder.d.ts +65 -0
  49. package/dist/src/url-builder.d.ts.map +1 -0
  50. package/dist/src/url-builder.js +167 -0
  51. package/dist/src/url-builder.js.map +1 -0
  52. package/examples/approval-gate.ts +35 -0
  53. package/examples/basic-alert.ts +53 -0
  54. package/examples/langchain-agent.ts +65 -0
  55. package/examples/langgraph-hitl.ts +70 -0
  56. package/examples/vercel-ai-agent.ts +34 -0
  57. package/examples/webhook-urls.ts +44 -0
  58. package/package.json +83 -4
  59. package/src/client.ts +324 -0
  60. package/src/exceptions.ts +229 -0
  61. package/src/http.ts +174 -0
  62. package/src/index.ts +91 -0
  63. package/src/integrations/index.ts +23 -0
  64. package/src/integrations/langchain.ts +104 -0
  65. package/src/integrations/langgraph.ts +142 -0
  66. package/src/integrations/specs.ts +224 -0
  67. package/src/integrations/vercel-ai.ts +99 -0
  68. package/src/models.ts +660 -0
  69. package/src/platform.ts +343 -0
  70. package/src/url-builder.ts +225 -0
@@ -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.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,0BAA0B,CAAC;AACxD,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"}
@@ -0,0 +1,286 @@
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 { M91ForbiddenError, M91NotFoundError, M91ValidationError } from './exceptions.js';
21
+ import { Transport } from './http.js';
22
+ import { CHANNEL_NAME_MAX, MAX_MEMBERS_PER_CALL, buildAlertPayload, collapse, parseAlertDetail, parseAlertResponse, parseApiKeyInfo, parseInviteResult, parseProvisionedChannel, parseRecipient, validatePhone, } from './models.js';
23
+ import { checkDelivery } from './client.js';
24
+ export const DEFAULT_BASE_URL = 'https://m91.msg91.com';
25
+ export const API_KEY_PREFIX = 'm91sk_';
26
+ /** Invite people, alert them one at a time, and provision team channels. */
27
+ export class M91Platform {
28
+ baseUrl;
29
+ throwOnZeroDelivery;
30
+ apiKey;
31
+ http;
32
+ constructor(apiKey, options = {}) {
33
+ this.apiKey = checkApiKey(apiKey);
34
+ this.throwOnZeroDelivery = options.throwOnZeroDelivery !== false;
35
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
36
+ this.http = new Transport({
37
+ ...options,
38
+ headers: { authorization: `Bearer ${this.apiKey}`, ...options.headers },
39
+ });
40
+ }
41
+ /** The key is a live credential that can wake people. Only its prefix. */
42
+ toString() {
43
+ return `M91Platform(${this.apiKey.slice(0, 10)}…, ${this.baseUrl})`;
44
+ }
45
+ url(path) {
46
+ return `${this.baseUrl}/api/v1${path}`;
47
+ }
48
+ /**
49
+ * Check the key works, and see which key it is. **Alerts nobody.**
50
+ *
51
+ * The only route on this surface that is safe to call just to find out
52
+ * whether a credential works — everything else writes something or needs an
53
+ * id that already exists. On an alerting product, "test the connection" must
54
+ * never mean "wake somebody", so do not verify a key by sending an alert.
55
+ *
56
+ * A revoked key never reaches this route, so a success means *live*, not
57
+ * merely well-formed.
58
+ *
59
+ * Note what it does **not** prove: a perfectly good key with nobody accepted
60
+ * behind it still alerts nobody. Invite a real number and check the state
61
+ * before you believe the integration works.
62
+ */
63
+ async verify() {
64
+ return parseApiKeyInfo(await this.http.request({ method: 'GET', url: this.url('/me') }));
65
+ }
66
+ /**
67
+ * Invite somebody to accept direct alerts. **Idempotent.**
68
+ *
69
+ * Keyed on the phone number, so calling it on every login is safe and is the
70
+ * intended usage — retries cannot produce a second channel.
71
+ *
72
+ * The returned `state` needs different handling in each case, and the
73
+ * important one is that only `accepted` can actually be woken. A `pending`
74
+ * recipient has been asked and has not answered: nag them in your own UI, do
75
+ * not re-invite them in a loop. `declined` is terminal — no API re-invites a
76
+ * declined number, and only they can undo it from their own app.
77
+ *
78
+ * Inviting is deliberately separate from alerting: **an alert must never be
79
+ * what invites somebody**, because an invited person is not an M91 user yet
80
+ * and the urgent thing would arrive as an ordinary message that does not
81
+ * pierce Do Not Disturb, does not repeat and does not escalate.
82
+ *
83
+ * `label` is **the name the person sees on the alert**, not a name for the
84
+ * person. It is the only thing on their screen saying where the alert came
85
+ * from, so it should be your product — "Acme CRM", not "Priya" and not an id.
86
+ * Woken at 3am, "Acme CRM" answers the question they have and their own name
87
+ * does not.
88
+ *
89
+ * Two things follow, and both bite: it defaults to `"Direct alerts"` when
90
+ * omitted, and **every invite overwrites it**. Since this call belongs in
91
+ * your login handler, omitting the label on the second login resets a good
92
+ * name back to the default. Pass the same constant every time.
93
+ */
94
+ async inviteRecipient(phone, label) {
95
+ const body = { phone: validatePhone(phone) };
96
+ if (label !== undefined && label !== null && collapse(label))
97
+ body.label = collapse(label);
98
+ return parseRecipient(await this.http.request({ method: 'POST', url: this.url('/recipients'), body }));
99
+ }
100
+ /**
101
+ * Stop alerting somebody. `true` when they are no longer a recipient.
102
+ *
103
+ * Worth wiring to whatever your system calls offboarding. Nothing in an
104
+ * integration is as routinely forgotten, and forgetting it means somebody who
105
+ * left the company is still woken at 3am.
106
+ */
107
+ async removeRecipient(phone) {
108
+ return this.tolerateMissing({
109
+ method: 'DELETE',
110
+ url: this.url(`/recipients/${encodeURIComponent(validatePhone(phone))}`),
111
+ });
112
+ }
113
+ /**
114
+ * Wake one person. They must have been invited **and have accepted**.
115
+ *
116
+ * Alerting a number nobody invited throws `M91NotFoundError`, never a silent
117
+ * invitation.
118
+ *
119
+ * A direct alert *is* a channel with one member, so responses, escalation,
120
+ * deduplication and the consent gate behave exactly as they do for a team —
121
+ * there is no second implementation to keep in step.
122
+ */
123
+ async alertPerson(phone, title, options = {}) {
124
+ const body = buildAlertPayload(title, options);
125
+ body.phone = validatePhone(phone);
126
+ const alert = parseAlertResponse(await this.http.request({ method: 'POST', url: this.url('/alerts'), body }));
127
+ // The same guard the send link gets. A person who reinstalled their phone
128
+ // still has an account and still shows as an accepted recipient, so this
129
+ // path answers 201 with delivered: 0 and looks exactly like success — and
130
+ // with one recipient there is nobody else it reached.
131
+ checkDelivery(alert, this.throwOnZeroDelivery);
132
+ return alert;
133
+ }
134
+ /**
135
+ * Read back what one person decided. `null` if there is no such alert.
136
+ * `alertId` is the `customId` you invented or the `_id` a send returned.
137
+ */
138
+ async getAlert(alertId, phone) {
139
+ try {
140
+ const raw = await this.http.request({
141
+ method: 'GET',
142
+ url: this.url(`/alerts/${encodeURIComponent(String(alertId))}`),
143
+ query: { phone: validatePhone(phone) },
144
+ });
145
+ return parseAlertDetail(raw);
146
+ }
147
+ catch (error) {
148
+ if (error instanceof M91NotFoundError)
149
+ return null;
150
+ throw error;
151
+ }
152
+ }
153
+ /**
154
+ * Close one person's alert.
155
+ *
156
+ * **404 and 403 are success**, as on the send link: "no such alert" and
157
+ * "already resolved" both mean it is not open, which is what was asked for.
158
+ */
159
+ async closeAlert(phone, options) {
160
+ const { customId, alertId } = options ?? {};
161
+ if (Boolean(customId) === Boolean(alertId)) {
162
+ throw new M91ValidationError(`closeAlert() needs exactly one of customId or alertId — got ${customId ? 'both' : 'neither'}`);
163
+ }
164
+ try {
165
+ await this.http.request({
166
+ method: 'POST',
167
+ url: this.url('/alerts/close'),
168
+ body: { phone: validatePhone(phone), ...(customId ? { customId } : { alertId }) },
169
+ });
170
+ }
171
+ catch (error) {
172
+ // 403 as well as 404, matching M91Client.close(). Production answers 403
173
+ // `already_resolved` when the alert is closed already, and "it is closed"
174
+ // is the state the caller asked for. Only close gets this: on a REMOVE a
175
+ // 403 means the channel is not yours, which must not be swallowed.
176
+ if (error instanceof M91NotFoundError || error instanceof M91ForbiddenError)
177
+ return true;
178
+ throw error;
179
+ }
180
+ return true;
181
+ }
182
+ /**
183
+ * Create a team channel and get back the send link that alerts it.
184
+ *
185
+ * **Not idempotent, and deliberately takes no id of your own to make it so.**
186
+ * Calling this twice makes two channels. Store the returned `id` and
187
+ * `sendLink` against your own team the moment you get them — a lost response
188
+ * is an orphaned channel, not something to retry.
189
+ *
190
+ * `alertOwner: false` skips adding the key's owner as a member: a platform
191
+ * minting one channel per customer team has no reason for its own account to
192
+ * be paged for every one of them. They stay the owner either way.
193
+ */
194
+ /**
195
+ * Every team channel this key can raise an alert on.
196
+ *
197
+ * The missing half of {@link createChannel}, which is **not idempotent**: a
198
+ * platform that lost the response to a create had an orphaned channel and no
199
+ * way to find it. Now it can read back what it already has.
200
+ *
201
+ * **Scoped by send access, not by ownership.** Every row carries a
202
+ * `sendLink`, so the list answers "what can I alert?" — which includes a
203
+ * channel whose owner granted this person send access, not only the ones they
204
+ * created. Creating a channel grants its owner send access too, so owned
205
+ * channels are a subset of this rather than a separate case.
206
+ *
207
+ * Channels they merely joined stay absent: being a member means you get
208
+ * woken, not that you may wake others. Archived channels are left out, since
209
+ * a link that cannot alert anybody is worse than no link.
210
+ */
211
+ async listChannels() {
212
+ const rows = await this.http.request({ method: 'GET', url: this.url('/channels') });
213
+ return (Array.isArray(rows) ? rows : []).map(parseProvisionedChannel);
214
+ }
215
+ async createChannel(name, alertOwner = true) {
216
+ const clean = collapse(name ?? '');
217
+ if (!clean)
218
+ throw new M91ValidationError('channel name is required');
219
+ if (clean.length > CHANNEL_NAME_MAX) {
220
+ throw new M91ValidationError(`channel name must be ${CHANNEL_NAME_MAX} characters or fewer, got ${clean.length}`);
221
+ }
222
+ return parseProvisionedChannel(await this.http.request({
223
+ method: 'POST',
224
+ url: this.url('/channels'),
225
+ body: { name: clean, alertOwner: alertOwner !== false },
226
+ }));
227
+ }
228
+ /**
229
+ * Invite people into a team channel. Up to 500 per call.
230
+ *
231
+ * Adding somebody to the roster is not the same as being able to alert them:
232
+ * they are invited, and an invitation is theirs to accept.
233
+ */
234
+ async addMembers(channelId, phones) {
235
+ return parseInviteResult(await this.http.request({
236
+ method: 'POST',
237
+ url: this.url(`/channels/${encodeURIComponent(String(channelId))}/members`),
238
+ body: { phones: checkPhones(phones) },
239
+ }));
240
+ }
241
+ /** Take somebody off a team channel's roster. */
242
+ async removeMember(channelId, phone) {
243
+ return this.tolerateMissing({
244
+ method: 'DELETE',
245
+ url: this.url(`/channels/${encodeURIComponent(String(channelId))}/members/${encodeURIComponent(validatePhone(phone))}`),
246
+ });
247
+ }
248
+ /** Already-not-there is the state the caller asked for. */
249
+ async tolerateMissing(request) {
250
+ try {
251
+ await this.http.request(request);
252
+ }
253
+ catch (error) {
254
+ if (error instanceof M91NotFoundError)
255
+ return true;
256
+ throw error;
257
+ }
258
+ return true;
259
+ }
260
+ }
261
+ /**
262
+ * An API key is told apart from a mobile JWT by its prefix, server-side. So a
263
+ * key without it never reaches the key verifier at all, and comes back as a
264
+ * bare 401 that looks like revocation. Checked here to say what is actually
265
+ * wrong.
266
+ */
267
+ export function checkApiKey(apiKey) {
268
+ const key = String(apiKey ?? '').trim();
269
+ if (!key)
270
+ throw new M91ValidationError('apiKey is required');
271
+ if (!key.startsWith(API_KEY_PREFIX)) {
272
+ throw new M91ValidationError(`apiKey must start with '${API_KEY_PREFIX}' — mint one in the M91 app. ` +
273
+ 'A mobile JWT will not work here.');
274
+ }
275
+ return key;
276
+ }
277
+ export function checkPhones(phones) {
278
+ if (!phones?.length)
279
+ throw new M91ValidationError('phones needs at least one number');
280
+ if (phones.length > MAX_MEMBERS_PER_CALL) {
281
+ throw new M91ValidationError(`cannot invite more than ${MAX_MEMBERS_PER_CALL} numbers at once, got ${phones.length}. ` +
282
+ 'Send them in batches.');
283
+ }
284
+ return phones.map(validatePhone);
285
+ }
286
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/platform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The GET form of a send: an alert spelled as a URL.
3
+ *
4
+ * This is the integration surface that needs no client at all. It goes in a
5
+ * browser bar, a phone shortcut, an `<img>` tag, a cron `curl`, a smart button,
6
+ * or any field in any tool labelled "URL to call". Somebody who has never made
7
+ * an HTTP request in their life can raise an alert by tapping a bookmark, and
8
+ * that is the difference between M91 being wired into something today and being
9
+ * wired in never.
10
+ *
11
+ * **A bare send link raises nothing.** It is the connection test: it answers
12
+ * with the channel's name so whoever pasted it can see they picked the right
13
+ * one. Only a URL with `?title=` fires. That is not a default nobody got round
14
+ * to — the token is in the path, so link previews, crawlers and mail scanners
15
+ * fetch these routinely, and `title` having no default is the only thing
16
+ * between a pasted link and a woken team.
17
+ */
18
+ import { type ResponseOption, type Severity } from './models.js';
19
+ /**
20
+ * Validate a send link and strip anything after the token.
21
+ *
22
+ * Callers paste these out of the app, out of a create-channel response, or out
23
+ * of a colleague's message, so a trailing slash, a stray query string or an
24
+ * already-built alert URL all arrive here. All of them normalise to the bare
25
+ * link.
26
+ */
27
+ export declare function normalizeSendLink(sendLink: string): string;
28
+ /**
29
+ * Render `respond=` from labels or response options.
30
+ *
31
+ * The compact syntax exists because `[{label, effect}]` cannot survive a query
32
+ * string without becoming unreadable. So: a comma-separated list where the
33
+ * **first label is SHARED and the rest are PERSONAL** — the shape almost every
34
+ * real alert has, one button that takes the job for the whole group and some
35
+ * number of "seen" buttons that do not. A trailing `!` forces SHARED on any
36
+ * label, for the caller who wants two people able to claim.
37
+ *
38
+ * Two things a link cannot express, both of which throw here rather than
39
+ * producing a URL that quietly does something else: a **PERSONAL first option**,
40
+ * and a label that genuinely **ends in `!`**. Both are reachable with a POST.
41
+ */
42
+ export declare function buildRespond(labels: Array<ResponseOption | string>): string;
43
+ export interface BuildUrlOptions {
44
+ description?: string;
45
+ severity?: Severity;
46
+ customId?: string;
47
+ /** First label is SHARED, the rest PERSONAL. Up to 6. */
48
+ respond?: Array<ResponseOption | string>;
49
+ isAutoClose?: boolean;
50
+ }
51
+ export interface BuildManySpec extends BuildUrlOptions {
52
+ title: string;
53
+ }
54
+ /** Builds ready-to-paste alert URLs for tools whose only field is "URL to call". */
55
+ export declare class M91URLBuilder {
56
+ readonly sendLink: string;
57
+ constructor(sendLink: string);
58
+ /** The bare link. Answers with the channel name and **raises nothing**. */
59
+ testUrl(): string;
60
+ /** A full URL that raises this alert when anything opens it. */
61
+ build(title: string, options?: BuildUrlOptions): string;
62
+ /** One URL per spec. Each takes the same options as `build`. */
63
+ buildMany(alerts: BuildManySpec[]): string[];
64
+ }
65
+ //# sourceMappingURL=url-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-builder.d.ts","sourceRoot":"","sources":["../../src/url-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,QAAQ,EAKd,MAAM,aAAa,CAAC;AAErB;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA+B1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,cAAc,GAAG,MAAM,CAAC,GAAG,MAAM,CAoD3E;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,OAAO,CAAC,EAAE,KAAK,CAAC,cAAc,GAAG,MAAM,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,oFAAoF;AACpF,qBAAa,aAAa;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;IAI5B,2EAA2E;IAC3E,OAAO,IAAI,MAAM;IAIjB,gEAAgE;IAChE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM;IA+C3D,gEAAgE;IAChE,SAAS,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE;CAQ7C"}