jmap-kit 0.0.0 → 1.0.2
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/LICENSE +21 -0
- package/README.md +138 -3
- package/dist/src/capabilities/blob/blob.d.ts +83 -0
- package/dist/src/capabilities/blob/blob.js +98 -0
- package/dist/src/capabilities/blob/blob.js.map +1 -0
- package/dist/src/capabilities/blob/types.d.ts +212 -0
- package/dist/src/capabilities/blob/types.js +16 -0
- package/dist/src/capabilities/blob/types.js.map +1 -0
- package/dist/src/capabilities/blob-capability.d.ts +195 -0
- package/dist/src/capabilities/blob-capability.js +277 -0
- package/dist/src/capabilities/blob-capability.js.map +1 -0
- package/dist/src/capabilities/core/core.d.ts +47 -0
- package/dist/src/capabilities/core/core.js +59 -0
- package/dist/src/capabilities/core/core.js.map +1 -0
- package/dist/src/capabilities/core/types.d.ts +13 -0
- package/dist/src/capabilities/core/types.js +2 -0
- package/dist/src/capabilities/core/types.js.map +1 -0
- package/dist/src/capabilities/core-capability.d.ts +307 -0
- package/dist/src/capabilities/core-capability.js +344 -0
- package/dist/src/capabilities/core-capability.js.map +1 -0
- package/dist/src/capabilities/email/email.d.ts +124 -0
- package/dist/src/capabilities/email/email.js +136 -0
- package/dist/src/capabilities/email/email.js.map +1 -0
- package/dist/src/capabilities/email/types.d.ts +776 -0
- package/dist/src/capabilities/email/types.js +2 -0
- package/dist/src/capabilities/email/types.js.map +1 -0
- package/dist/src/capabilities/email-capability.d.ts +266 -0
- package/dist/src/capabilities/email-capability.js +241 -0
- package/dist/src/capabilities/email-capability.js.map +1 -0
- package/dist/src/capabilities/emailsubmission/emailsubmission.d.ts +95 -0
- package/dist/src/capabilities/emailsubmission/emailsubmission.js +107 -0
- package/dist/src/capabilities/emailsubmission/emailsubmission.js.map +1 -0
- package/dist/src/capabilities/emailsubmission/types.d.ts +256 -0
- package/dist/src/capabilities/emailsubmission/types.js +2 -0
- package/dist/src/capabilities/emailsubmission/types.js.map +1 -0
- package/dist/src/capabilities/example/example.d.ts +80 -0
- package/dist/src/capabilities/example/example.js +91 -0
- package/dist/src/capabilities/example/example.js.map +1 -0
- package/dist/src/capabilities/example/types.d.ts +33 -0
- package/dist/src/capabilities/example/types.js +2 -0
- package/dist/src/capabilities/example/types.js.map +1 -0
- package/dist/src/capabilities/identity/identity.d.ts +71 -0
- package/dist/src/capabilities/identity/identity.js +83 -0
- package/dist/src/capabilities/identity/identity.js.map +1 -0
- package/dist/src/capabilities/identity/types.d.ts +110 -0
- package/dist/src/capabilities/identity/types.js +2 -0
- package/dist/src/capabilities/identity/types.js.map +1 -0
- package/dist/src/capabilities/mailbox/mailbox.d.ts +91 -0
- package/dist/src/capabilities/mailbox/mailbox.js +103 -0
- package/dist/src/capabilities/mailbox/mailbox.js.map +1 -0
- package/dist/src/capabilities/mailbox/types.d.ts +248 -0
- package/dist/src/capabilities/mailbox/types.js +2 -0
- package/dist/src/capabilities/mailbox/types.js.map +1 -0
- package/dist/src/capabilities/maskedemail/maskedemail.d.ts +60 -0
- package/dist/src/capabilities/maskedemail/maskedemail.js +72 -0
- package/dist/src/capabilities/maskedemail/maskedemail.js.map +1 -0
- package/dist/src/capabilities/maskedemail/types.d.ts +67 -0
- package/dist/src/capabilities/maskedemail/types.js +4 -0
- package/dist/src/capabilities/maskedemail/types.js.map +1 -0
- package/dist/src/capabilities/maskedemail-capability.d.ts +112 -0
- package/dist/src/capabilities/maskedemail-capability.js +166 -0
- package/dist/src/capabilities/maskedemail-capability.js.map +1 -0
- package/dist/src/capabilities/searchsnippet/searchsnippet.d.ts +51 -0
- package/dist/src/capabilities/searchsnippet/searchsnippet.js +63 -0
- package/dist/src/capabilities/searchsnippet/searchsnippet.js.map +1 -0
- package/dist/src/capabilities/searchsnippet/types.d.ts +88 -0
- package/dist/src/capabilities/searchsnippet/types.js +2 -0
- package/dist/src/capabilities/searchsnippet/types.js.map +1 -0
- package/dist/src/capabilities/submission-capability.d.ts +89 -0
- package/dist/src/capabilities/submission-capability.js +75 -0
- package/dist/src/capabilities/submission-capability.js.map +1 -0
- package/dist/src/capabilities/thread/thread.d.ts +58 -0
- package/dist/src/capabilities/thread/thread.js +70 -0
- package/dist/src/capabilities/thread/thread.js.map +1 -0
- package/dist/src/capabilities/thread/types.d.ts +43 -0
- package/dist/src/capabilities/thread/types.js +2 -0
- package/dist/src/capabilities/thread/types.js.map +1 -0
- package/dist/src/capabilities/utils/assert-invocation-datatype.d.ts +7 -0
- package/dist/src/capabilities/utils/assert-invocation-datatype.js +13 -0
- package/dist/src/capabilities/utils/assert-invocation-datatype.js.map +1 -0
- package/dist/src/capabilities/utils/assert-invocation-method.d.ts +7 -0
- package/dist/src/capabilities/utils/assert-invocation-method.js +13 -0
- package/dist/src/capabilities/utils/assert-invocation-method.js.map +1 -0
- package/dist/src/capabilities/utils/assert-invocation.d.ts +7 -0
- package/dist/src/capabilities/utils/assert-invocation.js +22 -0
- package/dist/src/capabilities/utils/assert-invocation.js.map +1 -0
- package/dist/src/capabilities/utils/assert-non-nullish.d.ts +1 -0
- package/dist/src/capabilities/utils/assert-non-nullish.js +6 -0
- package/dist/src/capabilities/utils/assert-non-nullish.js.map +1 -0
- package/dist/src/capabilities/utils/create-readonly-account-validator.d.ts +49 -0
- package/dist/src/capabilities/utils/create-readonly-account-validator.js +80 -0
- package/dist/src/capabilities/utils/create-readonly-account-validator.js.map +1 -0
- package/dist/src/capabilities/vacationresponse/types.d.ts +100 -0
- package/dist/src/capabilities/vacationresponse/types.js +2 -0
- package/dist/src/capabilities/vacationresponse/types.js.map +1 -0
- package/dist/src/capabilities/vacationresponse/vacationresponse.d.ts +61 -0
- package/dist/src/capabilities/vacationresponse/vacationresponse.js +73 -0
- package/dist/src/capabilities/vacationresponse/vacationresponse.js.map +1 -0
- package/dist/src/capabilities/vacationresponse-capability.d.ts +65 -0
- package/dist/src/capabilities/vacationresponse-capability.js +68 -0
- package/dist/src/capabilities/vacationresponse-capability.js.map +1 -0
- package/dist/src/capability-registry/capability-registry.d.ts +148 -0
- package/dist/src/capability-registry/capability-registry.js +360 -0
- package/dist/src/capability-registry/capability-registry.js.map +1 -0
- package/dist/src/capability-registry/types.d.ts +385 -0
- package/dist/src/capability-registry/types.js +2 -0
- package/dist/src/capability-registry/types.js.map +1 -0
- package/dist/src/capability-registry/utils.d.ts +71 -0
- package/dist/src/capability-registry/utils.js +163 -0
- package/dist/src/capability-registry/utils.js.map +1 -0
- package/dist/src/common/registry.d.ts +366 -0
- package/dist/src/common/registry.js +321 -0
- package/dist/src/common/registry.js.map +1 -0
- package/dist/src/common/types.d.ts +338 -0
- package/dist/src/common/types.js +21 -0
- package/dist/src/common/types.js.map +1 -0
- package/dist/src/common/utils.d.ts +20 -0
- package/dist/src/common/utils.js +26 -0
- package/dist/src/common/utils.js.map +1 -0
- package/dist/src/index.d.ts +40 -0
- package/dist/src/index.js +33 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/invocation/arguments-proxy.d.ts +14 -0
- package/dist/src/invocation/arguments-proxy.js +37 -0
- package/dist/src/invocation/arguments-proxy.js.map +1 -0
- package/dist/src/invocation/error-invocation.d.ts +27 -0
- package/dist/src/invocation/error-invocation.js +39 -0
- package/dist/src/invocation/error-invocation.js.map +1 -0
- package/dist/src/invocation/invocation.d.ts +111 -0
- package/dist/src/invocation/invocation.js +158 -0
- package/dist/src/invocation/invocation.js.map +1 -0
- package/dist/src/invocation/result-reference.d.ts +86 -0
- package/dist/src/invocation/result-reference.js +118 -0
- package/dist/src/invocation/result-reference.js.map +1 -0
- package/dist/src/invocation/types.d.ts +637 -0
- package/dist/src/invocation/types.js +2 -0
- package/dist/src/invocation/types.js.map +1 -0
- package/dist/src/invocation/utils.d.ts +21 -0
- package/dist/src/invocation/utils.js +30 -0
- package/dist/src/invocation/utils.js.map +1 -0
- package/dist/src/invocation-factory/invocation-factory-manager.d.ts +20 -0
- package/dist/src/invocation-factory/invocation-factory-manager.js +50 -0
- package/dist/src/invocation-factory/invocation-factory-manager.js.map +1 -0
- package/dist/src/invocation-factory/invocation-list.d.ts +32 -0
- package/dist/src/invocation-factory/invocation-list.js +77 -0
- package/dist/src/invocation-factory/invocation-list.js.map +1 -0
- package/dist/src/invocation-factory/types.d.ts +11 -0
- package/dist/src/invocation-factory/types.js +2 -0
- package/dist/src/invocation-factory/types.js.map +1 -0
- package/dist/src/jmap-client/jmap-client.d.ts +252 -0
- package/dist/src/jmap-client/jmap-client.js +777 -0
- package/dist/src/jmap-client/jmap-client.js.map +1 -0
- package/dist/src/jmap-client/types.d.ts +427 -0
- package/dist/src/jmap-client/types.js +21 -0
- package/dist/src/jmap-client/types.js.map +1 -0
- package/dist/src/jmap-client/utils/abort-controller.d.ts +8 -0
- package/dist/src/jmap-client/utils/abort-controller.js +24 -0
- package/dist/src/jmap-client/utils/abort-controller.js.map +1 -0
- package/dist/src/jmap-client/utils/assert-connected.d.ts +7 -0
- package/dist/src/jmap-client/utils/assert-connected.js +11 -0
- package/dist/src/jmap-client/utils/assert-connected.js.map +1 -0
- package/dist/src/jmap-client/utils/deep-freeze.d.ts +7 -0
- package/dist/src/jmap-client/utils/deep-freeze.js +17 -0
- package/dist/src/jmap-client/utils/deep-freeze.js.map +1 -0
- package/dist/src/jmap-client/utils/emitter.d.ts +9 -0
- package/dist/src/jmap-client/utils/emitter.js +18 -0
- package/dist/src/jmap-client/utils/emitter.js.map +1 -0
- package/dist/src/jmap-client/utils/filter-session-capabilities.d.ts +22 -0
- package/dist/src/jmap-client/utils/filter-session-capabilities.js +40 -0
- package/dist/src/jmap-client/utils/filter-session-capabilities.js.map +1 -0
- package/dist/src/jmap-client/utils/jmap-request-error.d.ts +28 -0
- package/dist/src/jmap-client/utils/jmap-request-error.js +48 -0
- package/dist/src/jmap-client/utils/jmap-request-error.js.map +1 -0
- package/dist/src/jmap-client/utils/logger.d.ts +6 -0
- package/dist/src/jmap-client/utils/logger.js +22 -0
- package/dist/src/jmap-client/utils/logger.js.map +1 -0
- package/dist/src/jmap-client/utils/merge-headers.d.ts +11 -0
- package/dist/src/jmap-client/utils/merge-headers.js +40 -0
- package/dist/src/jmap-client/utils/merge-headers.js.map +1 -0
- package/dist/src/jmap-client/utils/template-utils.d.ts +27 -0
- package/dist/src/jmap-client/utils/template-utils.js +61 -0
- package/dist/src/jmap-client/utils/template-utils.js.map +1 -0
- package/dist/src/jmap-client/utils/track-utils.d.ts +19 -0
- package/dist/src/jmap-client/utils/track-utils.js +35 -0
- package/dist/src/jmap-client/utils/track-utils.js.map +1 -0
- package/dist/src/jmap-client/utils/transport.d.ts +12 -0
- package/dist/src/jmap-client/utils/transport.js +38 -0
- package/dist/src/jmap-client/utils/transport.js.map +1 -0
- package/dist/src/jmap-client/utils/validate-session.d.ts +19 -0
- package/dist/src/jmap-client/utils/validate-session.js +29 -0
- package/dist/src/jmap-client/utils/validate-session.js.map +1 -0
- package/dist/src/request-builder/request-builder.d.ts +95 -0
- package/dist/src/request-builder/request-builder.js +343 -0
- package/dist/src/request-builder/request-builder.js.map +1 -0
- package/dist/src/request-builder/types.d.ts +32 -0
- package/dist/src/request-builder/types.js +2 -0
- package/dist/src/request-builder/types.js.map +1 -0
- package/package.json +69 -3
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { MASKED_EMAIL_CAPABILITY_URI } from "../common/registry.js";
|
|
2
|
+
import { MaskedEmail } from "./maskedemail/maskedemail.js";
|
|
3
|
+
import { assertInvocation } from "./utils/assert-invocation.js";
|
|
4
|
+
/**
|
|
5
|
+
* Validates that invocations using the MaskedEmail capability have a valid accountId that supports
|
|
6
|
+
* the MaskedEmail capability.
|
|
7
|
+
*
|
|
8
|
+
* This plugin performs three critical validation checks:
|
|
9
|
+
* 1. Verifies the invocation includes a valid `accountId` argument (non-empty string)
|
|
10
|
+
* 2. Confirms the account exists in the session's accounts collection
|
|
11
|
+
* 3. Ensures the account's `accountCapabilities` includes the MaskedEmail capability URI
|
|
12
|
+
*
|
|
13
|
+
* This validation applies to all MaskedEmail capability invocations (MaskedEmail/get, MaskedEmail/set)
|
|
14
|
+
* and implements the account capability checks for the FastMail Masked Email extension.
|
|
15
|
+
*
|
|
16
|
+
* @see {@link https://www.fastmail.com/dev/#masked-email-api | FastMail Developer Documentation - Masked Email API}
|
|
17
|
+
*/
|
|
18
|
+
export const maskedEmailAccountSupportPlugin = {
|
|
19
|
+
name: "maskedemail-account-support",
|
|
20
|
+
hook: "invocation",
|
|
21
|
+
trigger: {
|
|
22
|
+
capabilityUri: MASKED_EMAIL_CAPABILITY_URI,
|
|
23
|
+
},
|
|
24
|
+
validate(context) {
|
|
25
|
+
const { invocation, accounts } = context;
|
|
26
|
+
const accountId = invocation.getArgument("accountId");
|
|
27
|
+
if (typeof accountId !== "string" || accountId === "") {
|
|
28
|
+
return {
|
|
29
|
+
valid: false,
|
|
30
|
+
errors: [new Error(`Invocation is missing a valid accountId argument.`)],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const account = accounts[accountId];
|
|
34
|
+
if (!account) {
|
|
35
|
+
return {
|
|
36
|
+
valid: false,
|
|
37
|
+
errors: [new Error(`Account "${accountId}" does not exist.`)],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (!account.accountCapabilities[MASKED_EMAIL_CAPABILITY_URI]) {
|
|
41
|
+
return {
|
|
42
|
+
valid: false,
|
|
43
|
+
errors: [new Error(`Account "${accountId}" does not support the MaskedEmail capability.`)],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return { valid: true };
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Validates emailPrefix constraints for MaskedEmail creation.
|
|
51
|
+
*
|
|
52
|
+
* This plugin enforces FastMail's requirements for the emailPrefix property:
|
|
53
|
+
*
|
|
54
|
+
* **Email Prefix Constraints:**
|
|
55
|
+
* - Must be 64 characters or less
|
|
56
|
+
* - May only contain lowercase letters (a-z), digits (0-9), and underscores (_)
|
|
57
|
+
* - Only applicable during MaskedEmail creation (not updates)
|
|
58
|
+
*
|
|
59
|
+
* The emailPrefix is an optional property that allows clients to suggest a prefix for the
|
|
60
|
+
* generated masked email address. If not provided, the server generates one automatically.
|
|
61
|
+
*
|
|
62
|
+
* These validations catch invalid prefixes before sending requests to the server, providing
|
|
63
|
+
* immediate feedback and avoiding unnecessary network round-trips.
|
|
64
|
+
*
|
|
65
|
+
* @see {@link https://www.fastmail.com/dev/#masked-email-api | FastMail Developer Documentation - Masked Email API}
|
|
66
|
+
*/
|
|
67
|
+
export const maskedEmailPrefixValidationPlugin = {
|
|
68
|
+
name: "maskedemail-prefix-validation",
|
|
69
|
+
hook: "invocation",
|
|
70
|
+
trigger: {
|
|
71
|
+
dataType: "MaskedEmail",
|
|
72
|
+
method: "set",
|
|
73
|
+
},
|
|
74
|
+
validate(context) {
|
|
75
|
+
const { invocation } = context;
|
|
76
|
+
assertInvocation(invocation, "MaskedEmail", "set");
|
|
77
|
+
const create = invocation.getArgument("create");
|
|
78
|
+
if (!create || typeof create !== "object") {
|
|
79
|
+
return { valid: true }; // No creations to validate
|
|
80
|
+
}
|
|
81
|
+
const errors = [];
|
|
82
|
+
const prefixPattern = /^[a-z0-9_]+$/;
|
|
83
|
+
for (const [creationId, maskedEmail] of Object.entries(create)) {
|
|
84
|
+
const { emailPrefix } = maskedEmail;
|
|
85
|
+
if (emailPrefix !== undefined) {
|
|
86
|
+
// Check length constraint
|
|
87
|
+
if (emailPrefix.length > 64) {
|
|
88
|
+
errors.push(new Error(`MaskedEmail "${creationId}" has emailPrefix of ${emailPrefix.length} characters, but maximum is 64`));
|
|
89
|
+
}
|
|
90
|
+
// Check character constraint
|
|
91
|
+
if (!prefixPattern.test(emailPrefix)) {
|
|
92
|
+
errors.push(new Error(`MaskedEmail "${creationId}" has invalid emailPrefix. Only lowercase letters (a-z), digits (0-9), and underscores (_) are allowed`));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (errors.length > 0) {
|
|
97
|
+
return { valid: false, errors };
|
|
98
|
+
}
|
|
99
|
+
return { valid: true };
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Validates MaskedEmail state transition constraints.
|
|
104
|
+
*
|
|
105
|
+
* This plugin enforces FastMail's state machine rules for MaskedEmail objects:
|
|
106
|
+
*
|
|
107
|
+
* **State Transition Rules:**
|
|
108
|
+
* - Once a MaskedEmail transitions from "pending" to any other state, it cannot be set back to "pending"
|
|
109
|
+
* - Valid states: "pending", "enabled", "disabled", "deleted"
|
|
110
|
+
* - State can transition: pending → enabled/disabled/deleted
|
|
111
|
+
* - State can transition: enabled ⟷ disabled ⟷ deleted
|
|
112
|
+
* - State cannot transition: enabled/disabled/deleted → pending
|
|
113
|
+
*
|
|
114
|
+
* **Automatic Transitions:**
|
|
115
|
+
* - Pending addresses automatically become "enabled" when they receive their first message
|
|
116
|
+
* - Pending addresses are automatically deleted after 24 hours if unused
|
|
117
|
+
*
|
|
118
|
+
* This validation prevents invalid state transitions during updates, catching errors before
|
|
119
|
+
* they reach the server.
|
|
120
|
+
*
|
|
121
|
+
* @see {@link https://www.fastmail.com/dev/#masked-email-api | FastMail Developer Documentation - Masked Email API}
|
|
122
|
+
*/
|
|
123
|
+
export const maskedEmailStateValidationPlugin = {
|
|
124
|
+
name: "maskedemail-state-validation",
|
|
125
|
+
hook: "invocation",
|
|
126
|
+
trigger: {
|
|
127
|
+
dataType: "MaskedEmail",
|
|
128
|
+
method: "set",
|
|
129
|
+
},
|
|
130
|
+
validate(context) {
|
|
131
|
+
const { invocation } = context;
|
|
132
|
+
assertInvocation(invocation, "MaskedEmail", "set");
|
|
133
|
+
const update = invocation.getArgument("update");
|
|
134
|
+
if (!update || typeof update !== "object") {
|
|
135
|
+
return { valid: true }; // No updates to validate
|
|
136
|
+
}
|
|
137
|
+
const errors = [];
|
|
138
|
+
for (const [id, patch] of Object.entries(update)) {
|
|
139
|
+
const updateData = patch;
|
|
140
|
+
const { state } = updateData;
|
|
141
|
+
// Check if trying to set state back to pending
|
|
142
|
+
if (state === "pending") {
|
|
143
|
+
errors.push(new Error(`MaskedEmail "${id}" cannot be set to "pending" state. Once transitioned from pending, it cannot be set back`));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (errors.length > 0) {
|
|
147
|
+
return { valid: false, errors };
|
|
148
|
+
}
|
|
149
|
+
return { valid: true };
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Defines the MaskedEmail capability, including MaskedEmail invocations and validation plugins
|
|
154
|
+
* for the FastMail Masked Email extension.
|
|
155
|
+
*
|
|
156
|
+
* **Note:** Read-only account protection for MaskedEmail/set is handled by Core's generic
|
|
157
|
+
* `preventSetOnReadOnlyAccountPlugin`, which validates all `/set` methods.
|
|
158
|
+
*/
|
|
159
|
+
export const MaskedEmailCapability = {
|
|
160
|
+
uri: MASKED_EMAIL_CAPABILITY_URI,
|
|
161
|
+
invocations: {
|
|
162
|
+
MaskedEmail,
|
|
163
|
+
},
|
|
164
|
+
validators: [maskedEmailAccountSupportPlugin, maskedEmailPrefixValidationPlugin, maskedEmailStateValidationPlugin],
|
|
165
|
+
};
|
|
166
|
+
//# sourceMappingURL=maskedemail-capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maskedemail-capability.js","sourceRoot":"","sources":["../../../src/capabilities/maskedemail-capability.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { JMAPCapability, JMAPMethodName } from "../../common/types.js";
|
|
2
|
+
import { Invocation } from "../../invocation/invocation.js";
|
|
3
|
+
import type { InvocationArgs, InvocationFactory } from "../../invocation/types.js";
|
|
4
|
+
import type { SearchSnippetGetRequestInvocationArgs, SearchSnippetGetResponseInvocationArgs, SearchSnippetRequestInvocationArgs, SearchSnippetResponseInvocationArgs } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* SearchSnippetInvocation represents a JMAP SearchSnippet capability invocation.
|
|
7
|
+
*
|
|
8
|
+
* When doing a search on a string property, the client may wish to show the relevant section
|
|
9
|
+
* of the body that matches the search as a preview and to highlight any matching terms in both
|
|
10
|
+
* this and the subject of the Email.
|
|
11
|
+
*
|
|
12
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-5 | RFC 8621 Section 5: Search Snippets}
|
|
13
|
+
*/
|
|
14
|
+
export declare class SearchSnippetInvocation<TArgs extends SearchSnippetRequestInvocationArgs | SearchSnippetResponseInvocationArgs> extends Invocation<TArgs> {
|
|
15
|
+
get uri(): JMAPCapability;
|
|
16
|
+
/**
|
|
17
|
+
* Constructs a SearchSnippetInvocation
|
|
18
|
+
*
|
|
19
|
+
* @param method The name of the method being invoked
|
|
20
|
+
* @param args The arguments for the method invocation
|
|
21
|
+
* @param methodCallId An optional unique symbol to identify this method call for result referencing
|
|
22
|
+
*/
|
|
23
|
+
constructor(method: JMAPMethodName, args: InvocationArgs<TArgs>, methodCallId?: symbol);
|
|
24
|
+
/**
|
|
25
|
+
* Create an invocation factory function
|
|
26
|
+
*
|
|
27
|
+
* @param method The name of the method to create
|
|
28
|
+
* @returns A new SearchSnippet invocation factory function for creating invocations of the specified type
|
|
29
|
+
*/
|
|
30
|
+
static createInvocationFactory<TArgs extends SearchSnippetRequestInvocationArgs | SearchSnippetResponseInvocationArgs>(method: JMAPMethodName): InvocationFactory<TArgs, SearchSnippetInvocation<TArgs>>;
|
|
31
|
+
}
|
|
32
|
+
export declare const SearchSnippet: {
|
|
33
|
+
request: {
|
|
34
|
+
/**
|
|
35
|
+
* Fetches search snippets for the given Email ids matching the given filter.
|
|
36
|
+
*
|
|
37
|
+
* This is NOT a standard `/get` method. The `ids` argument is replaced by `emailIds`,
|
|
38
|
+
* and an additional `filter` argument is required (the same filter as passed to `Email/query`).
|
|
39
|
+
*
|
|
40
|
+
* @param args The invocation arguments for SearchSnippet/get
|
|
41
|
+
* @param methodCallId An optional unique symbol to identify this method call for result referencing
|
|
42
|
+
* @returns A SearchSnippetInvocation representing the SearchSnippet/get request
|
|
43
|
+
*
|
|
44
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-5.1 | RFC 8621 Section 5.1: SearchSnippet/get}
|
|
45
|
+
*/
|
|
46
|
+
get: InvocationFactory<SearchSnippetGetRequestInvocationArgs, SearchSnippetInvocation<SearchSnippetGetRequestInvocationArgs>>;
|
|
47
|
+
};
|
|
48
|
+
response: {
|
|
49
|
+
get: InvocationFactory<SearchSnippetGetResponseInvocationArgs, SearchSnippetInvocation<SearchSnippetGetResponseInvocationArgs>>;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { EMAIL_CAPABILITY_URI } from "../../common/registry.js";
|
|
2
|
+
import { Invocation } from "../../invocation/invocation.js";
|
|
3
|
+
/**
|
|
4
|
+
* SearchSnippetInvocation represents a JMAP SearchSnippet capability invocation.
|
|
5
|
+
*
|
|
6
|
+
* When doing a search on a string property, the client may wish to show the relevant section
|
|
7
|
+
* of the body that matches the search as a preview and to highlight any matching terms in both
|
|
8
|
+
* this and the subject of the Email.
|
|
9
|
+
*
|
|
10
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-5 | RFC 8621 Section 5: Search Snippets}
|
|
11
|
+
*/
|
|
12
|
+
export class SearchSnippetInvocation extends Invocation {
|
|
13
|
+
get uri() {
|
|
14
|
+
return EMAIL_CAPABILITY_URI;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Constructs a SearchSnippetInvocation
|
|
18
|
+
*
|
|
19
|
+
* @param method The name of the method being invoked
|
|
20
|
+
* @param args The arguments for the method invocation
|
|
21
|
+
* @param methodCallId An optional unique symbol to identify this method call for result referencing
|
|
22
|
+
*/
|
|
23
|
+
constructor(method, args, methodCallId) {
|
|
24
|
+
super("SearchSnippet", method, args, methodCallId);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create an invocation factory function
|
|
28
|
+
*
|
|
29
|
+
* @param method The name of the method to create
|
|
30
|
+
* @returns A new SearchSnippet invocation factory function for creating invocations of the specified type
|
|
31
|
+
*/
|
|
32
|
+
static createInvocationFactory(method) {
|
|
33
|
+
/**
|
|
34
|
+
* An invocation factory function to create a `SearchSnippet/{method}` invocation.
|
|
35
|
+
*
|
|
36
|
+
* @param args The invocation arguments for the specified `method`
|
|
37
|
+
* @param methodCallId An optional unique symbol to identify this method call for result referencing
|
|
38
|
+
* @returns An object representing the named arguments for the specified `method`
|
|
39
|
+
*/
|
|
40
|
+
return (args, methodCallId) => new SearchSnippetInvocation(method, args, methodCallId);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export const SearchSnippet = {
|
|
44
|
+
request: {
|
|
45
|
+
/**
|
|
46
|
+
* Fetches search snippets for the given Email ids matching the given filter.
|
|
47
|
+
*
|
|
48
|
+
* This is NOT a standard `/get` method. The `ids` argument is replaced by `emailIds`,
|
|
49
|
+
* and an additional `filter` argument is required (the same filter as passed to `Email/query`).
|
|
50
|
+
*
|
|
51
|
+
* @param args The invocation arguments for SearchSnippet/get
|
|
52
|
+
* @param methodCallId An optional unique symbol to identify this method call for result referencing
|
|
53
|
+
* @returns A SearchSnippetInvocation representing the SearchSnippet/get request
|
|
54
|
+
*
|
|
55
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-5.1 | RFC 8621 Section 5.1: SearchSnippet/get}
|
|
56
|
+
*/
|
|
57
|
+
get: SearchSnippetInvocation.createInvocationFactory("get"),
|
|
58
|
+
},
|
|
59
|
+
response: {
|
|
60
|
+
get: SearchSnippetInvocation.createInvocationFactory("get"),
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=searchsnippet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchsnippet.js","sourceRoot":"","sources":["../../../../src/capabilities/searchsnippet/searchsnippet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAS5D;;;;;;;;GAQG;AACH,MAAM,OAAO,uBAEX,SAAQ,UAAiB;IACvB,IAAI,GAAG;QACH,OAAO,oBAAoB,CAAC;IAChC,CAAC;IAED;;;;;;OAMG;IACH,YAAY,MAAsB,EAAE,IAA2B,EAAE,YAAqB;QAClF,KAAK,CAAC,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,uBAAuB,CAE5B,MAAsB;QACpB;;;;;;WAMG;QACH,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC,IAAI,uBAAuB,CAAQ,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IAClG,CAAC;CACJ;AAED,MAAM,CAAC,MAAM,aAAa,GAAG;IACzB,OAAO,EAAE;QACL;;;;;;;;;;;WAWG;QACH,GAAG,EAAE,uBAAuB,CAAC,uBAAuB,CAAwC,KAAK,CAAC;KACrG;IACD,QAAQ,EAAE;QACN,GAAG,EAAE,uBAAuB,CAAC,uBAAuB,CAAyC,KAAK,CAAC;KACtG;CACkC,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { Id } from "../../common/types.js";
|
|
2
|
+
import type { FilterCondition, FilterOperator } from "../../invocation/types.js";
|
|
3
|
+
import type { EmailFilterCondition } from "../email/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* A SearchSnippet object represents a relevant section of the body that matches a search,
|
|
6
|
+
* along with any matching terms highlighted in the subject.
|
|
7
|
+
*
|
|
8
|
+
* Note that unlike most data types, a SearchSnippet DOES NOT have a property called `id`.
|
|
9
|
+
*
|
|
10
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-5 | RFC 8621 Section 5: Search Snippets}
|
|
11
|
+
*/
|
|
12
|
+
export type SearchSnippetObject = {
|
|
13
|
+
/**
|
|
14
|
+
* The Email id the snippet applies to.
|
|
15
|
+
*/
|
|
16
|
+
emailId: Id;
|
|
17
|
+
/**
|
|
18
|
+
* If text from the filter matches the subject, this is the subject of the Email with
|
|
19
|
+
* the following transformations:
|
|
20
|
+
*
|
|
21
|
+
* 1. Any instance of `&`, `<`, and `>` MUST be replaced by an appropriate HTML entity.
|
|
22
|
+
* Other characters MAY also be replaced with an HTML entity form.
|
|
23
|
+
*
|
|
24
|
+
* 2. The matching words/phrases from the filter are wrapped in HTML `<mark></mark>` tags.
|
|
25
|
+
*
|
|
26
|
+
* If the subject does not match text from the filter, this property is `null`.
|
|
27
|
+
*/
|
|
28
|
+
subject: string | null;
|
|
29
|
+
/**
|
|
30
|
+
* If text from the filter matches the plaintext or HTML body, this is the relevant section
|
|
31
|
+
* of the body (converted to plaintext if originally HTML), with the same transformations as
|
|
32
|
+
* the `subject` property. It MUST NOT be bigger than 255 octets in size. If the body does
|
|
33
|
+
* not contain a match for the text from the filter, this property is `null`.
|
|
34
|
+
*/
|
|
35
|
+
preview: string | null;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* The arguments for fetching SearchSnippet objects via a `SearchSnippet/get` call.
|
|
39
|
+
*
|
|
40
|
+
* This is NOT a standard `/get` method. It takes a filter (the same as passed to `Email/query`)
|
|
41
|
+
* and a list of Email ids, and returns search snippets for those Emails.
|
|
42
|
+
*
|
|
43
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-5.1 | RFC 8621 Section 5.1: SearchSnippet/get}
|
|
44
|
+
*/
|
|
45
|
+
export type SearchSnippetGetRequestInvocationArgs = {
|
|
46
|
+
/**
|
|
47
|
+
* The id of the account to use.
|
|
48
|
+
*/
|
|
49
|
+
accountId: Id;
|
|
50
|
+
/**
|
|
51
|
+
* The same filter as passed to `Email/query`.
|
|
52
|
+
*
|
|
53
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-4.4 | RFC 8621 Section 4.4: Email/query}
|
|
54
|
+
*/
|
|
55
|
+
filter?: FilterOperator<EmailFilterCondition> | FilterCondition<EmailFilterCondition> | null;
|
|
56
|
+
/**
|
|
57
|
+
* The ids of the Emails to fetch snippets for.
|
|
58
|
+
*/
|
|
59
|
+
emailIds: Id[];
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* The response to a `SearchSnippet/get` call.
|
|
63
|
+
*
|
|
64
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-5.1 | RFC 8621 Section 5.1: SearchSnippet/get}
|
|
65
|
+
*/
|
|
66
|
+
export type SearchSnippetGetResponseInvocationArgs = {
|
|
67
|
+
/**
|
|
68
|
+
* The id of the account used for the call.
|
|
69
|
+
*/
|
|
70
|
+
accountId: Id;
|
|
71
|
+
/**
|
|
72
|
+
* An array of SearchSnippet objects for the requested Email ids. This may not be in the
|
|
73
|
+
* same order as the ids that were in the request.
|
|
74
|
+
*/
|
|
75
|
+
list: SearchSnippetObject[];
|
|
76
|
+
/**
|
|
77
|
+
* An array of Email ids requested that could not be found, or `null` if all ids were found.
|
|
78
|
+
*/
|
|
79
|
+
notFound: Id[] | null;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Union type of all SearchSnippet capability request invocation arguments.
|
|
83
|
+
*/
|
|
84
|
+
export type SearchSnippetRequestInvocationArgs = SearchSnippetGetRequestInvocationArgs;
|
|
85
|
+
/**
|
|
86
|
+
* Union type of all SearchSnippet capability response invocation arguments.
|
|
87
|
+
*/
|
|
88
|
+
export type SearchSnippetResponseInvocationArgs = SearchSnippetGetResponseInvocationArgs;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/capabilities/searchsnippet/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
import type { ValidationPlugin } from "../capability-registry/types.js";
|
|
3
|
+
import { SUBMISSION_CAPABILITY_URI } from "../common/registry.js";
|
|
4
|
+
/**
|
|
5
|
+
* Validates that invocations using the Submission capability have a valid accountId that supports
|
|
6
|
+
* the Submission capability.
|
|
7
|
+
*
|
|
8
|
+
* This plugin performs three critical validation checks:
|
|
9
|
+
* 1. Verifies the invocation includes a valid `accountId` argument (non-empty string)
|
|
10
|
+
* 2. Confirms the account exists in the session's accounts collection
|
|
11
|
+
* 3. Ensures the account's `accountCapabilities` includes the Submission capability URI
|
|
12
|
+
*
|
|
13
|
+
* This validation applies to all Submission capability invocations (Identity and EmailSubmission
|
|
14
|
+
* method calls) and implements the account capability checks described in RFC 8621 Section 1.3.2.
|
|
15
|
+
*
|
|
16
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-1.3.2 | RFC 8621 Section 1.3.2: The Submission Capability}
|
|
17
|
+
*/
|
|
18
|
+
export declare const submissionAccountSupportPlugin: ValidationPlugin<"invocation">;
|
|
19
|
+
export declare const SubmissionCapability: {
|
|
20
|
+
uri: "urn:ietf:params:jmap:submission";
|
|
21
|
+
invocations: {
|
|
22
|
+
EmailSubmission: {
|
|
23
|
+
request: {
|
|
24
|
+
get: import("../index.js").InvocationFactory<import("./emailsubmission/types.js").EmailSubmissionGetRequestInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("./emailsubmission/types.js").EmailSubmissionGetRequestInvocationArgs>>;
|
|
25
|
+
changes: import("../index.js").InvocationFactory<import("../index.js").BaseChangesRequestInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("../index.js").BaseChangesRequestInvocationArgs>>;
|
|
26
|
+
query: import("../index.js").InvocationFactory<import("./emailsubmission/types.js").EmailSubmissionQueryRequestInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("./emailsubmission/types.js").EmailSubmissionQueryRequestInvocationArgs>>;
|
|
27
|
+
queryChanges: import("../index.js").InvocationFactory<import("./emailsubmission/types.js").EmailSubmissionQueryChangesRequestInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("./emailsubmission/types.js").EmailSubmissionQueryChangesRequestInvocationArgs>>;
|
|
28
|
+
set: import("../index.js").InvocationFactory<import("./emailsubmission/types.js").EmailSubmissionSetRequestInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("./emailsubmission/types.js").EmailSubmissionSetRequestInvocationArgs>>;
|
|
29
|
+
};
|
|
30
|
+
response: {
|
|
31
|
+
get: import("../index.js").InvocationFactory<import("./emailsubmission/types.js").EmailSubmissionGetResponseInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("./emailsubmission/types.js").EmailSubmissionGetResponseInvocationArgs>>;
|
|
32
|
+
changes: import("../index.js").InvocationFactory<import("../index.js").BaseChangesResponseInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("../index.js").BaseChangesResponseInvocationArgs>>;
|
|
33
|
+
query: import("../index.js").InvocationFactory<import("../index.js").BaseQueryResponseInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("../index.js").BaseQueryResponseInvocationArgs>>;
|
|
34
|
+
queryChanges: import("../index.js").InvocationFactory<import("../index.js").BaseQueryChangesResponseInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("../index.js").BaseQueryChangesResponseInvocationArgs>>;
|
|
35
|
+
set: import("../index.js").InvocationFactory<import("./emailsubmission/types.js").EmailSubmissionSetResponseInvocationArgs, import("./emailsubmission/emailsubmission.js").EmailSubmissionInvocation<import("./emailsubmission/types.js").EmailSubmissionSetResponseInvocationArgs>>;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
Identity: {
|
|
39
|
+
request: {
|
|
40
|
+
get: import("../index.js").InvocationFactory<import("./identity/types.js").IdentityGetRequestInvocationArgs, import("./identity/identity.js").IdentityInvocation<import("./identity/types.js").IdentityGetRequestInvocationArgs>>;
|
|
41
|
+
changes: import("../index.js").InvocationFactory<import("../index.js").BaseChangesRequestInvocationArgs, import("./identity/identity.js").IdentityInvocation<import("../index.js").BaseChangesRequestInvocationArgs>>;
|
|
42
|
+
set: import("../index.js").InvocationFactory<import("./identity/types.js").IdentitySetRequestInvocationArgs, import("./identity/identity.js").IdentityInvocation<import("./identity/types.js").IdentitySetRequestInvocationArgs>>;
|
|
43
|
+
};
|
|
44
|
+
response: {
|
|
45
|
+
get: import("../index.js").InvocationFactory<import("./identity/types.js").IdentityGetResponseInvocationArgs, import("./identity/identity.js").IdentityInvocation<import("./identity/types.js").IdentityGetResponseInvocationArgs>>;
|
|
46
|
+
changes: import("../index.js").InvocationFactory<import("../index.js").BaseChangesResponseInvocationArgs, import("./identity/identity.js").IdentityInvocation<import("../index.js").BaseChangesResponseInvocationArgs>>;
|
|
47
|
+
set: import("../index.js").InvocationFactory<import("./identity/types.js").IdentitySetResponseInvocationArgs, import("./identity/identity.js").IdentityInvocation<import("./identity/types.js").IdentitySetResponseInvocationArgs>>;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
validators: {
|
|
52
|
+
name: string;
|
|
53
|
+
hook: "invocation";
|
|
54
|
+
trigger: {
|
|
55
|
+
capabilityUri?: import("../index.js").JMAPCapability;
|
|
56
|
+
dataType?: import("../index.js").JMAPDataType;
|
|
57
|
+
method?: import("../index.js").JMAPMethodName;
|
|
58
|
+
};
|
|
59
|
+
validate(this: void, context: import("../capability-registry/types.js").BasePluginContext & {
|
|
60
|
+
invocation: import("../index.js").Invocation<import("../index.js").BaseInvocationArgs>;
|
|
61
|
+
}): import("../index.js").MaybePromise<import("../capability-registry/types.js").ValidationResult>;
|
|
62
|
+
}[];
|
|
63
|
+
schema: {
|
|
64
|
+
accountCapability: z.ZodObject<{
|
|
65
|
+
maxDelayedSend: z.ZodNumber;
|
|
66
|
+
submissionExtensions: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
|
|
67
|
+
}, z.core.$loose>;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
declare module "../common/types.js" {
|
|
71
|
+
interface ServerCapabilityRegistry {
|
|
72
|
+
[SUBMISSION_CAPABILITY_URI]?: EmptyObject;
|
|
73
|
+
}
|
|
74
|
+
interface AccountCapabilityRegistry {
|
|
75
|
+
[SUBMISSION_CAPABILITY_URI]?: {
|
|
76
|
+
/**
|
|
77
|
+
* The number in seconds of the maximum delay the server supports in sending. This is 0 if
|
|
78
|
+
* the server does not support delayed send.
|
|
79
|
+
*/
|
|
80
|
+
maxDelayedSend: UnsignedInt;
|
|
81
|
+
/**
|
|
82
|
+
* The set of SMTP submission extensions supported by the server, which the client may use
|
|
83
|
+
* when creating an EmailSubmission object (see Section 7). Each key in the object is the
|
|
84
|
+
* ehlo-name, and the value is a list of ehlo-args.
|
|
85
|
+
*/
|
|
86
|
+
submissionExtensions: Record<string, string[]>;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
import { SUBMISSION_CAPABILITY_URI } from "../common/registry.js";
|
|
3
|
+
import { EmailSubmission } from "./emailsubmission/emailsubmission.js";
|
|
4
|
+
import { Identity } from "./identity/identity.js";
|
|
5
|
+
/**
|
|
6
|
+
* Validates that invocations using the Submission capability have a valid accountId that supports
|
|
7
|
+
* the Submission capability.
|
|
8
|
+
*
|
|
9
|
+
* This plugin performs three critical validation checks:
|
|
10
|
+
* 1. Verifies the invocation includes a valid `accountId` argument (non-empty string)
|
|
11
|
+
* 2. Confirms the account exists in the session's accounts collection
|
|
12
|
+
* 3. Ensures the account's `accountCapabilities` includes the Submission capability URI
|
|
13
|
+
*
|
|
14
|
+
* This validation applies to all Submission capability invocations (Identity and EmailSubmission
|
|
15
|
+
* method calls) and implements the account capability checks described in RFC 8621 Section 1.3.2.
|
|
16
|
+
*
|
|
17
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-1.3.2 | RFC 8621 Section 1.3.2: The Submission Capability}
|
|
18
|
+
*/
|
|
19
|
+
export const submissionAccountSupportPlugin = {
|
|
20
|
+
name: "submission-account-support",
|
|
21
|
+
hook: "invocation",
|
|
22
|
+
trigger: {
|
|
23
|
+
capabilityUri: SUBMISSION_CAPABILITY_URI,
|
|
24
|
+
},
|
|
25
|
+
validate(context) {
|
|
26
|
+
const { invocation, accounts } = context;
|
|
27
|
+
const accountId = invocation.getArgument("accountId");
|
|
28
|
+
if (typeof accountId !== "string" || accountId === "") {
|
|
29
|
+
return {
|
|
30
|
+
valid: false,
|
|
31
|
+
errors: [new Error(`Invocation is missing a valid accountId argument.`)],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const account = accounts[accountId];
|
|
35
|
+
if (!account) {
|
|
36
|
+
return {
|
|
37
|
+
valid: false,
|
|
38
|
+
errors: [new Error(`Account "${accountId}" does not exist.`)],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
if (!account.accountCapabilities[SUBMISSION_CAPABILITY_URI]) {
|
|
42
|
+
return {
|
|
43
|
+
valid: false,
|
|
44
|
+
errors: [new Error(`Account "${accountId}" does not support the Submission capability.`)],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return { valid: true };
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Defines the Submission capability, including all its associated invocations
|
|
52
|
+
* (EmailSubmission, Identity) and validation plugins.
|
|
53
|
+
*
|
|
54
|
+
* Per RFC 8621 Section 1.3.2, the `urn:ietf:params:jmap:submission` capability represents support
|
|
55
|
+
* for the Identity and EmailSubmission data types and associated API methods.
|
|
56
|
+
*
|
|
57
|
+
* Read-only account protection for `/set` methods is handled by Core's generic
|
|
58
|
+
* `preventSetOnReadOnlyAccountPlugin`.
|
|
59
|
+
*
|
|
60
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-1.3.2 | RFC 8621 Section 1.3.2: The Submission Capability}
|
|
61
|
+
*/
|
|
62
|
+
const submissionAccountCapabilitySchema = z.looseObject({
|
|
63
|
+
maxDelayedSend: z.number().int().min(0),
|
|
64
|
+
submissionExtensions: z.record(z.string(), z.array(z.string())),
|
|
65
|
+
});
|
|
66
|
+
export const SubmissionCapability = {
|
|
67
|
+
uri: SUBMISSION_CAPABILITY_URI,
|
|
68
|
+
invocations: {
|
|
69
|
+
EmailSubmission,
|
|
70
|
+
Identity,
|
|
71
|
+
},
|
|
72
|
+
validators: [submissionAccountSupportPlugin],
|
|
73
|
+
schema: { accountCapability: submissionAccountCapabilitySchema },
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=submission-capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submission-capability.js","sourceRoot":"","sources":["../../../src/capabilities/submission-capability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAmC;IAC1E,IAAI,EAAE,4BAA4B;IAClC,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE;QACL,aAAa,EAAE,yBAAyB;KAC3C;IACD,QAAQ,CAAC,OAAO;QACZ,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QACtD,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;YACpD,OAAO;gBACH,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,CAAC,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;aAC3E,CAAC;QACN,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,OAAO;gBACH,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,CAAC,IAAI,KAAK,CAAC,YAAY,SAAS,mBAAmB,CAAC,CAAC;aAChE,CAAC;QACN,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,yBAAyB,CAAC,EAAE,CAAC;YAC1D,OAAO;gBACH,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,CAAC,IAAI,KAAK,CAAC,YAAY,SAAS,+CAA+C,CAAC,CAAC;aAC5F,CAAC;QACN,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;CACJ,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,iCAAiC,GAAG,CAAC,CAAC,WAAW,CAAC;IACpD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,oBAAoB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;CAClE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAChC,GAAG,EAAE,yBAAyB;IAC9B,WAAW,EAAE;QACT,eAAe;QACf,QAAQ;KACX;IACD,UAAU,EAAE,CAAC,8BAA8B,CAAC;IAC5C,MAAM,EAAE,EAAE,iBAAiB,EAAE,iCAAiC,EAAE;CACpC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { JMAPCapability, JMAPMethodName } from "../../common/types.js";
|
|
2
|
+
import { Invocation } from "../../invocation/invocation.js";
|
|
3
|
+
import type { InvocationArgs, InvocationFactory } from "../../invocation/types.js";
|
|
4
|
+
import type { ThreadGetRequestInvocationArgs, ThreadGetResponseInvocationArgs, ThreadRequestInvocationArgs, ThreadResponseInvocationArgs } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* ThreadInvocation represents a JMAP Thread capability invocation.
|
|
7
|
+
*
|
|
8
|
+
* The Thread data type represents a conversation thread containing related email messages.
|
|
9
|
+
* It supports methods for retrieving threads and tracking changes.
|
|
10
|
+
*
|
|
11
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-3 | RFC 8621 Section 3: Threads}
|
|
12
|
+
*/
|
|
13
|
+
export declare class ThreadInvocation<TArgs extends ThreadRequestInvocationArgs | ThreadResponseInvocationArgs> extends Invocation<TArgs> {
|
|
14
|
+
get uri(): JMAPCapability;
|
|
15
|
+
/**
|
|
16
|
+
* Constructs a ThreadInvocation
|
|
17
|
+
*
|
|
18
|
+
* @param method The name of the method being invoked (e.g., "get", "changes")
|
|
19
|
+
* @param args The arguments for the method invocation
|
|
20
|
+
* @param methodCallId An optional unique symbol to identify this method call for result referencing
|
|
21
|
+
*/
|
|
22
|
+
constructor(method: JMAPMethodName, args: InvocationArgs<TArgs>, methodCallId?: symbol);
|
|
23
|
+
/**
|
|
24
|
+
* Create an invocation factory function
|
|
25
|
+
*
|
|
26
|
+
* @param method The name of the method to create
|
|
27
|
+
* @returns A new Thread invocation factory function for creating invocations of the specified type
|
|
28
|
+
*/
|
|
29
|
+
static createInvocationFactory<TArgs extends ThreadRequestInvocationArgs | ThreadResponseInvocationArgs>(method: JMAPMethodName): InvocationFactory<TArgs, ThreadInvocation<TArgs>>;
|
|
30
|
+
}
|
|
31
|
+
export declare const Thread: {
|
|
32
|
+
request: {
|
|
33
|
+
/**
|
|
34
|
+
* Retrieves Thread objects by their IDs.
|
|
35
|
+
*
|
|
36
|
+
* @param args The invocation arguments for Thread/get
|
|
37
|
+
* @param methodCallId An optional unique symbol to identify this method call for result referencing
|
|
38
|
+
* @returns A ThreadInvocation representing the Thread/get request
|
|
39
|
+
*
|
|
40
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-3.1 | RFC 8621 Section 3.1: Thread/get}
|
|
41
|
+
*/
|
|
42
|
+
get: InvocationFactory<ThreadGetRequestInvocationArgs, ThreadInvocation<ThreadGetRequestInvocationArgs>>;
|
|
43
|
+
/**
|
|
44
|
+
* Returns changes to Thread objects since a given state.
|
|
45
|
+
*
|
|
46
|
+
* @param args The invocation arguments for Thread/changes
|
|
47
|
+
* @param methodCallId An optional unique symbol to identify this method call for result referencing
|
|
48
|
+
* @returns A ThreadInvocation representing the Thread/changes request
|
|
49
|
+
*
|
|
50
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc8621.html#section-3.2 | RFC 8621 Section 3.2: Thread/changes}
|
|
51
|
+
*/
|
|
52
|
+
changes: InvocationFactory<import("../../invocation/types.js").BaseChangesRequestInvocationArgs, ThreadInvocation<import("../../invocation/types.js").BaseChangesRequestInvocationArgs>>;
|
|
53
|
+
};
|
|
54
|
+
response: {
|
|
55
|
+
get: InvocationFactory<ThreadGetResponseInvocationArgs, ThreadInvocation<ThreadGetResponseInvocationArgs>>;
|
|
56
|
+
changes: InvocationFactory<import("../../invocation/types.js").BaseChangesResponseInvocationArgs, ThreadInvocation<import("../../invocation/types.js").BaseChangesResponseInvocationArgs>>;
|
|
57
|
+
};
|
|
58
|
+
};
|