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,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 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/capabilities/core/types.ts"],"names":[],"mappings":""}
|