@lssm/integration.providers-impls 0.0.0-canary-20251217080011 → 1.41.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/dist/_virtual/rolldown_runtime.js +1 -42
- package/dist/calendar.js +1 -0
- package/dist/email.js +1 -0
- package/dist/embedding.js +1 -0
- package/dist/impls/elevenlabs-voice.js +1 -95
- package/dist/impls/gcs-storage.js +1 -88
- package/dist/impls/gmail-inbound.js +1 -200
- package/dist/impls/gmail-outbound.js +5 -104
- package/dist/impls/google-calendar.js +1 -154
- package/dist/impls/index.js +1 -16
- package/dist/impls/mistral-embedding.js +1 -41
- package/dist/impls/mistral-llm.js +1 -247
- package/dist/impls/postmark-email.js +1 -55
- package/dist/impls/powens-client.js +1 -171
- package/dist/impls/powens-openbanking.js +1 -218
- package/dist/impls/provider-factory.js +1 -142
- package/dist/impls/qdrant-vector.js +1 -69
- package/dist/impls/stripe-payments.js +1 -202
- package/dist/impls/twilio-sms.js +1 -58
- package/dist/index.js +1 -17
- package/dist/llm.js +1 -0
- package/dist/openbanking.js +1 -0
- package/dist/payments.js +1 -0
- package/dist/secrets/provider.js +1 -3
- package/dist/sms.js +1 -0
- package/dist/storage.js +1 -0
- package/dist/vector-store.js +1 -0
- package/dist/voice.js +1 -0
- package/package.json +33 -34
- package/dist/calendar.d.ts +0 -7
- package/dist/email.d.ts +0 -7
- package/dist/embedding.d.ts +0 -7
- package/dist/impls/elevenlabs-voice.d.ts +0 -20
- package/dist/impls/gcs-storage.d.ts +0 -24
- package/dist/impls/gmail-inbound.d.ts +0 -26
- package/dist/impls/gmail-outbound.d.ts +0 -18
- package/dist/impls/google-calendar.d.ts +0 -23
- package/dist/impls/index.d.ts +0 -15
- package/dist/impls/mistral-embedding.d.ts +0 -23
- package/dist/impls/mistral-llm.d.ts +0 -31
- package/dist/impls/postmark-email.d.ts +0 -19
- package/dist/impls/powens-client.d.ts +0 -124
- package/dist/impls/powens-openbanking.d.ts +0 -27
- package/dist/impls/provider-factory.d.ts +0 -26
- package/dist/impls/qdrant-vector.d.ts +0 -24
- package/dist/impls/stripe-payments.d.ts +0 -28
- package/dist/impls/twilio-sms.d.ts +0 -20
- package/dist/index.d.ts +0 -43
- package/dist/llm.d.ts +0 -7
- package/dist/openbanking.d.ts +0 -7
- package/dist/payments.d.ts +0 -7
- package/dist/runtime/dist/secrets/provider.js +0 -58
- package/dist/runtime.d.ts +0 -2
- package/dist/secrets/provider.d.ts +0 -2
- package/dist/sms.d.ts +0 -7
- package/dist/storage.d.ts +0 -7
- package/dist/vector-store.d.ts +0 -7
- package/dist/voice.d.ts +0 -7
|
@@ -1,42 +1 @@
|
|
|
1
|
-
|
|
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
|
|
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
|
|
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 {
|
|
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 {
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
`
|
|
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};
|