primcli 3.0.0-preview.1 → 3.0.0-preview.10
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.
- package/README.md +21 -11
- package/dist/api-command-D0KHkqhA.js +56084 -0
- package/dist/{json-output-BzSBR-KX.js → json-output-ch756TXV.js} +14 -1
- package/dist/{listen-background-C0F9gNDD.js → listen-background-DyBYca28.js} +323 -36
- package/dist/{machine-session-Cp_eQ9t_.js → machine-session-CI8tnGzz.js} +6 -6
- package/dist/{notify-session-BN0JTPZ3.js → notify-session-DN8tSfAi.js} +3 -3
- package/dist/oclif/auto-signal-worker.js +3 -3
- package/dist/oclif/auto-signals.js +1 -1
- package/dist/oclif/command-not-found.js +62 -0
- package/dist/oclif/index.js +10168 -47197
- package/dist/oclif/listen-supervisor.js +1 -1
- package/dist/oclif/proxy-auto-detect.js +1 -1
- package/dist/oclif/receiver-heal.js +4 -3
- package/dist/oclif/root-signup-hint.js +15 -15
- package/dist/{repeats-Dj_o6c-X-Bf9G0xds.js → repeats-Dj_o6c-X-CDaE-kdZ.js} +744 -227
- package/dist/{scoped-chat-DZ42V3jq.js → scoped-chat-C4TDfZND.js} +1 -1
- package/dist/{signal-command-CRUMUCNa.js → signal-command-f5QeK45s.js} +4 -4
- package/man/primitive.1 +20 -4
- package/package.json +18 -6
- package/dist/api-command-ctHBqTL5.js +0 -3634
|
@@ -34,6 +34,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
34
34
|
const client = createClient(createConfig({ baseUrl: "https://api.primitive.dev/v1" }));
|
|
35
35
|
// ../packages/api-core/src/api/sdk.gen.ts
|
|
36
36
|
var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
37
|
+
acceptEmailRuleObjection: () => acceptEmailRuleObjection,
|
|
37
38
|
acceptEmailRuleRequest: () => acceptEmailRuleRequest,
|
|
38
39
|
addDefaultNetworkMember: () => addDefaultNetworkMember,
|
|
39
40
|
addDomain: () => addDomain,
|
|
@@ -52,6 +53,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
52
53
|
cancelSentEmailByIdempotencyKey: () => cancelSentEmailByIdempotencyKey,
|
|
53
54
|
checkDefaultNetworkContactAdmission: () => checkDefaultNetworkContactAdmission,
|
|
54
55
|
checkDomainDns: () => checkDomainDns,
|
|
56
|
+
checkEmailRuleRequestTarget: () => checkEmailRuleRequestTarget,
|
|
55
57
|
checkSendability: () => checkSendability,
|
|
56
58
|
checkVanityInboxName: () => checkVanityInboxName,
|
|
57
59
|
claimAgentConnection: () => claimAgentConnection,
|
|
@@ -63,6 +65,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
63
65
|
createAgentClaimLink: () => createAgentClaimLink,
|
|
64
66
|
createAgentConnection: () => createAgentConnection,
|
|
65
67
|
createEmailRule: () => createEmailRule,
|
|
68
|
+
createEmailRuleObjection: () => createEmailRuleObjection,
|
|
66
69
|
createEmailRuleRequest: () => createEmailRuleRequest,
|
|
67
70
|
createEndpoint: () => createEndpoint,
|
|
68
71
|
createFilter: () => createFilter,
|
|
@@ -78,6 +81,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
78
81
|
createWakeSchedule: () => createWakeSchedule,
|
|
79
82
|
decideAccessMode: () => decideAccessMode,
|
|
80
83
|
decideSuspension: () => decideSuspension,
|
|
84
|
+
declineEmailRuleObjection: () => declineEmailRuleObjection,
|
|
81
85
|
declineEmailRuleRequest: () => declineEmailRuleRequest,
|
|
82
86
|
deleteAddressNote: () => deleteAddressNote,
|
|
83
87
|
deleteAgentContact: () => deleteAgentContact,
|
|
@@ -85,6 +89,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
85
89
|
deleteDomain: () => deleteDomain,
|
|
86
90
|
deleteEmail: () => deleteEmail,
|
|
87
91
|
deleteEmailRule: () => deleteEmailRule,
|
|
92
|
+
deleteEmailRuleRequest: () => deleteEmailRuleRequest,
|
|
88
93
|
deleteEndpoint: () => deleteEndpoint,
|
|
89
94
|
deleteFilter: () => deleteFilter,
|
|
90
95
|
deleteFunction: () => deleteFunction,
|
|
@@ -112,6 +117,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
112
117
|
downloadSentAttachments: () => downloadSentAttachments,
|
|
113
118
|
endBreakGlass: () => endBreakGlass,
|
|
114
119
|
endEmailRuleShare: () => endEmailRuleShare,
|
|
120
|
+
generateLookAlikes: () => generateLookAlikes,
|
|
115
121
|
getAccessMode: () => getAccessMode,
|
|
116
122
|
getAccount: () => getAccount,
|
|
117
123
|
getAddressNote: () => getAddressNote,
|
|
@@ -128,8 +134,14 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
128
134
|
getEmail: () => getEmail,
|
|
129
135
|
getEmailReadable: () => getEmailReadable,
|
|
130
136
|
getEmailRule: () => getEmailRule,
|
|
137
|
+
getEmailRuleCoveringMe: () => getEmailRuleCoveringMe,
|
|
138
|
+
getEmailRuleObjection: () => getEmailRuleObjection,
|
|
131
139
|
getEmailRuleRequest: () => getEmailRuleRequest,
|
|
140
|
+
getEmailRuleScope: () => getEmailRuleScope,
|
|
132
141
|
getEmailRuleShare: () => getEmailRuleShare,
|
|
142
|
+
getEmailRuleVocabulary: () => getEmailRuleVocabulary,
|
|
143
|
+
getEndpoint: () => getEndpoint,
|
|
144
|
+
getEndpointSigningSecret: () => getEndpointSigningSecret,
|
|
133
145
|
getFunction: () => getFunction,
|
|
134
146
|
getFunctionDeployment: () => getFunctionDeployment,
|
|
135
147
|
getFunctionInvocation: () => getFunctionInvocation,
|
|
@@ -159,6 +171,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
159
171
|
getRelayAutoJoin: () => getRelayAutoJoin,
|
|
160
172
|
getRepeatingSend: () => getRepeatingSend,
|
|
161
173
|
getSearchSettings: () => getSearchSettings,
|
|
174
|
+
getSendFrom: () => getSendFrom,
|
|
162
175
|
getSendPermissions: () => getSendPermissions,
|
|
163
176
|
getSentEmail: () => getSentEmail,
|
|
164
177
|
getSentHourlyStats: () => getSentHourlyStats,
|
|
@@ -174,6 +187,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
174
187
|
inviteOrganizationMember: () => inviteOrganizationMember,
|
|
175
188
|
inviteProjectMember: () => inviteProjectMember,
|
|
176
189
|
leaveOrganization: () => leaveOrganization,
|
|
190
|
+
listActivityObjects: () => listActivityObjects,
|
|
177
191
|
listAddressNotes: () => listAddressNotes,
|
|
178
192
|
listAddressNotesBatch: () => listAddressNotesBatch,
|
|
179
193
|
listAgentConnections: () => listAgentConnections,
|
|
@@ -191,10 +205,16 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
191
205
|
listDomains: () => listDomains,
|
|
192
206
|
listEmailAttachmentArchiveMembers: () => listEmailAttachmentArchiveMembers,
|
|
193
207
|
listEmailRuleDecisions: () => listEmailRuleDecisions,
|
|
208
|
+
listEmailRuleDecisionsOnMyMail: () => listEmailRuleDecisionsOnMyMail,
|
|
209
|
+
listEmailRuleObjections: () => listEmailRuleObjections,
|
|
194
210
|
listEmailRuleRequests: () => listEmailRuleRequests,
|
|
211
|
+
listEmailRuleResults: () => listEmailRuleResults,
|
|
212
|
+
listEmailRuleScopeOptions: () => listEmailRuleScopeOptions,
|
|
195
213
|
listEmailRuleShareEmails: () => listEmailRuleShareEmails,
|
|
196
214
|
listEmailRuleShares: () => listEmailRuleShares,
|
|
215
|
+
listEmailRuleVersions: () => listEmailRuleVersions,
|
|
197
216
|
listEmailRules: () => listEmailRules,
|
|
217
|
+
listEmailRulesCoveringMe: () => listEmailRulesCoveringMe,
|
|
198
218
|
listEmails: () => listEmails,
|
|
199
219
|
listEndpoints: () => listEndpoints,
|
|
200
220
|
listFilters: () => listFilters,
|
|
@@ -272,6 +292,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
272
292
|
revokeOAuthGrant: () => revokeOAuthGrant,
|
|
273
293
|
revokeOrganizationInvitation: () => revokeOrganizationInvitation,
|
|
274
294
|
revokeProjectInvitation: () => revokeProjectInvitation,
|
|
295
|
+
rotateEndpointSigningSecret: () => rotateEndpointSigningSecret,
|
|
275
296
|
rotateKey: () => rotateKey,
|
|
276
297
|
rotateWebhookSecret: () => rotateWebhookSecret,
|
|
277
298
|
runWakeSchedule: () => runWakeSchedule,
|
|
@@ -340,6 +361,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
340
361
|
verifyCliSignup: () => verifyCliSignup,
|
|
341
362
|
verifyDomain: () => verifyDomain,
|
|
342
363
|
whoami: () => whoami,
|
|
364
|
+
withdrawEmailRuleObjection: () => withdrawEmailRuleObjection,
|
|
343
365
|
withdrawEmailRuleRequest: () => withdrawEmailRuleRequest
|
|
344
366
|
});
|
|
345
367
|
/**
|
|
@@ -626,7 +648,7 @@ const getAccount = (options) => (options?.client ?? client).get({
|
|
|
626
648
|
/**
|
|
627
649
|
* Update account settings
|
|
628
650
|
*
|
|
629
|
-
* Update the
|
|
651
|
+
* Update the organization's spam threshold (spam_threshold) and whether an email's content is discarded once a webhook confirms receipt (discard_content_on_webhook_confirmed), the opt-in POST /emails/{id}/discard-content needs.
|
|
630
652
|
*/
|
|
631
653
|
const updateAccount = (options) => (options.client ?? client).patch({
|
|
632
654
|
security: [{
|
|
@@ -660,10 +682,7 @@ const getStorageStats = (options) => (options?.client ?? client).get({
|
|
|
660
682
|
* secret exists yet, one is generated automatically on first
|
|
661
683
|
* access.
|
|
662
684
|
*
|
|
663
|
-
*
|
|
664
|
-
* delivery from any of your registered endpoints is signed
|
|
665
|
-
* with this single secret. Rotate via
|
|
666
|
-
* `POST /account/webhook-secret/rotate`.
|
|
685
|
+
* Every webhook is signed with this secret unless it has its own. Rotate this secret via `POST /account/webhook-secret/rotate`. A webhook whose signed_with is own_secret is signed with its own secret instead; read it from GET /endpoints/{id}/signing-secret. A webhook's own secret rotates via `POST /endpoints/{id}/signing-secret/rotate`.
|
|
667
686
|
*
|
|
668
687
|
* **Secret format**: the returned string looks base64-shaped
|
|
669
688
|
* (e.g. `XNHBBW8VqoBjRfNs1tkZj11jTk...`) but is NOT base64.
|
|
@@ -1208,15 +1227,10 @@ const listEndpoints = (options) => (options?.client ?? client).get({
|
|
|
1208
1227
|
/**
|
|
1209
1228
|
* Create a webhook endpoint
|
|
1210
1229
|
*
|
|
1211
|
-
* Creates a new webhook endpoint.
|
|
1212
|
-
* with the same URL and domain exists, it is reactivated
|
|
1213
|
-
* instead. Subject to plan limits on the number of active
|
|
1230
|
+
* Creates a new webhook endpoint. A URL can have one endpoint per domain, route targets included (unlike the one default destination per domain), and endpoints with no domain_id count as one domain. A disabled endpoint still holds its URL; a deleted one does not. A create at a URL another endpoint has on the same domain is refused (400). A deleted endpoint's URL can be used again: the create makes a new endpoint, with a new id, and the deleted one stays as it was. Subject to plan limits on the number of active
|
|
1214
1231
|
* endpoints.
|
|
1215
1232
|
*
|
|
1216
|
-
* **Signing is account-
|
|
1217
|
-
* does not return any signing material; every endpoint on the
|
|
1218
|
-
* account uses the same webhook secret, fetched via
|
|
1219
|
-
* `GET /account/webhook-secret`. See the API-level "Webhook
|
|
1233
|
+
* **Signing.** A webhook is signed with the organization's webhook secret (`GET /account/webhook-secret`) unless it has its own. A webhook made as a person's own, or by an API key limited to some mailboxes, a third-party app or an agent delegate for itself, is made with its own secret: the response carries it once as `signing_secret`, and `GET /endpoints/{id}/signing-secret` returns it afterwards. Other webhooks, those a person who can read every mailbox makes among them, sign with the organization's secret until given their own. `signed_with` on the endpoint says which secret signs it. See the API-level "Webhook
|
|
1220
1234
|
* signing" section for the full wire format (header name,
|
|
1221
1235
|
* signed string, hash algo, secret format, tolerance) and a
|
|
1222
1236
|
* language-agnostic verification recipe.
|
|
@@ -1260,14 +1274,27 @@ const deleteEndpoint = (options) => (options.client ?? client).delete({
|
|
|
1260
1274
|
...options
|
|
1261
1275
|
});
|
|
1262
1276
|
/**
|
|
1277
|
+
* Get an endpoint
|
|
1278
|
+
*
|
|
1279
|
+
* One endpoint, as GET /endpoints shows it, to a caller who would see it there. Any other id, a deleted endpoint's included, answers 404. For a webhook, delivery says whether it is being sent received mail at all, why not, and how much rule-granted mail is held while its owner cannot act.
|
|
1280
|
+
*/
|
|
1281
|
+
const getEndpoint = (options) => (options.client ?? client).get({
|
|
1282
|
+
security: [{
|
|
1283
|
+
scheme: "bearer",
|
|
1284
|
+
type: "http"
|
|
1285
|
+
}],
|
|
1286
|
+
url: "/endpoints/{id}",
|
|
1287
|
+
...options
|
|
1288
|
+
});
|
|
1289
|
+
/**
|
|
1263
1290
|
* Update a webhook endpoint
|
|
1264
1291
|
*
|
|
1265
|
-
* Updates an active webhook endpoint.
|
|
1266
|
-
* endpoint is deactivated and a new one is created (or an existing
|
|
1267
|
-
* deactivated endpoint with the new URL is reactivated).
|
|
1292
|
+
* Updates an active webhook endpoint. Changing the URL keeps the endpoint: its id, recipient routes, signing secret, delivery history and any deliveries still owed to it stay with it, and owed deliveries go to the new URL. A URL can have one endpoint per domain, route targets included (unlike the one default destination per domain), and endpoints with no domain_id count as one domain. A disabled endpoint still holds its URL; a deleted one does not. A change onto a URL another endpoint has on the same domain is refused (400), and a move onto a domain where another endpoint has this URL is refused (409).
|
|
1268
1293
|
*
|
|
1269
1294
|
*
|
|
1270
1295
|
* Pull destinations cannot be assigned a URL, function or recipient-routing domain. Existing endpoint deletion disconnects the destination; creating a new destination does not backfill historical events.
|
|
1296
|
+
*
|
|
1297
|
+
* Giving a webhook the organization does not own to a different key (owner_key_id), or a key's webhook back to the organization (owner_key_id null), turns it off unless the request also sets enabled: its URL was chosen under its previous owner. It then reads enabled false with disabled_reason owner_changed, and turning it on or giving it a new URL starts it again. A key that carries on for the owning key through rotation (its successor, at any depth up to 16 rotations) is not a different key: the webhook stays as it was, with the same signing secret. That does not hold when the owning key was made from a key a transfer moved or rotated away, or from one that has since been deleted: no successor carries on for it. The answer's warnings name each such change (turned_off_owner_changed, turned_on_new_url), so a client can say so.
|
|
1271
1298
|
*/
|
|
1272
1299
|
const updateEndpoint = (options) => (options.client ?? client).patch({
|
|
1273
1300
|
security: [{
|
|
@@ -1324,6 +1351,8 @@ const completeWebhookEvent = (options) => (options.client ?? client).post({
|
|
|
1324
1351
|
* Successful deliveries and verified-domain endpoints are exempt
|
|
1325
1352
|
* from the rate limit.
|
|
1326
1353
|
*
|
|
1354
|
+
*
|
|
1355
|
+
* The test is sent whether or not real mail would be. reachable says whether the endpoint answered it with a 2xx; delivery says, apart from that, whether real email.received events would be sent to the endpoint by its own conditions (on, not held, an owner that can receive mail, subscribed to the event), with every reason it would not be. A 200 from the test alone does not mean mail arrives.
|
|
1327
1356
|
*/
|
|
1328
1357
|
const testEndpoint = (options) => (options.client ?? client).post({
|
|
1329
1358
|
security: [{
|
|
@@ -1357,6 +1386,8 @@ const testEndpoint = (options) => (options.client ?? client).post({
|
|
|
1357
1386
|
* delivered as if unfiltered), so `rules_valid: false` exposes a
|
|
1358
1387
|
* misconfiguration that is otherwise silent.
|
|
1359
1388
|
*
|
|
1389
|
+
*
|
|
1390
|
+
* would_deliver also covers the endpoint's own delivery conditions for this email (delivery): it is on, neither it nor the email's route is held, its owner may receive this email, and it subscribes to the event. Which endpoint routing sends the email to is decided separately: POST /routes/simulate answers that. A 503 means those conditions could not be read just now; retry.
|
|
1360
1391
|
*/
|
|
1361
1392
|
const testEndpointRules = (options) => (options.client ?? client).post({
|
|
1362
1393
|
security: [{
|
|
@@ -1629,6 +1660,7 @@ const listRoutes = (options) => (options?.client ?? client).get({
|
|
|
1629
1660
|
* transaction, enabling per-address function routing (e.g.
|
|
1630
1661
|
* `alice@acme.com -> functionA`).
|
|
1631
1662
|
*
|
|
1663
|
+
* A route that could never deliver is refused: an exact pattern that the endpoint's owner may not receive, or that the route's own owner may not act on, answers 400 validation_error with details.reason endpoint_owner_access or route_owner_access and details.recipient. A wildcard or regex route to an owned endpoint is written, with warnings saying it delivers only what the owner may receive. A route written disabled is judged when it is turned on.
|
|
1632
1664
|
*/
|
|
1633
1665
|
const createRoute = (options) => (options.client ?? client).post({
|
|
1634
1666
|
security: [{
|
|
@@ -1694,7 +1726,7 @@ const deleteRoute = (options) => (options.client ?? client).delete({
|
|
|
1694
1726
|
/**
|
|
1695
1727
|
* Update a recipient route
|
|
1696
1728
|
*
|
|
1697
|
-
*
|
|
1729
|
+
* A route that could never deliver is refused: an exact pattern that the endpoint's owner may not receive, or that the route's own owner may not act on, answers 400 validation_error with details.reason endpoint_owner_access or route_owner_access and details.recipient. A wildcard or regex route to an owned endpoint is written, with warnings saying it delivers only what the owner may receive. A route written disabled is judged when it is turned on.
|
|
1698
1730
|
*/
|
|
1699
1731
|
const updateRoute = (options) => (options.client ?? client).patch({
|
|
1700
1732
|
security: [{
|
|
@@ -1976,7 +2008,7 @@ const listSentEmails = (options) => (options?.client ?? client).get({
|
|
|
1976
2008
|
/**
|
|
1977
2009
|
* Delete a sent email
|
|
1978
2010
|
*
|
|
1979
|
-
* Permanently deletes eligible sender mailbox history and its owned attachment archive and transient payload. Allows delivered, bounced, agent_failed, gate_denied, canceled, deferred and wait_timeout; other states return 409 (cancel scheduled sends first). Preserves recipient copies, received replies and independent interaction/delivery audit. This does not recall or cancel delivery already admitted. A minimal non-content record preserves occupied idempotency keys and delivered-reply deduplication. Keys already released by cancellation, gate denial or a never-attempted failure remain reusable; deleting those records does not revoke their existing retry permission. Repeating a completed deletion returns success;
|
|
2011
|
+
* Permanently deletes eligible sender mailbox history and its owned attachment archive and transient payload. Allows delivered, bounced, agent_failed, gate_denied, canceled, deferred and wait_timeout; other states return 409 (cancel scheduled sends first). Preserves recipient copies, received replies and independent interaction/delivery audit. This does not recall or cancel delivery already admitted. A minimal non-content record preserves occupied idempotency keys and delivered-reply deduplication. Keys already released by cancellation, gate denial or a never-attempted failure remain reusable; deleting those records does not revoke their existing retry permission. Unknown IDs return 404. Needs sent:manage, and follows mail access rather than role: a caller with the whole organization's mail (an owner, admin or member whose access covers every mailbox, or an organization-wide key) can delete any send in the organization; a caller limited to some mailboxes, an owner or admin included, can delete only sends from addresses its access covers, made since that access starts (a member limited to their own mail: their own), and any other send returns 404. Repeating a completed deletion returns success; for a caller limited to some mailboxes, only when the send was from an address its access names one by one, otherwise 404. Organization API keys, sessions and OAuth are supported; Function and connected-agent credentials are denied.
|
|
1980
2012
|
*/
|
|
1981
2013
|
const deleteSentEmail = (options) => (options.client ?? client).delete({
|
|
1982
2014
|
security: [{
|
|
@@ -3035,7 +3067,7 @@ const putAgentContactPolicy = (options) => (options.client ?? client).put({
|
|
|
3035
3067
|
/**
|
|
3036
3068
|
* Get current caller identity
|
|
3037
3069
|
*
|
|
3038
|
-
* Current authenticated identity. member_address is null for machine credentials or an unavailable member address.
|
|
3070
|
+
* Current authenticated identity. member_address is null for machine credentials or an unavailable member address. email (your own sign-in email) and role_name (your role as the members list labels it) are set only when you are signed in as yourself, in the dashboard or with your own Primitive CLI or app login, and are null for API keys, Functions, connected agents, agent signup logins and other apps acting for you.
|
|
3039
3071
|
*/
|
|
3040
3072
|
const whoami = (options) => (options?.client ?? client).get({
|
|
3041
3073
|
security: [{
|
|
@@ -3575,9 +3607,35 @@ const getWebhookDeliveryStats = (options) => (options?.client ?? client).get({
|
|
|
3575
3607
|
...options
|
|
3576
3608
|
});
|
|
3577
3609
|
/**
|
|
3610
|
+
* List what you created, or what you were asked
|
|
3611
|
+
*
|
|
3612
|
+
* The objects the caller created, newest first, each with where it stands now, including ones since disabled, deleted or revoked where the object keeps a row: Functions, endpoints, Function triggers, pull subscriptions, recipient routes, filters, wake schedules, repeating sends and scheduled sends. An API key, an app or an agent sees what it created itself; a webhook given to an API key lists under that key. A person (a dashboard session, or their own Primitive CLI or app login) sees what they created through any credential of theirs, each item naming it, and also their API keys, personal agents, email rules, rule requests and objections to rules over their mail (objections only on the dashboard or the Primitive CLI). Each kind is listed only if the caller could list it through that kind's own route; a kind it could not is named in withheld, with no count. Ids, names and states only: never a webhook URL or mail content. Needs activity:read_self. With relation=asked it lists instead what other members asked of the person, open or answered: the rule requests made to them, and the objections to rules they wrote, under their current membership, each naming the member who asked or objected in created_through. A key, an app or an agent has none, and gets both kinds in withheld.
|
|
3613
|
+
*/
|
|
3614
|
+
const listActivityObjects = (options) => (options?.client ?? client).get({
|
|
3615
|
+
security: [{
|
|
3616
|
+
scheme: "bearer",
|
|
3617
|
+
type: "http"
|
|
3618
|
+
}],
|
|
3619
|
+
url: "/activity/objects",
|
|
3620
|
+
...options
|
|
3621
|
+
});
|
|
3622
|
+
/**
|
|
3623
|
+
* Read the column catalog
|
|
3624
|
+
*
|
|
3625
|
+
* What a rule tree you write yourself can say: each column of the current vocabulary with its type, source, meaning, operators and the value each takes, options, and whether it takes min_confidence; and the tree's limits, its stored size included. Built from the checks a saved or tested tree must pass. A tree is {version: tree_version, vocabulary: version, when, questions}. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3626
|
+
*/
|
|
3627
|
+
const getEmailRuleVocabulary = (options) => (options?.client ?? client).get({
|
|
3628
|
+
security: [{
|
|
3629
|
+
scheme: "bearer",
|
|
3630
|
+
type: "http"
|
|
3631
|
+
}],
|
|
3632
|
+
url: "/email-rules/vocabulary",
|
|
3633
|
+
...options
|
|
3634
|
+
});
|
|
3635
|
+
/**
|
|
3578
3636
|
* Compile a rule description
|
|
3579
3637
|
*
|
|
3580
|
-
* Turns a plain-English description of which received emails to match into a rule tree over the
|
|
3638
|
+
* Turns a plain-English description of which received emails to match into a rule tree over the column contract, with an explanation of what it matches, the assumptions made, and warnings for what the columns cannot express. Where the columns fall short it adds up to five yes/no questions, asked only after the conditions match; they read the subject, the new text and attachment file names, never attachment contents. Nothing is saved. For a rule with no questions, breadth counts, read only, how much of your recent classified mail its conditions match. include_sql returns the SQL it renders to. kind do_not_share compiles for recall. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3581
3639
|
*/
|
|
3582
3640
|
const compileEmailRule = (options) => (options.client ?? client).post({
|
|
3583
3641
|
security: [{
|
|
@@ -3594,7 +3652,7 @@ const compileEmailRule = (options) => (options.client ?? client).post({
|
|
|
3594
3652
|
/**
|
|
3595
3653
|
* Test a rule against received mail
|
|
3596
3654
|
*
|
|
3597
|
-
* Runs a rule over received mail and reports what it would decide for each email
|
|
3655
|
+
* Runs a rule over received mail and reports what it would decide for each email (matched, near_miss, no_match, unclassified, skipped or not_found), with a summary of how each top-level condition and question decided. Test an unsaved tree, or a saved rule by rule_id (its current version, as its author). It reads only mail its author can read and its scope covers. Without email_ids it tests the newest emails, at most 200 and none older than 30 days, plus any expected ones. Unclassified emails over 2 hours old are classified first unless classify_missing is false. It records no decision and grants nothing, and stops at about 90 seconds. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3598
3656
|
*/
|
|
3599
3657
|
const testEmailRule = (options) => (options.client ?? client).post({
|
|
3600
3658
|
security: [{
|
|
@@ -3609,9 +3667,26 @@ const testEmailRule = (options) => (options.client ?? client).post({
|
|
|
3609
3667
|
}
|
|
3610
3668
|
});
|
|
3611
3669
|
/**
|
|
3670
|
+
* Write look-alike emails a rule should or should not match
|
|
3671
|
+
*
|
|
3672
|
+
* Writes made-up emails that come close to what a grant rule describes, and reports what the rule decides for each, as test-sample would. Most should not match (expected no_match): business near misses from its senders and topic (kind other: an all-clear, a reply with nothing new, a related document, another subject) and private mail (a personal medical bill, pay for named people, a personal purchase, personal banking or tax). By default a third, rounded down, are near cases it should match (expected match, kind other). failed means the rule decided one against expected. Nothing is stored and no mail is read. Keep them, with their expected, with add_expectation_samples, or for a request with the accept's expectation_samples. Limited to 20 an hour per member. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3673
|
+
*/
|
|
3674
|
+
const generateLookAlikes = (options) => (options.client ?? client).post({
|
|
3675
|
+
security: [{
|
|
3676
|
+
scheme: "bearer",
|
|
3677
|
+
type: "http"
|
|
3678
|
+
}],
|
|
3679
|
+
url: "/email-rules/look-alikes",
|
|
3680
|
+
...options,
|
|
3681
|
+
headers: {
|
|
3682
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
3683
|
+
...options.headers
|
|
3684
|
+
}
|
|
3685
|
+
});
|
|
3686
|
+
/**
|
|
3612
3687
|
* Test a rule against a made-up email
|
|
3613
3688
|
*
|
|
3614
|
-
* Reports what a rule would decide for an email you describe
|
|
3689
|
+
* Reports what a rule would decide for an email you describe (sender, recipients, subject, plain text, attachment types; optionally automated, from a mailing list, and a spam score), classified and decided as received mail would be. A rule reading a spam score you gave none for decides on none (unset_columns). Nothing is stored. Test an unsaved tree or a saved rule by rule_id. The answer includes what the classifier read. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3615
3690
|
*/
|
|
3616
3691
|
const testEmailRuleOnSample = (options) => (options.client ?? client).post({
|
|
3617
3692
|
security: [{
|
|
@@ -3628,7 +3703,7 @@ const testEmailRuleOnSample = (options) => (options.client ?? client).post({
|
|
|
3628
3703
|
/**
|
|
3629
3704
|
* List rules
|
|
3630
3705
|
*
|
|
3631
|
-
* The rules the caller can see, newest first: their own, or every member's rules for a caller who reads the whole organization's mail. With matched_email_id, only the rules that matched that email. Needs mail:read, a
|
|
3706
|
+
* The rules the caller can see, newest first: their own, or every member's rules for a caller who reads the whole organization's mail. Each carries its scope (evaluation_scope, and scope_selection for a selected rule) and current_version, but not the version's text: read that under current from GET /email-rules/{id}. With matched_email_id, only the rules that matched that email. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3632
3707
|
*/
|
|
3633
3708
|
const listEmailRules = (options) => (options?.client ?? client).get({
|
|
3634
3709
|
security: [{
|
|
@@ -3641,7 +3716,7 @@ const listEmailRules = (options) => (options?.client ?? client).get({
|
|
|
3641
3716
|
/**
|
|
3642
3717
|
* Create a rule
|
|
3643
3718
|
*
|
|
3644
|
-
* Saves a rule as version 1
|
|
3719
|
+
* Saves a rule as version 1 from a compile response or a tree you wrote, checked against the column contract. It starts in observe (recorded, nothing granted or blocked) unless state is draft, or active for a do_not_share rule. You are its author, and it never reaches mail you cannot read. evaluation_scope is own_mailboxes unless you name author or selected (scope_selection names only what you can read). expectations are judged in expectations_check. kind do_not_share blocks sharing what it matches; a key cannot list it (details.reason rule_blocks_sharing). Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3645
3720
|
*/
|
|
3646
3721
|
const createEmailRule = (options) => (options.client ?? client).post({
|
|
3647
3722
|
security: [{
|
|
@@ -3658,7 +3733,7 @@ const createEmailRule = (options) => (options.client ?? client).post({
|
|
|
3658
3733
|
/**
|
|
3659
3734
|
* Delete a rule
|
|
3660
3735
|
*
|
|
3661
|
-
* Deletes a rule with its versions, its decisions and the access it granted. The
|
|
3736
|
+
* Deletes a rule with its versions, its decisions and the access it granted. A share of it ends (end_reason rule_deleted), and the member who shared can still list what it handed over. The answer lists the shares it ended (ended_shares) and the unrevoked keys that still list it, which now read nothing through it (keys, other_keys; left out when they could not be read). The author or a reader of all the organization's mail may delete it; while it is shared, only the author or someone who manages members from the dashboard. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3662
3737
|
*/
|
|
3663
3738
|
const deleteEmailRule = (options) => (options.client ?? client).delete({
|
|
3664
3739
|
security: [{
|
|
@@ -3671,7 +3746,7 @@ const deleteEmailRule = (options) => (options.client ?? client).delete({
|
|
|
3671
3746
|
/**
|
|
3672
3747
|
* Read a rule
|
|
3673
3748
|
*
|
|
3674
|
-
* A rule and its current version. The SQL the version renders to is included only when include_sql is true. Needs mail:read, a
|
|
3749
|
+
* A rule, its scope (evaluation_scope, and scope_selection for a selected rule), its current version and its saved expectations. The current version's text (english, tree, explanation, assumptions, warnings) is under current, and current_version is its number. What the scope comes to for its author now is GET /email-rules/{id}/scope. The SQL the version renders to is included only when include_sql is true. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3675
3750
|
*/
|
|
3676
3751
|
const getEmailRule = (options) => (options.client ?? client).get({
|
|
3677
3752
|
security: [{
|
|
@@ -3684,7 +3759,7 @@ const getEmailRule = (options) => (options.client ?? client).get({
|
|
|
3684
3759
|
/**
|
|
3685
3760
|
* Change a rule
|
|
3686
3761
|
*
|
|
3687
|
-
* Renames the rule, saves a new version (english
|
|
3762
|
+
* Renames the rule, saves a new version (english and tree together; earlier versions stay) or restores one (restore_version), changes its state (draft is off; observe; active), its scope (evaluation_scope, with scope_selection when selected) or its saved expectations (judged in expectations_check). Anyone but its author who sees it may only set state draft, and while it is shared only if they manage members from the dashboard. A scope change saves a new version; a shared rule keeps its scope, and a kind never changes. A saved version takes effect at once. if_version refuses a write once a version was saved since you read it; if_revision, once anything changed. Without if_expectations_pass a version is saved even when its expectations fail. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3688
3763
|
*/
|
|
3689
3764
|
const updateEmailRule = (options) => (options.client ?? client).patch({
|
|
3690
3765
|
security: [{
|
|
@@ -3701,7 +3776,7 @@ const updateEmailRule = (options) => (options.client ?? client).patch({
|
|
|
3701
3776
|
/**
|
|
3702
3777
|
* List a rule's decisions
|
|
3703
3778
|
*
|
|
3704
|
-
* What the rule decided for each email it was evaluated against, newest first: whether it matched, whether it nearly did, how each part decided and the answers to its questions. Only decisions on emails the caller can read are listed. With matched, only matches (true) or only the rest (false). Needs mail:read, a
|
|
3779
|
+
* What the rule decided for each email it was evaluated against, newest first: whether it matched, whether it nearly did, how each part decided and the answers to its questions, with which email it was (from_address, subject, received_at). Only decisions on emails the caller can read are listed. With matched, only matches (true) or only the rest (false). Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3705
3780
|
*/
|
|
3706
3781
|
const listEmailRuleDecisions = (options) => (options.client ?? client).get({
|
|
3707
3782
|
security: [{
|
|
@@ -3712,9 +3787,61 @@ const listEmailRuleDecisions = (options) => (options.client ?? client).get({
|
|
|
3712
3787
|
...options
|
|
3713
3788
|
});
|
|
3714
3789
|
/**
|
|
3790
|
+
* List every rule's result on an email
|
|
3791
|
+
*
|
|
3792
|
+
* What each rule you can see decided about this email (matched, not matched, or not run), in the words of the deciding version. A do_not_share rule that matched it blocks sharing while active; earlier shares stay. Only a caller who can read the email gets an answer. classification is every fact the classifier read, as rule conditions read it. At most 50 rules are listed, results first; not_listed counts the rest. Another member's rule that decided on your own mail is listed read_only (dashboard and CLI only); hidden counts deciding rules you cannot see. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3793
|
+
*/
|
|
3794
|
+
const listEmailRuleResults = (options) => (options.client ?? client).get({
|
|
3795
|
+
security: [{
|
|
3796
|
+
scheme: "bearer",
|
|
3797
|
+
type: "http"
|
|
3798
|
+
}],
|
|
3799
|
+
url: "/emails/{id}/rule-results",
|
|
3800
|
+
...options
|
|
3801
|
+
});
|
|
3802
|
+
/**
|
|
3803
|
+
* Read versions of a rule
|
|
3804
|
+
*
|
|
3805
|
+
* A rule's versions as they were written: what each one's conditions and questions were, so a decision can be read against the version that made it. Without versions, every version newest first, a page at a time (meta.cursor). With versions, only those named, oldest first; numbers that are not versions of the rule are left out. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3806
|
+
*/
|
|
3807
|
+
const listEmailRuleVersions = (options) => (options.client ?? client).get({
|
|
3808
|
+
security: [{
|
|
3809
|
+
scheme: "bearer",
|
|
3810
|
+
type: "http"
|
|
3811
|
+
}],
|
|
3812
|
+
url: "/email-rules/{id}/versions",
|
|
3813
|
+
...options
|
|
3814
|
+
});
|
|
3815
|
+
/**
|
|
3816
|
+
* Read what a rule covers
|
|
3817
|
+
*
|
|
3818
|
+
* Whose mail the rule runs over, and what that comes to now: a rule never reaches further than what its author can read when it runs, so what a selected rule names and its author can no longer read stops matching. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3819
|
+
*/
|
|
3820
|
+
const getEmailRuleScope = (options) => (options.client ?? client).get({
|
|
3821
|
+
security: [{
|
|
3822
|
+
scheme: "bearer",
|
|
3823
|
+
type: "http"
|
|
3824
|
+
}],
|
|
3825
|
+
url: "/email-rules/{id}/scope",
|
|
3826
|
+
...options
|
|
3827
|
+
});
|
|
3828
|
+
/**
|
|
3829
|
+
* List what a rule can cover
|
|
3830
|
+
*
|
|
3831
|
+
* How much the caller can read, and the inboxes and domains the caller can read, which is what they may name when a rule runs over selected inboxes and domains. For a caller who reads the whole organization, addresses lists the inboxes known as someone's (member addresses, members' verified work emails at the organization's domains, agents' addresses and inboxes with shared access), not every address that receives mail: may_name_unlisted says when an address that is not listed, such as an inbox nobody has claimed, may be named too. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3832
|
+
*/
|
|
3833
|
+
const listEmailRuleScopeOptions = (options) => (options?.client ?? client).get({
|
|
3834
|
+
security: [{
|
|
3835
|
+
scheme: "bearer",
|
|
3836
|
+
type: "http"
|
|
3837
|
+
}],
|
|
3838
|
+
url: "/email-rule-scope-options",
|
|
3839
|
+
...options
|
|
3840
|
+
});
|
|
3841
|
+
/**
|
|
3715
3842
|
* List rule requests
|
|
3716
3843
|
*
|
|
3717
|
-
* Rule requests, newest first: those made to you (box incoming, the default), those you made (outgoing), or every one you can see (all). Pending ones by default; status decided lists accepted, declined and withdrawn ones, and any lists both. A request is visible to the member who made it, the member it was made to, and the organization's owners and admins. Needs mail:read, a
|
|
3844
|
+
* Rule requests, newest first: those made to you (box incoming, the default), those you made (outgoing), or every one you can see (all). Pending ones by default; status decided lists accepted, declined and withdrawn ones, and any lists both. A request is visible to the member who made it, the member it was made to, and the organization's owners and admins. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3718
3845
|
*/
|
|
3719
3846
|
const listEmailRuleRequests = (options) => (options?.client ?? client).get({
|
|
3720
3847
|
security: [{
|
|
@@ -3727,7 +3854,7 @@ const listEmailRuleRequests = (options) => (options?.client ?? client).get({
|
|
|
3727
3854
|
/**
|
|
3728
3855
|
* Ask a member for a rule
|
|
3729
3856
|
*
|
|
3730
|
-
* Asks another member of the organization for a rule over their own mail, from a compile response or a tree you wrote. Name them by user id, or by their member mailbox address (at most 30 lookups by address an hour). Nothing is evaluated
|
|
3857
|
+
* Asks another member of the organization for a rule over their own mail, from a compile response or a tree you wrote. Name them by user id, or by their member mailbox address, or by their verified work email if you can list members (at most 30 lookups by address an hour). Nothing is evaluated or shared until they accept, and they may change the rule first. A message (up to 500 characters, fixed once sent) tells them why you ask. At most 5 pending requests to one member and 50 in all. With members:read the answer says whether they can accept it under their role (target_can_accept, target_warning); POST /v1/email-rule-requests/target-check checks first. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3731
3858
|
*/
|
|
3732
3859
|
const createEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3733
3860
|
security: [{
|
|
@@ -3742,9 +3869,39 @@ const createEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
|
3742
3869
|
}
|
|
3743
3870
|
});
|
|
3744
3871
|
/**
|
|
3872
|
+
* Check whether a member can accept a rule request
|
|
3873
|
+
*
|
|
3874
|
+
* Says, before you ask, whether a member could accept a rule request now under their role, and if not, which permission their role lacks. Nothing is sent and nothing is recorded. Needs members:read, as listing members and their roles does. At most 60 checks an hour. Name them by user id, or by their member mailbox address or verified work email (counted with asking: at most 30 lookups by address an hour). Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3875
|
+
*/
|
|
3876
|
+
const checkEmailRuleRequestTarget = (options) => (options.client ?? client).post({
|
|
3877
|
+
security: [{
|
|
3878
|
+
scheme: "bearer",
|
|
3879
|
+
type: "http"
|
|
3880
|
+
}],
|
|
3881
|
+
url: "/email-rule-requests/target-check",
|
|
3882
|
+
...options,
|
|
3883
|
+
headers: {
|
|
3884
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
3885
|
+
...options.headers
|
|
3886
|
+
}
|
|
3887
|
+
});
|
|
3888
|
+
/**
|
|
3889
|
+
* Delete a withdrawn rule request
|
|
3890
|
+
*
|
|
3891
|
+
* Deletes a request you withdrew, for everyone who could see it. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3892
|
+
*/
|
|
3893
|
+
const deleteEmailRuleRequest = (options) => (options.client ?? client).delete({
|
|
3894
|
+
security: [{
|
|
3895
|
+
scheme: "bearer",
|
|
3896
|
+
type: "http"
|
|
3897
|
+
}],
|
|
3898
|
+
url: "/email-rule-requests/{id}",
|
|
3899
|
+
...options
|
|
3900
|
+
});
|
|
3901
|
+
/**
|
|
3745
3902
|
* Read a rule request
|
|
3746
3903
|
*
|
|
3747
|
-
* A rule request: the rule as proposed, who made it and to whom, and whether each of them is still a member. A request is visible to the member who made it, the member it was made to, and the organization's owners and admins. Needs mail:read, a
|
|
3904
|
+
* A rule request: the rule as proposed, who made it and to whom, and whether each of them is still a member. A request is visible to the member who made it, the member it was made to, and the organization's owners and admins. If you are the member asked, you can try the rule as proposed before answering: pass the request's tree to POST /v1/email-rules/test to test it on mail you have received. To try it on an email that has not arrived, pass the request's tree to POST /v1/email-rules/test-sample with one you make up, or have look-alikes written (POST /v1/email-rules/look-alikes with request_id); neither stores anything. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3748
3905
|
*/
|
|
3749
3906
|
const getEmailRuleRequest = (options) => (options.client ?? client).get({
|
|
3750
3907
|
security: [{
|
|
@@ -3757,7 +3914,7 @@ const getEmailRuleRequest = (options) => (options.client ?? client).get({
|
|
|
3757
3914
|
/**
|
|
3758
3915
|
* Decline a rule request
|
|
3759
3916
|
*
|
|
3760
|
-
* Declines a pending request made to you. Nothing is written but the decision. Needs mail:read, a
|
|
3917
|
+
* Declines a pending request made to you. Nothing is written but the decision and, if you give one, its reason (reason, up to 500 characters), which the member who asked sees with the request. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3761
3918
|
*/
|
|
3762
3919
|
const declineEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3763
3920
|
security: [{
|
|
@@ -3765,12 +3922,16 @@ const declineEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
|
3765
3922
|
type: "http"
|
|
3766
3923
|
}],
|
|
3767
3924
|
url: "/email-rule-requests/{id}/decline",
|
|
3768
|
-
...options
|
|
3925
|
+
...options,
|
|
3926
|
+
headers: {
|
|
3927
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
3928
|
+
...options.headers
|
|
3929
|
+
}
|
|
3769
3930
|
});
|
|
3770
3931
|
/**
|
|
3771
3932
|
* Withdraw a rule request
|
|
3772
3933
|
*
|
|
3773
|
-
* Withdraws a pending request you made. Needs mail:read, a
|
|
3934
|
+
* Withdraws a pending request you made. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3774
3935
|
*/
|
|
3775
3936
|
const withdrawEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3776
3937
|
security: [{
|
|
@@ -3783,7 +3944,7 @@ const withdrawEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
|
3783
3944
|
/**
|
|
3784
3945
|
* Accept a rule request
|
|
3785
3946
|
*
|
|
3786
|
-
* Writes the rule as yours, over your own mailboxes only, turns it on, and shares what it matches from now on with the member who asked. Send no body to accept it as asked, or change it first with english
|
|
3947
|
+
* Writes the rule as yours, over your own mailboxes only, turns it on, and shares what it matches from now on with the member who asked: each email in full with its attachments, but never raw. It does not go back through mail already received. Send no body to accept it as asked, or change it first with english and tree together (and an explanation, or the server writes one). Because this gives your mail to someone else, it is limited to the dashboard and the Primitive CLI: other OAuth apps and agent tokens are refused. Before accepting, test it on your mail: pass the request's tree to POST /v1/email-rules/test. To try it on an email that has not arrived, pass the request's tree to POST /v1/email-rules/test-sample with one you make up, or have look-alikes written (POST /v1/email-rules/look-alikes with request_id); neither stores anything. expectation_samples are kept on the rule it writes. Accepting also needs mail:share_own. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3787
3948
|
*/
|
|
3788
3949
|
const acceptEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
3789
3950
|
security: [{
|
|
@@ -3800,7 +3961,7 @@ const acceptEmailRuleRequest = (options) => (options.client ?? client).post({
|
|
|
3800
3961
|
/**
|
|
3801
3962
|
* List rule shares
|
|
3802
3963
|
*
|
|
3803
|
-
* Lists rules shared with you, rules you share, or every share you can see. A share is visible to its two people and the organization's owners and admins. Needs mail:read, a
|
|
3964
|
+
* Lists rules shared with you, rules you share, or every share you can see. A share is visible to its two people and the organization's owners and admins. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3804
3965
|
*/
|
|
3805
3966
|
const listEmailRuleShares = (options) => (options?.client ?? client).get({
|
|
3806
3967
|
security: [{
|
|
@@ -3826,7 +3987,7 @@ const listGivenEmailRuleShares = (options) => (options?.client ?? client).get({
|
|
|
3826
3987
|
/**
|
|
3827
3988
|
* End a rule share
|
|
3828
3989
|
*
|
|
3829
|
-
* Stops sharing. Either person on the share can do this, or an owner or admin who manages members. The share is kept, marked as ended. This needs no mail access and does not depend on the email rules feature. An owner or admin not on the share must use a dashboard session. Otherwise use your own session, or an OAuth or CLI token that acts with your full access: API keys and agent keys are refused.
|
|
3990
|
+
* Stops sharing; the rule itself is left unchanged, as the answer's note says. Either person on the share can do this, or an owner or admin who manages members. The share is kept, marked as ended. This needs no mail access and does not depend on the email rules feature. An owner or admin not on the share must use a dashboard session. Otherwise use your own session, or an OAuth or CLI token that acts with your full access: API keys and agent keys are refused.
|
|
3830
3991
|
*/
|
|
3831
3992
|
const endEmailRuleShare = (options) => (options.client ?? client).delete({
|
|
3832
3993
|
security: [{
|
|
@@ -3839,7 +4000,7 @@ const endEmailRuleShare = (options) => (options.client ?? client).delete({
|
|
|
3839
4000
|
/**
|
|
3840
4001
|
* Get a rule share
|
|
3841
4002
|
*
|
|
3842
|
-
* One share. Needs mail:read, a
|
|
4003
|
+
* One share. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature.
|
|
3843
4004
|
*/
|
|
3844
4005
|
const getEmailRuleShare = (options) => (options.client ?? client).get({
|
|
3845
4006
|
security: [{
|
|
@@ -3850,9 +4011,9 @@ const getEmailRuleShare = (options) => (options.client ?? client).get({
|
|
|
3850
4011
|
...options
|
|
3851
4012
|
});
|
|
3852
4013
|
/**
|
|
3853
|
-
* List the emails a rule share has given
|
|
4014
|
+
* List the emails a rule share has given
|
|
3854
4015
|
*
|
|
3855
|
-
* The emails a rule
|
|
4016
|
+
* The emails a rule share has given, newest first, as the email list shows them, each with shared_at. For the person it was shared with: what they can read through it now, so an ended share lists nothing, and shared_at is when the share's rule first matched the email. For the person sharing their mail: everything it has handed over while it ran, including after it ended and whatever the rule's state now, so they can see what left their mailbox, and shared_at is when it was handed over. Only those two people can list them, from the dashboard or the Primitive CLI. A page can be short or empty and still carry a cursor: keep reading until meta.cursor is null.
|
|
3856
4017
|
*/
|
|
3857
4018
|
const listEmailRuleShareEmails = (options) => (options.client ?? client).get({
|
|
3858
4019
|
security: [{
|
|
@@ -3863,6 +4024,131 @@ const listEmailRuleShareEmails = (options) => (options.client ?? client).get({
|
|
|
3863
4024
|
...options
|
|
3864
4025
|
});
|
|
3865
4026
|
/**
|
|
4027
|
+
* List the rules over your mail
|
|
4028
|
+
*
|
|
4029
|
+
* Every email rule that covers one of your own mailboxes now, yours included, newest first, in any state. A rule covers you when the scope it runs with now reaches one of your own mailboxes (your member mailbox, or a personal agent's address): one whose author reads all your mail (author scope, for an author who reads the organization's mail or holds an access entry for your mailbox), or one that names your mailbox or its domain (selected). Another member's own_mailboxes rule never covers you. You see its name, wording, current tree, state, kind and author, and which of your own mailboxes it reaches. Its wording and tree are shown as written, so they can name other addresses (a condition on who an email is from or to). You do not see the other inboxes and domains its scope names, its saved expectations, or the keys, shares and webhooks that use it. A page can hold fewer rules than limit, or none, and still carry a cursor (one request reads a bounded number of rules): keep reading until meta.cursor is null. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature. Only on your own dashboard session or the Primitive CLI.
|
|
4030
|
+
*/
|
|
4031
|
+
const listEmailRulesCoveringMe = (options) => (options?.client ?? client).get({
|
|
4032
|
+
security: [{
|
|
4033
|
+
scheme: "bearer",
|
|
4034
|
+
type: "http"
|
|
4035
|
+
}],
|
|
4036
|
+
url: "/email-rules/covering-me",
|
|
4037
|
+
...options
|
|
4038
|
+
});
|
|
4039
|
+
/**
|
|
4040
|
+
* Get a rule over your mail
|
|
4041
|
+
*
|
|
4042
|
+
* One rule that covers one of your own mailboxes, read-only, with its current version; or one that no longer does but decided on mail at your own mailbox (covers_now false), shown as the version that last decided on your mail, without its current name. You see its name, wording, current tree, state, kind and author, and which of your own mailboxes it reaches. Its wording and tree are shown as written, so they can name other addresses (a condition on who an email is from or to). You do not see the other inboxes and domains its scope names, its saved expectations, or the keys, shares and webhooks that use it. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature. Only on your own dashboard session or the Primitive CLI.
|
|
4043
|
+
*/
|
|
4044
|
+
const getEmailRuleCoveringMe = (options) => (options.client ?? client).get({
|
|
4045
|
+
security: [{
|
|
4046
|
+
scheme: "bearer",
|
|
4047
|
+
type: "http"
|
|
4048
|
+
}],
|
|
4049
|
+
url: "/email-rules/covering-me/{id}",
|
|
4050
|
+
...options
|
|
4051
|
+
});
|
|
4052
|
+
/**
|
|
4053
|
+
* List what a rule decided about your mail
|
|
4054
|
+
*
|
|
4055
|
+
* What a rule that covers your mailboxes, or decided on your mail, decided about mail at your own mailboxes, newest first: never about anyone else's mail. Each decision is in the words of the version that made it, which can be earlier than the current one: the questions it asked about that email (question_answers) and the columns its conditions read (parts). Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature. Only on your own dashboard session or the Primitive CLI.
|
|
4056
|
+
*/
|
|
4057
|
+
const listEmailRuleDecisionsOnMyMail = (options) => (options.client ?? client).get({
|
|
4058
|
+
security: [{
|
|
4059
|
+
scheme: "bearer",
|
|
4060
|
+
type: "http"
|
|
4061
|
+
}],
|
|
4062
|
+
url: "/email-rules/covering-me/{id}/decisions",
|
|
4063
|
+
...options
|
|
4064
|
+
});
|
|
4065
|
+
/**
|
|
4066
|
+
* List objections
|
|
4067
|
+
*
|
|
4068
|
+
* Objections you made, objections to rules you wrote, or every objection you can see, newest first. An objection is seen by the member who made it, the rule's author and the organization's owners and admins. It stays pending until the rule's author accepts it, turning the rule off, or declines it, or the member who made it withdraws it, which clears its message. It never changes after that. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature. Only on your own dashboard session or the Primitive CLI.
|
|
4069
|
+
*/
|
|
4070
|
+
const listEmailRuleObjections = (options) => (options?.client ?? client).get({
|
|
4071
|
+
security: [{
|
|
4072
|
+
scheme: "bearer",
|
|
4073
|
+
type: "http"
|
|
4074
|
+
}],
|
|
4075
|
+
url: "/email-rule-objections",
|
|
4076
|
+
...options
|
|
4077
|
+
});
|
|
4078
|
+
/**
|
|
4079
|
+
* Object to a rule over your mail
|
|
4080
|
+
*
|
|
4081
|
+
* Asks the author of a rule that covers one of your own mailboxes now to turn it off. Only a rule that covers you now: one you see only because it once decided on your mail cannot be objected to. An objection is seen by the member who made it, the rule's author and the organization's owners and admins. It stays pending until the rule's author accepts it, turning the rule off, or declines it, or the member who made it withdraws it, which clears its message. It never changes after that. You may have one pending objection per rule and 50 in all, and object to the same rule again only 10 minutes after you last did, whatever became of it. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature. Only on your own dashboard session or the Primitive CLI.
|
|
4082
|
+
*/
|
|
4083
|
+
const createEmailRuleObjection = (options) => (options.client ?? client).post({
|
|
4084
|
+
security: [{
|
|
4085
|
+
scheme: "bearer",
|
|
4086
|
+
type: "http"
|
|
4087
|
+
}],
|
|
4088
|
+
url: "/email-rule-objections",
|
|
4089
|
+
...options,
|
|
4090
|
+
headers: {
|
|
4091
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
4092
|
+
...options.headers
|
|
4093
|
+
}
|
|
4094
|
+
});
|
|
4095
|
+
/**
|
|
4096
|
+
* Get an objection
|
|
4097
|
+
*
|
|
4098
|
+
* One objection you can see. An objection is seen by the member who made it, the rule's author and the organization's owners and admins. It stays pending until the rule's author accepts it, turning the rule off, or declines it, or the member who made it withdraws it, which clears its message. It never changes after that. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature. Only on your own dashboard session or the Primitive CLI.
|
|
4099
|
+
*/
|
|
4100
|
+
const getEmailRuleObjection = (options) => (options.client ?? client).get({
|
|
4101
|
+
security: [{
|
|
4102
|
+
scheme: "bearer",
|
|
4103
|
+
type: "http"
|
|
4104
|
+
}],
|
|
4105
|
+
url: "/email-rule-objections/{id}",
|
|
4106
|
+
...options
|
|
4107
|
+
});
|
|
4108
|
+
/**
|
|
4109
|
+
* Withdraw an objection
|
|
4110
|
+
*
|
|
4111
|
+
* Withdraws a pending objection you made, and clears its message. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature. Only on your own dashboard session or the Primitive CLI.
|
|
4112
|
+
*/
|
|
4113
|
+
const withdrawEmailRuleObjection = (options) => (options.client ?? client).post({
|
|
4114
|
+
security: [{
|
|
4115
|
+
scheme: "bearer",
|
|
4116
|
+
type: "http"
|
|
4117
|
+
}],
|
|
4118
|
+
url: "/email-rule-objections/{id}/withdraw",
|
|
4119
|
+
...options
|
|
4120
|
+
});
|
|
4121
|
+
/**
|
|
4122
|
+
* Decline an objection to your rule
|
|
4123
|
+
*
|
|
4124
|
+
* Declines a pending objection to a rule you wrote, optionally saying why; the rule stays as it is. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature. Only on your own dashboard session or the Primitive CLI.
|
|
4125
|
+
*/
|
|
4126
|
+
const declineEmailRuleObjection = (options) => (options.client ?? client).post({
|
|
4127
|
+
security: [{
|
|
4128
|
+
scheme: "bearer",
|
|
4129
|
+
type: "http"
|
|
4130
|
+
}],
|
|
4131
|
+
url: "/email-rule-objections/{id}/decline",
|
|
4132
|
+
...options,
|
|
4133
|
+
headers: {
|
|
4134
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
4135
|
+
...options.headers
|
|
4136
|
+
}
|
|
4137
|
+
});
|
|
4138
|
+
/**
|
|
4139
|
+
* Accept an objection to your rule
|
|
4140
|
+
*
|
|
4141
|
+
* Accepts a pending objection to a rule you wrote: turns the rule off (state draft), as updating it would, and records the objection accepted, together. You can turn the rule on again later. Needs mail:read, a member's own credential with their full access (not an API key, agent key or narrowed token), and the email rules feature. Only on your own dashboard session or the Primitive CLI.
|
|
4142
|
+
*/
|
|
4143
|
+
const acceptEmailRuleObjection = (options) => (options.client ?? client).post({
|
|
4144
|
+
security: [{
|
|
4145
|
+
scheme: "bearer",
|
|
4146
|
+
type: "http"
|
|
4147
|
+
}],
|
|
4148
|
+
url: "/email-rule-objections/{id}/accept",
|
|
4149
|
+
...options
|
|
4150
|
+
});
|
|
4151
|
+
/**
|
|
3866
4152
|
* Get a domain's Agent Authorization status
|
|
3867
4153
|
*
|
|
3868
4154
|
* Whether the domain publishes an Agent Authorization (`_agents`) TXT record that lets agents on Primitive email it, read from DNS with the same engine the send path uses (an answer may be up to five minutes old): published (a record authorizes them), published_unauthorized (a record exists but does not), not_set_up (no record, the default) or inconclusive (the lookup could not tell; retry). The domain is one of the organization's, verified or pending; a credential confined to some mailboxes sees only the domains its scope covers. Needs domains:read.
|
|
@@ -4077,6 +4363,19 @@ const getOwnGrant = (options) => (options?.client ?? client).get({
|
|
|
4077
4363
|
...options
|
|
4078
4364
|
});
|
|
4079
4365
|
/**
|
|
4366
|
+
* List the addresses this credential can send from
|
|
4367
|
+
*
|
|
4368
|
+
* The From addresses the calling credential may send from with POST /send-mail, and the one a send that names no From should use. Every address listed is one that send would accept as From for this credential, recipients aside. A connected agent's default is its own address. A person's default is their own member address, for a session and for every OAuth login of theirs, an agent's included. Any other credential has a default only when exactly one address and no domain is listed, and never a person's own member address. When there is no default, `reason` says why. `domains` lists the domains at which the credential may send from any address that is not reserved to someone else or left out of its grant; each is one GET /outbound/status lists as sendable for it. A credential that cannot send new mail, or one in an account where outbound mail is not enabled, gets no addresses and no domains. Every credential may ask about itself, a connected agent's key included, except a Function-bound key limited to its Function's own operations (403 function_scope_forbidden). It answers nothing about any other credential.
|
|
4369
|
+
*/
|
|
4370
|
+
const getSendFrom = (options) => (options?.client ?? client).get({
|
|
4371
|
+
security: [{
|
|
4372
|
+
scheme: "bearer",
|
|
4373
|
+
type: "http"
|
|
4374
|
+
}],
|
|
4375
|
+
url: "/whoami/send-from",
|
|
4376
|
+
...options
|
|
4377
|
+
});
|
|
4378
|
+
/**
|
|
4080
4379
|
* List consumer Inbox routing rules
|
|
4081
4380
|
*
|
|
4082
4381
|
* Mailbox-scoped exact visible audiences, excluding the owner and Bcc. Direct and group audiences are independent. Restores persist an explicit Conversations rule. New writes require the observed version (zero creates); only an identical latest mutation with its original expected version can be retried. Stale writes return mail_routing_conflict. Source messages and read state are unchanged. Merge paged rules by version; responses are never cached.
|
|
@@ -4269,7 +4568,7 @@ const listFunctionActivity = (options) => (options.client ?? client).get({
|
|
|
4269
4568
|
/**
|
|
4270
4569
|
* List a function's invocations
|
|
4271
4570
|
*
|
|
4272
|
-
* Each run of the function, newest first, with its outcome, timings, response status and exception. Lists runs only: a webhook delivery that never reached the function (for example one refused before it ran) is not an invocation; find those with listDeliveries.
|
|
4571
|
+
* Each run of the function, newest first, with its outcome, timings, response status and exception. Lists runs only: a webhook delivery that never reached the function (for example one refused before it ran) is not an invocation; find those with listDeliveries and its endpoint_id filter.
|
|
4273
4572
|
*/
|
|
4274
4573
|
const listFunctionInvocations = (options) => (options.client ?? client).get({
|
|
4275
4574
|
security: [{
|
|
@@ -4419,7 +4718,7 @@ const checkSendability = (options) => (options.client ?? client).post({
|
|
|
4419
4718
|
/**
|
|
4420
4719
|
* Get a webhook delivery
|
|
4421
4720
|
*
|
|
4422
|
-
* One webhook delivery attempt record, by the id listDeliveries returns.
|
|
4721
|
+
* One webhook delivery attempt record, by the id listDeliveries returns, with every attempt of the same delivery (a retry is recorded as a new attempt with its own id).
|
|
4423
4722
|
*/
|
|
4424
4723
|
const getDelivery = (options) => (options.client ?? client).get({
|
|
4425
4724
|
security: [{
|
|
@@ -4467,7 +4766,7 @@ const revokeOrganizationInvitation = (options) => (options.client ?? client).del
|
|
|
4467
4766
|
...options
|
|
4468
4767
|
});
|
|
4469
4768
|
/**
|
|
4470
|
-
* Requires a current human organization membership, or an org-wide API key: a super admin key, or a custom key with no addresses or domains whose grant holds members:read. A key lists members as the person it belongs to, at that person's live grant, and only while that person still holds members:read. Narrowed, Function and connected keys are refused. No local paths or existing conversation history are shared.
|
|
4769
|
+
* Requires a current human organization membership, or an org-wide API key: a super admin key, or a custom key with no addresses or domains whose grant holds members:read. A key lists members as the person it belongs to, at that person's live grant, and only while that person still holds members:read. Narrowed, Function and connected keys are refused. A caller holding members:read also gets each person's mail_access. No local paths or existing conversation history are shared.
|
|
4471
4770
|
*/
|
|
4472
4771
|
const listOrganizationPeople = (options) => (options?.client ?? client).get({
|
|
4473
4772
|
security: [{
|
|
@@ -4580,7 +4879,7 @@ const revokeProjectInvitation = (options) => (options.client ?? client).delete({
|
|
|
4580
4879
|
/**
|
|
4581
4880
|
* List mailbox access
|
|
4582
4881
|
*
|
|
4583
|
-
* Every access entry in the organization: who (a member, group, agent or address) may read, draft or send for each mailbox or domain. An entry that reads a mailbox reads the full email; raw MIME follows the person's mail.raw:read. `depth` is deprecated: it is accepted and ignored, and new entries record content. Needs members:read: a person, or an org-wide API key whose person holds it.
|
|
4882
|
+
* Every access entry in the organization: who (a member, group, agent or address) may read, draft or send for each mailbox or domain. An entry that reads a mailbox reads the full email; raw MIME follows the person's mail.raw:read. `depth` is deprecated: it is accepted and ignored, and new entries record content. With no entries, `note` says where each member's mail access comes from instead. Needs members:read: a person, or an org-wide API key whose person holds it.
|
|
4584
4883
|
*/
|
|
4585
4884
|
const listMailboxAccess = (options) => (options?.client ?? client).get({
|
|
4586
4885
|
security: [{
|
|
@@ -4670,7 +4969,7 @@ const updateGroup = (options) => (options.client ?? client).patch({
|
|
|
4670
4969
|
/**
|
|
4671
4970
|
* List every credential
|
|
4672
4971
|
*
|
|
4673
|
-
* Every credential that can act in the organization: API keys, Function keys, agent connection keys, connected apps (OAuth), agent delegates and, where enabled, CLI logins. Secrets are never returned. Filter with kind. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled.
|
|
4972
|
+
* Every credential that can act in the organization: API keys, Function keys, agent connection keys, connected apps (OAuth), agent delegates and, where enabled, CLI logins. Secrets are never returned. A key's grant.mail_scope.depth is raw only when it holds mail.raw:read and its scope lists an address or a domain, otherwise content. A rule the key lists that reads nothing any more (a deleted rule, or a share that ended) is listed under grant.mail_scope.ended_rules, each with its id and reason (rule_deleted or share_ended), and not under rules. Filter with kind. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4674
4973
|
*
|
|
4675
4974
|
* Person only: a dashboard session. The person's role must hold credentials:read. API keys, agent connection keys and agents are refused.
|
|
4676
4975
|
*/
|
|
@@ -4685,9 +4984,9 @@ const listCredentials = (options) => (options?.client ?? client).get({
|
|
|
4685
4984
|
/**
|
|
4686
4985
|
* Revoke a credential
|
|
4687
4986
|
*
|
|
4688
|
-
* Revoke one credential by kind and id. A Function key is rotated, never revoked (409 rotate_instead). An API key is revoked
|
|
4987
|
+
* Revoke one credential by kind and id. A Function key is rotated, never revoked (409 rotate_instead). An API key is revoked by the person who holds it, whatever it reaches, or by a person whose own access covers the key's access (an owner covers every key); otherwise 403 grant_forbidden, details.reason target_not_covered. Revoking an API key also revokes the keys it replaced in its rotation that are still in their overlap and that you may revoke (predecessors_revoked_count; predecessors_left counts the rest), so its webhooks stop at once; the keys that replaced it carry its work on. Revoking a key already revoked does the same for those keys. What the credential set up or owns is listed in standing_objects for review, and for an API key also what it carries on for the keys it was rotated from, each saying whether anything still acts for it (still_acting, with the key in acting_key_id) and, for a webhook, whether it is still delivering. An organization-owned object (org_owned true) keeps working; any other keeps working only while someone can still act for it, such as a key of the same rotation that still works, or whoever it was given to, except that a block filter an app made keeps blocking, within the reach the app had, unless the person revoking chose to stop it. An API key (kind org_key or connected_key) that is already revoked, and whose record is kept, answers 200 with already_revoked true, to a caller who could have revoked it, and revoked counts only the keys it replaced that were revoked now; anyone else gets the answer they would get for a key that does not exist. The person's own Primitive CLI login revokes an API key (kind org_key) as the person, with no step-up unless the organization's credential policy sets cli_writes_require_approval (then it takes a keys.create step-up); every other kind (a connected key named as org_key included, 403 grant_forbidden target_not_covered), and every other app even with a step-up, is refused outside the dashboard (403). Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4689
4988
|
*
|
|
4690
|
-
* Person only: a dashboard session. The person's role must hold keys:manage. API keys, agent connection keys and agents are refused.
|
|
4989
|
+
* Person only: a dashboard session or the person's own Primitive CLI token; no other OAuth app. The person's role must hold keys:manage. API keys, agent connection keys and agents are refused.
|
|
4691
4990
|
*/
|
|
4692
4991
|
const revokeCredential = (options) => (options.client ?? client).post({
|
|
4693
4992
|
security: [{
|
|
@@ -4704,7 +5003,7 @@ const revokeCredential = (options) => (options.client ?? client).post({
|
|
|
4704
5003
|
/**
|
|
4705
5004
|
* Revoke every credential (emergency)
|
|
4706
5005
|
*
|
|
4707
|
-
* The emergency response to a leak: revokes every API key, agent connection key and connected app created since a time, rotates the organization Function key and every running Function's own key, and optionally suspends Functions. Owners only, from a dashboard session, and the body must confirm with "revoke all". Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled.
|
|
5006
|
+
* The emergency response to a leak: revokes every API key, agent connection key and connected app created since a time, rotates the organization Function key and every running Function's own key, and optionally suspends Functions. Owners only, from a dashboard session, and the body must confirm with "revoke all". Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4708
5007
|
*
|
|
4709
5008
|
* Person only: a dashboard session. The person's role must hold credentials:revoke_all. API keys, agent connection keys and agents are refused.
|
|
4710
5009
|
*/
|
|
@@ -4723,7 +5022,7 @@ const revokeAllCredentials = (options) => (options.client ?? client).post({
|
|
|
4723
5022
|
/**
|
|
4724
5023
|
* Read the credential audit trail
|
|
4725
5024
|
*
|
|
4726
|
-
* Credential events (created, rotated, edited, revoked, used with a step-up, policy changes), newest first, with a cursor. format=csv returns the same page as CSV. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled.
|
|
5025
|
+
* Credential events (created, rotated, edited, revoked, used with a step-up, policy changes), newest first, with a cursor. format=csv returns the same page as CSV. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4727
5026
|
*
|
|
4728
5027
|
* Person only: a dashboard session. The person's role must hold credential_events:read. API keys, agent connection keys and agents are refused.
|
|
4729
5028
|
*/
|
|
@@ -4738,7 +5037,7 @@ const listCredentialEvents = (options) => (options?.client ?? client).get({
|
|
|
4738
5037
|
/**
|
|
4739
5038
|
* Read the credential policy
|
|
4740
5039
|
*
|
|
4741
|
-
* The organization credential policy: key lifetime and expiry rules, who may create super admin keys, whether members may create keys and the other rules every new key is held to. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled.
|
|
5040
|
+
* The organization credential policy: key lifetime and expiry rules, who may create super admin keys, whether members may create keys and the other rules every new key is held to. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4742
5041
|
*
|
|
4743
5042
|
* Person only: a dashboard session. The person's role must hold credentials:read. API keys, agent connection keys and agents are refused.
|
|
4744
5043
|
*/
|
|
@@ -4753,7 +5052,7 @@ const getCredentialPolicy = (options) => (options?.client ?? client).get({
|
|
|
4753
5052
|
/**
|
|
4754
5053
|
* Change the credential policy
|
|
4755
5054
|
*
|
|
4756
|
-
* Change one or more policy rules. Admins may only tighten the policy; loosening any rule needs an owner. Owners and admins are emailed about every change. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled.
|
|
5055
|
+
* Change one or more policy rules. Admins may only tighten the policy; loosening any rule needs an owner. Owners and admins are emailed about every change. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4757
5056
|
*
|
|
4758
5057
|
* Person only: a dashboard session. The person's role must hold credential_policy:manage. API keys, agent connection keys and agents are refused.
|
|
4759
5058
|
*/
|
|
@@ -4772,7 +5071,7 @@ const updateCredentialPolicy = (options) => (options.client ?? client).patch({
|
|
|
4772
5071
|
/**
|
|
4773
5072
|
* Read the key builder
|
|
4774
5073
|
*
|
|
4775
|
-
* The key presets the caller may use (each with whether it is available and why not), the permission matrix for custom keys and the policy in force. An area marked org_wide_only (Members) is listed only to a person who holds its permission, and only a custom key with no addresses or domains may hold it. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled.
|
|
5074
|
+
* The key presets the caller may use (each with whether it is available and why not), the permission matrix for custom keys and the policy in force. An area marked org_wide_only (Members) is listed only to a person who holds its permission, and only a custom key with no addresses or domains may hold it. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4776
5075
|
*
|
|
4777
5076
|
* Person only: a dashboard session. The person's role must hold keys:read. API keys, agent connection keys and agents are refused.
|
|
4778
5077
|
*/
|
|
@@ -4787,7 +5086,7 @@ const getKeyBuilder = (options) => (options?.client ?? client).get({
|
|
|
4787
5086
|
/**
|
|
4788
5087
|
* List API keys
|
|
4789
5088
|
*
|
|
4790
|
-
* Key metadata, never a secret: name, prefix, grant, creator, last use, expiry and
|
|
5089
|
+
* Key metadata, never a secret: name, prefix, grant, creator, last use, expiry, suspension and whether each key works now (status). Revoked keys are left out unless include_revoked is true, which lists them too with status revoked, revoked_at and revoked_by, under the same access rules as keys that work. A grant's mail_scope.depth is raw only when the key holds mail.raw:read and its scope lists an address or a domain, otherwise content. A rule the key lists that reads nothing any more (a deleted rule, or a share that ended) is listed under grant.mail_scope.ended_rules, each with its id and reason (rule_deleted or share_ended), and not under rules. The person needs access to the whole organization's mail. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4791
5090
|
*
|
|
4792
5091
|
* Person only: a dashboard session or the person's own Primitive CLI token; no other OAuth app. The person's role must hold keys:read. API keys, agent connection keys and agents are refused.
|
|
4793
5092
|
*/
|
|
@@ -4802,9 +5101,9 @@ const listKeys = (options) => (options?.client ?? client).get({
|
|
|
4802
5101
|
/**
|
|
4803
5102
|
* Create an API key
|
|
4804
5103
|
*
|
|
4805
|
-
* Create an API key, super admin or narrowed to a preset or a custom permission set, optionally with an expiry and conditions. The secret is returned once. A key never holds more than the person creating it; the credential policy decides who may create which keys. grant is required: a request without it is refused (400 validation_error, details.reason grant_required), never treated as super admin. A custom key must say which mail it reaches: the addresses and domains it lists (grant.addresses, grant.domains), or every mailbox in the organization with grant.mail_scope "org", which cannot be combined with them; one that says neither is refused (400 validation_error, details.reason mail_scope_required). Super admin, Send only and Read only reach every mailbox by definition. members:read is only for an org-wide custom key: naming it with grant.addresses or grant.domains is refused (400). Owners and admins are emailed about every super admin key. Send an Idempotency-Key to retry safely: a second create by the same person under the same key makes no second key and is refused (409 idempotency_key_reused) with the first key's id in error.details.key_id, so a caller whose first answer was lost can revoke that key. The onboarding field is for the dashboard only. The
|
|
5104
|
+
* Create an API key, super admin or narrowed to a preset or a custom permission set, optionally with an expiry and conditions. The secret is returned once. A key never holds more than the person creating it; the credential policy decides who may create which keys. grant is required: a request without it is refused (400 validation_error, details.reason grant_required), never treated as super admin. A custom key must say which mail it reaches: the addresses and domains it lists (grant.addresses, grant.domains), or every mailbox in the organization with grant.mail_scope "org", which cannot be combined with them; one that says neither is refused (400 validation_error, details.reason mail_scope_required). Super admin, Send only and Read only reach every mailbox by definition. members:read is only for an org-wide custom key: naming it with grant.addresses or grant.domains is refused (400). Owners and admins are emailed about every super admin key. Send an Idempotency-Key to retry safely: a second create by the same person under the same key makes no second key and is refused (409 idempotency_key_reused) with the first key's id in error.details.key_id, so a caller whose first answer was lost can revoke that key. The onboarding field is for the dashboard only. The person's own Primitive CLI login needs no step-up (it acts as the person, held to the same rules) unless the organization's credential policy sets cli_writes_require_approval; the Primitive app's token is refused, even with one. While the organization's keys API is not enabled, this answers 404 feature_disabled (details.feature keys_api; contact Primitive to turn it on), except that a dashboard session may still create a super admin key (the dashboard's own create).
|
|
4806
5105
|
*
|
|
4807
|
-
* Person only: a dashboard session, or the person's own OAuth token with a step-up token for purpose `keys.create` in the Primitive-Step-Up header. Without one
|
|
5106
|
+
* Person only: a dashboard session, the person's own Primitive CLI login with no step-up (unless the organization's credential policy sets cli_writes_require_approval), or the person's own OAuth token with a step-up token for purpose `keys.create` in the Primitive-Step-Up header. Without one any other OAuth token is answered 403 step_up_required, whose details carry the dashboard URL that issues it (or 403 grant_forbidden when the person's role, or the client, could not do it anyway). The person's role must hold keys:manage. API keys and agent connection keys are refused. An agent acting for the person is refused unless it carries a step-up token the person issued in the dashboard.
|
|
4808
5107
|
*/
|
|
4809
5108
|
const createKey = (options) => (options.client ?? client).post({
|
|
4810
5109
|
security: [{
|
|
@@ -4821,9 +5120,9 @@ const createKey = (options) => (options.client ?? client).post({
|
|
|
4821
5120
|
/**
|
|
4822
5121
|
* Rotate an API key
|
|
4823
5122
|
*
|
|
4824
|
-
* Mint a successor with the same grant and return its secret once. The old key keeps working for overlap_seconds, then stops. The person rotating must cover the key's access (403 grant_forbidden, details.reason target_not_covered), and a key an owner
|
|
5123
|
+
* Mint a successor with a new id and the same name, grant, expiry and conditions, and return its secret once. The old key keeps working for overlap_seconds, then stops: 24 hours when overlap_seconds is omitted, at most 7 days, never past its own expires_at, and at once with 0 (which is how to rotate a key whose secret leaked). previous_key_expires_at says when the old key stops. Revoking the successor during the overlap also revokes the old key when you may revoke that one too; the revoke's predecessors_left counts any left working. Rotating does not extend a key: the successor keeps the old expiry unless expires_at gives it a new one. That needs keys:manage (403 forbidden otherwise), is held to the credential policy (400 when past its maximum lifetime, with the latest expiry it allows now in the message), and someone limited to their own keys can only keep or bring it forward (403 grant_forbidden, details.reason own_key_tighten_only); the old key then never outlives the new one. The person rotating must cover the key's access (403 grant_forbidden, details.reason target_not_covered), and a key an owner holds is rotated by an owner only (403 forbidden, details.reason owner_key_rotation), since rotating hands over the new secret. The person's own Primitive CLI login needs no step-up (it acts as the person, held to the same rules) unless the organization's credential policy sets cli_writes_require_approval; the Primitive app's token is refused, even with one. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4825
5124
|
*
|
|
4826
|
-
* Person only: a dashboard session, or the person's own OAuth token with a step-up token for purpose `keys.create` in the Primitive-Step-Up header. Without one
|
|
5125
|
+
* Person only: a dashboard session, the person's own Primitive CLI login with no step-up (unless the organization's credential policy sets cli_writes_require_approval), or the person's own OAuth token with a step-up token for purpose `keys.create` in the Primitive-Step-Up header. Without one any other OAuth token is answered 403 step_up_required, whose details carry the dashboard URL that issues it (or 403 grant_forbidden when the person's role, or the client, could not do it anyway). The person's role must hold keys:manage. API keys and agent connection keys are refused. An agent acting for the person is refused unless it carries a step-up token the person issued in the dashboard.
|
|
4827
5126
|
*/
|
|
4828
5127
|
const rotateKey = (options) => (options.client ?? client).post({
|
|
4829
5128
|
security: [{
|
|
@@ -4840,7 +5139,7 @@ const rotateKey = (options) => (options.client ?? client).post({
|
|
|
4840
5139
|
/**
|
|
4841
5140
|
* Get an API key
|
|
4842
5141
|
*
|
|
4843
|
-
* One key's metadata, never its secret. The person needs access to the whole organization's mail. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled.
|
|
5142
|
+
* One key's metadata, never its secret, with whether it works now (status). A revoked key whose record is kept is answered too, with status revoked, revoked_at and revoked_by, under the same access rules as a key that works: one the caller may not read is 404, revoked or not. Its grant's mail_scope.depth is raw only when the key holds mail.raw:read and its scope lists an address or a domain, otherwise content. A rule the key lists that reads nothing any more (a deleted rule, or a share that ended) is listed under grant.mail_scope.ended_rules, each with its id and reason (rule_deleted or share_ended), and not under rules. The person needs access to the whole organization's mail. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4844
5143
|
*
|
|
4845
5144
|
* Person only: a dashboard session or the person's own Primitive CLI token; no other OAuth app. The person's role must hold keys:read. API keys, agent connection keys and agents are refused.
|
|
4846
5145
|
*/
|
|
@@ -4855,9 +5154,9 @@ const getKey = (options) => (options.client ?? client).get({
|
|
|
4855
5154
|
/**
|
|
4856
5155
|
* Change an API key
|
|
4857
5156
|
*
|
|
4858
|
-
* Rename a key, change its expiry, its grant or its conditions, or suspend it. Any change needs the person's own access to cover the key's access now (an owner covers every key); otherwise 403 grant_forbidden, details.reason target_not_covered. A grant change is a new version of the key and is held to the same rules as creating one (a custom grant that does not say which mail it reaches is refused with details.reason mail_scope_required), so it takes the same step-up. The Primitive CLI's token is refused, even with
|
|
5157
|
+
* Rename a key, change its expiry, its grant or its conditions, or suspend it. A later expires_at extends the key, which is how to keep a key working past its expiry (rotating keeps it, unless the rotation gives the new key an expires_at): it is held to the credential policy (400 when past its maximum lifetime, with the latest expiry it allows now in the message), and like any loosening needs the person to be allowed to create a key with the key's access. An expired key's expiry cannot be changed (409 conflict, details.reason key_expired); make a new key instead. Any change needs the person's own access to cover the key's access now (an owner covers every key); otherwise 403 grant_forbidden, details.reason target_not_covered. The one exception is suspending a key (suspended true with no other change; expected_grant_ref may accompany it), which the person who holds it may do whatever the key reaches, calling as themself rather than through another app; lifting a suspension is a change like any other. A grant change is a new version of the key and is held to the same rules as creating one (a custom grant that does not say which mail it reaches is refused with details.reason mail_scope_required), so it takes the same step-up. It replaces the whole grant: send expected_grant_ref (grant.ref from GET /v1/keys/{id}) to have it refused (409 conflict, details.reason grant_changed) if the grant changed since that read; a grant change sent without it answers grant_unguarded: true. On a key limited to selected resources (grant.resources), a grant change must drop the limits on purpose with a custom grant and grant.resources {}; one that leaves them out is refused (409 conflict, details.reason key_has_resource_limits) and nothing changes. The person's own Primitive CLI login needs no step-up (it acts as the person, held to the same rules) unless the organization's credential policy sets cli_writes_require_approval; the Primitive app's token is refused, even with one. Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4859
5158
|
*
|
|
4860
|
-
* Person only: a dashboard session, or the person's own OAuth token with a step-up token for purpose `keys.create` in the Primitive-Step-Up header. Without one
|
|
5159
|
+
* Person only: a dashboard session, the person's own Primitive CLI login with no step-up (unless the organization's credential policy sets cli_writes_require_approval), or the person's own OAuth token with a step-up token for purpose `keys.create` in the Primitive-Step-Up header. Without one any other OAuth token is answered 403 step_up_required, whose details carry the dashboard URL that issues it (or 403 grant_forbidden when the person's role, or the client, could not do it anyway). The person's role must hold keys:manage. API keys and agent connection keys are refused. An agent acting for the person is refused unless it carries a step-up token the person issued in the dashboard.
|
|
4861
5160
|
*/
|
|
4862
5161
|
const updateKey = (options) => (options.client ?? client).patch({
|
|
4863
5162
|
security: [{
|
|
@@ -4874,7 +5173,7 @@ const updateKey = (options) => (options.client ?? client).patch({
|
|
|
4874
5173
|
/**
|
|
4875
5174
|
* Suggest a least-privilege grant for a key
|
|
4876
5175
|
*
|
|
4877
|
-
* The permissions a key used over the last 30 days, as a custom grant that would have served every successful call (also as builder areas), the narrowest mail scope its calls support (depth is deprecated: raw when it downloaded raw MIME, otherwise content) (the mailboxes of the messages it named and sent, with notes on what the request log cannot account for), and whether it is unused. Calls to routes only the super admin key can use (groups and mailbox access) derive no permission, since a custom key is refused there; super_admin_only_calls counts them. usage gives the same window anonymized: successful and failed requests per UTC day, the routes called by their declared template (never the called path) with the permission each needed, and how many mailboxes the key read and sent from (counts only, and only for a person with access to the whole organization's mail). Nothing is applied: narrowing is a change to the key (PATCH /v1/keys/:id). Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled.
|
|
5176
|
+
* The permissions a key used over the last 30 days, as a custom grant that would have served every successful call (also as builder areas), the narrowest mail scope its calls support (depth is deprecated: raw when it downloaded raw MIME, otherwise content) (the mailboxes of the messages it named and sent, with notes on what the request log cannot account for), and whether it is unused. Calls to routes only the super admin key can use (groups and mailbox access) derive no permission, since a custom key is refused there; super_admin_only_calls counts them. usage gives the same window anonymized: successful and failed requests per UTC day, the routes called by their declared template (never the called path) with the permission each needed, and how many mailboxes the key read and sent from (counts only, and only for a person with access to the whole organization's mail). Nothing is applied: narrowing is a change to the key (PATCH /v1/keys/:id). Needs the organization's credential features to be enabled; while they are not, this answers 404 feature_disabled, with details.feature naming the feature. Contact Primitive to turn them on.
|
|
4878
5177
|
*
|
|
4879
5178
|
* Person only: a dashboard session. The person's role must hold credentials:read. API keys, agent connection keys and agents are refused.
|
|
4880
5179
|
*/
|
|
@@ -5055,7 +5354,7 @@ const updateSearchSettings = (options) => (options.client ?? client).put({
|
|
|
5055
5354
|
/**
|
|
5056
5355
|
* List roles
|
|
5057
5356
|
*
|
|
5058
|
-
* Every role in the organization (built-in, template copies and custom roles), with how many members and groups hold each, the templates not yet copied, and whether roles can be assigned now.
|
|
5357
|
+
* Every role in the organization (built-in, template copies and custom roles), with how many members and groups hold each, the templates not yet copied, and whether roles can be assigned now. `unassigned` describes role restricted on a member with no role_id, which is not a role and is never in `roles`. Needs members:read (owners, admins, members and roles that grant it); API keys are refused.
|
|
5059
5358
|
*/
|
|
5060
5359
|
const listRoles = (options) => (options?.client ?? client).get({
|
|
5061
5360
|
security: [{
|
|
@@ -5068,7 +5367,7 @@ const listRoles = (options) => (options?.client ?? client).get({
|
|
|
5068
5367
|
/**
|
|
5069
5368
|
* Create a custom role
|
|
5070
5369
|
*
|
|
5071
|
-
* A role nobody can use to gain access they do not hold: its permissions and mail scope must be within the author's own. mail_scope is "org" (the default) or { addresses, domains }; any other value is refused with 400 `validation_error`. Every role that reaches mail reads it in full, and raw MIME follows the role's mail.raw:read; `depth` is deprecated and ignored. Its mail scope names no other member's personal mailbox: otherwise 403 `grant_forbidden` with `details.reason` `personal_mailbox_member_only`. Person only: a dashboard session, or the person's own OAuth or CLI token with a session step-up of purpose `roles.write` (the person confirms at the step_up_url a 403 step_up_required answer carries, which names this client, then send the token in the Primitive-Step-Up header; the token works only with the client it was confirmed for). Needs roles:assign. API keys are refused.
|
|
5370
|
+
* A role nobody can use to gain access they do not hold: its permissions and mail scope must be within the author's own. mail_scope is "org" (the default) or { addresses, domains }; any other value is refused with 400 `validation_error`. Every role that reaches mail reads it in full, and raw MIME follows the role's mail.raw:read; `depth` is deprecated and ignored. Its mail scope names no other member's personal mailbox: otherwise 403 `grant_forbidden` with `details.reason` `personal_mailbox_member_only`. Each permission must have what it requires in the same role: mail:read for mail.raw:read, mail.search:semantic, mail:share_own, changes:read and webhooks:read; mail:send for mail:send_batch and mail:send_as_member; functions:deploy for templates:install; agent_connections:manage for agent_connections:custom_domains. Otherwise 400 `validation_error` with `details.reason` `unmet_requirement`, `details.permission` and `details.requires`. Person only: a dashboard session, or the person's own OAuth or CLI token with a session step-up of purpose `roles.write` (the person confirms at the step_up_url a 403 step_up_required answer carries, which names this client, then send the token in the Primitive-Step-Up header; the token works only with the client it was confirmed for). Needs roles:assign. API keys are refused.
|
|
5072
5371
|
*/
|
|
5073
5372
|
const createRole = (options) => (options.client ?? client).post({
|
|
5074
5373
|
security: [{
|
|
@@ -5098,7 +5397,7 @@ const deleteRole = (options) => (options.client ?? client).delete({
|
|
|
5098
5397
|
/**
|
|
5099
5398
|
* Change a custom role
|
|
5100
5399
|
*
|
|
5101
|
-
* A new version of the role, with a new `id`: the version you edited is retired, the response is the new one (same `key`, `version` one higher), and every member and group holding the role moves to it. The old id answers 404 `not_found` from then on, so store the returned `id` (or look the role up by `key` in GET /roles) before editing or assigning it again. Every holder whose access shrinks goes through the reduction path. mail_scope follows the same rules as creating a role; a role whose stored scope cannot be read must be sent a new mail_scope, otherwise 400 `validation_error` with `details.reason` `invalid_mail_scope`. A personal mailbox the new version adds must be the author's own, and every holder must be the member of each personal mailbox it names: otherwise 403 `grant_forbidden` with `details.reason` `personal_mailbox_member_only`. Person only: a dashboard session, or the person's own OAuth or CLI token with a session step-up of purpose `roles.write` (the person confirms at the step_up_url a 403 step_up_required answer carries, which names this client, then send the token in the Primitive-Step-Up header; the token works only with the client it was confirmed for). Needs roles:assign. API keys are refused.
|
|
5400
|
+
* A new version of the role, with a new `id`: the version you edited is retired, the response is the new one (same `key`, `version` one higher), and every member and group holding the role moves to it. The old id answers 404 `not_found` from then on, so store the returned `id` (or look the role up by `key` in GET /roles) before editing or assigning it again. Every holder whose access shrinks goes through the reduction path. mail_scope follows the same rules as creating a role; a role whose stored scope cannot be read must be sent a new mail_scope, otherwise 400 `validation_error` with `details.reason` `invalid_mail_scope`. A personal mailbox the new version adds must be the author's own, and every holder must be the member of each personal mailbox it names: otherwise 403 `grant_forbidden` with `details.reason` `personal_mailbox_member_only`. Each permission in the new version must have what it requires in the same role, as when creating one, including permissions carried over unchanged. Person only: a dashboard session, or the person's own OAuth or CLI token with a session step-up of purpose `roles.write` (the person confirms at the step_up_url a 403 step_up_required answer carries, which names this client, then send the token in the Primitive-Step-Up header; the token works only with the client it was confirmed for). Needs roles:assign. API keys are refused.
|
|
5102
5401
|
*/
|
|
5103
5402
|
const updateRole = (options) => (options.client ?? client).patch({
|
|
5104
5403
|
security: [{
|
|
@@ -5158,7 +5457,7 @@ const leaveOrganization = (options) => (options?.client ?? client).post({
|
|
|
5158
5457
|
/**
|
|
5159
5458
|
* Get the mailbox access mode
|
|
5160
5459
|
*
|
|
5161
|
-
* Whole-org or delegated mailbox access. Holders of roles:assign also get the preview of a switch (every item that needs a decision, each with the decision_options it takes, worded for what the switch does) and the decisions made, plus notices: member and group domain entries that delegated mode keeps off personal mailboxes, each with how many it leaves out. Notices are informational, never decided, and never hold the switch (notices_truncated past 500, notices_unavailable when they could not be read). In whole-org mode it also lists narrowed_agents: every live agent connection the switch narrows to an own-address key (personal agents of members, and shared agents), informational in the same way (narrowed_agents_truncated past 500, narrowed_agents_unavailable when they could not be read).
|
|
5460
|
+
* Whole-org or delegated mailbox access. Holders of roles:assign also get the preview of a switch (every item that needs a decision, each with the decision_options it takes, worded for what the switch does) and the decisions made, plus notices: member and group domain entries that delegated mode keeps off personal mailboxes, each with how many it leaves out. Notices are informational, never decided, and never hold the switch (notices_truncated past 500, notices_unavailable when they could not be read). In whole-org mode it also lists narrowed_agents: every live agent connection the switch narrows to an own-address key (personal agents of members, and shared agents), informational in the same way (narrowed_agents_truncated past 500, narrowed_agents_unavailable when they could not be read). Needs members:read (owners, admins, members and roles that grant it); API keys are refused.
|
|
5162
5461
|
*/
|
|
5163
5462
|
const getAccessMode = (options) => (options?.client ?? client).get({
|
|
5164
5463
|
security: [{
|
|
@@ -5321,7 +5620,7 @@ const listSuspensions = (options) => (options?.client ?? client).get({
|
|
|
5321
5620
|
/**
|
|
5322
5621
|
* Decide a suspension
|
|
5323
5622
|
*
|
|
5324
|
-
* Keep, narrow or revoke one suspended or flagged item. Keeping it, and revoking an API key
|
|
5623
|
+
* Keep, narrow or revoke one suspended or flagged item. Keeping it needs the decider to cover it, and so does revoking an API key unless the decider holds it and decides as themself rather than through another app (revoking an uncovered key someone else holds is refused with `grant_forbidden`, `target_not_covered`). Keeping an API key rotated (`rotate: true`, other than the shared Function key) also revokes its older secrets still in a rotation overlap, and needs keys:manage on both the credential and the person: without it, or if the decider lost members:manage meanwhile, it is refused with `grant_forbidden` (`keys_manage_required` or `actor_access_changed`) and nothing is rotated. A rule share paused by a role change (`email_rule_share`) takes keep, which leaves it paused, or revoke, which ends the share and needs confirm: true (the person it was shared with loses the emails already shared; without it, 409 `confirmation_required`, as for revoking a filter). Neither of the share's two people may keep it (`grant_forbidden`, `share_decision_forbidden`). Access a person gave on their own mailbox (`mailbox_access`) takes keep or revoke, and both need delegations:manage; revoke removes only what that person gave on that mailbox. Nobody the access reaches, nor the person who gave it, may keep it (`grant_forbidden`, `mailbox_access_decision_forbidden`). Person only: a dashboard session, or the person's own OAuth or CLI token with a session step-up of purpose `suspensions.decide` (the person confirms at the step_up_url a 403 step_up_required answer carries, which names this client, then send the token in the Primitive-Step-Up header; the token works only with the client it was confirmed for). Needs members:manage. API keys are refused.
|
|
5325
5624
|
*/
|
|
5326
5625
|
const decideSuspension = (options) => (options.client ?? client).post({
|
|
5327
5626
|
security: [{
|
|
@@ -5443,6 +5742,32 @@ const releaseSentEmail = (options) => (options.client ?? client).post({
|
|
|
5443
5742
|
}
|
|
5444
5743
|
});
|
|
5445
5744
|
/**
|
|
5745
|
+
* Get a webhook's own signing secret
|
|
5746
|
+
*
|
|
5747
|
+
* The secret deliveries to this webhook are signed with, when it signs with its own (signed_with is own_secret). Verify the Primitive-Signature header with it. A webhook a person owns is given its secret the first time it is asked for. A webhook that signs with the organization's secret answers 409 conflict: rotate its signing secret to give it its own. Answered to the person who owns the webhook; for a webhook an API key owns, to the key that acts for it and the person who holds that key; for one a third-party app or an agent delegate owns, to that app or delegate; and for a webhook the organization owns, to a caller who may change it and holds webhook_secret:read.
|
|
5748
|
+
*/
|
|
5749
|
+
const getEndpointSigningSecret = (options) => (options.client ?? client).get({
|
|
5750
|
+
security: [{
|
|
5751
|
+
scheme: "bearer",
|
|
5752
|
+
type: "http"
|
|
5753
|
+
}],
|
|
5754
|
+
url: "/endpoints/{id}/signing-secret",
|
|
5755
|
+
...options
|
|
5756
|
+
});
|
|
5757
|
+
/**
|
|
5758
|
+
* Rotate a webhook's signing secret, or give it its own
|
|
5759
|
+
*
|
|
5760
|
+
* Replaces the webhook's own signing secret, or gives a webhook that signs with the organization's secret one of its own, and returns it. Deliveries are signed with the new secret at once, so update the handler at the same time. Answered to the person who owns the webhook; for a webhook an API key owns, to the key that acts for it and the person who holds that key; for one a third-party app or an agent delegate owns, to that app or delegate; and for a webhook the organization owns, to a caller who may change it and holds webhook_secret:read.
|
|
5761
|
+
*/
|
|
5762
|
+
const rotateEndpointSigningSecret = (options) => (options.client ?? client).post({
|
|
5763
|
+
security: [{
|
|
5764
|
+
scheme: "bearer",
|
|
5765
|
+
type: "http"
|
|
5766
|
+
}],
|
|
5767
|
+
url: "/endpoints/{id}/signing-secret/rotate",
|
|
5768
|
+
...options
|
|
5769
|
+
});
|
|
5770
|
+
/**
|
|
5446
5771
|
* Send a batch of emails in one request
|
|
5447
5772
|
*
|
|
5448
5773
|
* Send up to 100 independent messages in a single call. Each message uses the same body schema and the same send path as `POST /send-mail`, so auth, validation, rate limiting, and idempotency apply per message. Messages are processed independently: one failing does not fail the others. Every message gets an entry in `results` carrying either `data` (on success) or `error` (on failure), with the original `index`.
|
|
@@ -6879,7 +7204,7 @@ function parseFromHeader(header) {
|
|
|
6879
7204
|
value: { address: address.toLowerCase() }
|
|
6880
7205
|
};
|
|
6881
7206
|
}
|
|
6882
|
-
// ../sdk-node/dist/
|
|
7207
|
+
// ../sdk-node/dist/understanding-Dv-rAk0U.js
|
|
6883
7208
|
/**
|
|
6884
7209
|
* AUTO-GENERATED - DO NOT EDIT
|
|
6885
7210
|
* Run `pnpm generate:validator` to regenerate.
|
|
@@ -7017,9 +7342,12 @@ const schema12 = {
|
|
|
7017
7342
|
},
|
|
7018
7343
|
"content": {
|
|
7019
7344
|
"type": "object",
|
|
7020
|
-
"if": { "
|
|
7021
|
-
"then": {
|
|
7022
|
-
|
|
7345
|
+
"if": { "required": ["raw"] },
|
|
7346
|
+
"then": {
|
|
7347
|
+
"if": { "properties": { "raw": { "type": "null" } } },
|
|
7348
|
+
"then": { "properties": { "download": { "type": "null" } } },
|
|
7349
|
+
"else": { "properties": { "download": { "type": "object" } } }
|
|
7350
|
+
},
|
|
7023
7351
|
"properties": {
|
|
7024
7352
|
"raw": {
|
|
7025
7353
|
"anyOf": [{ "$ref": "#/definitions/RawContent" }, { "type": "null" }],
|
|
@@ -15344,13 +15672,11 @@ function validate11$1(data, { instancePath = "", parentData, parentDataProperty,
|
|
|
15344
15672
|
let valid10 = true;
|
|
15345
15673
|
const _errs64 = errors;
|
|
15346
15674
|
if (data29 && typeof data29 == "object" && !Array.isArray(data29)) {
|
|
15347
|
-
if (data29.raw
|
|
15348
|
-
|
|
15349
|
-
|
|
15350
|
-
|
|
15351
|
-
|
|
15352
|
-
errors++;
|
|
15353
|
-
}
|
|
15675
|
+
if (data29.raw === void 0 && "raw") {
|
|
15676
|
+
const err65 = {};
|
|
15677
|
+
if (vErrors === null) vErrors = [err65];
|
|
15678
|
+
else vErrors.push(err65);
|
|
15679
|
+
errors++;
|
|
15354
15680
|
}
|
|
15355
15681
|
}
|
|
15356
15682
|
var _valid0 = _errs64 === errors;
|
|
@@ -15359,93 +15685,129 @@ function validate11$1(data, { instancePath = "", parentData, parentDataProperty,
|
|
|
15359
15685
|
if (_errs63) vErrors.length = _errs63;
|
|
15360
15686
|
else vErrors = null;
|
|
15361
15687
|
}
|
|
15362
|
-
let ifClause0;
|
|
15363
15688
|
if (_valid0) {
|
|
15689
|
+
const _errs65 = errors;
|
|
15690
|
+
const _errs66 = errors;
|
|
15691
|
+
let valid11 = true;
|
|
15364
15692
|
const _errs67 = errors;
|
|
15365
15693
|
if (data29 && typeof data29 == "object" && !Array.isArray(data29)) {
|
|
15366
|
-
if (data29.
|
|
15367
|
-
if (data29.
|
|
15368
|
-
const err66 = {
|
|
15369
|
-
instancePath: instancePath + "/email/content/download",
|
|
15370
|
-
schemaPath: "#/properties/email/properties/content/then/properties/download/type",
|
|
15371
|
-
keyword: "type",
|
|
15372
|
-
params: { type: "null" },
|
|
15373
|
-
message: "must be null"
|
|
15374
|
-
};
|
|
15694
|
+
if (data29.raw !== void 0) {
|
|
15695
|
+
if (data29.raw !== null) {
|
|
15696
|
+
const err66 = {};
|
|
15375
15697
|
if (vErrors === null) vErrors = [err66];
|
|
15376
15698
|
else vErrors.push(err66);
|
|
15377
15699
|
errors++;
|
|
15378
15700
|
}
|
|
15379
15701
|
}
|
|
15380
15702
|
}
|
|
15381
|
-
var
|
|
15382
|
-
|
|
15383
|
-
|
|
15384
|
-
|
|
15385
|
-
|
|
15386
|
-
|
|
15387
|
-
|
|
15388
|
-
|
|
15389
|
-
|
|
15390
|
-
|
|
15391
|
-
|
|
15392
|
-
|
|
15393
|
-
|
|
15394
|
-
|
|
15395
|
-
|
|
15396
|
-
|
|
15397
|
-
|
|
15398
|
-
|
|
15399
|
-
|
|
15703
|
+
var _valid1 = _errs67 === errors;
|
|
15704
|
+
errors = _errs66;
|
|
15705
|
+
if (vErrors !== null) {
|
|
15706
|
+
if (_errs66) vErrors.length = _errs66;
|
|
15707
|
+
else vErrors = null;
|
|
15708
|
+
}
|
|
15709
|
+
let ifClause0;
|
|
15710
|
+
if (_valid1) {
|
|
15711
|
+
const _errs70 = errors;
|
|
15712
|
+
if (data29 && typeof data29 == "object" && !Array.isArray(data29)) {
|
|
15713
|
+
if (data29.download !== void 0) {
|
|
15714
|
+
if (data29.download !== null) {
|
|
15715
|
+
const err67 = {
|
|
15716
|
+
instancePath: instancePath + "/email/content/download",
|
|
15717
|
+
schemaPath: "#/properties/email/properties/content/then/then/properties/download/type",
|
|
15718
|
+
keyword: "type",
|
|
15719
|
+
params: { type: "null" },
|
|
15720
|
+
message: "must be null"
|
|
15721
|
+
};
|
|
15722
|
+
if (vErrors === null) vErrors = [err67];
|
|
15723
|
+
else vErrors.push(err67);
|
|
15724
|
+
errors++;
|
|
15725
|
+
}
|
|
15726
|
+
}
|
|
15727
|
+
}
|
|
15728
|
+
var _valid1 = _errs70 === errors;
|
|
15729
|
+
valid11 = _valid1;
|
|
15730
|
+
ifClause0 = "then";
|
|
15731
|
+
} else {
|
|
15732
|
+
const _errs73 = errors;
|
|
15733
|
+
if (data29 && typeof data29 == "object" && !Array.isArray(data29)) {
|
|
15734
|
+
if (data29.download !== void 0) {
|
|
15735
|
+
let data32 = data29.download;
|
|
15736
|
+
if (!(data32 && typeof data32 == "object" && !Array.isArray(data32))) {
|
|
15737
|
+
const err68 = {
|
|
15738
|
+
instancePath: instancePath + "/email/content/download",
|
|
15739
|
+
schemaPath: "#/properties/email/properties/content/then/else/properties/download/type",
|
|
15740
|
+
keyword: "type",
|
|
15741
|
+
params: { type: "object" },
|
|
15742
|
+
message: "must be object"
|
|
15743
|
+
};
|
|
15744
|
+
if (vErrors === null) vErrors = [err68];
|
|
15745
|
+
else vErrors.push(err68);
|
|
15746
|
+
errors++;
|
|
15747
|
+
}
|
|
15400
15748
|
}
|
|
15401
15749
|
}
|
|
15750
|
+
var _valid1 = _errs73 === errors;
|
|
15751
|
+
valid11 = _valid1;
|
|
15752
|
+
ifClause0 = "else";
|
|
15753
|
+
}
|
|
15754
|
+
if (!valid11) {
|
|
15755
|
+
const err69 = {
|
|
15756
|
+
instancePath: instancePath + "/email/content",
|
|
15757
|
+
schemaPath: "#/properties/email/properties/content/then/if",
|
|
15758
|
+
keyword: "if",
|
|
15759
|
+
params: { failingKeyword: ifClause0 },
|
|
15760
|
+
message: "must match \"" + ifClause0 + "\" schema"
|
|
15761
|
+
};
|
|
15762
|
+
if (vErrors === null) vErrors = [err69];
|
|
15763
|
+
else vErrors.push(err69);
|
|
15764
|
+
errors++;
|
|
15402
15765
|
}
|
|
15403
|
-
var _valid0 =
|
|
15766
|
+
var _valid0 = _errs65 === errors;
|
|
15404
15767
|
valid10 = _valid0;
|
|
15405
|
-
ifClause0 = "else";
|
|
15406
15768
|
}
|
|
15407
15769
|
if (!valid10) {
|
|
15408
|
-
const
|
|
15770
|
+
const err70 = {
|
|
15409
15771
|
instancePath: instancePath + "/email/content",
|
|
15410
15772
|
schemaPath: "#/properties/email/properties/content/if",
|
|
15411
15773
|
keyword: "if",
|
|
15412
|
-
params: { failingKeyword:
|
|
15413
|
-
message: "must match \"
|
|
15774
|
+
params: { failingKeyword: "then" },
|
|
15775
|
+
message: "must match \"then\" schema"
|
|
15414
15776
|
};
|
|
15415
|
-
if (vErrors === null) vErrors = [
|
|
15416
|
-
else vErrors.push(
|
|
15777
|
+
if (vErrors === null) vErrors = [err70];
|
|
15778
|
+
else vErrors.push(err70);
|
|
15417
15779
|
errors++;
|
|
15418
15780
|
}
|
|
15419
15781
|
if (data29 && typeof data29 == "object" && !Array.isArray(data29)) {
|
|
15420
15782
|
if (data29.raw === void 0) {
|
|
15421
|
-
const
|
|
15783
|
+
const err71 = {
|
|
15422
15784
|
instancePath: instancePath + "/email/content",
|
|
15423
15785
|
schemaPath: "#/properties/email/properties/content/required",
|
|
15424
15786
|
keyword: "required",
|
|
15425
15787
|
params: { missingProperty: "raw" },
|
|
15426
15788
|
message: "must have required property 'raw'"
|
|
15427
15789
|
};
|
|
15428
|
-
if (vErrors === null) vErrors = [
|
|
15429
|
-
else vErrors.push(
|
|
15790
|
+
if (vErrors === null) vErrors = [err71];
|
|
15791
|
+
else vErrors.push(err71);
|
|
15430
15792
|
errors++;
|
|
15431
15793
|
}
|
|
15432
15794
|
if (data29.download === void 0) {
|
|
15433
|
-
const
|
|
15795
|
+
const err72 = {
|
|
15434
15796
|
instancePath: instancePath + "/email/content",
|
|
15435
15797
|
schemaPath: "#/properties/email/properties/content/required",
|
|
15436
15798
|
keyword: "required",
|
|
15437
15799
|
params: { missingProperty: "download" },
|
|
15438
15800
|
message: "must have required property 'download'"
|
|
15439
15801
|
};
|
|
15440
|
-
if (vErrors === null) vErrors = [
|
|
15441
|
-
else vErrors.push(
|
|
15802
|
+
if (vErrors === null) vErrors = [err72];
|
|
15803
|
+
else vErrors.push(err72);
|
|
15442
15804
|
errors++;
|
|
15443
15805
|
}
|
|
15444
15806
|
if (data29.raw !== void 0) {
|
|
15445
15807
|
let data33 = data29.raw;
|
|
15446
|
-
const
|
|
15447
|
-
let
|
|
15448
|
-
const
|
|
15808
|
+
const _errs77 = errors;
|
|
15809
|
+
let valid16 = false;
|
|
15810
|
+
const _errs78 = errors;
|
|
15449
15811
|
if (!validate12$1(data33, {
|
|
15450
15812
|
instancePath: instancePath + "/email/content/raw",
|
|
15451
15813
|
parentData: data29,
|
|
@@ -15455,40 +15817,40 @@ function validate11$1(data, { instancePath = "", parentData, parentDataProperty,
|
|
|
15455
15817
|
vErrors = vErrors === null ? validate12$1.errors : vErrors.concat(validate12$1.errors);
|
|
15456
15818
|
errors = vErrors.length;
|
|
15457
15819
|
}
|
|
15458
|
-
var
|
|
15459
|
-
|
|
15460
|
-
if (!
|
|
15461
|
-
const
|
|
15820
|
+
var _valid2 = _errs78 === errors;
|
|
15821
|
+
valid16 = valid16 || _valid2;
|
|
15822
|
+
if (!valid16) {
|
|
15823
|
+
const _errs79 = errors;
|
|
15462
15824
|
if (data33 !== null) {
|
|
15463
|
-
const
|
|
15825
|
+
const err73 = {
|
|
15464
15826
|
instancePath: instancePath + "/email/content/raw",
|
|
15465
15827
|
schemaPath: "#/properties/email/properties/content/properties/raw/anyOf/1/type",
|
|
15466
15828
|
keyword: "type",
|
|
15467
15829
|
params: { type: "null" },
|
|
15468
15830
|
message: "must be null"
|
|
15469
15831
|
};
|
|
15470
|
-
if (vErrors === null) vErrors = [
|
|
15471
|
-
else vErrors.push(
|
|
15832
|
+
if (vErrors === null) vErrors = [err73];
|
|
15833
|
+
else vErrors.push(err73);
|
|
15472
15834
|
errors++;
|
|
15473
15835
|
}
|
|
15474
|
-
var
|
|
15475
|
-
|
|
15836
|
+
var _valid2 = _errs79 === errors;
|
|
15837
|
+
valid16 = valid16 || _valid2;
|
|
15476
15838
|
}
|
|
15477
|
-
if (!
|
|
15478
|
-
const
|
|
15839
|
+
if (!valid16) {
|
|
15840
|
+
const err74 = {
|
|
15479
15841
|
instancePath: instancePath + "/email/content/raw",
|
|
15480
15842
|
schemaPath: "#/properties/email/properties/content/properties/raw/anyOf",
|
|
15481
15843
|
keyword: "anyOf",
|
|
15482
15844
|
params: {},
|
|
15483
15845
|
message: "must match a schema in anyOf"
|
|
15484
15846
|
};
|
|
15485
|
-
if (vErrors === null) vErrors = [
|
|
15486
|
-
else vErrors.push(
|
|
15847
|
+
if (vErrors === null) vErrors = [err74];
|
|
15848
|
+
else vErrors.push(err74);
|
|
15487
15849
|
errors++;
|
|
15488
15850
|
} else {
|
|
15489
|
-
errors =
|
|
15851
|
+
errors = _errs77;
|
|
15490
15852
|
if (vErrors !== null) {
|
|
15491
|
-
if (
|
|
15853
|
+
if (_errs77) vErrors.length = _errs77;
|
|
15492
15854
|
else vErrors = null;
|
|
15493
15855
|
}
|
|
15494
15856
|
}
|
|
@@ -15496,79 +15858,79 @@ function validate11$1(data, { instancePath = "", parentData, parentDataProperty,
|
|
|
15496
15858
|
if (data29.download !== void 0) {
|
|
15497
15859
|
let data34 = data29.download;
|
|
15498
15860
|
if (!(data34 && typeof data34 == "object" && !Array.isArray(data34)) && data34 !== null) {
|
|
15499
|
-
const
|
|
15861
|
+
const err75 = {
|
|
15500
15862
|
instancePath: instancePath + "/email/content/download",
|
|
15501
15863
|
schemaPath: "#/properties/email/properties/content/properties/download/type",
|
|
15502
15864
|
keyword: "type",
|
|
15503
15865
|
params: { type: schema12.properties.email.properties.content.properties.download.type },
|
|
15504
15866
|
message: "must be object,null"
|
|
15505
15867
|
};
|
|
15506
|
-
if (vErrors === null) vErrors = [
|
|
15507
|
-
else vErrors.push(
|
|
15868
|
+
if (vErrors === null) vErrors = [err75];
|
|
15869
|
+
else vErrors.push(err75);
|
|
15508
15870
|
errors++;
|
|
15509
15871
|
}
|
|
15510
15872
|
if (data34 && typeof data34 == "object" && !Array.isArray(data34)) {
|
|
15511
15873
|
if (data34.url === void 0) {
|
|
15512
|
-
const
|
|
15874
|
+
const err76 = {
|
|
15513
15875
|
instancePath: instancePath + "/email/content/download",
|
|
15514
15876
|
schemaPath: "#/properties/email/properties/content/properties/download/required",
|
|
15515
15877
|
keyword: "required",
|
|
15516
15878
|
params: { missingProperty: "url" },
|
|
15517
15879
|
message: "must have required property 'url'"
|
|
15518
15880
|
};
|
|
15519
|
-
if (vErrors === null) vErrors = [
|
|
15520
|
-
else vErrors.push(
|
|
15881
|
+
if (vErrors === null) vErrors = [err76];
|
|
15882
|
+
else vErrors.push(err76);
|
|
15521
15883
|
errors++;
|
|
15522
15884
|
}
|
|
15523
15885
|
if (data34.expires_at === void 0) {
|
|
15524
|
-
const
|
|
15886
|
+
const err77 = {
|
|
15525
15887
|
instancePath: instancePath + "/email/content/download",
|
|
15526
15888
|
schemaPath: "#/properties/email/properties/content/properties/download/required",
|
|
15527
15889
|
keyword: "required",
|
|
15528
15890
|
params: { missingProperty: "expires_at" },
|
|
15529
15891
|
message: "must have required property 'expires_at'"
|
|
15530
15892
|
};
|
|
15531
|
-
if (vErrors === null) vErrors = [
|
|
15532
|
-
else vErrors.push(
|
|
15893
|
+
if (vErrors === null) vErrors = [err77];
|
|
15894
|
+
else vErrors.push(err77);
|
|
15533
15895
|
errors++;
|
|
15534
15896
|
}
|
|
15535
15897
|
if (data34.url !== void 0) {
|
|
15536
15898
|
let data35 = data34.url;
|
|
15537
15899
|
if (typeof data35 === "string") {
|
|
15538
15900
|
if (!pattern4.test(data35)) {
|
|
15539
|
-
const
|
|
15901
|
+
const err78 = {
|
|
15540
15902
|
instancePath: instancePath + "/email/content/download/url",
|
|
15541
15903
|
schemaPath: "#/properties/email/properties/content/properties/download/properties/url/pattern",
|
|
15542
15904
|
keyword: "pattern",
|
|
15543
15905
|
params: { pattern: "^https?://" },
|
|
15544
15906
|
message: "must match pattern \"^https?://\""
|
|
15545
15907
|
};
|
|
15546
|
-
if (vErrors === null) vErrors = [
|
|
15547
|
-
else vErrors.push(
|
|
15908
|
+
if (vErrors === null) vErrors = [err78];
|
|
15909
|
+
else vErrors.push(err78);
|
|
15548
15910
|
errors++;
|
|
15549
15911
|
}
|
|
15550
15912
|
if (!formats4.test(data35)) {
|
|
15551
|
-
const
|
|
15913
|
+
const err79 = {
|
|
15552
15914
|
instancePath: instancePath + "/email/content/download/url",
|
|
15553
15915
|
schemaPath: "#/properties/email/properties/content/properties/download/properties/url/format",
|
|
15554
15916
|
keyword: "format",
|
|
15555
15917
|
params: { format: "uri" },
|
|
15556
15918
|
message: "must match format \"uri\""
|
|
15557
15919
|
};
|
|
15558
|
-
if (vErrors === null) vErrors = [
|
|
15559
|
-
else vErrors.push(
|
|
15920
|
+
if (vErrors === null) vErrors = [err79];
|
|
15921
|
+
else vErrors.push(err79);
|
|
15560
15922
|
errors++;
|
|
15561
15923
|
}
|
|
15562
15924
|
} else {
|
|
15563
|
-
const
|
|
15925
|
+
const err80 = {
|
|
15564
15926
|
instancePath: instancePath + "/email/content/download/url",
|
|
15565
15927
|
schemaPath: "#/properties/email/properties/content/properties/download/properties/url/type",
|
|
15566
15928
|
keyword: "type",
|
|
15567
15929
|
params: { type: "string" },
|
|
15568
15930
|
message: "must be string"
|
|
15569
15931
|
};
|
|
15570
|
-
if (vErrors === null) vErrors = [
|
|
15571
|
-
else vErrors.push(
|
|
15932
|
+
if (vErrors === null) vErrors = [err80];
|
|
15933
|
+
else vErrors.push(err80);
|
|
15572
15934
|
errors++;
|
|
15573
15935
|
}
|
|
15574
15936
|
}
|
|
@@ -15576,42 +15938,42 @@ function validate11$1(data, { instancePath = "", parentData, parentDataProperty,
|
|
|
15576
15938
|
let data36 = data34.expires_at;
|
|
15577
15939
|
if (typeof data36 === "string") {
|
|
15578
15940
|
if (!formats0$1.test(data36)) {
|
|
15579
|
-
const
|
|
15941
|
+
const err81 = {
|
|
15580
15942
|
instancePath: instancePath + "/email/content/download/expires_at",
|
|
15581
15943
|
schemaPath: "#/properties/email/properties/content/properties/download/properties/expires_at/format",
|
|
15582
15944
|
keyword: "format",
|
|
15583
15945
|
params: { format: "date-time" },
|
|
15584
15946
|
message: "must match format \"date-time\""
|
|
15585
15947
|
};
|
|
15586
|
-
if (vErrors === null) vErrors = [
|
|
15587
|
-
else vErrors.push(
|
|
15948
|
+
if (vErrors === null) vErrors = [err81];
|
|
15949
|
+
else vErrors.push(err81);
|
|
15588
15950
|
errors++;
|
|
15589
15951
|
}
|
|
15590
15952
|
} else {
|
|
15591
|
-
const
|
|
15953
|
+
const err82 = {
|
|
15592
15954
|
instancePath: instancePath + "/email/content/download/expires_at",
|
|
15593
15955
|
schemaPath: "#/properties/email/properties/content/properties/download/properties/expires_at/type",
|
|
15594
15956
|
keyword: "type",
|
|
15595
15957
|
params: { type: "string" },
|
|
15596
15958
|
message: "must be string"
|
|
15597
15959
|
};
|
|
15598
|
-
if (vErrors === null) vErrors = [
|
|
15599
|
-
else vErrors.push(
|
|
15960
|
+
if (vErrors === null) vErrors = [err82];
|
|
15961
|
+
else vErrors.push(err82);
|
|
15600
15962
|
errors++;
|
|
15601
15963
|
}
|
|
15602
15964
|
}
|
|
15603
15965
|
}
|
|
15604
15966
|
}
|
|
15605
15967
|
} else {
|
|
15606
|
-
const
|
|
15968
|
+
const err83 = {
|
|
15607
15969
|
instancePath: instancePath + "/email/content",
|
|
15608
15970
|
schemaPath: "#/properties/email/properties/content/type",
|
|
15609
15971
|
keyword: "type",
|
|
15610
15972
|
params: { type: "object" },
|
|
15611
15973
|
message: "must be object"
|
|
15612
15974
|
};
|
|
15613
|
-
if (vErrors === null) vErrors = [
|
|
15614
|
-
else vErrors.push(
|
|
15975
|
+
if (vErrors === null) vErrors = [err83];
|
|
15976
|
+
else vErrors.push(err83);
|
|
15615
15977
|
errors++;
|
|
15616
15978
|
}
|
|
15617
15979
|
}
|
|
@@ -15650,123 +16012,123 @@ function validate11$1(data, { instancePath = "", parentData, parentDataProperty,
|
|
|
15650
16012
|
}
|
|
15651
16013
|
if (data14.relay !== void 0) {
|
|
15652
16014
|
let data40 = data14.relay;
|
|
15653
|
-
const
|
|
15654
|
-
let
|
|
15655
|
-
const
|
|
16015
|
+
const _errs91 = errors;
|
|
16016
|
+
let valid18 = false;
|
|
16017
|
+
const _errs92 = errors;
|
|
15656
16018
|
if (data40 && typeof data40 == "object" && !Array.isArray(data40)) {
|
|
15657
16019
|
if (data40.hostname === void 0) {
|
|
15658
|
-
const
|
|
16020
|
+
const err84 = {
|
|
15659
16021
|
instancePath: instancePath + "/email/relay",
|
|
15660
16022
|
schemaPath: "#/definitions/EmailRelay/required",
|
|
15661
16023
|
keyword: "required",
|
|
15662
16024
|
params: { missingProperty: "hostname" },
|
|
15663
16025
|
message: "must have required property 'hostname'"
|
|
15664
16026
|
};
|
|
15665
|
-
if (vErrors === null) vErrors = [
|
|
15666
|
-
else vErrors.push(
|
|
16027
|
+
if (vErrors === null) vErrors = [err84];
|
|
16028
|
+
else vErrors.push(err84);
|
|
15667
16029
|
errors++;
|
|
15668
16030
|
}
|
|
15669
16031
|
if (data40.via === void 0) {
|
|
15670
|
-
const
|
|
16032
|
+
const err85 = {
|
|
15671
16033
|
instancePath: instancePath + "/email/relay",
|
|
15672
16034
|
schemaPath: "#/definitions/EmailRelay/required",
|
|
15673
16035
|
keyword: "required",
|
|
15674
16036
|
params: { missingProperty: "via" },
|
|
15675
16037
|
message: "must have required property 'via'"
|
|
15676
16038
|
};
|
|
15677
|
-
if (vErrors === null) vErrors = [
|
|
15678
|
-
else vErrors.push(
|
|
16039
|
+
if (vErrors === null) vErrors = [err85];
|
|
16040
|
+
else vErrors.push(err85);
|
|
15679
16041
|
errors++;
|
|
15680
16042
|
}
|
|
15681
16043
|
if (data40.hostname !== void 0) {
|
|
15682
16044
|
if (typeof data40.hostname !== "string") {
|
|
15683
|
-
const
|
|
16045
|
+
const err86 = {
|
|
15684
16046
|
instancePath: instancePath + "/email/relay/hostname",
|
|
15685
16047
|
schemaPath: "#/definitions/EmailRelay/properties/hostname/type",
|
|
15686
16048
|
keyword: "type",
|
|
15687
16049
|
params: { type: "string" },
|
|
15688
16050
|
message: "must be string"
|
|
15689
16051
|
};
|
|
15690
|
-
if (vErrors === null) vErrors = [
|
|
15691
|
-
else vErrors.push(
|
|
16052
|
+
if (vErrors === null) vErrors = [err86];
|
|
16053
|
+
else vErrors.push(err86);
|
|
15692
16054
|
errors++;
|
|
15693
16055
|
}
|
|
15694
16056
|
}
|
|
15695
16057
|
if (data40.via !== void 0) {
|
|
15696
16058
|
if (typeof data40.via !== "string") {
|
|
15697
|
-
const
|
|
16059
|
+
const err87 = {
|
|
15698
16060
|
instancePath: instancePath + "/email/relay/via",
|
|
15699
16061
|
schemaPath: "#/definitions/EmailRelay/properties/via/type",
|
|
15700
16062
|
keyword: "type",
|
|
15701
16063
|
params: { type: "string" },
|
|
15702
16064
|
message: "must be string"
|
|
15703
16065
|
};
|
|
15704
|
-
if (vErrors === null) vErrors = [
|
|
15705
|
-
else vErrors.push(
|
|
16066
|
+
if (vErrors === null) vErrors = [err87];
|
|
16067
|
+
else vErrors.push(err87);
|
|
15706
16068
|
errors++;
|
|
15707
16069
|
}
|
|
15708
16070
|
}
|
|
15709
16071
|
} else {
|
|
15710
|
-
const
|
|
16072
|
+
const err88 = {
|
|
15711
16073
|
instancePath: instancePath + "/email/relay",
|
|
15712
16074
|
schemaPath: "#/definitions/EmailRelay/type",
|
|
15713
16075
|
keyword: "type",
|
|
15714
16076
|
params: { type: "object" },
|
|
15715
16077
|
message: "must be object"
|
|
15716
16078
|
};
|
|
15717
|
-
if (vErrors === null) vErrors = [
|
|
15718
|
-
else vErrors.push(
|
|
16079
|
+
if (vErrors === null) vErrors = [err88];
|
|
16080
|
+
else vErrors.push(err88);
|
|
15719
16081
|
errors++;
|
|
15720
16082
|
}
|
|
15721
|
-
var
|
|
15722
|
-
|
|
15723
|
-
if (!
|
|
15724
|
-
const
|
|
16083
|
+
var _valid3 = _errs92 === errors;
|
|
16084
|
+
valid18 = valid18 || _valid3;
|
|
16085
|
+
if (!valid18) {
|
|
16086
|
+
const _errs99 = errors;
|
|
15725
16087
|
if (data40 !== null) {
|
|
15726
|
-
const
|
|
16088
|
+
const err89 = {
|
|
15727
16089
|
instancePath: instancePath + "/email/relay",
|
|
15728
16090
|
schemaPath: "#/properties/email/properties/relay/anyOf/1/type",
|
|
15729
16091
|
keyword: "type",
|
|
15730
16092
|
params: { type: "null" },
|
|
15731
16093
|
message: "must be null"
|
|
15732
16094
|
};
|
|
15733
|
-
if (vErrors === null) vErrors = [
|
|
15734
|
-
else vErrors.push(
|
|
16095
|
+
if (vErrors === null) vErrors = [err89];
|
|
16096
|
+
else vErrors.push(err89);
|
|
15735
16097
|
errors++;
|
|
15736
16098
|
}
|
|
15737
|
-
var
|
|
15738
|
-
|
|
16099
|
+
var _valid3 = _errs99 === errors;
|
|
16100
|
+
valid18 = valid18 || _valid3;
|
|
15739
16101
|
}
|
|
15740
|
-
if (!
|
|
15741
|
-
const
|
|
16102
|
+
if (!valid18) {
|
|
16103
|
+
const err90 = {
|
|
15742
16104
|
instancePath: instancePath + "/email/relay",
|
|
15743
16105
|
schemaPath: "#/properties/email/properties/relay/anyOf",
|
|
15744
16106
|
keyword: "anyOf",
|
|
15745
16107
|
params: {},
|
|
15746
16108
|
message: "must match a schema in anyOf"
|
|
15747
16109
|
};
|
|
15748
|
-
if (vErrors === null) vErrors = [
|
|
15749
|
-
else vErrors.push(
|
|
16110
|
+
if (vErrors === null) vErrors = [err90];
|
|
16111
|
+
else vErrors.push(err90);
|
|
15750
16112
|
errors++;
|
|
15751
16113
|
} else {
|
|
15752
|
-
errors =
|
|
16114
|
+
errors = _errs91;
|
|
15753
16115
|
if (vErrors !== null) {
|
|
15754
|
-
if (
|
|
16116
|
+
if (_errs91) vErrors.length = _errs91;
|
|
15755
16117
|
else vErrors = null;
|
|
15756
16118
|
}
|
|
15757
16119
|
}
|
|
15758
16120
|
}
|
|
15759
16121
|
if (data14.automated !== void 0) {
|
|
15760
16122
|
if (typeof data14.automated !== "boolean") {
|
|
15761
|
-
const
|
|
16123
|
+
const err91 = {
|
|
15762
16124
|
instancePath: instancePath + "/email/automated",
|
|
15763
16125
|
schemaPath: "#/properties/email/properties/automated/type",
|
|
15764
16126
|
keyword: "type",
|
|
15765
16127
|
params: { type: "boolean" },
|
|
15766
16128
|
message: "must be boolean"
|
|
15767
16129
|
};
|
|
15768
|
-
if (vErrors === null) vErrors = [
|
|
15769
|
-
else vErrors.push(
|
|
16130
|
+
if (vErrors === null) vErrors = [err91];
|
|
16131
|
+
else vErrors.push(err91);
|
|
15770
16132
|
errors++;
|
|
15771
16133
|
}
|
|
15772
16134
|
}
|
|
@@ -15775,53 +16137,53 @@ function validate11$1(data, { instancePath = "", parentData, parentDataProperty,
|
|
|
15775
16137
|
if (Array.isArray(data44)) {
|
|
15776
16138
|
const len1 = data44.length;
|
|
15777
16139
|
for (let i1 = 0; i1 < len1; i1++) if (typeof data44[i1] !== "string") {
|
|
15778
|
-
const
|
|
16140
|
+
const err92 = {
|
|
15779
16141
|
instancePath: instancePath + "/email/automated_reasons/" + i1,
|
|
15780
16142
|
schemaPath: "#/properties/email/properties/automated_reasons/items/type",
|
|
15781
16143
|
keyword: "type",
|
|
15782
16144
|
params: { type: "string" },
|
|
15783
16145
|
message: "must be string"
|
|
15784
16146
|
};
|
|
15785
|
-
if (vErrors === null) vErrors = [
|
|
15786
|
-
else vErrors.push(
|
|
16147
|
+
if (vErrors === null) vErrors = [err92];
|
|
16148
|
+
else vErrors.push(err92);
|
|
15787
16149
|
errors++;
|
|
15788
16150
|
}
|
|
15789
16151
|
} else {
|
|
15790
|
-
const
|
|
16152
|
+
const err93 = {
|
|
15791
16153
|
instancePath: instancePath + "/email/automated_reasons",
|
|
15792
16154
|
schemaPath: "#/properties/email/properties/automated_reasons/type",
|
|
15793
16155
|
keyword: "type",
|
|
15794
16156
|
params: { type: "array" },
|
|
15795
16157
|
message: "must be array"
|
|
15796
16158
|
};
|
|
15797
|
-
if (vErrors === null) vErrors = [
|
|
15798
|
-
else vErrors.push(
|
|
16159
|
+
if (vErrors === null) vErrors = [err93];
|
|
16160
|
+
else vErrors.push(err93);
|
|
15799
16161
|
errors++;
|
|
15800
16162
|
}
|
|
15801
16163
|
}
|
|
15802
16164
|
} else {
|
|
15803
|
-
const
|
|
16165
|
+
const err94 = {
|
|
15804
16166
|
instancePath: instancePath + "/email",
|
|
15805
16167
|
schemaPath: "#/properties/email/type",
|
|
15806
16168
|
keyword: "type",
|
|
15807
16169
|
params: { type: "object" },
|
|
15808
16170
|
message: "must be object"
|
|
15809
16171
|
};
|
|
15810
|
-
if (vErrors === null) vErrors = [
|
|
15811
|
-
else vErrors.push(
|
|
16172
|
+
if (vErrors === null) vErrors = [err94];
|
|
16173
|
+
else vErrors.push(err94);
|
|
15812
16174
|
errors++;
|
|
15813
16175
|
}
|
|
15814
16176
|
}
|
|
15815
16177
|
} else {
|
|
15816
|
-
const
|
|
16178
|
+
const err95 = {
|
|
15817
16179
|
instancePath,
|
|
15818
16180
|
schemaPath: "#/type",
|
|
15819
16181
|
keyword: "type",
|
|
15820
16182
|
params: { type: "object" },
|
|
15821
16183
|
message: "must be object"
|
|
15822
16184
|
};
|
|
15823
|
-
if (vErrors === null) vErrors = [
|
|
15824
|
-
else vErrors.push(
|
|
16185
|
+
if (vErrors === null) vErrors = [err95];
|
|
16186
|
+
else vErrors.push(err95);
|
|
15825
16187
|
errors++;
|
|
15826
16188
|
}
|
|
15827
16189
|
validate11$1.errors = vErrors;
|
|
@@ -16028,10 +16390,10 @@ function formatValidationIssue(error, input) {
|
|
|
16028
16390
|
switch (error.keyword) {
|
|
16029
16391
|
case "required": {
|
|
16030
16392
|
const missing = String(error.params.missingProperty ?? "unknown");
|
|
16031
|
-
const
|
|
16393
|
+
const missingField = field === "payload" ? missing : `${field}.${missing}`;
|
|
16032
16394
|
return {
|
|
16033
|
-
field:
|
|
16034
|
-
message: `Missing required field: ${
|
|
16395
|
+
field: missingField,
|
|
16396
|
+
message: `Missing required field: ${missingField}`,
|
|
16035
16397
|
suggestion: `Add the required field "${missing}" to the webhook payload.`
|
|
16036
16398
|
};
|
|
16037
16399
|
}
|
|
@@ -23679,13 +24041,27 @@ const INTERACTION_EVENT_TYPES = [
|
|
|
23679
24041
|
"interaction.ack.requested"
|
|
23680
24042
|
];
|
|
23681
24043
|
/**
|
|
24044
|
+
* The rule request events (subject = a request one member made to another for
|
|
24045
|
+
* an email rule over the other's own mail). Each goes to the person who did
|
|
24046
|
+
* not act: `created` and `withdrawn` to the member asked, `accepted` and
|
|
24047
|
+
* `declined` to the member who asked. They are opt-in, and only a webhook that
|
|
24048
|
+
* person made for them receives them.
|
|
24049
|
+
*/
|
|
24050
|
+
const EMAIL_RULE_REQUEST_EVENT_TYPES = [
|
|
24051
|
+
"email_rule_request.created",
|
|
24052
|
+
"email_rule_request.accepted",
|
|
24053
|
+
"email_rule_request.declined",
|
|
24054
|
+
"email_rule_request.withdrawn"
|
|
24055
|
+
];
|
|
24056
|
+
/**
|
|
23682
24057
|
* The full enumerated catalog of every current webhook event type: the five
|
|
23683
|
-
* email.*, the four opt-in sent_email.*,
|
|
23684
|
-
* interaction.<protocol>.<suffix>.
|
|
24058
|
+
* email.*, the four opt-in sent_email.*, the four opt-in
|
|
24059
|
+
* email_rule_request.*, and every interaction.<protocol>.<suffix>.
|
|
23685
24060
|
*/
|
|
23686
24061
|
const WEBHOOK_EVENT_TYPES = [
|
|
23687
24062
|
...EMAIL_EVENT_TYPES,
|
|
23688
24063
|
...SENT_EMAIL_EVENT_TYPES,
|
|
24064
|
+
...EMAIL_RULE_REQUEST_EVENT_TYPES,
|
|
23689
24065
|
...INTERACTION_EVENT_TYPES
|
|
23690
24066
|
];
|
|
23691
24067
|
const WEBHOOK_EVENT_TYPE_SET = new Set(WEBHOOK_EVENT_TYPES);
|
|
@@ -24224,7 +24600,6 @@ function ensureSearchReportsReplyState(apiClient) {
|
|
|
24224
24600
|
}
|
|
24225
24601
|
return probe;
|
|
24226
24602
|
}
|
|
24227
|
-
// src/oclif/commands/emails-poll.ts
|
|
24228
24603
|
function quoteDslValue(value) {
|
|
24229
24604
|
if (/^[^\s"]+$/.test(value)) return value;
|
|
24230
24605
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
@@ -24233,11 +24608,6 @@ function combineQ(q, domain) {
|
|
|
24233
24608
|
const parts = [q?.trim(), domain ? `domain:${quoteDslValue(domain.trim())}` : void 0].filter((part) => Boolean(part));
|
|
24234
24609
|
return parts.length > 0 ? parts.join(" ") : void 0;
|
|
24235
24610
|
}
|
|
24236
|
-
function normalizeIsoDate(value, label) {
|
|
24237
|
-
const parsed = new Date(value);
|
|
24238
|
-
if (Number.isNaN(parsed.getTime())) throw new Error(`${label} must be a valid date or ISO-8601 timestamp.`);
|
|
24239
|
-
return parsed.toISOString();
|
|
24240
|
-
}
|
|
24241
24611
|
function filtersFromFlags(flags) {
|
|
24242
24612
|
if (flags.automated !== void 0 && !AUTOMATED_VALUES.includes(flags.automated)) throw new Error("--automated must be true or false.");
|
|
24243
24613
|
return {
|
|
@@ -24256,16 +24626,37 @@ function filtersFromFlags(flags) {
|
|
|
24256
24626
|
to: flags.to
|
|
24257
24627
|
};
|
|
24258
24628
|
}
|
|
24259
|
-
|
|
24260
|
-
|
|
24261
|
-
|
|
24629
|
+
const SINCE_DURATION = /^(\d+)\s*(s|m|h|d)$/i;
|
|
24630
|
+
const SINCE_UNIT_MS = {
|
|
24631
|
+
s: 1e3,
|
|
24632
|
+
m: 6e4,
|
|
24633
|
+
h: 36e5,
|
|
24634
|
+
d: 864e5
|
|
24635
|
+
};
|
|
24636
|
+
/** How --since reads: a date or timestamp, or a duration ago (`15m`). */
|
|
24637
|
+
const SINCE_VALUE_HELP = "an ISO-8601 timestamp or date, or a duration ago such as 30s, 15m, 2h or 1d";
|
|
24638
|
+
/**
|
|
24639
|
+
* Read --since: an ISO-8601 timestamp or date, or a duration before `now`
|
|
24640
|
+
* (`30s`, `15m`, `2h`, `1d`).
|
|
24641
|
+
*/
|
|
24642
|
+
function parseSince(value, now = Date.now()) {
|
|
24643
|
+
if (/^\s*\d+\s*$/.test(value)) throw new Error(`--since needs a unit on a duration, for example ${value.trim()}m; it takes ${SINCE_VALUE_HELP}.`);
|
|
24644
|
+
const duration = SINCE_DURATION.exec(value.trim());
|
|
24645
|
+
const unit = duration ? SINCE_UNIT_MS[duration[2].toLowerCase()] : void 0;
|
|
24646
|
+
const parsed = duration && unit !== void 0 ? new Date(now - Number(duration[1]) * unit) : new Date(value);
|
|
24647
|
+
if (Number.isNaN(parsed.getTime()) || parsed.getTime() < 0) throw new Error(`--since must be ${SINCE_VALUE_HELP}.`);
|
|
24648
|
+
return parsed.toISOString();
|
|
24649
|
+
}
|
|
24650
|
+
function sinceFromFlags(flags, now = Date.now()) {
|
|
24651
|
+
if (flags.since) return parseSince(flags.since, now);
|
|
24652
|
+
return flags["include-existing"] ? void 0 : new Date(now).toISOString();
|
|
24262
24653
|
}
|
|
24263
24654
|
function buildEmailSearchQuery(params) {
|
|
24264
24655
|
const query = {
|
|
24265
24656
|
include_facets: "false",
|
|
24266
24657
|
limit: params.pageSize,
|
|
24267
24658
|
snippet: "false",
|
|
24268
|
-
sort: "received_at_asc"
|
|
24659
|
+
sort: params.order ?? "received_at_asc"
|
|
24269
24660
|
};
|
|
24270
24661
|
const q = combineQ(params.filters.q, params.filters.domain);
|
|
24271
24662
|
if (q) query.q = q;
|
|
@@ -24282,6 +24673,7 @@ function buildEmailSearchQuery(params) {
|
|
|
24282
24673
|
if (params.filters.to) query.to = params.filters.to;
|
|
24283
24674
|
if (params.since) query.date_from = params.since;
|
|
24284
24675
|
if (params.cursor) query.cursor = params.cursor;
|
|
24676
|
+
if (params.count === false) query.count = "false";
|
|
24285
24677
|
return query;
|
|
24286
24678
|
}
|
|
24287
24679
|
function encodeReceivedAtSearchCursor(email) {
|
|
@@ -24309,12 +24701,126 @@ function collectNewAcceptedEmails(rows, seenIds) {
|
|
|
24309
24701
|
}
|
|
24310
24702
|
return fresh;
|
|
24311
24703
|
}
|
|
24704
|
+
/**
|
|
24705
|
+
* How long after arriving an email may become readable and still be reported
|
|
24706
|
+
* by an idle poll's re-read; how often a re-read comes; and the most pages, of
|
|
24707
|
+
* MAX_EMAIL_POLL_PAGE_SIZE each, one re-read reads.
|
|
24708
|
+
*/
|
|
24709
|
+
const LATE_MAIL_WINDOW_MS = 6e5;
|
|
24710
|
+
const LATE_MAIL_REREAD_MS = 15e3;
|
|
24711
|
+
/** How far a re-read reads back at most, however long re-reads have been cut short, unless its interval needs more. */
|
|
24712
|
+
const LATE_MAIL_MAX_LOOKBACK_MS = 36e5;
|
|
24713
|
+
/** Read back this much further, as this clock may run ahead of the server's. */
|
|
24714
|
+
const LATE_MAIL_CLOCK_SLACK_MS = 6e4;
|
|
24715
|
+
/**
|
|
24716
|
+
* Mail received from `from` (LATE_MAIL_WINDOW_MS ago when not given, and
|
|
24717
|
+
* never before `since`), oldest first. Pages come in order of when an email
|
|
24718
|
+
* was received, but an email can become readable to this credential after one
|
|
24719
|
+
* received later: it was accepted more slowly, held while its sender was
|
|
24720
|
+
* checked, or granted to a key by an email rule once classified. By then the
|
|
24721
|
+
* cursor is past its place, so an idle poll re-reads recent mail and keeps
|
|
24722
|
+
* only rows it has not seen. It reads newest first, where late mail mostly
|
|
24723
|
+
* is, so a busy stretch that holds more than the pages read loses its oldest
|
|
24724
|
+
* part rather than its newest. Best effort: a page that fails ends the
|
|
24725
|
+
* re-read with what it has, and the poll goes on; so does reaching
|
|
24726
|
+
* `deadline`. `cutShort` says it did not reach as far back as it would have:
|
|
24727
|
+
* a page failed, the deadline came, or a search the server stopped early for
|
|
24728
|
+
* time returned short pages up to the page limit. `failed` is the page that
|
|
24729
|
+
* failed, so the caller can wait as long as the server asked (Retry-After).
|
|
24730
|
+
*/
|
|
24731
|
+
async function fetchRecentEmails(params) {
|
|
24732
|
+
const fetchPage = params.fetchPage ?? fetchEmailSearchPage;
|
|
24733
|
+
const now = params.now ?? Date.now();
|
|
24734
|
+
const sinceMs = params.since ? Date.parse(params.since) : NaN;
|
|
24735
|
+
const wanted = params.from ?? now - 6e5;
|
|
24736
|
+
const from = Number.isNaN(sinceMs) ? wanted : Math.max(wanted, sinceMs);
|
|
24737
|
+
const newestFirst = [];
|
|
24738
|
+
const result = (cutShort) => ({
|
|
24739
|
+
rows: newestFirst.reverse(),
|
|
24740
|
+
cutShort
|
|
24741
|
+
});
|
|
24742
|
+
let cursor = null;
|
|
24743
|
+
for (let pages = 0; pages < 3; pages += 1) {
|
|
24744
|
+
if (params.deadline !== void 0 && params.deadline !== null && Date.now() >= params.deadline) return result(true);
|
|
24745
|
+
let page;
|
|
24746
|
+
try {
|
|
24747
|
+
page = await fetchPage({
|
|
24748
|
+
apiClient: params.apiClient,
|
|
24749
|
+
count: false,
|
|
24750
|
+
cursor,
|
|
24751
|
+
filters: params.filters,
|
|
24752
|
+
order: "received_at_desc",
|
|
24753
|
+
pageSize: 100,
|
|
24754
|
+
since: new Date(from).toISOString()
|
|
24755
|
+
});
|
|
24756
|
+
} catch {
|
|
24757
|
+
return result(true);
|
|
24758
|
+
}
|
|
24759
|
+
if (!page.ok) return {
|
|
24760
|
+
...result(true),
|
|
24761
|
+
failed: page
|
|
24762
|
+
};
|
|
24763
|
+
newestFirst.push(...page.rows);
|
|
24764
|
+
if (!page.more || !page.cursor) return result(false);
|
|
24765
|
+
cursor = page.cursor;
|
|
24766
|
+
}
|
|
24767
|
+
return result(newestFirst.length < 300);
|
|
24768
|
+
}
|
|
24769
|
+
/**
|
|
24770
|
+
* An idle poll's re-reads of recent mail (fetchRecentEmails), made once the
|
|
24771
|
+
* poll's cursor has passed some mail, with `start` when the poll that first
|
|
24772
|
+
* moved it was made.
|
|
24773
|
+
*
|
|
24774
|
+
* One is due an interval after `start`, as until then the poll has read the
|
|
24775
|
+
* same mail itself, and then an interval after the last one ended, so a slow
|
|
24776
|
+
* re-read is not followed straight away by another. The interval is
|
|
24777
|
+
* LATE_MAIL_REREAD_MS, or LATE_MAIL_REREAD_POLLS poll intervals when that is
|
|
24778
|
+
* longer. A re-read is made only on a poll that brought nothing new once it
|
|
24779
|
+
* is due, so a wait that ends before the next one is made does not report
|
|
24780
|
+
* mail that became readable since the last. `deadline` stops a re-read's
|
|
24781
|
+
* paging (fetchRecentEmails).
|
|
24782
|
+
*
|
|
24783
|
+
* Each re-read reads from LATE_MAIL_WINDOW_MS (and LATE_MAIL_CLOCK_SLACK_MS)
|
|
24784
|
+
* before the last one that was not cut short began (before `start`, at
|
|
24785
|
+
* first), so an email that becomes readable within LATE_MAIL_WINDOW_MS of
|
|
24786
|
+
* arriving is read however far apart re-reads come. That holds while it is
|
|
24787
|
+
* among the most one re-read reads, and while a re-read that is not cut short
|
|
24788
|
+
* comes within the look-back limit (LATE_MAIL_MAX_LOOKBACK_MS, or more for a
|
|
24789
|
+
* long interval) less LATE_MAIL_WINDOW_MS of it becoming readable.
|
|
24790
|
+
*/
|
|
24791
|
+
function lateMailReread(options) {
|
|
24792
|
+
const { pollIntervalMs, deadline, start } = options;
|
|
24793
|
+
const intervalMs = Math.max(LATE_MAIL_REREAD_MS, 3 * pollIntervalMs);
|
|
24794
|
+
const maxLookBackMs = Math.max(LATE_MAIL_MAX_LOOKBACK_MS, LATE_MAIL_WINDOW_MS + 2 * intervalMs);
|
|
24795
|
+
let covered = start;
|
|
24796
|
+
let ended = start;
|
|
24797
|
+
return {
|
|
24798
|
+
due: (now = Date.now()) => now - ended >= intervalMs,
|
|
24799
|
+
read: async (params) => {
|
|
24800
|
+
const begun = Date.now();
|
|
24801
|
+
const { rows, cutShort, failed } = await fetchRecentEmails({
|
|
24802
|
+
...params,
|
|
24803
|
+
deadline,
|
|
24804
|
+
from: Math.max(covered - LATE_MAIL_WINDOW_MS, begun - maxLookBackMs) - LATE_MAIL_CLOCK_SLACK_MS,
|
|
24805
|
+
now: begun
|
|
24806
|
+
});
|
|
24807
|
+
if (!cutShort) covered = begun;
|
|
24808
|
+
ended = Date.now();
|
|
24809
|
+
return {
|
|
24810
|
+
rows,
|
|
24811
|
+
failed
|
|
24812
|
+
};
|
|
24813
|
+
}
|
|
24814
|
+
};
|
|
24815
|
+
}
|
|
24312
24816
|
async function fetchEmailSearchPage(params) {
|
|
24313
24817
|
const result = await searchEmails({
|
|
24314
24818
|
client: params.apiClient.client,
|
|
24315
24819
|
query: buildEmailSearchQuery({
|
|
24820
|
+
count: params.count,
|
|
24316
24821
|
cursor: params.cursor,
|
|
24317
24822
|
filters: params.filters,
|
|
24823
|
+
order: params.order,
|
|
24318
24824
|
pageSize: params.pageSize,
|
|
24319
24825
|
since: params.since
|
|
24320
24826
|
}),
|
|
@@ -24344,6 +24850,7 @@ async function fetchEmailSearchPage(params) {
|
|
|
24344
24850
|
return {
|
|
24345
24851
|
ok: true,
|
|
24346
24852
|
cursor: envelope?.meta.cursor ?? cursorFromRows(rows),
|
|
24853
|
+
more: Boolean(envelope?.meta.cursor),
|
|
24347
24854
|
rows
|
|
24348
24855
|
};
|
|
24349
24856
|
}
|
|
@@ -24438,6 +24945,16 @@ async function pauseForTransientFailure(failure, attempt, options) {
|
|
|
24438
24945
|
return deadline === null || Date.now() < deadline;
|
|
24439
24946
|
}
|
|
24440
24947
|
/**
|
|
24948
|
+
* After a failed read the caller does not retry, wait as long as the server
|
|
24949
|
+
* asked (Retry-After), if it did, before the caller's next request. False when
|
|
24950
|
+
* the deadline came first.
|
|
24951
|
+
*/
|
|
24952
|
+
async function waitOutRetryAfter(result, options) {
|
|
24953
|
+
const failure = transientFailure(result);
|
|
24954
|
+
if (failure?.retryAfterMs === void 0) return true;
|
|
24955
|
+
return pauseForTransientFailure(failure, 0, options);
|
|
24956
|
+
}
|
|
24957
|
+
/**
|
|
24441
24958
|
* Run an idempotent read, retrying transient failures until the deadline.
|
|
24442
24959
|
* Resolves the first result that is not transient, or null when the
|
|
24443
24960
|
* deadline passes first (or the read itself resolved null).
|
|
@@ -25280,4 +25797,4 @@ function repeatStopCommand(emailId) {
|
|
|
25280
25797
|
if (!UUID.test(emailId)) throw new TypeError("emailId must be an email UUID");
|
|
25281
25798
|
return `primitive repeat stop --id ${emailId.toLowerCase()}`;
|
|
25282
25799
|
}
|
|
25283
|
-
export {
|
|
25800
|
+
export { parseFromHeader as $, startAgentClaim as $n, getSendFrom as $t, lateMailReread as A, listWakeSchedules as An, downloadEmailAttachmentArchiveMember as At, ensureSearchReportsReplyState as B, resendAgentSignupVerification as Bn, getCreditBalance as Bt, waitOutRetryAfter as C, listRepeatingSends as Cn, createWakeSchedule as Ct, encodeReceivedAtSearchCursor as D, listSentEmails as Dn, deleteRoute as Dt, cursorFromAcceptedRows as E, listSentAttachmentArchiveMembers as En, deleteMemory as Et, AWAITING_VALUES as F, putContact as Fn, getAccessMode as Ft, queryUsesAwaiting as G, searchEmails as Gn, getFunctionTestRunTrace as Gt, formatRepliesCell as H, rotateKey as Hn, getEmail as Ht, REPLY_STATE_UNSUPPORTED_CODE as I, redeemCreditCode as In, getAccount as It, SENT_EMAIL_EVENT_TYPES as J, sendEmail as Jn, getMemory as Jt, replyStateSurfaceForOperation as K, searchMemories as Kn, getInboxStatus as Kt, ReplyStateUnsupportedError as L, removeDefaultNetworkMember as Ln, getAgentContactPolicy as Lt, sinceFromFlags as M, pullWebhookEvent as Mn, downloadEmailAttachmentPart as Mt, sleep as N, putAgentContact as Nn, downloadSentAttachmentArchiveMember as Nt, fetchEmailSearchPage as O, listWakeAuthorizations as On, deleteWakeAuthorization as Ot, AWAITING_FLAG_DESCRIPTION as P, putAgentContactPolicy as Pn, downloadSentAttachmentByFilename as Pt, parseWebhookEvent as Q, simulateRoute as Qn, getRepeatingSend as Qt, assertAwaitingFilterRows as R, reorderRoutes as Rn, getContact as Rt, transientFailure as S, listOrganizationPeople as Sn, createWakeAuthorization as St, collectNewAcceptedEmails as T, listRoutes as Tn, deleteContact as Tt, hasReplyState as U, runWakeSchedule as Un, getFunction as Ut, formatAwaitingCell as V, revokeCredential as Vn, getDefaultNetworkAgent as Vt, isAwaitingRejectedError as W, sdk_gen_exports as Wn, getFunctionRouting as Wt, isEmailReceivedEvent as X, setFunctionSecret as Xn, getOutboundStatus as Xt, WEBHOOK_EVENT_TYPES as Y, setFunctionRoute as Yn, getOrgRoutingTopology as Yt, isTrustedSender as Z, setMemory as Zn, getOwnGrant as Zt, describeApiFailure as _, listFunctionLogs as _n, completeWebhookEvent as _t, REPEAT_IDLE_MAX_MINUTES as a, listActivityObjects as an, updateDefaultNetworkMember as ar, automatedRejectedError as at, retryTransient as b, listKeys as bn, createKey as bt, classifySignalContent as c, listAgentNetworks as cn, updateRepeatingSend as cr, expectedAutomatedVerdicts as ct, parseRepeatTick as d, listDefaultNetworkMembers as dn, updateWakeSchedule as dr, addDefaultNetworkMember as dt, getSentEmail as en, startAgentSignup as er, AUTOMATED_FILTER_UNSUPPORTED_CODE as et, preparePresenceAliveEmail as f, listDomains as fn, verifyAgentClaim as fr, cancelSentEmail as ft, WaitDeadlineReached as g, listEndpoints as gn, cliLogout as gt, sendPreparedSignal as h, listEmails as hn, __exportAll as hr, checkSendability as ht, REPEAT_EVERY_MAX_MINUTES as i, leaveOrganization as in, unsetFunctionRoute as ir, assertAutomatedVerdict as it, quoteDslValue as j, pollCliLogin as jn, downloadEmailAttachmentByFilename as jt, filtersFromFlags as k, listWakeDispatches as kn, deleteWakeSchedule as kt, parseInteractionEnvelope as l, listContacts as ln, updateRoute as lr, hasAutomatedVerdict as lt, repeatStopCommand as m, listEmailRuleResults as mn, whoami as mr, checkDefaultNetworkContactAdmission as mt, MAX_PRESENCE_ENVELOPE_BYTES as n, getWakeSchedule as nn, stopRepeatFromEmail as nr, AUTOMATED_VALUES as nt, REPEAT_MAX_SENDS_MAX as o, listAgentConnections as on, updateFunction as or, automatedSurfaceForOperation as ot, prepareSignalEmail as p, listEmailAttachmentArchiveMembers as pn, verifyAgentSignup as pr, cancelSentEmailByIdempotencyKey as pt, EMAIL_RULE_REQUEST_EVENT_TYPES as q, semanticSearch as qn, getKey as qt, PRESENCE_PROBE_TEXT as r, inviteAgentConnection as rn, testFunction as rr, AutomatedFilterUnsupportedError as rt, buildRepeatStopBody as s, listAgentContacts as sn, updateKey as sr, ensureSearchReportsAutomated as st, MAX_INTERACTION_BYTES as t, getThread as tn, startCliLogin as tr, AUTOMATED_FLAG_DESCRIPTION as tt, parsePresenceEnvelope as u, listDefaultNetworkAgents as un, updateWakeAuthorization as ur, isAutomatedRejectedError as ut, parseRetryAfter as v, listFunctions as vn, createEndpoint as vt, SINCE_VALUE_HELP as w, listRoles as wn, deleteAgentContact as wt, retryingOperation as x, listMailboxAccess as xn, createRoute as xt, pauseForTransientFailure as y, listGroups as yn, createFunction as yt, awaitingRejectedError as z, replyToEmail as zn, getConversation as zt };
|