@lssm/integration.providers-impls 0.0.0-canary-20251217083314 → 1.41.1

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 (58) hide show
  1. package/dist/_virtual/rolldown_runtime.js +1 -42
  2. package/dist/calendar.js +1 -0
  3. package/dist/email.js +1 -0
  4. package/dist/embedding.js +1 -0
  5. package/dist/impls/elevenlabs-voice.js +1 -95
  6. package/dist/impls/gcs-storage.js +1 -88
  7. package/dist/impls/gmail-inbound.js +1 -200
  8. package/dist/impls/gmail-outbound.js +5 -104
  9. package/dist/impls/google-calendar.js +1 -154
  10. package/dist/impls/index.js +1 -16
  11. package/dist/impls/mistral-embedding.js +1 -41
  12. package/dist/impls/mistral-llm.js +1 -247
  13. package/dist/impls/postmark-email.js +1 -55
  14. package/dist/impls/powens-client.js +1 -171
  15. package/dist/impls/powens-openbanking.js +1 -218
  16. package/dist/impls/provider-factory.js +1 -142
  17. package/dist/impls/qdrant-vector.js +1 -69
  18. package/dist/impls/stripe-payments.js +1 -202
  19. package/dist/impls/twilio-sms.js +1 -58
  20. package/dist/index.js +1 -17
  21. package/dist/llm.js +1 -0
  22. package/dist/openbanking.js +1 -0
  23. package/dist/payments.js +1 -0
  24. package/dist/secrets/provider.js +1 -3
  25. package/dist/sms.js +1 -0
  26. package/dist/storage.js +1 -0
  27. package/dist/vector-store.js +1 -0
  28. package/dist/voice.js +1 -0
  29. package/package.json +33 -33
  30. package/dist/calendar.d.ts +0 -7
  31. package/dist/email.d.ts +0 -7
  32. package/dist/embedding.d.ts +0 -7
  33. package/dist/impls/elevenlabs-voice.d.ts +0 -20
  34. package/dist/impls/gcs-storage.d.ts +0 -24
  35. package/dist/impls/gmail-inbound.d.ts +0 -26
  36. package/dist/impls/gmail-outbound.d.ts +0 -18
  37. package/dist/impls/google-calendar.d.ts +0 -23
  38. package/dist/impls/index.d.ts +0 -15
  39. package/dist/impls/mistral-embedding.d.ts +0 -23
  40. package/dist/impls/mistral-llm.d.ts +0 -31
  41. package/dist/impls/postmark-email.d.ts +0 -19
  42. package/dist/impls/powens-client.d.ts +0 -124
  43. package/dist/impls/powens-openbanking.d.ts +0 -27
  44. package/dist/impls/provider-factory.d.ts +0 -26
  45. package/dist/impls/qdrant-vector.d.ts +0 -24
  46. package/dist/impls/stripe-payments.d.ts +0 -28
  47. package/dist/impls/twilio-sms.d.ts +0 -20
  48. package/dist/index.d.ts +0 -43
  49. package/dist/llm.d.ts +0 -7
  50. package/dist/openbanking.d.ts +0 -7
  51. package/dist/payments.d.ts +0 -7
  52. package/dist/runtime/dist/secrets/provider.js +0 -58
  53. package/dist/runtime.d.ts +0 -2
  54. package/dist/secrets/provider.d.ts +0 -2
  55. package/dist/sms.d.ts +0 -7
  56. package/dist/storage.d.ts +0 -7
  57. package/dist/vector-store.d.ts +0 -7
  58. package/dist/voice.d.ts +0 -7
