primcli 3.0.0-preview.12 → 3.0.0-preview.13
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-D5Tj9C-K.js} +1229 -101
- package/dist/{machine-session-DkXYR62a.js → machine-session-BMr-zPLx.js} +4 -4
- package/dist/{notify-session-WKFsaFt3.js → notify-session-cIUz_kxR.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 +802 -119
- package/dist/oclif/receiver-heal.js +2 -2
- package/dist/{repeats-Dj_o6c-X-wjmw2Jbx.js → repeats-Dj_o6c-X-ykfsraq6.js} +54 -4
- package/dist/{scoped-chat-B1Fi6_qM.js → scoped-chat-DVSsLSRw.js} +1 -1
- package/dist/{signal-command-BdJVZXGl.js → signal-command-gpH2AhIi.js} +4 -4
- package/man/primitive.1 +3 -2
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as ensureSearchReportsReplyState, Gn as sdk_gen_exports, J as EMAIL_RULE_REQUEST_EVENT_TYPES, K as replyStateSurfaceForOperation, L as ReplyStateUnsupportedError, Qt as getOwnGrant, R as assertAwaitingFilterRows, Ut as getEmail, W as isAwaitingRejectedError, X as WEBHOOK_EVENT_TYPES, Y as SENT_EMAIL_EVENT_TYPES, _n as listEndpoints, at as assertAutomatedVerdict, ct as ensureSearchReportsAutomated, dt as isAutomatedRejectedError, it as AutomatedFilterUnsupportedError, lt as expectedAutomatedVerdicts, nn as getThread, ot as automatedRejectedError, q as EMAIL_RULE_OBJECTION_EVENT_TYPES, st as automatedSurfaceForOperation, v as parseRetryAfter, z as awaitingRejectedError } from "./repeats-Dj_o6c-X-
|
|
1
|
+
import { B as ensureSearchReportsReplyState, Gn as sdk_gen_exports, J as EMAIL_RULE_REQUEST_EVENT_TYPES, K as replyStateSurfaceForOperation, L as ReplyStateUnsupportedError, Qt as getOwnGrant, R as assertAwaitingFilterRows, Ut as getEmail, W as isAwaitingRejectedError, X as WEBHOOK_EVENT_TYPES, Y as SENT_EMAIL_EVENT_TYPES, _n as listEndpoints, at as assertAutomatedVerdict, ct as ensureSearchReportsAutomated, dt as isAutomatedRejectedError, it as AutomatedFilterUnsupportedError, lt as expectedAutomatedVerdicts, nn as getThread, ot as automatedRejectedError, q as EMAIL_RULE_OBJECTION_EVENT_TYPES, st as automatedSurfaceForOperation, v as parseRetryAfter, z as awaitingRejectedError } from "./repeats-Dj_o6c-X-ykfsraq6.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";
|
|
@@ -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, 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,11 @@ 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"
|
|
903
908
|
}
|
|
904
909
|
},
|
|
905
910
|
"required": [
|
|
@@ -11227,6 +11232,27 @@ const operationManifest = [
|
|
|
11227
11232
|
"additionalProperties": {}
|
|
11228
11233
|
}
|
|
11229
11234
|
},
|
|
11235
|
+
"rules_added": {
|
|
11236
|
+
"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.",
|
|
11237
|
+
"type": "array",
|
|
11238
|
+
"items": {
|
|
11239
|
+
"type": "object",
|
|
11240
|
+
"properties": {
|
|
11241
|
+
"id": { "type": "string" },
|
|
11242
|
+
"granted_emails": {
|
|
11243
|
+
"type": ["integer", "null"],
|
|
11244
|
+
"minimum": 0,
|
|
11245
|
+
"maximum": 9007199254740991
|
|
11246
|
+
},
|
|
11247
|
+
"more": {
|
|
11248
|
+
"type": "boolean",
|
|
11249
|
+
"const": true
|
|
11250
|
+
}
|
|
11251
|
+
},
|
|
11252
|
+
"required": ["id", "granted_emails"],
|
|
11253
|
+
"additionalProperties": {}
|
|
11254
|
+
}
|
|
11255
|
+
},
|
|
11230
11256
|
"grant_unguarded": {
|
|
11231
11257
|
"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
11258
|
"type": "boolean",
|
|
@@ -12344,11 +12370,17 @@ const operationManifest = [
|
|
|
12344
12370
|
"type": "string"
|
|
12345
12371
|
}],
|
|
12346
12372
|
"queryParams": [{
|
|
12347
|
-
"description": "When true, include only outbound DNS records.
|
|
12373
|
+
"description": "When true, include only outbound DNS records. Cannot be combined with inbound_only=true. By default, include all records.",
|
|
12348
12374
|
"enum": null,
|
|
12349
12375
|
"name": "outbound_only",
|
|
12350
12376
|
"required": false,
|
|
12351
12377
|
"type": "boolean"
|
|
12378
|
+
}, {
|
|
12379
|
+
"description": "When true, include only inbound MX and ownership TXT records. Cannot be combined with outbound_only=true.",
|
|
12380
|
+
"enum": null,
|
|
12381
|
+
"name": "inbound_only",
|
|
12382
|
+
"required": false,
|
|
12383
|
+
"type": "boolean"
|
|
12352
12384
|
}],
|
|
12353
12385
|
"headerParams": [],
|
|
12354
12386
|
"permissions": ["domains:read"],
|
|
@@ -13141,8 +13173,14 @@ const operationManifest = [
|
|
|
13141
13173
|
"email"
|
|
13142
13174
|
]
|
|
13143
13175
|
},
|
|
13144
|
-
"is_objector": {
|
|
13145
|
-
|
|
13176
|
+
"is_objector": {
|
|
13177
|
+
"type": "boolean",
|
|
13178
|
+
"description": "Whether you made it, in your current membership."
|
|
13179
|
+
},
|
|
13180
|
+
"is_author": {
|
|
13181
|
+
"type": "boolean",
|
|
13182
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
13183
|
+
},
|
|
13146
13184
|
"message": {
|
|
13147
13185
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
13148
13186
|
"type": ["string", "null"]
|
|
@@ -13289,8 +13327,14 @@ const operationManifest = [
|
|
|
13289
13327
|
"email"
|
|
13290
13328
|
]
|
|
13291
13329
|
},
|
|
13292
|
-
"is_objector": {
|
|
13293
|
-
|
|
13330
|
+
"is_objector": {
|
|
13331
|
+
"type": "boolean",
|
|
13332
|
+
"description": "Whether you made it, in your current membership."
|
|
13333
|
+
},
|
|
13334
|
+
"is_author": {
|
|
13335
|
+
"type": "boolean",
|
|
13336
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
13337
|
+
},
|
|
13294
13338
|
"message": {
|
|
13295
13339
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
13296
13340
|
"type": ["string", "null"]
|
|
@@ -13435,8 +13479,14 @@ const operationManifest = [
|
|
|
13435
13479
|
"email"
|
|
13436
13480
|
]
|
|
13437
13481
|
},
|
|
13438
|
-
"is_objector": {
|
|
13439
|
-
|
|
13482
|
+
"is_objector": {
|
|
13483
|
+
"type": "boolean",
|
|
13484
|
+
"description": "Whether you made it, in your current membership."
|
|
13485
|
+
},
|
|
13486
|
+
"is_author": {
|
|
13487
|
+
"type": "boolean",
|
|
13488
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
13489
|
+
},
|
|
13440
13490
|
"message": {
|
|
13441
13491
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
13442
13492
|
"type": ["string", "null"]
|
|
@@ -13576,7 +13626,163 @@ const operationManifest = [
|
|
|
13576
13626
|
"description": "Null when covers_now is false."
|
|
13577
13627
|
},
|
|
13578
13628
|
"receivers": {
|
|
13579
|
-
"description": "Null when covers_now is false (who receives it now is not about your mail),
|
|
13629
|
+
"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.",
|
|
13630
|
+
"anyOf": [{
|
|
13631
|
+
"type": "object",
|
|
13632
|
+
"properties": {
|
|
13633
|
+
"keys": {
|
|
13634
|
+
"type": "array",
|
|
13635
|
+
"items": {
|
|
13636
|
+
"type": "object",
|
|
13637
|
+
"properties": {
|
|
13638
|
+
"owner": { "anyOf": [{
|
|
13639
|
+
"type": "object",
|
|
13640
|
+
"properties": {
|
|
13641
|
+
"kind": {
|
|
13642
|
+
"type": "string",
|
|
13643
|
+
"const": "member"
|
|
13644
|
+
},
|
|
13645
|
+
"user_id": {
|
|
13646
|
+
"type": "string",
|
|
13647
|
+
"description": "The member's user id.",
|
|
13648
|
+
"format": "uuid"
|
|
13649
|
+
},
|
|
13650
|
+
"name": {
|
|
13651
|
+
"description": "Their name; null when they have none set.",
|
|
13652
|
+
"type": ["string", "null"]
|
|
13653
|
+
}
|
|
13654
|
+
},
|
|
13655
|
+
"required": [
|
|
13656
|
+
"kind",
|
|
13657
|
+
"user_id",
|
|
13658
|
+
"name"
|
|
13659
|
+
]
|
|
13660
|
+
}, {
|
|
13661
|
+
"type": "object",
|
|
13662
|
+
"properties": { "kind": {
|
|
13663
|
+
"type": "string",
|
|
13664
|
+
"const": "organization",
|
|
13665
|
+
"description": "Held by no member: an organization key, or one whose holder has left."
|
|
13666
|
+
} },
|
|
13667
|
+
"required": ["kind"]
|
|
13668
|
+
}] },
|
|
13669
|
+
"count": {
|
|
13670
|
+
"type": "integer",
|
|
13671
|
+
"exclusiveMinimum": 0
|
|
13672
|
+
},
|
|
13673
|
+
"reads_in_full": {
|
|
13674
|
+
"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.",
|
|
13675
|
+
"type": "integer",
|
|
13676
|
+
"minimum": 0
|
|
13677
|
+
}
|
|
13678
|
+
},
|
|
13679
|
+
"required": ["owner", "count"]
|
|
13680
|
+
},
|
|
13681
|
+
"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."
|
|
13682
|
+
},
|
|
13683
|
+
"webhooks": {
|
|
13684
|
+
"type": "array",
|
|
13685
|
+
"items": {
|
|
13686
|
+
"type": "object",
|
|
13687
|
+
"properties": {
|
|
13688
|
+
"owner": { "anyOf": [{
|
|
13689
|
+
"type": "object",
|
|
13690
|
+
"properties": {
|
|
13691
|
+
"kind": {
|
|
13692
|
+
"type": "string",
|
|
13693
|
+
"const": "member"
|
|
13694
|
+
},
|
|
13695
|
+
"user_id": {
|
|
13696
|
+
"type": "string",
|
|
13697
|
+
"description": "The member's user id.",
|
|
13698
|
+
"format": "uuid"
|
|
13699
|
+
},
|
|
13700
|
+
"name": {
|
|
13701
|
+
"description": "Their name; null when they have none set.",
|
|
13702
|
+
"type": ["string", "null"]
|
|
13703
|
+
}
|
|
13704
|
+
},
|
|
13705
|
+
"required": [
|
|
13706
|
+
"kind",
|
|
13707
|
+
"user_id",
|
|
13708
|
+
"name"
|
|
13709
|
+
]
|
|
13710
|
+
}, {
|
|
13711
|
+
"type": "object",
|
|
13712
|
+
"properties": { "kind": {
|
|
13713
|
+
"type": "string",
|
|
13714
|
+
"const": "organization",
|
|
13715
|
+
"description": "Held by no member: an organization key, or one whose holder has left."
|
|
13716
|
+
} },
|
|
13717
|
+
"required": ["kind"]
|
|
13718
|
+
}] },
|
|
13719
|
+
"count": {
|
|
13720
|
+
"type": "integer",
|
|
13721
|
+
"exclusiveMinimum": 0
|
|
13722
|
+
},
|
|
13723
|
+
"hosts": {
|
|
13724
|
+
"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.",
|
|
13725
|
+
"type": "array",
|
|
13726
|
+
"items": { "type": "string" }
|
|
13727
|
+
},
|
|
13728
|
+
"hosts_not_listed": {
|
|
13729
|
+
"description": "Hosts past those listed.",
|
|
13730
|
+
"type": "integer",
|
|
13731
|
+
"minimum": 0
|
|
13732
|
+
}
|
|
13733
|
+
},
|
|
13734
|
+
"required": ["owner", "count"]
|
|
13735
|
+
},
|
|
13736
|
+
"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)."
|
|
13737
|
+
},
|
|
13738
|
+
"shares": {
|
|
13739
|
+
"type": "array",
|
|
13740
|
+
"items": {
|
|
13741
|
+
"type": "object",
|
|
13742
|
+
"properties": {
|
|
13743
|
+
"beneficiary": {
|
|
13744
|
+
"type": "object",
|
|
13745
|
+
"properties": {
|
|
13746
|
+
"kind": {
|
|
13747
|
+
"type": "string",
|
|
13748
|
+
"const": "member"
|
|
13749
|
+
},
|
|
13750
|
+
"user_id": {
|
|
13751
|
+
"type": "string",
|
|
13752
|
+
"description": "The member's user id.",
|
|
13753
|
+
"format": "uuid"
|
|
13754
|
+
},
|
|
13755
|
+
"name": {
|
|
13756
|
+
"description": "Their name; null when they have none set.",
|
|
13757
|
+
"type": ["string", "null"]
|
|
13758
|
+
}
|
|
13759
|
+
},
|
|
13760
|
+
"required": [
|
|
13761
|
+
"kind",
|
|
13762
|
+
"user_id",
|
|
13763
|
+
"name"
|
|
13764
|
+
]
|
|
13765
|
+
},
|
|
13766
|
+
"count": {
|
|
13767
|
+
"type": "integer",
|
|
13768
|
+
"exclusiveMinimum": 0
|
|
13769
|
+
}
|
|
13770
|
+
},
|
|
13771
|
+
"required": ["beneficiary", "count"]
|
|
13772
|
+
},
|
|
13773
|
+
"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."
|
|
13774
|
+
}
|
|
13775
|
+
},
|
|
13776
|
+
"required": [
|
|
13777
|
+
"keys",
|
|
13778
|
+
"webhooks",
|
|
13779
|
+
"shares"
|
|
13780
|
+
],
|
|
13781
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
13782
|
+
}, { "type": "null" }]
|
|
13783
|
+
},
|
|
13784
|
+
"receivers_once_active": {
|
|
13785
|
+
"description": "As on the list; also null when covers_now is false.",
|
|
13580
13786
|
"anyOf": [{
|
|
13581
13787
|
"type": "object",
|
|
13582
13788
|
"properties": {
|
|
@@ -13619,6 +13825,11 @@ const operationManifest = [
|
|
|
13619
13825
|
"count": {
|
|
13620
13826
|
"type": "integer",
|
|
13621
13827
|
"exclusiveMinimum": 0
|
|
13828
|
+
},
|
|
13829
|
+
"reads_in_full": {
|
|
13830
|
+
"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.",
|
|
13831
|
+
"type": "integer",
|
|
13832
|
+
"minimum": 0
|
|
13622
13833
|
}
|
|
13623
13834
|
},
|
|
13624
13835
|
"required": ["owner", "count"]
|
|
@@ -13666,7 +13877,7 @@ const operationManifest = [
|
|
|
13666
13877
|
"exclusiveMinimum": 0
|
|
13667
13878
|
},
|
|
13668
13879
|
"hosts": {
|
|
13669
|
-
"description": "Distinct sites they deliver to (a host's
|
|
13880
|
+
"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
13881
|
"type": "array",
|
|
13671
13882
|
"items": { "type": "string" }
|
|
13672
13883
|
},
|
|
@@ -13723,7 +13934,7 @@ const operationManifest = [
|
|
|
13723
13934
|
"webhooks",
|
|
13724
13935
|
"shares"
|
|
13725
13936
|
],
|
|
13726
|
-
"description": "Who receives what the rule shares
|
|
13937
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
13727
13938
|
}, { "type": "null" }]
|
|
13728
13939
|
},
|
|
13729
13940
|
"created_at": {
|
|
@@ -13819,6 +14030,7 @@ const operationManifest = [
|
|
|
13819
14030
|
"covers",
|
|
13820
14031
|
"current_version",
|
|
13821
14032
|
"receivers",
|
|
14033
|
+
"receivers_once_active",
|
|
13822
14034
|
"created_at",
|
|
13823
14035
|
"covers_now",
|
|
13824
14036
|
"current"
|
|
@@ -13920,8 +14132,14 @@ const operationManifest = [
|
|
|
13920
14132
|
"email"
|
|
13921
14133
|
]
|
|
13922
14134
|
},
|
|
13923
|
-
"is_objector": {
|
|
13924
|
-
|
|
14135
|
+
"is_objector": {
|
|
14136
|
+
"type": "boolean",
|
|
14137
|
+
"description": "Whether you made it, in your current membership."
|
|
14138
|
+
},
|
|
14139
|
+
"is_author": {
|
|
14140
|
+
"type": "boolean",
|
|
14141
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
14142
|
+
},
|
|
13925
14143
|
"message": {
|
|
13926
14144
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
13927
14145
|
"type": ["string", "null"]
|
|
@@ -14087,7 +14305,7 @@ const operationManifest = [
|
|
|
14087
14305
|
"binaryResponse": false,
|
|
14088
14306
|
"bodyRequired": false,
|
|
14089
14307
|
"command": "list-email-rule-objections",
|
|
14090
|
-
"description": "Objections you made
|
|
14308
|
+
"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
14309
|
"hasJsonBody": false,
|
|
14092
14310
|
"method": "GET",
|
|
14093
14311
|
"operationId": "listEmailRuleObjections",
|
|
@@ -14095,9 +14313,10 @@ const operationManifest = [
|
|
|
14095
14313
|
"pathParams": [],
|
|
14096
14314
|
"queryParams": [
|
|
14097
14315
|
{
|
|
14098
|
-
"default": "
|
|
14099
|
-
"description": "
|
|
14316
|
+
"default": "mine",
|
|
14317
|
+
"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
14318
|
"enum": [
|
|
14319
|
+
"mine",
|
|
14101
14320
|
"outgoing",
|
|
14102
14321
|
"incoming",
|
|
14103
14322
|
"all"
|
|
@@ -14212,8 +14431,14 @@ const operationManifest = [
|
|
|
14212
14431
|
"email"
|
|
14213
14432
|
]
|
|
14214
14433
|
},
|
|
14215
|
-
"is_objector": {
|
|
14216
|
-
|
|
14434
|
+
"is_objector": {
|
|
14435
|
+
"type": "boolean",
|
|
14436
|
+
"description": "Whether you made it, in your current membership."
|
|
14437
|
+
},
|
|
14438
|
+
"is_author": {
|
|
14439
|
+
"type": "boolean",
|
|
14440
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
14441
|
+
},
|
|
14217
14442
|
"message": {
|
|
14218
14443
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
14219
14444
|
"type": ["string", "null"]
|
|
@@ -14253,6 +14478,126 @@ const operationManifest = [
|
|
|
14253
14478
|
"tag": "Email Rule Oversight",
|
|
14254
14479
|
"tagCommand": "email-rule-oversight"
|
|
14255
14480
|
},
|
|
14481
|
+
{
|
|
14482
|
+
"binaryResponse": false,
|
|
14483
|
+
"bodyRequired": false,
|
|
14484
|
+
"command": "list-email-rule-versions-covering-me",
|
|
14485
|
+
"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.",
|
|
14486
|
+
"hasJsonBody": false,
|
|
14487
|
+
"method": "GET",
|
|
14488
|
+
"operationId": "listEmailRuleVersionsCoveringMe",
|
|
14489
|
+
"path": "/email-rules/covering-me/{id}/versions",
|
|
14490
|
+
"pathParams": [{
|
|
14491
|
+
"description": "The rule id.",
|
|
14492
|
+
"enum": null,
|
|
14493
|
+
"name": "id",
|
|
14494
|
+
"required": true,
|
|
14495
|
+
"type": "string"
|
|
14496
|
+
}],
|
|
14497
|
+
"queryParams": [
|
|
14498
|
+
{
|
|
14499
|
+
"description": "Versions per page when versions is not given: 1 to 100, default 50.",
|
|
14500
|
+
"enum": null,
|
|
14501
|
+
"maximum": 100,
|
|
14502
|
+
"minimum": 1,
|
|
14503
|
+
"name": "limit",
|
|
14504
|
+
"required": false,
|
|
14505
|
+
"type": "integer"
|
|
14506
|
+
},
|
|
14507
|
+
{
|
|
14508
|
+
"description": "meta.cursor from the preceding page. Omit for the first page. Not with versions.",
|
|
14509
|
+
"enum": null,
|
|
14510
|
+
"name": "cursor",
|
|
14511
|
+
"required": false,
|
|
14512
|
+
"type": "string"
|
|
14513
|
+
},
|
|
14514
|
+
{
|
|
14515
|
+
"description": "Read only these version numbers, comma-separated, at most 100. Not with limit or cursor.",
|
|
14516
|
+
"enum": null,
|
|
14517
|
+
"name": "versions",
|
|
14518
|
+
"required": false,
|
|
14519
|
+
"type": "string"
|
|
14520
|
+
}
|
|
14521
|
+
],
|
|
14522
|
+
"headerParams": [],
|
|
14523
|
+
"permissions": ["mail:read"],
|
|
14524
|
+
"access": null,
|
|
14525
|
+
"requestSchema": null,
|
|
14526
|
+
"responseSchema": {
|
|
14527
|
+
"type": "array",
|
|
14528
|
+
"items": {
|
|
14529
|
+
"type": "object",
|
|
14530
|
+
"properties": {
|
|
14531
|
+
"version": {
|
|
14532
|
+
"type": "integer",
|
|
14533
|
+
"exclusiveMinimum": 0
|
|
14534
|
+
},
|
|
14535
|
+
"english": {
|
|
14536
|
+
"type": "string",
|
|
14537
|
+
"description": "What its author asked for, in their words."
|
|
14538
|
+
},
|
|
14539
|
+
"tree": {
|
|
14540
|
+
"type": "object",
|
|
14541
|
+
"properties": {
|
|
14542
|
+
"version": {
|
|
14543
|
+
"type": "number",
|
|
14544
|
+
"const": 1
|
|
14545
|
+
},
|
|
14546
|
+
"vocabulary": {
|
|
14547
|
+
"type": "string",
|
|
14548
|
+
"description": "Vocabulary version, such as v1."
|
|
14549
|
+
},
|
|
14550
|
+
"when": {
|
|
14551
|
+
"type": "object",
|
|
14552
|
+
"propertyNames": { "type": "string" },
|
|
14553
|
+
"additionalProperties": {},
|
|
14554
|
+
"description": "A condition {column, op, value?, min_confidence?} (see GET /email-rules/vocabulary) or {all: [...]}, {any: [...]}, {not: ...}."
|
|
14555
|
+
},
|
|
14556
|
+
"questions": {
|
|
14557
|
+
"type": "array",
|
|
14558
|
+
"items": { "type": "string" },
|
|
14559
|
+
"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."
|
|
14560
|
+
}
|
|
14561
|
+
},
|
|
14562
|
+
"required": [
|
|
14563
|
+
"version",
|
|
14564
|
+
"vocabulary",
|
|
14565
|
+
"when",
|
|
14566
|
+
"questions"
|
|
14567
|
+
]
|
|
14568
|
+
},
|
|
14569
|
+
"explanation": {
|
|
14570
|
+
"type": "string",
|
|
14571
|
+
"description": "What the rule matches, as compiled."
|
|
14572
|
+
},
|
|
14573
|
+
"assumptions": {
|
|
14574
|
+
"type": "array",
|
|
14575
|
+
"items": { "type": "string" }
|
|
14576
|
+
},
|
|
14577
|
+
"compiled_by": { "type": "string" },
|
|
14578
|
+
"vocabulary": { "type": "string" },
|
|
14579
|
+
"created_at": {
|
|
14580
|
+
"type": "string",
|
|
14581
|
+
"format": "date-time"
|
|
14582
|
+
}
|
|
14583
|
+
},
|
|
14584
|
+
"required": [
|
|
14585
|
+
"version",
|
|
14586
|
+
"english",
|
|
14587
|
+
"tree",
|
|
14588
|
+
"explanation",
|
|
14589
|
+
"assumptions",
|
|
14590
|
+
"compiled_by",
|
|
14591
|
+
"vocabulary",
|
|
14592
|
+
"created_at"
|
|
14593
|
+
]
|
|
14594
|
+
}
|
|
14595
|
+
},
|
|
14596
|
+
"sdkName": "listEmailRuleVersionsCoveringMe",
|
|
14597
|
+
"summary": "Read versions of a rule over your mail",
|
|
14598
|
+
"tag": "Email Rule Oversight",
|
|
14599
|
+
"tagCommand": "email-rule-oversight"
|
|
14600
|
+
},
|
|
14256
14601
|
{
|
|
14257
14602
|
"binaryResponse": false,
|
|
14258
14603
|
"bodyRequired": false,
|
|
@@ -14358,7 +14703,7 @@ const operationManifest = [
|
|
|
14358
14703
|
"exclusiveMinimum": 0
|
|
14359
14704
|
},
|
|
14360
14705
|
"receivers": {
|
|
14361
|
-
"description": "Null when it could not be read in time; try again.",
|
|
14706
|
+
"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
14707
|
"anyOf": [{
|
|
14363
14708
|
"type": "object",
|
|
14364
14709
|
"properties": {
|
|
@@ -14401,6 +14746,167 @@ const operationManifest = [
|
|
|
14401
14746
|
"count": {
|
|
14402
14747
|
"type": "integer",
|
|
14403
14748
|
"exclusiveMinimum": 0
|
|
14749
|
+
},
|
|
14750
|
+
"reads_in_full": {
|
|
14751
|
+
"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.",
|
|
14752
|
+
"type": "integer",
|
|
14753
|
+
"minimum": 0
|
|
14754
|
+
}
|
|
14755
|
+
},
|
|
14756
|
+
"required": ["owner", "count"]
|
|
14757
|
+
},
|
|
14758
|
+
"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."
|
|
14759
|
+
},
|
|
14760
|
+
"webhooks": {
|
|
14761
|
+
"type": "array",
|
|
14762
|
+
"items": {
|
|
14763
|
+
"type": "object",
|
|
14764
|
+
"properties": {
|
|
14765
|
+
"owner": { "anyOf": [{
|
|
14766
|
+
"type": "object",
|
|
14767
|
+
"properties": {
|
|
14768
|
+
"kind": {
|
|
14769
|
+
"type": "string",
|
|
14770
|
+
"const": "member"
|
|
14771
|
+
},
|
|
14772
|
+
"user_id": {
|
|
14773
|
+
"type": "string",
|
|
14774
|
+
"description": "The member's user id.",
|
|
14775
|
+
"format": "uuid"
|
|
14776
|
+
},
|
|
14777
|
+
"name": {
|
|
14778
|
+
"description": "Their name; null when they have none set.",
|
|
14779
|
+
"type": ["string", "null"]
|
|
14780
|
+
}
|
|
14781
|
+
},
|
|
14782
|
+
"required": [
|
|
14783
|
+
"kind",
|
|
14784
|
+
"user_id",
|
|
14785
|
+
"name"
|
|
14786
|
+
]
|
|
14787
|
+
}, {
|
|
14788
|
+
"type": "object",
|
|
14789
|
+
"properties": { "kind": {
|
|
14790
|
+
"type": "string",
|
|
14791
|
+
"const": "organization",
|
|
14792
|
+
"description": "Held by no member: an organization key, or one whose holder has left."
|
|
14793
|
+
} },
|
|
14794
|
+
"required": ["kind"]
|
|
14795
|
+
}] },
|
|
14796
|
+
"count": {
|
|
14797
|
+
"type": "integer",
|
|
14798
|
+
"exclusiveMinimum": 0
|
|
14799
|
+
},
|
|
14800
|
+
"hosts": {
|
|
14801
|
+
"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.",
|
|
14802
|
+
"type": "array",
|
|
14803
|
+
"items": { "type": "string" }
|
|
14804
|
+
},
|
|
14805
|
+
"hosts_not_listed": {
|
|
14806
|
+
"description": "Hosts past those listed.",
|
|
14807
|
+
"type": "integer",
|
|
14808
|
+
"minimum": 0
|
|
14809
|
+
}
|
|
14810
|
+
},
|
|
14811
|
+
"required": ["owner", "count"]
|
|
14812
|
+
},
|
|
14813
|
+
"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)."
|
|
14814
|
+
},
|
|
14815
|
+
"shares": {
|
|
14816
|
+
"type": "array",
|
|
14817
|
+
"items": {
|
|
14818
|
+
"type": "object",
|
|
14819
|
+
"properties": {
|
|
14820
|
+
"beneficiary": {
|
|
14821
|
+
"type": "object",
|
|
14822
|
+
"properties": {
|
|
14823
|
+
"kind": {
|
|
14824
|
+
"type": "string",
|
|
14825
|
+
"const": "member"
|
|
14826
|
+
},
|
|
14827
|
+
"user_id": {
|
|
14828
|
+
"type": "string",
|
|
14829
|
+
"description": "The member's user id.",
|
|
14830
|
+
"format": "uuid"
|
|
14831
|
+
},
|
|
14832
|
+
"name": {
|
|
14833
|
+
"description": "Their name; null when they have none set.",
|
|
14834
|
+
"type": ["string", "null"]
|
|
14835
|
+
}
|
|
14836
|
+
},
|
|
14837
|
+
"required": [
|
|
14838
|
+
"kind",
|
|
14839
|
+
"user_id",
|
|
14840
|
+
"name"
|
|
14841
|
+
]
|
|
14842
|
+
},
|
|
14843
|
+
"count": {
|
|
14844
|
+
"type": "integer",
|
|
14845
|
+
"exclusiveMinimum": 0
|
|
14846
|
+
}
|
|
14847
|
+
},
|
|
14848
|
+
"required": ["beneficiary", "count"]
|
|
14849
|
+
},
|
|
14850
|
+
"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."
|
|
14851
|
+
}
|
|
14852
|
+
},
|
|
14853
|
+
"required": [
|
|
14854
|
+
"keys",
|
|
14855
|
+
"webhooks",
|
|
14856
|
+
"shares"
|
|
14857
|
+
],
|
|
14858
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
14859
|
+
}, { "type": "null" }]
|
|
14860
|
+
},
|
|
14861
|
+
"receivers_once_active": {
|
|
14862
|
+
"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.",
|
|
14863
|
+
"anyOf": [{
|
|
14864
|
+
"type": "object",
|
|
14865
|
+
"properties": {
|
|
14866
|
+
"keys": {
|
|
14867
|
+
"type": "array",
|
|
14868
|
+
"items": {
|
|
14869
|
+
"type": "object",
|
|
14870
|
+
"properties": {
|
|
14871
|
+
"owner": { "anyOf": [{
|
|
14872
|
+
"type": "object",
|
|
14873
|
+
"properties": {
|
|
14874
|
+
"kind": {
|
|
14875
|
+
"type": "string",
|
|
14876
|
+
"const": "member"
|
|
14877
|
+
},
|
|
14878
|
+
"user_id": {
|
|
14879
|
+
"type": "string",
|
|
14880
|
+
"description": "The member's user id.",
|
|
14881
|
+
"format": "uuid"
|
|
14882
|
+
},
|
|
14883
|
+
"name": {
|
|
14884
|
+
"description": "Their name; null when they have none set.",
|
|
14885
|
+
"type": ["string", "null"]
|
|
14886
|
+
}
|
|
14887
|
+
},
|
|
14888
|
+
"required": [
|
|
14889
|
+
"kind",
|
|
14890
|
+
"user_id",
|
|
14891
|
+
"name"
|
|
14892
|
+
]
|
|
14893
|
+
}, {
|
|
14894
|
+
"type": "object",
|
|
14895
|
+
"properties": { "kind": {
|
|
14896
|
+
"type": "string",
|
|
14897
|
+
"const": "organization",
|
|
14898
|
+
"description": "Held by no member: an organization key, or one whose holder has left."
|
|
14899
|
+
} },
|
|
14900
|
+
"required": ["kind"]
|
|
14901
|
+
}] },
|
|
14902
|
+
"count": {
|
|
14903
|
+
"type": "integer",
|
|
14904
|
+
"exclusiveMinimum": 0
|
|
14905
|
+
},
|
|
14906
|
+
"reads_in_full": {
|
|
14907
|
+
"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.",
|
|
14908
|
+
"type": "integer",
|
|
14909
|
+
"minimum": 0
|
|
14404
14910
|
}
|
|
14405
14911
|
},
|
|
14406
14912
|
"required": ["owner", "count"]
|
|
@@ -14448,7 +14954,7 @@ const operationManifest = [
|
|
|
14448
14954
|
"exclusiveMinimum": 0
|
|
14449
14955
|
},
|
|
14450
14956
|
"hosts": {
|
|
14451
|
-
"description": "Distinct sites they deliver to (a host's
|
|
14957
|
+
"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
14958
|
"type": "array",
|
|
14453
14959
|
"items": { "type": "string" }
|
|
14454
14960
|
},
|
|
@@ -14505,7 +15011,7 @@ const operationManifest = [
|
|
|
14505
15011
|
"webhooks",
|
|
14506
15012
|
"shares"
|
|
14507
15013
|
],
|
|
14508
|
-
"description": "Who receives what the rule shares
|
|
15014
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
14509
15015
|
}, { "type": "null" }]
|
|
14510
15016
|
},
|
|
14511
15017
|
"created_at": {
|
|
@@ -14523,6 +15029,7 @@ const operationManifest = [
|
|
|
14523
15029
|
"covers",
|
|
14524
15030
|
"current_version",
|
|
14525
15031
|
"receivers",
|
|
15032
|
+
"receivers_once_active",
|
|
14526
15033
|
"created_at"
|
|
14527
15034
|
]
|
|
14528
15035
|
}
|
|
@@ -14629,8 +15136,14 @@ const operationManifest = [
|
|
|
14629
15136
|
"email"
|
|
14630
15137
|
]
|
|
14631
15138
|
},
|
|
14632
|
-
"is_objector": {
|
|
14633
|
-
|
|
15139
|
+
"is_objector": {
|
|
15140
|
+
"type": "boolean",
|
|
15141
|
+
"description": "Whether you made it, in your current membership."
|
|
15142
|
+
},
|
|
15143
|
+
"is_author": {
|
|
15144
|
+
"type": "boolean",
|
|
15145
|
+
"description": "Whether it is to a rule you wrote, in your current membership."
|
|
15146
|
+
},
|
|
14634
15147
|
"message": {
|
|
14635
15148
|
"description": "Why the objector objects; null when none was given, or once withdrawn.",
|
|
14636
15149
|
"type": ["string", "null"]
|
|
@@ -14757,7 +15270,7 @@ const operationManifest = [
|
|
|
14757
15270
|
}
|
|
14758
15271
|
},
|
|
14759
15272
|
"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).",
|
|
15273
|
+
"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
15274
|
"maxItems": 10,
|
|
14762
15275
|
"type": "array",
|
|
14763
15276
|
"items": {
|
|
@@ -14780,7 +15293,7 @@ const operationManifest = [
|
|
|
14780
15293
|
"checked": {
|
|
14781
15294
|
"type": "integer",
|
|
14782
15295
|
"minimum": 0,
|
|
14783
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
15296
|
+
"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
15297
|
},
|
|
14785
15298
|
"matched": {
|
|
14786
15299
|
"type": "integer",
|
|
@@ -14799,7 +15312,7 @@ const operationManifest = [
|
|
|
14799
15312
|
"checked": {
|
|
14800
15313
|
"type": "integer",
|
|
14801
15314
|
"minimum": 0,
|
|
14802
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
15315
|
+
"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
15316
|
},
|
|
14804
15317
|
"matched": {
|
|
14805
15318
|
"type": "integer",
|
|
@@ -14896,6 +15409,16 @@ const operationManifest = [
|
|
|
14896
15409
|
"pattern": "^[^\\u0000]*$"
|
|
14897
15410
|
}
|
|
14898
15411
|
},
|
|
15412
|
+
"attachment_names": {
|
|
15413
|
+
"maxItems": 10,
|
|
15414
|
+
"type": "array",
|
|
15415
|
+
"items": {
|
|
15416
|
+
"type": "string",
|
|
15417
|
+
"minLength": 1,
|
|
15418
|
+
"maxLength": 255,
|
|
15419
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
15420
|
+
}
|
|
15421
|
+
},
|
|
14899
15422
|
"automated": { "type": "boolean" },
|
|
14900
15423
|
"from_mailing_list": { "type": "boolean" },
|
|
14901
15424
|
"spam_score": {
|
|
@@ -15206,6 +15729,15 @@ const operationManifest = [
|
|
|
15206
15729
|
"type": "boolean",
|
|
15207
15730
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
15208
15731
|
},
|
|
15732
|
+
"pending_objections": {
|
|
15733
|
+
"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.",
|
|
15734
|
+
"type": "integer",
|
|
15735
|
+
"minimum": 0
|
|
15736
|
+
},
|
|
15737
|
+
"objection_notice": {
|
|
15738
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
15739
|
+
"type": "string"
|
|
15740
|
+
},
|
|
15209
15741
|
"created_at": {
|
|
15210
15742
|
"type": "string",
|
|
15211
15743
|
"format": "date-time"
|
|
@@ -15473,7 +16005,7 @@ const operationManifest = [
|
|
|
15473
16005
|
]
|
|
15474
16006
|
},
|
|
15475
16007
|
"notice": {
|
|
15476
|
-
"description": "What is now shared, in words.",
|
|
16008
|
+
"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
16009
|
"type": "string"
|
|
15478
16010
|
}
|
|
15479
16011
|
},
|
|
@@ -15574,7 +16106,7 @@ const operationManifest = [
|
|
|
15574
16106
|
"binaryResponse": false,
|
|
15575
16107
|
"bodyRequired": true,
|
|
15576
16108
|
"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
|
|
16109
|
+
"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
16110
|
"hasJsonBody": true,
|
|
15579
16111
|
"method": "POST",
|
|
15580
16112
|
"operationId": "compileEmailRule",
|
|
@@ -15607,6 +16139,42 @@ const operationManifest = [
|
|
|
15607
16139
|
"include_sql": {
|
|
15608
16140
|
"description": "Also return the SQL the rule renders to. Off by default.",
|
|
15609
16141
|
"type": "boolean"
|
|
16142
|
+
},
|
|
16143
|
+
"evaluation_scope": {
|
|
16144
|
+
"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.",
|
|
16145
|
+
"type": "string",
|
|
16146
|
+
"enum": [
|
|
16147
|
+
"author",
|
|
16148
|
+
"own_mailboxes",
|
|
16149
|
+
"selected"
|
|
16150
|
+
]
|
|
16151
|
+
},
|
|
16152
|
+
"scope_selection": {
|
|
16153
|
+
"type": "object",
|
|
16154
|
+
"properties": {
|
|
16155
|
+
"addresses": {
|
|
16156
|
+
"maxItems": 100,
|
|
16157
|
+
"type": "array",
|
|
16158
|
+
"items": {
|
|
16159
|
+
"type": "string",
|
|
16160
|
+
"minLength": 3,
|
|
16161
|
+
"maxLength": 320,
|
|
16162
|
+
"pattern": "^[^\\s@]+@[^\\s@]+$"
|
|
16163
|
+
}
|
|
16164
|
+
},
|
|
16165
|
+
"domains": {
|
|
16166
|
+
"maxItems": 50,
|
|
16167
|
+
"type": "array",
|
|
16168
|
+
"items": {
|
|
16169
|
+
"type": "string",
|
|
16170
|
+
"minLength": 1,
|
|
16171
|
+
"maxLength": 253,
|
|
16172
|
+
"pattern": "^[^\\s@]+\\.[^\\s@]+$"
|
|
16173
|
+
}
|
|
16174
|
+
}
|
|
16175
|
+
},
|
|
16176
|
+
"additionalProperties": false,
|
|
16177
|
+
"description": "For a selected rule: inboxes, and domains (each address at them the author reads); each one you can read."
|
|
15610
16178
|
}
|
|
15611
16179
|
},
|
|
15612
16180
|
"required": ["english"],
|
|
@@ -15669,14 +16237,14 @@ const operationManifest = [
|
|
|
15669
16237
|
"enum": ["grant", "do_not_share"]
|
|
15670
16238
|
},
|
|
15671
16239
|
"breadth": {
|
|
15672
|
-
"description": "How many
|
|
16240
|
+
"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
16241
|
"anyOf": [{
|
|
15674
16242
|
"type": "object",
|
|
15675
16243
|
"properties": {
|
|
15676
16244
|
"checked": {
|
|
15677
16245
|
"type": "integer",
|
|
15678
16246
|
"minimum": 0,
|
|
15679
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
16247
|
+
"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
16248
|
},
|
|
15681
16249
|
"matched": {
|
|
15682
16250
|
"type": "integer",
|
|
@@ -15695,7 +16263,7 @@ const operationManifest = [
|
|
|
15695
16263
|
"checked": {
|
|
15696
16264
|
"type": "integer",
|
|
15697
16265
|
"minimum": 0,
|
|
15698
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
16266
|
+
"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
16267
|
},
|
|
15700
16268
|
"matched": {
|
|
15701
16269
|
"type": "integer",
|
|
@@ -15919,6 +16487,16 @@ const operationManifest = [
|
|
|
15919
16487
|
"pattern": "^[^\\u0000]*$"
|
|
15920
16488
|
}
|
|
15921
16489
|
},
|
|
16490
|
+
"attachment_names": {
|
|
16491
|
+
"maxItems": 10,
|
|
16492
|
+
"type": "array",
|
|
16493
|
+
"items": {
|
|
16494
|
+
"type": "string",
|
|
16495
|
+
"minLength": 1,
|
|
16496
|
+
"maxLength": 255,
|
|
16497
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
16498
|
+
}
|
|
16499
|
+
},
|
|
15922
16500
|
"automated": { "type": "boolean" },
|
|
15923
16501
|
"from_mailing_list": { "type": "boolean" },
|
|
15924
16502
|
"spam_score": {
|
|
@@ -15997,7 +16575,7 @@ const operationManifest = [
|
|
|
15997
16575
|
}
|
|
15998
16576
|
},
|
|
15999
16577
|
"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).",
|
|
16578
|
+
"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
16579
|
"maxItems": 10,
|
|
16002
16580
|
"type": "array",
|
|
16003
16581
|
"items": {
|
|
@@ -16020,7 +16598,7 @@ const operationManifest = [
|
|
|
16020
16598
|
"checked": {
|
|
16021
16599
|
"type": "integer",
|
|
16022
16600
|
"minimum": 0,
|
|
16023
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
16601
|
+
"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
16602
|
},
|
|
16025
16603
|
"matched": {
|
|
16026
16604
|
"type": "integer",
|
|
@@ -16039,7 +16617,7 @@ const operationManifest = [
|
|
|
16039
16617
|
"checked": {
|
|
16040
16618
|
"type": "integer",
|
|
16041
16619
|
"minimum": 0,
|
|
16042
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
16620
|
+
"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
16621
|
},
|
|
16044
16622
|
"matched": {
|
|
16045
16623
|
"type": "integer",
|
|
@@ -16148,6 +16726,15 @@ const operationManifest = [
|
|
|
16148
16726
|
"type": "boolean",
|
|
16149
16727
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
16150
16728
|
},
|
|
16729
|
+
"pending_objections": {
|
|
16730
|
+
"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.",
|
|
16731
|
+
"type": "integer",
|
|
16732
|
+
"minimum": 0
|
|
16733
|
+
},
|
|
16734
|
+
"objection_notice": {
|
|
16735
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
16736
|
+
"type": "string"
|
|
16737
|
+
},
|
|
16151
16738
|
"created_at": {
|
|
16152
16739
|
"type": "string",
|
|
16153
16740
|
"format": "date-time"
|
|
@@ -16274,6 +16861,27 @@ const operationManifest = [
|
|
|
16274
16861
|
]
|
|
16275
16862
|
}
|
|
16276
16863
|
},
|
|
16864
|
+
"expectations": {
|
|
16865
|
+
"description": "Its saved expectations, each list by email id, as stored: on every create, and on an update that set or removed them.",
|
|
16866
|
+
"type": "object",
|
|
16867
|
+
"properties": {
|
|
16868
|
+
"match": {
|
|
16869
|
+
"type": "array",
|
|
16870
|
+
"items": {
|
|
16871
|
+
"type": "string",
|
|
16872
|
+
"format": "uuid"
|
|
16873
|
+
}
|
|
16874
|
+
},
|
|
16875
|
+
"no_match": {
|
|
16876
|
+
"type": "array",
|
|
16877
|
+
"items": {
|
|
16878
|
+
"type": "string",
|
|
16879
|
+
"format": "uuid"
|
|
16880
|
+
}
|
|
16881
|
+
}
|
|
16882
|
+
},
|
|
16883
|
+
"required": ["match", "no_match"]
|
|
16884
|
+
},
|
|
16277
16885
|
"expectation_samples": {
|
|
16278
16886
|
"description": "Its saved made-up emails, when this write set or added some.",
|
|
16279
16887
|
"type": "array",
|
|
@@ -16351,6 +16959,16 @@ const operationManifest = [
|
|
|
16351
16959
|
"pattern": "^[^\\u0000]*$"
|
|
16352
16960
|
}
|
|
16353
16961
|
},
|
|
16962
|
+
"attachment_names": {
|
|
16963
|
+
"maxItems": 10,
|
|
16964
|
+
"type": "array",
|
|
16965
|
+
"items": {
|
|
16966
|
+
"type": "string",
|
|
16967
|
+
"minLength": 1,
|
|
16968
|
+
"maxLength": 255,
|
|
16969
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
16970
|
+
}
|
|
16971
|
+
},
|
|
16354
16972
|
"automated": { "type": "boolean" },
|
|
16355
16973
|
"from_mailing_list": { "type": "boolean" },
|
|
16356
16974
|
"spam_score": {
|
|
@@ -16476,6 +17094,10 @@ const operationManifest = [
|
|
|
16476
17094
|
"notice": {
|
|
16477
17095
|
"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
17096
|
"type": "string"
|
|
17097
|
+
},
|
|
17098
|
+
"share_notice": {
|
|
17099
|
+
"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.",
|
|
17100
|
+
"type": "string"
|
|
16479
17101
|
}
|
|
16480
17102
|
},
|
|
16481
17103
|
"required": [
|
|
@@ -16595,7 +17217,7 @@ const operationManifest = [
|
|
|
16595
17217
|
}
|
|
16596
17218
|
},
|
|
16597
17219
|
"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).",
|
|
17220
|
+
"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
17221
|
"maxItems": 10,
|
|
16600
17222
|
"type": "array",
|
|
16601
17223
|
"items": {
|
|
@@ -16618,7 +17240,7 @@ const operationManifest = [
|
|
|
16618
17240
|
"checked": {
|
|
16619
17241
|
"type": "integer",
|
|
16620
17242
|
"minimum": 0,
|
|
16621
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
17243
|
+
"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
17244
|
},
|
|
16623
17245
|
"matched": {
|
|
16624
17246
|
"type": "integer",
|
|
@@ -16637,7 +17259,7 @@ const operationManifest = [
|
|
|
16637
17259
|
"checked": {
|
|
16638
17260
|
"type": "integer",
|
|
16639
17261
|
"minimum": 0,
|
|
16640
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
17262
|
+
"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
17263
|
},
|
|
16642
17264
|
"matched": {
|
|
16643
17265
|
"type": "integer",
|
|
@@ -17097,7 +17719,7 @@ const operationManifest = [
|
|
|
17097
17719
|
"binaryResponse": false,
|
|
17098
17720
|
"bodyRequired": false,
|
|
17099
17721
|
"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).",
|
|
17722
|
+
"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
17723
|
"hasJsonBody": false,
|
|
17102
17724
|
"method": "DELETE",
|
|
17103
17725
|
"operationId": "deleteEmailRule",
|
|
@@ -17149,6 +17771,10 @@ const operationManifest = [
|
|
|
17149
17771
|
"other_keys": {
|
|
17150
17772
|
"description": "How many more keys, not revoked, list the rule that you may not read. They are not named.",
|
|
17151
17773
|
"type": "integer"
|
|
17774
|
+
},
|
|
17775
|
+
"share_notice": {
|
|
17776
|
+
"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.",
|
|
17777
|
+
"type": "string"
|
|
17152
17778
|
}
|
|
17153
17779
|
},
|
|
17154
17780
|
"required": ["deleted"]
|
|
@@ -17321,7 +17947,7 @@ const operationManifest = [
|
|
|
17321
17947
|
"description": "For a selected rule: inboxes, and domains (each address at them the author reads); each one you can read."
|
|
17322
17948
|
},
|
|
17323
17949
|
"rule_id": {
|
|
17324
|
-
"description": "A saved rule you can see: its current version and words.",
|
|
17950
|
+
"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
17951
|
"type": "string",
|
|
17326
17952
|
"format": "uuid"
|
|
17327
17953
|
},
|
|
@@ -17447,6 +18073,10 @@ const operationManifest = [
|
|
|
17447
18073
|
"type": "array",
|
|
17448
18074
|
"items": { "type": "string" }
|
|
17449
18075
|
},
|
|
18076
|
+
"attachment_names": {
|
|
18077
|
+
"type": "array",
|
|
18078
|
+
"items": { "type": "string" }
|
|
18079
|
+
},
|
|
17450
18080
|
"automated": { "type": "boolean" },
|
|
17451
18081
|
"from_mailing_list": { "type": "boolean" }
|
|
17452
18082
|
},
|
|
@@ -17457,6 +18087,7 @@ const operationManifest = [
|
|
|
17457
18087
|
"subject",
|
|
17458
18088
|
"text",
|
|
17459
18089
|
"attachment_types",
|
|
18090
|
+
"attachment_names",
|
|
17460
18091
|
"automated",
|
|
17461
18092
|
"from_mailing_list"
|
|
17462
18093
|
],
|
|
@@ -17671,6 +18302,15 @@ const operationManifest = [
|
|
|
17671
18302
|
"type": "boolean",
|
|
17672
18303
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
17673
18304
|
},
|
|
18305
|
+
"pending_objections": {
|
|
18306
|
+
"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.",
|
|
18307
|
+
"type": "integer",
|
|
18308
|
+
"minimum": 0
|
|
18309
|
+
},
|
|
18310
|
+
"objection_notice": {
|
|
18311
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
18312
|
+
"type": "string"
|
|
18313
|
+
},
|
|
17674
18314
|
"created_at": {
|
|
17675
18315
|
"type": "string",
|
|
17676
18316
|
"format": "date-time"
|
|
@@ -17865,6 +18505,16 @@ const operationManifest = [
|
|
|
17865
18505
|
"pattern": "^[^\\u0000]*$"
|
|
17866
18506
|
}
|
|
17867
18507
|
},
|
|
18508
|
+
"attachment_names": {
|
|
18509
|
+
"maxItems": 10,
|
|
18510
|
+
"type": "array",
|
|
18511
|
+
"items": {
|
|
18512
|
+
"type": "string",
|
|
18513
|
+
"minLength": 1,
|
|
18514
|
+
"maxLength": 255,
|
|
18515
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
18516
|
+
}
|
|
18517
|
+
},
|
|
17868
18518
|
"automated": { "type": "boolean" },
|
|
17869
18519
|
"from_mailing_list": { "type": "boolean" },
|
|
17870
18520
|
"spam_score": {
|
|
@@ -19329,6 +19979,11 @@ const operationManifest = [
|
|
|
19329
19979
|
"count": {
|
|
19330
19980
|
"type": "integer",
|
|
19331
19981
|
"exclusiveMinimum": 0
|
|
19982
|
+
},
|
|
19983
|
+
"reads_in_full": {
|
|
19984
|
+
"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.",
|
|
19985
|
+
"type": "integer",
|
|
19986
|
+
"minimum": 0
|
|
19332
19987
|
}
|
|
19333
19988
|
},
|
|
19334
19989
|
"required": ["owner", "count"]
|
|
@@ -19376,7 +20031,7 @@ const operationManifest = [
|
|
|
19376
20031
|
"exclusiveMinimum": 0
|
|
19377
20032
|
},
|
|
19378
20033
|
"hosts": {
|
|
19379
|
-
"description": "Distinct sites they deliver to (a host's
|
|
20034
|
+
"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
20035
|
"type": "array",
|
|
19381
20036
|
"items": { "type": "string" }
|
|
19382
20037
|
},
|
|
@@ -19433,7 +20088,7 @@ const operationManifest = [
|
|
|
19433
20088
|
"webhooks",
|
|
19434
20089
|
"shares"
|
|
19435
20090
|
],
|
|
19436
|
-
"description": "Who receives what the rule shares
|
|
20091
|
+
"description": "Who receives what the rule shares, by person and count. As receivers, empty unless it is an active grant rule."
|
|
19437
20092
|
}, { "type": "null" }]
|
|
19438
20093
|
}
|
|
19439
20094
|
},
|
|
@@ -20420,6 +21075,15 @@ const operationManifest = [
|
|
|
20420
21075
|
"type": "boolean",
|
|
20421
21076
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
20422
21077
|
},
|
|
21078
|
+
"pending_objections": {
|
|
21079
|
+
"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.",
|
|
21080
|
+
"type": "integer",
|
|
21081
|
+
"minimum": 0
|
|
21082
|
+
},
|
|
21083
|
+
"objection_notice": {
|
|
21084
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
21085
|
+
"type": "string"
|
|
21086
|
+
},
|
|
20423
21087
|
"created_at": {
|
|
20424
21088
|
"type": "string",
|
|
20425
21089
|
"format": "date-time"
|
|
@@ -20867,6 +21531,16 @@ const operationManifest = [
|
|
|
20867
21531
|
"pattern": "^[^\\u0000]*$"
|
|
20868
21532
|
}
|
|
20869
21533
|
},
|
|
21534
|
+
"attachment_names": {
|
|
21535
|
+
"maxItems": 10,
|
|
21536
|
+
"type": "array",
|
|
21537
|
+
"items": {
|
|
21538
|
+
"type": "string",
|
|
21539
|
+
"minLength": 1,
|
|
21540
|
+
"maxLength": 255,
|
|
21541
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
21542
|
+
}
|
|
21543
|
+
},
|
|
20870
21544
|
"automated": { "type": "boolean" },
|
|
20871
21545
|
"from_mailing_list": { "type": "boolean" },
|
|
20872
21546
|
"spam_score": {
|
|
@@ -21177,6 +21851,11 @@ const operationManifest = [
|
|
|
21177
21851
|
"minimum": 0,
|
|
21178
21852
|
"description": "Emails decided on their conditions: matched, near_miss and no_match, less any missing a fact the rule reads."
|
|
21179
21853
|
},
|
|
21854
|
+
"conditions_held": {
|
|
21855
|
+
"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.",
|
|
21856
|
+
"type": "integer",
|
|
21857
|
+
"minimum": 0
|
|
21858
|
+
},
|
|
21180
21859
|
"conditions": {
|
|
21181
21860
|
"type": "array",
|
|
21182
21861
|
"items": {
|
|
@@ -21244,7 +21923,7 @@ const operationManifest = [
|
|
|
21244
21923
|
"warnings": {
|
|
21245
21924
|
"type": "array",
|
|
21246
21925
|
"items": { "type": "string" },
|
|
21247
|
-
"description": "What to look at first, such as what stopped every email when nothing matched."
|
|
21926
|
+
"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
21927
|
}
|
|
21249
21928
|
},
|
|
21250
21929
|
"required": [
|
|
@@ -21447,7 +22126,7 @@ const operationManifest = [
|
|
|
21447
22126
|
"binaryResponse": false,
|
|
21448
22127
|
"bodyRequired": true,
|
|
21449
22128
|
"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).",
|
|
22129
|
+
"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
22130
|
"hasJsonBody": true,
|
|
21452
22131
|
"method": "POST",
|
|
21453
22132
|
"operationId": "testEmailRuleOnSample",
|
|
@@ -21533,7 +22212,7 @@ const operationManifest = [
|
|
|
21533
22212
|
"description": "For a selected rule: inboxes, and domains (each address at them the author reads); each one you can read."
|
|
21534
22213
|
},
|
|
21535
22214
|
"rule_id": {
|
|
21536
|
-
"description": "A saved rule you can see. Its current version is tested.",
|
|
22215
|
+
"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
22216
|
"type": "string",
|
|
21538
22217
|
"format": "uuid"
|
|
21539
22218
|
},
|
|
@@ -21604,6 +22283,17 @@ const operationManifest = [
|
|
|
21604
22283
|
"maxLength": 255
|
|
21605
22284
|
}
|
|
21606
22285
|
},
|
|
22286
|
+
"attachment_names": {
|
|
22287
|
+
"description": "File names of those attachments, which the classifier and the questions read. With attachment_types, the same number, paired in order.",
|
|
22288
|
+
"maxItems": 20,
|
|
22289
|
+
"type": "array",
|
|
22290
|
+
"items": {
|
|
22291
|
+
"type": "string",
|
|
22292
|
+
"minLength": 1,
|
|
22293
|
+
"maxLength": 255,
|
|
22294
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
22295
|
+
}
|
|
22296
|
+
},
|
|
21607
22297
|
"automated": {
|
|
21608
22298
|
"description": "Whether the email was sent automatically, as its headers would show. Defaults to false.",
|
|
21609
22299
|
"type": "boolean"
|
|
@@ -21890,7 +22580,7 @@ const operationManifest = [
|
|
|
21890
22580
|
}
|
|
21891
22581
|
},
|
|
21892
22582
|
"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).",
|
|
22583
|
+
"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
22584
|
"maxItems": 10,
|
|
21895
22585
|
"type": "array",
|
|
21896
22586
|
"items": {
|
|
@@ -21913,7 +22603,7 @@ const operationManifest = [
|
|
|
21913
22603
|
"checked": {
|
|
21914
22604
|
"type": "integer",
|
|
21915
22605
|
"minimum": 0,
|
|
21916
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
22606
|
+
"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
22607
|
},
|
|
21918
22608
|
"matched": {
|
|
21919
22609
|
"type": "integer",
|
|
@@ -21932,7 +22622,7 @@ const operationManifest = [
|
|
|
21932
22622
|
"checked": {
|
|
21933
22623
|
"type": "integer",
|
|
21934
22624
|
"minimum": 0,
|
|
21935
|
-
"description": "Classified emails the conditions were decided for: of the newest 200 from the last 30 days in your own mailboxes
|
|
22625
|
+
"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
22626
|
},
|
|
21937
22627
|
"matched": {
|
|
21938
22628
|
"type": "integer",
|
|
@@ -22091,6 +22781,16 @@ const operationManifest = [
|
|
|
22091
22781
|
"pattern": "^[^\\u0000]*$"
|
|
22092
22782
|
}
|
|
22093
22783
|
},
|
|
22784
|
+
"attachment_names": {
|
|
22785
|
+
"maxItems": 10,
|
|
22786
|
+
"type": "array",
|
|
22787
|
+
"items": {
|
|
22788
|
+
"type": "string",
|
|
22789
|
+
"minLength": 1,
|
|
22790
|
+
"maxLength": 255,
|
|
22791
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
22792
|
+
}
|
|
22793
|
+
},
|
|
22094
22794
|
"automated": { "type": "boolean" },
|
|
22095
22795
|
"from_mailing_list": { "type": "boolean" },
|
|
22096
22796
|
"spam_score": {
|
|
@@ -22198,6 +22898,16 @@ const operationManifest = [
|
|
|
22198
22898
|
"pattern": "^[^\\u0000]*$"
|
|
22199
22899
|
}
|
|
22200
22900
|
},
|
|
22901
|
+
"attachment_names": {
|
|
22902
|
+
"maxItems": 10,
|
|
22903
|
+
"type": "array",
|
|
22904
|
+
"items": {
|
|
22905
|
+
"type": "string",
|
|
22906
|
+
"minLength": 1,
|
|
22907
|
+
"maxLength": 255,
|
|
22908
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
22909
|
+
}
|
|
22910
|
+
},
|
|
22201
22911
|
"automated": { "type": "boolean" },
|
|
22202
22912
|
"from_mailing_list": { "type": "boolean" },
|
|
22203
22913
|
"spam_score": {
|
|
@@ -22332,6 +23042,15 @@ const operationManifest = [
|
|
|
22332
23042
|
"type": "boolean",
|
|
22333
23043
|
"description": "Whether you are its author, in your current membership. Only its author edits it."
|
|
22334
23044
|
},
|
|
23045
|
+
"pending_objections": {
|
|
23046
|
+
"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.",
|
|
23047
|
+
"type": "integer",
|
|
23048
|
+
"minimum": 0
|
|
23049
|
+
},
|
|
23050
|
+
"objection_notice": {
|
|
23051
|
+
"description": "With pending_objections above 0: that members asked you to turn it off, and how to answer.",
|
|
23052
|
+
"type": "string"
|
|
23053
|
+
},
|
|
22335
23054
|
"created_at": {
|
|
22336
23055
|
"type": "string",
|
|
22337
23056
|
"format": "date-time"
|
|
@@ -22458,6 +23177,27 @@ const operationManifest = [
|
|
|
22458
23177
|
]
|
|
22459
23178
|
}
|
|
22460
23179
|
},
|
|
23180
|
+
"expectations": {
|
|
23181
|
+
"description": "Its saved expectations, each list by email id, as stored: on every create, and on an update that set or removed them.",
|
|
23182
|
+
"type": "object",
|
|
23183
|
+
"properties": {
|
|
23184
|
+
"match": {
|
|
23185
|
+
"type": "array",
|
|
23186
|
+
"items": {
|
|
23187
|
+
"type": "string",
|
|
23188
|
+
"format": "uuid"
|
|
23189
|
+
}
|
|
23190
|
+
},
|
|
23191
|
+
"no_match": {
|
|
23192
|
+
"type": "array",
|
|
23193
|
+
"items": {
|
|
23194
|
+
"type": "string",
|
|
23195
|
+
"format": "uuid"
|
|
23196
|
+
}
|
|
23197
|
+
}
|
|
23198
|
+
},
|
|
23199
|
+
"required": ["match", "no_match"]
|
|
23200
|
+
},
|
|
22461
23201
|
"expectation_samples": {
|
|
22462
23202
|
"description": "Its saved made-up emails, when this write set or added some.",
|
|
22463
23203
|
"type": "array",
|
|
@@ -22535,6 +23275,16 @@ const operationManifest = [
|
|
|
22535
23275
|
"pattern": "^[^\\u0000]*$"
|
|
22536
23276
|
}
|
|
22537
23277
|
},
|
|
23278
|
+
"attachment_names": {
|
|
23279
|
+
"maxItems": 10,
|
|
23280
|
+
"type": "array",
|
|
23281
|
+
"items": {
|
|
23282
|
+
"type": "string",
|
|
23283
|
+
"minLength": 1,
|
|
23284
|
+
"maxLength": 255,
|
|
23285
|
+
"pattern": "^[^\\u0000-\\u001f\\u007f]*$"
|
|
23286
|
+
}
|
|
23287
|
+
},
|
|
22538
23288
|
"automated": { "type": "boolean" },
|
|
22539
23289
|
"from_mailing_list": { "type": "boolean" },
|
|
22540
23290
|
"spam_score": {
|
|
@@ -22660,6 +23410,10 @@ const operationManifest = [
|
|
|
22660
23410
|
"notice": {
|
|
22661
23411
|
"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
23412
|
"type": "string"
|
|
23413
|
+
},
|
|
23414
|
+
"share_notice": {
|
|
23415
|
+
"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.",
|
|
23416
|
+
"type": "string"
|
|
22663
23417
|
}
|
|
22664
23418
|
},
|
|
22665
23419
|
"required": [
|
|
@@ -24272,6 +25026,29 @@ const operationManifest = [
|
|
|
24272
25026
|
}
|
|
24273
25027
|
}
|
|
24274
25028
|
},
|
|
25029
|
+
"attachments": {
|
|
25030
|
+
"type": "array",
|
|
25031
|
+
"items": {
|
|
25032
|
+
"type": "object",
|
|
25033
|
+
"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",
|
|
25034
|
+
"properties": {
|
|
25035
|
+
"filename": { "type": ["string", "null"] },
|
|
25036
|
+
"content_type": { "type": ["string", "null"] },
|
|
25037
|
+
"size_bytes": { "type": "integer" },
|
|
25038
|
+
"sha256": { "type": ["string", "null"] },
|
|
25039
|
+
"part_index": {
|
|
25040
|
+
"type": "integer",
|
|
25041
|
+
"description": "Zero-based index of this part within the message."
|
|
25042
|
+
},
|
|
25043
|
+
"tar_path": {
|
|
25044
|
+
"type": "string",
|
|
25045
|
+
"description": "This part's file name inside the message's attachments archive. Absent on attachments stored before it was recorded."
|
|
25046
|
+
}
|
|
25047
|
+
},
|
|
25048
|
+
"required": ["size_bytes"]
|
|
25049
|
+
},
|
|
25050
|
+
"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}`."
|
|
25051
|
+
},
|
|
24275
25052
|
"imported": {
|
|
24276
25053
|
"type": ["object", "null"],
|
|
24277
25054
|
"description": "Historical acquisition; never sender or SMTP delivery proof. Null for live mail. Excluded from live tails and deltas.",
|
|
@@ -24330,6 +25107,7 @@ const operationManifest = [
|
|
|
24330
25107
|
"from_verified",
|
|
24331
25108
|
"from_header_email",
|
|
24332
25109
|
"from_name",
|
|
25110
|
+
"attachments",
|
|
24333
25111
|
"imported",
|
|
24334
25112
|
"snippet"
|
|
24335
25113
|
]
|
|
@@ -24590,6 +25368,94 @@ const operationManifest = [
|
|
|
24590
25368
|
"tag": "Emails",
|
|
24591
25369
|
"tagCommand": "emails"
|
|
24592
25370
|
},
|
|
25371
|
+
{
|
|
25372
|
+
"binaryResponse": false,
|
|
25373
|
+
"bodyRequired": true,
|
|
25374
|
+
"command": "import-google-mail-message",
|
|
25375
|
+
"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.",
|
|
25376
|
+
"hasJsonBody": true,
|
|
25377
|
+
"method": "POST",
|
|
25378
|
+
"operationId": "importGoogleMailMessage",
|
|
25379
|
+
"path": "/mail-imports/google/messages",
|
|
25380
|
+
"pathParams": [],
|
|
25381
|
+
"queryParams": [],
|
|
25382
|
+
"headerParams": [{
|
|
25383
|
+
"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.",
|
|
25384
|
+
"enum": null,
|
|
25385
|
+
"name": "X-Primitive-Google-Access-Token",
|
|
25386
|
+
"required": true,
|
|
25387
|
+
"type": "string"
|
|
25388
|
+
}, {
|
|
25389
|
+
"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.",
|
|
25390
|
+
"enum": null,
|
|
25391
|
+
"name": "Idempotency-Key",
|
|
25392
|
+
"required": false,
|
|
25393
|
+
"type": "string"
|
|
25394
|
+
}],
|
|
25395
|
+
"permissions": ["mail:read"],
|
|
25396
|
+
"access": null,
|
|
25397
|
+
"requestSchema": {
|
|
25398
|
+
"type": "object",
|
|
25399
|
+
"properties": { "message_id": {
|
|
25400
|
+
"type": "string",
|
|
25401
|
+
"pattern": "^[A-Za-z0-9_-]{1,128}$"
|
|
25402
|
+
} },
|
|
25403
|
+
"required": ["message_id"],
|
|
25404
|
+
"additionalProperties": false
|
|
25405
|
+
},
|
|
25406
|
+
"responseSchema": { "anyOf": [
|
|
25407
|
+
{
|
|
25408
|
+
"type": "object",
|
|
25409
|
+
"properties": {
|
|
25410
|
+
"status": {
|
|
25411
|
+
"type": "string",
|
|
25412
|
+
"enum": ["imported", "already_present"]
|
|
25413
|
+
},
|
|
25414
|
+
"email_id": {
|
|
25415
|
+
"type": "string",
|
|
25416
|
+
"format": "uuid",
|
|
25417
|
+
"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)$"
|
|
25418
|
+
}
|
|
25419
|
+
},
|
|
25420
|
+
"required": ["status", "email_id"]
|
|
25421
|
+
},
|
|
25422
|
+
{
|
|
25423
|
+
"type": "object",
|
|
25424
|
+
"properties": { "status": {
|
|
25425
|
+
"type": "string",
|
|
25426
|
+
"enum": [
|
|
25427
|
+
"suppressed",
|
|
25428
|
+
"in_progress",
|
|
25429
|
+
"indeterminate"
|
|
25430
|
+
]
|
|
25431
|
+
} },
|
|
25432
|
+
"required": ["status"]
|
|
25433
|
+
},
|
|
25434
|
+
{
|
|
25435
|
+
"type": "object",
|
|
25436
|
+
"properties": {
|
|
25437
|
+
"status": {
|
|
25438
|
+
"type": "string",
|
|
25439
|
+
"const": "skipped"
|
|
25440
|
+
},
|
|
25441
|
+
"reason": {
|
|
25442
|
+
"type": "string",
|
|
25443
|
+
"enum": [
|
|
25444
|
+
"excluded_label",
|
|
25445
|
+
"out_of_window",
|
|
25446
|
+
"too_large",
|
|
25447
|
+
"provider_missing"
|
|
25448
|
+
]
|
|
25449
|
+
}
|
|
25450
|
+
},
|
|
25451
|
+
"required": ["status", "reason"]
|
|
25452
|
+
}
|
|
25453
|
+
] },
|
|
25454
|
+
"sdkName": "importGoogleMailMessage",
|
|
25455
|
+
"summary": "Import one historical Google Workspace message",
|
|
25456
|
+
"tag": "Emails",
|
|
25457
|
+
"tagCommand": "emails"
|
|
25458
|
+
},
|
|
24593
25459
|
{
|
|
24594
25460
|
"binaryResponse": false,
|
|
24595
25461
|
"bodyRequired": false,
|
|
@@ -25306,6 +26172,50 @@ const operationManifest = [
|
|
|
25306
26172
|
"tag": "Emails",
|
|
25307
26173
|
"tagCommand": "emails"
|
|
25308
26174
|
},
|
|
26175
|
+
{
|
|
26176
|
+
"binaryResponse": false,
|
|
26177
|
+
"bodyRequired": true,
|
|
26178
|
+
"command": "reconcile-google-mail-import",
|
|
26179
|
+
"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.",
|
|
26180
|
+
"hasJsonBody": true,
|
|
26181
|
+
"method": "POST",
|
|
26182
|
+
"operationId": "reconcileGoogleMailImport",
|
|
26183
|
+
"path": "/mail-imports/google/reconcile",
|
|
26184
|
+
"pathParams": [],
|
|
26185
|
+
"queryParams": [],
|
|
26186
|
+
"headerParams": [{
|
|
26187
|
+
"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.",
|
|
26188
|
+
"enum": null,
|
|
26189
|
+
"name": "Idempotency-Key",
|
|
26190
|
+
"required": false,
|
|
26191
|
+
"type": "string"
|
|
26192
|
+
}],
|
|
26193
|
+
"permissions": ["mail:read"],
|
|
26194
|
+
"access": null,
|
|
26195
|
+
"requestSchema": {
|
|
26196
|
+
"type": "object",
|
|
26197
|
+
"properties": {},
|
|
26198
|
+
"additionalProperties": false
|
|
26199
|
+
},
|
|
26200
|
+
"responseSchema": {
|
|
26201
|
+
"type": "object",
|
|
26202
|
+
"properties": {
|
|
26203
|
+
"cleaned": {
|
|
26204
|
+
"type": "integer",
|
|
26205
|
+
"minimum": 0
|
|
26206
|
+
},
|
|
26207
|
+
"unresolved": {
|
|
26208
|
+
"type": "integer",
|
|
26209
|
+
"minimum": 0
|
|
26210
|
+
}
|
|
26211
|
+
},
|
|
26212
|
+
"required": ["cleaned", "unresolved"]
|
|
26213
|
+
},
|
|
26214
|
+
"sdkName": "reconcileGoogleMailImport",
|
|
26215
|
+
"summary": "Reconcile scoped historical import attempts",
|
|
26216
|
+
"tag": "Emails",
|
|
26217
|
+
"tagCommand": "emails"
|
|
26218
|
+
},
|
|
25309
26219
|
{
|
|
25310
26220
|
"binaryResponse": false,
|
|
25311
26221
|
"bodyRequired": false,
|
|
@@ -45776,6 +46686,33 @@ const operationManifest = [
|
|
|
45776
46686
|
"type": "boolean",
|
|
45777
46687
|
"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
46688
|
},
|
|
46689
|
+
"unsubscribe": {
|
|
46690
|
+
"type": "object",
|
|
46691
|
+
"additionalProperties": false,
|
|
46692
|
+
"required": ["url"],
|
|
46693
|
+
"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.",
|
|
46694
|
+
"properties": {
|
|
46695
|
+
"url": {
|
|
46696
|
+
"type": "string",
|
|
46697
|
+
"minLength": 1,
|
|
46698
|
+
"maxLength": 700,
|
|
46699
|
+
"pattern": "^[Hh][Tt][Tt][Pp][Ss]://(?:[A-Za-z0-9\\-._~:/?#\\[\\]@!$&'()*+;=]|%[0-9A-Fa-f]{2})+$",
|
|
46700
|
+
"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."
|
|
46701
|
+
},
|
|
46702
|
+
"one_click": {
|
|
46703
|
+
"type": "boolean",
|
|
46704
|
+
"default": true,
|
|
46705
|
+
"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."
|
|
46706
|
+
},
|
|
46707
|
+
"mailto": {
|
|
46708
|
+
"type": "string",
|
|
46709
|
+
"minLength": 3,
|
|
46710
|
+
"maxLength": 254,
|
|
46711
|
+
"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])?)+$",
|
|
46712
|
+
"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."
|
|
46713
|
+
}
|
|
46714
|
+
}
|
|
46715
|
+
},
|
|
45779
46716
|
"headers": {
|
|
45780
46717
|
"type": "object",
|
|
45781
46718
|
"maxProperties": 25,
|
|
@@ -46937,6 +47874,33 @@ const operationManifest = [
|
|
|
46937
47874
|
}
|
|
46938
47875
|
}
|
|
46939
47876
|
},
|
|
47877
|
+
"unsubscribe": {
|
|
47878
|
+
"type": "object",
|
|
47879
|
+
"additionalProperties": false,
|
|
47880
|
+
"required": ["url"],
|
|
47881
|
+
"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.",
|
|
47882
|
+
"properties": {
|
|
47883
|
+
"url": {
|
|
47884
|
+
"type": "string",
|
|
47885
|
+
"minLength": 1,
|
|
47886
|
+
"maxLength": 700,
|
|
47887
|
+
"pattern": "^[Hh][Tt][Tt][Pp][Ss]://(?:[A-Za-z0-9\\-._~:/?#\\[\\]@!$&'()*+;=]|%[0-9A-Fa-f]{2})+$",
|
|
47888
|
+
"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."
|
|
47889
|
+
},
|
|
47890
|
+
"one_click": {
|
|
47891
|
+
"type": "boolean",
|
|
47892
|
+
"default": true,
|
|
47893
|
+
"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."
|
|
47894
|
+
},
|
|
47895
|
+
"mailto": {
|
|
47896
|
+
"type": "string",
|
|
47897
|
+
"minLength": 3,
|
|
47898
|
+
"maxLength": 254,
|
|
47899
|
+
"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])?)+$",
|
|
47900
|
+
"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."
|
|
47901
|
+
}
|
|
47902
|
+
}
|
|
47903
|
+
},
|
|
46940
47904
|
"headers": {
|
|
46941
47905
|
"type": "object",
|
|
46942
47906
|
"maxProperties": 25,
|
|
@@ -47417,6 +48381,33 @@ const operationManifest = [
|
|
|
47417
48381
|
}
|
|
47418
48382
|
}
|
|
47419
48383
|
},
|
|
48384
|
+
"unsubscribe": {
|
|
48385
|
+
"type": "object",
|
|
48386
|
+
"additionalProperties": false,
|
|
48387
|
+
"required": ["url"],
|
|
48388
|
+
"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.",
|
|
48389
|
+
"properties": {
|
|
48390
|
+
"url": {
|
|
48391
|
+
"type": "string",
|
|
48392
|
+
"minLength": 1,
|
|
48393
|
+
"maxLength": 700,
|
|
48394
|
+
"pattern": "^[Hh][Tt][Tt][Pp][Ss]://(?:[A-Za-z0-9\\-._~:/?#\\[\\]@!$&'()*+;=]|%[0-9A-Fa-f]{2})+$",
|
|
48395
|
+
"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."
|
|
48396
|
+
},
|
|
48397
|
+
"one_click": {
|
|
48398
|
+
"type": "boolean",
|
|
48399
|
+
"default": true,
|
|
48400
|
+
"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."
|
|
48401
|
+
},
|
|
48402
|
+
"mailto": {
|
|
48403
|
+
"type": "string",
|
|
48404
|
+
"minLength": 3,
|
|
48405
|
+
"maxLength": 254,
|
|
48406
|
+
"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])?)+$",
|
|
48407
|
+
"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."
|
|
48408
|
+
}
|
|
48409
|
+
}
|
|
48410
|
+
},
|
|
47420
48411
|
"headers": {
|
|
47421
48412
|
"type": "object",
|
|
47422
48413
|
"maxProperties": 25,
|
|
@@ -52064,6 +53055,7 @@ const SAMPLE_EMAIL_KEYS = /* @__PURE__ */ new Set([
|
|
|
52064
53055
|
"subject",
|
|
52065
53056
|
"text",
|
|
52066
53057
|
"attachment_types",
|
|
53058
|
+
"attachment_names",
|
|
52067
53059
|
"automated",
|
|
52068
53060
|
"from_mailing_list",
|
|
52069
53061
|
"spam_score"
|
|
@@ -52091,6 +53083,10 @@ function checkSampleEmail(email, at) {
|
|
|
52091
53083
|
list("to", 1);
|
|
52092
53084
|
list("cc", 0);
|
|
52093
53085
|
list("attachment_types", 0);
|
|
53086
|
+
list("attachment_names", 0);
|
|
53087
|
+
const types = email.attachment_types;
|
|
53088
|
+
const names = email.attachment_names;
|
|
53089
|
+
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
53090
|
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
53091
|
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
53092
|
for (const key of ["automated", "from_mailing_list"]) if (email[key] !== void 0 && typeof email[key] !== "boolean") fail(`${key} must be true or false`);
|
|
@@ -52647,7 +53643,9 @@ function answerText(answer) {
|
|
|
52647
53643
|
function conditionLines(summary) {
|
|
52648
53644
|
const conditions = Array.isArray(summary?.conditions) ? summary.conditions : [];
|
|
52649
53645
|
if (conditions.length === 0) return [];
|
|
52650
|
-
|
|
53646
|
+
const held = summary?.conditions_held;
|
|
53647
|
+
const together = typeof held === "number" ? `; together they held on ${held}` : "";
|
|
53648
|
+
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
53649
|
}
|
|
52652
53650
|
function questionLines(summary, results) {
|
|
52653
53651
|
const questions = Array.isArray(summary?.questions) ? summary.questions : [];
|
|
@@ -52991,6 +53989,10 @@ function authorLine(author) {
|
|
|
52991
53989
|
if (name || email) return `Author: ${name ?? email}`;
|
|
52992
53990
|
return `Author: user ${author.user_id} (name and email not shown to you)`;
|
|
52993
53991
|
}
|
|
53992
|
+
/** A note the server wrote on a rule answer, as a line, or undefined. */
|
|
53993
|
+
function noteLine(note) {
|
|
53994
|
+
return typeof note === "string" && note.trim() ? note.trim() : void 0;
|
|
53995
|
+
}
|
|
52994
53996
|
/** The stderr report of a rule written by create-email-rule or update-email-rule. */
|
|
52995
53997
|
function writtenEmailRuleReport(data, request) {
|
|
52996
53998
|
if (!isRecord(data)) return { lines: [] };
|
|
@@ -53005,11 +54007,17 @@ function writtenEmailRuleReport(data, request) {
|
|
|
53005
54007
|
if (restored) lines.push(restored);
|
|
53006
54008
|
const reach = affectsLine(rule.affects);
|
|
53007
54009
|
if (reach) lines.push(reach);
|
|
54010
|
+
for (const note of [rule.share_notice, rule.notice]) {
|
|
54011
|
+
const line = noteLine(note);
|
|
54012
|
+
if (line) lines.push(line);
|
|
54013
|
+
}
|
|
53008
54014
|
const sentExpectations = sentExpectationsIn(request.body);
|
|
53009
54015
|
const name = writtenSampleNamer(request.body, request.flags, rule.expectation_samples);
|
|
53010
54016
|
const checked = expectationsCheckLine(rule.expectations_check, ruleId, name);
|
|
53011
54017
|
if (checked) lines.push(checked);
|
|
53012
54018
|
else if (sentExpectations) lines.push(`Expectations were not checked on this write. Test them with \`primitive email-rules test-email-rule --rule-id ${ruleId}\`.`);
|
|
54019
|
+
const objections = noteLine(rule.objection_notice);
|
|
54020
|
+
if (objections) lines.push(objections);
|
|
53013
54021
|
if (request.flags?.["fail-on-expectations"] !== true) return { lines };
|
|
53014
54022
|
return {
|
|
53015
54023
|
lines,
|
|
@@ -53060,7 +54068,9 @@ function deleteEmailRuleReport(data, request) {
|
|
|
53060
54068
|
const answer = data;
|
|
53061
54069
|
const lines = [];
|
|
53062
54070
|
const ended = Array.isArray(answer.ended_shares) ? answer.ended_shares.length : 0;
|
|
53063
|
-
|
|
54071
|
+
const shareNotice = noteLine(answer.share_notice);
|
|
54072
|
+
if (shareNotice) lines.push(shareNotice);
|
|
54073
|
+
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
54074
|
const keys = Array.isArray(answer.keys) ? answer.keys : [];
|
|
53065
54075
|
const others = typeof answer.other_keys === "number" && answer.other_keys > 0 ? answer.other_keys : 0;
|
|
53066
54076
|
const ruleId = typeof request.path.id === "string" ? request.path.id : "<rule-id>";
|
|
@@ -53097,16 +54107,37 @@ function readAgain(id) {
|
|
|
53097
54107
|
return `Read it again with \`primitive email-rules get-email-rule ${id}\` and send the write again`;
|
|
53098
54108
|
}
|
|
53099
54109
|
/**
|
|
54110
|
+
* Who reads an active rule, from a refusal's details.read_by: the server
|
|
54111
|
+
* sends it when it checked the write against the rule's expectations because
|
|
54112
|
+
* API keys or webhooks read the rule, whether or not the write asked.
|
|
54113
|
+
* Undefined without it.
|
|
54114
|
+
*/
|
|
54115
|
+
function readByText(details) {
|
|
54116
|
+
const readBy = details.read_by;
|
|
54117
|
+
if (!isRecord(readBy)) return void 0;
|
|
54118
|
+
const { keys, webhooks } = readBy;
|
|
54119
|
+
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)";
|
|
54120
|
+
}
|
|
54121
|
+
/** How to save a write the default check refused, without the check. */
|
|
54122
|
+
function saveUncheckedText(flags) {
|
|
54123
|
+
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";
|
|
54124
|
+
}
|
|
54125
|
+
/**
|
|
53100
54126
|
* The hint for update-email-rule's refusals: an email_rule_conflict by its
|
|
53101
54127
|
* details.reason (version_moved, revision_moved, expectations_moved,
|
|
53102
|
-
* rule_changed), and the expectations guard's
|
|
53103
|
-
* expectations_undecided, expectations_unreadable and
|
|
53104
|
-
*
|
|
54128
|
+
* rule_changed, readers_changed), and the expectations guard's
|
|
54129
|
+
* expectations_failed, expectations_undecided, expectations_unreadable and
|
|
54130
|
+
* no_expectations. The guard runs when the write sends if_expectations_pass,
|
|
54131
|
+
* and by default (details.read_by) when it changes what an active rule that
|
|
54132
|
+
* API keys or webhooks read grants. Nothing was saved in any of them.
|
|
53105
54133
|
*/
|
|
53106
54134
|
function updateEmailRuleErrorHint(code, payload, ruleId, body, flags) {
|
|
53107
54135
|
const id = typeof ruleId === "string" && ruleId ? ruleId : "<rule-id>";
|
|
53108
54136
|
const details = errorDetails(payload);
|
|
53109
54137
|
const guarded = isRecord(body) && body.if_expectations_pass === true;
|
|
54138
|
+
const readBy = readByText(details);
|
|
54139
|
+
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";
|
|
54140
|
+
const unchecked = readBy ? ` The rule is active and ${readBy}; to save the write without the check, ${saveUncheckedText(flags)}.` : "";
|
|
53110
54141
|
if (code === "email_rule_conflict") switch (details.reason) {
|
|
53111
54142
|
case "version_moved": return versionMovedHint(payload, ruleId);
|
|
53112
54143
|
case "revision_moved": {
|
|
@@ -53115,6 +54146,7 @@ function updateEmailRuleErrorHint(code, payload, ruleId, body, flags) {
|
|
|
53115
54146
|
}
|
|
53116
54147
|
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
54148
|
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)}.`;
|
|
54149
|
+
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
54150
|
default: return;
|
|
53119
54151
|
}
|
|
53120
54152
|
if (code === "expectations_failed" || code === "expectations_undecided") {
|
|
@@ -53131,16 +54163,16 @@ function updateEmailRuleErrorHint(code, payload, ruleId, body, flags) {
|
|
|
53131
54163
|
const reason = String(details.reason);
|
|
53132
54164
|
const samplesMayStay = undecidedSamplesMayStay(undecidedSamples.length, reason);
|
|
53133
54165
|
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,
|
|
54166
|
+
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
54167
|
}
|
|
53136
54168
|
if (code === "expectations_unreadable") {
|
|
53137
54169
|
const unreadable = Array.isArray(details.unreadable) ? details.unreadable.filter((entry) => entry !== null && entry !== void 0 && entry !== "").map(String) : [];
|
|
53138
54170
|
const one = unreadable.length === 1;
|
|
53139
54171
|
const named = unreadable.length > 0 ? `: ${unreadable.join(", ")}` : "";
|
|
53140
54172
|
const them = one ? "it" : "them";
|
|
53141
|
-
return `Hint: the rule, as this write would leave it,
|
|
54173
|
+
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
54174
|
}
|
|
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).";
|
|
54175
|
+
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
54176
|
}
|
|
53145
54177
|
/** The reasons a guard's undecided judgment can be decided by sending the write again. */
|
|
53146
54178
|
const RETRYABLE_REASONS = /* @__PURE__ */ new Set([
|
|
@@ -53197,12 +54229,20 @@ function updateEmailRuleErrorExitCode(payload) {
|
|
|
53197
54229
|
function undecidedSamplesMayStay(count, reason) {
|
|
53198
54230
|
return count > 0 && !RETRYABLE_REASONS.has(reason) && reason !== "author_unresolvable";
|
|
53199
54231
|
}
|
|
54232
|
+
/** Where compile counted breadth, by the evaluation_scope it was sent. */
|
|
54233
|
+
const BREADTH_SCOPE = {
|
|
54234
|
+
own_mailboxes: "in your own mailboxes",
|
|
54235
|
+
author: "in all the mail you can read",
|
|
54236
|
+
selected: "in the inboxes and domains the selected scope names"
|
|
54237
|
+
};
|
|
53200
54238
|
/** The stderr report of compile-email-rule: how many recent emails it holds for. */
|
|
53201
|
-
function compileEmailRuleReport(data) {
|
|
54239
|
+
function compileEmailRuleReport(data, request) {
|
|
53202
54240
|
if (!isRecord(data)) return { lines: [] };
|
|
53203
54241
|
const lines = (Array.isArray(data.warnings) ? data.warnings : []).filter((warning) => typeof warning === "string" && warning.trim() !== "").map((warning) => `Warning: ${warning.trim()}`);
|
|
53204
54242
|
const breadth = data.breadth;
|
|
53205
|
-
|
|
54243
|
+
const sent = isRecord(request?.body) && typeof request.body.evaluation_scope === "string" ? request.body.evaluation_scope : void 0;
|
|
54244
|
+
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}`;
|
|
54245
|
+
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
54246
|
return { lines };
|
|
53207
54247
|
}
|
|
53208
54248
|
/** The stderr report of get-email-rule: who wrote it, and its revision. */
|
|
@@ -53214,6 +54254,8 @@ function getEmailRuleReport(data) {
|
|
|
53214
54254
|
const protection = protectionLine(data);
|
|
53215
54255
|
if (protection) lines.push(protection);
|
|
53216
54256
|
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.`);
|
|
54257
|
+
const objections = noteLine(data.objection_notice);
|
|
54258
|
+
if (objections) lines.push(objections);
|
|
53217
54259
|
return { lines };
|
|
53218
54260
|
}
|
|
53219
54261
|
/** The stderr report of list-email-rules: the protective rules that protect nothing yet, or less than they seem. */
|
|
@@ -53233,9 +54275,11 @@ function listEmailRulesReport(data) {
|
|
|
53233
54275
|
/** create-email-rule's --fail-on-expectations: the exit code follows the check made after saving. */
|
|
53234
54276
|
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
54277
|
/** 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.";
|
|
54278
|
+
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.";
|
|
54279
|
+
/** When update-email-rule judges the made-up emails a samples flag sets. */
|
|
54280
|
+
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
54281
|
/** 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
|
|
54282
|
+
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
54283
|
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
54284
|
/**
|
|
53241
54285
|
* update-email-rule's --fail-on-expectations sends if_expectations_pass, over
|
|
@@ -53313,11 +54357,11 @@ const EMAIL_RULE_OPERATION_EXTENSIONS = {
|
|
|
53313
54357
|
flags: {
|
|
53314
54358
|
"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
54359
|
[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}.
|
|
54360
|
+
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
54361
|
exclusive: [ADD_SAMPLES_FILE_FLAG]
|
|
53318
54362
|
}),
|
|
53319
54363
|
[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}.
|
|
54364
|
+
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
54365
|
exclusive: [SAMPLES_FILE_FLAG]
|
|
53322
54366
|
}),
|
|
53323
54367
|
[PICK_FLAG]: Flags.string({ description: pickFlagHelp([SAMPLES_FILE_FLAG, ADD_SAMPLES_FILE_FLAG]) }),
|
|
@@ -53363,7 +54407,9 @@ const EMAIL_RULE_OPERATION_EXTENSIONS = {
|
|
|
53363
54407
|
bodyProperties: ["expectation_samples"]
|
|
53364
54408
|
},
|
|
53365
54409
|
compileEmailRule: {
|
|
53366
|
-
flags:
|
|
54410
|
+
flags: scopeSelectionFlags(),
|
|
54411
|
+
bodyFields: scopeSelectionBodyFields,
|
|
54412
|
+
bodyProperties: ["scope_selection"],
|
|
53367
54413
|
report: compileEmailRuleReport
|
|
53368
54414
|
},
|
|
53369
54415
|
endEmailRuleShare: {
|
|
@@ -55530,7 +56576,7 @@ function savedConnectedProfiles(configDir, exclude) {
|
|
|
55530
56576
|
*/
|
|
55531
56577
|
async function otherProfiles(configDir, session, current) {
|
|
55532
56578
|
if (session) try {
|
|
55533
|
-
const { connectedProfilesForSession } = await import("./machine-session-
|
|
56579
|
+
const { connectedProfilesForSession } = await import("./machine-session-BMr-zPLx.js").then((n) => n.s);
|
|
55534
56580
|
return {
|
|
55535
56581
|
inSession: true,
|
|
55536
56582
|
profiles: connectedProfilesForSession(configDir, session, current)
|
|
@@ -55604,6 +56650,96 @@ async function explainPendingMailNotFound(configDir, emailId, write = (line) =>
|
|
|
55604
56650
|
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
56651
|
} catch {}
|
|
55606
56652
|
}
|
|
56653
|
+
// src/oclif/rule-list-defaults.ts
|
|
56654
|
+
/** The box the objection list asks for when --box is not given: objections you made and objections to rules you wrote. */
|
|
56655
|
+
const OBJECTION_BOX_DEFAULT = "mine";
|
|
56656
|
+
/** The box asked for instead when a server refuses OBJECTION_BOX_DEFAULT: objections you made. */
|
|
56657
|
+
const OBJECTION_BOX_FALLBACK = "outgoing";
|
|
56658
|
+
/** --box on `email-rule-oversight list-email-rule-objections`, with the CLI's default. */
|
|
56659
|
+
const OBJECTION_BOX_FLAG = {
|
|
56660
|
+
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.",
|
|
56661
|
+
options: [
|
|
56662
|
+
OBJECTION_BOX_DEFAULT,
|
|
56663
|
+
"outgoing",
|
|
56664
|
+
"incoming",
|
|
56665
|
+
"all"
|
|
56666
|
+
]
|
|
56667
|
+
};
|
|
56668
|
+
/**
|
|
56669
|
+
* The query to send: for the objection list read without --box, the CLI's
|
|
56670
|
+
* default box by name; any other query as it is.
|
|
56671
|
+
*/
|
|
56672
|
+
function withDefaultObjectionBox(sdkName, query) {
|
|
56673
|
+
return sdkName === "listEmailRuleObjections" && query.box === void 0 ? {
|
|
56674
|
+
...query,
|
|
56675
|
+
box: OBJECTION_BOX_DEFAULT
|
|
56676
|
+
} : query;
|
|
56677
|
+
}
|
|
56678
|
+
function errorBody(payload) {
|
|
56679
|
+
if (payload === null || typeof payload !== "object") return {};
|
|
56680
|
+
const inner = payload.error;
|
|
56681
|
+
return inner !== null && typeof inner === "object" ? inner : payload;
|
|
56682
|
+
}
|
|
56683
|
+
/**
|
|
56684
|
+
* True when an API error is a server that predates box=mine refusing the
|
|
56685
|
+
* value: a validation error whose issue for box is an unknown option, not
|
|
56686
|
+
* any other refusal that happens to name box.
|
|
56687
|
+
*/
|
|
56688
|
+
function isObjectionBoxRefused(payload) {
|
|
56689
|
+
const body = errorBody(payload);
|
|
56690
|
+
return body.code === "validation_error" && typeof body.message === "string" && /(^|,\s*)box: Invalid (option|enum value)/.test(body.message);
|
|
56691
|
+
}
|
|
56692
|
+
/** The error line for `--box mine` given to a server that refuses it. */
|
|
56693
|
+
function objectionBoxErrorHint(payload, flags) {
|
|
56694
|
+
if (flags?.box !== "mine" || !isObjectionBoxRefused(payload)) return void 0;
|
|
56695
|
+
return "This server does not take --box mine: use --box outgoing for objections you made, and --box incoming for objections to rules you wrote.";
|
|
56696
|
+
}
|
|
56697
|
+
const widen = (flags) => `add \`${flags.join(" ")}\` to widen it`;
|
|
56698
|
+
/** The objection list's line: what its defaults left out, and how to see more. */
|
|
56699
|
+
function objectionsNote(box, status, refused) {
|
|
56700
|
+
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.`;
|
|
56701
|
+
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;
|
|
56702
|
+
if (phrase === null) return void 0;
|
|
56703
|
+
return `By default this lists only ${phrase}: ${widen([...box ? ["--box all"] : [], ...status ? ["--status any"] : []])}.`;
|
|
56704
|
+
}
|
|
56705
|
+
/**
|
|
56706
|
+
* What a rule request, share or objection list read with `query` (the
|
|
56707
|
+
* flags as given) left out by its defaults, and the flags that show more.
|
|
56708
|
+
* Said on any page. Undefined for any other list, or when every default was
|
|
56709
|
+
* overridden.
|
|
56710
|
+
*/
|
|
56711
|
+
function ruleListDefaultsNote(sdkName, query, options = {}) {
|
|
56712
|
+
const unset = (name) => query[name] === void 0;
|
|
56713
|
+
const said = (phrase, flags) => phrase === null ? void 0 : `By default this lists only ${phrase}: ${widen(flags)}.`;
|
|
56714
|
+
if (sdkName === "listEmailRuleRequests") {
|
|
56715
|
+
const box = unset("box");
|
|
56716
|
+
const status = unset("status");
|
|
56717
|
+
return said(box && status ? "pending requests made to you" : box ? "requests made to you" : status ? "pending requests" : null, [...box ? ["--box all"] : [], ...status ? ["--status any"] : []]);
|
|
56718
|
+
}
|
|
56719
|
+
if (sdkName === "listEmailRuleShares") {
|
|
56720
|
+
const box = unset("box");
|
|
56721
|
+
const live = unset("live");
|
|
56722
|
+
return said(box && live ? "live shares made with you" : box ? "shares made with you" : live ? "live shares" : null, [...box ? ["--box all"] : [], ...live ? ["--live any"] : []]);
|
|
56723
|
+
}
|
|
56724
|
+
if (sdkName === "listGivenEmailRuleShares") return said(unset("live") ? "live shares of your mail" : null, ["--live any"]);
|
|
56725
|
+
if (sdkName === "listEmailRuleObjections") return objectionsNote(unset("box"), unset("status"), options.objectionBoxRefused === true);
|
|
56726
|
+
}
|
|
56727
|
+
const NOUNS = {
|
|
56728
|
+
listEmailRuleRequests: "requests",
|
|
56729
|
+
listEmailRuleShares: "shares",
|
|
56730
|
+
listGivenEmailRuleShares: "shares",
|
|
56731
|
+
listEmailRuleObjections: "objections"
|
|
56732
|
+
};
|
|
56733
|
+
/**
|
|
56734
|
+
* An empty first page of one of those lists: that nothing matched, then the
|
|
56735
|
+
* line above. Undefined for any other list, when every default was
|
|
56736
|
+
* overridden, or on a later page (--cursor), where the line alone is said.
|
|
56737
|
+
*/
|
|
56738
|
+
function emptyRuleListHint(sdkName, query, options = {}) {
|
|
56739
|
+
if (query.cursor !== void 0) return void 0;
|
|
56740
|
+
const note = ruleListDefaultsNote(sdkName, query, options);
|
|
56741
|
+
return note ? `(no results) No ${NOUNS[sdkName]} match. ${note}` : void 0;
|
|
56742
|
+
}
|
|
55607
56743
|
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
56744
|
const RULE_REQUEST_WEBHOOK_HTTP_HINT = "Hint: rule request and objection events go only to an http webhook (kind http).";
|
|
55609
56745
|
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 +57149,7 @@ const OPERATION_PATH_FLAGS = {
|
|
|
56013
57149
|
flag: "email-id",
|
|
56014
57150
|
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
57151
|
} },
|
|
57152
|
+
listEmailRuleObjections: { box: OBJECTION_BOX_FLAG },
|
|
56016
57153
|
replyToEmail: { id: {
|
|
56017
57154
|
flag: "email-id",
|
|
56018
57155
|
description: EMAIL_ID_NOT_SENT
|
|
@@ -56205,7 +57342,7 @@ function flagForParameter(parameter, override) {
|
|
|
56205
57342
|
});
|
|
56206
57343
|
if (parameter.enum && parameter.enum.length > 0) return Flags.string({
|
|
56207
57344
|
...common,
|
|
56208
|
-
options: parameter.enum
|
|
57345
|
+
options: [...override?.options ?? parameter.enum]
|
|
56209
57346
|
});
|
|
56210
57347
|
return Flags.string(common);
|
|
56211
57348
|
}
|
|
@@ -56461,7 +57598,7 @@ function buildFlags(operation) {
|
|
|
56461
57598
|
time: Flags.boolean({ description: TIME_FLAG_DESCRIPTION })
|
|
56462
57599
|
};
|
|
56463
57600
|
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
|
|
57601
|
+
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
57602
|
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
57603
|
}
|
|
56467
57604
|
const positional = positionalPathParameter(operation);
|
|
@@ -56640,6 +57777,7 @@ const OPERATION_ERROR_HINTS = {
|
|
|
56640
57777
|
createEndpoint: (code, body, payload) => createEndpointRuleRequestHint(code, body, payload),
|
|
56641
57778
|
updateEndpoint: (code, body, payload) => updateEndpointRuleRequestHint(code, body, payload),
|
|
56642
57779
|
updateEmailRule: (code, body, payload, path, flags) => updateEmailRuleErrorHint(code, payload, path?.id, body, flags),
|
|
57780
|
+
listEmailRuleObjections: (_code, _body, payload, _path, flags) => objectionBoxErrorHint(payload, flags),
|
|
56643
57781
|
verifyDomain: (code, _body, payload) => code === "dns_verification_failed" ? domainVerificationFailedHint(payload) : void 0,
|
|
56644
57782
|
addDomain: (code, body) => {
|
|
56645
57783
|
if (code === "mail_relay_unavailable") return MAIL_RELAY_UNAVAILABLE_MESSAGE;
|
|
@@ -56752,7 +57890,9 @@ function createOperationCommand(operation) {
|
|
|
56752
57890
|
const replyStateSurface = replyStateSurfaceForOperation(operation.sdkName, query);
|
|
56753
57891
|
const automatedSurface = automatedSurfaceForOperation(operation.sdkName, query);
|
|
56754
57892
|
const fromVerified = fromVerifiedExpectation(operation.sdkName, query);
|
|
56755
|
-
|
|
57893
|
+
let sentQuery = withDefaultObjectionBox(operation.sdkName, query);
|
|
57894
|
+
let objectionBoxRefused = false;
|
|
57895
|
+
const callOperation = (stepUpToken, pageQuery = sentQuery) => {
|
|
56756
57896
|
const sent = stepUpToken ? {
|
|
56757
57897
|
...headers,
|
|
56758
57898
|
[STEP_UP_HEADER]: stepUpToken
|
|
@@ -56797,7 +57937,7 @@ function createOperationCommand(operation) {
|
|
|
56797
57937
|
const rows = [];
|
|
56798
57938
|
let sentCursor = query.cursor;
|
|
56799
57939
|
let last = await callOperation(void 0, {
|
|
56800
|
-
...
|
|
57940
|
+
...sentQuery,
|
|
56801
57941
|
limit: Math.min(max, wanted)
|
|
56802
57942
|
});
|
|
56803
57943
|
const budget = Math.ceil(wanted / max) + 20;
|
|
@@ -56823,7 +57963,7 @@ function createOperationCommand(operation) {
|
|
|
56823
57963
|
};
|
|
56824
57964
|
sentCursor = cursor;
|
|
56825
57965
|
last = await callOperation(void 0, {
|
|
56826
|
-
...
|
|
57966
|
+
...sentQuery,
|
|
56827
57967
|
cursor,
|
|
56828
57968
|
limit: Math.min(max, wanted - rows.length)
|
|
56829
57969
|
});
|
|
@@ -56834,13 +57974,22 @@ function createOperationCommand(operation) {
|
|
|
56834
57974
|
const warning = typeof role === "string" ? roleReadsAllMailWarning(role, await readRoles(apiClient.client)) : null;
|
|
56835
57975
|
if (warning) process.stderr.write(`${warning}\n`);
|
|
56836
57976
|
}
|
|
56837
|
-
const
|
|
57977
|
+
const send = async () => paged ? await callPaged() : takesStepUp(operation) ? await callWithApproval() : ATTACHMENT_WAIT_OPERATIONS.has(operation.sdkName) ? await withAttachmentWait(callOperation, {
|
|
56838
57978
|
wait: parsedFlags.wait !== false,
|
|
56839
57979
|
errorCode: (error) => extractErrorCode(extractErrorPayload(error)),
|
|
56840
57980
|
onFirstWait: () => {
|
|
56841
57981
|
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
57982
|
}
|
|
56843
57983
|
}) : await callOperation();
|
|
57984
|
+
let result = await send();
|
|
57985
|
+
if (result.error && sentQuery !== query && isObjectionBoxRefused(extractErrorPayload(result.error))) {
|
|
57986
|
+
sentQuery = {
|
|
57987
|
+
...query,
|
|
57988
|
+
box: OBJECTION_BOX_FALLBACK
|
|
57989
|
+
};
|
|
57990
|
+
objectionBoxRefused = true;
|
|
57991
|
+
result = await send();
|
|
57992
|
+
}
|
|
56844
57993
|
if (result.error) {
|
|
56845
57994
|
const errorPayload = extractErrorPayload(result.error);
|
|
56846
57995
|
const operationErrorHint = OPERATION_ERROR_HINTS[operation.sdkName]?.(extractErrorCode(errorPayload), body, errorPayload, collectValues(operation.pathParams, parsedFlags, operation.sdkName), parsedFlags);
|
|
@@ -56920,18 +58069,26 @@ function createOperationCommand(operation) {
|
|
|
56920
58069
|
if (cursor && !jsonOutput) process.stderr.write(`next cursor: ${cursor}\n`);
|
|
56921
58070
|
if (pagingNote && !jsonOutput) process.stderr.write(`${pagingNote}\n`);
|
|
56922
58071
|
const summary = [];
|
|
58072
|
+
let ruleListHintSaid = false;
|
|
56923
58073
|
if (Array.isArray(envelope?.data) && envelope.data.length === 0 && (!jsonOutput || withEnvelope) && (jsonOutput || !metaExplainsEmptyList(envelope?.meta))) {
|
|
56924
58074
|
const tail = query.since !== void 0;
|
|
56925
58075
|
const more = envelope?.meta?.cursor ?? null;
|
|
58076
|
+
const ruleListHint = emptyRuleListHint(operation.sdkName, query, { objectionBoxRefused });
|
|
58077
|
+
ruleListHintSaid = ruleListHint !== void 0;
|
|
56926
58078
|
const hint = operation.sdkName === "listEmails" ? emptyEmailListHint({
|
|
56927
58079
|
filterFlags: listFilters(query).map((name) => `--${parameterFlagName(operation.sdkName, name)}`),
|
|
56928
58080
|
...tail ? { pastFlag: "--since" } : query.cursor !== void 0 ? { pastFlag: "--cursor" } : {},
|
|
56929
58081
|
nextCursor: tail ? null : more,
|
|
56930
58082
|
caller: tail || more ? null : await readCallerMailFor(auth, apiClient.client)
|
|
56931
|
-
}) :
|
|
58083
|
+
}) : ruleListHint ?? emptyDeliveriesHint(operation.sdkName, query) ?? EMPTY_RESULT_HINTS[operation.sdkName];
|
|
56932
58084
|
if (hint && jsonOutput) summary.push(hint);
|
|
56933
58085
|
else if (hint) process.stderr.write(`${hint}\n`);
|
|
56934
58086
|
}
|
|
58087
|
+
if (Array.isArray(envelope?.data) && (!jsonOutput || withEnvelope)) {
|
|
58088
|
+
const note = ruleListHintSaid ? void 0 : ruleListDefaultsNote(operation.sdkName, query, { objectionBoxRefused });
|
|
58089
|
+
if (note && jsonOutput) summary.push(note);
|
|
58090
|
+
else if (note) process.stderr.write(`${note}\n`);
|
|
58091
|
+
}
|
|
56935
58092
|
if (!jsonOutput) for (const line of metaNoteLines(envelope?.meta)) process.stderr.write(`${line}\n`);
|
|
56936
58093
|
if (operation.sdkName === "listSentEmails") {
|
|
56937
58094
|
const note = sentListOtherSendersNote(envelope?.data, auth.connectedAgent?.agentAddress);
|
|
@@ -57007,35 +58164,6 @@ const EMPTY_RESULT_HINTS = {
|
|
|
57007
58164
|
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
58165
|
};
|
|
57009
58166
|
/**
|
|
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
58167
|
* An empty delivery list narrowed by a filter (--endpoint-id, --status,
|
|
57040
58168
|
* --event-type and the rest) names the filters given, in place of the general
|
|
57041
58169
|
* hint, which reads as if nothing was ever delivered, and keeps its point that
|