@contractspec/integration.providers-impls 0.0.0-canary-20260113170453

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 (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -0
  3. package/dist/_virtual/rolldown_runtime.js +36 -0
  4. package/dist/calendar.d.ts +8 -0
  5. package/dist/calendar.d.ts.map +1 -0
  6. package/dist/calendar.js +3 -0
  7. package/dist/email.d.ts +8 -0
  8. package/dist/email.d.ts.map +1 -0
  9. package/dist/email.js +3 -0
  10. package/dist/embedding.d.ts +8 -0
  11. package/dist/embedding.d.ts.map +1 -0
  12. package/dist/embedding.js +3 -0
  13. package/dist/impls/elevenlabs-voice.d.ts +21 -0
  14. package/dist/impls/elevenlabs-voice.d.ts.map +1 -0
  15. package/dist/impls/elevenlabs-voice.js +93 -0
  16. package/dist/impls/elevenlabs-voice.js.map +1 -0
  17. package/dist/impls/gcs-storage.d.ts +25 -0
  18. package/dist/impls/gcs-storage.d.ts.map +1 -0
  19. package/dist/impls/gcs-storage.js +90 -0
  20. package/dist/impls/gcs-storage.js.map +1 -0
  21. package/dist/impls/gmail-inbound.d.ts +27 -0
  22. package/dist/impls/gmail-inbound.d.ts.map +1 -0
  23. package/dist/impls/gmail-inbound.js +201 -0
  24. package/dist/impls/gmail-inbound.js.map +1 -0
  25. package/dist/impls/gmail-outbound.d.ts +19 -0
  26. package/dist/impls/gmail-outbound.d.ts.map +1 -0
  27. package/dist/impls/gmail-outbound.js +106 -0
  28. package/dist/impls/gmail-outbound.js.map +1 -0
  29. package/dist/impls/google-calendar.d.ts +24 -0
  30. package/dist/impls/google-calendar.d.ts.map +1 -0
  31. package/dist/impls/google-calendar.js +155 -0
  32. package/dist/impls/google-calendar.js.map +1 -0
  33. package/dist/impls/index.d.ts +15 -0
  34. package/dist/impls/index.js +16 -0
  35. package/dist/impls/mistral-embedding.d.ts +24 -0
  36. package/dist/impls/mistral-embedding.d.ts.map +1 -0
  37. package/dist/impls/mistral-embedding.js +42 -0
  38. package/dist/impls/mistral-embedding.js.map +1 -0
  39. package/dist/impls/mistral-llm.d.ts +32 -0
  40. package/dist/impls/mistral-llm.d.ts.map +1 -0
  41. package/dist/impls/mistral-llm.js +248 -0
  42. package/dist/impls/mistral-llm.js.map +1 -0
  43. package/dist/impls/postmark-email.d.ts +20 -0
  44. package/dist/impls/postmark-email.d.ts.map +1 -0
  45. package/dist/impls/postmark-email.js +56 -0
  46. package/dist/impls/postmark-email.js.map +1 -0
  47. package/dist/impls/powens-client.d.ts +125 -0
  48. package/dist/impls/powens-client.d.ts.map +1 -0
  49. package/dist/impls/powens-client.js +172 -0
  50. package/dist/impls/powens-client.js.map +1 -0
  51. package/dist/impls/powens-openbanking.d.ts +28 -0
  52. package/dist/impls/powens-openbanking.d.ts.map +1 -0
  53. package/dist/impls/powens-openbanking.js +219 -0
  54. package/dist/impls/powens-openbanking.js.map +1 -0
  55. package/dist/impls/provider-factory.d.ts +27 -0
  56. package/dist/impls/provider-factory.d.ts.map +1 -0
  57. package/dist/impls/provider-factory.js +143 -0
  58. package/dist/impls/provider-factory.js.map +1 -0
  59. package/dist/impls/qdrant-vector.d.ts +25 -0
  60. package/dist/impls/qdrant-vector.d.ts.map +1 -0
  61. package/dist/impls/qdrant-vector.js +72 -0
  62. package/dist/impls/qdrant-vector.js.map +1 -0
  63. package/dist/impls/stripe-payments.d.ts +29 -0
  64. package/dist/impls/stripe-payments.d.ts.map +1 -0
  65. package/dist/impls/stripe-payments.js +203 -0
  66. package/dist/impls/stripe-payments.js.map +1 -0
  67. package/dist/impls/twilio-sms.d.ts +21 -0
  68. package/dist/impls/twilio-sms.d.ts.map +1 -0
  69. package/dist/impls/twilio-sms.js +59 -0
  70. package/dist/impls/twilio-sms.js.map +1 -0
  71. package/dist/index.d.ts +44 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +69 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/llm.d.ts +8 -0
  76. package/dist/llm.d.ts.map +1 -0
  77. package/dist/llm.js +3 -0
  78. package/dist/openbanking.d.ts +8 -0
  79. package/dist/openbanking.d.ts.map +1 -0
  80. package/dist/openbanking.js +3 -0
  81. package/dist/payments.d.ts +8 -0
  82. package/dist/payments.d.ts.map +1 -0
  83. package/dist/payments.js +3 -0
  84. package/dist/runtime.d.ts +2 -0
  85. package/dist/runtime.js +0 -0
  86. package/dist/secrets/provider.d.ts +2 -0
  87. package/dist/secrets/provider.js +3 -0
  88. package/dist/sms.d.ts +8 -0
  89. package/dist/sms.d.ts.map +1 -0
  90. package/dist/sms.js +3 -0
  91. package/dist/storage.d.ts +8 -0
  92. package/dist/storage.d.ts.map +1 -0
  93. package/dist/storage.js +3 -0
  94. package/dist/vector-store.d.ts +8 -0
  95. package/dist/vector-store.d.ts.map +1 -0
  96. package/dist/vector-store.js +3 -0
  97. package/dist/voice.d.ts +8 -0
  98. package/dist/voice.d.ts.map +1 -0
  99. package/dist/voice.js +3 -0
  100. package/package.json +125 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Chaman Ventures, SASU
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # @contractspec/integration.providers-impls
2
+
3
+ Website: https://contractspec.io/
4
+
5
+
6
+ SDK-backed implementations of ContractSpec integration provider interfaces.
7
+
8
+ Depends on:
9
+ - `@contractspec/lib.contracts` for provider interface types and IntegrationSpec declarations
10
+ - `@contractspec/integration.runtime` for secret/guard helpers (when needed)
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
@@ -0,0 +1,36 @@
1
+ //#region rolldown:runtime
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __exportAll = (all, symbols) => {
7
+ let target = {};
8
+ for (var name in all) {
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ }
14
+ if (symbols) {
15
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ }
17
+ return target;
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
22
+ key = keys[i];
23
+ if (!__hasOwnProp.call(to, key) && key !== except) {
24
+ __defProp(to, key, {
25
+ get: ((k) => from[k]).bind(null, key),
26
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
27
+ });
28
+ }
29
+ }
30
+ }
31
+ return to;
32
+ };
33
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
34
+
35
+ //#endregion
36
+ export { __exportAll, __reExport };
@@ -0,0 +1,8 @@
1
+ export * from "@contractspec/lib.contracts/integrations/providers/calendar";
2
+
3
+ //#region src/calendar.d.ts
4
+
5
+ import * as import__contractspec_lib_contracts_integrations_providers_calendar from "@contractspec/lib.contracts/integrations/providers/calendar";
6
+ //#endregion
7
+ export { import__contractspec_lib_contracts_integrations_providers_calendar as calendar_d_exports };
8
+ //# sourceMappingURL=calendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar.d.ts","names":[],"sources":["../src/calendar.ts"],"sourcesContent":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { __reExport } from "./_virtual/rolldown_runtime.js";
2
+
3
+ export * from "@contractspec/lib.contracts/integrations/providers/calendar"
@@ -0,0 +1,8 @@
1
+ export * from "@contractspec/lib.contracts/integrations/providers/email";
2
+
3
+ //#region src/email.d.ts
4
+
5
+ import * as import__contractspec_lib_contracts_integrations_providers_email from "@contractspec/lib.contracts/integrations/providers/email";
6
+ //#endregion
7
+ export { import__contractspec_lib_contracts_integrations_providers_email as email_d_exports };
8
+ //# sourceMappingURL=email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.d.ts","names":[],"sources":["../src/email.ts"],"sourcesContent":[],"mappings":""}
package/dist/email.js ADDED
@@ -0,0 +1,3 @@
1
+ import { __reExport } from "./_virtual/rolldown_runtime.js";
2
+
3
+ export * from "@contractspec/lib.contracts/integrations/providers/email"
@@ -0,0 +1,8 @@
1
+ export * from "@contractspec/lib.contracts/integrations/providers/embedding";
2
+
3
+ //#region src/embedding.d.ts
4
+
5
+ import * as import__contractspec_lib_contracts_integrations_providers_embedding from "@contractspec/lib.contracts/integrations/providers/embedding";
6
+ //#endregion
7
+ export { import__contractspec_lib_contracts_integrations_providers_embedding as embedding_d_exports };
8
+ //# sourceMappingURL=embedding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedding.d.ts","names":[],"sources":["../src/embedding.ts"],"sourcesContent":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { __reExport } from "./_virtual/rolldown_runtime.js";
2
+
3
+ export * from "@contractspec/lib.contracts/integrations/providers/embedding"
@@ -0,0 +1,21 @@
1
+ import { voice_d_exports } from "../voice.js";
2
+ import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
3
+
4
+ //#region src/impls/elevenlabs-voice.d.ts
5
+ interface ElevenLabsVoiceProviderOptions {
6
+ apiKey: string;
7
+ defaultVoiceId?: string;
8
+ modelId?: string;
9
+ client?: ElevenLabsClient;
10
+ }
11
+ declare class ElevenLabsVoiceProvider implements voice_d_exports.VoiceProvider {
12
+ private readonly client;
13
+ private readonly defaultVoiceId?;
14
+ private readonly modelId?;
15
+ constructor(options: ElevenLabsVoiceProviderOptions);
16
+ listVoices(): Promise<voice_d_exports.Voice[]>;
17
+ synthesize(input: voice_d_exports.VoiceSynthesisInput): Promise<voice_d_exports.VoiceSynthesisResult>;
18
+ }
19
+ //#endregion
20
+ export { ElevenLabsVoiceProvider, ElevenLabsVoiceProviderOptions };
21
+ //# sourceMappingURL=elevenlabs-voice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elevenlabs-voice.d.ts","names":[],"sources":["../../src/impls/elevenlabs-voice.ts"],"sourcesContent":[],"mappings":";;;;UAUiB,8BAAA;;EAAA,cAAA,CAAA,EAAA,MAAA;EAiCJ,OAAA,CAAA,EAAA,MAAA;EAKU,MAAA,CAAA,EAlCZ,gBAkCY;;AAUD,cAfT,uBAAA,YAAmC,eAAA,CAAA,aAe1B,CAAA;EAkBI,iBAAA,MAAA;EAA8B,iBAAA,cAAA;EAAR,iBAAA,OAAA;EAjCA,WAAA,CAAA,OAAA,EAKzB,8BALyB;EAAa,UAAA,CAAA,CAAA,EAevC,OAfuC,CAe/B,eAAA,CAAA,KAf+B,EAAA,CAAA;oBAiCnC,eAAA,CAAA,sBAAsB,QAAQ,eAAA,CAAA"}
@@ -0,0 +1,93 @@
1
+ import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
2
+
3
+ //#region src/impls/elevenlabs-voice.ts
4
+ const FORMAT_MAP = {
5
+ mp3: "mp3_44100_128",
6
+ wav: "pcm_44100",
7
+ ogg: "mp3_44100_128",
8
+ pcm: "pcm_16000"
9
+ };
10
+ const SAMPLE_RATE = {
11
+ mp3_22050_32: 22050,
12
+ mp3_44100_32: 44100,
13
+ mp3_44100_64: 44100,
14
+ mp3_44100_96: 44100,
15
+ mp3_44100_128: 44100,
16
+ mp3_44100_192: 44100,
17
+ pcm_16000: 16e3,
18
+ pcm_22050: 22050,
19
+ pcm_24000: 24e3,
20
+ pcm_44100: 44100,
21
+ ulaw_8000: 8e3
22
+ };
23
+ var ElevenLabsVoiceProvider = class {
24
+ client;
25
+ defaultVoiceId;
26
+ modelId;
27
+ constructor(options) {
28
+ this.client = options.client ?? new ElevenLabsClient({ apiKey: options.apiKey });
29
+ this.defaultVoiceId = options.defaultVoiceId;
30
+ this.modelId = options.modelId;
31
+ }
32
+ async listVoices() {
33
+ return ((await this.client.voices.getAll()).voices ?? []).map((voice) => ({
34
+ id: voice.voiceId ?? "",
35
+ name: voice.name ?? "",
36
+ description: voice.description ?? void 0,
37
+ language: voice.labels?.language ?? void 0,
38
+ metadata: {
39
+ category: voice.category ?? "",
40
+ ...voice.previewUrl ? { previewUrl: voice.previewUrl } : {},
41
+ ...(() => {
42
+ const { language, ...rest } = voice.labels ?? {};
43
+ return rest;
44
+ })()
45
+ }
46
+ }));
47
+ }
48
+ async synthesize(input) {
49
+ const voiceId = input.voiceId ?? this.defaultVoiceId;
50
+ if (!voiceId) throw new Error("Voice ID is required for ElevenLabs synthesis.");
51
+ const formatKey = input.format ?? "mp3";
52
+ const outputFormat = FORMAT_MAP[formatKey] ?? FORMAT_MAP.mp3;
53
+ const sampleRate = input.sampleRateHz ?? SAMPLE_RATE[outputFormat] ?? SAMPLE_RATE.mp3_44100_128 ?? 44100;
54
+ const voiceSettings = input.stability != null || input.similarityBoost != null || input.style != null ? {
55
+ ...input.stability != null ? { stability: input.stability } : {},
56
+ ...input.similarityBoost != null ? { similarityBoost: input.similarityBoost } : {},
57
+ ...input.style != null ? { style: input.style } : {}
58
+ } : void 0;
59
+ return {
60
+ audio: await readWebStream(await this.client.textToSpeech.convert(voiceId, {
61
+ text: input.text,
62
+ modelId: this.modelId,
63
+ outputFormat,
64
+ voiceSettings
65
+ })),
66
+ format: formatKey,
67
+ sampleRateHz: sampleRate,
68
+ durationSeconds: void 0,
69
+ url: void 0
70
+ };
71
+ }
72
+ };
73
+ async function readWebStream(stream) {
74
+ const reader = stream.getReader();
75
+ const chunks = [];
76
+ while (true) {
77
+ const { done, value } = await reader.read();
78
+ if (done) break;
79
+ if (value) chunks.push(value);
80
+ }
81
+ const length = chunks.reduce((total, chunk) => total + chunk.length, 0);
82
+ const result = new Uint8Array(length);
83
+ let offset = 0;
84
+ for (const chunk of chunks) {
85
+ result.set(chunk, offset);
86
+ offset += chunk.length;
87
+ }
88
+ return result;
89
+ }
90
+
91
+ //#endregion
92
+ export { ElevenLabsVoiceProvider };
93
+ //# sourceMappingURL=elevenlabs-voice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elevenlabs-voice.js","names":[],"sources":["../../src/impls/elevenlabs-voice.ts"],"sourcesContent":["import type { ElevenLabs } from '@elevenlabs/elevenlabs-js';\nimport { ElevenLabsClient } from '@elevenlabs/elevenlabs-js';\n\nimport type {\n Voice,\n VoiceProvider,\n VoiceSynthesisInput,\n VoiceSynthesisResult,\n} from '../voice';\n\nexport interface ElevenLabsVoiceProviderOptions {\n apiKey: string;\n defaultVoiceId?: string;\n modelId?: string;\n client?: ElevenLabsClient;\n}\n\nconst FORMAT_MAP: Record<\n NonNullable<VoiceSynthesisInput['format']>,\n ElevenLabs.TextToSpeechConvertRequestOutputFormat\n> = {\n mp3: 'mp3_44100_128',\n wav: 'pcm_44100',\n ogg: 'mp3_44100_128',\n pcm: 'pcm_16000',\n};\n\nconst SAMPLE_RATE: Partial<\n Record<ElevenLabs.TextToSpeechConvertRequestOutputFormat, number>\n> = {\n mp3_22050_32: 22050,\n mp3_44100_32: 44100,\n mp3_44100_64: 44100,\n mp3_44100_96: 44100,\n mp3_44100_128: 44100,\n mp3_44100_192: 44100,\n pcm_16000: 16000,\n pcm_22050: 22050,\n pcm_24000: 24000,\n pcm_44100: 44100,\n ulaw_8000: 8000,\n};\n\nexport class ElevenLabsVoiceProvider implements VoiceProvider {\n private readonly client: ElevenLabsClient;\n private readonly defaultVoiceId?: string;\n private readonly modelId?: string;\n\n constructor(options: ElevenLabsVoiceProviderOptions) {\n this.client =\n options.client ??\n new ElevenLabsClient({\n apiKey: options.apiKey,\n });\n this.defaultVoiceId = options.defaultVoiceId;\n this.modelId = options.modelId;\n }\n\n async listVoices(): Promise<Voice[]> {\n const response = await this.client.voices.getAll();\n return (response.voices ?? []).map((voice) => ({\n id: voice.voiceId ?? '',\n name: voice.name ?? '',\n description: voice.description ?? undefined,\n language: voice.labels?.language ?? undefined,\n metadata: {\n category: voice.category ?? '',\n ...(voice.previewUrl ? { previewUrl: voice.previewUrl } : {}),\n ...(() => {\n const { language, ...rest } = voice.labels ?? {};\n return rest;\n })(),\n },\n }));\n }\n\n async synthesize(input: VoiceSynthesisInput): Promise<VoiceSynthesisResult> {\n const voiceId = input.voiceId ?? this.defaultVoiceId;\n if (!voiceId) {\n throw new Error('Voice ID is required for ElevenLabs synthesis.');\n }\n\n const formatKey = input.format ?? 'mp3';\n const outputFormat = FORMAT_MAP[formatKey] ?? FORMAT_MAP.mp3;\n const sampleRate =\n input.sampleRateHz ??\n SAMPLE_RATE[outputFormat] ??\n SAMPLE_RATE.mp3_44100_128 ??\n 44100;\n\n const voiceSettings =\n input.stability != null ||\n input.similarityBoost != null ||\n input.style != null\n ? {\n ...(input.stability != null ? { stability: input.stability } : {}),\n ...(input.similarityBoost != null\n ? { similarityBoost: input.similarityBoost }\n : {}),\n ...(input.style != null ? { style: input.style } : {}),\n }\n : undefined;\n\n const stream = await this.client.textToSpeech.convert(voiceId, {\n text: input.text,\n modelId: this.modelId,\n outputFormat,\n voiceSettings,\n });\n\n const audio = await readWebStream(stream);\n\n return {\n audio,\n format: formatKey,\n sampleRateHz: sampleRate,\n durationSeconds: undefined,\n url: undefined,\n };\n }\n}\n\nasync function readWebStream(\n stream: ReadableStream<Uint8Array>\n): Promise<Uint8Array> {\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) {\n chunks.push(value);\n }\n }\n\n const length = chunks.reduce((total, chunk) => total + chunk.length, 0);\n const result = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n return result;\n}\n"],"mappings":";;;AAiBA,MAAM,aAGF;CACF,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACN;AAED,MAAM,cAEF;CACF,cAAc;CACd,cAAc;CACd,cAAc;CACd,cAAc;CACd,eAAe;CACf,eAAe;CACf,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACX,WAAW;CACZ;AAED,IAAa,0BAAb,MAA8D;CAC5D,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,SAAyC;AACnD,OAAK,SACH,QAAQ,UACR,IAAI,iBAAiB,EACnB,QAAQ,QAAQ,QACjB,CAAC;AACJ,OAAK,iBAAiB,QAAQ;AAC9B,OAAK,UAAU,QAAQ;;CAGzB,MAAM,aAA+B;AAEnC,WADiB,MAAM,KAAK,OAAO,OAAO,QAAQ,EACjC,UAAU,EAAE,EAAE,KAAK,WAAW;GAC7C,IAAI,MAAM,WAAW;GACrB,MAAM,MAAM,QAAQ;GACpB,aAAa,MAAM,eAAe;GAClC,UAAU,MAAM,QAAQ,YAAY;GACpC,UAAU;IACR,UAAU,MAAM,YAAY;IAC5B,GAAI,MAAM,aAAa,EAAE,YAAY,MAAM,YAAY,GAAG,EAAE;IAC5D,UAAU;KACR,MAAM,EAAE,UAAU,GAAG,SAAS,MAAM,UAAU,EAAE;AAChD,YAAO;QACL;IACL;GACF,EAAE;;CAGL,MAAM,WAAW,OAA2D;EAC1E,MAAM,UAAU,MAAM,WAAW,KAAK;AACtC,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,iDAAiD;EAGnE,MAAM,YAAY,MAAM,UAAU;EAClC,MAAM,eAAe,WAAW,cAAc,WAAW;EACzD,MAAM,aACJ,MAAM,gBACN,YAAY,iBACZ,YAAY,iBACZ;EAEF,MAAM,gBACJ,MAAM,aAAa,QACnB,MAAM,mBAAmB,QACzB,MAAM,SAAS,OACX;GACE,GAAI,MAAM,aAAa,OAAO,EAAE,WAAW,MAAM,WAAW,GAAG,EAAE;GACjE,GAAI,MAAM,mBAAmB,OACzB,EAAE,iBAAiB,MAAM,iBAAiB,GAC1C,EAAE;GACN,GAAI,MAAM,SAAS,OAAO,EAAE,OAAO,MAAM,OAAO,GAAG,EAAE;GACtD,GACD;AAWN,SAAO;GACL,OAHY,MAAM,cAPL,MAAM,KAAK,OAAO,aAAa,QAAQ,SAAS;IAC7D,MAAM,MAAM;IACZ,SAAS,KAAK;IACd;IACA;IACD,CAAC,CAEuC;GAIvC,QAAQ;GACR,cAAc;GACd,iBAAiB;GACjB,KAAK;GACN;;;AAIL,eAAe,cACb,QACqB;CACrB,MAAM,SAAS,OAAO,WAAW;CACjC,MAAM,SAAuB,EAAE;AAE/B,QAAO,MAAM;EACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,MAAI,KAAM;AACV,MAAI,MACF,QAAO,KAAK,MAAM;;CAItB,MAAM,SAAS,OAAO,QAAQ,OAAO,UAAU,QAAQ,MAAM,QAAQ,EAAE;CACvE,MAAM,SAAS,IAAI,WAAW,OAAO;CACrC,IAAI,SAAS;AACb,MAAK,MAAM,SAAS,QAAQ;AAC1B,SAAO,IAAI,OAAO,OAAO;AACzB,YAAU,MAAM;;AAElB,QAAO"}
@@ -0,0 +1,25 @@
1
+ import { storage_d_exports } from "../storage.js";
2
+ import { Storage, StorageOptions } from "@google-cloud/storage";
3
+
4
+ //#region src/impls/gcs-storage.d.ts
5
+ interface GoogleCloudStorageProviderOptions {
6
+ bucket: string;
7
+ storage?: Storage;
8
+ clientOptions?: StorageOptions;
9
+ }
10
+ declare class GoogleCloudStorageProvider implements storage_d_exports.ObjectStorageProvider {
11
+ private readonly storage;
12
+ private readonly bucketName;
13
+ constructor(options: GoogleCloudStorageProviderOptions);
14
+ putObject(input: storage_d_exports.PutObjectInput): Promise<storage_d_exports.StorageObjectMetadata>;
15
+ getObject(input: storage_d_exports.DeleteObjectInput): Promise<storage_d_exports.GetObjectResult | null>;
16
+ deleteObject(input: storage_d_exports.DeleteObjectInput): Promise<void>;
17
+ generateSignedUrl(options: storage_d_exports.SignedUrlOptions): Promise<{
18
+ url: string;
19
+ expiresAt: Date;
20
+ }>;
21
+ listObjects(query: storage_d_exports.ListObjectsQuery): Promise<storage_d_exports.ListObjectsResult>;
22
+ }
23
+ //#endregion
24
+ export { GoogleCloudStorageProvider, GoogleCloudStorageProviderOptions };
25
+ //# sourceMappingURL=gcs-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gcs-storage.d.ts","names":[],"sources":["../../src/impls/gcs-storage.ts"],"sourcesContent":[],"mappings":";;;;UAaiB,iCAAA;;EAAA,OAAA,CAAA,EAEL,OAFK;EAMJ,aAAA,CAAA,EAHK,cAGsB;;AAUf,cAVZ,0BAAA,YAAsC,iBAAA,CAAA,qBAU1B,CAAA;EAAyB,iBAAA,OAAA;EAAR,iBAAA,UAAA;EAiBjB,WAAA,CAAA,OAAA,EAvBF,iCAuBE;EAA4B,SAAA,CAAA,KAAA,EAjB5B,iBAAA,CAAA,cAiB4B,CAAA,EAjBX,OAiBW,CAjBH,iBAAA,CAAA,qBAiBG,CAAA;EAAR,SAAA,CAAA,KAAA,EAApB,iBAAA,CAAA,iBAAoB,CAAA,EAAA,OAAA,CAAQ,iBAAA,CAAA,eAAR,GAAA,IAAA,CAAA;EAcjB,YAAA,CAAA,KAAA,EAAA,iBAAA,CAAA,iBAAA,CAAA,EAAoB,OAApB,CAAA,IAAA,CAAA;EAAoB,iBAAA,CAAA,OAAA,EAOb,iBAAA,CAAA,gBAPa,CAAA,EAOM,OAPN,CAAA;IAOb,GAAA,EAAA,MAAA;IAEpB,SAAA,EAAA,IAAA;EAFuC,CAAA,CAAA;EAiB3B,WAAA,CAAA,KAAA,EAAA,iBAAA,CAAA,gBAAA,CAAA,EAAmB,OAAnB,CAA2B,iBAAA,CAAA,iBAA3B,CAAA"}
@@ -0,0 +1,90 @@
1
+ import { Storage } from "@google-cloud/storage";
2
+
3
+ //#region src/impls/gcs-storage.ts
4
+ var GoogleCloudStorageProvider = class {
5
+ storage;
6
+ bucketName;
7
+ constructor(options) {
8
+ this.storage = options.storage ?? new Storage(options.clientOptions ?? void 0);
9
+ this.bucketName = options.bucket;
10
+ }
11
+ async putObject(input) {
12
+ const bucketName = input.bucket ?? this.bucketName;
13
+ const file = this.storage.bucket(bucketName).file(input.key);
14
+ const buffer = toBuffer(input.data);
15
+ await file.save(buffer, {
16
+ resumable: false,
17
+ contentType: input.contentType,
18
+ metadata: input.metadata
19
+ });
20
+ if (input.makePublic) await file.makePublic();
21
+ const [metadata] = await file.getMetadata();
22
+ return toMetadata(metadata);
23
+ }
24
+ async getObject(input) {
25
+ const bucketName = input.bucket ?? this.bucketName;
26
+ const file = this.storage.bucket(bucketName).file(input.key);
27
+ const [exists] = await file.exists();
28
+ if (!exists) return null;
29
+ const [contents] = await file.download();
30
+ const [metadata] = await file.getMetadata();
31
+ return {
32
+ ...toMetadata(metadata),
33
+ data: new Uint8Array(contents)
34
+ };
35
+ }
36
+ async deleteObject(input) {
37
+ const bucketName = input.bucket ?? this.bucketName;
38
+ await this.storage.bucket(bucketName).file(input.key).delete({ ignoreNotFound: true });
39
+ }
40
+ async generateSignedUrl(options) {
41
+ const bucketName = options.bucket ?? this.bucketName;
42
+ const file = this.storage.bucket(bucketName).file(options.key);
43
+ const action = options.method === "PUT" ? "write" : "read";
44
+ const expires = Date.now() + options.expiresInSeconds * 1e3;
45
+ const [url] = await file.getSignedUrl({
46
+ action,
47
+ expires,
48
+ contentType: options.contentType
49
+ });
50
+ return {
51
+ url,
52
+ expiresAt: new Date(expires)
53
+ };
54
+ }
55
+ async listObjects(query) {
56
+ const bucketName = query.bucket ?? this.bucketName;
57
+ const [files, nextQuery, response] = await this.storage.bucket(bucketName).getFiles({
58
+ prefix: query.prefix,
59
+ maxResults: query.maxResults,
60
+ pageToken: query.pageToken
61
+ });
62
+ const nextTokenFromQuery = typeof nextQuery === "object" && nextQuery !== null && "pageToken" in nextQuery ? nextQuery.pageToken : void 0;
63
+ const nextTokenFromResponse = response && typeof response === "object" && "nextPageToken" in response ? response.nextPageToken : void 0;
64
+ return {
65
+ objects: files.map((file) => toMetadata(file.metadata)),
66
+ nextPageToken: nextTokenFromQuery ?? nextTokenFromResponse ?? void 0
67
+ };
68
+ }
69
+ };
70
+ function toBuffer(data) {
71
+ if (data instanceof Uint8Array) return Buffer.from(data);
72
+ return Buffer.from(data);
73
+ }
74
+ function toMetadata(metadata) {
75
+ const meta = metadata;
76
+ return {
77
+ bucket: String(meta.bucket ?? ""),
78
+ key: String(meta.name ?? ""),
79
+ sizeBytes: meta.size ? Number(meta.size) : void 0,
80
+ contentType: meta.contentType ? String(meta.contentType) : void 0,
81
+ etag: meta.etag ? String(meta.etag) : void 0,
82
+ checksum: meta.md5Hash ? String(meta.md5Hash) : void 0,
83
+ lastModified: meta.updated ? new Date(String(meta.updated)) : void 0,
84
+ metadata: meta.metadata
85
+ };
86
+ }
87
+
88
+ //#endregion
89
+ export { GoogleCloudStorageProvider };
90
+ //# sourceMappingURL=gcs-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gcs-storage.js","names":[],"sources":["../../src/impls/gcs-storage.ts"],"sourcesContent":["import { Storage, type StorageOptions } from '@google-cloud/storage';\n\nimport type {\n ObjectStorageProvider,\n PutObjectInput,\n GetObjectResult,\n StorageObjectMetadata,\n ListObjectsQuery,\n ListObjectsResult,\n SignedUrlOptions,\n DeleteObjectInput,\n} from '../storage';\n\nexport interface GoogleCloudStorageProviderOptions {\n bucket: string;\n storage?: Storage;\n clientOptions?: StorageOptions;\n}\n\nexport class GoogleCloudStorageProvider implements ObjectStorageProvider {\n private readonly storage: Storage;\n private readonly bucketName: string;\n\n constructor(options: GoogleCloudStorageProviderOptions) {\n this.storage =\n options.storage ?? new Storage(options.clientOptions ?? undefined);\n this.bucketName = options.bucket;\n }\n\n async putObject(input: PutObjectInput): Promise<StorageObjectMetadata> {\n const bucketName = input.bucket ?? this.bucketName;\n const bucket = this.storage.bucket(bucketName);\n const file = bucket.file(input.key);\n const buffer = toBuffer(input.data);\n await file.save(buffer, {\n resumable: false,\n contentType: input.contentType,\n metadata: input.metadata,\n });\n if (input.makePublic) {\n await file.makePublic();\n }\n const [metadata] = await file.getMetadata();\n return toMetadata(metadata);\n }\n\n async getObject(input: DeleteObjectInput): Promise<GetObjectResult | null> {\n const bucketName = input.bucket ?? this.bucketName;\n const bucket = this.storage.bucket(bucketName);\n const file = bucket.file(input.key);\n const [exists] = await file.exists();\n if (!exists) return null;\n const [contents] = await file.download();\n const [metadata] = await file.getMetadata();\n return {\n ...toMetadata(metadata),\n data: new Uint8Array(contents),\n };\n }\n\n async deleteObject(input: DeleteObjectInput): Promise<void> {\n const bucketName = input.bucket ?? this.bucketName;\n const bucket = this.storage.bucket(bucketName);\n const file = bucket.file(input.key);\n await file.delete({ ignoreNotFound: true });\n }\n\n async generateSignedUrl(options: SignedUrlOptions): Promise<{\n url: string;\n expiresAt: Date;\n }> {\n const bucketName = options.bucket ?? this.bucketName;\n const bucket = this.storage.bucket(bucketName);\n const file = bucket.file(options.key);\n const action = options.method === 'PUT' ? 'write' : 'read';\n const expires = Date.now() + options.expiresInSeconds * 1000;\n const [url] = await file.getSignedUrl({\n action,\n expires,\n contentType: options.contentType,\n });\n return { url, expiresAt: new Date(expires) };\n }\n\n async listObjects(query: ListObjectsQuery): Promise<ListObjectsResult> {\n const bucketName = query.bucket ?? this.bucketName;\n const bucket = this.storage.bucket(bucketName);\n const [files, nextQuery, response] = await bucket.getFiles({\n prefix: query.prefix,\n maxResults: query.maxResults,\n pageToken: query.pageToken,\n });\n const nextTokenFromQuery =\n typeof nextQuery === 'object' &&\n nextQuery !== null &&\n 'pageToken' in nextQuery\n ? (nextQuery as { pageToken?: string }).pageToken\n : undefined;\n const nextTokenFromResponse =\n response && typeof response === 'object' && 'nextPageToken' in response\n ? (response as { nextPageToken?: string }).nextPageToken\n : undefined;\n return {\n objects: files.map((file) => toMetadata(file.metadata)),\n nextPageToken: nextTokenFromQuery ?? nextTokenFromResponse ?? undefined,\n };\n }\n}\n\nfunction toBuffer(data: Uint8Array | ArrayBuffer): Buffer {\n if (data instanceof Uint8Array) {\n return Buffer.from(data);\n }\n return Buffer.from(data);\n}\n\nfunction toMetadata(metadata: unknown): StorageObjectMetadata {\n const meta = metadata as Record<string, unknown>;\n return {\n bucket: String(meta.bucket ?? ''),\n key: String(meta.name ?? ''),\n sizeBytes: meta.size ? Number(meta.size) : undefined,\n contentType: meta.contentType ? String(meta.contentType) : undefined,\n etag: meta.etag ? String(meta.etag) : undefined,\n checksum: meta.md5Hash ? String(meta.md5Hash) : undefined,\n lastModified: meta.updated ? new Date(String(meta.updated)) : undefined,\n metadata: meta.metadata as Record<string, string> | undefined,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { email_d_exports } from "../email.js";
2
+ import { gmail_v1 } from "googleapis";
3
+
4
+ //#region src/impls/gmail-inbound.d.ts
5
+ interface GmailInboundProviderOptions {
6
+ auth: gmail_v1.Options['auth'];
7
+ userId?: string;
8
+ gmail?: gmail_v1.Gmail;
9
+ includeSpamTrash?: boolean;
10
+ }
11
+ declare class GmailInboundProvider implements email_d_exports.EmailInboundProvider {
12
+ private readonly gmail;
13
+ private readonly userId;
14
+ private readonly includeSpamTrash;
15
+ private readonly auth;
16
+ constructor(options: GmailInboundProviderOptions);
17
+ listThreads(query?: email_d_exports.EmailThreadListQuery): Promise<email_d_exports.EmailThread[]>;
18
+ getThread(threadId: string): Promise<email_d_exports.EmailThread | null>;
19
+ listMessagesSince(query: email_d_exports.EmailMessagesSinceQuery): Promise<{
20
+ messages: email_d_exports.EmailMessage[];
21
+ nextPageToken: string | undefined;
22
+ }>;
23
+ private transformMessage;
24
+ }
25
+ //#endregion
26
+ export { GmailInboundProvider, GmailInboundProviderOptions };
27
+ //# sourceMappingURL=gmail-inbound.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gmail-inbound.d.ts","names":[],"sources":["../../src/impls/gmail-inbound.ts"],"sourcesContent":[],"mappings":";;;;UAUiB,2BAAA;QACT,QAAA,CAAS;EADA,MAAA,CAAA,EAAA,MAAA;EAOJ,KAAA,CAAA,EAJH,QAAA,CAAS,KAIN;EAMU,gBAAA,CAAA,EAAA,OAAA;;AAYoC,cAlB9C,oBAAA,YAAgC,eAAA,CAAA,oBAkBc,CAAA;EAAR,iBAAA,KAAA;EAqBN,iBAAA,MAAA;EAAR,iBAAA,gBAAA;EAsDJ,iBAAA,IAAA;uBAvFV;EAuFiC,WAAA,CAAA,KAAA,CAAA,EA3E5B,eAAA,CAAA,oBA2E4B,CAAA,EA3EL,OA2EK,CA3EG,eAAA,CAAA,WA2EH,EAAA,CAAA;EA7FX,SAAA,CAAA,QAAA,EAAA,MAAA,CAAA,EAuCR,OAvCQ,CAuCA,eAAA,CAAA,WAvCA,GAAA,IAAA,CAAA;EAAoB,iBAAA,CAAA,KAAA,EA6FhC,eAAA,CAAA,uBA7FgC,CAAA,EA6FT,OA7FS,CAAA"}
@@ -0,0 +1,201 @@
1
+ import { google } from "googleapis";
2
+
3
+ //#region src/impls/gmail-inbound.ts
4
+ var GmailInboundProvider = class {
5
+ gmail;
6
+ userId;
7
+ includeSpamTrash;
8
+ auth;
9
+ constructor(options) {
10
+ this.auth = options.auth;
11
+ this.gmail = options.gmail ?? google.gmail({
12
+ version: "v1",
13
+ auth: options.auth
14
+ });
15
+ this.userId = options.userId ?? "me";
16
+ this.includeSpamTrash = options.includeSpamTrash ?? false;
17
+ }
18
+ async listThreads(query) {
19
+ const response = await this.gmail.users.threads.list({
20
+ userId: this.userId,
21
+ maxResults: query?.pageSize,
22
+ pageToken: query?.pageToken,
23
+ q: query?.query,
24
+ labelIds: query?.label ? [query.label] : void 0,
25
+ includeSpamTrash: this.includeSpamTrash,
26
+ auth: this.auth
27
+ });
28
+ return (await Promise.all((response.data.threads ?? []).map(async (thread) => {
29
+ if (!thread.id) return null;
30
+ return this.getThread(thread.id);
31
+ }))).filter((thread) => thread !== null);
32
+ }
33
+ async getThread(threadId) {
34
+ const thread = (await this.gmail.users.threads.get({
35
+ id: threadId,
36
+ userId: this.userId,
37
+ format: "full",
38
+ auth: this.auth
39
+ })).data;
40
+ if (!thread) return null;
41
+ const messages = thread.messages?.map((message) => this.transformMessage(message)) ?? [];
42
+ const participants = dedupeAddresses(messages.flatMap((message) => [
43
+ message.from,
44
+ ...message.to,
45
+ ...message.cc ?? []
46
+ ]));
47
+ const firstMessage = messages[0];
48
+ const lastMessage = messages[messages.length - 1];
49
+ const updatedAt = lastMessage?.receivedAt ?? lastMessage?.sentAt ?? firstMessage?.receivedAt ?? firstMessage?.sentAt ?? /* @__PURE__ */ new Date();
50
+ const labels = Array.from(new Set(messages.flatMap((message) => {
51
+ const labelField = message.metadata?.labelIds;
52
+ if (!labelField) return [];
53
+ return labelField.split(",").map((label) => label.trim());
54
+ }).filter((label) => Boolean(label))));
55
+ return {
56
+ id: thread.id ?? threadId,
57
+ subject: messages[0]?.subject,
58
+ snippet: thread.snippet ?? "",
59
+ participants,
60
+ messages,
61
+ updatedAt,
62
+ labels,
63
+ metadata: thread.historyId ? { historyId: thread.historyId } : void 0
64
+ };
65
+ }
66
+ async listMessagesSince(query) {
67
+ const after = query.since ? Math.floor(query.since.getTime() / 1e3) : void 0;
68
+ const q = [];
69
+ if (after) q.push(`after:${after}`);
70
+ const response = await this.gmail.users.messages.list({
71
+ userId: this.userId,
72
+ maxResults: query.pageSize,
73
+ pageToken: query.pageToken,
74
+ labelIds: query.label ? [query.label] : void 0,
75
+ q: q.join(" "),
76
+ includeSpamTrash: this.includeSpamTrash,
77
+ auth: this.auth
78
+ });
79
+ return {
80
+ messages: (await Promise.all((response.data.messages ?? []).map(async (item) => {
81
+ if (!item.id) return null;
82
+ const full = await this.gmail.users.messages.get({
83
+ userId: this.userId,
84
+ id: item.id,
85
+ format: "full",
86
+ auth: this.auth
87
+ });
88
+ if (!full.data) return null;
89
+ return this.transformMessage(full.data);
90
+ }))).filter((message) => message !== null),
91
+ nextPageToken: response.data.nextPageToken ?? void 0
92
+ };
93
+ }
94
+ transformMessage(message) {
95
+ const headers = message.payload?.headers ?? [];
96
+ const subject = headerValue(headers, "Subject") ?? "";
97
+ const from = parseAddress(headerValue(headers, "From")) ?? inferFallbackAddress("from", message.id);
98
+ const to = parseAddressList(headerValue(headers, "To"));
99
+ const cc = parseAddressList(headerValue(headers, "Cc"));
100
+ const bcc = parseAddressList(headerValue(headers, "Bcc"));
101
+ const replyTo = parseAddress(headerValue(headers, "Reply-To"));
102
+ const { text, html, attachments } = extractContent(message.payload);
103
+ const timestamp = message.internalDate ? new Date(Number(message.internalDate)) : /* @__PURE__ */ new Date();
104
+ const metadata = {
105
+ ...message.labelIds?.length ? { labelIds: message.labelIds.join(",") } : {},
106
+ ...message.historyId ? { historyId: message.historyId } : {}
107
+ };
108
+ return {
109
+ id: message.id ?? "",
110
+ threadId: message.threadId ?? "",
111
+ subject,
112
+ from,
113
+ to,
114
+ cc,
115
+ bcc,
116
+ replyTo: replyTo ?? void 0,
117
+ sentAt: timestamp,
118
+ receivedAt: timestamp,
119
+ textBody: text ?? void 0,
120
+ htmlBody: html ?? void 0,
121
+ attachments,
122
+ headers: Object.fromEntries(headers.map((header) => [header.name ?? "", header.value ?? ""])),
123
+ metadata: Object.keys(metadata).length > 0 ? metadata : void 0
124
+ };
125
+ }
126
+ };
127
+ function headerValue(headers, name) {
128
+ const value = headers.find((candidate) => candidate.name?.toLowerCase() === name.toLowerCase())?.value;
129
+ return typeof value === "string" ? value : void 0;
130
+ }
131
+ function parseAddress(header) {
132
+ const addresses = parseAddressList(header);
133
+ if (addresses.length === 0) return null;
134
+ return addresses[0] || null;
135
+ }
136
+ function inferFallbackAddress(field, messageId) {
137
+ return { email: `${field}-${messageId ? messageId.replace(/[^\w]/g, "").slice(-8) || "unknown" : "unknown"}@mail.local` };
138
+ }
139
+ function parseAddressList(header) {
140
+ if (!header) return [];
141
+ return header.split(",").map((part) => part.trim()).filter(Boolean).map((value) => {
142
+ const match = value.match(/^(?:"?([^"]*)"?\s)?<?([^<>]+)>?$/);
143
+ if (!match) return { email: value };
144
+ const name = match[1]?.trim();
145
+ const email = match[2]?.trim();
146
+ if (!email) return { email: value };
147
+ return name ? {
148
+ email,
149
+ name
150
+ } : { email };
151
+ });
152
+ }
153
+ function dedupeAddresses(addresses) {
154
+ const map = /* @__PURE__ */ new Map();
155
+ for (const address of addresses) {
156
+ if (!address) continue;
157
+ map.set(address.email.toLowerCase(), address);
158
+ }
159
+ return Array.from(map.values());
160
+ }
161
+ function extractContent(payload) {
162
+ if (!payload) return { attachments: [] };
163
+ const attachments = [];
164
+ const visit = (part) => {
165
+ if (!part) return {};
166
+ if (part.filename && part.body?.attachmentId) attachments.push({
167
+ id: part.body.attachmentId,
168
+ filename: part.filename,
169
+ contentType: part.mimeType ?? "application/octet-stream",
170
+ sizeBytes: part.body.size ?? void 0
171
+ });
172
+ const mimeType = part.mimeType ?? "";
173
+ const data = part.body?.data;
174
+ if (mimeType === "text/plain" && data) return { text: decodeBase64Url(data) };
175
+ if (mimeType === "text/html" && data) return { html: decodeBase64Url(data) };
176
+ if (part.parts?.length) return part.parts.reduce((acc, nested) => {
177
+ const value = visit(nested);
178
+ return {
179
+ text: value.text ?? acc.text,
180
+ html: value.html ?? acc.html
181
+ };
182
+ }, {});
183
+ return {};
184
+ };
185
+ const { text, html } = visit(payload);
186
+ return {
187
+ text,
188
+ html,
189
+ attachments
190
+ };
191
+ }
192
+ function decodeBase64Url(data) {
193
+ const normalized = data.replace(/-/g, "+").replace(/_/g, "/");
194
+ const padding = normalized.length % 4;
195
+ const padded = padding === 0 ? normalized : normalized + "=".repeat(4 - padding);
196
+ return Buffer.from(padded, "base64").toString("utf-8");
197
+ }
198
+
199
+ //#endregion
200
+ export { GmailInboundProvider };
201
+ //# sourceMappingURL=gmail-inbound.js.map