@@ -1,42 +1 @@
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 __export = (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, symbols) => {
34
- if (symbols) {
35
- __defProp(target, Symbol.toStringTag, { value: "Module" });
36
- secondTarget && __defProp(secondTarget, Symbol.toStringTag, { value: "Module" });
37
- }
38
- __copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default");
39
- };
40
-
41
- //#endregion
42
- export { __export, __reExport };
1
+ var e=Object.defineProperty,t=Object.getOwnPropertyDescriptor,n=Object.getOwnPropertyNames,r=Object.prototype.hasOwnProperty,i=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n&&e(r,Symbol.toStringTag,{value:`Module`}),r},a=(i,a,o,s)=>{if(a&&typeof a==`object`||typeof a==`function`)for(var c=n(a),l=0,u=c.length,d;l<u;l++)d=c[l],!r.call(i,d)&&d!==o&&e(i,d,{get:(e=>a[e]).bind(null,d),enumerable:!(s=t(a,d))||s.enumerable});return i},o=(t,n,r,i)=>{i&&(e(t,Symbol.toStringTag,{value:`Module`}),r&&e(r,Symbol.toStringTag,{value:`Module`})),a(t,n,`default`),r&&a(r,n,`default`)};export{i as __export,o as __reExport};
package/dist/calendar.js CHANGED
@@ -0,0 +1 @@
1
+ import{__reExport as e}from"./_virtual/rolldown_runtime.js";export*from"@lssm/lib.contracts/integrations/providers/calendar";
package/dist/email.js CHANGED
@@ -0,0 +1 @@
1
+ import{__reExport as e}from"./_virtual/rolldown_runtime.js";export*from"@lssm/lib.contracts/integrations/providers/email";
package/dist/embedding.js CHANGED
@@ -0,0 +1 @@
1
+ import{__reExport as e}from"./_virtual/rolldown_runtime.js";export*from"@lssm/lib.contracts/integrations/providers/embedding";
@@ -1,95 +1 @@
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 ?? voice.voiceId ?? "",
36
- description: voice.description ?? void 0,
37
- language: voice.labels?.language ?? void 0,
38
- gender: normalizeGender(voice.labels?.gender),
39
- previewUrl: voice.previewUrl ?? void 0,
40
- metadata: {
41
- category: voice.category ?? "",
42
- ...voice.labels
43
- }
44
- }));
45
- }
46
- async synthesize(input) {
47
- const voiceId = input.voiceId ?? this.defaultVoiceId;
48
- if (!voiceId) throw new Error("Voice ID is required for ElevenLabs synthesis.");
49
- const formatKey = input.format ?? "mp3";
50
- const outputFormat = FORMAT_MAP[formatKey] ?? FORMAT_MAP.mp3;
51
- const sampleRate = input.sampleRateHz ?? SAMPLE_RATE[outputFormat] ?? SAMPLE_RATE.mp3_44100_128 ?? 44100;
52
- const voiceSettings = input.stability != null || input.similarityBoost != null || input.style != null ? {
53
- ...input.stability != null ? { stability: input.stability } : {},
54
- ...input.similarityBoost != null ? { similarityBoost: input.similarityBoost } : {},
55
- ...input.style != null ? { style: input.style } : {}
56
- } : void 0;
57
- return {
58
- audio: await readWebStream(await this.client.textToSpeech.convert(voiceId, {
59
- text: input.text,
60
- modelId: this.modelId,
61
- outputFormat,
62
- voiceSettings
63
- })),
64
- format: formatKey,
65
- sampleRateHz: sampleRate,
66
- durationSeconds: void 0,
67
- url: void 0
68
- };
69
- }
70
- };
71
- function normalizeGender(value) {
72
- if (!value) return void 0;
73
- const normalized = value.toLowerCase();
74
- if (normalized === "male" || normalized === "female" || normalized === "neutral") return normalized;
75
- }
76
- async function readWebStream(stream) {
77
- const reader = stream.getReader();
78
- const chunks = [];
79
- while (true) {
80
- const { done, value } = await reader.read();
81
- if (done) break;
82
- if (value) chunks.push(value);
83
- }
84
- const length = chunks.reduce((total, chunk) => total + chunk.length, 0);
85
- const result = new Uint8Array(length);
86
- let offset = 0;
87
- for (const chunk of chunks) {
88
- result.set(chunk, offset);
89
- offset += chunk.length;
90
- }
91
- return result;
92
- }
93
-
94
- //#endregion
95
- export { ElevenLabsVoiceProvider };
1
+ import{ElevenLabsClient as e}from"@elevenlabs/elevenlabs-js";const t={mp3:`mp3_44100_128`,wav:`pcm_44100`,ogg:`mp3_44100_128`,pcm:`pcm_16000`},n={mp3_22050_32:22050,mp3_44100_32:44100,mp3_44100_64:44100,mp3_44100_96:44100,mp3_44100_128:44100,mp3_44100_192:44100,pcm_16000:16e3,pcm_22050:22050,pcm_24000:24e3,pcm_44100:44100,ulaw_8000:8e3};var r=class{client;defaultVoiceId;modelId;constructor(t){this.client=t.client??new e({apiKey:t.apiKey}),this.defaultVoiceId=t.defaultVoiceId,this.modelId=t.modelId}async listVoices(){return((await this.client.voices.getAll()).voices??[]).map(e=>({id:e.voiceId??``,name:e.name??e.voiceId??``,description:e.description??void 0,language:e.labels?.language??void 0,gender:i(e.labels?.gender),previewUrl:e.previewUrl??void 0,metadata:{category:e.category??``,...e.labels}}))}async synthesize(e){let r=e.voiceId??this.defaultVoiceId;if(!r)throw Error(`Voice ID is required for ElevenLabs synthesis.`);let i=e.format??`mp3`,o=t[i]??t.mp3,s=e.sampleRateHz??n[o]??n.mp3_44100_128??44100,c=e.stability!=null||e.similarityBoost!=null||e.style!=null?{...e.stability==null?{}:{stability:e.stability},...e.similarityBoost==null?{}:{similarityBoost:e.similarityBoost},...e.style==null?{}:{style:e.style}}:void 0;return{audio:await a(await this.client.textToSpeech.convert(r,{text:e.text,modelId:this.modelId,outputFormat:o,voiceSettings:c})),format:i,sampleRateHz:s,durationSeconds:void 0,url:void 0}}};function i(e){if(!e)return;let t=e.toLowerCase();if(t===`male`||t===`female`||t===`neutral`)return t}async function a(e){let t=e.getReader(),n=[];for(;;){let{done:e,value:r}=await t.read();if(e)break;r&&n.push(r)}let r=n.reduce((e,t)=>e+t.length,0),i=new Uint8Array(r),a=0;for(let e of n)i.set(e,a),a+=e.length;return i}export{r as ElevenLabsVoiceProvider};
@@ -1,88 +1 @@
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
- return {
76
- bucket: metadata.bucket ?? "",
77
- key: metadata.name ?? "",
78
- sizeBytes: metadata.size ? Number(metadata.size) : void 0,
79
- contentType: metadata.contentType ?? void 0,
80
- etag: metadata.etag ?? void 0,
81
- checksum: metadata.md5Hash ?? void 0,
82
- lastModified: metadata.updated ? new Date(metadata.updated) : void 0,
83
- metadata: metadata.metadata
84
- };
85
- }
86
-
87
- //#endregion
88
- export { GoogleCloudStorageProvider };
1
+ import{Storage as e}from"@google-cloud/storage";var t=class{storage;bucketName;constructor(t){this.storage=t.storage??new e(t.clientOptions??void 0),this.bucketName=t.bucket}async putObject(e){let t=e.bucket??this.bucketName,i=this.storage.bucket(t).file(e.key),a=n(e.data);await i.save(a,{resumable:!1,contentType:e.contentType,metadata:e.metadata}),e.makePublic&&await i.makePublic();let[o]=await i.getMetadata();return r(o)}async getObject(e){let t=e.bucket??this.bucketName,n=this.storage.bucket(t).file(e.key),[i]=await n.exists();if(!i)return null;let[a]=await n.download(),[o]=await n.getMetadata();return{...r(o),data:new Uint8Array(a)}}async deleteObject(e){let t=e.bucket??this.bucketName;await this.storage.bucket(t).file(e.key).delete({ignoreNotFound:!0})}async generateSignedUrl(e){let t=e.bucket??this.bucketName,n=this.storage.bucket(t).file(e.key),r=e.method===`PUT`?`write`:`read`,i=Date.now()+e.expiresInSeconds*1e3,[a]=await n.getSignedUrl({action:r,expires:i,contentType:e.contentType});return{url:a,expiresAt:new Date(i)}}async listObjects(e){let t=e.bucket??this.bucketName,[n,i,a]=await this.storage.bucket(t).getFiles({prefix:e.prefix,maxResults:e.maxResults,pageToken:e.pageToken}),o=typeof i==`object`&&i&&`pageToken`in i?i.pageToken:void 0,s=a&&typeof a==`object`&&`nextPageToken`in a?a.nextPageToken:void 0;return{objects:n.map(e=>r(e.metadata)),nextPageToken:o??s??void 0}}};function n(e){return e instanceof Uint8Array,Buffer.from(e)}function r(e){return{bucket:e.bucket??``,key:e.name??``,sizeBytes:e.size?Number(e.size):void 0,contentType:e.contentType??void 0,etag:e.etag??void 0,checksum:e.md5Hash??void 0,lastModified:e.updated?new Date(e.updated):void 0,metadata:e.metadata}}export{t as GoogleCloudStorageProvider};
@@ -1,200 +1 @@
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];
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 };
1
+ import{google as e}from"googleapis";var t=class{gmail;userId;includeSpamTrash;auth;constructor(t){this.auth=t.auth,this.gmail=t.gmail??e.gmail({version:`v1`,auth:t.auth}),this.userId=t.userId??`me`,this.includeSpamTrash=t.includeSpamTrash??!1}async listThreads(e){let t=await this.gmail.users.threads.list({userId:this.userId,maxResults:e?.pageSize,pageToken:e?.pageToken,q:e?.query,labelIds:e?.label?[e.label]:void 0,includeSpamTrash:this.includeSpamTrash,auth:this.auth});return(await Promise.all((t.data.threads??[]).map(async e=>e.id?this.getThread(e.id):null))).filter(e=>e!==null)}async getThread(e){let t=(await this.gmail.users.threads.get({id:e,userId:this.userId,format:`full`,auth:this.auth})).data;if(!t)return null;let n=t.messages?.map(e=>this.transformMessage(e))??[],r=o(n.flatMap(e=>[e.from,...e.to,...e.cc??[]])),i=n[0],a=n[n.length-1],s=a?.receivedAt??a?.sentAt??i?.receivedAt??i?.sentAt??new Date,c=Array.from(new Set(n.flatMap(e=>{let t=e.metadata?.labelIds;return t?t.split(`,`).map(e=>e.trim()):[]}).filter(e=>!!e)));return{id:t.id??e,subject:n[0]?.subject,snippet:t.snippet??``,participants:r,messages:n,updatedAt:s,labels:c,metadata:t.historyId?{historyId:t.historyId}:void 0}}async listMessagesSince(e){let t=e.since?Math.floor(e.since.getTime()/1e3):void 0,n=[];t&&n.push(`after:${t}`);let r=await this.gmail.users.messages.list({userId:this.userId,maxResults:e.pageSize,pageToken:e.pageToken,labelIds:e.label?[e.label]:void 0,q:n.join(` `),includeSpamTrash:this.includeSpamTrash,auth:this.auth});return{messages:(await Promise.all((r.data.messages??[]).map(async e=>{if(!e.id)return null;let t=await this.gmail.users.messages.get({userId:this.userId,id:e.id,format:`full`,auth:this.auth});return t.data?this.transformMessage(t.data):null}))).filter(e=>e!==null),nextPageToken:r.data.nextPageToken??void 0}}transformMessage(e){let t=e.payload?.headers??[],o=n(t,`Subject`)??``,c=r(n(t,`From`))??i(`from`,e.id),l=a(n(t,`To`)),u=a(n(t,`Cc`)),d=a(n(t,`Bcc`)),f=r(n(t,`Reply-To`)),{text:p,html:m,attachments:h}=s(e.payload),g=e.internalDate?new Date(Number(e.internalDate)):new Date,_={...e.labelIds?.length?{labelIds:e.labelIds.join(`,`)}:{},...e.historyId?{historyId:e.historyId}:{}};return{id:e.id??``,threadId:e.threadId??``,subject:o,from:c,to:l,cc:u,bcc:d,replyTo:f??void 0,sentAt:g,receivedAt:g,textBody:p??void 0,htmlBody:m??void 0,attachments:h,headers:Object.fromEntries(t.map(e=>[e.name??``,e.value??``])),metadata:Object.keys(_).length>0?_:void 0}}};function n(e,t){let n=e.find(e=>e.name?.toLowerCase()===t.toLowerCase())?.value;return typeof n==`string`?n:void 0}function r(e){let t=a(e);return t.length===0?null:t[0]}function i(e,t){return{email:`${e}-${t&&t.replace(/[^\w]/g,``).slice(-8)||`unknown`}@mail.local`}}function a(e){return e?e.split(`,`).map(e=>e.trim()).filter(Boolean).map(e=>{let t=e.match(/^(?:"?([^"]*)"?\s)?<?([^<>]+)>?$/);if(!t)return{email:e};let n=t[1]?.trim(),r=t[2]?.trim();return r?n?{email:r,name:n}:{email:r}:{email:e}}):[]}function o(e){let t=new Map;for(let n of e)n&&t.set(n.email.toLowerCase(),n);return Array.from(t.values())}function s(e){if(!e)return{attachments:[]};let t=[],n=e=>{if(!e)return{};e.filename&&e.body?.attachmentId&&t.push({id:e.body.attachmentId,filename:e.filename,contentType:e.mimeType??`application/octet-stream`,sizeBytes:e.body.size??void 0});let r=e.mimeType??``,i=e.body?.data;return r===`text/plain`&&i?{text:c(i)}:r===`text/html`&&i?{html:c(i)}:e.parts?.length?e.parts.reduce((e,t)=>{let r=n(t);return{text:r.text??e.text,html:r.html??e.html}},{}):{}},{text:r,html:i}=n(e);return{text:r,html:i,attachments:t}}function c(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=t.length%4,r=n===0?t:t+`=`.repeat(4-n);return Buffer.from(r,`base64`).toString(`utf-8`)}export{t as GmailInboundProvider};
@@ -1,105 +1,6 @@
1
- import { google } from "googleapis";
2
-
3
- //#region src/impls/gmail-outbound.ts
4
- var GmailOutboundProvider = class {
5
- gmail;
6
- userId;
7
- auth;
8
- constructor(options) {
9
- this.auth = options.auth;
10
- this.gmail = options.gmail ?? google.gmail({
11
- version: "v1",
12
- auth: options.auth
13
- });
14
- this.userId = options.userId ?? "me";
15
- }
16
- async sendEmail(message) {
17
- const raw = encodeMessage(message);
18
- const response = await this.gmail.users.messages.send({
19
- userId: this.userId,
20
- requestBody: { raw },
21
- auth: this.auth
22
- });
23
- return {
24
- id: response.data.id ?? "",
25
- providerMessageId: response.data.id ?? void 0,
26
- queuedAt: /* @__PURE__ */ new Date()
27
- };
28
- }
29
- };
30
- function encodeMessage(message) {
31
- const headers = [
32
- `From: ${formatAddress(message.from)}`,
33
- `To: ${message.to.map(formatAddress).join(", ")}`,
34
- `Subject: ${message.subject}`,
35
- "MIME-Version: 1.0"
36
- ];
37
- if (message.cc?.length) headers.push(`Cc: ${message.cc.map(formatAddress).join(", ")}`);
38
- if (message.replyTo) headers.push(`Reply-To: ${formatAddress(message.replyTo)}`);
39
- Object.entries(message.headers ?? {}).forEach(([key, value]) => {
40
- headers.push(`${key}: ${value}`);
41
- });
42
- const attachments = message.attachments ?? [];
43
- const hasHtml = Boolean(message.htmlBody);
44
- const hasText = Boolean(message.textBody);
45
- const boundaryMain = `mixed_${Date.now()}`;
46
- const boundaryAlt = `alt_${Date.now()}`;
47
- let body = "";
48
- if (attachments.length > 0) {
49
- headers.push(`Content-Type: multipart/mixed; boundary="${boundaryMain}"`);
50
- body += `\r\n--${boundaryMain}\r\n`;
51
- body += buildAlternativePart(hasText, hasHtml, boundaryAlt, message);
52
- attachments.forEach((attachment) => {
53
- body += buildAttachmentPart(boundaryMain, attachment);
54
- });
55
- body += `\r\n--${boundaryMain}--`;
56
- } else if (hasText && hasHtml) {
57
- headers.push(`Content-Type: multipart/alternative; boundary="${boundaryAlt}"`);
58
- body += `\r\n--${boundaryAlt}\r\n`;
59
- body += buildTextPart("text/plain; charset=\"utf-8\"", message.textBody);
60
- body += `\r\n--${boundaryAlt}\r\n`;
61
- body += buildTextPart("text/html; charset=\"utf-8\"", message.htmlBody);
62
- body += `\r\n--${boundaryAlt}--`;
63
- } else if (hasHtml) {
64
- headers.push("Content-Type: text/html; charset=\"utf-8\"");
65
- body += `\r\n\r\n${message.htmlBody}`;
66
- } else {
67
- headers.push("Content-Type: text/plain; charset=\"utf-8\"");
68
- body += `\r\n\r\n${message.textBody ?? ""}`;
69
- }
70
- const mime = `${headers.join("\r\n")}${body}`;
71
- return Buffer.from(mime).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
72
- }
73
- function buildAlternativePart(hasText, hasHtml, boundary, message) {
74
- let content = "";
75
- content += `Content-Type: multipart/alternative; boundary="${boundary}"\r\n`;
76
- content += "\r\n";
77
- if (hasText) {
78
- content += `--${boundary}\r\n`;
79
- content += buildTextPart("text/plain; charset=\"utf-8\"", message.textBody);
80
- }
81
- if (hasHtml) {
82
- content += `\r\n--${boundary}\r\n`;
83
- content += buildTextPart("text/html; charset=\"utf-8\"", message.htmlBody);
84
- }
85
- content += `\r\n--${boundary}--`;
86
- return content;
87
- }
88
- function buildTextPart(contentType, content) {
89
- return `Content-Type: ${contentType}\r\nContent-Transfer-Encoding: 7bit\r
1
+ import{google as e}from"googleapis";var t=class{gmail;userId;auth;constructor(t){this.auth=t.auth,this.gmail=t.gmail??e.gmail({version:`v1`,auth:t.auth}),this.userId=t.userId??`me`}async sendEmail(e){let t=n(e),r=await this.gmail.users.messages.send({userId:this.userId,requestBody:{raw:t},auth:this.auth});return{id:r.data.id??``,providerMessageId:r.data.id??void 0,queuedAt:new Date}}};function n(e){let t=[`From: ${o(e.from)}`,`To: ${e.to.map(o).join(`, `)}`,`Subject: ${e.subject}`,`MIME-Version: 1.0`];e.cc?.length&&t.push(`Cc: ${e.cc.map(o).join(`, `)}`),e.replyTo&&t.push(`Reply-To: ${o(e.replyTo)}`),Object.entries(e.headers??{}).forEach(([e,n])=>{t.push(`${e}: ${n}`)});let n=e.attachments??[],s=!!e.htmlBody,c=!!e.textBody,l=`mixed_${Date.now()}`,u=`alt_${Date.now()}`,d=``;n.length>0?(t.push(`Content-Type: multipart/mixed; boundary="${l}"`),d+=`\r\n--${l}\r\n`,d+=r(c,s,u,e),n.forEach(e=>{d+=a(l,e)}),d+=`\r\n--${l}--`):c&&s?(t.push(`Content-Type: multipart/alternative; boundary="${u}"`),d+=`\r\n--${u}\r\n`,d+=i(`text/plain; charset="utf-8"`,e.textBody),d+=`\r\n--${u}\r\n`,d+=i(`text/html; charset="utf-8"`,e.htmlBody),d+=`\r\n--${u}--`):s?(t.push(`Content-Type: text/html; charset="utf-8"`),d+=`\r\n\r\n${e.htmlBody}`):(t.push(`Content-Type: text/plain; charset="utf-8"`),d+=`\r\n\r\n${e.textBody??``}`);let f=`${t.join(`\r
2
+ `)}${d}`;return Buffer.from(f).toString(`base64`).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function r(e,t,n,r){let a=``;return a+=`Content-Type: multipart/alternative; boundary="${n}"\r\n`,a+=`\r
3
+ `,e&&(a+=`--${n}\r\n`,a+=i(`text/plain; charset="utf-8"`,r.textBody)),t&&(a+=`\r\n--${n}\r\n`,a+=i(`text/html; charset="utf-8"`,r.htmlBody)),a+=`\r\n--${n}--`,a}function i(e,t){return`Content-Type: ${e}\r\nContent-Transfer-Encoding: 7bit\r
90
4
  \r
91
- ` + content;
92
- }
93
- function buildAttachmentPart(boundary, attachment) {
94
- const data = attachment.data ?? new Uint8Array();
95
- const encoded = data.byteLength > 0 ? Buffer.from(data).toString("base64") : "";
96
- return `\r\n--${boundary}\r\nContent-Type: ${attachment.contentType}; name="${attachment.filename}"\r\nContent-Transfer-Encoding: base64\r
97
- Content-Disposition: attachment; filename="${attachment.filename}"\r\n\r\n` + encoded;
98
- }
99
- function formatAddress(address) {
100
- if (address.name) return `"${address.name}" <${address.email}>`;
101
- return address.email;
102
- }
103
-
104
- //#endregion
105
- export { GmailOutboundProvider };
5
+ `+t}function a(e,t){let n=t.data??new Uint8Array,r=n.byteLength>0?Buffer.from(n).toString(`base64`):``;return`\r\n--${e}\r\nContent-Type: ${t.contentType}; name="${t.filename}"\r\nContent-Transfer-Encoding: base64\r
6
+ Content-Disposition: attachment; filename="${t.filename}"\r\n\r\n`+r}function o(e){return e.name?`"${e.name}" <${e.email}>`:e.email}export{t as GmailOutboundProvider};