primcli 3.0.0-preview.12 → 3.0.0-preview.14
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 +2 -1
- package/dist/{api-command-CNCsVNk0.js → api-command-BTOIanV1.js} +2007 -125
- package/dist/{machine-session-DkXYR62a.js → machine-session-BTkDAKda.js} +4 -4
- package/dist/{notify-session-WKFsaFt3.js → notify-session-b_0jyPIk.js} +2 -2
- package/dist/oclif/auto-signal-worker.js +3 -3
- package/dist/oclif/auto-signals.js +1 -1
- package/dist/oclif/index.js +2248 -423
- package/dist/oclif/receiver-heal.js +2 -2
- package/dist/{repeats-Dj_o6c-X-wjmw2Jbx.js → repeats-Dj_o6c-X-B7sSj0oc.js} +128 -6
- package/dist/{scoped-chat-B1Fi6_qM.js → scoped-chat-Cqmn-k7q.js} +1 -1
- package/dist/{signal-command-BdJVZXGl.js → signal-command-ewPBzvjU.js} +4 -4
- package/man/primitive.1 +3 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $t as getOwnGrant, B as awaitingRejectedError, G as isAwaitingRejectedError, J as EMAIL_RULE_OBJECTION_EVENT_TYPES, Kn as sdk_gen_exports, R as ReplyStateUnsupportedError, V as ensureSearchReportsReplyState, Wt as getEmail, X as SENT_EMAIL_EVENT_TYPES, Y as EMAIL_RULE_REQUEST_EVENT_TYPES, Z as WEBHOOK_EVENT_TYPES, at as AutomatedFilterUnsupportedError, ct as automatedSurfaceForOperation, ft as isAutomatedRejectedError, lt as ensureSearchReportsAutomated, ot as assertAutomatedVerdict, q as replyStateSurfaceForOperation, rn as getThread, st as automatedRejectedError, ut as expectedAutomatedVerdicts, vn as listEndpoints, y as parseRetryAfter, z as assertAwaitingFilterRows } from "./repeats-Dj_o6c-X-B7sSj0oc.js";
|
|
2
2
|
import { C as saveCliCredentials, F as agentProfilesDirectory, H as requireDefaultLoginProfile, N as agentProfileDirectory, R as loadConnectedAgentProfile, S as resolveCliAuth, W as PrimitiveApiClient, _ as deleteCliCredentials, b as loadCliCredentials, c as resolveConfigEnvironment, d as validateCliHeaderName, f as validateCliHeaderValue, i as loadCliConfig, j as AGENT_PROFILE_ENV, m as cliAccessTokenExpiresAt, p as acquireCliCredentialsLock, w as saveSignupCredentials, x as normalizeApiBaseUrl, y as detectPrimitiveKeyEnvMisname } from "./cli-config-Ms_0vNjq.js";
|
|
3
3
|
import "./oclif/global-org-flag.js";
|
|
4
4
|
import { a as thrownErrorBody } from "./json-output-ch756TXV.js";
|
|
@@ -780,7 +780,7 @@ const operationManifest = [
|
|
|
780
780
|
"binaryResponse": false,
|
|
781
781
|
"bodyRequired": false,
|
|
782
782
|
"command": "list-activity-objects",
|
|
783
|
-
"description": "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. With relation=concerning it lists instead what other members did that concerns the person's own mail: each time a rule started covering one of their mailboxes
|
|
783
|
+
"description": "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. With relation=concerning it lists instead what other members did that concerns the person's own mail: each time a rule started covering one of their mailboxes, saved a new version, or changed who receives its matches while covering it, named as the rule was then, naming its author in created_through, under their current membership; only on the dashboard or the Primitive CLI. A key, an app or an agent has none, and gets email_rule_coverage in withheld. A notice never reads as ended. Notices are written by a periodic job and can lag: until the notices record a rule starting to cover you, the first page lists that rule as pending (pending_complete says whether that check finished), and as_of says about when the notices last looked. For what covers you now, read GET /email-rules/covering-me.",
|
|
784
784
|
"hasJsonBody": false,
|
|
785
785
|
"method": "GET",
|
|
786
786
|
"operationId": "listActivityObjects",
|
|
@@ -863,7 +863,7 @@ const operationManifest = [
|
|
|
863
863
|
},
|
|
864
864
|
"state": {
|
|
865
865
|
"type": "string",
|
|
866
|
-
"description": "Where it stands now: enabled, disabled, deleted or replaced (endpoints and routes), enabled or disabled (filters, wake schedules), live, suspended or deleted (Functions), active, paused or ended (repeating sends), scheduled (scheduled sends), active, suspended, expired or revoked (API keys), pending, claimed, connected or revoked (agents), draft, observe or active (email rules), pending, accepted, declined or withdrawn (rule requests and objections), and for a coverage notice what it told: started (a rule
|
|
866
|
+
"description": "Where it stands now: enabled, disabled, deleted or replaced (endpoints and routes), enabled or disabled (filters, wake schedules), live, suspended or deleted (Functions), active, paused or ended (repeating sends), scheduled (scheduled sends), active, suspended, expired or revoked (API keys), pending, claimed, connected or revoked (agents), draft, observe or active (email rules), pending, accepted, declined or withdrawn (rule requests and objections), and for a coverage notice what it told: started (a rule was made or turned active over your mailboxes, or an active rule came to reach you; once per rule, not per mailbox), new_version, receivers_changed (who receives an active rule's matches changed: its keys, webhooks or share), or baseline (it already covered you when notices began). pending: a rule started covering your mailbox and the notices have not recorded that start yet (a restart within an hour of the last start notice is recorded without a new one); its id is then the rule's, and created_at when the rule last changed."
|
|
867
867
|
},
|
|
868
868
|
"created_at": {
|
|
869
869
|
"type": "string",
|
|
@@ -872,7 +872,7 @@ const operationManifest = [
|
|
|
872
872
|
"ended_at": {
|
|
873
873
|
"type": ["string", "null"],
|
|
874
874
|
"format": "date-time",
|
|
875
|
-
"description": "When it was deleted, replaced or revoked, when an API key expired, when a repeating send stopped, or when a rule request or objection was decided (accepted, declined or withdrawn); null otherwise."
|
|
875
|
+
"description": "When it was deleted, replaced or revoked, when an API key expired, when a repeating send stopped, or when a rule request or objection was decided (accepted, declined or withdrawn); null otherwise, as on every coverage notice."
|
|
876
876
|
},
|
|
877
877
|
"owned_now": {
|
|
878
878
|
"type": "string",
|
|
@@ -900,6 +900,74 @@ const operationManifest = [
|
|
|
900
900
|
"id",
|
|
901
901
|
"name"
|
|
902
902
|
]
|
|
903
|
+
},
|
|
904
|
+
"rule_id": {
|
|
905
|
+
"description": "For email_rule_coverage, always: the rule it is about, since names need not be unique (for pending, the same as id). GET /v1/email-rules/covering-me/{rule_id} shows the rule while it covers you, or as it last decided on your mail; otherwise it answers not_found.",
|
|
906
|
+
"type": "string",
|
|
907
|
+
"format": "uuid"
|
|
908
|
+
},
|
|
909
|
+
"receivers_change": {
|
|
910
|
+
"description": "For a receivers_changed notice: who received the rule's matches before and after, in totals. They can be equal when only an owner or a webhook site changed; covering-me shows them by owner. A rotated key counts once here while the old one still works; covering-me counts both.",
|
|
911
|
+
"type": "object",
|
|
912
|
+
"properties": {
|
|
913
|
+
"before": {
|
|
914
|
+
"type": "object",
|
|
915
|
+
"properties": {
|
|
916
|
+
"keys": {
|
|
917
|
+
"type": "integer",
|
|
918
|
+
"minimum": 0
|
|
919
|
+
},
|
|
920
|
+
"reads_in_full": {
|
|
921
|
+
"type": "integer",
|
|
922
|
+
"minimum": 0,
|
|
923
|
+
"description": "Of the keys, how many also read your own mail beyond the rule."
|
|
924
|
+
},
|
|
925
|
+
"webhooks": {
|
|
926
|
+
"type": "integer",
|
|
927
|
+
"minimum": 0
|
|
928
|
+
},
|
|
929
|
+
"shares": {
|
|
930
|
+
"type": "integer",
|
|
931
|
+
"minimum": 0
|
|
932
|
+
}
|
|
933
|
+
},
|
|
934
|
+
"required": [
|
|
935
|
+
"keys",
|
|
936
|
+
"reads_in_full",
|
|
937
|
+
"webhooks",
|
|
938
|
+
"shares"
|
|
939
|
+
]
|
|
940
|
+
},
|
|
941
|
+
"after": {
|
|
942
|
+
"type": "object",
|
|
943
|
+
"properties": {
|
|
944
|
+
"keys": {
|
|
945
|
+
"type": "integer",
|
|
946
|
+
"minimum": 0
|
|
947
|
+
},
|
|
948
|
+
"reads_in_full": {
|
|
949
|
+
"type": "integer",
|
|
950
|
+
"minimum": 0,
|
|
951
|
+
"description": "Of the keys, how many also read your own mail beyond the rule."
|
|
952
|
+
},
|
|
953
|
+
"webhooks": {
|
|
954
|
+
"type": "integer",
|
|
955
|
+
"minimum": 0
|
|
956
|
+
},
|
|
957
|
+
"shares": {
|
|
958
|
+
"type": "integer",
|
|
959
|
+
"minimum": 0
|
|
960
|
+
}
|
|
961
|
+
},
|
|
962
|
+
"required": [
|
|
963
|
+
"keys",
|
|
964
|
+
"reads_in_full",
|
|
965
|
+
"webhooks",
|
|
966
|
+
"shares"
|
|
967
|
+
]
|
|
968
|
+
}
|
|
969
|
+
},
|
|
970
|
+
"required": ["before", "after"]
|
|
903
971
|
}
|
|
904
972
|
},
|
|
905
973
|
"required": [
|
|
@@ -9695,6 +9763,14 @@ const operationManifest = [
|
|
|
9695
9763
|
"additionalProperties": {}
|
|
9696
9764
|
}
|
|
9697
9765
|
},
|
|
9766
|
+
"mail_limits_available": {
|
|
9767
|
+
"description": "Whether a key limited to some mail (addresses, domains or email rules) would be created now. While false, creating one is refused, so a client offers neither the listed-address presets nor a listed mail reach for a custom key.",
|
|
9768
|
+
"type": "boolean"
|
|
9769
|
+
},
|
|
9770
|
+
"org_reach_available": {
|
|
9771
|
+
"description": "Whether the credential policy lets a new key reach every mailbox. While false, creating one is refused, so a client offers no preset that reaches every mailbox, and a custom key lists its addresses or domains. With mail_limits_available false as well, no key can be created and every preset is unavailable.",
|
|
9772
|
+
"type": "boolean"
|
|
9773
|
+
},
|
|
9698
9774
|
"matrix": {
|
|
9699
9775
|
"type": "array",
|
|
9700
9776
|
"items": {
|
|
@@ -11227,6 +11303,27 @@ const operationManifest = [
|
|
|
11227
11303
|
"additionalProperties": {}
|
|
11228
11304
|
}
|
|
11229
11305
|
},
|
|
11306
|
+
"rules_added": {
|
|
11307
|
+
"description": "Each rule (or share) the edit put on a key that reads mail, with granted_emails, how many emails it has already shared, which the key can now read while it is active: counted up to 10,000, with more: true past that; null when not counted.",
|
|
11308
|
+
"type": "array",
|
|
11309
|
+
"items": {
|
|
11310
|
+
"type": "object",
|
|
11311
|
+
"properties": {
|
|
11312
|
+
"id": { "type": "string" },
|
|
11313
|
+
"granted_emails": {
|
|
11314
|
+
"type": ["integer", "null"],
|
|
11315
|
+
"minimum": 0,
|
|
11316
|
+
"maximum": 9007199254740991
|
|
11317
|
+
},
|
|
11318
|
+
"more": {
|
|
11319
|
+
"type": "boolean",
|
|
11320
|
+
"const": true
|
|
11321
|
+
}
|
|
11322
|
+
},
|
|
11323
|
+
"required": ["id", "granted_emails"],
|
|
11324
|
+
"additionalProperties": {}
|
|
11325
|
+
}
|
|
11326
|
+
},
|
|
11230
11327
|
"grant_unguarded": {
|
|
11231
11328
|
"description": "Present, as true, when the grant was changed without expected_grant_ref, so the change was not checked against changes made since the key was read. Send grant.ref from GET /v1/keys/{id} as expected_grant_ref to have such a change refused instead (409 conflict, details.reason grant_changed).",
|
|
11232
11329
|
"type": "boolean",
|
|
@@ -12344,11 +12441,17 @@ const operationManifest = [
|
|
|
12344
12441
|
"type": "string"
|
|
12345
12442
|
}],
|
|
12346
12443
|
"queryParams": [{
|
|
12347
|
-
"description": "When true, include only outbound DNS records.
|
|
12444
|
+
"description": "When true, include only outbound DNS records. Cannot be combined with inbound_only=true. By default, include all records.",
|
|
12348
12445
|
"enum": null,
|
|
12349
12446
|
"name": "outbound_only",
|
|
12350
12447
|
"required": false,
|
|
12351
12448
|
"type": "boolean"
|
|
12449
|
+
}, {
|
|
12450
|
+
"description": "When true, include only inbound MX and ownership TXT records. Cannot be combined with outbound_only=true.",
|
|
12451
|
+
"enum": null,
|
|
12452
|
+
"name": "inbound_only",
|
|
12453
|
+
"required": false,
|
|
12454
|
+
"type": "boolean"
|
|
12352
12455
|
}],
|
|
12353
12456
|
"headerParams": [],
|
|
12354
12457
|
"permissions": ["domains:read"],
|
|
@@ -13044,6 +13147,388 @@ const operationManifest = [
|
|
|
13044
13147
|
"tag": "Domains",
|
|
13045
13148
|
"tagCommand": "domains"
|
|
13046
13149
|
},
|
|
13150
|
+
{
|
|
13151
|
+
"binaryResponse": false,
|
|
13152
|
+
"bodyRequired": false,
|
|
13153
|
+
"command": "get-email-notification-preferences",
|
|
13154
|
+
"description": "The notification emails the calling member gets, and which of them they may turn on or off. Each kind lists its label and description, its class, whether it needs an entitlement and whether the organization has it, the organization's mode (null for platform_required) and the modes it may choose, and whether the calling member gets it and may change that.\n\nPerson only: a dashboard session or the person's own OAuth token (the CLI or an app they connected). The person's role must hold notifications:manage. API keys, agent connection keys and agents are refused.",
|
|
13155
|
+
"hasJsonBody": false,
|
|
13156
|
+
"method": "GET",
|
|
13157
|
+
"operationId": "getEmailNotificationPreferences",
|
|
13158
|
+
"path": "/email-notification-preferences",
|
|
13159
|
+
"pathParams": [],
|
|
13160
|
+
"queryParams": [],
|
|
13161
|
+
"headerParams": [],
|
|
13162
|
+
"permissions": ["notifications:manage"],
|
|
13163
|
+
"access": "person",
|
|
13164
|
+
"requestSchema": null,
|
|
13165
|
+
"responseSchema": {
|
|
13166
|
+
"type": "object",
|
|
13167
|
+
"properties": {
|
|
13168
|
+
"entitled": { "type": "boolean" },
|
|
13169
|
+
"kinds": {
|
|
13170
|
+
"type": "array",
|
|
13171
|
+
"items": {
|
|
13172
|
+
"type": "object",
|
|
13173
|
+
"properties": {
|
|
13174
|
+
"kind": { "type": "string" },
|
|
13175
|
+
"label": { "type": "string" },
|
|
13176
|
+
"description": { "type": "string" },
|
|
13177
|
+
"class": {
|
|
13178
|
+
"type": "string",
|
|
13179
|
+
"enum": [
|
|
13180
|
+
"platform_required",
|
|
13181
|
+
"org_requirable",
|
|
13182
|
+
"optional"
|
|
13183
|
+
]
|
|
13184
|
+
},
|
|
13185
|
+
"entitlement_required": { "type": "boolean" },
|
|
13186
|
+
"entitled": { "type": "boolean" },
|
|
13187
|
+
"org_mode": {
|
|
13188
|
+
"type": ["string", "null"],
|
|
13189
|
+
"enum": [
|
|
13190
|
+
"off",
|
|
13191
|
+
"optional_on",
|
|
13192
|
+
"optional_off",
|
|
13193
|
+
"required",
|
|
13194
|
+
null
|
|
13195
|
+
]
|
|
13196
|
+
},
|
|
13197
|
+
"org_mode_is_default": { "type": "boolean" },
|
|
13198
|
+
"org_modes": {
|
|
13199
|
+
"type": "array",
|
|
13200
|
+
"items": {
|
|
13201
|
+
"type": "string",
|
|
13202
|
+
"enum": [
|
|
13203
|
+
"off",
|
|
13204
|
+
"optional_on",
|
|
13205
|
+
"optional_off",
|
|
13206
|
+
"required"
|
|
13207
|
+
]
|
|
13208
|
+
}
|
|
13209
|
+
},
|
|
13210
|
+
"member_enabled": { "type": "boolean" },
|
|
13211
|
+
"member_can_change": { "type": "boolean" }
|
|
13212
|
+
},
|
|
13213
|
+
"required": [
|
|
13214
|
+
"kind",
|
|
13215
|
+
"label",
|
|
13216
|
+
"description",
|
|
13217
|
+
"class",
|
|
13218
|
+
"entitlement_required",
|
|
13219
|
+
"entitled",
|
|
13220
|
+
"org_mode",
|
|
13221
|
+
"org_mode_is_default",
|
|
13222
|
+
"org_modes",
|
|
13223
|
+
"member_enabled",
|
|
13224
|
+
"member_can_change"
|
|
13225
|
+
]
|
|
13226
|
+
}
|
|
13227
|
+
}
|
|
13228
|
+
},
|
|
13229
|
+
"required": ["entitled", "kinds"]
|
|
13230
|
+
},
|
|
13231
|
+
"sdkName": "getEmailNotificationPreferences",
|
|
13232
|
+
"summary": "Get my email notification preferences",
|
|
13233
|
+
"tag": "Email notifications",
|
|
13234
|
+
"tagCommand": "email-notifications"
|
|
13235
|
+
},
|
|
13236
|
+
{
|
|
13237
|
+
"binaryResponse": false,
|
|
13238
|
+
"bodyRequired": false,
|
|
13239
|
+
"command": "get-email-notification-settings",
|
|
13240
|
+
"description": "Every kind of notification email Primitive sends the organization's members, and who may turn it off. Each kind lists its label and description, its class, whether it needs an entitlement and whether the organization has it, the organization's mode (null for platform_required) and the modes it may choose, and whether the calling member gets it and may change that.\n\nPerson only: a dashboard session or the person's own OAuth token (the CLI or an app they connected). API keys, agent connection keys and agents are refused.",
|
|
13241
|
+
"hasJsonBody": false,
|
|
13242
|
+
"method": "GET",
|
|
13243
|
+
"operationId": "getEmailNotificationSettings",
|
|
13244
|
+
"path": "/email-notification-settings",
|
|
13245
|
+
"pathParams": [],
|
|
13246
|
+
"queryParams": [],
|
|
13247
|
+
"headerParams": [],
|
|
13248
|
+
"permissions": ["org:read"],
|
|
13249
|
+
"access": "person",
|
|
13250
|
+
"requestSchema": null,
|
|
13251
|
+
"responseSchema": {
|
|
13252
|
+
"type": "object",
|
|
13253
|
+
"properties": {
|
|
13254
|
+
"entitled": { "type": "boolean" },
|
|
13255
|
+
"kinds": {
|
|
13256
|
+
"type": "array",
|
|
13257
|
+
"items": {
|
|
13258
|
+
"type": "object",
|
|
13259
|
+
"properties": {
|
|
13260
|
+
"kind": { "type": "string" },
|
|
13261
|
+
"label": { "type": "string" },
|
|
13262
|
+
"description": { "type": "string" },
|
|
13263
|
+
"class": {
|
|
13264
|
+
"type": "string",
|
|
13265
|
+
"enum": [
|
|
13266
|
+
"platform_required",
|
|
13267
|
+
"org_requirable",
|
|
13268
|
+
"optional"
|
|
13269
|
+
]
|
|
13270
|
+
},
|
|
13271
|
+
"entitlement_required": { "type": "boolean" },
|
|
13272
|
+
"entitled": { "type": "boolean" },
|
|
13273
|
+
"org_mode": {
|
|
13274
|
+
"type": ["string", "null"],
|
|
13275
|
+
"enum": [
|
|
13276
|
+
"off",
|
|
13277
|
+
"optional_on",
|
|
13278
|
+
"optional_off",
|
|
13279
|
+
"required",
|
|
13280
|
+
null
|
|
13281
|
+
]
|
|
13282
|
+
},
|
|
13283
|
+
"org_mode_is_default": { "type": "boolean" },
|
|
13284
|
+
"org_modes": {
|
|
13285
|
+
"type": "array",
|
|
13286
|
+
"items": {
|
|
13287
|
+
"type": "string",
|
|
13288
|
+
"enum": [
|
|
13289
|
+
"off",
|
|
13290
|
+
"optional_on",
|
|
13291
|
+
"optional_off",
|
|
13292
|
+
"required"
|
|
13293
|
+
]
|
|
13294
|
+
}
|
|
13295
|
+
},
|
|
13296
|
+
"member_enabled": { "type": "boolean" },
|
|
13297
|
+
"member_can_change": { "type": "boolean" }
|
|
13298
|
+
},
|
|
13299
|
+
"required": [
|
|
13300
|
+
"kind",
|
|
13301
|
+
"label",
|
|
13302
|
+
"description",
|
|
13303
|
+
"class",
|
|
13304
|
+
"entitlement_required",
|
|
13305
|
+
"entitled",
|
|
13306
|
+
"org_mode",
|
|
13307
|
+
"org_mode_is_default",
|
|
13308
|
+
"org_modes",
|
|
13309
|
+
"member_enabled",
|
|
13310
|
+
"member_can_change"
|
|
13311
|
+
]
|
|
13312
|
+
}
|
|
13313
|
+
}
|
|
13314
|
+
},
|
|
13315
|
+
"required": ["entitled", "kinds"]
|
|
13316
|
+
},
|
|
13317
|
+
"sdkName": "getEmailNotificationSettings",
|
|
13318
|
+
"summary": "Get the organization's email notification settings",
|
|
13319
|
+
"tag": "Email notifications",
|
|
13320
|
+
"tagCommand": "email-notifications"
|
|
13321
|
+
},
|
|
13322
|
+
{
|
|
13323
|
+
"binaryResponse": false,
|
|
13324
|
+
"bodyRequired": true,
|
|
13325
|
+
"command": "update-email-notification-preferences",
|
|
13326
|
+
"description": "Turn one or more kinds on or off for the calling member. Only a kind whose organization mode is optional_on or optional_off can be changed: a platform_required kind, one the organization requires, and one it turned off are refused with 409 (conflict, details.reason not_member_choice, details.org_mode saying which), and nothing is changed. An unknown kind is refused with 400. Answers the preferences as they now stand. Each kind lists its label and description, its class, whether it needs an entitlement and whether the organization has it, the organization's mode (null for platform_required) and the modes it may choose, and whether the calling member gets it and may change that.\n\nPerson only: a dashboard session or the person's own OAuth token (the CLI or an app they connected). The person's role must hold notifications:manage. API keys, agent connection keys and agents are refused.",
|
|
13327
|
+
"hasJsonBody": true,
|
|
13328
|
+
"method": "PUT",
|
|
13329
|
+
"operationId": "updateEmailNotificationPreferences",
|
|
13330
|
+
"path": "/email-notification-preferences",
|
|
13331
|
+
"pathParams": [],
|
|
13332
|
+
"queryParams": [],
|
|
13333
|
+
"headerParams": [],
|
|
13334
|
+
"permissions": ["notifications:manage"],
|
|
13335
|
+
"access": "person",
|
|
13336
|
+
"requestSchema": {
|
|
13337
|
+
"type": "object",
|
|
13338
|
+
"properties": { "preferences": {
|
|
13339
|
+
"type": "object",
|
|
13340
|
+
"propertyNames": {
|
|
13341
|
+
"type": "string",
|
|
13342
|
+
"pattern": "^[a-z][a-z0-9_]{0,63}$"
|
|
13343
|
+
},
|
|
13344
|
+
"additionalProperties": { "type": "boolean" }
|
|
13345
|
+
} },
|
|
13346
|
+
"required": ["preferences"],
|
|
13347
|
+
"additionalProperties": false
|
|
13348
|
+
},
|
|
13349
|
+
"responseSchema": {
|
|
13350
|
+
"type": "object",
|
|
13351
|
+
"properties": {
|
|
13352
|
+
"entitled": { "type": "boolean" },
|
|
13353
|
+
"kinds": {
|
|
13354
|
+
"type": "array",
|
|
13355
|
+
"items": {
|
|
13356
|
+
"type": "object",
|
|
13357
|
+
"properties": {
|
|
13358
|
+
"kind": { "type": "string" },
|
|
13359
|
+
"label": { "type": "string" },
|
|
13360
|
+
"description": { "type": "string" },
|
|
13361
|
+
"class": {
|
|
13362
|
+
"type": "string",
|
|
13363
|
+
"enum": [
|
|
13364
|
+
"platform_required",
|
|
13365
|
+
"org_requirable",
|
|
13366
|
+
"optional"
|
|
13367
|
+
]
|
|
13368
|
+
},
|
|
13369
|
+
"entitlement_required": { "type": "boolean" },
|
|
13370
|
+
"entitled": { "type": "boolean" },
|
|
13371
|
+
"org_mode": {
|
|
13372
|
+
"type": ["string", "null"],
|
|
13373
|
+
"enum": [
|
|
13374
|
+
"off",
|
|
13375
|
+
"optional_on",
|
|
13376
|
+
"optional_off",
|
|
13377
|
+
"required",
|
|
13378
|
+
null
|
|
13379
|
+
]
|
|
13380
|
+
},
|
|
13381
|
+
"org_mode_is_default": { "type": "boolean" },
|
|
13382
|
+
"org_modes": {
|
|
13383
|
+
"type": "array",
|
|
13384
|
+
"items": {
|
|
13385
|
+
"type": "string",
|
|
13386
|
+
"enum": [
|
|
13387
|
+
"off",
|
|
13388
|
+
"optional_on",
|
|
13389
|
+
"optional_off",
|
|
13390
|
+
"required"
|
|
13391
|
+
]
|
|
13392
|
+
}
|
|
13393
|
+
},
|
|
13394
|
+
"member_enabled": { "type": "boolean" },
|
|
13395
|
+
"member_can_change": { "type": "boolean" }
|
|
13396
|
+
},
|
|
13397
|
+
"required": [
|
|
13398
|
+
"kind",
|
|
13399
|
+
"label",
|
|
13400
|
+
"description",
|
|
13401
|
+
"class",
|
|
13402
|
+
"entitlement_required",
|
|
13403
|
+
"entitled",
|
|
13404
|
+
"org_mode",
|
|
13405
|
+
"org_mode_is_default",
|
|
13406
|
+
"org_modes",
|
|
13407
|
+
"member_enabled",
|
|
13408
|
+
"member_can_change"
|
|
13409
|
+
]
|
|
13410
|
+
}
|
|
13411
|
+
}
|
|
13412
|
+
},
|
|
13413
|
+
"required": ["entitled", "kinds"]
|
|
13414
|
+
},
|
|
13415
|
+
"sdkName": "updateEmailNotificationPreferences",
|
|
13416
|
+
"summary": "Change my email notification preferences",
|
|
13417
|
+
"tag": "Email notifications",
|
|
13418
|
+
"tagCommand": "email-notifications"
|
|
13419
|
+
},
|
|
13420
|
+
{
|
|
13421
|
+
"binaryResponse": false,
|
|
13422
|
+
"bodyRequired": true,
|
|
13423
|
+
"command": "update-email-notification-settings",
|
|
13424
|
+
"description": "Set the organization's mode for one or more kinds: off (nobody gets it), optional_on (each member gets it unless they turn it off), optional_off (only members who turn it on get it) or required (every member gets it). Kinds left out keep their mode. An unknown kind is refused with 400 (validation_error, details.reason unknown_kind). A platform_required kind is refused with 409 (conflict, details.reason platform_required), and required for an optional kind with 409 (conflict, details.reason mode_not_allowed); nothing is changed. Answers the settings as they now stand. Each kind lists its label and description, its class, whether it needs an entitlement and whether the organization has it, the organization's mode (null for platform_required) and the modes it may choose, and whether the calling member gets it and may change that.\n\nPerson only: a dashboard session, or the person's own OAuth token with a step-up token for purpose `org_settings.write` in the Primitive-Step-Up header. Without one an 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 could not do it anyway). The person's role must hold notification_policy: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.",
|
|
13425
|
+
"hasJsonBody": true,
|
|
13426
|
+
"method": "PUT",
|
|
13427
|
+
"operationId": "updateEmailNotificationSettings",
|
|
13428
|
+
"path": "/email-notification-settings",
|
|
13429
|
+
"pathParams": [],
|
|
13430
|
+
"queryParams": [],
|
|
13431
|
+
"headerParams": [{
|
|
13432
|
+
"description": "A single-use step-up token of purpose `org_settings.write` (Change the organization name, logo, semantic search setting or email notification settings), valid 5 minutes. When this operation answers 403 `step_up_required`, the person confirms at the link in `details.step_up_url` and the request is retried with the token that page shows, in this header. Accepted only with the person's own OAuth token of the client it was confirmed for; refused with a token issued for MCP, with any API key or agent connection key, and with a dashboard session.",
|
|
13433
|
+
"enum": null,
|
|
13434
|
+
"name": "Primitive-Step-Up",
|
|
13435
|
+
"required": false,
|
|
13436
|
+
"type": "string"
|
|
13437
|
+
}],
|
|
13438
|
+
"permissions": ["notification_policy:manage"],
|
|
13439
|
+
"access": "step_up",
|
|
13440
|
+
"requestSchema": {
|
|
13441
|
+
"type": "object",
|
|
13442
|
+
"properties": { "modes": {
|
|
13443
|
+
"type": "object",
|
|
13444
|
+
"propertyNames": {
|
|
13445
|
+
"type": "string",
|
|
13446
|
+
"pattern": "^[a-z][a-z0-9_]{0,63}$"
|
|
13447
|
+
},
|
|
13448
|
+
"additionalProperties": {
|
|
13449
|
+
"type": "string",
|
|
13450
|
+
"enum": [
|
|
13451
|
+
"off",
|
|
13452
|
+
"optional_on",
|
|
13453
|
+
"optional_off",
|
|
13454
|
+
"required"
|
|
13455
|
+
]
|
|
13456
|
+
}
|
|
13457
|
+
} },
|
|
13458
|
+
"required": ["modes"],
|
|
13459
|
+
"additionalProperties": false
|
|
13460
|
+
},
|
|
13461
|
+
"responseSchema": {
|
|
13462
|
+
"type": "object",
|
|
13463
|
+
"properties": {
|
|
13464
|
+
"entitled": { "type": "boolean" },
|
|
13465
|
+
"kinds": {
|
|
13466
|
+
"type": "array",
|
|
13467
|
+
"items": {
|
|
13468
|
+
"type": "object",
|
|
13469
|
+
"properties": {
|
|
13470
|
+
"kind": { "type": "string" },
|
|
13471
|
+
"label": { "type": "string" },
|
|
13472
|
+
"description": { "type": "string" },
|
|
13473
|
+
"class": {
|
|
13474
|
+
"type": "string",
|
|
13475
|
+
"enum": [
|
|
13476
|
+
"platform_required",
|
|
13477
|
+
"org_requirable",
|
|
13478
|
+
"optional"
|
|
13479
|
+
]
|
|
13480
|
+
},
|
|
13481
|
+
"entitlement_required": { "type": "boolean" },
|
|
13482
|
+
"entitled": { "type": "boolean" },
|
|
13483
|
+
"org_mode": {
|
|
13484
|
+
"type": ["string", "null"],
|
|
13485
|
+
"enum": [
|
|
13486
|
+
"off",
|
|
13487
|
+
"optional_on",
|
|
13488
|
+
"optional_off",
|
|
13489
|
+
"required",
|
|
13490
|
+
null
|
|
13491
|
+
]
|
|
13492
|
+
},
|
|
13493
|
+
"org_mode_is_default": { "type": "boolean" },
|
|
13494
|
+
"org_modes": {
|
|
13495
|
+
"type": "array",
|
|
13496
|
+
"items": {
|
|
13497
|
+
"type": "string",
|
|
13498
|
+
"enum": [
|
|
13499
|
+
"off",
|
|
13500
|
+
"optional_on",
|
|
13501
|
+
"optional_off",
|
|
13502
|
+
"required"
|
|
13503
|
+
]
|
|
13504
|
+
}
|
|
13505
|
+
},
|
|
13506
|
+
"member_enabled": { "type": "boolean" },
|
|
13507
|
+
"member_can_change": { "type": "boolean" }
|
|
13508
|
+
},
|
|
13509
|
+
"required": [
|
|
13510
|
+
"kind",
|
|
13511
|
+
"label",
|
|
13512
|
+
"description",
|
|
13513
|
+
"class",
|
|
13514
|
+
"entitlement_required",
|
|
13515
|
+
"entitled",
|
|
13516
|
+
"org_mode",
|
|
13517
|
+
"org_mode_is_default",
|
|
13518
|
+
"org_modes",
|
|
13519
|
+
"member_enabled",
|
|
13520
|
+
"member_can_change"
|
|
13521
|
+
]
|
|
13522
|
+
}
|
|
13523
|
+
}
|
|
13524
|
+
},
|
|
13525
|
+
"required": ["entitled", "kinds"]
|
|
13526
|
+
},
|
|
13527
|
+
"sdkName": "updateEmailNotificationSettings",
|
|
13528
|
+
"summary": "Change the organization's email notification settings",
|
|
13529
|
+
"tag": "Email notifications",
|
|
13530
|
+
"tagCommand": "email-notifications"
|
|
13531
|
+
},
|
|
13047
13532
|
{
|
|
13048
13533
|
"binaryResponse": false,
|
|
13049
13534
|
"bodyRequired": false,
|
|
@@ -13141,8 +13626,14 @@ const operationManifest = [
|
|
|
13141
13626
|
"email"
|
|
13142
13627
|
]
|
|
13143
13628
|
},
|
|
13144
|
-
"is_objector": {
|
|
13145
|
-
|
|
13629
|
+
"is_objector": {
|
|
13630
|
+
"type": "boolean",
|
|
13631
|
+
"description": "Whether you made it, in your current membership."
|
|
13632
|
+
},
|
|
13633
|
+
"is_author": {
|
|
13634
|
+
"type": "boolean",
|
|
13635
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
13636
|
+
},
|
|
13146
13637
|
"message": {
|
|
13147
13638
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
13148
13639
|
"type": ["string", "null"]
|
|
@@ -13289,8 +13780,14 @@ const operationManifest = [
|
|
|
13289
13780
|
"email"
|
|
13290
13781
|
]
|
|
13291
13782
|
},
|
|
13292
|
-
"is_objector": {
|
|
13293
|
-
|
|
13783
|
+
"is_objector": {
|
|
13784
|
+
"type": "boolean",
|
|
13785
|
+
"description": "Whether you made it, in your current membership."
|
|
13786
|
+
},
|
|
13787
|
+
"is_author": {
|
|
13788
|
+
"type": "boolean",
|
|
13789
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
13790
|
+
},
|
|
13294
13791
|
"message": {
|
|
13295
13792
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
13296
13793
|
"type": ["string", "null"]
|
|
@@ -13435,8 +13932,14 @@ const operationManifest = [
|
|
|
13435
13932
|
"email"
|
|
13436
13933
|
]
|
|
13437
13934
|
},
|
|
13438
|
-
"is_objector": {
|
|
13439
|
-
|
|
13935
|
+
"is_objector": {
|
|
13936
|
+
"type": "boolean",
|
|
13937
|
+
"description": "Whether you made it, in your current membership."
|
|
13938
|
+
},
|
|
13939
|
+
"is_author": {
|
|
13940
|
+
"type": "boolean",
|
|
13941
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
13942
|
+
},
|
|
13440
13943
|
"message": {
|
|
13441
13944
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
13442
13945
|
"type": ["string", "null"]
|
|
@@ -13576,7 +14079,7 @@ const operationManifest = [
|
|
|
13576
14079
|
"description": "Null when covers_now is false."
|
|
13577
14080
|
},
|
|
13578
14081
|
"receivers": {
|
|
13579
|
-
"description": "Null when covers_now is false (who receives it now is not about your mail),
|
|
14082
|
+
"description": "Null when covers_now is false (who receives it now is not about your mail), when it could not be read in time, or for a rule shown in draft or observe that turned active or was deleted after it was read; try again.",
|
|
13580
14083
|
"anyOf": [{
|
|
13581
14084
|
"type": "object",
|
|
13582
14085
|
"properties": {
|
|
@@ -13619,6 +14122,16 @@ const operationManifest = [
|
|
|
13619
14122
|
"count": {
|
|
13620
14123
|
"type": "integer",
|
|
13621
14124
|
"exclusiveMinimum": 0
|
|
14125
|
+
},
|
|
14126
|
+
"reads_in_full": {
|
|
14127
|
+
"description": "On a rule over your mail: how many of these keys also list one of your own mailboxes, or its domain, so they read your mail there beyond what this rule matches.",
|
|
14128
|
+
"type": "integer",
|
|
14129
|
+
"minimum": 0
|
|
14130
|
+
},
|
|
14131
|
+
"newest_at": {
|
|
14132
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
14133
|
+
"type": "string",
|
|
14134
|
+
"format": "date-time"
|
|
13622
14135
|
}
|
|
13623
14136
|
},
|
|
13624
14137
|
"required": ["owner", "count"]
|
|
@@ -13666,7 +14179,7 @@ const operationManifest = [
|
|
|
13666
14179
|
"exclusiveMinimum": 0
|
|
13667
14180
|
},
|
|
13668
14181
|
"hosts": {
|
|
13669
|
-
"description": "Distinct sites they deliver to (a host's
|
|
14182
|
+
"description": "Distinct sites they deliver to (the domain a host is registered under, an app's own name on a known app platform, or a function URL service in its region), sorted, at most 10; \"unknown host\" (last) for any that cannot be named.",
|
|
13670
14183
|
"type": "array",
|
|
13671
14184
|
"items": { "type": "string" }
|
|
13672
14185
|
},
|
|
@@ -13674,6 +14187,11 @@ const operationManifest = [
|
|
|
13674
14187
|
"description": "Hosts past those listed.",
|
|
13675
14188
|
"type": "integer",
|
|
13676
14189
|
"minimum": 0
|
|
14190
|
+
},
|
|
14191
|
+
"newest_at": {
|
|
14192
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
14193
|
+
"type": "string",
|
|
14194
|
+
"format": "date-time"
|
|
13677
14195
|
}
|
|
13678
14196
|
},
|
|
13679
14197
|
"required": ["owner", "count"]
|
|
@@ -13711,6 +14229,11 @@ const operationManifest = [
|
|
|
13711
14229
|
"count": {
|
|
13712
14230
|
"type": "integer",
|
|
13713
14231
|
"exclusiveMinimum": 0
|
|
14232
|
+
},
|
|
14233
|
+
"newest_at": {
|
|
14234
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
14235
|
+
"type": "string",
|
|
14236
|
+
"format": "date-time"
|
|
13714
14237
|
}
|
|
13715
14238
|
},
|
|
13716
14239
|
"required": ["beneficiary", "count"]
|
|
@@ -13723,7 +14246,178 @@ const operationManifest = [
|
|
|
13723
14246
|
"webhooks",
|
|
13724
14247
|
"shares"
|
|
13725
14248
|
],
|
|
13726
|
-
"description": "Who receives what the rule shares
|
|
14249
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
14250
|
+
}, { "type": "null" }]
|
|
14251
|
+
},
|
|
14252
|
+
"receivers_once_active": {
|
|
14253
|
+
"description": "As on the list; also null when covers_now is false.",
|
|
14254
|
+
"anyOf": [{
|
|
14255
|
+
"type": "object",
|
|
14256
|
+
"properties": {
|
|
14257
|
+
"keys": {
|
|
14258
|
+
"type": "array",
|
|
14259
|
+
"items": {
|
|
14260
|
+
"type": "object",
|
|
14261
|
+
"properties": {
|
|
14262
|
+
"owner": { "anyOf": [{
|
|
14263
|
+
"type": "object",
|
|
14264
|
+
"properties": {
|
|
14265
|
+
"kind": {
|
|
14266
|
+
"type": "string",
|
|
14267
|
+
"const": "member"
|
|
14268
|
+
},
|
|
14269
|
+
"user_id": {
|
|
14270
|
+
"type": "string",
|
|
14271
|
+
"description": "The member's user id.",
|
|
14272
|
+
"format": "uuid"
|
|
14273
|
+
},
|
|
14274
|
+
"name": {
|
|
14275
|
+
"description": "Their name; null when they have none set.",
|
|
14276
|
+
"type": ["string", "null"]
|
|
14277
|
+
}
|
|
14278
|
+
},
|
|
14279
|
+
"required": [
|
|
14280
|
+
"kind",
|
|
14281
|
+
"user_id",
|
|
14282
|
+
"name"
|
|
14283
|
+
]
|
|
14284
|
+
}, {
|
|
14285
|
+
"type": "object",
|
|
14286
|
+
"properties": { "kind": {
|
|
14287
|
+
"type": "string",
|
|
14288
|
+
"const": "organization",
|
|
14289
|
+
"description": "Held by no member: an organization key, or one whose holder has left."
|
|
14290
|
+
} },
|
|
14291
|
+
"required": ["kind"]
|
|
14292
|
+
}] },
|
|
14293
|
+
"count": {
|
|
14294
|
+
"type": "integer",
|
|
14295
|
+
"exclusiveMinimum": 0
|
|
14296
|
+
},
|
|
14297
|
+
"reads_in_full": {
|
|
14298
|
+
"description": "On a rule over your mail: how many of these keys also list one of your own mailboxes, or its domain, so they read your mail there beyond what this rule matches.",
|
|
14299
|
+
"type": "integer",
|
|
14300
|
+
"minimum": 0
|
|
14301
|
+
},
|
|
14302
|
+
"newest_at": {
|
|
14303
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
14304
|
+
"type": "string",
|
|
14305
|
+
"format": "date-time"
|
|
14306
|
+
}
|
|
14307
|
+
},
|
|
14308
|
+
"required": ["owner", "count"]
|
|
14309
|
+
},
|
|
14310
|
+
"description": "API keys that work now (not revoked, expired or suspended) and hold mail:read, whose access lists the rule or its live share. Owner: who holds each, or the organization."
|
|
14311
|
+
},
|
|
14312
|
+
"webhooks": {
|
|
14313
|
+
"type": "array",
|
|
14314
|
+
"items": {
|
|
14315
|
+
"type": "object",
|
|
14316
|
+
"properties": {
|
|
14317
|
+
"owner": { "anyOf": [{
|
|
14318
|
+
"type": "object",
|
|
14319
|
+
"properties": {
|
|
14320
|
+
"kind": {
|
|
14321
|
+
"type": "string",
|
|
14322
|
+
"const": "member"
|
|
14323
|
+
},
|
|
14324
|
+
"user_id": {
|
|
14325
|
+
"type": "string",
|
|
14326
|
+
"description": "The member's user id.",
|
|
14327
|
+
"format": "uuid"
|
|
14328
|
+
},
|
|
14329
|
+
"name": {
|
|
14330
|
+
"description": "Their name; null when they have none set.",
|
|
14331
|
+
"type": ["string", "null"]
|
|
14332
|
+
}
|
|
14333
|
+
},
|
|
14334
|
+
"required": [
|
|
14335
|
+
"kind",
|
|
14336
|
+
"user_id",
|
|
14337
|
+
"name"
|
|
14338
|
+
]
|
|
14339
|
+
}, {
|
|
14340
|
+
"type": "object",
|
|
14341
|
+
"properties": { "kind": {
|
|
14342
|
+
"type": "string",
|
|
14343
|
+
"const": "organization",
|
|
14344
|
+
"description": "Held by no member: an organization key, or one whose holder has left."
|
|
14345
|
+
} },
|
|
14346
|
+
"required": ["kind"]
|
|
14347
|
+
}] },
|
|
14348
|
+
"count": {
|
|
14349
|
+
"type": "integer",
|
|
14350
|
+
"exclusiveMinimum": 0
|
|
14351
|
+
},
|
|
14352
|
+
"hosts": {
|
|
14353
|
+
"description": "Distinct sites they deliver to (the domain a host is registered under, an app's own name on a known app platform, or a function URL service in its region), sorted, at most 10; \"unknown host\" (last) for any that cannot be named.",
|
|
14354
|
+
"type": "array",
|
|
14355
|
+
"items": { "type": "string" }
|
|
14356
|
+
},
|
|
14357
|
+
"hosts_not_listed": {
|
|
14358
|
+
"description": "Hosts past those listed.",
|
|
14359
|
+
"type": "integer",
|
|
14360
|
+
"minimum": 0
|
|
14361
|
+
},
|
|
14362
|
+
"newest_at": {
|
|
14363
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
14364
|
+
"type": "string",
|
|
14365
|
+
"format": "date-time"
|
|
14366
|
+
}
|
|
14367
|
+
},
|
|
14368
|
+
"required": ["owner", "count"]
|
|
14369
|
+
},
|
|
14370
|
+
"description": "Webhooks taking received mail, bounces or reports that are sent what it matches: those of the key delivery acts as, when it lists the rule or its live share (owner: its holder, or the organization), and those of the member it is shared with (owner: that member)."
|
|
14371
|
+
},
|
|
14372
|
+
"shares": {
|
|
14373
|
+
"type": "array",
|
|
14374
|
+
"items": {
|
|
14375
|
+
"type": "object",
|
|
14376
|
+
"properties": {
|
|
14377
|
+
"beneficiary": {
|
|
14378
|
+
"type": "object",
|
|
14379
|
+
"properties": {
|
|
14380
|
+
"kind": {
|
|
14381
|
+
"type": "string",
|
|
14382
|
+
"const": "member"
|
|
14383
|
+
},
|
|
14384
|
+
"user_id": {
|
|
14385
|
+
"type": "string",
|
|
14386
|
+
"description": "The member's user id.",
|
|
14387
|
+
"format": "uuid"
|
|
14388
|
+
},
|
|
14389
|
+
"name": {
|
|
14390
|
+
"description": "Their name; null when they have none set.",
|
|
14391
|
+
"type": ["string", "null"]
|
|
14392
|
+
}
|
|
14393
|
+
},
|
|
14394
|
+
"required": [
|
|
14395
|
+
"kind",
|
|
14396
|
+
"user_id",
|
|
14397
|
+
"name"
|
|
14398
|
+
]
|
|
14399
|
+
},
|
|
14400
|
+
"count": {
|
|
14401
|
+
"type": "integer",
|
|
14402
|
+
"exclusiveMinimum": 0
|
|
14403
|
+
},
|
|
14404
|
+
"newest_at": {
|
|
14405
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
14406
|
+
"type": "string",
|
|
14407
|
+
"format": "date-time"
|
|
14408
|
+
}
|
|
14409
|
+
},
|
|
14410
|
+
"required": ["beneficiary", "count"]
|
|
14411
|
+
},
|
|
14412
|
+
"description": "The rule's live share (at most one), by its member, if they can read it and it is among their newest 20 shares."
|
|
14413
|
+
}
|
|
14414
|
+
},
|
|
14415
|
+
"required": [
|
|
14416
|
+
"keys",
|
|
14417
|
+
"webhooks",
|
|
14418
|
+
"shares"
|
|
14419
|
+
],
|
|
14420
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
13727
14421
|
}, { "type": "null" }]
|
|
13728
14422
|
},
|
|
13729
14423
|
"created_at": {
|
|
@@ -13819,6 +14513,7 @@ const operationManifest = [
|
|
|
13819
14513
|
"covers",
|
|
13820
14514
|
"current_version",
|
|
13821
14515
|
"receivers",
|
|
14516
|
+
"receivers_once_active",
|
|
13822
14517
|
"created_at",
|
|
13823
14518
|
"covers_now",
|
|
13824
14519
|
"current"
|
|
@@ -13920,8 +14615,14 @@ const operationManifest = [
|
|
|
13920
14615
|
"email"
|
|
13921
14616
|
]
|
|
13922
14617
|
},
|
|
13923
|
-
"is_objector": {
|
|
13924
|
-
|
|
14618
|
+
"is_objector": {
|
|
14619
|
+
"type": "boolean",
|
|
14620
|
+
"description": "Whether you made it, in your current membership."
|
|
14621
|
+
},
|
|
14622
|
+
"is_author": {
|
|
14623
|
+
"type": "boolean",
|
|
14624
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
14625
|
+
},
|
|
13925
14626
|
"message": {
|
|
13926
14627
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
13927
14628
|
"type": ["string", "null"]
|
|
@@ -14087,7 +14788,7 @@ const operationManifest = [
|
|
|
14087
14788
|
"binaryResponse": false,
|
|
14088
14789
|
"bodyRequired": false,
|
|
14089
14790
|
"command": "list-email-rule-objections",
|
|
14090
|
-
"description": "Objections you made
|
|
14791
|
+
"description": "Objections you made and objections to rules you wrote (by default), only one of the two, 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, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
|
|
14091
14792
|
"hasJsonBody": false,
|
|
14092
14793
|
"method": "GET",
|
|
14093
14794
|
"operationId": "listEmailRuleObjections",
|
|
@@ -14095,9 +14796,10 @@ const operationManifest = [
|
|
|
14095
14796
|
"pathParams": [],
|
|
14096
14797
|
"queryParams": [
|
|
14097
14798
|
{
|
|
14098
|
-
"default": "
|
|
14099
|
-
"description": "
|
|
14799
|
+
"default": "mine",
|
|
14800
|
+
"description": "mine (the default): objections you made and objections to rules you wrote, each saying which (is_objector, is_author). outgoing: only those you made. incoming: only those to rules you wrote. all: every objection you can see.",
|
|
14100
14801
|
"enum": [
|
|
14802
|
+
"mine",
|
|
14101
14803
|
"outgoing",
|
|
14102
14804
|
"incoming",
|
|
14103
14805
|
"all"
|
|
@@ -14212,8 +14914,14 @@ const operationManifest = [
|
|
|
14212
14914
|
"email"
|
|
14213
14915
|
]
|
|
14214
14916
|
},
|
|
14215
|
-
"is_objector": {
|
|
14216
|
-
|
|
14917
|
+
"is_objector": {
|
|
14918
|
+
"type": "boolean",
|
|
14919
|
+
"description": "Whether you made it, in your current membership."
|
|
14920
|
+
},
|
|
14921
|
+
"is_author": {
|
|
14922
|
+
"type": "boolean",
|
|
14923
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
14924
|
+
},
|
|
14217
14925
|
"message": {
|
|
14218
14926
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
14219
14927
|
"type": ["string", "null"]
|
|
@@ -14253,6 +14961,126 @@ const operationManifest = [
|
|
|
14253
14961
|
"tag": "Email Rule Oversight",
|
|
14254
14962
|
"tagCommand": "email-rule-oversight"
|
|
14255
14963
|
},
|
|
14964
|
+
{
|
|
14965
|
+
"binaryResponse": false,
|
|
14966
|
+
"bodyRequired": false,
|
|
14967
|
+
"command": "list-email-rule-versions-covering-me",
|
|
14968
|
+
"description": "The versions of a rule that covers one of your own mailboxes now that applied to your mail: its current version and each earlier one that decided on mail at your own mailboxes, so a decision can be read in the words of the version that made it. Each has what the covering view shows of a version: its wording, tree, explanation and assumptions. A version that did neither is not listed. Without versions, newest first, a page at a time (meta.cursor); with versions, only those named that are listed, oldest first. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token). Only on your own dashboard session or the Primitive CLI.",
|
|
14969
|
+
"hasJsonBody": false,
|
|
14970
|
+
"method": "GET",
|
|
14971
|
+
"operationId": "listEmailRuleVersionsCoveringMe",
|
|
14972
|
+
"path": "/email-rules/covering-me/{id}/versions",
|
|
14973
|
+
"pathParams": [{
|
|
14974
|
+
"description": "The rule id.",
|
|
14975
|
+
"enum": null,
|
|
14976
|
+
"name": "id",
|
|
14977
|
+
"required": true,
|
|
14978
|
+
"type": "string"
|
|
14979
|
+
}],
|
|
14980
|
+
"queryParams": [
|
|
14981
|
+
{
|
|
14982
|
+
"description": "Versions per page when versions is not given: 1 to 100, default 50.",
|
|
14983
|
+
"enum": null,
|
|
14984
|
+
"maximum": 100,
|
|
14985
|
+
"minimum": 1,
|
|
14986
|
+
"name": "limit",
|
|
14987
|
+
"required": false,
|
|
14988
|
+
"type": "integer"
|
|
14989
|
+
},
|
|
14990
|
+
{
|
|
14991
|
+
"description": "meta.cursor from the preceding page. Omit for the first page. Not with versions.",
|
|
14992
|
+
"enum": null,
|
|
14993
|
+
"name": "cursor",
|
|
14994
|
+
"required": false,
|
|
14995
|
+
"type": "string"
|
|
14996
|
+
},
|
|
14997
|
+
{
|
|
14998
|
+
"description": "Read only these version numbers, comma-separated, at most 100. Not with limit or cursor.",
|
|
14999
|
+
"enum": null,
|
|
15000
|
+
"name": "versions",
|
|
15001
|
+
"required": false,
|
|
15002
|
+
"type": "string"
|
|
15003
|
+
}
|
|
15004
|
+
],
|
|
15005
|
+
"headerParams": [],
|
|
15006
|
+
"permissions": ["mail:read"],
|
|
15007
|
+
"access": null,
|
|
15008
|
+
"requestSchema": null,
|
|
15009
|
+
"responseSchema": {
|
|
15010
|
+
"type": "array",
|
|
15011
|
+
"items": {
|
|
15012
|
+
"type": "object",
|
|
15013
|
+
"properties": {
|
|
15014
|
+
"version": {
|
|
15015
|
+
"type": "integer",
|
|
15016
|
+
"exclusiveMinimum": 0
|
|
15017
|
+
},
|
|
15018
|
+
"english": {
|
|
15019
|
+
"type": "string",
|
|
15020
|
+
"description": "What its author asked for, in their words."
|
|
15021
|
+
},
|
|
15022
|
+
"tree": {
|
|
15023
|
+
"type": "object",
|
|
15024
|
+
"properties": {
|
|
15025
|
+
"version": {
|
|
15026
|
+
"type": "number",
|
|
15027
|
+
"const": 1
|
|
15028
|
+
},
|
|
15029
|
+
"vocabulary": {
|
|
15030
|
+
"type": "string",
|
|
15031
|
+
"description": "Vocabulary version, such as v1."
|
|
15032
|
+
},
|
|
15033
|
+
"when": {
|
|
15034
|
+
"type": "object",
|
|
15035
|
+
"propertyNames": { "type": "string" },
|
|
15036
|
+
"additionalProperties": {},
|
|
15037
|
+
"description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
|
|
15038
|
+
},
|
|
15039
|
+
"questions": {
|
|
15040
|
+
"type": "array",
|
|
15041
|
+
"items": { "type": "string" },
|
|
15042
|
+
"description": "Yes/no questions asked once the conditions match, over the email's text and attachment names, never attachment contents. A grant rule needs every one yes; a do_not_share rule matches on any yes."
|
|
15043
|
+
}
|
|
15044
|
+
},
|
|
15045
|
+
"required": [
|
|
15046
|
+
"version",
|
|
15047
|
+
"vocabulary",
|
|
15048
|
+
"when",
|
|
15049
|
+
"questions"
|
|
15050
|
+
]
|
|
15051
|
+
},
|
|
15052
|
+
"explanation": {
|
|
15053
|
+
"type": "string",
|
|
15054
|
+
"description": "What the rule matches, as compiled."
|
|
15055
|
+
},
|
|
15056
|
+
"assumptions": {
|
|
15057
|
+
"type": "array",
|
|
15058
|
+
"items": { "type": "string" }
|
|
15059
|
+
},
|
|
15060
|
+
"compiled_by": { "type": "string" },
|
|
15061
|
+
"vocabulary": { "type": "string" },
|
|
15062
|
+
"created_at": {
|
|
15063
|
+
"type": "string",
|
|
15064
|
+
"format": "date-time"
|
|
15065
|
+
}
|
|
15066
|
+
},
|
|
15067
|
+
"required": [
|
|
15068
|
+
"version",
|
|
15069
|
+
"english",
|
|
15070
|
+
"tree",
|
|
15071
|
+
"explanation",
|
|
15072
|
+
"assumptions",
|
|
15073
|
+
"compiled_by",
|
|
15074
|
+
"vocabulary",
|
|
15075
|
+
"created_at"
|
|
15076
|
+
]
|
|
15077
|
+
}
|
|
15078
|
+
},
|
|
15079
|
+
"sdkName": "listEmailRuleVersionsCoveringMe",
|
|
15080
|
+
"summary": "Read versions of a rule over your mail",
|
|
15081
|
+
"tag": "Email Rule Oversight",
|
|
15082
|
+
"tagCommand": "email-rule-oversight"
|
|
15083
|
+
},
|
|
14256
15084
|
{
|
|
14257
15085
|
"binaryResponse": false,
|
|
14258
15086
|
"bodyRequired": false,
|
|
@@ -14358,7 +15186,7 @@ const operationManifest = [
|
|
|
14358
15186
|
"exclusiveMinimum": 0
|
|
14359
15187
|
},
|
|
14360
15188
|
"receivers": {
|
|
14361
|
-
"description": "Null when it could not be read in time; try again.",
|
|
15189
|
+
"description": "Null when it could not be read in time, or for a rule shown in draft or observe that turned active or was deleted after the page was read; try again.",
|
|
14362
15190
|
"anyOf": [{
|
|
14363
15191
|
"type": "object",
|
|
14364
15192
|
"properties": {
|
|
@@ -14401,6 +15229,187 @@ const operationManifest = [
|
|
|
14401
15229
|
"count": {
|
|
14402
15230
|
"type": "integer",
|
|
14403
15231
|
"exclusiveMinimum": 0
|
|
15232
|
+
},
|
|
15233
|
+
"reads_in_full": {
|
|
15234
|
+
"description": "On a rule over your mail: how many of these keys also list one of your own mailboxes, or its domain, so they read your mail there beyond what this rule matches.",
|
|
15235
|
+
"type": "integer",
|
|
15236
|
+
"minimum": 0
|
|
15237
|
+
},
|
|
15238
|
+
"newest_at": {
|
|
15239
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
15240
|
+
"type": "string",
|
|
15241
|
+
"format": "date-time"
|
|
15242
|
+
}
|
|
15243
|
+
},
|
|
15244
|
+
"required": ["owner", "count"]
|
|
15245
|
+
},
|
|
15246
|
+
"description": "API keys that work now (not revoked, expired or suspended) and hold mail:read, whose access lists the rule or its live share. Owner: who holds each, or the organization."
|
|
15247
|
+
},
|
|
15248
|
+
"webhooks": {
|
|
15249
|
+
"type": "array",
|
|
15250
|
+
"items": {
|
|
15251
|
+
"type": "object",
|
|
15252
|
+
"properties": {
|
|
15253
|
+
"owner": { "anyOf": [{
|
|
15254
|
+
"type": "object",
|
|
15255
|
+
"properties": {
|
|
15256
|
+
"kind": {
|
|
15257
|
+
"type": "string",
|
|
15258
|
+
"const": "member"
|
|
15259
|
+
},
|
|
15260
|
+
"user_id": {
|
|
15261
|
+
"type": "string",
|
|
15262
|
+
"description": "The member's user id.",
|
|
15263
|
+
"format": "uuid"
|
|
15264
|
+
},
|
|
15265
|
+
"name": {
|
|
15266
|
+
"description": "Their name; null when they have none set.",
|
|
15267
|
+
"type": ["string", "null"]
|
|
15268
|
+
}
|
|
15269
|
+
},
|
|
15270
|
+
"required": [
|
|
15271
|
+
"kind",
|
|
15272
|
+
"user_id",
|
|
15273
|
+
"name"
|
|
15274
|
+
]
|
|
15275
|
+
}, {
|
|
15276
|
+
"type": "object",
|
|
15277
|
+
"properties": { "kind": {
|
|
15278
|
+
"type": "string",
|
|
15279
|
+
"const": "organization",
|
|
15280
|
+
"description": "Held by no member: an organization key, or one whose holder has left."
|
|
15281
|
+
} },
|
|
15282
|
+
"required": ["kind"]
|
|
15283
|
+
}] },
|
|
15284
|
+
"count": {
|
|
15285
|
+
"type": "integer",
|
|
15286
|
+
"exclusiveMinimum": 0
|
|
15287
|
+
},
|
|
15288
|
+
"hosts": {
|
|
15289
|
+
"description": "Distinct sites they deliver to (the domain a host is registered under, an app's own name on a known app platform, or a function URL service in its region), sorted, at most 10; \"unknown host\" (last) for any that cannot be named.",
|
|
15290
|
+
"type": "array",
|
|
15291
|
+
"items": { "type": "string" }
|
|
15292
|
+
},
|
|
15293
|
+
"hosts_not_listed": {
|
|
15294
|
+
"description": "Hosts past those listed.",
|
|
15295
|
+
"type": "integer",
|
|
15296
|
+
"minimum": 0
|
|
15297
|
+
},
|
|
15298
|
+
"newest_at": {
|
|
15299
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
15300
|
+
"type": "string",
|
|
15301
|
+
"format": "date-time"
|
|
15302
|
+
}
|
|
15303
|
+
},
|
|
15304
|
+
"required": ["owner", "count"]
|
|
15305
|
+
},
|
|
15306
|
+
"description": "Webhooks taking received mail, bounces or reports that are sent what it matches: those of the key delivery acts as, when it lists the rule or its live share (owner: its holder, or the organization), and those of the member it is shared with (owner: that member)."
|
|
15307
|
+
},
|
|
15308
|
+
"shares": {
|
|
15309
|
+
"type": "array",
|
|
15310
|
+
"items": {
|
|
15311
|
+
"type": "object",
|
|
15312
|
+
"properties": {
|
|
15313
|
+
"beneficiary": {
|
|
15314
|
+
"type": "object",
|
|
15315
|
+
"properties": {
|
|
15316
|
+
"kind": {
|
|
15317
|
+
"type": "string",
|
|
15318
|
+
"const": "member"
|
|
15319
|
+
},
|
|
15320
|
+
"user_id": {
|
|
15321
|
+
"type": "string",
|
|
15322
|
+
"description": "The member's user id.",
|
|
15323
|
+
"format": "uuid"
|
|
15324
|
+
},
|
|
15325
|
+
"name": {
|
|
15326
|
+
"description": "Their name; null when they have none set.",
|
|
15327
|
+
"type": ["string", "null"]
|
|
15328
|
+
}
|
|
15329
|
+
},
|
|
15330
|
+
"required": [
|
|
15331
|
+
"kind",
|
|
15332
|
+
"user_id",
|
|
15333
|
+
"name"
|
|
15334
|
+
]
|
|
15335
|
+
},
|
|
15336
|
+
"count": {
|
|
15337
|
+
"type": "integer",
|
|
15338
|
+
"exclusiveMinimum": 0
|
|
15339
|
+
},
|
|
15340
|
+
"newest_at": {
|
|
15341
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
15342
|
+
"type": "string",
|
|
15343
|
+
"format": "date-time"
|
|
15344
|
+
}
|
|
15345
|
+
},
|
|
15346
|
+
"required": ["beneficiary", "count"]
|
|
15347
|
+
},
|
|
15348
|
+
"description": "The rule's live share (at most one), by its member, if they can read it and it is among their newest 20 shares."
|
|
15349
|
+
}
|
|
15350
|
+
},
|
|
15351
|
+
"required": [
|
|
15352
|
+
"keys",
|
|
15353
|
+
"webhooks",
|
|
15354
|
+
"shares"
|
|
15355
|
+
],
|
|
15356
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
15357
|
+
}, { "type": "null" }]
|
|
15358
|
+
},
|
|
15359
|
+
"receivers_once_active": {
|
|
15360
|
+
"description": "For a grant rule in draft or observe: who would receive what it matches once it is turned active. None of them receives anything yet. Null for any other rule, and as receivers is null.",
|
|
15361
|
+
"anyOf": [{
|
|
15362
|
+
"type": "object",
|
|
15363
|
+
"properties": {
|
|
15364
|
+
"keys": {
|
|
15365
|
+
"type": "array",
|
|
15366
|
+
"items": {
|
|
15367
|
+
"type": "object",
|
|
15368
|
+
"properties": {
|
|
15369
|
+
"owner": { "anyOf": [{
|
|
15370
|
+
"type": "object",
|
|
15371
|
+
"properties": {
|
|
15372
|
+
"kind": {
|
|
15373
|
+
"type": "string",
|
|
15374
|
+
"const": "member"
|
|
15375
|
+
},
|
|
15376
|
+
"user_id": {
|
|
15377
|
+
"type": "string",
|
|
15378
|
+
"description": "The member's user id.",
|
|
15379
|
+
"format": "uuid"
|
|
15380
|
+
},
|
|
15381
|
+
"name": {
|
|
15382
|
+
"description": "Their name; null when they have none set.",
|
|
15383
|
+
"type": ["string", "null"]
|
|
15384
|
+
}
|
|
15385
|
+
},
|
|
15386
|
+
"required": [
|
|
15387
|
+
"kind",
|
|
15388
|
+
"user_id",
|
|
15389
|
+
"name"
|
|
15390
|
+
]
|
|
15391
|
+
}, {
|
|
15392
|
+
"type": "object",
|
|
15393
|
+
"properties": { "kind": {
|
|
15394
|
+
"type": "string",
|
|
15395
|
+
"const": "organization",
|
|
15396
|
+
"description": "Held by no member: an organization key, or one whose holder has left."
|
|
15397
|
+
} },
|
|
15398
|
+
"required": ["kind"]
|
|
15399
|
+
}] },
|
|
15400
|
+
"count": {
|
|
15401
|
+
"type": "integer",
|
|
15402
|
+
"exclusiveMinimum": 0
|
|
15403
|
+
},
|
|
15404
|
+
"reads_in_full": {
|
|
15405
|
+
"description": "On a rule over your mail: how many of these keys also list one of your own mailboxes, or its domain, so they read your mail there beyond what this rule matches.",
|
|
15406
|
+
"type": "integer",
|
|
15407
|
+
"minimum": 0
|
|
15408
|
+
},
|
|
15409
|
+
"newest_at": {
|
|
15410
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
15411
|
+
"type": "string",
|
|
15412
|
+
"format": "date-time"
|
|
14404
15413
|
}
|
|
14405
15414
|
},
|
|
14406
15415
|
"required": ["owner", "count"]
|
|
@@ -14448,7 +15457,7 @@ const operationManifest = [
|
|
|
14448
15457
|
"exclusiveMinimum": 0
|
|
14449
15458
|
},
|
|
14450
15459
|
"hosts": {
|
|
14451
|
-
"description": "Distinct sites they deliver to (a host's
|
|
15460
|
+
"description": "Distinct sites they deliver to (the domain a host is registered under, an app's own name on a known app platform, or a function URL service in its region), sorted, at most 10; \"unknown host\" (last) for any that cannot be named.",
|
|
14452
15461
|
"type": "array",
|
|
14453
15462
|
"items": { "type": "string" }
|
|
14454
15463
|
},
|
|
@@ -14456,6 +15465,11 @@ const operationManifest = [
|
|
|
14456
15465
|
"description": "Hosts past those listed.",
|
|
14457
15466
|
"type": "integer",
|
|
14458
15467
|
"minimum": 0
|
|
15468
|
+
},
|
|
15469
|
+
"newest_at": {
|
|
15470
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
15471
|
+
"type": "string",
|
|
15472
|
+
"format": "date-time"
|
|
14459
15473
|
}
|
|
14460
15474
|
},
|
|
14461
15475
|
"required": ["owner", "count"]
|
|
@@ -14493,6 +15507,11 @@ const operationManifest = [
|
|
|
14493
15507
|
"count": {
|
|
14494
15508
|
"type": "integer",
|
|
14495
15509
|
"exclusiveMinimum": 0
|
|
15510
|
+
},
|
|
15511
|
+
"newest_at": {
|
|
15512
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
15513
|
+
"type": "string",
|
|
15514
|
+
"format": "date-time"
|
|
14496
15515
|
}
|
|
14497
15516
|
},
|
|
14498
15517
|
"required": ["beneficiary", "count"]
|
|
@@ -14505,7 +15524,7 @@ const operationManifest = [
|
|
|
14505
15524
|
"webhooks",
|
|
14506
15525
|
"shares"
|
|
14507
15526
|
],
|
|
14508
|
-
"description": "Who receives what the rule shares
|
|
15527
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
14509
15528
|
}, { "type": "null" }]
|
|
14510
15529
|
},
|
|
14511
15530
|
"created_at": {
|
|
@@ -14523,6 +15542,7 @@ const operationManifest = [
|
|
|
14523
15542
|
"covers",
|
|
14524
15543
|
"current_version",
|
|
14525
15544
|
"receivers",
|
|
15545
|
+
"receivers_once_active",
|
|
14526
15546
|
"created_at"
|
|
14527
15547
|
]
|
|
14528
15548
|
}
|
|
@@ -14629,8 +15649,14 @@ const operationManifest = [
|
|
|
14629
15649
|
"email"
|
|
14630
15650
|
]
|
|
14631
15651
|
},
|
|
14632
|
-
"is_objector": {
|
|
14633
|
-
|
|
15652
|
+
"is_objector": {
|
|
15653
|
+
"type": "boolean",
|
|
15654
|
+
"description": "Whether you made it, in your current membership."
|
|
15655
|
+
},
|
|
15656
|
+
"is_author": {
|
|
15657
|
+
"type": "boolean",
|
|
15658
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
15659
|
+
},
|
|
14634
15660
|
"message": {
|
|
14635
15661
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
14636
15662
|
"type": ["string", "null"]
|
|
@@ -14757,7 +15783,7 @@ const operationManifest = [
|
|
|
14757
15783
|
}
|
|
14758
15784
|
},
|
|
14759
15785
|
"warnings": {
|
|
14760
|
-
"description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test (on a rule request, every compiler note on the rule).",
|
|
15786
|
+
"description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test, or on a grant rule that tests only who an email was sent to (on a rule request, every compiler note on the rule).",
|
|
14761
15787
|
"maxItems": 10,
|
|
14762
15788
|
"type": "array",
|
|
14763
15789
|
"items": {
|
|
@@ -14780,7 +15806,7 @@ const operationManifest = [
|
|
|
14780
15806
|
"checked": {
|
|
14781
15807
|
"type": "integer",
|
|
14782
15808
|
"minimum": 0,
|
|
14783
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
15809
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
14784
15810
|
},
|
|
14785
15811
|
"matched": {
|
|
14786
15812
|
"type": "integer",
|
|
@@ -14799,7 +15825,7 @@ const operationManifest = [
|
|
|
14799
15825
|
"checked": {
|
|
14800
15826
|
"type": "integer",
|
|
14801
15827
|
"minimum": 0,
|
|
14802
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
15828
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
14803
15829
|
},
|
|
14804
15830
|
"matched": {
|
|
14805
15831
|
"type": "integer",
|
|
@@ -14896,6 +15922,16 @@ const operationManifest = [
|
|
|
14896
15922
|
"pattern": "^[^\\u0000]*$"
|
|
14897
15923
|
}
|
|
14898
15924
|
},
|
|
15925
|
+
"attachment_names": {
|
|
15926
|
+
"maxItems": 10,
|
|
15927
|
+
"type": "array",
|
|
15928
|
+
"items": {
|
|
15929
|
+
"type": "string",
|
|
15930
|
+
"minLength": 1,
|
|
15931
|
+
"maxLength": 255,
|
|
15932
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
15933
|
+
}
|
|
15934
|
+
},
|
|
14899
15935
|
"automated": { "type": "boolean" },
|
|
14900
15936
|
"from_mailing_list": { "type": "boolean" },
|
|
14901
15937
|
"spam_score": {
|
|
@@ -15206,6 +16242,15 @@ const operationManifest = [
|
|
|
15206
16242
|
"type": "boolean",
|
|
15207
16243
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
15208
16244
|
},
|
|
16245
|
+
"pending_objections": {
|
|
16246
|
+
"description": "To its author, on the dashboard or the Primitive CLI: objections to it waiting for their answer (GET /email-rule-objections). A write's answer leaves it out when it could not be read in time: absent is not 0.",
|
|
16247
|
+
"type": "integer",
|
|
16248
|
+
"minimum": 0
|
|
16249
|
+
},
|
|
16250
|
+
"objection_notice": {
|
|
16251
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
16252
|
+
"type": "string"
|
|
16253
|
+
},
|
|
15209
16254
|
"created_at": {
|
|
15210
16255
|
"type": "string",
|
|
15211
16256
|
"format": "date-time"
|
|
@@ -15473,7 +16518,7 @@ const operationManifest = [
|
|
|
15473
16518
|
]
|
|
15474
16519
|
},
|
|
15475
16520
|
"notice": {
|
|
15476
|
-
"description": "What is now shared, in words.",
|
|
16521
|
+
"description": "What is now shared, in words. When you changed the rule and it can now match mail the request left out by who it was sent to (such as mail where an address is only copied), that comes first.",
|
|
15477
16522
|
"type": "string"
|
|
15478
16523
|
}
|
|
15479
16524
|
},
|
|
@@ -15574,7 +16619,7 @@ const operationManifest = [
|
|
|
15574
16619
|
"binaryResponse": false,
|
|
15575
16620
|
"bodyRequired": true,
|
|
15576
16621
|
"command": "compile-email-rule",
|
|
15577
|
-
"description": "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
|
|
16622
|
+
"description": "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 the recent classified mail in evaluation_scope (by default your own mailboxes) its conditions match; for a grant rule with questions, conditions_breadth counts its conditions alone. include_sql returns the SQL it renders to. kind do_not_share compiles for recall. Needs mail:read, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
|
|
15578
16623
|
"hasJsonBody": true,
|
|
15579
16624
|
"method": "POST",
|
|
15580
16625
|
"operationId": "compileEmailRule",
|
|
@@ -15607,6 +16652,42 @@ const operationManifest = [
|
|
|
15607
16652
|
"include_sql": {
|
|
15608
16653
|
"description": "Also return the SQL the rule renders to. Off by default.",
|
|
15609
16654
|
"type": "boolean"
|
|
16655
|
+
},
|
|
16656
|
+
"evaluation_scope": {
|
|
16657
|
+
"description": "The scope breadth is counted over, as a test of the tree runs it: send the one you will save the rule with. Nothing is saved. own_mailboxes (the default): mail to your own addresses and agents (for a rule that shares, those mail:share_own lets you share). author: all you can read, inboxes added later included. selected: what scope_selection names.",
|
|
16658
|
+
"type": "string",
|
|
16659
|
+
"enum": [
|
|
16660
|
+
"author",
|
|
16661
|
+
"own_mailboxes",
|
|
16662
|
+
"selected"
|
|
16663
|
+
]
|
|
16664
|
+
},
|
|
16665
|
+
"scope_selection": {
|
|
16666
|
+
"type": "object",
|
|
16667
|
+
"properties": {
|
|
16668
|
+
"addresses": {
|
|
16669
|
+
"maxItems": 100,
|
|
16670
|
+
"type": "array",
|
|
16671
|
+
"items": {
|
|
16672
|
+
"type": "string",
|
|
16673
|
+
"minLength": 3,
|
|
16674
|
+
"maxLength": 320,
|
|
16675
|
+
"pattern": "^[^\\s@]+@[^\\s@]+$"
|
|
16676
|
+
}
|
|
16677
|
+
},
|
|
16678
|
+
"domains": {
|
|
16679
|
+
"maxItems": 50,
|
|
16680
|
+
"type": "array",
|
|
16681
|
+
"items": {
|
|
16682
|
+
"type": "string",
|
|
16683
|
+
"minLength": 1,
|
|
16684
|
+
"maxLength": 253,
|
|
16685
|
+
"pattern": "^[^\\s@]+\\.[^\\s@]+$"
|
|
16686
|
+
}
|
|
16687
|
+
}
|
|
16688
|
+
},
|
|
16689
|
+
"additionalProperties": false,
|
|
16690
|
+
"description": "For a selected rule: inboxes, and domains (each address at them the author reads); each one you can read."
|
|
15610
16691
|
}
|
|
15611
16692
|
},
|
|
15612
16693
|
"required": ["english"],
|
|
@@ -15669,14 +16750,14 @@ const operationManifest = [
|
|
|
15669
16750
|
"enum": ["grant", "do_not_share"]
|
|
15670
16751
|
},
|
|
15671
16752
|
"breadth": {
|
|
15672
|
-
"description": "How many
|
|
16753
|
+
"description": "How many recent emails its conditions hold for, warning or not, counted over evaluation_scope as sent (by default your own mailboxes, whatever scope you save it with). Null when not counted in full: a rule with questions, headers-only access, no test of it possible as you, a count that failed or ran out of time, or, with no scope sent, a rule that holds only for mail to To or Cc addresses outside your own mailboxes (a warning says so). Writes ignore it, so a compile answer (without include_sql) can be sent back unchanged.",
|
|
15673
16754
|
"anyOf": [{
|
|
15674
16755
|
"type": "object",
|
|
15675
16756
|
"properties": {
|
|
15676
16757
|
"checked": {
|
|
15677
16758
|
"type": "integer",
|
|
15678
16759
|
"minimum": 0,
|
|
15679
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
16760
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
15680
16761
|
},
|
|
15681
16762
|
"matched": {
|
|
15682
16763
|
"type": "integer",
|
|
@@ -15695,7 +16776,7 @@ const operationManifest = [
|
|
|
15695
16776
|
"checked": {
|
|
15696
16777
|
"type": "integer",
|
|
15697
16778
|
"minimum": 0,
|
|
15698
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
16779
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
15699
16780
|
},
|
|
15700
16781
|
"matched": {
|
|
15701
16782
|
"type": "integer",
|
|
@@ -15919,6 +17000,16 @@ const operationManifest = [
|
|
|
15919
17000
|
"pattern": "^[^\\u0000]*$"
|
|
15920
17001
|
}
|
|
15921
17002
|
},
|
|
17003
|
+
"attachment_names": {
|
|
17004
|
+
"maxItems": 10,
|
|
17005
|
+
"type": "array",
|
|
17006
|
+
"items": {
|
|
17007
|
+
"type": "string",
|
|
17008
|
+
"minLength": 1,
|
|
17009
|
+
"maxLength": 255,
|
|
17010
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
17011
|
+
}
|
|
17012
|
+
},
|
|
15922
17013
|
"automated": { "type": "boolean" },
|
|
15923
17014
|
"from_mailing_list": { "type": "boolean" },
|
|
15924
17015
|
"spam_score": {
|
|
@@ -15997,7 +17088,7 @@ const operationManifest = [
|
|
|
15997
17088
|
}
|
|
15998
17089
|
},
|
|
15999
17090
|
"warnings": {
|
|
16000
|
-
"description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test (on a rule request, every compiler note on the rule).",
|
|
17091
|
+
"description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test, or on a grant rule that tests only who an email was sent to (on a rule request, every compiler note on the rule).",
|
|
16001
17092
|
"maxItems": 10,
|
|
16002
17093
|
"type": "array",
|
|
16003
17094
|
"items": {
|
|
@@ -16020,7 +17111,7 @@ const operationManifest = [
|
|
|
16020
17111
|
"checked": {
|
|
16021
17112
|
"type": "integer",
|
|
16022
17113
|
"minimum": 0,
|
|
16023
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
17114
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
16024
17115
|
},
|
|
16025
17116
|
"matched": {
|
|
16026
17117
|
"type": "integer",
|
|
@@ -16039,7 +17130,7 @@ const operationManifest = [
|
|
|
16039
17130
|
"checked": {
|
|
16040
17131
|
"type": "integer",
|
|
16041
17132
|
"minimum": 0,
|
|
16042
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
17133
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
16043
17134
|
},
|
|
16044
17135
|
"matched": {
|
|
16045
17136
|
"type": "integer",
|
|
@@ -16148,6 +17239,15 @@ const operationManifest = [
|
|
|
16148
17239
|
"type": "boolean",
|
|
16149
17240
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
16150
17241
|
},
|
|
17242
|
+
"pending_objections": {
|
|
17243
|
+
"description": "To its author, on the dashboard or the Primitive CLI: objections to it waiting for their answer (GET /email-rule-objections). A write's answer leaves it out when it could not be read in time: absent is not 0.",
|
|
17244
|
+
"type": "integer",
|
|
17245
|
+
"minimum": 0
|
|
17246
|
+
},
|
|
17247
|
+
"objection_notice": {
|
|
17248
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
17249
|
+
"type": "string"
|
|
17250
|
+
},
|
|
16151
17251
|
"created_at": {
|
|
16152
17252
|
"type": "string",
|
|
16153
17253
|
"format": "date-time"
|
|
@@ -16274,6 +17374,27 @@ const operationManifest = [
|
|
|
16274
17374
|
]
|
|
16275
17375
|
}
|
|
16276
17376
|
},
|
|
17377
|
+
"expectations": {
|
|
17378
|
+
"description": "Its saved expectations, each list by email id, as stored: on every create, and on an update that set or removed them.",
|
|
17379
|
+
"type": "object",
|
|
17380
|
+
"properties": {
|
|
17381
|
+
"match": {
|
|
17382
|
+
"type": "array",
|
|
17383
|
+
"items": {
|
|
17384
|
+
"type": "string",
|
|
17385
|
+
"format": "uuid"
|
|
17386
|
+
}
|
|
17387
|
+
},
|
|
17388
|
+
"no_match": {
|
|
17389
|
+
"type": "array",
|
|
17390
|
+
"items": {
|
|
17391
|
+
"type": "string",
|
|
17392
|
+
"format": "uuid"
|
|
17393
|
+
}
|
|
17394
|
+
}
|
|
17395
|
+
},
|
|
17396
|
+
"required": ["match", "no_match"]
|
|
17397
|
+
},
|
|
16277
17398
|
"expectation_samples": {
|
|
16278
17399
|
"description": "Its saved made-up emails, when this write set or added some.",
|
|
16279
17400
|
"type": "array",
|
|
@@ -16351,6 +17472,16 @@ const operationManifest = [
|
|
|
16351
17472
|
"pattern": "^[^\\u0000]*$"
|
|
16352
17473
|
}
|
|
16353
17474
|
},
|
|
17475
|
+
"attachment_names": {
|
|
17476
|
+
"maxItems": 10,
|
|
17477
|
+
"type": "array",
|
|
17478
|
+
"items": {
|
|
17479
|
+
"type": "string",
|
|
17480
|
+
"minLength": 1,
|
|
17481
|
+
"maxLength": 255,
|
|
17482
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
17483
|
+
}
|
|
17484
|
+
},
|
|
16354
17485
|
"automated": { "type": "boolean" },
|
|
16355
17486
|
"from_mailing_list": { "type": "boolean" },
|
|
16356
17487
|
"spam_score": {
|
|
@@ -16476,6 +17607,10 @@ const operationManifest = [
|
|
|
16476
17607
|
"notice": {
|
|
16477
17608
|
"description": "After a write that saved a version of an active rule keys or webhooks read without checking it first: what it changes, and how to have the next one checked.",
|
|
16478
17609
|
"type": "string"
|
|
17610
|
+
},
|
|
17611
|
+
"share_notice": {
|
|
17612
|
+
"description": "After a write that ended the rule's share: that it did, given even when affects is not, with whom it was with and the version they accepted when those can be read.",
|
|
17613
|
+
"type": "string"
|
|
16479
17614
|
}
|
|
16480
17615
|
},
|
|
16481
17616
|
"required": [
|
|
@@ -16595,7 +17730,7 @@ const operationManifest = [
|
|
|
16595
17730
|
}
|
|
16596
17731
|
},
|
|
16597
17732
|
"warnings": {
|
|
16598
|
-
"description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test (on a rule request, every compiler note on the rule).",
|
|
17733
|
+
"description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test, or on a grant rule that tests only who an email was sent to (on a rule request, every compiler note on the rule).",
|
|
16599
17734
|
"maxItems": 10,
|
|
16600
17735
|
"type": "array",
|
|
16601
17736
|
"items": {
|
|
@@ -16618,7 +17753,7 @@ const operationManifest = [
|
|
|
16618
17753
|
"checked": {
|
|
16619
17754
|
"type": "integer",
|
|
16620
17755
|
"minimum": 0,
|
|
16621
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
17756
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
16622
17757
|
},
|
|
16623
17758
|
"matched": {
|
|
16624
17759
|
"type": "integer",
|
|
@@ -16637,7 +17772,7 @@ const operationManifest = [
|
|
|
16637
17772
|
"checked": {
|
|
16638
17773
|
"type": "integer",
|
|
16639
17774
|
"minimum": 0,
|
|
16640
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
17775
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
16641
17776
|
},
|
|
16642
17777
|
"matched": {
|
|
16643
17778
|
"type": "integer",
|
|
@@ -17097,7 +18232,7 @@ const operationManifest = [
|
|
|
17097
18232
|
"binaryResponse": false,
|
|
17098
18233
|
"bodyRequired": false,
|
|
17099
18234
|
"command": "delete-email-rule",
|
|
17100
|
-
"description": "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, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
|
|
18235
|
+
"description": "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), says whom with (share_notice), and lists 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, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
|
|
17101
18236
|
"hasJsonBody": false,
|
|
17102
18237
|
"method": "DELETE",
|
|
17103
18238
|
"operationId": "deleteEmailRule",
|
|
@@ -17149,6 +18284,10 @@ const operationManifest = [
|
|
|
17149
18284
|
"other_keys": {
|
|
17150
18285
|
"description": "How many more keys, not revoked, list the rule that you may not read. They are not named.",
|
|
17151
18286
|
"type": "integer"
|
|
18287
|
+
},
|
|
18288
|
+
"share_notice": {
|
|
18289
|
+
"description": "When the delete ended a share: that it did, with whom it was with and the version they accepted when those can be read.",
|
|
18290
|
+
"type": "string"
|
|
17152
18291
|
}
|
|
17153
18292
|
},
|
|
17154
18293
|
"required": ["deleted"]
|
|
@@ -17321,7 +18460,7 @@ const operationManifest = [
|
|
|
17321
18460
|
"description": "For a selected rule: inboxes, and domains (each address at them the author reads); each one you can read."
|
|
17322
18461
|
},
|
|
17323
18462
|
"rule_id": {
|
|
17324
|
-
"description": "A saved rule you can see: its current version and words.",
|
|
18463
|
+
"description": "A saved rule you can see, or one that covers your mailboxes (as you, sent to one of them; dashboard or Primitive CLI only): its current version and words.",
|
|
17325
18464
|
"type": "string",
|
|
17326
18465
|
"format": "uuid"
|
|
17327
18466
|
},
|
|
@@ -17447,6 +18586,10 @@ const operationManifest = [
|
|
|
17447
18586
|
"type": "array",
|
|
17448
18587
|
"items": { "type": "string" }
|
|
17449
18588
|
},
|
|
18589
|
+
"attachment_names": {
|
|
18590
|
+
"type": "array",
|
|
18591
|
+
"items": { "type": "string" }
|
|
18592
|
+
},
|
|
17450
18593
|
"automated": { "type": "boolean" },
|
|
17451
18594
|
"from_mailing_list": { "type": "boolean" }
|
|
17452
18595
|
},
|
|
@@ -17457,6 +18600,7 @@ const operationManifest = [
|
|
|
17457
18600
|
"subject",
|
|
17458
18601
|
"text",
|
|
17459
18602
|
"attachment_types",
|
|
18603
|
+
"attachment_names",
|
|
17460
18604
|
"automated",
|
|
17461
18605
|
"from_mailing_list"
|
|
17462
18606
|
],
|
|
@@ -17671,6 +18815,15 @@ const operationManifest = [
|
|
|
17671
18815
|
"type": "boolean",
|
|
17672
18816
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
17673
18817
|
},
|
|
18818
|
+
"pending_objections": {
|
|
18819
|
+
"description": "To its author, on the dashboard or the Primitive CLI: objections to it waiting for their answer (GET /email-rule-objections). A write's answer leaves it out when it could not be read in time: absent is not 0.",
|
|
18820
|
+
"type": "integer",
|
|
18821
|
+
"minimum": 0
|
|
18822
|
+
},
|
|
18823
|
+
"objection_notice": {
|
|
18824
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
18825
|
+
"type": "string"
|
|
18826
|
+
},
|
|
17674
18827
|
"created_at": {
|
|
17675
18828
|
"type": "string",
|
|
17676
18829
|
"format": "date-time"
|
|
@@ -17865,6 +19018,16 @@ const operationManifest = [
|
|
|
17865
19018
|
"pattern": "^[^\\u0000]*$"
|
|
17866
19019
|
}
|
|
17867
19020
|
},
|
|
19021
|
+
"attachment_names": {
|
|
19022
|
+
"maxItems": 10,
|
|
19023
|
+
"type": "array",
|
|
19024
|
+
"items": {
|
|
19025
|
+
"type": "string",
|
|
19026
|
+
"minLength": 1,
|
|
19027
|
+
"maxLength": 255,
|
|
19028
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
19029
|
+
}
|
|
19030
|
+
},
|
|
17868
19031
|
"automated": { "type": "boolean" },
|
|
17869
19032
|
"from_mailing_list": { "type": "boolean" },
|
|
17870
19033
|
"spam_score": {
|
|
@@ -19329,6 +20492,16 @@ const operationManifest = [
|
|
|
19329
20492
|
"count": {
|
|
19330
20493
|
"type": "integer",
|
|
19331
20494
|
"exclusiveMinimum": 0
|
|
20495
|
+
},
|
|
20496
|
+
"reads_in_full": {
|
|
20497
|
+
"description": "On a rule over your mail: how many of these keys also list one of your own mailboxes, or its domain, so they read your mail there beyond what this rule matches.",
|
|
20498
|
+
"type": "integer",
|
|
20499
|
+
"minimum": 0
|
|
20500
|
+
},
|
|
20501
|
+
"newest_at": {
|
|
20502
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
20503
|
+
"type": "string",
|
|
20504
|
+
"format": "date-time"
|
|
19332
20505
|
}
|
|
19333
20506
|
},
|
|
19334
20507
|
"required": ["owner", "count"]
|
|
@@ -19376,7 +20549,7 @@ const operationManifest = [
|
|
|
19376
20549
|
"exclusiveMinimum": 0
|
|
19377
20550
|
},
|
|
19378
20551
|
"hosts": {
|
|
19379
|
-
"description": "Distinct sites they deliver to (a host's
|
|
20552
|
+
"description": "Distinct sites they deliver to (the domain a host is registered under, an app's own name on a known app platform, or a function URL service in its region), sorted, at most 10; \"unknown host\" (last) for any that cannot be named.",
|
|
19380
20553
|
"type": "array",
|
|
19381
20554
|
"items": { "type": "string" }
|
|
19382
20555
|
},
|
|
@@ -19384,6 +20557,11 @@ const operationManifest = [
|
|
|
19384
20557
|
"description": "Hosts past those listed.",
|
|
19385
20558
|
"type": "integer",
|
|
19386
20559
|
"minimum": 0
|
|
20560
|
+
},
|
|
20561
|
+
"newest_at": {
|
|
20562
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
20563
|
+
"type": "string",
|
|
20564
|
+
"format": "date-time"
|
|
19387
20565
|
}
|
|
19388
20566
|
},
|
|
19389
20567
|
"required": ["owner", "count"]
|
|
@@ -19421,6 +20599,11 @@ const operationManifest = [
|
|
|
19421
20599
|
"count": {
|
|
19422
20600
|
"type": "integer",
|
|
19423
20601
|
"exclusiveMinimum": 0
|
|
20602
|
+
},
|
|
20603
|
+
"newest_at": {
|
|
20604
|
+
"description": "When the newest of these was made, to the minute: a key, a webhook or the share, or the rule (the share, for what reaches it only through the share) if that was later. Not when a key was given access to this rule, or anything turned back on; a rotated key shows as newly made, and one key on two rules can show the same minute under both.",
|
|
20605
|
+
"type": "string",
|
|
20606
|
+
"format": "date-time"
|
|
19424
20607
|
}
|
|
19425
20608
|
},
|
|
19426
20609
|
"required": ["beneficiary", "count"]
|
|
@@ -19433,7 +20616,7 @@ const operationManifest = [
|
|
|
19433
20616
|
"webhooks",
|
|
19434
20617
|
"shares"
|
|
19435
20618
|
],
|
|
19436
|
-
"description": "Who receives what the rule shares
|
|
20619
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
19437
20620
|
}, { "type": "null" }]
|
|
19438
20621
|
}
|
|
19439
20622
|
},
|
|
@@ -20420,6 +21603,15 @@ const operationManifest = [
|
|
|
20420
21603
|
"type": "boolean",
|
|
20421
21604
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
20422
21605
|
},
|
|
21606
|
+
"pending_objections": {
|
|
21607
|
+
"description": "To its author, on the dashboard or the Primitive CLI: objections to it waiting for their answer (GET /email-rule-objections). A write's answer leaves it out when it could not be read in time: absent is not 0.",
|
|
21608
|
+
"type": "integer",
|
|
21609
|
+
"minimum": 0
|
|
21610
|
+
},
|
|
21611
|
+
"objection_notice": {
|
|
21612
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
21613
|
+
"type": "string"
|
|
21614
|
+
},
|
|
20423
21615
|
"created_at": {
|
|
20424
21616
|
"type": "string",
|
|
20425
21617
|
"format": "date-time"
|
|
@@ -20867,6 +22059,16 @@ const operationManifest = [
|
|
|
20867
22059
|
"pattern": "^[^\\u0000]*$"
|
|
20868
22060
|
}
|
|
20869
22061
|
},
|
|
22062
|
+
"attachment_names": {
|
|
22063
|
+
"maxItems": 10,
|
|
22064
|
+
"type": "array",
|
|
22065
|
+
"items": {
|
|
22066
|
+
"type": "string",
|
|
22067
|
+
"minLength": 1,
|
|
22068
|
+
"maxLength": 255,
|
|
22069
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
22070
|
+
}
|
|
22071
|
+
},
|
|
20870
22072
|
"automated": { "type": "boolean" },
|
|
20871
22073
|
"from_mailing_list": { "type": "boolean" },
|
|
20872
22074
|
"spam_score": {
|
|
@@ -21177,6 +22379,11 @@ const operationManifest = [
|
|
|
21177
22379
|
"minimum": 0,
|
|
21178
22380
|
"description": "Emails decided on their conditions: matched, near_miss and no_match, less any missing a fact the rule reads."
|
|
21179
22381
|
},
|
|
22382
|
+
"conditions_held": {
|
|
22383
|
+
"description": "Of decided, how many its conditions alone held for. Compile's breadth and conditions_breadth count this over recent mail in the scope sent to it, by default your own; here it is counted over the emails this test decided.",
|
|
22384
|
+
"type": "integer",
|
|
22385
|
+
"minimum": 0
|
|
22386
|
+
},
|
|
21180
22387
|
"conditions": {
|
|
21181
22388
|
"type": "array",
|
|
21182
22389
|
"items": {
|
|
@@ -21244,7 +22451,7 @@ const operationManifest = [
|
|
|
21244
22451
|
"warnings": {
|
|
21245
22452
|
"type": "array",
|
|
21246
22453
|
"items": { "type": "string" },
|
|
21247
|
-
"description": "What to look at first, such as what stopped every email when nothing matched."
|
|
22454
|
+
"description": "What to look at first, such as what stopped every email when nothing matched. On a test of the recent window, a grant rule whose conditions held for more than 20% of at least 20 emails checked (at least 90% if it has no questions), or for every one of fewer, gets a warning saying so, before those about what it decided."
|
|
21248
22455
|
}
|
|
21249
22456
|
},
|
|
21250
22457
|
"required": [
|
|
@@ -21447,7 +22654,7 @@ const operationManifest = [
|
|
|
21447
22654
|
"binaryResponse": false,
|
|
21448
22655
|
"bodyRequired": true,
|
|
21449
22656
|
"command": "test-email-rule-on-sample",
|
|
21450
|
-
"description": "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, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
|
|
22657
|
+
"description": "Reports what a rule would decide for an email you describe (sender, recipients, subject, plain text, attachment types and file names; 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, the email rules feature, and a member's own full-access credential (no API key, agent key or narrowed token).",
|
|
21451
22658
|
"hasJsonBody": true,
|
|
21452
22659
|
"method": "POST",
|
|
21453
22660
|
"operationId": "testEmailRuleOnSample",
|
|
@@ -21533,7 +22740,7 @@ const operationManifest = [
|
|
|
21533
22740
|
"description": "For a selected rule: inboxes, and domains (each address at them the author reads); each one you can read."
|
|
21534
22741
|
},
|
|
21535
22742
|
"rule_id": {
|
|
21536
|
-
"description": "A saved rule you can see. Its current version is tested.",
|
|
22743
|
+
"description": "A saved rule you can see, or one that covers your mailboxes (as you; dashboard or Primitive CLI only). Its current version is tested.",
|
|
21537
22744
|
"type": "string",
|
|
21538
22745
|
"format": "uuid"
|
|
21539
22746
|
},
|
|
@@ -21604,6 +22811,17 @@ const operationManifest = [
|
|
|
21604
22811
|
"maxLength": 255
|
|
21605
22812
|
}
|
|
21606
22813
|
},
|
|
22814
|
+
"attachment_names": {
|
|
22815
|
+
"description": "File names of those attachments, which the classifier and the questions read. With attachment_types, the same number, paired in order.",
|
|
22816
|
+
"maxItems": 20,
|
|
22817
|
+
"type": "array",
|
|
22818
|
+
"items": {
|
|
22819
|
+
"type": "string",
|
|
22820
|
+
"minLength": 1,
|
|
22821
|
+
"maxLength": 255,
|
|
22822
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
22823
|
+
}
|
|
22824
|
+
},
|
|
21607
22825
|
"automated": {
|
|
21608
22826
|
"description": "Whether the email was sent automatically, as its headers would show. Defaults to false.",
|
|
21609
22827
|
"type": "boolean"
|
|
@@ -21890,7 +23108,7 @@ const operationManifest = [
|
|
|
21890
23108
|
}
|
|
21891
23109
|
},
|
|
21892
23110
|
"warnings": {
|
|
21893
|
-
"description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test (on a rule request, every compiler note on the rule).",
|
|
23111
|
+
"description": "The compile response's warnings. Stored as sent, then any server note they lack on an address or domain the description names that the rule does not test, or on a grant rule that tests only who an email was sent to (on a rule request, every compiler note on the rule).",
|
|
21894
23112
|
"maxItems": 10,
|
|
21895
23113
|
"type": "array",
|
|
21896
23114
|
"items": {
|
|
@@ -21913,7 +23131,7 @@ const operationManifest = [
|
|
|
21913
23131
|
"checked": {
|
|
21914
23132
|
"type": "integer",
|
|
21915
23133
|
"minimum": 0,
|
|
21916
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
23134
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
21917
23135
|
},
|
|
21918
23136
|
"matched": {
|
|
21919
23137
|
"type": "integer",
|
|
@@ -21932,7 +23150,7 @@ const operationManifest = [
|
|
|
21932
23150
|
"checked": {
|
|
21933
23151
|
"type": "integer",
|
|
21934
23152
|
"minimum": 0,
|
|
21935
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
23153
|
+
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in the scope counted (evaluation_scope as sent; by default your own mailboxes, for a grant rule those you may share), the ones you can still read."
|
|
21936
23154
|
},
|
|
21937
23155
|
"matched": {
|
|
21938
23156
|
"type": "integer",
|
|
@@ -22091,6 +23309,16 @@ const operationManifest = [
|
|
|
22091
23309
|
"pattern": "^[^\\u0000]*$"
|
|
22092
23310
|
}
|
|
22093
23311
|
},
|
|
23312
|
+
"attachment_names": {
|
|
23313
|
+
"maxItems": 10,
|
|
23314
|
+
"type": "array",
|
|
23315
|
+
"items": {
|
|
23316
|
+
"type": "string",
|
|
23317
|
+
"minLength": 1,
|
|
23318
|
+
"maxLength": 255,
|
|
23319
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
23320
|
+
}
|
|
23321
|
+
},
|
|
22094
23322
|
"automated": { "type": "boolean" },
|
|
22095
23323
|
"from_mailing_list": { "type": "boolean" },
|
|
22096
23324
|
"spam_score": {
|
|
@@ -22198,6 +23426,16 @@ const operationManifest = [
|
|
|
22198
23426
|
"pattern": "^[^\\u0000]*$"
|
|
22199
23427
|
}
|
|
22200
23428
|
},
|
|
23429
|
+
"attachment_names": {
|
|
23430
|
+
"maxItems": 10,
|
|
23431
|
+
"type": "array",
|
|
23432
|
+
"items": {
|
|
23433
|
+
"type": "string",
|
|
23434
|
+
"minLength": 1,
|
|
23435
|
+
"maxLength": 255,
|
|
23436
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
23437
|
+
}
|
|
23438
|
+
},
|
|
22201
23439
|
"automated": { "type": "boolean" },
|
|
22202
23440
|
"from_mailing_list": { "type": "boolean" },
|
|
22203
23441
|
"spam_score": {
|
|
@@ -22332,6 +23570,15 @@ const operationManifest = [
|
|
|
22332
23570
|
"type": "boolean",
|
|
22333
23571
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
22334
23572
|
},
|
|
23573
|
+
"pending_objections": {
|
|
23574
|
+
"description": "To its author, on the dashboard or the Primitive CLI: objections to it waiting for their answer (GET /email-rule-objections). A write's answer leaves it out when it could not be read in time: absent is not 0.",
|
|
23575
|
+
"type": "integer",
|
|
23576
|
+
"minimum": 0
|
|
23577
|
+
},
|
|
23578
|
+
"objection_notice": {
|
|
23579
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
23580
|
+
"type": "string"
|
|
23581
|
+
},
|
|
22335
23582
|
"created_at": {
|
|
22336
23583
|
"type": "string",
|
|
22337
23584
|
"format": "date-time"
|
|
@@ -22458,6 +23705,27 @@ const operationManifest = [
|
|
|
22458
23705
|
]
|
|
22459
23706
|
}
|
|
22460
23707
|
},
|
|
23708
|
+
"expectations": {
|
|
23709
|
+
"description": "Its saved expectations, each list by email id, as stored: on every create, and on an update that set or removed them.",
|
|
23710
|
+
"type": "object",
|
|
23711
|
+
"properties": {
|
|
23712
|
+
"match": {
|
|
23713
|
+
"type": "array",
|
|
23714
|
+
"items": {
|
|
23715
|
+
"type": "string",
|
|
23716
|
+
"format": "uuid"
|
|
23717
|
+
}
|
|
23718
|
+
},
|
|
23719
|
+
"no_match": {
|
|
23720
|
+
"type": "array",
|
|
23721
|
+
"items": {
|
|
23722
|
+
"type": "string",
|
|
23723
|
+
"format": "uuid"
|
|
23724
|
+
}
|
|
23725
|
+
}
|
|
23726
|
+
},
|
|
23727
|
+
"required": ["match", "no_match"]
|
|
23728
|
+
},
|
|
22461
23729
|
"expectation_samples": {
|
|
22462
23730
|
"description": "Its saved made-up emails, when this write set or added some.",
|
|
22463
23731
|
"type": "array",
|
|
@@ -22535,6 +23803,16 @@ const operationManifest = [
|
|
|
22535
23803
|
"pattern": "^[^\\u0000]*$"
|
|
22536
23804
|
}
|
|
22537
23805
|
},
|
|
23806
|
+
"attachment_names": {
|
|
23807
|
+
"maxItems": 10,
|
|
23808
|
+
"type": "array",
|
|
23809
|
+
"items": {
|
|
23810
|
+
"type": "string",
|
|
23811
|
+
"minLength": 1,
|
|
23812
|
+
"maxLength": 255,
|
|
23813
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
23814
|
+
}
|
|
23815
|
+
},
|
|
22538
23816
|
"automated": { "type": "boolean" },
|
|
22539
23817
|
"from_mailing_list": { "type": "boolean" },
|
|
22540
23818
|
"spam_score": {
|
|
@@ -22660,6 +23938,10 @@ const operationManifest = [
|
|
|
22660
23938
|
"notice": {
|
|
22661
23939
|
"description": "After a write that saved a version of an active rule keys or webhooks read without checking it first: what it changes, and how to have the next one checked.",
|
|
22662
23940
|
"type": "string"
|
|
23941
|
+
},
|
|
23942
|
+
"share_notice": {
|
|
23943
|
+
"description": "After a write that ended the rule's share: that it did, given even when affects is not, with whom it was with and the version they accepted when those can be read.",
|
|
23944
|
+
"type": "string"
|
|
22663
23945
|
}
|
|
22664
23946
|
},
|
|
22665
23947
|
"required": [
|
|
@@ -24272,6 +25554,29 @@ const operationManifest = [
|
|
|
24272
25554
|
}
|
|
24273
25555
|
}
|
|
24274
25556
|
},
|
|
25557
|
+
"attachments": {
|
|
25558
|
+
"type": "array",
|
|
25559
|
+
"items": {
|
|
25560
|
+
"type": "object",
|
|
25561
|
+
"description": "Metadata for one attachment. The bytes are not inline; download\nall attachments for a message as a gzipped tarball via\n`/emails/{id}/attachments.tar.gz`. `sha256` lets you verify a\nspecific part after extraction.\n",
|
|
25562
|
+
"properties": {
|
|
25563
|
+
"filename": { "type": ["string", "null"] },
|
|
25564
|
+
"content_type": { "type": ["string", "null"] },
|
|
25565
|
+
"size_bytes": { "type": "integer" },
|
|
25566
|
+
"sha256": { "type": ["string", "null"] },
|
|
25567
|
+
"part_index": {
|
|
25568
|
+
"type": "integer",
|
|
25569
|
+
"description": "Zero-based index of this part within the message."
|
|
25570
|
+
},
|
|
25571
|
+
"tar_path": {
|
|
25572
|
+
"type": "string",
|
|
25573
|
+
"description": "This part's file name inside the message's attachments archive. Absent on attachments stored before it was recorded."
|
|
25574
|
+
}
|
|
25575
|
+
},
|
|
25576
|
+
"required": ["size_bytes"]
|
|
25577
|
+
},
|
|
25578
|
+
"description": "Attachment metadata (file name, type, size), the same items in the same order as `parsed.attachments`. Kept for a credential that reads headers only, where `parsed` is null. Empty when the email has none, its content is withheld (read `status` and `rejection_reason`), or it is not parsed yet or its parse failed (read `parse_status`). No bytes; download a part with `/emails/{id}/attachments/{part_index}`."
|
|
25579
|
+
},
|
|
24275
25580
|
"imported": {
|
|
24276
25581
|
"type": ["object", "null"],
|
|
24277
25582
|
"description": "Historical acquisition; never sender or SMTP delivery proof. Null for live mail. Excluded from live tails and deltas.",
|
|
@@ -24330,6 +25635,7 @@ const operationManifest = [
|
|
|
24330
25635
|
"from_verified",
|
|
24331
25636
|
"from_header_email",
|
|
24332
25637
|
"from_name",
|
|
25638
|
+
"attachments",
|
|
24333
25639
|
"imported",
|
|
24334
25640
|
"snippet"
|
|
24335
25641
|
]
|
|
@@ -24590,6 +25896,94 @@ const operationManifest = [
|
|
|
24590
25896
|
"tag": "Emails",
|
|
24591
25897
|
"tagCommand": "emails"
|
|
24592
25898
|
},
|
|
25899
|
+
{
|
|
25900
|
+
"binaryResponse": false,
|
|
25901
|
+
"bodyRequired": true,
|
|
25902
|
+
"command": "import-google-mail-message",
|
|
25903
|
+
"description": "Requires the organization email_import entitlement, granted by staff. Only the configured current owner, using a full personal session or verified first-party CLI, may import into the configured primary mailbox. Primitive verifies the transient provider token and fetches RAW content itself. No raw uploads or client provenance are accepted. Sent, draft, spam and trash messages are skipped. Historical mail appears in normal history without live delivery effects. An indeterminate response requires retrying the same provider ID. User provider credentials are never stored or queued.",
|
|
25904
|
+
"hasJsonBody": true,
|
|
25905
|
+
"method": "POST",
|
|
25906
|
+
"operationId": "importGoogleMailMessage",
|
|
25907
|
+
"path": "/mail-imports/google/messages",
|
|
25908
|
+
"pathParams": [],
|
|
25909
|
+
"queryParams": [],
|
|
25910
|
+
"headerParams": [{
|
|
25911
|
+
"description": "Transient provider user access token. Send only in this redacted header, never in a URL or JSON body. Uses the dedicated configured desktop client and readonly/identity scopes.",
|
|
25912
|
+
"enum": null,
|
|
25913
|
+
"name": "X-Primitive-Google-Access-Token",
|
|
25914
|
+
"required": true,
|
|
25915
|
+
"type": "string"
|
|
25916
|
+
}, {
|
|
25917
|
+
"description": "Optional, and not used to deduplicate: this operation stores no result by the key, so a retry with the same key runs the request again. Operations that need a credential refuse a key that is empty, longer than 255 characters or not printable ASCII with 400 `validation_error` and echo a valid one in the Idempotency-Key response header; operations that need none ignore it.",
|
|
25918
|
+
"enum": null,
|
|
25919
|
+
"name": "Idempotency-Key",
|
|
25920
|
+
"required": false,
|
|
25921
|
+
"type": "string"
|
|
25922
|
+
}],
|
|
25923
|
+
"permissions": ["mail:read"],
|
|
25924
|
+
"access": null,
|
|
25925
|
+
"requestSchema": {
|
|
25926
|
+
"type": "object",
|
|
25927
|
+
"properties": { "message_id": {
|
|
25928
|
+
"type": "string",
|
|
25929
|
+
"pattern": "^[A-Za-z0-9_-]{1,128}$"
|
|
25930
|
+
} },
|
|
25931
|
+
"required": ["message_id"],
|
|
25932
|
+
"additionalProperties": false
|
|
25933
|
+
},
|
|
25934
|
+
"responseSchema": { "anyOf": [
|
|
25935
|
+
{
|
|
25936
|
+
"type": "object",
|
|
25937
|
+
"properties": {
|
|
25938
|
+
"status": {
|
|
25939
|
+
"type": "string",
|
|
25940
|
+
"enum": ["imported", "already_present"]
|
|
25941
|
+
},
|
|
25942
|
+
"email_id": {
|
|
25943
|
+
"type": "string",
|
|
25944
|
+
"format": "uuid",
|
|
25945
|
+
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
|
|
25946
|
+
}
|
|
25947
|
+
},
|
|
25948
|
+
"required": ["status", "email_id"]
|
|
25949
|
+
},
|
|
25950
|
+
{
|
|
25951
|
+
"type": "object",
|
|
25952
|
+
"properties": { "status": {
|
|
25953
|
+
"type": "string",
|
|
25954
|
+
"enum": [
|
|
25955
|
+
"suppressed",
|
|
25956
|
+
"in_progress",
|
|
25957
|
+
"indeterminate"
|
|
25958
|
+
]
|
|
25959
|
+
} },
|
|
25960
|
+
"required": ["status"]
|
|
25961
|
+
},
|
|
25962
|
+
{
|
|
25963
|
+
"type": "object",
|
|
25964
|
+
"properties": {
|
|
25965
|
+
"status": {
|
|
25966
|
+
"type": "string",
|
|
25967
|
+
"const": "skipped"
|
|
25968
|
+
},
|
|
25969
|
+
"reason": {
|
|
25970
|
+
"type": "string",
|
|
25971
|
+
"enum": [
|
|
25972
|
+
"excluded_label",
|
|
25973
|
+
"out_of_window",
|
|
25974
|
+
"too_large",
|
|
25975
|
+
"provider_missing"
|
|
25976
|
+
]
|
|
25977
|
+
}
|
|
25978
|
+
},
|
|
25979
|
+
"required": ["status", "reason"]
|
|
25980
|
+
}
|
|
25981
|
+
] },
|
|
25982
|
+
"sdkName": "importGoogleMailMessage",
|
|
25983
|
+
"summary": "Import one historical Google Workspace message",
|
|
25984
|
+
"tag": "Emails",
|
|
25985
|
+
"tagCommand": "emails"
|
|
25986
|
+
},
|
|
24593
25987
|
{
|
|
24594
25988
|
"binaryResponse": false,
|
|
24595
25989
|
"bodyRequired": false,
|
|
@@ -25306,6 +26700,50 @@ const operationManifest = [
|
|
|
25306
26700
|
"tag": "Emails",
|
|
25307
26701
|
"tagCommand": "emails"
|
|
25308
26702
|
},
|
|
26703
|
+
{
|
|
26704
|
+
"binaryResponse": false,
|
|
26705
|
+
"bodyRequired": true,
|
|
26706
|
+
"command": "reconcile-google-mail-import",
|
|
26707
|
+
"description": "The same configured owner may recover expired attempts after the email_import entitlement is revoked. Recovery does not require that entitlement. Selects only server-owned manifests for the configured mailbox/account/policy. No provider token, object keys, prefixes or email IDs are accepted. Unsettled uploads remain unresolved and charged; this operation does not promise automatic cleanup after a process dies.",
|
|
26708
|
+
"hasJsonBody": true,
|
|
26709
|
+
"method": "POST",
|
|
26710
|
+
"operationId": "reconcileGoogleMailImport",
|
|
26711
|
+
"path": "/mail-imports/google/reconcile",
|
|
26712
|
+
"pathParams": [],
|
|
26713
|
+
"queryParams": [],
|
|
26714
|
+
"headerParams": [{
|
|
26715
|
+
"description": "Optional, and not used to deduplicate: this operation stores no result by the key, so a retry with the same key runs the request again. Operations that need a credential refuse a key that is empty, longer than 255 characters or not printable ASCII with 400 `validation_error` and echo a valid one in the Idempotency-Key response header; operations that need none ignore it.",
|
|
26716
|
+
"enum": null,
|
|
26717
|
+
"name": "Idempotency-Key",
|
|
26718
|
+
"required": false,
|
|
26719
|
+
"type": "string"
|
|
26720
|
+
}],
|
|
26721
|
+
"permissions": ["mail:read"],
|
|
26722
|
+
"access": null,
|
|
26723
|
+
"requestSchema": {
|
|
26724
|
+
"type": "object",
|
|
26725
|
+
"properties": {},
|
|
26726
|
+
"additionalProperties": false
|
|
26727
|
+
},
|
|
26728
|
+
"responseSchema": {
|
|
26729
|
+
"type": "object",
|
|
26730
|
+
"properties": {
|
|
26731
|
+
"cleaned": {
|
|
26732
|
+
"type": "integer",
|
|
26733
|
+
"minimum": 0
|
|
26734
|
+
},
|
|
26735
|
+
"unresolved": {
|
|
26736
|
+
"type": "integer",
|
|
26737
|
+
"minimum": 0
|
|
26738
|
+
}
|
|
26739
|
+
},
|
|
26740
|
+
"required": ["cleaned", "unresolved"]
|
|
26741
|
+
},
|
|
26742
|
+
"sdkName": "reconcileGoogleMailImport",
|
|
26743
|
+
"summary": "Reconcile scoped historical import attempts",
|
|
26744
|
+
"tag": "Emails",
|
|
26745
|
+
"tagCommand": "emails"
|
|
26746
|
+
},
|
|
25309
26747
|
{
|
|
25310
26748
|
"binaryResponse": false,
|
|
25311
26749
|
"bodyRequired": false,
|
|
@@ -35797,7 +37235,7 @@ const operationManifest = [
|
|
|
35797
37235
|
"pathParams": [],
|
|
35798
37236
|
"queryParams": [],
|
|
35799
37237
|
"headerParams": [{
|
|
35800
|
-
"description": "A single-use step-up token of purpose `org_settings.write` (Change the organization name, logo
|
|
37238
|
+
"description": "A single-use step-up token of purpose `org_settings.write` (Change the organization name, logo, semantic search setting or email notification settings), valid 5 minutes. When this operation answers 403 `step_up_required`, the person confirms at the link in `details.step_up_url` and the request is retried with the token that page shows, in this header. Accepted only with the person's own OAuth token of the client it was confirmed for; refused with a token issued for MCP, with any API key or agent connection key, and with a dashboard session.",
|
|
35801
37239
|
"enum": null,
|
|
35802
37240
|
"name": "Primitive-Step-Up",
|
|
35803
37241
|
"required": false,
|
|
@@ -35943,7 +37381,7 @@ const operationManifest = [
|
|
|
35943
37381
|
"pathParams": [],
|
|
35944
37382
|
"queryParams": [],
|
|
35945
37383
|
"headerParams": [{
|
|
35946
|
-
"description": "A single-use step-up token of purpose `org_settings.write` (Change the organization name, logo
|
|
37384
|
+
"description": "A single-use step-up token of purpose `org_settings.write` (Change the organization name, logo, semantic search setting or email notification settings), valid 5 minutes. When this operation answers 403 `step_up_required`, the person confirms at the link in `details.step_up_url` and the request is retried with the token that page shows, in this header. Accepted only with the person's own OAuth token of the client it was confirmed for; refused with a token issued for MCP, with any API key or agent connection key, and with a dashboard session.",
|
|
35947
37385
|
"enum": null,
|
|
35948
37386
|
"name": "Primitive-Step-Up",
|
|
35949
37387
|
"required": false,
|
|
@@ -35992,7 +37430,7 @@ const operationManifest = [
|
|
|
35992
37430
|
"pathParams": [],
|
|
35993
37431
|
"queryParams": [],
|
|
35994
37432
|
"headerParams": [{
|
|
35995
|
-
"description": "A single-use step-up token of purpose `org_settings.write` (Change the organization name, logo
|
|
37433
|
+
"description": "A single-use step-up token of purpose `org_settings.write` (Change the organization name, logo, semantic search setting or email notification settings), valid 5 minutes. When this operation answers 403 `step_up_required`, the person confirms at the link in `details.step_up_url` and the request is retried with the token that page shows, in this header. Accepted only with the person's own OAuth token of the client it was confirmed for; refused with a token issued for MCP, with any API key or agent connection key, and with a dashboard session.",
|
|
35996
37434
|
"enum": null,
|
|
35997
37435
|
"name": "Primitive-Step-Up",
|
|
35998
37436
|
"required": false,
|
|
@@ -36052,7 +37490,7 @@ const operationManifest = [
|
|
|
36052
37490
|
"pathParams": [],
|
|
36053
37491
|
"queryParams": [],
|
|
36054
37492
|
"headerParams": [{
|
|
36055
|
-
"description": "A single-use step-up token of purpose `org_settings.write` (Change the organization name, logo
|
|
37493
|
+
"description": "A single-use step-up token of purpose `org_settings.write` (Change the organization name, logo, semantic search setting or email notification settings), valid 5 minutes. When this operation answers 403 `step_up_required`, the person confirms at the link in `details.step_up_url` and the request is retried with the token that page shows, in this header. Accepted only with the person's own OAuth token of the client it was confirmed for; refused with a token issued for MCP, with any API key or agent connection key, and with a dashboard session.",
|
|
36056
37494
|
"enum": null,
|
|
36057
37495
|
"name": "Primitive-Step-Up",
|
|
36058
37496
|
"required": false,
|
|
@@ -45776,6 +47214,33 @@ const operationManifest = [
|
|
|
45776
47214
|
"type": "boolean",
|
|
45777
47215
|
"description": "Send an informational message the receiver need not answer or wake for. It is sent as an `ack` signal (status `received`) about the message in `in_reply_to`, whose note is `body_text` (at most 2000 characters, which may be omitted). Receivers see it as `fyi: true`. Plain text only: it cannot be combined with `body_html`, `attachments`, `payload_attachments` or `scheduled_at`, and on `/send-mail` it requires `in_reply_to`."
|
|
45778
47216
|
},
|
|
47217
|
+
"unsubscribe": {
|
|
47218
|
+
"type": "object",
|
|
47219
|
+
"additionalProperties": false,
|
|
47220
|
+
"required": ["url"],
|
|
47221
|
+
"description": "One-click unsubscribe for the message. Primitive writes a `List-Unsubscribe` header naming `url` (and `mailto` when given) and, unless `one_click` is false, `List-Unsubscribe-Post: List-Unsubscribe=One-Click` (RFC 8058), and DKIM-signs both. A receiver that offers one-click unsubscribe sends an HTTPS POST to `url` with the form body `List-Unsubscribe=One-Click`; your endpoint records the unsubscribe. Every recipient of the message gets the same `url`, so send one message per recipient when the URL identifies who to unsubscribe. The `headers` map refuses both header names, so this field is the only way to set them, and the headers it adds count toward the 25 entries `headers` may hold. A field whose rendered `List-Unsubscribe` would pass 980 characters is refused. Not accepted on a repeating send.",
|
|
47222
|
+
"properties": {
|
|
47223
|
+
"url": {
|
|
47224
|
+
"type": "string",
|
|
47225
|
+
"minLength": 1,
|
|
47226
|
+
"maxLength": 700,
|
|
47227
|
+
"pattern": "^[Hh][Tt][Tt][Pp][Ss]://(?:[A-Za-z0-9\\-._~:/?#\\[\\]@!$&'()*+;=]|%[0-9A-Fa-f]{2})+$",
|
|
47228
|
+
"description": "Absolute https URL that unsubscribes the recipient, at most 700 characters of URL characters only: printable ASCII with no spaces, double quotes, angle brackets or commas (percent-encode a comma as %2C), `%` only as a percent-encoded byte, `[` and `]` only around an IPv6 address host, a port from 1 to 65535, no `=?` (which mail readers can decode as an encoded word), and no user name or password. The host must be public: not a single-label name, `localhost` or a name under `.localhost`, `.internal`, `.local`, `.home.arpa` or `.localdomain`, or a loopback, link-local, private, shared, reserved, multicast or unspecified IP address, including an IPv6 address that embeds one. The scheme is written in lower case."
|
|
47229
|
+
},
|
|
47230
|
+
"one_click": {
|
|
47231
|
+
"type": "boolean",
|
|
47232
|
+
"default": true,
|
|
47233
|
+
"description": "Whether to also write `List-Unsubscribe-Post: List-Unsubscribe=One-Click`, which tells the receiver it may unsubscribe with a single POST to `url`. Set false when `url` needs the recipient to open a page and confirm."
|
|
47234
|
+
},
|
|
47235
|
+
"mailto": {
|
|
47236
|
+
"type": "string",
|
|
47237
|
+
"minLength": 3,
|
|
47238
|
+
"maxLength": 254,
|
|
47239
|
+
"pattern": "^[A-Za-z0-9!$'*+=_~-]+(?:\\.[A-Za-z0-9!$'*+=_~-]+)*@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$",
|
|
47240
|
+
"description": "An address to also offer as a `mailto:` unsubscribe, written after `url`. The address alone, without the `mailto:` prefix: at most 64 letters, digits and `.!$'*+=_~-` before the `@`, and a dotted domain after it. An `=` is written as `%3D` in the header."
|
|
47241
|
+
}
|
|
47242
|
+
}
|
|
47243
|
+
},
|
|
45779
47244
|
"headers": {
|
|
45780
47245
|
"type": "object",
|
|
45781
47246
|
"maxProperties": 25,
|
|
@@ -46937,6 +48402,33 @@ const operationManifest = [
|
|
|
46937
48402
|
}
|
|
46938
48403
|
}
|
|
46939
48404
|
},
|
|
48405
|
+
"unsubscribe": {
|
|
48406
|
+
"type": "object",
|
|
48407
|
+
"additionalProperties": false,
|
|
48408
|
+
"required": ["url"],
|
|
48409
|
+
"description": "One-click unsubscribe for the message. Primitive writes a `List-Unsubscribe` header naming `url` (and `mailto` when given) and, unless `one_click` is false, `List-Unsubscribe-Post: List-Unsubscribe=One-Click` (RFC 8058), and DKIM-signs both. A receiver that offers one-click unsubscribe sends an HTTPS POST to `url` with the form body `List-Unsubscribe=One-Click`; your endpoint records the unsubscribe. Every recipient of the message gets the same `url`, so send one message per recipient when the URL identifies who to unsubscribe. The `headers` map refuses both header names, so this field is the only way to set them, and the headers it adds count toward the 25 entries `headers` may hold. A field whose rendered `List-Unsubscribe` would pass 980 characters is refused. Not accepted on a repeating send.",
|
|
48410
|
+
"properties": {
|
|
48411
|
+
"url": {
|
|
48412
|
+
"type": "string",
|
|
48413
|
+
"minLength": 1,
|
|
48414
|
+
"maxLength": 700,
|
|
48415
|
+
"pattern": "^[Hh][Tt][Tt][Pp][Ss]://(?:[A-Za-z0-9\\-._~:/?#\\[\\]@!$&'()*+;=]|%[0-9A-Fa-f]{2})+$",
|
|
48416
|
+
"description": "Absolute https URL that unsubscribes the recipient, at most 700 characters of URL characters only: printable ASCII with no spaces, double quotes, angle brackets or commas (percent-encode a comma as %2C), `%` only as a percent-encoded byte, `[` and `]` only around an IPv6 address host, a port from 1 to 65535, no `=?` (which mail readers can decode as an encoded word), and no user name or password. The host must be public: not a single-label name, `localhost` or a name under `.localhost`, `.internal`, `.local`, `.home.arpa` or `.localdomain`, or a loopback, link-local, private, shared, reserved, multicast or unspecified IP address, including an IPv6 address that embeds one. The scheme is written in lower case."
|
|
48417
|
+
},
|
|
48418
|
+
"one_click": {
|
|
48419
|
+
"type": "boolean",
|
|
48420
|
+
"default": true,
|
|
48421
|
+
"description": "Whether to also write `List-Unsubscribe-Post: List-Unsubscribe=One-Click`, which tells the receiver it may unsubscribe with a single POST to `url`. Set false when `url` needs the recipient to open a page and confirm."
|
|
48422
|
+
},
|
|
48423
|
+
"mailto": {
|
|
48424
|
+
"type": "string",
|
|
48425
|
+
"minLength": 3,
|
|
48426
|
+
"maxLength": 254,
|
|
48427
|
+
"pattern": "^[A-Za-z0-9!$'*+=_~-]+(?:\\.[A-Za-z0-9!$'*+=_~-]+)*@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$",
|
|
48428
|
+
"description": "An address to also offer as a `mailto:` unsubscribe, written after `url`. The address alone, without the `mailto:` prefix: at most 64 letters, digits and `.!$'*+=_~-` before the `@`, and a dotted domain after it. An `=` is written as `%3D` in the header."
|
|
48429
|
+
}
|
|
48430
|
+
}
|
|
48431
|
+
},
|
|
46940
48432
|
"headers": {
|
|
46941
48433
|
"type": "object",
|
|
46942
48434
|
"maxProperties": 25,
|
|
@@ -47417,6 +48909,33 @@ const operationManifest = [
|
|
|
47417
48909
|
}
|
|
47418
48910
|
}
|
|
47419
48911
|
},
|
|
48912
|
+
"unsubscribe": {
|
|
48913
|
+
"type": "object",
|
|
48914
|
+
"additionalProperties": false,
|
|
48915
|
+
"required": ["url"],
|
|
48916
|
+
"description": "One-click unsubscribe for the message. Primitive writes a `List-Unsubscribe` header naming `url` (and `mailto` when given) and, unless `one_click` is false, `List-Unsubscribe-Post: List-Unsubscribe=One-Click` (RFC 8058), and DKIM-signs both. A receiver that offers one-click unsubscribe sends an HTTPS POST to `url` with the form body `List-Unsubscribe=One-Click`; your endpoint records the unsubscribe. Every recipient of the message gets the same `url`, so send one message per recipient when the URL identifies who to unsubscribe. The `headers` map refuses both header names, so this field is the only way to set them, and the headers it adds count toward the 25 entries `headers` may hold. A field whose rendered `List-Unsubscribe` would pass 980 characters is refused. Not accepted on a repeating send.",
|
|
48917
|
+
"properties": {
|
|
48918
|
+
"url": {
|
|
48919
|
+
"type": "string",
|
|
48920
|
+
"minLength": 1,
|
|
48921
|
+
"maxLength": 700,
|
|
48922
|
+
"pattern": "^[Hh][Tt][Tt][Pp][Ss]://(?:[A-Za-z0-9\\-._~:/?#\\[\\]@!$&'()*+;=]|%[0-9A-Fa-f]{2})+$",
|
|
48923
|
+
"description": "Absolute https URL that unsubscribes the recipient, at most 700 characters of URL characters only: printable ASCII with no spaces, double quotes, angle brackets or commas (percent-encode a comma as %2C), `%` only as a percent-encoded byte, `[` and `]` only around an IPv6 address host, a port from 1 to 65535, no `=?` (which mail readers can decode as an encoded word), and no user name or password. The host must be public: not a single-label name, `localhost` or a name under `.localhost`, `.internal`, `.local`, `.home.arpa` or `.localdomain`, or a loopback, link-local, private, shared, reserved, multicast or unspecified IP address, including an IPv6 address that embeds one. The scheme is written in lower case."
|
|
48924
|
+
},
|
|
48925
|
+
"one_click": {
|
|
48926
|
+
"type": "boolean",
|
|
48927
|
+
"default": true,
|
|
48928
|
+
"description": "Whether to also write `List-Unsubscribe-Post: List-Unsubscribe=One-Click`, which tells the receiver it may unsubscribe with a single POST to `url`. Set false when `url` needs the recipient to open a page and confirm."
|
|
48929
|
+
},
|
|
48930
|
+
"mailto": {
|
|
48931
|
+
"type": "string",
|
|
48932
|
+
"minLength": 3,
|
|
48933
|
+
"maxLength": 254,
|
|
48934
|
+
"pattern": "^[A-Za-z0-9!$'*+=_~-]+(?:\\.[A-Za-z0-9!$'*+=_~-]+)*@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$",
|
|
48935
|
+
"description": "An address to also offer as a `mailto:` unsubscribe, written after `url`. The address alone, without the `mailto:` prefix: at most 64 letters, digits and `.!$'*+=_~-` before the `@`, and a dotted domain after it. An `=` is written as `%3D` in the header."
|
|
48936
|
+
}
|
|
48937
|
+
}
|
|
48938
|
+
},
|
|
47420
48939
|
"headers": {
|
|
47421
48940
|
"type": "object",
|
|
47422
48941
|
"maxProperties": 25,
|
|
@@ -50941,6 +52460,48 @@ function deliveryAttemptLines(data) {
|
|
|
50941
52460
|
}
|
|
50942
52461
|
return lines.length > 0 ? [`Attempts (${lines.length}):`, ...lines] : [];
|
|
50943
52462
|
}
|
|
52463
|
+
/**
|
|
52464
|
+
* What an endpoint's DELIVERING column says, from `delivery` and never from
|
|
52465
|
+
* `enabled`: an endpoint can be on and still be sent nothing (its owner's key
|
|
52466
|
+
* revoked, say). A delivery the answer gives is read for any kind. Without
|
|
52467
|
+
* one, a webhook (or an endpoint of no stated kind) shows `unknown`, since it
|
|
52468
|
+
* could not be checked just now or the server does not say, and any other
|
|
52469
|
+
* kind (a Function or pull endpoint, which has no delivery) shows `-`.
|
|
52470
|
+
*/
|
|
52471
|
+
function deliveringCell(endpoint) {
|
|
52472
|
+
const delivery = endpoint.delivery;
|
|
52473
|
+
if (isRecord$3(delivery) && typeof delivery.delivering === "boolean") {
|
|
52474
|
+
if (delivery.delivering) return "yes";
|
|
52475
|
+
const codes = Array.isArray(delivery.reasons) ? delivery.reasons.flatMap((reason) => isRecord$3(reason) && typeof reason.code === "string" && reason.code ? [oneLine(reason.code)] : []) : [];
|
|
52476
|
+
return codes.length > 0 ? `no (${codes.join(", ")})` : "no";
|
|
52477
|
+
}
|
|
52478
|
+
return endpoint.kind === void 0 || endpoint.kind === "http" ? "unknown" : "-";
|
|
52479
|
+
}
|
|
52480
|
+
/**
|
|
52481
|
+
* A table of an endpoints list (listEndpoints): each endpoint's id, kind,
|
|
52482
|
+
* whether it is on (ENABLED) and whether it is being sent mail at all
|
|
52483
|
+
* (DELIVERING, from `delivery`), and its name. Nothing for an empty list.
|
|
52484
|
+
*/
|
|
52485
|
+
function endpointDeliveryLines(data) {
|
|
52486
|
+
const rows = Array.isArray(data) ? data.filter(isRecord$3) : [];
|
|
52487
|
+
if (rows.length === 0) return [];
|
|
52488
|
+
const text = (value) => typeof value === "string" && value ? oneLine(value) : "";
|
|
52489
|
+
const table = [[
|
|
52490
|
+
"ID",
|
|
52491
|
+
"KIND",
|
|
52492
|
+
"ENABLED",
|
|
52493
|
+
"DELIVERING",
|
|
52494
|
+
"NAME"
|
|
52495
|
+
], ...rows.map((row) => [
|
|
52496
|
+
text(row.id),
|
|
52497
|
+
text(row.kind),
|
|
52498
|
+
typeof row.enabled === "boolean" ? row.enabled ? "yes" : "no" : "",
|
|
52499
|
+
deliveringCell(row),
|
|
52500
|
+
text(row.name)
|
|
52501
|
+
])];
|
|
52502
|
+
const widths = table[0].map((_, column) => Math.max(...table.map((cells) => (cells[column] ?? "").length)));
|
|
52503
|
+
return table.map((cells) => cells.map((cell, column) => column === cells.length - 1 ? cell : cell.padEnd(widths[column] ?? 0)).join(" ").trimEnd());
|
|
52504
|
+
}
|
|
50944
52505
|
const routeReport = {
|
|
50945
52506
|
flags: {},
|
|
50946
52507
|
report: (data) => ({ lines: routeWarningLines(data) })
|
|
@@ -50951,6 +52512,10 @@ const ANSWER_REPORT_EXTENSIONS = {
|
|
|
50951
52512
|
getDelivery: {
|
|
50952
52513
|
flags: {},
|
|
50953
52514
|
report: (data) => ({ lines: deliveryAttemptLines(data) })
|
|
52515
|
+
},
|
|
52516
|
+
listEndpoints: {
|
|
52517
|
+
flags: {},
|
|
52518
|
+
report: (data) => ({ lines: endpointDeliveryLines(data) })
|
|
50954
52519
|
}
|
|
50955
52520
|
};
|
|
50956
52521
|
// src/oclif/user-grant.ts
|
|
@@ -52064,6 +53629,7 @@ const SAMPLE_EMAIL_KEYS = /* @__PURE__ */ new Set([
|
|
|
52064
53629
|
"subject",
|
|
52065
53630
|
"text",
|
|
52066
53631
|
"attachment_types",
|
|
53632
|
+
"attachment_names",
|
|
52067
53633
|
"automated",
|
|
52068
53634
|
"from_mailing_list",
|
|
52069
53635
|
"spam_score"
|
|
@@ -52072,16 +53638,44 @@ const SAMPLE_TEXT_MAX = 4e3;
|
|
|
52072
53638
|
const SAMPLE_SUBJECT_MAX = 998;
|
|
52073
53639
|
const SAMPLE_LIST_MAX = 10;
|
|
52074
53640
|
/**
|
|
53641
|
+
* The fields of each sample read from a file that this CLI does not know
|
|
53642
|
+
* (`email field "x"`, `sample field "y"`). They are sent as they are: the API
|
|
53643
|
+
* validates samples itself, so a field it added after this CLI was built is
|
|
53644
|
+
* not refused here. Said once per file, for the samples actually sent
|
|
53645
|
+
* (unknownFieldsNote).
|
|
53646
|
+
*/
|
|
53647
|
+
const UNKNOWN_FIELDS = /* @__PURE__ */ new WeakMap();
|
|
53648
|
+
/**
|
|
53649
|
+
* A field name from a file or an answer, quoted and safe to print: JSON
|
|
53650
|
+
* escapes control characters, and a long name is cut.
|
|
53651
|
+
*/
|
|
53652
|
+
function shownKey(key) {
|
|
53653
|
+
return JSON.stringify(key.length > 60 ? `${key.slice(0, 57)}...` : key).replace(/[\u007f-\u009f]/g, "?");
|
|
53654
|
+
}
|
|
53655
|
+
/**
|
|
53656
|
+
* One line naming the fields this CLI does not know in the samples sent, with
|
|
53657
|
+
* the numbers of the samples in the file that carry each; null when none do.
|
|
53658
|
+
*/
|
|
53659
|
+
function unknownFieldsNote(source, sent, all) {
|
|
53660
|
+
const carriers = /* @__PURE__ */ new Map();
|
|
53661
|
+
for (const sample of sent) {
|
|
53662
|
+
const number = all.indexOf(sample) + 1;
|
|
53663
|
+
for (const field of UNKNOWN_FIELDS.get(sample) ?? []) carriers.set(field, [...carriers.get(field) ?? [], number]);
|
|
53664
|
+
}
|
|
53665
|
+
if (carriers.size === 0) return null;
|
|
53666
|
+
return `${source} has fields this CLI does not know, which it does not refuse but leaves for the API to judge (if the API refuses one, take it out): ${[...carriers].map(([field, numbers]) => `${field} (sample${numbers.length === 1 ? "" : "s"} ${numbers.join(", ")})`).join(", ")}.`;
|
|
53667
|
+
}
|
|
53668
|
+
/**
|
|
52075
53669
|
* Refuse, naming the sample and the field, a made-up email the API would
|
|
52076
|
-
* refuse to keep: the fields it takes
|
|
52077
|
-
*
|
|
53670
|
+
* refuse to keep: the bounds of the fields it takes. Returns the fields this
|
|
53671
|
+
* CLI does not know, which are passed on. The API checks the rest (address
|
|
53672
|
+
* forms, a NUL).
|
|
52078
53673
|
*/
|
|
52079
53674
|
function checkSampleEmail(email, at) {
|
|
52080
53675
|
const fail = (what) => {
|
|
52081
53676
|
throw usageError$2(`${at}: email ${what}.`);
|
|
52082
53677
|
};
|
|
52083
|
-
const unknown = Object.keys(email).
|
|
52084
|
-
if (unknown !== void 0) fail(`takes no "${unknown}" (it takes ${[...SAMPLE_EMAIL_KEYS].join(", ")})`);
|
|
53678
|
+
const unknown = Object.keys(email).filter((key) => !SAMPLE_EMAIL_KEYS.has(key)).map((key) => `email field ${shownKey(key)}`);
|
|
52085
53679
|
if (!isRecord$1(email.from) || typeof email.from.address !== "string") fail("needs from.address");
|
|
52086
53680
|
const list = (key, min) => {
|
|
52087
53681
|
const value = email[key];
|
|
@@ -52091,10 +53685,15 @@ function checkSampleEmail(email, at) {
|
|
|
52091
53685
|
list("to", 1);
|
|
52092
53686
|
list("cc", 0);
|
|
52093
53687
|
list("attachment_types", 0);
|
|
53688
|
+
list("attachment_names", 0);
|
|
53689
|
+
const types = email.attachment_types;
|
|
53690
|
+
const names = email.attachment_names;
|
|
53691
|
+
if (Array.isArray(types) && Array.isArray(names) && types.length > 0 && names.length > 0 && types.length !== names.length) fail("attachment_names pairs with attachment_types by position, so give the same number of each");
|
|
52094
53692
|
if (email.subject !== void 0 && (typeof email.subject !== "string" || email.subject.length > SAMPLE_SUBJECT_MAX)) fail(`subject must be a string of at most ${SAMPLE_SUBJECT_MAX} characters`);
|
|
52095
53693
|
if (typeof email.text !== "string" || email.text.length === 0 || email.text.length > SAMPLE_TEXT_MAX) fail(`text must be 1 to ${SAMPLE_TEXT_MAX} characters`);
|
|
52096
53694
|
for (const key of ["automated", "from_mailing_list"]) if (email[key] !== void 0 && typeof email[key] !== "boolean") fail(`${key} must be true or false`);
|
|
52097
53695
|
if (email.spam_score !== void 0 && (typeof email.spam_score !== "number" || !Number.isFinite(email.spam_score))) fail("spam_score must be a number");
|
|
53696
|
+
return unknown;
|
|
52098
53697
|
}
|
|
52099
53698
|
/** The keys a sample may carry: a saved one's id and time are taken and ignored. */
|
|
52100
53699
|
const SAMPLE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -52117,7 +53716,8 @@ function samplesFromJson(value, source) {
|
|
|
52117
53716
|
const samples = lookAlikeSamples(data);
|
|
52118
53717
|
if (samples.length === 0) throw usageError$2(`${source} is a generate-look-alikes answer with no look-alikes in it.`);
|
|
52119
53718
|
samples.forEach((sample, index) => {
|
|
52120
|
-
checkSampleEmail(sample.email, `${source}, look-alike ${index + 1}`);
|
|
53719
|
+
const unknown = checkSampleEmail(sample.email, `${source}, look-alike ${index + 1}`);
|
|
53720
|
+
if (unknown.length > 0) UNKNOWN_FIELDS.set(sample, unknown);
|
|
52121
53721
|
});
|
|
52122
53722
|
return samples;
|
|
52123
53723
|
}
|
|
@@ -52125,22 +53725,25 @@ function samplesFromJson(value, source) {
|
|
|
52125
53725
|
return data.map((item, index) => {
|
|
52126
53726
|
const at = `${source}, sample ${index + 1}`;
|
|
52127
53727
|
if (!isRecord$1(item)) throw usageError$2(`${at} is not an object.`);
|
|
52128
|
-
const unknown = Object.keys(item).
|
|
52129
|
-
if (unknown !== void 0) throw usageError$2(`${at}: "${unknown}" is not a sample field; a sample takes expected, label and email.`);
|
|
53728
|
+
const unknown = Object.keys(item).filter((key) => !SAMPLE_KEYS.has(key));
|
|
52130
53729
|
if (item.expected !== "match" && item.expected !== "no_match") throw usageError$2(`${at}: expected must be "match" or "no_match".`);
|
|
52131
53730
|
if (!isRecord$1(item.email)) throw usageError$2(`${at}: email must be an object, as test-email-rule-on-sample takes it.`);
|
|
52132
|
-
checkSampleEmail(item.email, at);
|
|
53731
|
+
const unknownEmail = checkSampleEmail(item.email, at);
|
|
52133
53732
|
const label = item.label;
|
|
52134
53733
|
if (label !== void 0 && label !== null) {
|
|
52135
53734
|
if (typeof label !== "string") throw usageError$2(`${at}: label must be a string.`);
|
|
52136
53735
|
if (label.trim() === "") throw usageError$2(`${at}: label is blank; leave it out or say what the email stands for.`);
|
|
52137
53736
|
if (label.trim().length > SAMPLE_LABEL_MAX) throw usageError$2(`${at}: label is longer than ${SAMPLE_LABEL_MAX} characters.`);
|
|
52138
53737
|
}
|
|
52139
|
-
|
|
53738
|
+
const sample = {
|
|
53739
|
+
...Object.fromEntries(unknown.map((key) => [key, item[key]])),
|
|
52140
53740
|
expected: item.expected,
|
|
52141
53741
|
...label !== void 0 ? { label } : {},
|
|
52142
53742
|
email: item.email
|
|
52143
53743
|
};
|
|
53744
|
+
const fields = [...unknown.map((key) => `sample field ${shownKey(key)}`), ...unknownEmail];
|
|
53745
|
+
if (fields.length > 0) UNKNOWN_FIELDS.set(sample, fields);
|
|
53746
|
+
return sample;
|
|
52144
53747
|
});
|
|
52145
53748
|
}
|
|
52146
53749
|
/**
|
|
@@ -52191,6 +53794,8 @@ function readSamplesFile(path, flag, pick) {
|
|
|
52191
53794
|
const all = samplesFromJson(readJsonFileFlag(path, `--${flag}`), source);
|
|
52192
53795
|
const samples = typeof pick === "string" ? pickSamples(all, pick, source) : all;
|
|
52193
53796
|
if (samples.length > 20) throw usageError$2(`${source} holds ${samples.length} samples, and a rule or a test takes at most 20; take some with --pick.`);
|
|
53797
|
+
const note = unknownFieldsNote(source, samples, all);
|
|
53798
|
+
if (note) process.stderr.write(`${note}\n`);
|
|
52194
53799
|
return samples;
|
|
52195
53800
|
}
|
|
52196
53801
|
/** The one of `names` given as a file path, or null; --pick without one is refused. */
|
|
@@ -52647,7 +54252,9 @@ function answerText(answer) {
|
|
|
52647
54252
|
function conditionLines(summary) {
|
|
52648
54253
|
const conditions = Array.isArray(summary?.conditions) ? summary.conditions : [];
|
|
52649
54254
|
if (conditions.length === 0) return [];
|
|
52650
|
-
|
|
54255
|
+
const held = summary?.conditions_held;
|
|
54256
|
+
const together = typeof held === "number" ? `; together they held on ${held}` : "";
|
|
54257
|
+
return [`Conditions (${summary?.decided ?? 0} decided${together}):`, ...conditions.map((condition) => ` ${condition.index}. ${condition.text}: held on ${condition.held}, failed on ${condition.failed} (the only failure on ${condition.only_failure})`)];
|
|
52651
54258
|
}
|
|
52652
54259
|
function questionLines(summary, results) {
|
|
52653
54260
|
const questions = Array.isArray(summary?.questions) ? summary.questions : [];
|
|
@@ -52991,6 +54598,10 @@ function authorLine(author) {
|
|
|
52991
54598
|
if (name || email) return `Author: ${name ?? email}`;
|
|
52992
54599
|
return `Author: user ${author.user_id} (name and email not shown to you)`;
|
|
52993
54600
|
}
|
|
54601
|
+
/** A note the server wrote on a rule answer, as a line, or undefined. */
|
|
54602
|
+
function noteLine(note) {
|
|
54603
|
+
return typeof note === "string" && note.trim() ? note.trim() : void 0;
|
|
54604
|
+
}
|
|
52994
54605
|
/** The stderr report of a rule written by create-email-rule or update-email-rule. */
|
|
52995
54606
|
function writtenEmailRuleReport(data, request) {
|
|
52996
54607
|
if (!isRecord(data)) return { lines: [] };
|
|
@@ -53005,11 +54616,17 @@ function writtenEmailRuleReport(data, request) {
|
|
|
53005
54616
|
if (restored) lines.push(restored);
|
|
53006
54617
|
const reach = affectsLine(rule.affects);
|
|
53007
54618
|
if (reach) lines.push(reach);
|
|
54619
|
+
for (const note of [rule.share_notice, rule.notice]) {
|
|
54620
|
+
const line = noteLine(note);
|
|
54621
|
+
if (line) lines.push(line);
|
|
54622
|
+
}
|
|
53008
54623
|
const sentExpectations = sentExpectationsIn(request.body);
|
|
53009
54624
|
const name = writtenSampleNamer(request.body, request.flags, rule.expectation_samples);
|
|
53010
54625
|
const checked = expectationsCheckLine(rule.expectations_check, ruleId, name);
|
|
53011
54626
|
if (checked) lines.push(checked);
|
|
53012
54627
|
else if (sentExpectations) lines.push(`Expectations were not checked on this write. Test them with \`primitive email-rules test-email-rule --rule-id ${ruleId}\`.`);
|
|
54628
|
+
const objections = noteLine(rule.objection_notice);
|
|
54629
|
+
if (objections) lines.push(objections);
|
|
53013
54630
|
if (request.flags?.["fail-on-expectations"] !== true) return { lines };
|
|
53014
54631
|
return {
|
|
53015
54632
|
lines,
|
|
@@ -53060,7 +54677,9 @@ function deleteEmailRuleReport(data, request) {
|
|
|
53060
54677
|
const answer = data;
|
|
53061
54678
|
const lines = [];
|
|
53062
54679
|
const ended = Array.isArray(answer.ended_shares) ? answer.ended_shares.length : 0;
|
|
53063
|
-
|
|
54680
|
+
const shareNotice = noteLine(answer.share_notice);
|
|
54681
|
+
if (shareNotice) lines.push(shareNotice);
|
|
54682
|
+
else if (ended > 0) lines.push(`Ended ${ended === 1 ? "1 share" : `${ended} shares`} of this rule (end_reason rule_deleted). ${ended === 1 ? "It keeps its record" : "Each keeps its record"}.`);
|
|
53064
54683
|
const keys = Array.isArray(answer.keys) ? answer.keys : [];
|
|
53065
54684
|
const others = typeof answer.other_keys === "number" && answer.other_keys > 0 ? answer.other_keys : 0;
|
|
53066
54685
|
const ruleId = typeof request.path.id === "string" ? request.path.id : "<rule-id>";
|
|
@@ -53097,16 +54716,37 @@ function readAgain(id) {
|
|
|
53097
54716
|
return `Read it again with \`primitive email-rules get-email-rule ${id}\` and send the write again`;
|
|
53098
54717
|
}
|
|
53099
54718
|
/**
|
|
54719
|
+
* Who reads an active rule, from a refusal's details.read_by: the server
|
|
54720
|
+
* sends it when it checked the write against the rule's expectations because
|
|
54721
|
+
* API keys or webhooks read the rule, whether or not the write asked.
|
|
54722
|
+
* Undefined without it.
|
|
54723
|
+
*/
|
|
54724
|
+
function readByText(details) {
|
|
54725
|
+
const readBy = details.read_by;
|
|
54726
|
+
if (!isRecord(readBy)) return void 0;
|
|
54727
|
+
const { keys, webhooks } = readBy;
|
|
54728
|
+
return typeof keys === "number" && typeof webhooks === "number" ? `${plural$1(keys, "API key", "API keys")} and ${plural$1(webhooks, "webhook", "webhooks")} read what it grants` : "API keys or webhooks may read what it grants (they could not be counted in time)";
|
|
54729
|
+
}
|
|
54730
|
+
/** How to save a write the default check refused, without the check. */
|
|
54731
|
+
function saveUncheckedText(flags) {
|
|
54732
|
+
return flags?.["fail-on-expectations"] === true ? `send it again without --${FAIL_ON_EXPECTATIONS_FLAG} and with --no-if-expectations-pass` : "send it again with --no-if-expectations-pass";
|
|
54733
|
+
}
|
|
54734
|
+
/**
|
|
53100
54735
|
* The hint for update-email-rule's refusals: an email_rule_conflict by its
|
|
53101
54736
|
* details.reason (version_moved, revision_moved, expectations_moved,
|
|
53102
|
-
* rule_changed), and the expectations guard's
|
|
53103
|
-
* expectations_undecided, expectations_unreadable and
|
|
53104
|
-
*
|
|
54737
|
+
* rule_changed, readers_changed), and the expectations guard's
|
|
54738
|
+
* expectations_failed, expectations_undecided, expectations_unreadable and
|
|
54739
|
+
* no_expectations. The guard runs when the write sends if_expectations_pass,
|
|
54740
|
+
* and by default (details.read_by) when it changes what an active rule that
|
|
54741
|
+
* API keys or webhooks read grants. Nothing was saved in any of them.
|
|
53105
54742
|
*/
|
|
53106
54743
|
function updateEmailRuleErrorHint(code, payload, ruleId, body, flags) {
|
|
53107
54744
|
const id = typeof ruleId === "string" && ruleId ? ruleId : "<rule-id>";
|
|
53108
54745
|
const details = errorDetails(payload);
|
|
53109
54746
|
const guarded = isRecord(body) && body.if_expectations_pass === true;
|
|
54747
|
+
const readBy = readByText(details);
|
|
54748
|
+
const judged = readBy ? "was judged against its expectations before saving, as a write that changes what an active rule grants is by default while API keys or webhooks read it, and nothing was saved" : "was judged against its expectations before saving (if_expectations_pass), and nothing was saved";
|
|
54749
|
+
const unchecked = readBy ? ` The rule is active and ${readBy}; to save the write without the check, ${saveUncheckedText(flags)}.` : "";
|
|
53110
54750
|
if (code === "email_rule_conflict") switch (details.reason) {
|
|
53111
54751
|
case "version_moved": return versionMovedHint(payload, ruleId);
|
|
53112
54752
|
case "revision_moved": {
|
|
@@ -53115,6 +54755,7 @@ function updateEmailRuleErrorHint(code, payload, ruleId, body, flags) {
|
|
|
53115
54755
|
}
|
|
53116
54756
|
case "expectations_moved": return `Hint: the rule's saved expectations changed while this write was checked against them, so nothing was saved. ${readAgain(id)}.`;
|
|
53117
54757
|
case "rule_changed": return guarded ? `Hint: the rule changed after this write was judged against its expectations and before it was saved, so saving it would have gone unchecked; nothing was saved. ${readAgain(id)}.` : `Hint: the rule changed while this write was being saved, so nothing was saved. ${readAgain(id)}.`;
|
|
54758
|
+
case "readers_changed": return "Hint: API keys or webhooks started reading this rule while this write was being saved, and saving it would have changed what they receive without checking it against the rule's expectations, so nothing was saved. Send the write again: it is then checked first.";
|
|
53118
54759
|
default: return;
|
|
53119
54760
|
}
|
|
53120
54761
|
if (code === "expectations_failed" || code === "expectations_undecided") {
|
|
@@ -53131,16 +54772,16 @@ function updateEmailRuleErrorHint(code, payload, ruleId, body, flags) {
|
|
|
53131
54772
|
const reason = String(details.reason);
|
|
53132
54773
|
const samplesMayStay = undecidedSamplesMayStay(undecidedSamples.length, reason);
|
|
53133
54774
|
const byReason = reason !== "none" && Object.hasOwn(UNDECIDED_NEXT_STEP, reason) ? UNDECIDED_NEXT_STEP[reason] : UNDECIDED_NEXT_STEP.none;
|
|
53134
|
-
return `Hint: the rule, as this write would leave it,
|
|
54775
|
+
return `Hint: the rule, as this write would leave it, ${judged}.${which}${code === "expectations_failed" ? "" : samplesMayStay ? `${undecided.length > 0 ? ` ${byReason}` : ""} ${UNDECIDED_SAMPLES_NEXT_STEP} ${refusedSampleTest(body, id)}` : ` ${byReason}`}${unchecked} The command exits ${updateEmailRuleErrorExitCode(payload) ?? 1}.`;
|
|
53135
54776
|
}
|
|
53136
54777
|
if (code === "expectations_unreadable") {
|
|
53137
54778
|
const unreadable = Array.isArray(details.unreadable) ? details.unreadable.filter((entry) => entry !== null && entry !== void 0 && entry !== "").map(String) : [];
|
|
53138
54779
|
const one = unreadable.length === 1;
|
|
53139
54780
|
const named = unreadable.length > 0 ? `: ${unreadable.join(", ")}` : "";
|
|
53140
54781
|
const them = one ? "it" : "them";
|
|
53141
|
-
return `Hint: the rule, as this write would leave it,
|
|
54782
|
+
return `Hint: the rule, as this write would leave it, ${judged}. ${one ? "An expectation names an email" : "Expectations name emails"} this rule cannot read (deleted, or outside its scope or its author's mail)${named}. Sending the write again will not decide ${them}: send --expectations-file without ${them}, or an evaluation_scope that reads ${them}.${unchecked} The command exits 1.`;
|
|
53142
54783
|
}
|
|
53143
|
-
if (code === "no_expectations") return "Hint: nothing was saved. Give the rule expectations with --expectations-file or made-up emails with --expectation-samples-file or --add-expectation-samples-file (in this write or before it), or send the write without if_expectations_pass (--fail-on-expectations or --if-expectations-pass).";
|
|
54784
|
+
if (code === "no_expectations") return readBy ? `Hint: nothing was saved: this write removes the rule's expectations, and the rule is active and ${readBy}, so a write that changes what it grants is checked against them first. Keep some with --expectations-file, --expectation-samples-file or --add-expectation-samples-file, or, to save the write without the check, ${saveUncheckedText(flags)}.` : "Hint: nothing was saved. Give the rule expectations with --expectations-file or made-up emails with --expectation-samples-file or --add-expectation-samples-file (in this write or before it), or send the write without if_expectations_pass (--fail-on-expectations or --if-expectations-pass).";
|
|
53144
54785
|
}
|
|
53145
54786
|
/** The reasons a guard's undecided judgment can be decided by sending the write again. */
|
|
53146
54787
|
const RETRYABLE_REASONS = /* @__PURE__ */ new Set([
|
|
@@ -53197,12 +54838,20 @@ function updateEmailRuleErrorExitCode(payload) {
|
|
|
53197
54838
|
function undecidedSamplesMayStay(count, reason) {
|
|
53198
54839
|
return count > 0 && !RETRYABLE_REASONS.has(reason) && reason !== "author_unresolvable";
|
|
53199
54840
|
}
|
|
54841
|
+
/** Where compile counted breadth, by the evaluation_scope it was sent. */
|
|
54842
|
+
const BREADTH_SCOPE = {
|
|
54843
|
+
own_mailboxes: "in your own mailboxes",
|
|
54844
|
+
author: "in all the mail you can read",
|
|
54845
|
+
selected: "in the inboxes and domains the selected scope names"
|
|
54846
|
+
};
|
|
53200
54847
|
/** The stderr report of compile-email-rule: how many recent emails it holds for. */
|
|
53201
|
-
function compileEmailRuleReport(data) {
|
|
54848
|
+
function compileEmailRuleReport(data, request) {
|
|
53202
54849
|
if (!isRecord(data)) return { lines: [] };
|
|
53203
54850
|
const lines = (Array.isArray(data.warnings) ? data.warnings : []).filter((warning) => typeof warning === "string" && warning.trim() !== "").map((warning) => `Warning: ${warning.trim()}`);
|
|
53204
54851
|
const breadth = data.breadth;
|
|
53205
|
-
|
|
54852
|
+
const sent = isRecord(request?.body) && typeof request.body.evaluation_scope === "string" ? request.body.evaluation_scope : void 0;
|
|
54853
|
+
const where = sent === void 0 ? "in your own mailboxes, the default; pass --evaluation-scope to count over the scope you will save it with" : BREADTH_SCOPE[sent] ?? `in evaluation_scope ${sent}`;
|
|
54854
|
+
if (isRecord(breadth) && typeof breadth.checked === "number" && typeof breadth.matched === "number") lines.push(`Breadth: its conditions hold for ${breadth.matched} of ${plural$1(breadth.checked, "recent email", "recent emails")} checked ${where}.`);
|
|
53206
54855
|
return { lines };
|
|
53207
54856
|
}
|
|
53208
54857
|
/** The stderr report of get-email-rule: who wrote it, and its revision. */
|
|
@@ -53214,6 +54863,8 @@ function getEmailRuleReport(data) {
|
|
|
53214
54863
|
const protection = protectionLine(data);
|
|
53215
54864
|
if (protection) lines.push(protection);
|
|
53216
54865
|
if (typeof data.revision === "number") lines.push(`Revision ${data.revision}: pass --if-revision ${data.revision} to update-email-rule so a change made since is never replaced unseen.`);
|
|
54866
|
+
const objections = noteLine(data.objection_notice);
|
|
54867
|
+
if (objections) lines.push(objections);
|
|
53217
54868
|
return { lines };
|
|
53218
54869
|
}
|
|
53219
54870
|
/** The stderr report of list-email-rules: the protective rules that protect nothing yet, or less than they seem. */
|
|
@@ -53233,9 +54884,11 @@ function listEmailRulesReport(data) {
|
|
|
53233
54884
|
/** create-email-rule's --fail-on-expectations: the exit code follows the check made after saving. */
|
|
53234
54885
|
const FAIL_ON_EXPECTATIONS_HELP = "Exit 1 when an expectation in the answer's expectations_check failed, and 3 when none failed but one is undecided or the expectations this write sent were not checked (test the rule to decide). A create does not judge made-up emails, so with some it exits 3. Without it the command exits 0 whatever the check says.";
|
|
53235
54886
|
/** update-email-rule's --fail-on-expectations: the server refuses the write. */
|
|
53236
|
-
const UPDATE_FAIL_ON_EXPECTATIONS_HELP = "Refuse the write unless the rule, as this write would leave it, passes its expectations. It sends if_expectations_pass (over any in --body-file or --raw-body), so the server judges a new version, a restored one, a new scope or turning the rule active before saving, on its emails by id and its made-up emails, and saves nothing when one failed (exit 1), one names an email the rule cannot read (exit 1, since sending again never decides it), one is undecided (exit 3, or 1 when the rule cannot run as its author or a made-up email is undecided for no reason the answer gives) or the rule has none (exit 1). It can take as long as a test of the rule; the command waits for it. Judging needs a credential that reads the mail's content. A write the server does not judge (one changing only expectations, say) is saved, and the exit code then follows the answer's expectations_check, as on create. With --json, a refused write's document holds the API's error alone; a saved write's holds the rule.";
|
|
54887
|
+
const UPDATE_FAIL_ON_EXPECTATIONS_HELP = "Refuse the write unless the rule, as this write would leave it, passes its expectations. It sends if_expectations_pass (over any in --body-file or --raw-body), so the server judges a new version, a restored one, a new scope or turning the rule active before saving, on its emails by id and its made-up emails, and saves nothing when one failed (exit 1), one names an email the rule cannot read (exit 1, since sending again never decides it), one is undecided (exit 3, or 1 when the rule cannot run as its author or a made-up email is undecided for no reason the answer gives) or the rule has none (exit 1). It can take as long as a test of the rule; the command waits for it. Judging needs a credential that reads the mail's content. A write the server does not judge (one changing only expectations, say) is saved, and the exit code then follows the answer's expectations_check, as on create. Without it, the server still judges, and refuses the same way, a write that saves a version or changes the scope of an active rule that API keys or webhooks read and that has expectations (the refusal's details.read_by counts them), unless --no-if-expectations-pass is sent. With --json, a refused write's document holds the API's error alone; a saved write's holds the rule.";
|
|
54888
|
+
/** When update-email-rule judges the made-up emails a samples flag sets. */
|
|
54889
|
+
const UPDATE_JUDGES_SAMPLES = `The write judges them before saving with --${FAIL_ON_EXPECTATIONS_FLAG}, when it saves a version or turns the rule active, and without it when it saves a version or changes the scope of an active rule that API keys or webhooks read, unless --no-if-expectations-pass is sent.`;
|
|
53237
54890
|
/** What a samples file flag reads. */
|
|
53238
|
-
const SAMPLES_FILE_SHAPE = "A JSON file of made-up emails the rule must match or not: an array such as [{\"expected\": \"no_match\", \"label\": \"a personal bill\", \"email\": {...}}], with email as test-email-rule-on-sample takes it (text up to 4,000 characters, at most 10 each of to, cc and
|
|
54891
|
+
const SAMPLES_FILE_SHAPE = "A JSON file of made-up emails the rule must match or not: an array such as [{\"expected\": \"no_match\", \"label\": \"a personal bill\", \"email\": {...}}], with email as test-email-rule-on-sample takes it (text up to 4,000 characters, at most 10 each of to, cc, attachment_types and attachment_names), like the one generate-look-alikes --samples-file writes, or a generate-look-alikes answer saved as it printed it.";
|
|
53239
54892
|
const EXPECTATION_FLAG_NOTE = "Replaces any expect in --body-file or --raw-body. The answer reports them in expectations (passed, counts, results) and the exit code follows it; see --help-full.";
|
|
53240
54893
|
/**
|
|
53241
54894
|
* update-email-rule's --fail-on-expectations sends if_expectations_pass, over
|
|
@@ -53313,11 +54966,11 @@ const EMAIL_RULE_OPERATION_EXTENSIONS = {
|
|
|
53313
54966
|
flags: {
|
|
53314
54967
|
"expectations-file": Flags.string({ description: "A JSON file holding the emails the rule must match and must not, such as {\"match\": [\"<email-id>\"], \"no_match\": [\"<email-id>\"]}, replacing its saved expectations; a file holding null removes them. Sets expectations, over any in --body-file or --raw-body; the answer judges them in expectations_check (passed, decided, failed, undecided); the report test-email-rule answers with is named expectations instead." }),
|
|
53315
54968
|
[SAMPLES_FILE_FLAG]: Flags.string({
|
|
53316
|
-
description: `${SAMPLES_FILE_SHAPE} They replace the rule's saved ones, and a file holding [] removes them. Sets expectation_samples, over any in --body-file or --raw-body. Not with --${ADD_SAMPLES_FILE_FLAG}.
|
|
54969
|
+
description: `${SAMPLES_FILE_SHAPE} They replace the rule's saved ones, and a file holding [] removes them. Sets expectation_samples, over any in --body-file or --raw-body. Not with --${ADD_SAMPLES_FILE_FLAG}. ${UPDATE_JUDGES_SAMPLES}`,
|
|
53317
54970
|
exclusive: [ADD_SAMPLES_FILE_FLAG]
|
|
53318
54971
|
}),
|
|
53319
54972
|
[ADD_SAMPLES_FILE_FLAG]: Flags.string({
|
|
53320
|
-
description: `${SAMPLES_FILE_SHAPE} They are added to the rule's saved ones, 20 at most in all. Sets add_expectation_samples, over any in --body-file or --raw-body. Not with --${SAMPLES_FILE_FLAG}.
|
|
54973
|
+
description: `${SAMPLES_FILE_SHAPE} They are added to the rule's saved ones, 20 at most in all. Sets add_expectation_samples, over any in --body-file or --raw-body. Not with --${SAMPLES_FILE_FLAG}. ${UPDATE_JUDGES_SAMPLES}`,
|
|
53321
54974
|
exclusive: [SAMPLES_FILE_FLAG]
|
|
53322
54975
|
}),
|
|
53323
54976
|
[PICK_FLAG]: Flags.string({ description: pickFlagHelp([SAMPLES_FILE_FLAG, ADD_SAMPLES_FILE_FLAG]) }),
|
|
@@ -53363,7 +55016,9 @@ const EMAIL_RULE_OPERATION_EXTENSIONS = {
|
|
|
53363
55016
|
bodyProperties: ["expectation_samples"]
|
|
53364
55017
|
},
|
|
53365
55018
|
compileEmailRule: {
|
|
53366
|
-
flags:
|
|
55019
|
+
flags: scopeSelectionFlags(),
|
|
55020
|
+
bodyFields: scopeSelectionBodyFields,
|
|
55021
|
+
bodyProperties: ["scope_selection"],
|
|
53367
55022
|
report: compileEmailRuleReport
|
|
53368
55023
|
},
|
|
53369
55024
|
endEmailRuleShare: {
|
|
@@ -53638,7 +55293,7 @@ function unknownEventTypes(eventTypes) {
|
|
|
53638
55293
|
function unknownEventTypesWarning(unknown) {
|
|
53639
55294
|
return `Warning: ${unknown.join(", ")} ${unknown.length === 1 ? "is" : "are"} not an event type this CLI knows. Subscriptions match exact names, so a misspelled name receives nothing. Continuing; newer event types may not be known to this CLI yet.\n`;
|
|
53640
55295
|
}
|
|
53641
|
-
function isPlainObject(value) {
|
|
55296
|
+
function isPlainObject$1(value) {
|
|
53642
55297
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
53643
55298
|
}
|
|
53644
55299
|
/**
|
|
@@ -53651,16 +55306,16 @@ async function currentEndpointRules(endpointId, listEndpoints) {
|
|
|
53651
55306
|
if (response.error) throw new EventTypesFlagError("Could not read the endpoint's current rules to keep them. Retry, or pass the full rules with --raw-body.");
|
|
53652
55307
|
const row = (response.data?.data ?? []).find((endpoint) => endpoint.id === endpointId);
|
|
53653
55308
|
if (!row) throw new EventTypesFlagError(`No endpoint ${endpointId} is visible to this credential, so its rules cannot be updated.`);
|
|
53654
|
-
return isPlainObject(row.rules) ? row.rules : {};
|
|
55309
|
+
return isPlainObject$1(row.rules) ? row.rules : {};
|
|
53655
55310
|
}
|
|
53656
55311
|
/**
|
|
53657
55312
|
* Put `eventTypes` in the request body's `rules.event_types`, on top of
|
|
53658
55313
|
* `baseRules` (rules the caller passed in the body win over `baseRules`).
|
|
53659
55314
|
*/
|
|
53660
55315
|
function withEventTypes(body, eventTypes, baseRules = {}) {
|
|
53661
|
-
if (body !== void 0 && !isPlainObject(body)) throw new EventTypesFlagError("--raw-body must be a JSON object when also passing --event-types.");
|
|
55316
|
+
if (body !== void 0 && !isPlainObject$1(body)) throw new EventTypesFlagError("--raw-body must be a JSON object when also passing --event-types.");
|
|
53662
55317
|
const current = body ?? {};
|
|
53663
|
-
if (current.rules !== void 0 && !isPlainObject(current.rules)) throw new EventTypesFlagError("rules in --raw-body must be a JSON object when also passing --event-types.");
|
|
55318
|
+
if (current.rules !== void 0 && !isPlainObject$1(current.rules)) throw new EventTypesFlagError("rules in --raw-body must be a JSON object when also passing --event-types.");
|
|
53664
55319
|
const explicitRules = current.rules ?? {};
|
|
53665
55320
|
return {
|
|
53666
55321
|
...current,
|
|
@@ -53673,7 +55328,115 @@ function withEventTypes(body, eventTypes, baseRules = {}) {
|
|
|
53673
55328
|
}
|
|
53674
55329
|
/** True when the caller already passed `rules` in the request body. */
|
|
53675
55330
|
function bodyHasRules(body) {
|
|
53676
|
-
return isPlainObject(body) && body.rules !== void 0;
|
|
55331
|
+
return isPlainObject$1(body) && body.rules !== void 0;
|
|
55332
|
+
}
|
|
55333
|
+
// src/oclif/endpoint-url-shown.ts
|
|
55334
|
+
/** The commands whose answers carry endpoints, by operation sdkName. */
|
|
55335
|
+
const ENDPOINT_URL_OPERATIONS = /* @__PURE__ */ new Set([
|
|
55336
|
+
"getEndpoint",
|
|
55337
|
+
"listEndpoints",
|
|
55338
|
+
"createEndpoint",
|
|
55339
|
+
"updateEndpoint"
|
|
55340
|
+
]);
|
|
55341
|
+
/** The commands that send a URL, whose value is checked for the placeholder. */
|
|
55342
|
+
const ENDPOINT_URL_WRITE_OPERATIONS = /* @__PURE__ */ new Set(["createEndpoint", "updateEndpoint"]);
|
|
55343
|
+
/** What a hidden query string is replaced with. */
|
|
55344
|
+
const HIDDEN_QUERY = "?... (query hidden)";
|
|
55345
|
+
const SHOW_URL_FLAG_DESCRIPTION = "Print each webhook URL in full, its query string included. Without it the query string is shown as ?... (query hidden), with url_query_hidden: true on the endpoint, because it can carry a secret such as a deployment protection bypass token.";
|
|
55346
|
+
/**
|
|
55347
|
+
* Said when an answer had a URL shortened: on stderr without --json, and in
|
|
55348
|
+
* the document's summary with --json --envelope.
|
|
55349
|
+
*/
|
|
55350
|
+
const HIDDEN_QUERY_NOTE = "A webhook URL's query string is hidden, as it can carry a secret. Pass --show-url to print it in full.";
|
|
55351
|
+
/**
|
|
55352
|
+
* The URL with its query string, and anything after it, replaced by
|
|
55353
|
+
* HIDDEN_QUERY; null when it has no query string. A `?` after a `#` is part
|
|
55354
|
+
* of the fragment, not a query.
|
|
55355
|
+
*/
|
|
55356
|
+
function urlWithQueryHidden(url) {
|
|
55357
|
+
const query = url.indexOf("?");
|
|
55358
|
+
if (query < 0) return null;
|
|
55359
|
+
const fragment = url.indexOf("#");
|
|
55360
|
+
if (fragment >= 0 && fragment < query) return null;
|
|
55361
|
+
return `${url.slice(0, query)}${HIDDEN_QUERY}`;
|
|
55362
|
+
}
|
|
55363
|
+
function hideOne(endpoint) {
|
|
55364
|
+
if (endpoint === null || typeof endpoint !== "object" || Array.isArray(endpoint)) return {
|
|
55365
|
+
value: endpoint,
|
|
55366
|
+
hidden: false
|
|
55367
|
+
};
|
|
55368
|
+
const url = endpoint.url;
|
|
55369
|
+
const shown = typeof url === "string" ? urlWithQueryHidden(url) : null;
|
|
55370
|
+
if (shown === null) return {
|
|
55371
|
+
value: endpoint,
|
|
55372
|
+
hidden: false
|
|
55373
|
+
};
|
|
55374
|
+
return {
|
|
55375
|
+
value: {
|
|
55376
|
+
...endpoint,
|
|
55377
|
+
url: shown,
|
|
55378
|
+
url_query_hidden: true
|
|
55379
|
+
},
|
|
55380
|
+
hidden: true
|
|
55381
|
+
};
|
|
55382
|
+
}
|
|
55383
|
+
/**
|
|
55384
|
+
* An answer's data (one endpoint, or a list of them) with each URL's query
|
|
55385
|
+
* string hidden, and whether any was.
|
|
55386
|
+
*/
|
|
55387
|
+
function endpointsWithQueryHidden(data) {
|
|
55388
|
+
if (!Array.isArray(data)) {
|
|
55389
|
+
const one = hideOne(data);
|
|
55390
|
+
return {
|
|
55391
|
+
data: one.value,
|
|
55392
|
+
hidden: one.hidden
|
|
55393
|
+
};
|
|
55394
|
+
}
|
|
55395
|
+
let hidden = false;
|
|
55396
|
+
return {
|
|
55397
|
+
data: data.map((row) => {
|
|
55398
|
+
const one = hideOne(row);
|
|
55399
|
+
hidden ||= one.hidden;
|
|
55400
|
+
return one.value;
|
|
55401
|
+
}),
|
|
55402
|
+
hidden
|
|
55403
|
+
};
|
|
55404
|
+
}
|
|
55405
|
+
function isPlainObject(value) {
|
|
55406
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
55407
|
+
const prototype = Object.getPrototypeOf(value);
|
|
55408
|
+
return prototype === Object.prototype || prototype === null;
|
|
55409
|
+
}
|
|
55410
|
+
/** How deep errorWithQueryHidden looks into an error payload. */
|
|
55411
|
+
const ERROR_DEPTH = 8;
|
|
55412
|
+
/**
|
|
55413
|
+
* An error answer with the query string hidden in every `url` it names, such
|
|
55414
|
+
* as `details.holder.url` on a 409 for a slot another endpoint holds.
|
|
55415
|
+
* Anything that is not a plain object or a list is left as it is.
|
|
55416
|
+
*/
|
|
55417
|
+
function errorWithQueryHidden(payload, depth = 0) {
|
|
55418
|
+
if (depth > ERROR_DEPTH) return payload;
|
|
55419
|
+
if (Array.isArray(payload)) return payload.map((entry) => errorWithQueryHidden(entry, depth + 1));
|
|
55420
|
+
if (!isPlainObject(payload)) return payload;
|
|
55421
|
+
const out = {};
|
|
55422
|
+
for (const [key, value] of Object.entries(payload)) out[key] = errorWithQueryHidden(value, depth + 1);
|
|
55423
|
+
return hideOne(out).value;
|
|
55424
|
+
}
|
|
55425
|
+
/**
|
|
55426
|
+
* A query string as a partial copy of HIDDEN_QUERY leaves it: a terminal's
|
|
55427
|
+
* word selection stops at its first space, after `?...`.
|
|
55428
|
+
*/
|
|
55429
|
+
const HIDDEN_QUERY_START = "?...";
|
|
55430
|
+
/**
|
|
55431
|
+
* The refusal for a request body whose url is a URL as these commands print
|
|
55432
|
+
* it with the query hidden, whole or cut at its first space, so a printed URL
|
|
55433
|
+
* is never written back in place of the real one; null for any other body.
|
|
55434
|
+
*/
|
|
55435
|
+
function hiddenQueryUrlRefusal(body) {
|
|
55436
|
+
if (body === null || typeof body !== "object" || Array.isArray(body)) return null;
|
|
55437
|
+
const url = body.url;
|
|
55438
|
+
if (typeof url !== "string" || !url.includes(HIDDEN_QUERY_START)) return null;
|
|
55439
|
+
return `The url carries ${HIDDEN_QUERY_START}, the start of ${HIDDEN_QUERY}, which is how the endpoint commands print a URL with its query string hidden, not the URL itself. Pass the full URL; \`primitive endpoints get <id> --show-url\` prints a webhook's URL in full.`;
|
|
53677
55440
|
}
|
|
53678
55441
|
// src/oclif/endpoints-test-redirect.ts
|
|
53679
55442
|
async function detectFunctionEndpoint(endpointId, listEndpoints) {
|
|
@@ -55530,7 +57293,7 @@ function savedConnectedProfiles(configDir, exclude) {
|
|
|
55530
57293
|
*/
|
|
55531
57294
|
async function otherProfiles(configDir, session, current) {
|
|
55532
57295
|
if (session) try {
|
|
55533
|
-
const { connectedProfilesForSession } = await import("./machine-session-
|
|
57296
|
+
const { connectedProfilesForSession } = await import("./machine-session-BTkDAKda.js").then((n) => n.s);
|
|
55534
57297
|
return {
|
|
55535
57298
|
inSession: true,
|
|
55536
57299
|
profiles: connectedProfilesForSession(configDir, session, current)
|
|
@@ -55604,6 +57367,96 @@ async function explainPendingMailNotFound(configDir, emailId, write = (line) =>
|
|
|
55604
57367
|
if (outcome.kind === "dropped") write(`Dropped the pending notice for ${id} from profile ${current.profile} after ${outcome.reads} consecutive not_found reads; the email is no longer visible to this profile.\n`);
|
|
55605
57368
|
} catch {}
|
|
55606
57369
|
}
|
|
57370
|
+
// src/oclif/rule-list-defaults.ts
|
|
57371
|
+
/** The box the objection list asks for when --box is not given: objections you made and objections to rules you wrote. */
|
|
57372
|
+
const OBJECTION_BOX_DEFAULT = "mine";
|
|
57373
|
+
/** The box asked for instead when a server refuses OBJECTION_BOX_DEFAULT: objections you made. */
|
|
57374
|
+
const OBJECTION_BOX_FALLBACK = "outgoing";
|
|
57375
|
+
/** --box on `email-rule-oversight list-email-rule-objections`, with the CLI's default. */
|
|
57376
|
+
const OBJECTION_BOX_FLAG = {
|
|
57377
|
+
description: "mine (the default): objections you made and objections to rules you wrote, each saying which (is_objector, is_author). outgoing: only those you made. incoming: only those to rules you wrote. all: every objection you can see. On a server that does not take mine, the CLI lists only those you made by default, and says so.",
|
|
57378
|
+
options: [
|
|
57379
|
+
OBJECTION_BOX_DEFAULT,
|
|
57380
|
+
"outgoing",
|
|
57381
|
+
"incoming",
|
|
57382
|
+
"all"
|
|
57383
|
+
]
|
|
57384
|
+
};
|
|
57385
|
+
/**
|
|
57386
|
+
* The query to send: for the objection list read without --box, the CLI's
|
|
57387
|
+
* default box by name; any other query as it is.
|
|
57388
|
+
*/
|
|
57389
|
+
function withDefaultObjectionBox(sdkName, query) {
|
|
57390
|
+
return sdkName === "listEmailRuleObjections" && query.box === void 0 ? {
|
|
57391
|
+
...query,
|
|
57392
|
+
box: OBJECTION_BOX_DEFAULT
|
|
57393
|
+
} : query;
|
|
57394
|
+
}
|
|
57395
|
+
function errorBody(payload) {
|
|
57396
|
+
if (payload === null || typeof payload !== "object") return {};
|
|
57397
|
+
const inner = payload.error;
|
|
57398
|
+
return inner !== null && typeof inner === "object" ? inner : payload;
|
|
57399
|
+
}
|
|
57400
|
+
/**
|
|
57401
|
+
* True when an API error is a server that predates box=mine refusing the
|
|
57402
|
+
* value: a validation error whose issue for box is an unknown option, not
|
|
57403
|
+
* any other refusal that happens to name box.
|
|
57404
|
+
*/
|
|
57405
|
+
function isObjectionBoxRefused(payload) {
|
|
57406
|
+
const body = errorBody(payload);
|
|
57407
|
+
return body.code === "validation_error" && typeof body.message === "string" && /(^|,\s*)box: Invalid (option|enum value)/.test(body.message);
|
|
57408
|
+
}
|
|
57409
|
+
/** The error line for `--box mine` given to a server that refuses it. */
|
|
57410
|
+
function objectionBoxErrorHint(payload, flags) {
|
|
57411
|
+
if (flags?.box !== "mine" || !isObjectionBoxRefused(payload)) return void 0;
|
|
57412
|
+
return "This server does not take --box mine: use --box outgoing for objections you made, and --box incoming for objections to rules you wrote.";
|
|
57413
|
+
}
|
|
57414
|
+
const widen = (flags) => `add \`${flags.join(" ")}\` to widen it`;
|
|
57415
|
+
/** The objection list's line: what its defaults left out, and how to see more. */
|
|
57416
|
+
function objectionsNote(box, status, refused) {
|
|
57417
|
+
if (box && refused) return `By default this server lists only ${status ? "pending objections you made" : "objections you made"}: add \`--box incoming\` for objections to rules you wrote, or \`${["--box all", ...status ? ["--status any"] : []].join(" ")}\` for every one you can see.`;
|
|
57418
|
+
const phrase = box && status ? "pending objections you made and those to rules you wrote" : box ? "objections you made and those to rules you wrote" : status ? "pending objections" : null;
|
|
57419
|
+
if (phrase === null) return void 0;
|
|
57420
|
+
return `By default this lists only ${phrase}: ${widen([...box ? ["--box all"] : [], ...status ? ["--status any"] : []])}.`;
|
|
57421
|
+
}
|
|
57422
|
+
/**
|
|
57423
|
+
* What a rule request, share or objection list read with `query` (the
|
|
57424
|
+
* flags as given) left out by its defaults, and the flags that show more.
|
|
57425
|
+
* Said on any page. Undefined for any other list, or when every default was
|
|
57426
|
+
* overridden.
|
|
57427
|
+
*/
|
|
57428
|
+
function ruleListDefaultsNote(sdkName, query, options = {}) {
|
|
57429
|
+
const unset = (name) => query[name] === void 0;
|
|
57430
|
+
const said = (phrase, flags) => phrase === null ? void 0 : `By default this lists only ${phrase}: ${widen(flags)}.`;
|
|
57431
|
+
if (sdkName === "listEmailRuleRequests") {
|
|
57432
|
+
const box = unset("box");
|
|
57433
|
+
const status = unset("status");
|
|
57434
|
+
return said(box && status ? "pending requests made to you" : box ? "requests made to you" : status ? "pending requests" : null, [...box ? ["--box all"] : [], ...status ? ["--status any"] : []]);
|
|
57435
|
+
}
|
|
57436
|
+
if (sdkName === "listEmailRuleShares") {
|
|
57437
|
+
const box = unset("box");
|
|
57438
|
+
const live = unset("live");
|
|
57439
|
+
return said(box && live ? "live shares made with you" : box ? "shares made with you" : live ? "live shares" : null, [...box ? ["--box all"] : [], ...live ? ["--live any"] : []]);
|
|
57440
|
+
}
|
|
57441
|
+
if (sdkName === "listGivenEmailRuleShares") return said(unset("live") ? "live shares of your mail" : null, ["--live any"]);
|
|
57442
|
+
if (sdkName === "listEmailRuleObjections") return objectionsNote(unset("box"), unset("status"), options.objectionBoxRefused === true);
|
|
57443
|
+
}
|
|
57444
|
+
const NOUNS = {
|
|
57445
|
+
listEmailRuleRequests: "requests",
|
|
57446
|
+
listEmailRuleShares: "shares",
|
|
57447
|
+
listGivenEmailRuleShares: "shares",
|
|
57448
|
+
listEmailRuleObjections: "objections"
|
|
57449
|
+
};
|
|
57450
|
+
/**
|
|
57451
|
+
* An empty first page of one of those lists: that nothing matched, then the
|
|
57452
|
+
* line above. Undefined for any other list, when every default was
|
|
57453
|
+
* overridden, or on a later page (--cursor), where the line alone is said.
|
|
57454
|
+
*/
|
|
57455
|
+
function emptyRuleListHint(sdkName, query, options = {}) {
|
|
57456
|
+
if (query.cursor !== void 0) return void 0;
|
|
57457
|
+
const note = ruleListDefaultsNote(sdkName, query, options);
|
|
57458
|
+
return note ? `(no results) No ${NOUNS[sdkName]} match. ${note}` : void 0;
|
|
57459
|
+
}
|
|
55607
57460
|
const RULE_REQUEST_WEBHOOK_CREATE_HINT = "Hint: a webhook for rule request or objection events is made by the person it is for, signed in as themself: after `primitive login`, run this without --api-key, PRIMITIVE_API_KEY or PRIMITIVE_AGENT_PROFILE set, or create it in the dashboard. An API key, another app or an agent cannot make one. If you are already signed in as yourself, try again. It is a route target whatever your access, so it never takes a domain's or the organization's default slot.";
|
|
55608
57461
|
const RULE_REQUEST_WEBHOOK_HTTP_HINT = "Hint: rule request and objection events go only to an http webhook (kind http).";
|
|
55609
57462
|
const RULE_REQUEST_WEBHOOK_SUBSCRIBE_HINT = "Hint: rule request and objection events go only to a webhook made for them. If this webhook does not list them yet, it cannot be given them: create a new one with `--event-types` naming them (such as 'email_rule_request.*' or 'email_rule_objection.*'), signed in as yourself. If it does, only its maker, signed in as themself, can change it.";
|
|
@@ -56013,6 +57866,7 @@ const OPERATION_PATH_FLAGS = {
|
|
|
56013
57866
|
flag: "email-id",
|
|
56014
57867
|
description: "The id of the email (from `primitive emails list`), not a rule id: lists what every rule you can see decided about this email, and why a rule did not run. --id is accepted too."
|
|
56015
57868
|
} },
|
|
57869
|
+
listEmailRuleObjections: { box: OBJECTION_BOX_FLAG },
|
|
56016
57870
|
replyToEmail: { id: {
|
|
56017
57871
|
flag: "email-id",
|
|
56018
57872
|
description: EMAIL_ID_NOT_SENT
|
|
@@ -56205,7 +58059,7 @@ function flagForParameter(parameter, override) {
|
|
|
56205
58059
|
});
|
|
56206
58060
|
if (parameter.enum && parameter.enum.length > 0) return Flags.string({
|
|
56207
58061
|
...common,
|
|
56208
|
-
options: parameter.enum
|
|
58062
|
+
options: [...override?.options ?? parameter.enum]
|
|
56209
58063
|
});
|
|
56210
58064
|
return Flags.string(common);
|
|
56211
58065
|
}
|
|
@@ -56301,8 +58155,13 @@ const NETWORK_ERROR_HINTS = {
|
|
|
56301
58155
|
ENETUNREACH: "Hint: the network is unreachable. If you're behind a proxy and set HTTP(S)_PROXY, re-run with NODE_USE_ENV_PROXY=1 (Node 22+ ignores those env vars by default). `primitive doctor` reports the local environment in one shot.",
|
|
56302
58156
|
ECONNREFUSED: "Hint: the server refused the connection. Check that your firewall allows egress to *.primitive.dev, that your PRIMITIVE_API_BASE_URL_* overrides (if any) point at a reachable host, and re-run with NODE_USE_ENV_PROXY=1 if you're behind a proxy. `primitive doctor` reports the local environment in one shot.",
|
|
56303
58157
|
ETIMEDOUT: "Hint: the connection timed out. Check egress rules and proxy configuration; if you're behind a proxy, re-run with NODE_USE_ENV_PROXY=1 and HTTPS_PROXY set. `primitive doctor` reports the local environment in one shot.",
|
|
56304
|
-
EAI_AGAIN: "Hint: DNS lookup failed. Check /etc/resolv.conf inside containers, and try `curl -v https://api.primitive.dev/v1/account` to confirm the host resolves. `primitive doctor` reports the local environment in one shot."
|
|
58158
|
+
EAI_AGAIN: "Hint: DNS lookup failed. Check /etc/resolv.conf inside containers, and try `curl -v https://api.primitive.dev/v1/account` to confirm the host resolves. `primitive doctor` reports the local environment in one shot.",
|
|
58159
|
+
ENOTFOUND: "Hint: the API host name did not resolve. Check PRIMITIVE_API_BASE_URL and any --api-base-url for a typo, and your DNS. `primitive doctor` reports the local environment in one shot."
|
|
56305
58160
|
};
|
|
58161
|
+
/** The hint for a network failure's code (`cause.code` on a failed fetch), if there is one. */
|
|
58162
|
+
function networkErrorHint(code) {
|
|
58163
|
+
return Object.hasOwn(NETWORK_ERROR_HINTS, code) ? NETWORK_ERROR_HINTS[code] : void 0;
|
|
58164
|
+
}
|
|
56306
58165
|
const RATE_LIMIT_CODES = /* @__PURE__ */ new Set(["rate_limited", "rate_limit_exceeded"]);
|
|
56307
58166
|
/** When to retry a rate-limited request, from Retry-After when it was sent. */
|
|
56308
58167
|
function rateLimitHint(response) {
|
|
@@ -56461,7 +58320,7 @@ function buildFlags(operation) {
|
|
|
56461
58320
|
time: Flags.boolean({ description: TIME_FLAG_DESCRIPTION })
|
|
56462
58321
|
};
|
|
56463
58322
|
if (!operation.binaryResponse) {
|
|
56464
|
-
flags.json = Flags.boolean({ description: "Print exactly one JSON document on stdout, on success and on failure, and nothing on stderr. Stdout keeps its usual shape: the data payload, or with --envelope the full response envelope (data plus meta, including meta.cursor, and empty-result hints
|
|
58323
|
+
flags.json = Flags.boolean({ description: "Print exactly one JSON document on stdout, on success and on failure, and nothing on stderr. Stdout keeps its usual shape: the data payload, or with --envelope the full response envelope (data plus meta, including meta.cursor, and, in summary, empty-result hints and what a list's default filters left out). The next-cursor line is not printed; use --envelope to page. A failure prints the error with exit_code. Without --json, the cursor and notices go to stderr." });
|
|
56465
58324
|
flags.envelope = Flags.boolean({ description: "Print the full response envelope, including pagination metadata such as meta.cursor. Defaults to printing only the data payload for backward compatibility." });
|
|
56466
58325
|
}
|
|
56467
58326
|
const positional = positionalPathParameter(operation);
|
|
@@ -56525,6 +58384,10 @@ function buildFlags(operation) {
|
|
|
56525
58384
|
multiple: true
|
|
56526
58385
|
});
|
|
56527
58386
|
if (operation.binaryResponse) flags.output = Flags.string({ description: "Write binary response bytes to a file" });
|
|
58387
|
+
if (ENDPOINT_URL_OPERATIONS.has(operation.sdkName)) {
|
|
58388
|
+
if (flags["show-url"] !== void 0) throw new Error(`${operation.sdkName}: --show-url is both a generated flag and the CLI's own`);
|
|
58389
|
+
flags["show-url"] = Flags.boolean({ description: SHOW_URL_FLAG_DESCRIPTION });
|
|
58390
|
+
}
|
|
56528
58391
|
if (ATTACHMENT_WAIT_OPERATIONS.has(operation.sdkName)) flags.wait = Flags.boolean({
|
|
56529
58392
|
allowNo: true,
|
|
56530
58393
|
default: true,
|
|
@@ -56620,6 +58483,9 @@ const OPERATION_HINTS = {
|
|
|
56620
58483
|
getMemory: "Tip: prefer `primitive memories get <key> [--function <function-id>]` for the common read path.",
|
|
56621
58484
|
deleteMemory: "Tip: prefer `primitive memories delete <key> [--function <function-id>]` for the common delete path.",
|
|
56622
58485
|
searchMemories: "Tip: prefer `primitive memories search [prefix] [--metadata-only] [--function <function-id>]` for the common search path.",
|
|
58486
|
+
createEmailRuleObjection: "Tip: say in --message (up to 500 characters) what you want. It can ask for less than turning the rule off: ask the author to narrow the rule, or to explain where its matches go (its receivers). The author accepts, which turns the rule off, or declines, optionally giving a reason, which you see in `primitive email-rule-oversight get-email-rule-objection <objection-id>`. You can withdraw it with `primitive email-rule-oversight withdraw-email-rule-objection <objection-id>`. Objecting does not change the rule.",
|
|
58487
|
+
declineEmailRuleObjection: "Tip: the member who objected sees --reason (up to 500 characters). When the objection asked you to narrow the rule or explain a receiver, the reason can answer that: say what you changed, or what the receiver is for.",
|
|
58488
|
+
listEndpoints: "Tip: without --json, a table on stderr after the JSON shows each endpoint's ENABLED and DELIVERING. DELIVERING is read from delivery.delivering, whether a webhook is being sent mail at all, not from enabled: an endpoint can be enabled and still not be delivering (its owner's key revoked, say), shown as no with the reason codes in parentheses. A webhook whose delivery could not be checked shows unknown, and a Function or pull endpoint shows -.",
|
|
56623
58489
|
startAgentSignup: "Tip: pass --terms-accepted. Capture the signup_token from the response and feed it to `primitive agent verify-agent-signup --signup-token <token> --verification-code <6-digit-code>` (the verify flag accepts --code as an alias). The high-level `primitive signup <email>` command walks an interactive user through both steps with friendlier prompts.",
|
|
56624
58490
|
testEmailRule: "Tip: --expect-match and --expect-no-match (or --expect-file) set expect, the emails the rule must match and must not. When no expect is sent, by these flags or in the body, a saved rule's saved expectations are judged instead. Either way, the answer reports the expectations it judged in expectations: passed, counts and per-email results. (create-email-rule and update-email-rule instead judge the rule's saved expectations on the version they save, in expectations_check: passed, decided, failed and undecided.) The exit code follows that report: 1 when one failed; 1 when one is undecided and testing again will not decide it (its email cannot be found or read, cannot be classified, or cannot be tested: skipped); 3 when the only undecided ones can be decided later (not classified yet, or a question unanswered), so test again later. Exit 1 also means the request failed. With --json, error.code tells these apart: expectations_failed, expectations_unresolvable, expectations_undecided (exit 3), or the API's own code. Without --json a readable report follows the JSON on stderr: warnings, how each condition held, the expectations, and the values each email that did not match was compared on.",
|
|
56625
58491
|
verifyAgentSignup: "Tip: pass --verification-code <code> (or --code; both work). The response carries OAuth tokens but not your assigned inbox domain; run `primitive domains list` (or `primitive whoami`) after success to see the managed *.primitive.email address that routes to this account."
|
|
@@ -56640,6 +58506,7 @@ const OPERATION_ERROR_HINTS = {
|
|
|
56640
58506
|
createEndpoint: (code, body, payload) => createEndpointRuleRequestHint(code, body, payload),
|
|
56641
58507
|
updateEndpoint: (code, body, payload) => updateEndpointRuleRequestHint(code, body, payload),
|
|
56642
58508
|
updateEmailRule: (code, body, payload, path, flags) => updateEmailRuleErrorHint(code, payload, path?.id, body, flags),
|
|
58509
|
+
listEmailRuleObjections: (_code, _body, payload, _path, flags) => objectionBoxErrorHint(payload, flags),
|
|
56643
58510
|
verifyDomain: (code, _body, payload) => code === "dns_verification_failed" ? domainVerificationFailedHint(payload) : void 0,
|
|
56644
58511
|
addDomain: (code, body) => {
|
|
56645
58512
|
if (code === "mail_relay_unavailable") return MAIL_RELAY_UNAVAILABLE_MESSAGE;
|
|
@@ -56708,6 +58575,13 @@ function createOperationCommand(operation) {
|
|
|
56708
58575
|
"verifyAgentSignup",
|
|
56709
58576
|
"resendAgentSignupVerification"
|
|
56710
58577
|
].includes(operation.operationId)) requireDefaultLoginProfile();
|
|
58578
|
+
const prereadBody = ENDPOINT_URL_WRITE_OPERATIONS.has(operation.sdkName) && operation.hasJsonBody ? { value: readJsonBody(parsedFlags) } : void 0;
|
|
58579
|
+
if (prereadBody) {
|
|
58580
|
+
const urlFlag = [...bodyFieldFlagToProperty].find(([, property]) => property === "url")?.[0];
|
|
58581
|
+
const flagUrl = urlFlag ? parsedFlags[urlFlag] : void 0;
|
|
58582
|
+
const refusal = hiddenQueryUrlRefusal(typeof flagUrl === "string" ? { url: flagUrl } : prereadBody.value);
|
|
58583
|
+
if (refusal) throw new Errors.CLIError(refusal, { exit: 2 });
|
|
58584
|
+
}
|
|
56711
58585
|
await runWithTiming(parsedFlags.time === true, async () => {
|
|
56712
58586
|
const { apiClient, auth, baseUrlOverridden } = await createAuthenticatedCliApiClient({
|
|
56713
58587
|
apiKey: typeof parsedFlags["api-key"] === "string" ? parsedFlags["api-key"] : void 0,
|
|
@@ -56716,7 +58590,7 @@ function createOperationCommand(operation) {
|
|
|
56716
58590
|
});
|
|
56717
58591
|
let body;
|
|
56718
58592
|
if (operation.hasJsonBody) {
|
|
56719
|
-
const explicit = readJsonBody(parsedFlags);
|
|
58593
|
+
const explicit = prereadBody ? prereadBody.value : readJsonBody(parsedFlags);
|
|
56720
58594
|
const overrides = collectBodyFieldFlags(parsedFlags, bodyFieldFlagToProperty);
|
|
56721
58595
|
const extensionFlagFor = /* @__PURE__ */ new Map();
|
|
56722
58596
|
for (const field of extension?.bodyFields?.(parsedFlags, explicit) ?? []) {
|
|
@@ -56736,6 +58610,10 @@ function createOperationCommand(operation) {
|
|
|
56736
58610
|
}
|
|
56737
58611
|
} else body = explicit;
|
|
56738
58612
|
}
|
|
58613
|
+
if (ENDPOINT_URL_WRITE_OPERATIONS.has(operation.sdkName)) {
|
|
58614
|
+
const refusal = hiddenQueryUrlRefusal(body);
|
|
58615
|
+
if (refusal) throw new Errors.CLIError(refusal, { exit: 2 });
|
|
58616
|
+
}
|
|
56739
58617
|
if (EVENT_TYPES_FLAG_OPERATIONS.has(operation.sdkName) && Array.isArray(parsedFlags["event-types"])) body = await applyEventTypesFlag({
|
|
56740
58618
|
body,
|
|
56741
58619
|
values: parsedFlags["event-types"],
|
|
@@ -56752,7 +58630,9 @@ function createOperationCommand(operation) {
|
|
|
56752
58630
|
const replyStateSurface = replyStateSurfaceForOperation(operation.sdkName, query);
|
|
56753
58631
|
const automatedSurface = automatedSurfaceForOperation(operation.sdkName, query);
|
|
56754
58632
|
const fromVerified = fromVerifiedExpectation(operation.sdkName, query);
|
|
56755
|
-
|
|
58633
|
+
let sentQuery = withDefaultObjectionBox(operation.sdkName, query);
|
|
58634
|
+
let objectionBoxRefused = false;
|
|
58635
|
+
const callOperation = (stepUpToken, pageQuery = sentQuery) => {
|
|
56756
58636
|
const sent = stepUpToken ? {
|
|
56757
58637
|
...headers,
|
|
56758
58638
|
[STEP_UP_HEADER]: stepUpToken
|
|
@@ -56797,7 +58677,7 @@ function createOperationCommand(operation) {
|
|
|
56797
58677
|
const rows = [];
|
|
56798
58678
|
let sentCursor = query.cursor;
|
|
56799
58679
|
let last = await callOperation(void 0, {
|
|
56800
|
-
...
|
|
58680
|
+
...sentQuery,
|
|
56801
58681
|
limit: Math.min(max, wanted)
|
|
56802
58682
|
});
|
|
56803
58683
|
const budget = Math.ceil(wanted / max) + 20;
|
|
@@ -56823,7 +58703,7 @@ function createOperationCommand(operation) {
|
|
|
56823
58703
|
};
|
|
56824
58704
|
sentCursor = cursor;
|
|
56825
58705
|
last = await callOperation(void 0, {
|
|
56826
|
-
...
|
|
58706
|
+
...sentQuery,
|
|
56827
58707
|
cursor,
|
|
56828
58708
|
limit: Math.min(max, wanted - rows.length)
|
|
56829
58709
|
});
|
|
@@ -56834,17 +58714,26 @@ function createOperationCommand(operation) {
|
|
|
56834
58714
|
const warning = typeof role === "string" ? roleReadsAllMailWarning(role, await readRoles(apiClient.client)) : null;
|
|
56835
58715
|
if (warning) process.stderr.write(`${warning}\n`);
|
|
56836
58716
|
}
|
|
56837
|
-
const
|
|
58717
|
+
const send = async () => paged ? await callPaged() : takesStepUp(operation) ? await callWithApproval() : ATTACHMENT_WAIT_OPERATIONS.has(operation.sdkName) ? await withAttachmentWait(callOperation, {
|
|
56838
58718
|
wait: parsedFlags.wait !== false,
|
|
56839
58719
|
errorCode: (error) => extractErrorCode(extractErrorPayload(error)),
|
|
56840
58720
|
onFirstWait: () => {
|
|
56841
58721
|
process.stderr.write(`Attachment content is not ready yet; waiting up to ${ATTACHMENT_WAIT_MAX_MS / 1e3}s. Pass --no-wait to return immediately.\n`);
|
|
56842
58722
|
}
|
|
56843
58723
|
}) : await callOperation();
|
|
58724
|
+
let result = await send();
|
|
58725
|
+
if (result.error && sentQuery !== query && isObjectionBoxRefused(extractErrorPayload(result.error))) {
|
|
58726
|
+
sentQuery = {
|
|
58727
|
+
...query,
|
|
58728
|
+
box: OBJECTION_BOX_FALLBACK
|
|
58729
|
+
};
|
|
58730
|
+
objectionBoxRefused = true;
|
|
58731
|
+
result = await send();
|
|
58732
|
+
}
|
|
56844
58733
|
if (result.error) {
|
|
56845
58734
|
const errorPayload = extractErrorPayload(result.error);
|
|
56846
58735
|
const operationErrorHint = OPERATION_ERROR_HINTS[operation.sdkName]?.(extractErrorCode(errorPayload), body, errorPayload, collectValues(operation.pathParams, parsedFlags, operation.sdkName), parsedFlags);
|
|
56847
|
-
writeErrorWithHints(errorPayload, result.response, { codeHint: !(operationErrorHint && OPERATION_ERROR_HINTS_REPLACING_CODE_HINT.has(operation.sdkName)) });
|
|
58736
|
+
writeErrorWithHints(ENDPOINT_URL_OPERATIONS.has(operation.sdkName) && parsedFlags["show-url"] !== true ? errorWithQueryHidden(errorPayload) : errorPayload, result.response, { codeHint: !(operationErrorHint && OPERATION_ERROR_HINTS_REPLACING_CODE_HINT.has(operation.sdkName)) });
|
|
56848
58737
|
if (operationErrorHint) process.stderr.write(`${operationErrorHint}\n`);
|
|
56849
58738
|
if (stepUpUrl) process.stderr.write(approveThenRerunHint(stepUpUrl));
|
|
56850
58739
|
if (replyStateSurface && isAwaitingRejectedError(errorPayload)) process.stderr.write(`${awaitingRejectedError(replyStateSurface).message}\n`);
|
|
@@ -56920,18 +58809,26 @@ function createOperationCommand(operation) {
|
|
|
56920
58809
|
if (cursor && !jsonOutput) process.stderr.write(`next cursor: ${cursor}\n`);
|
|
56921
58810
|
if (pagingNote && !jsonOutput) process.stderr.write(`${pagingNote}\n`);
|
|
56922
58811
|
const summary = [];
|
|
58812
|
+
let ruleListHintSaid = false;
|
|
56923
58813
|
if (Array.isArray(envelope?.data) && envelope.data.length === 0 && (!jsonOutput || withEnvelope) && (jsonOutput || !metaExplainsEmptyList(envelope?.meta))) {
|
|
56924
58814
|
const tail = query.since !== void 0;
|
|
56925
58815
|
const more = envelope?.meta?.cursor ?? null;
|
|
58816
|
+
const ruleListHint = emptyRuleListHint(operation.sdkName, query, { objectionBoxRefused });
|
|
58817
|
+
ruleListHintSaid = ruleListHint !== void 0;
|
|
56926
58818
|
const hint = operation.sdkName === "listEmails" ? emptyEmailListHint({
|
|
56927
58819
|
filterFlags: listFilters(query).map((name) => `--${parameterFlagName(operation.sdkName, name)}`),
|
|
56928
58820
|
...tail ? { pastFlag: "--since" } : query.cursor !== void 0 ? { pastFlag: "--cursor" } : {},
|
|
56929
58821
|
nextCursor: tail ? null : more,
|
|
56930
58822
|
caller: tail || more ? null : await readCallerMailFor(auth, apiClient.client)
|
|
56931
|
-
}) :
|
|
58823
|
+
}) : ruleListHint ?? emptyDeliveriesHint(operation.sdkName, query) ?? EMPTY_RESULT_HINTS[operation.sdkName];
|
|
56932
58824
|
if (hint && jsonOutput) summary.push(hint);
|
|
56933
58825
|
else if (hint) process.stderr.write(`${hint}\n`);
|
|
56934
58826
|
}
|
|
58827
|
+
if (Array.isArray(envelope?.data) && (!jsonOutput || withEnvelope)) {
|
|
58828
|
+
const note = ruleListHintSaid ? void 0 : ruleListDefaultsNote(operation.sdkName, query, { objectionBoxRefused });
|
|
58829
|
+
if (note && jsonOutput) summary.push(note);
|
|
58830
|
+
else if (note) process.stderr.write(`${note}\n`);
|
|
58831
|
+
}
|
|
56935
58832
|
if (!jsonOutput) for (const line of metaNoteLines(envelope?.meta)) process.stderr.write(`${line}\n`);
|
|
56936
58833
|
if (operation.sdkName === "listSentEmails") {
|
|
56937
58834
|
const note = sentListOtherSendersNote(envelope?.data, auth.connectedAgent?.agentAddress);
|
|
@@ -56984,12 +58881,26 @@ function createOperationCommand(operation) {
|
|
|
56984
58881
|
}
|
|
56985
58882
|
};
|
|
56986
58883
|
}
|
|
56987
|
-
let
|
|
58884
|
+
let shownEnvelope = envelope;
|
|
58885
|
+
let queryHidden = false;
|
|
58886
|
+
if (ENDPOINT_URL_OPERATIONS.has(operation.sdkName) && parsedFlags["show-url"] !== true && envelope) {
|
|
58887
|
+
const shown = endpointsWithQueryHidden(envelope.data);
|
|
58888
|
+
if (shown.hidden) {
|
|
58889
|
+
shownEnvelope = {
|
|
58890
|
+
...envelope,
|
|
58891
|
+
data: shown.data
|
|
58892
|
+
};
|
|
58893
|
+
queryHidden = true;
|
|
58894
|
+
if (jsonOutput && withEnvelope) summary.push(HIDDEN_QUERY_NOTE);
|
|
58895
|
+
}
|
|
58896
|
+
}
|
|
58897
|
+
let printed = jsonOutput && withEnvelope ? operationJsonDocument(shownEnvelope, summary) : operationOutputPayload(shownEnvelope, withEnvelope);
|
|
56988
58898
|
if (jsonOutput && report?.exitCode && report.error && printed !== null && typeof printed === "object" && !Array.isArray(printed)) printed = {
|
|
56989
58899
|
...printed,
|
|
56990
58900
|
error: report.error
|
|
56991
58901
|
};
|
|
56992
58902
|
this.log(JSON.stringify(printed, null, 2));
|
|
58903
|
+
if (queryHidden && !jsonOutput) process.stderr.write(`${HIDDEN_QUERY_NOTE}\n`);
|
|
56993
58904
|
if (reportError !== void 0) process.stderr.write(`Warning: ${operation.sdkName} succeeded but its report could not be built (${reportError}). The JSON above is the full answer; read it rather than the exit code.\n`);
|
|
56994
58905
|
if (report && !jsonOutput) for (const line of report.lines) process.stderr.write(`${line}\n`);
|
|
56995
58906
|
if (reportError !== void 0 && report?.exitCode && !jsonOutput) process.stderr.write(`The answer's expectations were not all shown to pass, so the command exits ${report.exitCode}.\n`);
|
|
@@ -57007,35 +58918,6 @@ const EMPTY_RESULT_HINTS = {
|
|
|
57007
58918
|
listFunctions: "(no results) No Functions configured yet. Start with `primitive functions templates`, then `primitive functions init --template <template>` and `primitive functions deploy --name <name> --file <bundle>`."
|
|
57008
58919
|
};
|
|
57009
58920
|
/**
|
|
57010
|
-
* An empty rule request, share or objection list, read by the filters the
|
|
57011
|
-
* call left at their defaults: each list shows only part of what you can see
|
|
57012
|
-
* by default (pending requests made to you; live shares made with you;
|
|
57013
|
-
* pending objections you made), so an empty answer says which flags widen
|
|
57014
|
-
* it. Undefined for any other list, when every filter was given, or on a
|
|
57015
|
-
* later page (--cursor), which is empty only past the end.
|
|
57016
|
-
*/
|
|
57017
|
-
function emptyRuleListHint(sdkName, query) {
|
|
57018
|
-
if (query.cursor !== void 0) return void 0;
|
|
57019
|
-
const unset = (name) => query[name] === void 0;
|
|
57020
|
-
const said = (noun, phrase, flags) => phrase === null ? void 0 : `(no results) No ${noun} match. By default this lists only ${phrase}: add \`${flags.join(" ")}\` to widen it.`;
|
|
57021
|
-
if (sdkName === "listEmailRuleRequests") {
|
|
57022
|
-
const box = unset("box");
|
|
57023
|
-
const status = unset("status");
|
|
57024
|
-
return said("requests", box && status ? "pending requests made to you" : box ? "requests made to you" : status ? "pending requests" : null, [...box ? ["--box all"] : [], ...status ? ["--status any"] : []]);
|
|
57025
|
-
}
|
|
57026
|
-
if (sdkName === "listEmailRuleShares") {
|
|
57027
|
-
const box = unset("box");
|
|
57028
|
-
const live = unset("live");
|
|
57029
|
-
return said("shares", box && live ? "live shares made with you" : box ? "shares made with you" : live ? "live shares" : null, [...box ? ["--box all"] : [], ...live ? ["--live any"] : []]);
|
|
57030
|
-
}
|
|
57031
|
-
if (sdkName === "listGivenEmailRuleShares") return said("shares", unset("live") ? "live shares of your mail" : null, ["--live any"]);
|
|
57032
|
-
if (sdkName === "listEmailRuleObjections") {
|
|
57033
|
-
const box = unset("box");
|
|
57034
|
-
const status = unset("status");
|
|
57035
|
-
return said("objections", box && status ? "pending objections you made" : box ? "objections you made" : status ? "pending objections" : null, [...box ? ["--box all"] : [], ...status ? ["--status any"] : []]);
|
|
57036
|
-
}
|
|
57037
|
-
}
|
|
57038
|
-
/**
|
|
57039
58921
|
* An empty delivery list narrowed by a filter (--endpoint-id, --status,
|
|
57040
58922
|
* --event-type and the rest) names the filters given, in place of the general
|
|
57041
58923
|
* hint, which reads as if nothing was ever delivered, and keeps its point that
|
|
@@ -57052,4 +58934,4 @@ function emptyDeliveriesHint(sdkName, query) {
|
|
|
57052
58934
|
function canonicalizeCliReferences(description) {
|
|
57053
58935
|
return description.replaceAll("`primitive emails:latest`", "`primitive emails latest`").replaceAll("`primitive describe emails:get-email | jq '.responseSchema.properties'`", "`primitive describe emails:get | jq '.responseSchema.properties'`");
|
|
57054
58936
|
}
|
|
57055
|
-
export {
|
|
58937
|
+
export { interactionNextActions as $, ConnectedAgentKeyRequiredError as $t, openBrowser as A, DEFAULT_ENROLL_NAME as At, serverRelationship as B, runtimeSessionVariableList as Bt, approveThenRerunHint as C, sendIdentityFields as Ct, canOfferCopyHotkey as D, serializeErrorPayload as Dt, withApproval as E, sentHistoryWindowStart as Et, formatMailWakeLine as F, identitySuggestions as Ft, claimPendingMail as G, readCallerMailFor as Gt, wakeReadCommand as H, withFlagSuggestion as Ht, latestOwnOutbound as I, loadSkillLine as It, pendingMailPath as J, isEmailId as Jt, clearConsumedPendingMail as K, classificationFactLines as Kt, readThreadContext as L, currentMailSessionKey as Lt, bareAddress$1 as M, connectNextSteps as Mt, describeWake as N, defaultConnectionName as Nt, formatBrowserLoginInstructions as O, successfulSendOutcome as Ot, displayAddress as P, generatedAgentName as Pt, interactionHumanLine as Q, withAttachmentWait as Qt, sentInThread as R, detectAgentRuntime as Rt, STEP_UP_TOKEN_FLAG_DESCRIPTION as S, reportSendCommandResult as St, terminalApprovalIo as T, sendWaitClampNotice as Tt, wakeRecipientField as U, emptyEmailListHint as Ut, skillFirstLine as V, formatAlreadySentNotice as Vt, wakeRelationship as W, mailReach as Wt, recordPendingMail as X, ATTACHMENT_WAIT_FLAG_DESCRIPTION as Xt, readPendingMail as Y, noFactsMessage as Yt, removePendingMail as Z, ATTACHMENT_WAIT_MAX_MS as Zt, surfaceUnauthorizedHint as _, sanitizeForTerminal as _n, formatPriorRepliesCheckSkipped as _t, createOperationCommand as a, resolveCliApiRequestConfig as an, MAX_SEND_WAIT_TIMEOUT_MS as at, BROWSER_FLAG_DESCRIPTION as b, formatSendRecordFailureSummary as bt, formatErrorPayload as c, RESTRICTED_ROLE_NOTE as cn, assertValidIdempotencyKey as ct, isGrantRefusal as d, isBuiltInRoleKey as dn, checkPriorReplies as dt, SAVED_CLI_OAUTH_SESSION_EXPIRED_MESSAGE as en, readEmailInteraction as et, networkErrorHint as f, revokeUserLogin as fn, classifySendError as ft, runWithTiming as g, routeWarningLines as gn, formatDeletedEarlierSendNotice as gt, refusalDetails as h, switchCurrentOrg as hn, followUpCommandPrefix as ht, TIME_FLAG_DESCRIPTION as i, refuseOrgSelectionForProfile as in, IDEMPOTENCY_KEY_FLAG_DESCRIPTION as it, explainPendingMailNotFound as j, cliInvocation as jt, listenForCopyHotkey as k, thrownErrorExitCode as kt, hasControlCharacter as l, credentialsFromUserLogin as ln, buildFollowUpCommand as lt, readTextFileFlag as m, roleKeyText as mn, excludeSignalReplies as mt, API_ERROR_CODES as n, createCliApiClient as nn, replyInteractionWarning as nt, extractErrorCode as o, selectedOrgFromEnv as on, SEND_OUTCOME_HELP as ot, parameterFlagName as p, roleKeyLabel as pn, deriveSendIdempotencyKey as pt, clearReadPendingMail as q, classificationOf as qt, OPERATION_PATH_FLAGS as r, refreshStoredCliCredentials as rn, wakeInteractionSentence as rt, extractErrorPayload as s, CliOrgRefusedError as sn, apiResultHttpStatus as st, API_BASE_URL_FLAG_DESCRIPTION as t, createAuthenticatedCliApiClient as tn, replyExpectation as tt, headerFlagName as u, fetchCliOrgs as un, buildThrownSendFailureEnvelope as ut, takesStepUp as v, setKnownCommands as vn, formatPriorRepliesWarning as vt, promptLine as w, sendOutcomeExitCode as wt, STEP_UP_HEADER as x, priorRepliesThatWentOut as xt, writeErrorWithHints as y, operationManifest as yn, formatSendFailureSummary as yt, serverMuted as z, detectRuntimeSession as zt };
|