@dxos/plugin-jmap 0.10.0
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 +105 -0
- package/dist/lib/JmapPlugin.mjs +16 -0
- package/dist/lib/JmapPlugin.mjs.map +1 -0
- package/dist/lib/apis.mjs +2 -0
- package/dist/lib/capabilities.mjs +17 -0
- package/dist/lib/capabilities.mjs.map +1 -0
- package/dist/lib/chunk-apis.mjs +756 -0
- package/dist/lib/chunk-apis.mjs.map +1 -0
- package/dist/lib/chunk-connector.mjs +111 -0
- package/dist/lib/chunk-connector.mjs.map +1 -0
- package/dist/lib/chunk-constants.mjs +23 -0
- package/dist/lib/chunk-constants.mjs.map +1 -0
- package/dist/lib/chunk-errors.mjs +42 -0
- package/dist/lib/chunk-errors.mjs.map +1 -0
- package/dist/lib/chunk-handler.mjs +27 -0
- package/dist/lib/chunk-handler.mjs.map +1 -0
- package/dist/lib/chunk-jmap-fixtures.mjs +102 -0
- package/dist/lib/chunk-jmap-fixtures.mjs.map +1 -0
- package/dist/lib/chunk-mail-send.mjs +17 -0
- package/dist/lib/chunk-mail-send.mjs.map +1 -0
- package/dist/lib/chunk-meta.mjs +37 -0
- package/dist/lib/chunk-meta.mjs.map +1 -0
- package/dist/lib/chunk-operation-handler.mjs +12 -0
- package/dist/lib/chunk-operation-handler.mjs.map +1 -0
- package/dist/lib/chunk-send.mjs +98 -0
- package/dist/lib/chunk-send.mjs.map +1 -0
- package/dist/lib/chunk-sync-provider.mjs +511 -0
- package/dist/lib/chunk-sync-provider.mjs.map +1 -0
- package/dist/lib/chunk-sync.mjs +37 -0
- package/dist/lib/chunk-sync.mjs.map +1 -0
- package/dist/lib/index.mjs +4 -0
- package/dist/lib/meta.mjs +2 -0
- package/dist/lib/operations.mjs +13 -0
- package/dist/lib/operations.mjs.map +1 -0
- package/dist/lib/plugin.mjs +9 -0
- package/dist/lib/plugin.mjs.map +1 -0
- package/dist/lib/services.mjs +139 -0
- package/dist/lib/services.mjs.map +1 -0
- package/dist/lib/testing/node.mjs +2 -0
- package/dist/lib/testing.mjs +19 -0
- package/dist/lib/testing.mjs.map +1 -0
- package/dist/lib/translations.mjs +7 -0
- package/dist/lib/translations.mjs.map +1 -0
- package/dist/types/dx.config.d.ts +28 -0
- package/dist/types/dx.config.d.ts.map +1 -0
- package/dist/types/src/JmapPlugin.d.ts +9 -0
- package/dist/types/src/JmapPlugin.d.ts.map +1 -0
- package/dist/types/src/apis/Jmap/api.d.ts +42 -0
- package/dist/types/src/apis/Jmap/api.d.ts.map +1 -0
- package/dist/types/src/apis/Jmap/index.d.ts +3 -0
- package/dist/types/src/apis/Jmap/index.d.ts.map +1 -0
- package/dist/types/src/apis/Jmap/types.d.ts +65 -0
- package/dist/types/src/apis/Jmap/types.d.ts.map +1 -0
- package/dist/types/src/apis/JmapMail/api.d.ts +223 -0
- package/dist/types/src/apis/JmapMail/api.d.ts.map +1 -0
- package/dist/types/src/apis/JmapMail/index.d.ts +4 -0
- package/dist/types/src/apis/JmapMail/index.d.ts.map +1 -0
- package/dist/types/src/apis/JmapMail/query.d.ts +26 -0
- package/dist/types/src/apis/JmapMail/query.d.ts.map +1 -0
- package/dist/types/src/apis/JmapMail/query.test.d.ts +2 -0
- package/dist/types/src/apis/JmapMail/query.test.d.ts.map +1 -0
- package/dist/types/src/apis/JmapMail/types.d.ts +290 -0
- package/dist/types/src/apis/JmapMail/types.d.ts.map +1 -0
- package/dist/types/src/apis/index.d.ts +3 -0
- package/dist/types/src/apis/index.d.ts.map +1 -0
- package/dist/types/src/apis/jmap-api.test.d.ts +2 -0
- package/dist/types/src/apis/jmap-api.test.d.ts.map +1 -0
- package/dist/types/src/capabilities/connector.d.ts +5 -0
- package/dist/types/src/capabilities/connector.d.ts.map +1 -0
- package/dist/types/src/capabilities/credential-form.d.ts +37 -0
- package/dist/types/src/capabilities/credential-form.d.ts.map +1 -0
- package/dist/types/src/capabilities/credential-form.test.d.ts +2 -0
- package/dist/types/src/capabilities/credential-form.test.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +5 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/mail-send.d.ts +6 -0
- package/dist/types/src/capabilities/mail-send.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-handler.d.ts +5 -0
- package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
- package/dist/types/src/constants.d.ts +19 -0
- package/dist/types/src/constants.d.ts.map +1 -0
- package/dist/types/src/errors.d.ts +103 -0
- package/dist/types/src/errors.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +4 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +33 -0
- package/dist/types/src/meta.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts +3 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/src/operations/mail/mapper.d.ts +49 -0
- package/dist/types/src/operations/mail/mapper.d.ts.map +1 -0
- package/dist/types/src/operations/mail/materialize/handler.d.ts +11 -0
- package/dist/types/src/operations/mail/materialize/handler.d.ts.map +1 -0
- package/dist/types/src/operations/mail/send/handler.d.ts +4 -0
- package/dist/types/src/operations/mail/send/handler.d.ts.map +1 -0
- package/dist/types/src/operations/mail/send/index.d.ts +2 -0
- package/dist/types/src/operations/mail/send/index.d.ts.map +1 -0
- package/dist/types/src/operations/mail/sync/handler.d.ts +4 -0
- package/dist/types/src/operations/mail/sync/handler.d.ts.map +1 -0
- package/dist/types/src/operations/mail/sync/index.d.ts +3 -0
- package/dist/types/src/operations/mail/sync/index.d.ts.map +1 -0
- package/dist/types/src/operations/mail/sync/mapper.test.d.ts +2 -0
- package/dist/types/src/operations/mail/sync/mapper.test.d.ts.map +1 -0
- package/dist/types/src/operations/mail/sync/sync-e2e.test.d.ts +2 -0
- package/dist/types/src/operations/mail/sync/sync-e2e.test.d.ts.map +1 -0
- package/dist/types/src/operations/mail/sync/sync-provider.d.ts +11 -0
- package/dist/types/src/operations/mail/sync/sync-provider.d.ts.map +1 -0
- package/dist/types/src/operations/mail/sync/sync.test.d.ts +2 -0
- package/dist/types/src/operations/mail/sync/sync.test.d.ts.map +1 -0
- package/dist/types/src/operations/mail/sync/system-tags.d.ts +14 -0
- package/dist/types/src/operations/mail/sync/system-tags.d.ts.map +1 -0
- package/dist/types/src/operations/mail/tags.d.ts +12 -0
- package/dist/types/src/operations/mail/tags.d.ts.map +1 -0
- package/dist/types/src/plugin.d.ts +4 -0
- package/dist/types/src/plugin.d.ts.map +1 -0
- package/dist/types/src/services/index.d.ts +3 -0
- package/dist/types/src/services/index.d.ts.map +1 -0
- package/dist/types/src/services/jmap-credentials.d.ts +39 -0
- package/dist/types/src/services/jmap-credentials.d.ts.map +1 -0
- package/dist/types/src/services/jmap-mail-api.d.ts +109 -0
- package/dist/types/src/services/jmap-mail-api.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +5 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/jmap-fixtures.d.ts +26 -0
- package/dist/types/src/testing/jmap-fixtures.d.ts.map +1 -0
- package/dist/types/src/testing/jmap-fixtures.test.d.ts +2 -0
- package/dist/types/src/testing/jmap-fixtures.test.d.ts.map +1 -0
- package/dist/types/src/testing/node.d.ts +4 -0
- package/dist/types/src/testing/node.d.ts.map +1 -0
- package/dist/types/src/testing/sync-fixture.d.ts +22 -0
- package/dist/types/src/testing/sync-fixture.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +8 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/dx.config.ts +32 -0
- package/package.json +121 -0
- package/src/JmapPlugin.ts +25 -0
- package/src/apis/Jmap/api.ts +138 -0
- package/src/apis/Jmap/index.ts +6 -0
- package/src/apis/Jmap/types.ts +86 -0
- package/src/apis/JmapMail/api.ts +324 -0
- package/src/apis/JmapMail/index.ts +7 -0
- package/src/apis/JmapMail/query.test.ts +181 -0
- package/src/apis/JmapMail/query.ts +231 -0
- package/src/apis/JmapMail/types.ts +196 -0
- package/src/apis/index.ts +8 -0
- package/src/apis/jmap-api.test.ts +261 -0
- package/src/capabilities/connector.ts +44 -0
- package/src/capabilities/credential-form.test.ts +69 -0
- package/src/capabilities/credential-form.ts +113 -0
- package/src/capabilities/index.ts +24 -0
- package/src/capabilities/mail-send.ts +21 -0
- package/src/capabilities/operation-handler.ts +16 -0
- package/src/constants.ts +24 -0
- package/src/errors.ts +38 -0
- package/src/index.ts +7 -0
- package/src/meta.ts +9 -0
- package/src/operations/index.ts +13 -0
- package/src/operations/mail/mapper.ts +191 -0
- package/src/operations/mail/materialize/handler.ts +41 -0
- package/src/operations/mail/send/handler.ts +116 -0
- package/src/operations/mail/send/index.ts +5 -0
- package/src/operations/mail/sync/handler.ts +52 -0
- package/src/operations/mail/sync/index.ts +7 -0
- package/src/operations/mail/sync/mapper.test.ts +150 -0
- package/src/operations/mail/sync/sync-e2e.test.ts +63 -0
- package/src/operations/mail/sync/sync-provider.ts +481 -0
- package/src/operations/mail/sync/sync.test.ts +766 -0
- package/src/operations/mail/sync/system-tags.ts +24 -0
- package/src/operations/mail/tags.ts +29 -0
- package/src/plugin.ts +11 -0
- package/src/services/index.ts +6 -0
- package/src/services/jmap-credentials.ts +61 -0
- package/src/services/jmap-mail-api.ts +294 -0
- package/src/testing/index.ts +8 -0
- package/src/testing/jmap-fixtures.test.ts +107 -0
- package/src/testing/jmap-fixtures.ts +105 -0
- package/src/testing/node.ts +12 -0
- package/src/testing/sync-fixture.ts +39 -0
- package/src/translations.ts +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-form.test.d.ts","sourceRoot":"","sources":["../../../../src/capabilities/credential-form.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as Capability from '@dxos/app-framework/Capability';
|
|
2
|
+
export declare const Connector: Capability.Module<void>;
|
|
3
|
+
export declare const MailSend: Capability.Module<void>;
|
|
4
|
+
export declare const OperationHandler: Capability.Module<void>;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/capabilities/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAM7D,eAAO,MAAM,SAAS,yBAIrB,CAAC;AACF,eAAO,MAAM,QAAQ,yBAIpB,CAAC;AACF,eAAO,MAAM,gBAAgB,yBAE3B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as Effect from 'effect/Effect';
|
|
2
|
+
import * as Capability from '@dxos/app-framework/Capability';
|
|
3
|
+
/** Routes a draft whose mailbox is bound to a JMAP connection to this provider's send operation. */
|
|
4
|
+
declare const _default: (props: void) => Effect.Effect<Capability.Contribution<Capability.CapabilityIdentifier<`${string}.capability.mailSendOperation`, "multi">>, never, import("effect/Scope").Scope>;
|
|
5
|
+
export default _default;
|
|
6
|
+
//# sourceMappingURL=mail-send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mail-send.d.ts","sourceRoot":"","sources":["../../../../src/capabilities/mail-send.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC;AAM7D,oGAAoG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as Effect from 'effect/Effect';
|
|
2
|
+
import * as Capability from '@dxos/app-framework/Capability';
|
|
3
|
+
declare const _default: (props: void) => Effect.Effect<Capability.Contribution<Capability.CapabilityIdentifier<"org.dxos.app-framework.capability.operationHandler", "multi">>, never, import("effect/Scope").Scope>;
|
|
4
|
+
export default _default;
|
|
5
|
+
//# sourceMappingURL=operation-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-handler.d.ts","sourceRoot":"","sources":["../../../../src/capabilities/operation-handler.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,UAAU,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** `Connector.id` for the JMAP mail connector (RFC 8620/8621); stored as `Connection.connectorId`. */
|
|
2
|
+
export declare const JMAP_MAIL_CONNECTOR_ID = "jmap-mail";
|
|
3
|
+
/**
|
|
4
|
+
* Default JMAP server host pre-filled in the credential form. Fastmail is the canonical JMAP
|
|
5
|
+
* provider; the session is discovered at `https://${host}/.well-known/jmap`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const JMAP_DEFAULT_HOST = "api.fastmail.com";
|
|
8
|
+
/**
|
|
9
|
+
* The provider's origin domain, used as the foreign-key `Meta.keys[].source` on everything this plugin
|
|
10
|
+
* syncs — messages (the dedup key; see the mapper) and folder {@link Tag}s alike. One string for both
|
|
11
|
+
* is deliberate: a foreign key is scoped by the object it sits on, so the type already distinguishes a
|
|
12
|
+
* message key from a tag key, and `Tag.getOrigin` reads it to mark synced tags read-only.
|
|
13
|
+
*
|
|
14
|
+
* (Gmail is asymmetric here — its message source is the older `com.google.mail` while its tags carry
|
|
15
|
+
* `com.google.gmail`. That is left alone deliberately: renaming a persisted message key would orphan
|
|
16
|
+
* mail. See `Tag.md` §"Origin domain == key source".)
|
|
17
|
+
*/
|
|
18
|
+
export declare const JMAP_DOMAIN = "org.ietf.jmap";
|
|
19
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/constants.ts"],"names":[],"mappings":"AAIA,sGAAsG;AACtG,eAAO,MAAM,sBAAsB,cAAc,CAAC;AAElD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { BaseError, type BaseErrorOptions } from '@dxos/errors';
|
|
2
|
+
declare const JmapApiError_base: {
|
|
3
|
+
new (options?: BaseErrorOptions): {
|
|
4
|
+
cause?: unknown;
|
|
5
|
+
stack?: string;
|
|
6
|
+
name: "JmapApiError";
|
|
7
|
+
context: Record<string, unknown>;
|
|
8
|
+
readonly message: string;
|
|
9
|
+
readonly _tag: "JmapApiError";
|
|
10
|
+
};
|
|
11
|
+
isError(error: unknown): error is Error;
|
|
12
|
+
name: "JmapApiError";
|
|
13
|
+
is(error: unknown): error is BaseError;
|
|
14
|
+
wrap(options?: Omit<BaseErrorOptions, 'cause'> & {
|
|
15
|
+
ifTypeDiffers?: boolean;
|
|
16
|
+
}): (error: unknown) => {
|
|
17
|
+
cause?: unknown;
|
|
18
|
+
stack?: string;
|
|
19
|
+
name: "JmapApiError";
|
|
20
|
+
context: Record<string, unknown>;
|
|
21
|
+
readonly message: string;
|
|
22
|
+
readonly _tag: "JmapApiError";
|
|
23
|
+
};
|
|
24
|
+
extend<Name extends string = string>(name: Name, message?: string): any;
|
|
25
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
26
|
+
prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
|
|
27
|
+
stackTraceLimit: number;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* JMAP request failed: a non-2xx HTTP status, a JMAP problem-details body, or a method-level
|
|
31
|
+
* `["error", { type, description }, id]` response. `status` carries the HTTP status (when the
|
|
32
|
+
* failure is transport-level) and `type` the JMAP error type (when method-level) so callers can
|
|
33
|
+
* recover with `Effect.catchTag` and distinguish auth (401) from other failures.
|
|
34
|
+
*/
|
|
35
|
+
export declare class JmapApiError extends JmapApiError_base {
|
|
36
|
+
readonly status: number | undefined;
|
|
37
|
+
readonly detail: string;
|
|
38
|
+
readonly type?: string | undefined;
|
|
39
|
+
constructor(status: number | undefined, detail: string, type?: string | undefined, options?: BaseErrorOptions);
|
|
40
|
+
}
|
|
41
|
+
declare const JmapSendMessageInvalidError_base: {
|
|
42
|
+
new (options?: BaseErrorOptions): {
|
|
43
|
+
cause?: unknown;
|
|
44
|
+
stack?: string;
|
|
45
|
+
name: "JmapSendMessageInvalidError";
|
|
46
|
+
context: Record<string, unknown>;
|
|
47
|
+
readonly message: string;
|
|
48
|
+
readonly _tag: "JmapSendMessageInvalidError";
|
|
49
|
+
};
|
|
50
|
+
isError(error: unknown): error is Error;
|
|
51
|
+
name: "JmapSendMessageInvalidError";
|
|
52
|
+
is(error: unknown): error is BaseError;
|
|
53
|
+
wrap(options?: Omit<BaseErrorOptions, 'cause'> & {
|
|
54
|
+
ifTypeDiffers?: boolean;
|
|
55
|
+
}): (error: unknown) => {
|
|
56
|
+
cause?: unknown;
|
|
57
|
+
stack?: string;
|
|
58
|
+
name: "JmapSendMessageInvalidError";
|
|
59
|
+
context: Record<string, unknown>;
|
|
60
|
+
readonly message: string;
|
|
61
|
+
readonly _tag: "JmapSendMessageInvalidError";
|
|
62
|
+
};
|
|
63
|
+
extend<Name extends string = string>(name: Name, message?: string): any;
|
|
64
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
65
|
+
prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
|
|
66
|
+
stackTraceLimit: number;
|
|
67
|
+
};
|
|
68
|
+
/** JMAP send payload missing required fields (`to` or body text). */
|
|
69
|
+
export declare class JmapSendMessageInvalidError extends JmapSendMessageInvalidError_base {
|
|
70
|
+
}
|
|
71
|
+
declare const JmapSendIdentityNotFoundError_base: {
|
|
72
|
+
new (options?: BaseErrorOptions): {
|
|
73
|
+
cause?: unknown;
|
|
74
|
+
stack?: string;
|
|
75
|
+
name: "JmapSendIdentityNotFoundError";
|
|
76
|
+
context: Record<string, unknown>;
|
|
77
|
+
readonly message: string;
|
|
78
|
+
readonly _tag: "JmapSendIdentityNotFoundError";
|
|
79
|
+
};
|
|
80
|
+
isError(error: unknown): error is Error;
|
|
81
|
+
name: "JmapSendIdentityNotFoundError";
|
|
82
|
+
is(error: unknown): error is BaseError;
|
|
83
|
+
wrap(options?: Omit<BaseErrorOptions, 'cause'> & {
|
|
84
|
+
ifTypeDiffers?: boolean;
|
|
85
|
+
}): (error: unknown) => {
|
|
86
|
+
cause?: unknown;
|
|
87
|
+
stack?: string;
|
|
88
|
+
name: "JmapSendIdentityNotFoundError";
|
|
89
|
+
context: Record<string, unknown>;
|
|
90
|
+
readonly message: string;
|
|
91
|
+
readonly _tag: "JmapSendIdentityNotFoundError";
|
|
92
|
+
};
|
|
93
|
+
extend<Name extends string = string>(name: Name, message?: string): any;
|
|
94
|
+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
|
|
95
|
+
prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
|
|
96
|
+
stackTraceLimit: number;
|
|
97
|
+
};
|
|
98
|
+
/** No JMAP identity permits the connection account as a `from` address, so the email cannot be sent. */
|
|
99
|
+
export declare class JmapSendIdentityNotFoundError extends JmapSendIdentityNotFoundError_base {
|
|
100
|
+
constructor(account: string | undefined, options?: Omit<BaseErrorOptions, 'context'>);
|
|
101
|
+
}
|
|
102
|
+
export {};
|
|
103
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/errors.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEhE;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,iBAA4D;aAE1E,MAAM,EAAE,MAAM,GAAG,SAAS;aAC1B,MAAM,EAAE,MAAM;aACd,IAAI,CAAC,EAAE,MAAM;IAH/B,YACkB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,YAAA,EAC7B,OAAO,CAAC,EAAE,gBAAgB,EAG3B;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAED,qEAAqE;AACrE,qBAAa,2BAA4B,SAAQ,gCAGhD;CAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEJ,wGAAwG;AACxG,qBAAa,6BAA8B,SAAQ,kCAGlD;IACC,YAAY,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,CAAC,EAEnF;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const meta: {
|
|
2
|
+
readonly profile: {
|
|
3
|
+
readonly key: string;
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly description?: string | undefined;
|
|
6
|
+
readonly homePage?: string | undefined;
|
|
7
|
+
readonly source?: string | undefined;
|
|
8
|
+
readonly tags?: readonly string[] | undefined;
|
|
9
|
+
readonly screenshots?: readonly {
|
|
10
|
+
readonly light?: string | undefined;
|
|
11
|
+
readonly dark?: string | undefined;
|
|
12
|
+
}[] | undefined;
|
|
13
|
+
readonly icon?: {
|
|
14
|
+
readonly key: string;
|
|
15
|
+
readonly hue?: string | undefined;
|
|
16
|
+
} | undefined;
|
|
17
|
+
readonly dependsOn?: readonly string[] | undefined;
|
|
18
|
+
readonly spec?: string | undefined;
|
|
19
|
+
readonly createdAt?: string | undefined;
|
|
20
|
+
readonly author?: string | undefined;
|
|
21
|
+
};
|
|
22
|
+
readonly release?: {
|
|
23
|
+
readonly version: string;
|
|
24
|
+
readonly moduleUrl: string;
|
|
25
|
+
readonly dependencies?: {
|
|
26
|
+
readonly [x: string]: string;
|
|
27
|
+
} | undefined;
|
|
28
|
+
readonly pluginKey?: string | undefined;
|
|
29
|
+
readonly manifestHash?: string | undefined;
|
|
30
|
+
readonly createdAt?: string | undefined;
|
|
31
|
+
} | undefined;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=meta.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/meta.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAmC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/operations/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,mBAAmB,MAAM,mCAAmC,CAAC;AAGzE,eAAO,MAAM,uBAAuB,yCAIlC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as Effect from 'effect/Effect';
|
|
2
|
+
import { type Resolver } from '@dxos/extractor';
|
|
3
|
+
import { Message, Person } from '@dxos/types';
|
|
4
|
+
import { JmapMail } from '../../apis';
|
|
5
|
+
/**
|
|
6
|
+
* Result of mapping a JMAP email. `mailboxIds` (the folders the email is in) and `keywords` (the set
|
|
7
|
+
* flags, e.g. `$flagged`) are propagated separately so the caller can apply the corresponding tags to
|
|
8
|
+
* the immutable feed Message — mirrors the Gmail mapper's `labelIds`. Both axes are needed because JMAP
|
|
9
|
+
* splits folder membership (`mailboxIds`) from flags (`keywords`), unlike Gmail's single label list.
|
|
10
|
+
*/
|
|
11
|
+
export type MappedEmail = {
|
|
12
|
+
message: Message.Message;
|
|
13
|
+
mailboxIds: readonly string[];
|
|
14
|
+
keywords: readonly string[];
|
|
15
|
+
};
|
|
16
|
+
/** A JMAP email with its raw HTML and/or plaintext body (JMAP delivers decoded values; no markdown). */
|
|
17
|
+
export type DecodedEmail = {
|
|
18
|
+
raw: JmapMail.Email;
|
|
19
|
+
html?: string;
|
|
20
|
+
plain?: string;
|
|
21
|
+
attachments: readonly AttachmentMetadata[];
|
|
22
|
+
};
|
|
23
|
+
/** Metadata for an attachment part (`Email.attachments`, distinct from the `textBody`/`htmlBody` parts). */
|
|
24
|
+
export type AttachmentMetadata = {
|
|
25
|
+
readonly blobId: string;
|
|
26
|
+
readonly name?: string;
|
|
27
|
+
readonly mimeType?: string;
|
|
28
|
+
readonly size?: number;
|
|
29
|
+
/** The part's `Content-ID` (angle brackets stripped, if present), if any — matches a `cid:` reference in an HTML body. */
|
|
30
|
+
readonly contentId?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Extracts the raw HTML and plaintext bodies from a JMAP email (values fetched via
|
|
34
|
+
* `fetchHTMLBodyValues`/`fetchTextBodyValues`). Returns `null` when the email has neither. No
|
|
35
|
+
* HTML→markdown conversion — the markdown/plain views derive from these raw blocks in the component.
|
|
36
|
+
*/
|
|
37
|
+
export declare const decodeBody: (email: JmapMail.Email) => DecodedEmail | null;
|
|
38
|
+
/**
|
|
39
|
+
* Builds an ECHO Message from a decoded (already body-normalized) JMAP email and an optional resolved
|
|
40
|
+
* sender contact. Pure — contact resolution is done by the caller. Returns `null` when the email has
|
|
41
|
+
* no sender.
|
|
42
|
+
*/
|
|
43
|
+
export declare const mapToMessage: (decoded: DecodedEmail, contact: Person.Person | undefined) => MappedEmail | null;
|
|
44
|
+
/**
|
|
45
|
+
* Maps a JMAP email to an ECHO Message, resolving the sender against existing contacts. Composes
|
|
46
|
+
* {@link decodeBody} → {@link mapToMessage}. Returns `null` when the email has no body or no sender.
|
|
47
|
+
*/
|
|
48
|
+
export declare const mapEmail: (email: JmapMail.Email) => Effect.Effect<MappedEmail | null, never, Resolver>;
|
|
49
|
+
//# sourceMappingURL=mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../../../../src/operations/mail/mapper.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,EAAE,KAAK,QAAQ,EAAW,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAgB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtC;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IACzB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC;AAEF,wGAAwG;AACxG,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAC;CAC5C,CAAC;AAEF,4GAA4G;AAC5G,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,0HAA0H;IAC1H,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAoBF;;;;GAIG;AACH,eAAO,MAAM,UAAU,UAAW,QAAQ,CAAC,KAAK,KAAG,YAAY,GAAG,IAajE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,YAAa,YAAY,WAAW,MAAM,CAAC,MAAM,GAAG,SAAS,KAAG,WAAW,GAAG,IA8DtG,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,EAAE,KAAK,EAAE,QAAQ,CAS/F,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as Operation from '@dxos/compute/Operation';
|
|
2
|
+
import * as InboxOperation from '@dxos/plugin-inbox/InboxOperation';
|
|
3
|
+
/**
|
|
4
|
+
* Eagerly materializes a local Mailbox so the sync cursor's target exists before the cursor is
|
|
5
|
+
* created. JMAP is a single-target connector (the account inbox), so a fresh Mailbox is always
|
|
6
|
+
* created; the connection's `accessToken.account` seeds the default name. Mirrors the Gmail
|
|
7
|
+
* materialize-target.
|
|
8
|
+
*/
|
|
9
|
+
declare const handler: Operation.WithHandler<typeof InboxOperation.MaterializeJmapTarget>;
|
|
10
|
+
export default handler;
|
|
11
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/materialize/handler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,SAAS,MAAM,yBAAyB,CAAC;AAErD,OAAO,KAAK,cAAc,MAAM,mCAAmC,CAAC;AAGpE;;;;;GAKG;AACH,QAAA,MAAM,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,OAAO,cAAc,CAAC,qBAAqB,CAoB7E,CAAC;eAEW,OAAO"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/send/handler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,SAAS,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/send/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/sync/handler.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,SAAS,MAAM,yBAAyB,CAAC;AAWrD,QAAA,MAAM,OAAO,iDA8BZ,CAAC;eAEa,OAAO"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/sync/index.ts"],"names":[],"mappings":"AAIA,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapper.test.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/sync/mapper.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-e2e.test.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/sync/sync-e2e.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as Layer from 'effect/Layer';
|
|
2
|
+
import { type Resolver } from '@dxos/extractor';
|
|
3
|
+
import { MailSyncProvider } from '@dxos/plugin-inbox/sync';
|
|
4
|
+
import { JmapMailApi } from '../../../services';
|
|
5
|
+
/**
|
|
6
|
+
* JMAP's {@link MailSyncProvider}: session/account discovery, the email source, the folder→tag map, and
|
|
7
|
+
* the fused decode+map. Captures {@link JmapMailApi} + {@link Resolver} so the harness never names them.
|
|
8
|
+
* Mirror of the Gmail provider (`googleMailSyncProvider`).
|
|
9
|
+
*/
|
|
10
|
+
export declare const jmapMailSyncProvider: () => Layer.Layer<MailSyncProvider, never, JmapMailApi | Resolver>;
|
|
11
|
+
//# sourceMappingURL=sync-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-provider.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/sync/sync-provider.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAKtC,OAAO,EAAE,KAAK,QAAQ,EAAW,MAAM,iBAAiB,CAAC;AAMzD,OAAO,EAAoC,gBAAgB,EAAuB,MAAM,yBAAyB,CAAC;AASlH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAuBhD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,QAAO,KAAK,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,EAAE,WAAW,GAAG,QAAQ,CA4LhG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.test.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/sync/sync.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type * as SystemTags from '@dxos/plugin-inbox/SystemTags';
|
|
2
|
+
/**
|
|
3
|
+
* JMAP mailbox role → canonical system tag ({@link SystemTags.SystemTag}). Roles absent here are
|
|
4
|
+
* intentionally dropped: `archive` is derived as "not in inbox" (Gmail's model), and
|
|
5
|
+
* `drafts`/`trash`/`junk` are never synced.
|
|
6
|
+
*/
|
|
7
|
+
export declare const JMAP_ROLE_TAGS: Partial<Record<string, SystemTags.SystemTagId>>;
|
|
8
|
+
/**
|
|
9
|
+
* JMAP keyword → canonical system tag ({@link SystemTags.SystemTag}). Only `$flagged` (starred) is
|
|
10
|
+
* projected; read-state (`$seen`) and the rest (`$answered`, `$draft`, `$forwarded`, …) are intentionally
|
|
11
|
+
* dropped as high-churn and noisier than useful.
|
|
12
|
+
*/
|
|
13
|
+
export declare const JMAP_KEYWORD_TAGS: Partial<Record<string, SystemTags.SystemTagId>>;
|
|
14
|
+
//# sourceMappingURL=system-tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-tags.d.ts","sourceRoot":"","sources":["../../../../../../src/operations/mail/sync/system-tags.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,UAAU,MAAM,+BAA+B,CAAC;AAEjE;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,CAG1E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,CAE7E,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Database, Tag } from '@dxos/echo';
|
|
2
|
+
/**
|
|
3
|
+
* Finds an existing JMAP provider {@link Tag} object by its JMAP mailbox-id foreign key, or creates one
|
|
4
|
+
* carrying that key ({@link JMAP_DOMAIN}, which also marks it read-only via `Tag.isProviderTag`). Keeps
|
|
5
|
+
* the folder label in sync with the server on re-sync. Used by `sync/` for custom user folders;
|
|
6
|
+
* well-known roles map onto canonical system tags instead. Mirrors Gmail's `findOrCreateGmailTag`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const findOrCreateJmapTag: (db: Database.Database, { id, name }: {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
}) => Promise<Tag.Tag>;
|
|
12
|
+
//# sourceMappingURL=tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../../../../src/operations/mail/tags.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,QAAQ,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAUhD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,OAC1B,QAAQ,CAAC,QAAQ,gBACP;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,KACzC,OAAO,CAAC,GAAG,CAAC,GAAG,CAKd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AAIrD,eAAO,MAAM,UAAU,4BAA6C,CAAC;AAErE,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/index.ts"],"names":[],"mappings":"AAIA,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as Context from 'effect/Context';
|
|
2
|
+
import * as Layer from 'effect/Layer';
|
|
3
|
+
import { type Ref } from '@dxos/echo';
|
|
4
|
+
import { type AccessToken } from '@dxos/link';
|
|
5
|
+
import * as Connection from '@dxos/plugin-connector/Connection';
|
|
6
|
+
/**
|
|
7
|
+
* Credentials needed to talk to a JMAP server: the server `host` (used to discover the session at
|
|
8
|
+
* `https://${host}/.well-known/jmap`), the optional `account` (email/username for display and
|
|
9
|
+
* identity matching), and the Bearer `token`.
|
|
10
|
+
*/
|
|
11
|
+
export type Credentials = {
|
|
12
|
+
readonly host: string;
|
|
13
|
+
readonly account: string | undefined;
|
|
14
|
+
readonly token: string;
|
|
15
|
+
};
|
|
16
|
+
declare const JmapCredentials_base: Context.TagClass<JmapCredentials, "JmapCredentials", Credentials>;
|
|
17
|
+
/**
|
|
18
|
+
* Service for accessing JMAP credentials.
|
|
19
|
+
*
|
|
20
|
+
* Mirrors `GoogleCredentials`: an operation invoked with a `Connection` composes
|
|
21
|
+
* `fromConnection(ref)`; one invoked with an external-sync cursor composes
|
|
22
|
+
* `fromAccessToken(cursor.spec.source)` directly (the cursor no longer relates to `Connection`).
|
|
23
|
+
* Unlike Google, there is no database-credential fallback — a JMAP connection always carries host +
|
|
24
|
+
* token in its token record.
|
|
25
|
+
*/
|
|
26
|
+
export declare class JmapCredentials extends JmapCredentials_base {
|
|
27
|
+
/** Creates a credentials layer from an AccessToken ref. Loads its `source` (host), `account`, `token`. */
|
|
28
|
+
static fromAccessToken: (accessTokenRef: Ref.Ref<AccessToken.AccessToken>) => Layer.Layer<JmapCredentials, import("@dxos/echo/Err").EntityNotFoundError, never>;
|
|
29
|
+
/** Creates a credentials layer from a Connection ref. Loads its `accessToken`'s host/account/token. */
|
|
30
|
+
static fromConnection: (connectionRef: Ref.Ref<Connection.Connection>) => Layer.Layer<JmapCredentials, import("@dxos/echo/Err").EntityNotFoundError, never>;
|
|
31
|
+
/** Creates a credentials layer from explicit values (credential-form validation and tests). */
|
|
32
|
+
static fromValues: (values: {
|
|
33
|
+
host: string;
|
|
34
|
+
account?: string;
|
|
35
|
+
token: string;
|
|
36
|
+
}) => Layer.Layer<JmapCredentials, never, never>;
|
|
37
|
+
}
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=jmap-credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jmap-credentials.d.ts","sourceRoot":"","sources":["../../../../src/services/jmap-credentials.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAE1C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAY,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,KAAK,UAAU,MAAM,mCAAmC,CAAC;AAEhE;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,CAAC;;AAEF;;;;;;;;GAQG;AACH,qBAAa,eAAgB,SAAQ,oBAA8D;IACjG,0GAA0G;IAC1G,MAAM,CAAC,eAAe,mBAAoB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,uFAQtE;IAEJ,uGAAuG;IACvG,MAAM,CAAC,cAAc,kBAAmB,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,uFASlE;IAEJ,+FAA+F;IAC/F,MAAM,CAAC,UAAU,WAAY;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,gDACwB;CACvG"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type * as HttpClient from '@effect/platform/HttpClient';
|
|
2
|
+
import * as Context from 'effect/Context';
|
|
3
|
+
import * as Effect from 'effect/Effect';
|
|
4
|
+
import * as Layer from 'effect/Layer';
|
|
5
|
+
import { Jmap, JmapMail } from '../apis';
|
|
6
|
+
import { JmapApiError } from '../errors';
|
|
7
|
+
import { type JmapCredentials } from './jmap-credentials';
|
|
8
|
+
/**
|
|
9
|
+
* The requirements the underlying {@link Jmap}/{@link JmapMail} request functions carry (HTTP client
|
|
10
|
+
* + JMAP credentials). {@link JmapMailApi.Live} bakes these in so the service methods themselves
|
|
11
|
+
* require nothing — which is what lets a test satisfy {@link JmapMailApi} with a zero-dependency mock
|
|
12
|
+
* (no HTTP, no credentials, no live server).
|
|
13
|
+
*/
|
|
14
|
+
type Requirements = HttpClient.HttpClient | JmapCredentials;
|
|
15
|
+
/**
|
|
16
|
+
* Swappable JMAP API surface. `Live` delegates to the real {@link Jmap}/{@link JmapMail} request
|
|
17
|
+
* functions; tests provide a data-backed mock. Making the JMAP dependency a service (rather than the
|
|
18
|
+
* sync operation calling `Jmap.*`/`JmapMail.*` and hardcoding `FetchHttpClient.layer` internally) is
|
|
19
|
+
* what lets the sync run against generated data with no live account — mirrors `GoogleMailApi`.
|
|
20
|
+
* Every request fails only with {@link JmapApiError}, and methods carry no requirements: `Live`
|
|
21
|
+
* bakes them in (see {@link Requirements}) so a mock can satisfy the surface with no HTTP or creds.
|
|
22
|
+
*/
|
|
23
|
+
export interface JmapMailApiService {
|
|
24
|
+
readonly getSession: Effect.Effect<Jmap.Session, JmapApiError>;
|
|
25
|
+
readonly mailboxGet: (target: JmapMail.Target) => Effect.Effect<JmapMail.MailboxGetResult, JmapApiError>;
|
|
26
|
+
readonly emailQuery: (target: JmapMail.Target, options?: {
|
|
27
|
+
filter?: unknown;
|
|
28
|
+
sort?: readonly {
|
|
29
|
+
property: string;
|
|
30
|
+
isAscending?: boolean;
|
|
31
|
+
}[];
|
|
32
|
+
position?: number;
|
|
33
|
+
limit?: number;
|
|
34
|
+
calculateTotal?: boolean;
|
|
35
|
+
}) => Effect.Effect<JmapMail.EmailQueryResult, JmapApiError>;
|
|
36
|
+
readonly emailGet: (target: JmapMail.Target, ids: readonly string[], properties?: readonly string[]) => Effect.Effect<JmapMail.EmailGetResult, JmapApiError>;
|
|
37
|
+
readonly emailChanges: (target: JmapMail.Target, sinceState: string, maxChanges?: number) => Effect.Effect<JmapMail.EmailChangesResult, JmapApiError>;
|
|
38
|
+
readonly downloadBlob: (target: JmapMail.Target, blobId: string, options?: {
|
|
39
|
+
name?: string;
|
|
40
|
+
type?: string;
|
|
41
|
+
}) => Effect.Effect<Uint8Array, JmapApiError>;
|
|
42
|
+
readonly identityGet: (target: JmapMail.Target) => Effect.Effect<JmapMail.IdentityGetResult, JmapApiError>;
|
|
43
|
+
readonly emailSetUpdate: (target: JmapMail.Target, emailId: string, patch: Record<string, unknown>) => Effect.Effect<JmapMail.EmailSetResult, JmapApiError>;
|
|
44
|
+
readonly submitEmail: (target: JmapMail.Target, args: {
|
|
45
|
+
identityId: string;
|
|
46
|
+
draftsMailboxId: string;
|
|
47
|
+
sentMailboxId: string;
|
|
48
|
+
draft: {
|
|
49
|
+
from: readonly JmapMail.EmailAddress[];
|
|
50
|
+
to: readonly JmapMail.EmailAddress[];
|
|
51
|
+
cc?: readonly JmapMail.EmailAddress[];
|
|
52
|
+
bcc?: readonly JmapMail.EmailAddress[];
|
|
53
|
+
subject?: string;
|
|
54
|
+
inReplyTo?: readonly string[];
|
|
55
|
+
references?: readonly string[];
|
|
56
|
+
text: string;
|
|
57
|
+
};
|
|
58
|
+
}) => Effect.Effect<{
|
|
59
|
+
id: string;
|
|
60
|
+
threadId: string | undefined;
|
|
61
|
+
}, JmapApiError>;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* An in-memory JMAP dataset a {@link JmapMailApi.mock} serves — the session (account discovery), the
|
|
65
|
+
* folders (mailboxes), and the full emails the sync would fetch. Build one with `generateJmapDataset`
|
|
66
|
+
* from this plugin's `./testing`.
|
|
67
|
+
*/
|
|
68
|
+
export interface JmapDataset {
|
|
69
|
+
readonly session: Jmap.Session;
|
|
70
|
+
readonly folders: readonly JmapMail.Mailbox[];
|
|
71
|
+
/** Full emails, ordered ascending by `receivedAt` (the mock sorts/paginates a window over them). */
|
|
72
|
+
readonly emails: readonly JmapMail.Email[];
|
|
73
|
+
/** Attachment bytes keyed by `blobId`, served by `downloadBlob` for emails that carry one. */
|
|
74
|
+
readonly blobs?: Readonly<Record<string, Uint8Array>>;
|
|
75
|
+
/**
|
|
76
|
+
* Current `Email/get` state token — `emailGet` returns it and it's the newest `Email/changes` state.
|
|
77
|
+
* Set to exercise the incremental path; absent means "no delta support" (token capture returns undefined).
|
|
78
|
+
*/
|
|
79
|
+
readonly state?: string;
|
|
80
|
+
/** Ordered `Email/changes` steps chaining `sinceState` → `newState`, each carrying the delta. */
|
|
81
|
+
readonly changeLog?: readonly JmapChangeStep[];
|
|
82
|
+
}
|
|
83
|
+
/** One `Email/changes` step in a {@link JmapDataset}'s change log. */
|
|
84
|
+
export interface JmapChangeStep {
|
|
85
|
+
readonly sinceState: string;
|
|
86
|
+
readonly newState: string;
|
|
87
|
+
readonly created?: readonly string[];
|
|
88
|
+
readonly updated?: readonly string[];
|
|
89
|
+
readonly destroyed?: readonly string[];
|
|
90
|
+
}
|
|
91
|
+
declare const JmapMailApi_base: Context.TagClass<JmapMailApi, "@dxos/plugin-inbox/JmapMailApi", JmapMailApiService>;
|
|
92
|
+
export declare class JmapMailApi extends JmapMailApi_base {
|
|
93
|
+
/**
|
|
94
|
+
* Live layer backed by the real JMAP HTTP client. Captures the auth/HTTP context once and provides
|
|
95
|
+
* it to each request, so the resulting service methods carry no requirements. Requires an
|
|
96
|
+
* `HttpClient` and a `JmapCredentials` (e.g. {@link JmapCredentials.fromConnection}) to be available
|
|
97
|
+
* where it is provided.
|
|
98
|
+
*/
|
|
99
|
+
static readonly Live: Layer.Layer<JmapMailApi, never, Requirements>;
|
|
100
|
+
/**
|
|
101
|
+
* Zero-dependency mock backed by an in-memory {@link JmapDataset} — for unit tests that drive the
|
|
102
|
+
* real sync pipeline with no live account. `emailQuery` honours the query filter (`after`/`before`
|
|
103
|
+
* window + folder scope), the `receivedAt` sort, and `position`/`limit` pagination, so the sync's
|
|
104
|
+
* window walk and pagination exercise realistically. Write methods are unsupported (die).
|
|
105
|
+
*/
|
|
106
|
+
static readonly mock: (dataset: JmapDataset) => Layer.Layer<JmapMailApi>;
|
|
107
|
+
}
|
|
108
|
+
export {};
|
|
109
|
+
//# sourceMappingURL=jmap-mail-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jmap-mail-api.d.ts","sourceRoot":"","sources":["../../../../src/services/jmap-mail-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/testing/index.ts"],"names":[],"mappings":"AAIA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC"}
|