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,195 @@
1
+ import { z } from "zod/v4";
2
+ import type { ValidationPlugin } from "../capability-registry/types.js";
3
+ import { BLOB_CAPABILITY_URI } from "../common/registry.js";
4
+ import type { BlobCopyRequestInvocationArgs, BlobUploadRequestInvocationArgs, HTTPDigestAlgorithm } from "./blob/types.js";
5
+ /**
6
+ * Validates that invocations using the Blob capability have a valid accountId that supports the Blob 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 Blob capability URI
12
+ *
13
+ * This validation applies to all Blob capability invocations (`Blob/upload`, `Blob/get`, `Blob/lookup`)
14
+ * and implements the account capability checks for the Blob Management Extension (RFC 9404).
15
+ *
16
+ * Note: `Blob/copy` is part of the Core capability and is validated separately in core-capability.ts.
17
+ *
18
+ * @see {@link https://www.rfc-editor.org/rfc/rfc9404.html | RFC 9404: JMAP Blob Management Extension}
19
+ * @see {@link https://www.rfc-editor.org/rfc/rfc8620.html#section-1.6.2 | RFC 8620 Section 1.6.2: Accounts}
20
+ */
21
+ export declare const blobAccountSupportPlugin: ValidationPlugin<"invocation">;
22
+ /**
23
+ * Validates server-defined constraints for Blob/copy operations.
24
+ *
25
+ * This plugin enforces the requirement that Blob/copy operations must copy between
26
+ * different accounts. Attempting to copy blobs within the same account is invalid and would
27
+ * be rejected by the server.
28
+ *
29
+ * **Same-Account Copy Prevention (RFC 8620 Section 6.3):**
30
+ * - Validates that `fromAccountId` and `accountId` are different
31
+ * - `Blob/copy` is designed for cross-account blob sharing
32
+ * - Blobs within the same account are already accessible without copying
33
+ * - Prevents unnecessary server operations and resource usage
34
+ *
35
+ * This validation catches the error client-side before making a server request, providing
36
+ * immediate feedback and avoiding unnecessary network round-trips.
37
+ *
38
+ * @see {@link https://www.rfc-editor.org/rfc/rfc8620.html#section-6.3 | RFC 8620 Section 6.3: Blob/copy}
39
+ */
40
+ export declare const blobCopyValidationPlugin: ValidationPlugin<"invocation", BlobCopyRequestInvocationArgs>;
41
+ /**
42
+ * Validates server-defined constraints for `Blob/upload` operations.
43
+ *
44
+ * This plugin enforces account-specific blob creation limits defined in the Blob capability:
45
+ *
46
+ * **Blob Size Limit (RFC 9404 Section 4.1):**
47
+ * - Validates that the total blob size does not exceed `maxSizeBlobSet` octets
48
+ * - The limit is server-defined and specified in the account's Blob capability object
49
+ * - If `maxSizeBlobSet` is null, no client-side size limit is enforced
50
+ * - Calculates size from all DataSourceObjects (literal data and referenced blobs)
51
+ * - Note: For referenced blobs, size validation requires the client to know the blob sizes
52
+ *
53
+ * **Data Source Count Limit (RFC 9404 Section 4.1):**
54
+ * - Validates that the number of DataSourceObjects does not exceed `maxDataSources`
55
+ * - Servers MUST support at least 64 DataSourceObjects per creation
56
+ * - This limit prevents excessive resource usage during blob concatenation
57
+ *
58
+ * These validations catch client errors before sending requests to the server, providing
59
+ * immediate feedback and avoiding unnecessary network round-trips. Note that servers may
60
+ * still reject uploads for other reasons (disk space, rate limits, etc.).
61
+ *
62
+ * @see {@link https://www.rfc-editor.org/rfc/rfc9404.html#section-4.1 | RFC 9404 Section 4.1: Blob/upload}
63
+ * @see {@link https://www.rfc-editor.org/rfc/rfc9404.html#section-2 | RFC 9404 Section 2: Addition to the Capabilities Object}
64
+ */
65
+ export declare const blobUploadValidationPlugin: ValidationPlugin<"invocation", BlobUploadRequestInvocationArgs>;
66
+ /**
67
+ * Prevents Blob/upload operations on read-only accounts.
68
+ *
69
+ * **Read-Only Account Protection for Blob/upload:**
70
+ * - Validates that the target account's `isReadOnly` property is `false`
71
+ * - Blob/upload creates new blobs in the account, requiring write access
72
+ * - Attempting to upload to a read-only account would fail with an `accountReadOnly` error
73
+ *
74
+ * This validator catches the error client-side before making a server request, providing
75
+ * immediate feedback when attempting to upload blobs to read-only accounts.
76
+ *
77
+ * **Common read-only scenarios:**
78
+ * - Shared accounts with read-only permissions
79
+ * - Archive or backup accounts
80
+ * - Accounts in maintenance mode
81
+ *
82
+ * @see {@link https://www.rfc-editor.org/rfc/rfc9404.html#section-4.1 | RFC 9404 Section 4.1: Blob/upload}
83
+ */
84
+ export declare const preventBlobUploadOnReadOnlyAccountPlugin: ValidationPlugin<"invocation", BlobUploadRequestInvocationArgs>;
85
+ /**
86
+ * Defines the Blob capability, including Blob invocations (except Blob/copy which is in Core)
87
+ * and validation plugins for the Blob Management Extension.
88
+ */
89
+ export declare const BlobCapability: {
90
+ uri: "urn:ietf:params:jmap:blob";
91
+ invocations: {
92
+ Blob: {
93
+ request: {
94
+ upload: import("../index.js").InvocationFactory<BlobUploadRequestInvocationArgs, import("./blob/blob.js").BlobInvocation<BlobUploadRequestInvocationArgs>>;
95
+ get: import("../index.js").InvocationFactory<import("./blob/types.js").BlobGetRequestInvocationArgs, import("./blob/blob.js").BlobInvocation<import("./blob/types.js").BlobGetRequestInvocationArgs>>;
96
+ lookup: import("../index.js").InvocationFactory<import("./blob/types.js").BlobLookupRequestInvocationArgs, import("./blob/blob.js").BlobInvocation<import("./blob/types.js").BlobLookupRequestInvocationArgs>>;
97
+ };
98
+ response: {
99
+ upload: import("../index.js").InvocationFactory<import("./blob/types.js").BlobUploadResponseInvocationArgs, import("./blob/blob.js").BlobInvocation<import("./blob/types.js").BlobUploadResponseInvocationArgs>>;
100
+ get: import("../index.js").InvocationFactory<import("./blob/types.js").BlobGetResponseInvocationArgs, import("./blob/blob.js").BlobInvocation<import("./blob/types.js").BlobGetResponseInvocationArgs>>;
101
+ lookup: import("../index.js").InvocationFactory<import("./blob/types.js").BlobLookupResponseInvocationArgs, import("./blob/blob.js").BlobInvocation<import("./blob/types.js").BlobLookupResponseInvocationArgs>>;
102
+ };
103
+ };
104
+ };
105
+ validators: ({
106
+ name: string;
107
+ hook: "invocation";
108
+ trigger: {
109
+ capabilityUri?: import("../index.js").JMAPCapability;
110
+ dataType?: import("../index.js").JMAPDataType;
111
+ method?: import("../index.js").JMAPMethodName;
112
+ };
113
+ validate(this: void, context: import("../capability-registry/types.js").BasePluginContext & {
114
+ invocation: import("../index.js").Invocation<BlobCopyRequestInvocationArgs>;
115
+ }): import("../index.js").MaybePromise<import("../capability-registry/types.js").ValidationResult>;
116
+ } | {
117
+ name: string;
118
+ hook: "invocation";
119
+ trigger: {
120
+ capabilityUri?: import("../index.js").JMAPCapability;
121
+ dataType?: import("../index.js").JMAPDataType;
122
+ method?: import("../index.js").JMAPMethodName;
123
+ };
124
+ validate(this: void, context: import("../capability-registry/types.js").BasePluginContext & {
125
+ invocation: import("../index.js").Invocation<import("../index.js").BaseInvocationArgs>;
126
+ }): import("../index.js").MaybePromise<import("../capability-registry/types.js").ValidationResult>;
127
+ } | {
128
+ name: string;
129
+ hook: "invocation";
130
+ trigger: {
131
+ capabilityUri?: import("../index.js").JMAPCapability;
132
+ dataType?: import("../index.js").JMAPDataType;
133
+ method?: import("../index.js").JMAPMethodName;
134
+ };
135
+ validate(this: void, context: import("../capability-registry/types.js").BasePluginContext & {
136
+ invocation: import("../index.js").Invocation<BlobUploadRequestInvocationArgs>;
137
+ }): import("../index.js").MaybePromise<import("../capability-registry/types.js").ValidationResult>;
138
+ })[];
139
+ schema: {
140
+ accountCapability: z.ZodObject<{
141
+ maxSizeBlobSet: z.ZodNullable<z.ZodNumber>;
142
+ maxDataSources: z.ZodNumber;
143
+ supportedTypeNames: z.ZodArray<z.ZodString>;
144
+ supportedDigestAlgorithms: z.ZodArray<z.ZodEnum<{
145
+ adler32: "adler32";
146
+ crc32c: "crc32c";
147
+ md5: "md5";
148
+ sha: "sha";
149
+ "sha-256": "sha-256";
150
+ "sha-512": "sha-512";
151
+ unixsum: "unixsum";
152
+ unixcksum: "unixcksum";
153
+ }>>;
154
+ }, z.core.$loose>;
155
+ };
156
+ };
157
+ declare module "../common/types.js" {
158
+ interface ServerCapabilityRegistry {
159
+ [BLOB_CAPABILITY_URI]?: EmptyObject;
160
+ }
161
+ interface AccountCapabilityRegistry {
162
+ [BLOB_CAPABILITY_URI]?: {
163
+ /**
164
+ * The maximum size of the blob (in octets) that the server will allow to be created
165
+ * (including blobs created by concatenating multiple data sources together).Clients
166
+ * MUST NOT attempt to create blobs larger than this size.If this value is null, then
167
+ * clients are not required to limit the size of the blob they try to create, though
168
+ * servers can always reject creation of blobs regardless of size, e.g., due to lack
169
+ * of disk space or per-user rate limits.
170
+ */
171
+ maxSizeBlobSet: UnsignedInt | null;
172
+ /**
173
+ * The maximum number of DataSourceObjects allowed per creation in a Blob/upload.
174
+ * Servers MUST allow at least 64 DataSourceObjects per creation.
175
+ */
176
+ maxDataSources: UnsignedInt;
177
+ /**
178
+ * An array of data type names that are supported for Blob/lookup. If the server does not
179
+ * support lookups, then this will be the empty list. Note that the supportedTypeNames list
180
+ * may include private types that are not in the "JMAP Data Types" registry defined by this
181
+ * document. Clients MUST ignore type names they do not recognise.
182
+ */
183
+ supportedTypeNames: JMAPDataType[];
184
+ /**
185
+ * An array of supported digest algorithms that are supported for Blob/get. If the server
186
+ * does not support calculating blob digests, then this will be the empty list. Algorithms
187
+ * in this list MUST be present in the "HTTP Digest Algorithm Values" registry defined by
188
+ * {@link https://www.rfc-editor.org/rfc/rfc3230.html RFC 3230}; however, in JMAP, they must be
189
+ * lowercased, e.g., "md5" rather than "MD5".Clients SHOULD prefer algorithms listed earlier
190
+ * in this list.
191
+ */
192
+ supportedDigestAlgorithms: HTTPDigestAlgorithm[];
193
+ };
194
+ }
195
+ }
@@ -0,0 +1,277 @@
1
+ import { z } from "zod/v4";
2
+ import { BLOB_CAPABILITY_URI } from "../common/registry.js";
3
+ import { Blob } from "./blob/blob.js";
4
+ import { HTTPDigestAlgorithmSchema } from "./blob/types.js";
5
+ import { assertInvocation } from "./utils/assert-invocation.js";
6
+ import { createReadOnlyAccountValidator } from "./utils/create-readonly-account-validator.js";
7
+ /**
8
+ * Validates that invocations using the Blob capability have a valid accountId that supports the Blob capability.
9
+ *
10
+ * This plugin performs three critical validation checks:
11
+ * 1. Verifies the invocation includes a valid `accountId` argument (non-empty string)
12
+ * 2. Confirms the account exists in the session's accounts collection
13
+ * 3. Ensures the account's `accountCapabilities` includes the Blob capability URI
14
+ *
15
+ * This validation applies to all Blob capability invocations (`Blob/upload`, `Blob/get`, `Blob/lookup`)
16
+ * and implements the account capability checks for the Blob Management Extension (RFC 9404).
17
+ *
18
+ * Note: `Blob/copy` is part of the Core capability and is validated separately in core-capability.ts.
19
+ *
20
+ * @see {@link https://www.rfc-editor.org/rfc/rfc9404.html | RFC 9404: JMAP Blob Management Extension}
21
+ * @see {@link https://www.rfc-editor.org/rfc/rfc8620.html#section-1.6.2 | RFC 8620 Section 1.6.2: Accounts}
22
+ */
23
+ export const blobAccountSupportPlugin = {
24
+ name: "blob-account-support",
25
+ hook: "invocation",
26
+ trigger: {
27
+ capabilityUri: BLOB_CAPABILITY_URI,
28
+ },
29
+ validate(context) {
30
+ const { invocation, accounts } = context;
31
+ const accountId = invocation.getArgument("accountId");
32
+ if (typeof accountId !== "string" || accountId === "") {
33
+ return {
34
+ valid: false,
35
+ errors: [new Error(`Invocation is missing a valid accountId argument.`)],
36
+ };
37
+ }
38
+ const account = accounts[accountId];
39
+ if (!account) {
40
+ return {
41
+ valid: false,
42
+ errors: [new Error(`Account "${accountId}" does not exist.`)],
43
+ };
44
+ }
45
+ if (!account.accountCapabilities[BLOB_CAPABILITY_URI]) {
46
+ return {
47
+ valid: false,
48
+ errors: [new Error(`Account "${accountId}" does not support the Blob capability.`)],
49
+ };
50
+ }
51
+ return { valid: true };
52
+ },
53
+ };
54
+ /**
55
+ * Validates server-defined constraints for Blob/copy operations.
56
+ *
57
+ * This plugin enforces the requirement that Blob/copy operations must copy between
58
+ * different accounts. Attempting to copy blobs within the same account is invalid and would
59
+ * be rejected by the server.
60
+ *
61
+ * **Same-Account Copy Prevention (RFC 8620 Section 6.3):**
62
+ * - Validates that `fromAccountId` and `accountId` are different
63
+ * - `Blob/copy` is designed for cross-account blob sharing
64
+ * - Blobs within the same account are already accessible without copying
65
+ * - Prevents unnecessary server operations and resource usage
66
+ *
67
+ * This validation catches the error client-side before making a server request, providing
68
+ * immediate feedback and avoiding unnecessary network round-trips.
69
+ *
70
+ * @see {@link https://www.rfc-editor.org/rfc/rfc8620.html#section-6.3 | RFC 8620 Section 6.3: Blob/copy}
71
+ */
72
+ export const blobCopyValidationPlugin = {
73
+ name: "blob-copy-validation",
74
+ hook: "invocation",
75
+ trigger: {
76
+ dataType: "Blob",
77
+ method: "copy",
78
+ },
79
+ validate(context) {
80
+ const { invocation, accounts } = context;
81
+ assertInvocation(invocation, "Blob", "copy");
82
+ const accountId = invocation.getArgument("accountId");
83
+ const fromAccountId = invocation.getArgument("fromAccountId");
84
+ if (accountId === fromAccountId) {
85
+ return {
86
+ valid: false,
87
+ errors: [new Error(`Cannot copy blobs to the same account. fromAccountId and accountId must differ.`)],
88
+ };
89
+ }
90
+ // Validate both accounts exist
91
+ const errors = [];
92
+ if (!accounts[accountId]) {
93
+ errors.push(new Error(`Account "${accountId}" does not exist.`));
94
+ }
95
+ if (!accounts[fromAccountId]) {
96
+ errors.push(new Error(`Account "${fromAccountId}" does not exist.`));
97
+ }
98
+ if (errors.length > 0) {
99
+ return { valid: false, errors };
100
+ }
101
+ return { valid: true };
102
+ },
103
+ };
104
+ /**
105
+ * Calculates the total size in octets for an array of DataSourceObjects.
106
+ * Returns null if the size cannot be calculated (e.g., when referencing external blobs).
107
+ */
108
+ function calculateDataSourceSize(data) {
109
+ let totalSize = 0;
110
+ for (const source of data) {
111
+ if ("data:asText" in source && source["data:asText"] !== null) {
112
+ // UTF-8 encoded text
113
+ totalSize += new TextEncoder().encode(source["data:asText"]).length;
114
+ }
115
+ else if ("data:asBase64" in source && source["data:asBase64"] !== null) {
116
+ // Base64 encoded data (decode to get actual size)
117
+ const base64 = source["data:asBase64"];
118
+ // Each base64 group of 4 chars represents 3 bytes
119
+ // Remove padding characters to calculate accurate size
120
+ const paddingChars = (base64.match(/=/g) ?? []).length;
121
+ totalSize += (base64.length * 3) / 4 - paddingChars;
122
+ }
123
+ else /* ("blobId" in source) */ {
124
+ // Referenced blob - we can't validate size without knowing the blob size
125
+ // Server will validate this
126
+ return null;
127
+ }
128
+ }
129
+ return totalSize;
130
+ }
131
+ /**
132
+ * Validates a single blob upload against account limits.
133
+ */
134
+ function validateBlobUpload(creationId, uploadObject, maxDataSources, maxSizeBlobSet) {
135
+ const errors = [];
136
+ const data = uploadObject.data;
137
+ if (!Array.isArray(data)) {
138
+ return errors;
139
+ }
140
+ // Check data source count
141
+ if (data.length > maxDataSources) {
142
+ errors.push(new Error(`Blob "${creationId}" has ${data.length} data sources, but account limit is ${maxDataSources}`));
143
+ }
144
+ // Check blob size if maxSizeBlobSet is set
145
+ if (maxSizeBlobSet !== null) {
146
+ const totalSize = calculateDataSourceSize(data);
147
+ if (totalSize !== null && totalSize > maxSizeBlobSet) {
148
+ const sizeInKB = (totalSize / 1000).toFixed(2);
149
+ const maxSizeInKB = (maxSizeBlobSet / 1000).toFixed(2);
150
+ errors.push(new Error(`Blob "${creationId}" size (${sizeInKB} KB) exceeds account limit of ${maxSizeInKB} KB`));
151
+ }
152
+ }
153
+ return errors;
154
+ }
155
+ /**
156
+ * Validates server-defined constraints for `Blob/upload` operations.
157
+ *
158
+ * This plugin enforces account-specific blob creation limits defined in the Blob capability:
159
+ *
160
+ * **Blob Size Limit (RFC 9404 Section 4.1):**
161
+ * - Validates that the total blob size does not exceed `maxSizeBlobSet` octets
162
+ * - The limit is server-defined and specified in the account's Blob capability object
163
+ * - If `maxSizeBlobSet` is null, no client-side size limit is enforced
164
+ * - Calculates size from all DataSourceObjects (literal data and referenced blobs)
165
+ * - Note: For referenced blobs, size validation requires the client to know the blob sizes
166
+ *
167
+ * **Data Source Count Limit (RFC 9404 Section 4.1):**
168
+ * - Validates that the number of DataSourceObjects does not exceed `maxDataSources`
169
+ * - Servers MUST support at least 64 DataSourceObjects per creation
170
+ * - This limit prevents excessive resource usage during blob concatenation
171
+ *
172
+ * These validations catch client errors before sending requests to the server, providing
173
+ * immediate feedback and avoiding unnecessary network round-trips. Note that servers may
174
+ * still reject uploads for other reasons (disk space, rate limits, etc.).
175
+ *
176
+ * @see {@link https://www.rfc-editor.org/rfc/rfc9404.html#section-4.1 | RFC 9404 Section 4.1: Blob/upload}
177
+ * @see {@link https://www.rfc-editor.org/rfc/rfc9404.html#section-2 | RFC 9404 Section 2: Addition to the Capabilities Object}
178
+ */
179
+ export const blobUploadValidationPlugin = {
180
+ name: "blob-upload-validation",
181
+ hook: "invocation",
182
+ trigger: {
183
+ dataType: "Blob",
184
+ method: "upload",
185
+ },
186
+ validate(context) {
187
+ const { invocation, accounts } = context;
188
+ assertInvocation(invocation, "Blob", "upload");
189
+ const accountId = invocation.getArgument("accountId");
190
+ const account = accounts[accountId];
191
+ if (!account) {
192
+ return {
193
+ valid: false,
194
+ errors: [new Error(`Account "${accountId}" does not exist.`)],
195
+ };
196
+ }
197
+ const blobCapability = account.accountCapabilities[BLOB_CAPABILITY_URI];
198
+ if (!blobCapability) {
199
+ return {
200
+ valid: false,
201
+ errors: [new Error(`Account "${accountId}" does not support the Blob capability.`)],
202
+ };
203
+ }
204
+ const create = invocation.getArgument("create");
205
+ const errors = [];
206
+ const { maxSizeBlobSet, maxDataSources } = blobCapability;
207
+ // Validate each blob creation
208
+ for (const [creationId, uploadObject] of Object.entries(create)) {
209
+ const blobErrors = validateBlobUpload(creationId, uploadObject, maxDataSources, maxSizeBlobSet);
210
+ errors.push(...blobErrors);
211
+ }
212
+ if (errors.length > 0) {
213
+ return { valid: false, errors };
214
+ }
215
+ return { valid: true };
216
+ },
217
+ };
218
+ /**
219
+ * Prevents Blob/upload operations on read-only accounts.
220
+ *
221
+ * **Read-Only Account Protection for Blob/upload:**
222
+ * - Validates that the target account's `isReadOnly` property is `false`
223
+ * - Blob/upload creates new blobs in the account, requiring write access
224
+ * - Attempting to upload to a read-only account would fail with an `accountReadOnly` error
225
+ *
226
+ * This validator catches the error client-side before making a server request, providing
227
+ * immediate feedback when attempting to upload blobs to read-only accounts.
228
+ *
229
+ * **Common read-only scenarios:**
230
+ * - Shared accounts with read-only permissions
231
+ * - Archive or backup accounts
232
+ * - Accounts in maintenance mode
233
+ *
234
+ * @see {@link https://www.rfc-editor.org/rfc/rfc9404.html#section-4.1 | RFC 9404 Section 4.1: Blob/upload}
235
+ */
236
+ export const preventBlobUploadOnReadOnlyAccountPlugin = createReadOnlyAccountValidator({
237
+ name: "blob-prevent-upload-on-readonly-account",
238
+ trigger: {
239
+ dataType: "Blob",
240
+ method: "upload",
241
+ },
242
+ });
243
+ const blobAccountCapabilitySchema = z.looseObject({
244
+ maxSizeBlobSet: z.number().int().min(0).nullable(),
245
+ maxDataSources: z.number().int().min(1),
246
+ supportedTypeNames: z.array(z.string()),
247
+ supportedDigestAlgorithms: z.array(HTTPDigestAlgorithmSchema),
248
+ });
249
+ /**
250
+ * Defines the Blob capability, including Blob invocations (except Blob/copy which is in Core)
251
+ * and validation plugins for the Blob Management Extension.
252
+ */
253
+ export const BlobCapability = {
254
+ uri: BLOB_CAPABILITY_URI,
255
+ invocations: {
256
+ Blob: {
257
+ request: {
258
+ upload: Blob.request.upload,
259
+ get: Blob.request.get,
260
+ lookup: Blob.request.lookup,
261
+ },
262
+ response: {
263
+ upload: Blob.response.upload,
264
+ get: Blob.response.get,
265
+ lookup: Blob.response.lookup,
266
+ },
267
+ },
268
+ },
269
+ validators: [
270
+ blobAccountSupportPlugin,
271
+ blobCopyValidationPlugin,
272
+ blobUploadValidationPlugin,
273
+ preventBlobUploadOnReadOnlyAccountPlugin,
274
+ ],
275
+ schema: { accountCapability: blobAccountCapabilitySchema },
276
+ };
277
+ //# sourceMappingURL=blob-capability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob-capability.js","sourceRoot":"","sources":["../../../src/capabilities/blob-capability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
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 { CoreInvocationArgs } from "./types.js";
5
+ /**
6
+ * CoreInvocation represents a JMAP Core capability invocation.
7
+ *
8
+ * The Core data type only exposes the `/echo` method and must be supported by all JMAP servers.
9
+ *
10
+ * @see {@link https://www.rfc-editor.org/rfc/rfc8620.html#section-4 | RFC 8620 Section 4: The Core/echo Method}
11
+ */
12
+ export declare class CoreInvocation<TArgs extends CoreInvocationArgs> extends Invocation<TArgs> {
13
+ get uri(): JMAPCapability;
14
+ /**
15
+ * Constructs a CoreInvocation
16
+ *
17
+ * @param method The name of the method being invoked (e.g., "echo")
18
+ * @param args The arguments for the method invocation
19
+ * @param methodCallId An optional unique symbol to identify this method call for result referencing
20
+ */
21
+ constructor(method: JMAPMethodName, args: InvocationArgs<TArgs>, methodCallId?: symbol);
22
+ /**
23
+ * Create an invocation factory function
24
+ *
25
+ * @param method The name of the method to create
26
+ * @returns A new Core invocation factory function for creating invocations of the specified type
27
+ */
28
+ static createInvocationFactory<TArgs extends CoreInvocationArgs>(method: JMAPMethodName): InvocationFactory<TArgs, CoreInvocation<TArgs>>;
29
+ }
30
+ export declare const Core: {
31
+ request: {
32
+ /**
33
+ * The Core/echo method returns exactly the same arguments as it is given. It is useful for
34
+ * testing if you have a valid authenticated connection to a JMAP API endpoint.
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
+ * @see {@link https://www.rfc-editor.org/rfc/rfc8620.html#section-4 | RFC 8620 Section 4: The Core/echo Method}
41
+ */
42
+ echo: InvocationFactory<import("../../invocation/types.js").BaseInvocationArgs, CoreInvocation<import("../../invocation/types.js").BaseInvocationArgs>>;
43
+ };
44
+ response: {
45
+ echo: InvocationFactory<import("../../invocation/types.js").BaseInvocationArgs, CoreInvocation<import("../../invocation/types.js").BaseInvocationArgs>>;
46
+ };
47
+ };
@@ -0,0 +1,59 @@
1
+ import { CORE_CAPABILITY_URI } from "../../common/registry.js";
2
+ import { Invocation } from "../../invocation/invocation.js";
3
+ /**
4
+ * CoreInvocation represents a JMAP Core capability invocation.
5
+ *
6
+ * The Core data type only exposes the `/echo` method and must be supported by all JMAP servers.
7
+ *
8
+ * @see {@link https://www.rfc-editor.org/rfc/rfc8620.html#section-4 | RFC 8620 Section 4: The Core/echo Method}
9
+ */
10
+ export class CoreInvocation extends Invocation {
11
+ get uri() {
12
+ return CORE_CAPABILITY_URI;
13
+ }
14
+ /**
15
+ * Constructs a CoreInvocation
16
+ *
17
+ * @param method The name of the method being invoked (e.g., "echo")
18
+ * @param args The arguments for the method invocation
19
+ * @param methodCallId An optional unique symbol to identify this method call for result referencing
20
+ */
21
+ constructor(method, args, methodCallId) {
22
+ super("Core", method, args, methodCallId);
23
+ }
24
+ /**
25
+ * Create an invocation factory function
26
+ *
27
+ * @param method The name of the method to create
28
+ * @returns A new Core invocation factory function for creating invocations of the specified type
29
+ */
30
+ static createInvocationFactory(method) {
31
+ /**
32
+ * An invocation factory function to create a `Core/*` invocation for the specified `method`
33
+ *
34
+ * @param args The invocation arguments for the specified `method`
35
+ * @param methodCallId An optional unique symbol to identify this method call for result referencing
36
+ * @returns An object representing the named arguments for the specified `method`
37
+ */
38
+ return (args, methodCallId) => new CoreInvocation(method, args, methodCallId);
39
+ }
40
+ }
41
+ export const Core = {
42
+ request: {
43
+ /**
44
+ * The Core/echo method returns exactly the same arguments as it is given. It is useful for
45
+ * testing if you have a valid authenticated connection to a JMAP API endpoint.
46
+ *
47
+ * @param args The invocation arguments for the specified `method`
48
+ * @param methodCallId An optional unique symbol to identify this method call for result referencing
49
+ * @returns An object representing the named arguments for the specified `method`
50
+ *
51
+ * @see {@link https://www.rfc-editor.org/rfc/rfc8620.html#section-4 | RFC 8620 Section 4: The Core/echo Method}
52
+ */
53
+ echo: CoreInvocation.createInvocationFactory("echo"),
54
+ },
55
+ response: {
56
+ echo: CoreInvocation.createInvocationFactory("echo"),
57
+ },
58
+ };
59
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../../../src/capabilities/core/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAI5D;;;;;;GAMG;AACH,MAAM,OAAO,cAAiD,SAAQ,UAAiB;IACnF,IAAI,GAAG;QACH,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAED;;;;;;OAMG;IACH,YAAY,MAAsB,EAAE,IAA2B,EAAE,YAAqB;QAClF,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,uBAAuB,CAC1B,MAAsB;QAEtB;;;;;;WAMG;QACH,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC,IAAI,cAAc,CAAQ,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IACzF,CAAC;CACJ;AAED,MAAM,CAAC,MAAM,IAAI,GAAG;IAChB,OAAO,EAAE;QACL;;;;;;;;;WASG;QACH,IAAI,EAAE,cAAc,CAAC,uBAAuB,CAAgC,MAAM,CAAC;KACtF;IACD,QAAQ,EAAE;QACN,IAAI,EAAE,cAAc,CAAC,uBAAuB,CAAiC,MAAM,CAAC;KACvF;CACkC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { BaseInvocationArgs } from "../../invocation/types.js";
2
+ /**
3
+ * The arguments for a Core/echo request invocation
4
+ */
5
+ export type CoreEchoRequestInvocationArgs = BaseInvocationArgs;
6
+ /**
7
+ * The response arguments for a Core/echo response invocation
8
+ */
9
+ export type CoreEchoResponseInvocationArgs = BaseInvocationArgs;
10
+ /**
11
+ * Union type of all Core capability invocation arguments (request and response)
12
+ */
13
+ export type CoreInvocationArgs = BaseInvocationArgs;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/capabilities/core/types.ts"],"names":[],"mappings":""}