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.
Files changed (198) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -3
  3. package/dist/src/capabilities/blob/blob.d.ts +83 -0
  4. package/dist/src/capabilities/blob/blob.js +98 -0
  5. package/dist/src/capabilities/blob/blob.js.map +1 -0
  6. package/dist/src/capabilities/blob/types.d.ts +212 -0
  7. package/dist/src/capabilities/blob/types.js +16 -0
  8. package/dist/src/capabilities/blob/types.js.map +1 -0
  9. package/dist/src/capabilities/blob-capability.d.ts +195 -0
  10. package/dist/src/capabilities/blob-capability.js +277 -0
  11. package/dist/src/capabilities/blob-capability.js.map +1 -0
  12. package/dist/src/capabilities/core/core.d.ts +47 -0
  13. package/dist/src/capabilities/core/core.js +59 -0
  14. package/dist/src/capabilities/core/core.js.map +1 -0
  15. package/dist/src/capabilities/core/types.d.ts +13 -0
  16. package/dist/src/capabilities/core/types.js +2 -0
  17. package/dist/src/capabilities/core/types.js.map +1 -0
  18. package/dist/src/capabilities/core-capability.d.ts +307 -0
  19. package/dist/src/capabilities/core-capability.js +344 -0
  20. package/dist/src/capabilities/core-capability.js.map +1 -0
  21. package/dist/src/capabilities/email/email.d.ts +124 -0
  22. package/dist/src/capabilities/email/email.js +136 -0
  23. package/dist/src/capabilities/email/email.js.map +1 -0
  24. package/dist/src/capabilities/email/types.d.ts +776 -0
  25. package/dist/src/capabilities/email/types.js +2 -0
  26. package/dist/src/capabilities/email/types.js.map +1 -0
  27. package/dist/src/capabilities/email-capability.d.ts +266 -0
  28. package/dist/src/capabilities/email-capability.js +241 -0
  29. package/dist/src/capabilities/email-capability.js.map +1 -0
  30. package/dist/src/capabilities/emailsubmission/emailsubmission.d.ts +95 -0
  31. package/dist/src/capabilities/emailsubmission/emailsubmission.js +107 -0
  32. package/dist/src/capabilities/emailsubmission/emailsubmission.js.map +1 -0
  33. package/dist/src/capabilities/emailsubmission/types.d.ts +256 -0
  34. package/dist/src/capabilities/emailsubmission/types.js +2 -0
  35. package/dist/src/capabilities/emailsubmission/types.js.map +1 -0
  36. package/dist/src/capabilities/example/example.d.ts +80 -0
  37. package/dist/src/capabilities/example/example.js +91 -0
  38. package/dist/src/capabilities/example/example.js.map +1 -0
  39. package/dist/src/capabilities/example/types.d.ts +33 -0
  40. package/dist/src/capabilities/example/types.js +2 -0
  41. package/dist/src/capabilities/example/types.js.map +1 -0
  42. package/dist/src/capabilities/identity/identity.d.ts +71 -0
  43. package/dist/src/capabilities/identity/identity.js +83 -0
  44. package/dist/src/capabilities/identity/identity.js.map +1 -0
  45. package/dist/src/capabilities/identity/types.d.ts +110 -0
  46. package/dist/src/capabilities/identity/types.js +2 -0
  47. package/dist/src/capabilities/identity/types.js.map +1 -0
  48. package/dist/src/capabilities/mailbox/mailbox.d.ts +91 -0
  49. package/dist/src/capabilities/mailbox/mailbox.js +103 -0
  50. package/dist/src/capabilities/mailbox/mailbox.js.map +1 -0
  51. package/dist/src/capabilities/mailbox/types.d.ts +248 -0
  52. package/dist/src/capabilities/mailbox/types.js +2 -0
  53. package/dist/src/capabilities/mailbox/types.js.map +1 -0
  54. package/dist/src/capabilities/maskedemail/maskedemail.d.ts +60 -0
  55. package/dist/src/capabilities/maskedemail/maskedemail.js +72 -0
  56. package/dist/src/capabilities/maskedemail/maskedemail.js.map +1 -0
  57. package/dist/src/capabilities/maskedemail/types.d.ts +67 -0
  58. package/dist/src/capabilities/maskedemail/types.js +4 -0
  59. package/dist/src/capabilities/maskedemail/types.js.map +1 -0
  60. package/dist/src/capabilities/maskedemail-capability.d.ts +112 -0
  61. package/dist/src/capabilities/maskedemail-capability.js +166 -0
  62. package/dist/src/capabilities/maskedemail-capability.js.map +1 -0
  63. package/dist/src/capabilities/searchsnippet/searchsnippet.d.ts +51 -0
  64. package/dist/src/capabilities/searchsnippet/searchsnippet.js +63 -0
  65. package/dist/src/capabilities/searchsnippet/searchsnippet.js.map +1 -0
  66. package/dist/src/capabilities/searchsnippet/types.d.ts +88 -0
  67. package/dist/src/capabilities/searchsnippet/types.js +2 -0
  68. package/dist/src/capabilities/searchsnippet/types.js.map +1 -0
  69. package/dist/src/capabilities/submission-capability.d.ts +89 -0
  70. package/dist/src/capabilities/submission-capability.js +75 -0
  71. package/dist/src/capabilities/submission-capability.js.map +1 -0
  72. package/dist/src/capabilities/thread/thread.d.ts +58 -0
  73. package/dist/src/capabilities/thread/thread.js +70 -0
  74. package/dist/src/capabilities/thread/thread.js.map +1 -0
  75. package/dist/src/capabilities/thread/types.d.ts +43 -0
  76. package/dist/src/capabilities/thread/types.js +2 -0
  77. package/dist/src/capabilities/thread/types.js.map +1 -0
  78. package/dist/src/capabilities/utils/assert-invocation-datatype.d.ts +7 -0
  79. package/dist/src/capabilities/utils/assert-invocation-datatype.js +13 -0
  80. package/dist/src/capabilities/utils/assert-invocation-datatype.js.map +1 -0
  81. package/dist/src/capabilities/utils/assert-invocation-method.d.ts +7 -0
  82. package/dist/src/capabilities/utils/assert-invocation-method.js +13 -0
  83. package/dist/src/capabilities/utils/assert-invocation-method.js.map +1 -0
  84. package/dist/src/capabilities/utils/assert-invocation.d.ts +7 -0
  85. package/dist/src/capabilities/utils/assert-invocation.js +22 -0
  86. package/dist/src/capabilities/utils/assert-invocation.js.map +1 -0
  87. package/dist/src/capabilities/utils/assert-non-nullish.d.ts +1 -0
  88. package/dist/src/capabilities/utils/assert-non-nullish.js +6 -0
  89. package/dist/src/capabilities/utils/assert-non-nullish.js.map +1 -0
  90. package/dist/src/capabilities/utils/create-readonly-account-validator.d.ts +49 -0
  91. package/dist/src/capabilities/utils/create-readonly-account-validator.js +80 -0
  92. package/dist/src/capabilities/utils/create-readonly-account-validator.js.map +1 -0
  93. package/dist/src/capabilities/vacationresponse/types.d.ts +100 -0
  94. package/dist/src/capabilities/vacationresponse/types.js +2 -0
  95. package/dist/src/capabilities/vacationresponse/types.js.map +1 -0
  96. package/dist/src/capabilities/vacationresponse/vacationresponse.d.ts +61 -0
  97. package/dist/src/capabilities/vacationresponse/vacationresponse.js +73 -0
  98. package/dist/src/capabilities/vacationresponse/vacationresponse.js.map +1 -0
  99. package/dist/src/capabilities/vacationresponse-capability.d.ts +65 -0
  100. package/dist/src/capabilities/vacationresponse-capability.js +68 -0
  101. package/dist/src/capabilities/vacationresponse-capability.js.map +1 -0
  102. package/dist/src/capability-registry/capability-registry.d.ts +148 -0
  103. package/dist/src/capability-registry/capability-registry.js +360 -0
  104. package/dist/src/capability-registry/capability-registry.js.map +1 -0
  105. package/dist/src/capability-registry/types.d.ts +385 -0
  106. package/dist/src/capability-registry/types.js +2 -0
  107. package/dist/src/capability-registry/types.js.map +1 -0
  108. package/dist/src/capability-registry/utils.d.ts +71 -0
  109. package/dist/src/capability-registry/utils.js +163 -0
  110. package/dist/src/capability-registry/utils.js.map +1 -0
  111. package/dist/src/common/registry.d.ts +366 -0
  112. package/dist/src/common/registry.js +321 -0
  113. package/dist/src/common/registry.js.map +1 -0
  114. package/dist/src/common/types.d.ts +338 -0
  115. package/dist/src/common/types.js +21 -0
  116. package/dist/src/common/types.js.map +1 -0
  117. package/dist/src/common/utils.d.ts +20 -0
  118. package/dist/src/common/utils.js +26 -0
  119. package/dist/src/common/utils.js.map +1 -0
  120. package/dist/src/index.d.ts +40 -0
  121. package/dist/src/index.js +33 -0
  122. package/dist/src/index.js.map +1 -0
  123. package/dist/src/invocation/arguments-proxy.d.ts +14 -0
  124. package/dist/src/invocation/arguments-proxy.js +37 -0
  125. package/dist/src/invocation/arguments-proxy.js.map +1 -0
  126. package/dist/src/invocation/error-invocation.d.ts +27 -0
  127. package/dist/src/invocation/error-invocation.js +39 -0
  128. package/dist/src/invocation/error-invocation.js.map +1 -0
  129. package/dist/src/invocation/invocation.d.ts +111 -0
  130. package/dist/src/invocation/invocation.js +158 -0
  131. package/dist/src/invocation/invocation.js.map +1 -0
  132. package/dist/src/invocation/result-reference.d.ts +86 -0
  133. package/dist/src/invocation/result-reference.js +118 -0
  134. package/dist/src/invocation/result-reference.js.map +1 -0
  135. package/dist/src/invocation/types.d.ts +637 -0
  136. package/dist/src/invocation/types.js +2 -0
  137. package/dist/src/invocation/types.js.map +1 -0
  138. package/dist/src/invocation/utils.d.ts +21 -0
  139. package/dist/src/invocation/utils.js +30 -0
  140. package/dist/src/invocation/utils.js.map +1 -0
  141. package/dist/src/invocation-factory/invocation-factory-manager.d.ts +20 -0
  142. package/dist/src/invocation-factory/invocation-factory-manager.js +50 -0
  143. package/dist/src/invocation-factory/invocation-factory-manager.js.map +1 -0
  144. package/dist/src/invocation-factory/invocation-list.d.ts +32 -0
  145. package/dist/src/invocation-factory/invocation-list.js +77 -0
  146. package/dist/src/invocation-factory/invocation-list.js.map +1 -0
  147. package/dist/src/invocation-factory/types.d.ts +11 -0
  148. package/dist/src/invocation-factory/types.js +2 -0
  149. package/dist/src/invocation-factory/types.js.map +1 -0
  150. package/dist/src/jmap-client/jmap-client.d.ts +252 -0
  151. package/dist/src/jmap-client/jmap-client.js +777 -0
  152. package/dist/src/jmap-client/jmap-client.js.map +1 -0
  153. package/dist/src/jmap-client/types.d.ts +427 -0
  154. package/dist/src/jmap-client/types.js +21 -0
  155. package/dist/src/jmap-client/types.js.map +1 -0
  156. package/dist/src/jmap-client/utils/abort-controller.d.ts +8 -0
  157. package/dist/src/jmap-client/utils/abort-controller.js +24 -0
  158. package/dist/src/jmap-client/utils/abort-controller.js.map +1 -0
  159. package/dist/src/jmap-client/utils/assert-connected.d.ts +7 -0
  160. package/dist/src/jmap-client/utils/assert-connected.js +11 -0
  161. package/dist/src/jmap-client/utils/assert-connected.js.map +1 -0
  162. package/dist/src/jmap-client/utils/deep-freeze.d.ts +7 -0
  163. package/dist/src/jmap-client/utils/deep-freeze.js +17 -0
  164. package/dist/src/jmap-client/utils/deep-freeze.js.map +1 -0
  165. package/dist/src/jmap-client/utils/emitter.d.ts +9 -0
  166. package/dist/src/jmap-client/utils/emitter.js +18 -0
  167. package/dist/src/jmap-client/utils/emitter.js.map +1 -0
  168. package/dist/src/jmap-client/utils/filter-session-capabilities.d.ts +22 -0
  169. package/dist/src/jmap-client/utils/filter-session-capabilities.js +40 -0
  170. package/dist/src/jmap-client/utils/filter-session-capabilities.js.map +1 -0
  171. package/dist/src/jmap-client/utils/jmap-request-error.d.ts +28 -0
  172. package/dist/src/jmap-client/utils/jmap-request-error.js +48 -0
  173. package/dist/src/jmap-client/utils/jmap-request-error.js.map +1 -0
  174. package/dist/src/jmap-client/utils/logger.d.ts +6 -0
  175. package/dist/src/jmap-client/utils/logger.js +22 -0
  176. package/dist/src/jmap-client/utils/logger.js.map +1 -0
  177. package/dist/src/jmap-client/utils/merge-headers.d.ts +11 -0
  178. package/dist/src/jmap-client/utils/merge-headers.js +40 -0
  179. package/dist/src/jmap-client/utils/merge-headers.js.map +1 -0
  180. package/dist/src/jmap-client/utils/template-utils.d.ts +27 -0
  181. package/dist/src/jmap-client/utils/template-utils.js +61 -0
  182. package/dist/src/jmap-client/utils/template-utils.js.map +1 -0
  183. package/dist/src/jmap-client/utils/track-utils.d.ts +19 -0
  184. package/dist/src/jmap-client/utils/track-utils.js +35 -0
  185. package/dist/src/jmap-client/utils/track-utils.js.map +1 -0
  186. package/dist/src/jmap-client/utils/transport.d.ts +12 -0
  187. package/dist/src/jmap-client/utils/transport.js +38 -0
  188. package/dist/src/jmap-client/utils/transport.js.map +1 -0
  189. package/dist/src/jmap-client/utils/validate-session.d.ts +19 -0
  190. package/dist/src/jmap-client/utils/validate-session.js +29 -0
  191. package/dist/src/jmap-client/utils/validate-session.js.map +1 -0
  192. package/dist/src/request-builder/request-builder.d.ts +95 -0
  193. package/dist/src/request-builder/request-builder.js +343 -0
  194. package/dist/src/request-builder/request-builder.js.map +1 -0
  195. package/dist/src/request-builder/types.d.ts +32 -0
  196. package/dist/src/request-builder/types.js +2 -0
  197. package/dist/src/request-builder/types.js.map +1 -0
  198. 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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -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
+ };