zele 0.3.11 → 0.3.13
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/generated/internal/class.js +2 -10
- package/dist/generated/internal/class.js.map +1 -1
- package/dist/generated/internal/prismaNamespace.d.ts +2 -2
- package/dist/generated/internal/prismaNamespace.js +4 -4
- package/dist/gmail-client.d.ts +11 -12
- package/dist/gmail-client.js +55 -40
- package/dist/gmail-client.js.map +1 -1
- package/dist/mail-tui.js +151 -184
- package/dist/mail-tui.js.map +1 -1
- package/package.json +5 -4
- package/src/generated/internal/class.ts +2 -10
- package/src/generated/internal/prismaNamespace.ts +4 -4
- package/src/gmail-client.test.ts +8 -3
- package/src/gmail-client.ts +64 -58
- package/src/mail-tui.tsx +398 -416
|
@@ -12,25 +12,17 @@
|
|
|
12
12
|
import * as runtime from "@prisma/client/runtime/client";
|
|
13
13
|
const config = {
|
|
14
14
|
"previewFeatures": [],
|
|
15
|
-
"clientVersion": "7.
|
|
16
|
-
"engineVersion": "
|
|
15
|
+
"clientVersion": "7.3.0",
|
|
16
|
+
"engineVersion": "9d6ad21cbbceab97458517b147a6a09ff43aa735",
|
|
17
17
|
"activeProvider": "sqlite",
|
|
18
18
|
"inlineSchema": "generator client {\n provider = \"prisma-client\"\n output = \"./src/generated\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n}\n\n// Lifecycle status for account credentials stored in `Account`.\nenum AccountStatus {\n active\n disabled\n}\n\n// Stores one OAuth credential set per (email, appId) pair.\n// appId is the Google OAuth client ID used during login, enabling\n// multiple OAuth apps per email (different quotas, scopes, etc.).\n// Default is the Thunderbird client ID (the original/only client).\nmodel Account {\n email String\n appId String\n accountStatus AccountStatus\n tokens String // JSON-encoded OAuth2 Credentials\n createdAt DateTime\n updatedAt DateTime @updatedAt\n\n threads Thread[]\n labels Label?\n profiles Profile?\n syncStates SyncState[]\n calendarLists CalendarList?\n\n @@id([email, appId])\n}\n\n// Caches hydrated thread payloads per account + thread ID.\n// Used by mail read and post-mutation cache invalidation.\n// rawData stores the raw Google gmail_v1.Schema$Thread response (format: full)\n// so the cache is resilient to changes in our own ThreadData type.\n// Indexed columns are extracted for queryability and display.\nmodel Thread {\n id Int @id @default(autoincrement())\n email String\n appId String\n threadId String\n subject String // extracted for display/search\n snippet String // extracted for display\n fromEmail String // extracted for filtering\n fromName String // extracted for display\n date String // extracted for sorting (RFC2822 from header)\n labelIds String // comma-separated, extracted for filtering\n hasUnread Boolean // extracted for filtering\n msgCount Int // extracted for display\n historyId String? // for sync\n rawData String // raw Google API response JSON (gmail_v1.Schema$Thread)\n ttlMs Int\n createdAt DateTime\n\n account Account @relation(fields: [email, appId], references: [email, appId], onDelete: Cascade)\n\n @@unique([email, appId, threadId])\n}\n\n// Caches label metadata per account (label id/name/type payload).\n// Used by label list/get and related command outputs.\n// rawData stores the raw Google gmail_v1.Schema$Label[] response.\nmodel Label {\n email String\n appId String\n rawData String // raw Google API response JSON (gmail_v1.Schema$Label[])\n ttlMs Int\n createdAt DateTime\n\n account Account @relation(fields: [email, appId], references: [email, appId], onDelete: Cascade)\n\n @@id([email, appId])\n}\n\n// Caches Gmail profile payload per account (totals/history id).\n// Used by profile command and account metadata lookups.\n// Fully flattened — no JSON blob needed, only 4 fields from Google.\nmodel Profile {\n email String\n appId String\n emailAddress String // from Gmail API\n messagesTotal Int // from Gmail API\n threadsTotal Int // from Gmail API\n historyId String // from Gmail API\n ttlMs Int\n createdAt DateTime\n\n account Account @relation(fields: [email, appId], references: [email, appId], onDelete: Cascade)\n\n @@id([email, appId])\n}\n\n// Caches calendar list per account.\n// Used by cal list to avoid fetching calendar metadata on every invocation.\n// rawData stores parsed CalendarListItem[] JSON (not raw tsdav — parsed at write time).\nmodel CalendarList {\n email String\n appId String\n rawData String // JSON blob of CalendarListItem[]\n ttlMs Int\n createdAt DateTime\n\n account Account @relation(fields: [email, appId], references: [email, appId], onDelete: Cascade)\n\n @@id([email, appId])\n}\n\n// Stores persistent per-account sync metadata as generic key/value pairs.\n// Use this for lightweight sync cursors and markers that are not cached API\n// payloads, for example `history_id` (incremental Gmail history cursor),\n// `last_full_sync_at`, or other small account-scoped checkpoints.\nmodel SyncState {\n email String\n appId String\n key String\n value String\n\n account Account @relation(fields: [email, appId], references: [email, appId], onDelete: Cascade)\n\n @@id([email, appId, key])\n}\n",
|
|
19
19
|
"runtimeDataModel": {
|
|
20
20
|
"models": {},
|
|
21
21
|
"enums": {},
|
|
22
22
|
"types": {}
|
|
23
|
-
},
|
|
24
|
-
"parameterizationSchema": {
|
|
25
|
-
"strings": [],
|
|
26
|
-
"graph": ""
|
|
27
23
|
}
|
|
28
24
|
};
|
|
29
25
|
config.runtimeDataModel = JSON.parse("{\"models\":{\"Account\":{\"fields\":[{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"appId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"accountStatus\",\"kind\":\"enum\",\"type\":\"AccountStatus\"},{\"name\":\"tokens\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"threads\",\"kind\":\"object\",\"type\":\"Thread\",\"relationName\":\"AccountToThread\"},{\"name\":\"labels\",\"kind\":\"object\",\"type\":\"Label\",\"relationName\":\"AccountToLabel\"},{\"name\":\"profiles\",\"kind\":\"object\",\"type\":\"Profile\",\"relationName\":\"AccountToProfile\"},{\"name\":\"syncStates\",\"kind\":\"object\",\"type\":\"SyncState\",\"relationName\":\"AccountToSyncState\"},{\"name\":\"calendarLists\",\"kind\":\"object\",\"type\":\"CalendarList\",\"relationName\":\"AccountToCalendarList\"}],\"dbName\":null},\"Thread\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"appId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"threadId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"subject\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"snippet\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"fromEmail\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"fromName\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"date\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"labelIds\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"hasUnread\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"msgCount\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"historyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rawData\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"ttlMs\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"account\",\"kind\":\"object\",\"type\":\"Account\",\"relationName\":\"AccountToThread\"}],\"dbName\":null},\"Label\":{\"fields\":[{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"appId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rawData\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"ttlMs\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"account\",\"kind\":\"object\",\"type\":\"Account\",\"relationName\":\"AccountToLabel\"}],\"dbName\":null},\"Profile\":{\"fields\":[{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"appId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"emailAddress\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"messagesTotal\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"threadsTotal\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"historyId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"ttlMs\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"account\",\"kind\":\"object\",\"type\":\"Account\",\"relationName\":\"AccountToProfile\"}],\"dbName\":null},\"CalendarList\":{\"fields\":[{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"appId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"rawData\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"ttlMs\",\"kind\":\"scalar\",\"type\":\"Int\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"account\",\"kind\":\"object\",\"type\":\"Account\",\"relationName\":\"AccountToCalendarList\"}],\"dbName\":null},\"SyncState\":{\"fields\":[{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"appId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"key\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"value\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"account\",\"kind\":\"object\",\"type\":\"Account\",\"relationName\":\"AccountToSyncState\"}],\"dbName\":null}},\"enums\":{},\"types\":{}}");
|
|
30
|
-
config.parameterizationSchema = {
|
|
31
|
-
strings: JSON.parse("[\"where\",\"orderBy\",\"cursor\",\"account\",\"threads\",\"labels\",\"profiles\",\"syncStates\",\"calendarLists\",\"_count\",\"Account.findUnique\",\"Account.findUniqueOrThrow\",\"Account.findFirst\",\"Account.findFirstOrThrow\",\"Account.findMany\",\"data\",\"Account.createOne\",\"Account.createMany\",\"Account.createManyAndReturn\",\"Account.updateOne\",\"Account.updateMany\",\"Account.updateManyAndReturn\",\"create\",\"update\",\"Account.upsertOne\",\"Account.deleteOne\",\"Account.deleteMany\",\"having\",\"_min\",\"_max\",\"Account.groupBy\",\"Account.aggregate\",\"Thread.findUnique\",\"Thread.findUniqueOrThrow\",\"Thread.findFirst\",\"Thread.findFirstOrThrow\",\"Thread.findMany\",\"Thread.createOne\",\"Thread.createMany\",\"Thread.createManyAndReturn\",\"Thread.updateOne\",\"Thread.updateMany\",\"Thread.updateManyAndReturn\",\"Thread.upsertOne\",\"Thread.deleteOne\",\"Thread.deleteMany\",\"_avg\",\"_sum\",\"Thread.groupBy\",\"Thread.aggregate\",\"Label.findUnique\",\"Label.findUniqueOrThrow\",\"Label.findFirst\",\"Label.findFirstOrThrow\",\"Label.findMany\",\"Label.createOne\",\"Label.createMany\",\"Label.createManyAndReturn\",\"Label.updateOne\",\"Label.updateMany\",\"Label.updateManyAndReturn\",\"Label.upsertOne\",\"Label.deleteOne\",\"Label.deleteMany\",\"Label.groupBy\",\"Label.aggregate\",\"Profile.findUnique\",\"Profile.findUniqueOrThrow\",\"Profile.findFirst\",\"Profile.findFirstOrThrow\",\"Profile.findMany\",\"Profile.createOne\",\"Profile.createMany\",\"Profile.createManyAndReturn\",\"Profile.updateOne\",\"Profile.updateMany\",\"Profile.updateManyAndReturn\",\"Profile.upsertOne\",\"Profile.deleteOne\",\"Profile.deleteMany\",\"Profile.groupBy\",\"Profile.aggregate\",\"CalendarList.findUnique\",\"CalendarList.findUniqueOrThrow\",\"CalendarList.findFirst\",\"CalendarList.findFirstOrThrow\",\"CalendarList.findMany\",\"CalendarList.createOne\",\"CalendarList.createMany\",\"CalendarList.createManyAndReturn\",\"CalendarList.updateOne\",\"CalendarList.updateMany\",\"CalendarList.updateManyAndReturn\",\"CalendarList.upsertOne\",\"CalendarList.deleteOne\",\"CalendarList.deleteMany\",\"CalendarList.groupBy\",\"CalendarList.aggregate\",\"SyncState.findUnique\",\"SyncState.findUniqueOrThrow\",\"SyncState.findFirst\",\"SyncState.findFirstOrThrow\",\"SyncState.findMany\",\"SyncState.createOne\",\"SyncState.createMany\",\"SyncState.createManyAndReturn\",\"SyncState.updateOne\",\"SyncState.updateMany\",\"SyncState.updateManyAndReturn\",\"SyncState.upsertOne\",\"SyncState.deleteOne\",\"SyncState.deleteMany\",\"SyncState.groupBy\",\"SyncState.aggregate\",\"AND\",\"OR\",\"NOT\",\"email\",\"appId\",\"key\",\"value\",\"equals\",\"in\",\"notIn\",\"lt\",\"lte\",\"gt\",\"gte\",\"contains\",\"startsWith\",\"endsWith\",\"not\",\"rawData\",\"ttlMs\",\"createdAt\",\"email_appId\",\"emailAddress\",\"messagesTotal\",\"threadsTotal\",\"historyId\",\"id\",\"threadId\",\"subject\",\"snippet\",\"fromEmail\",\"fromName\",\"date\",\"labelIds\",\"hasUnread\",\"msgCount\",\"AccountStatus\",\"accountStatus\",\"tokens\",\"updatedAt\",\"every\",\"some\",\"none\",\"email_appId_key\",\"email_appId_threadId\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"disconnect\",\"delete\",\"connect\",\"createMany\",\"set\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"),
|
|
32
|
-
graph: "zAI6YA8EAADEAQAgBQAAxQEAIAYAAMYBACAHAADHAQAgCAAAyAEAIHIAAMIBADBzAAAUABB0AADCAQAwdQEArAEAIXYBAKwBACGGAUAArgEAIYcBAADPAQAglwEAAMMBlwEimAEBAKwBACGZAUAArgEAIQEAAAABACAUAwAArwEAIHIAAMwBADBzAAADABB0AADMAQAwdQEArAEAIXYBAKwBACGEAQEArAEAIYUBAgCtAQAhhgFAAK4BACGLAQEAzgEAIYwBAgCtAQAhjQEBAKwBACGOAQEArAEAIY8BAQCsAQAhkAEBAKwBACGRAQEArAEAIZIBAQCsAQAhkwEBAKwBACGUASAAzQEAIZUBAgCtAQAhAgMAAN8BACCLAQAA7gEAIBUDAACvAQAgcgAAzAEAMHMAAAMAEHQAAMwBADB1AQCsAQAhdgEArAEAIYQBAQCsAQAhhQECAK0BACGGAUAArgEAIYsBAQDOAQAhjAECAAAAAY0BAQCsAQAhjgEBAKwBACGPAQEArAEAIZABAQCsAQAhkQEBAKwBACGSAQEArAEAIZMBAQCsAQAhlAEgAM0BACGVAQIArQEAIZ4BAADLAQAgAwAAAAMAIAEAAAQAMAIAAAUAIAkDAACvAQAgcgAAtQEAMHMAAAcAEHQAALUBADB1AQCsAQAhdgEArAEAIYQBAQCsAQAhhQECAK0BACGGAUAArgEAIQEAAAAHACAMAwAArwEAIHIAALIBADBzAAAJABB0AACyAQAwdQEArAEAIXYBAKwBACGFAQIArQEAIYYBQACuAQAhiAEBAKwBACGJAQIArQEAIYoBAgCtAQAhiwEBAKwBACEBAAAACQAgCAMAAK8BACByAADKAQAwcwAACwAQdAAAygEAMHUBAKwBACF2AQCsAQAhdwEArAEAIXgBAKwBACEBAwAA3wEAIAkDAACvAQAgcgAAygEAMHMAAAsAEHQAAMoBADB1AQCsAQAhdgEArAEAIXcBAKwBACF4AQCsAQAhnQEAAMkBACADAAAACwAgAQAADAAwAgAADQAgCQMAAK8BACByAACrAQAwcwAADwAQdAAAqwEAMHUBAKwBACF2AQCsAQAhhAEBAKwBACGFAQIArQEAIYYBQACuAQAhAQAAAA8AIAEAAAADACABAAAACwAgAQAAAAEAIA4EAADEAQAgBQAAxQEAIAYAAMYBACAHAADHAQAgCAAAyAEAIHIAAMIBADBzAAAUABB0AADCAQAwdQEArAEAIXYBAKwBACGGAUAArgEAIZcBAADDAZcBIpgBAQCsAQAhmQFAAK4BACEFBAAArQIAIAUAAK4CACAGAACvAgAgBwAAsAIAIAgAALECACADAAAAFAAgAQAAFQAwAgAAAQAgAwAAABQAIAEAABUAMAIAAAEAIAMAAAAUACABAAAVADACAAABACALBAAAqAIAIAUAAKkCACAGAACqAgAgBwAAqwIAIAgAAKwCACB1AQAAAAF2AQAAAAGGAUAAAAABlwEAAACXAQKYAQEAAAABmQFAAAAAAQEPAAAZACAGdQEAAAABdgEAAAABhgFAAAAAAZcBAAAAlwECmAEBAAAAAZkBQAAAAAEBDwAAGwAwAQ8AABsAMAsEAAD8AQAgBQAA_QEAIAYAAP4BACAHAAD_AQAgCAAAgAIAIHUBANMBACF2AQDTAQAhhgFAANwBACGXAQAA-wGXASKYAQEA0wEAIZkBQADcAQAhAgAAAAEAIA8AAB4AIAZ1AQDTAQAhdgEA0wEAIYYBQADcAQAhlwEAAPsBlwEimAEBANMBACGZAUAA3AEAIQIAAAAUACAPAAAgACACAAAAFAAgDwAAIAAgAwAAAAEAIBYAABkAIBcAAB4AIAEAAAABACABAAAAFAAgAwkAAPgBACAcAAD6AQAgHQAA-QEAIAlyAAC-AQAwcwAAJwAQdAAAvgEAMHUBAJ8BACF2AQCfAQAhhgFAAKUBACGXAQAAvwGXASKYAQEAnwEAIZkBQAClAQAhAwAAABQAIAEAACYAMBsAACcAIAMAAAAUACABAAAVADACAAABACABAAAABQAgAQAAAAUAIAMAAAADACABAAAEADACAAAFACADAAAAAwAgAQAABAAwAgAABQAgAwAAAAMAIAEAAAQAMAIAAAUAIBEDAAD3AQAgdQEAAAABdgEAAAABhAEBAAAAAYUBAgAAAAGGAUAAAAABiwEBAAAAAYwBAgAAAAGNAQEAAAABjgEBAAAAAY8BAQAAAAGQAQEAAAABkQEBAAAAAZIBAQAAAAGTAQEAAAABlAEgAAAAAZUBAgAAAAEBDwAALwAgEHUBAAAAAXYBAAAAAYQBAQAAAAGFAQIAAAABhgFAAAAAAYsBAQAAAAGMAQIAAAABjQEBAAAAAY4BAQAAAAGPAQEAAAABkAEBAAAAAZEBAQAAAAGSAQEAAAABkwEBAAAAAZQBIAAAAAGVAQIAAAABAQ8AADEAMAEPAAAxADARAwAA9gEAIHUBANMBACF2AQDTAQAhhAEBANMBACGFAQIA2wEAIYYBQADcAQAhiwEBAPUBACGMAQIA2wEAIY0BAQDTAQAhjgEBANMBACGPAQEA0wEAIZABAQDTAQAhkQEBANMBACGSAQEA0wEAIZMBAQDTAQAhlAEgAPQBACGVAQIA2wEAIQIAAAAFACAPAAA0ACAQdQEA0wEAIXYBANMBACGEAQEA0wEAIYUBAgDbAQAhhgFAANwBACGLAQEA9QEAIYwBAgDbAQAhjQEBANMBACGOAQEA0wEAIY8BAQDTAQAhkAEBANMBACGRAQEA0wEAIZIBAQDTAQAhkwEBANMBACGUASAA9AEAIZUBAgDbAQAhAgAAAAMAIA8AADYAIAIAAAADACAPAAA2ACADAAAABQAgFgAALwAgFwAANAAgAQAAAAUAIAEAAAADACAGCQAA7wEAIBwAAPIBACAdAADxAQAgLgAA8AEAIC8AAPMBACCLAQAA7gEAIBNyAAC2AQAwcwAAPQAQdAAAtgEAMHUBAJ8BACF2AQCfAQAhhAEBAJ8BACGFAQIApAEAIYYBQAClAQAhiwEBALgBACGMAQIApAEAIY0BAQCfAQAhjgEBAJ8BACGPAQEAnwEAIZABAQCfAQAhkQEBAJ8BACGSAQEAnwEAIZMBAQCfAQAhlAEgALcBACGVAQIApAEAIQMAAAADACABAAA8ADAbAAA9ACADAAAAAwAgAQAABAAwAgAABQAgCgMAAK8BACByAAC1AQAwcwAABwAQdAAAtQEAMHUBAKwBACF2AQCsAQAhhAEBAKwBACGFAQIArQEAIYYBQACuAQAhhwEAALQBACABAAAAQAAgAQAAAEAAIAEDAADfAQAgAwAAAAcAIAEAAEMAMAIAAEAAIAMAAAAHACABAABDADACAABAACADAAAABwAgAQAAQwAwAgAAQAAgBgMAAO0BACB1AQAAAAF2AQAAAAGEAQEAAAABhQECAAAAAYYBQAAAAAEBDwAARwAgBXUBAAAAAXYBAAAAAYQBAQAAAAGFAQIAAAABhgFAAAAAAQEPAABJADABDwAASQAwBgMAAOwBACB1AQDTAQAhdgEA0wEAIYQBAQDTAQAhhQECANsBACGGAUAA3AEAIQIAAABAACAPAABMACAFdQEA0wEAIXYBANMBACGEAQEA0wEAIYUBAgDbAQAhhgFAANwBACECAAAABwAgDwAATgAgAgAAAAcAIA8AAE4AIAMAAABAACAWAABHACAXAABMACABAAAAQAAgAQAAAAcAIAUJAADnAQAgHAAA6gEAIB0AAOkBACAuAADoAQAgLwAA6wEAIAhyAACzAQAwcwAAVQAQdAAAswEAMHUBAJ8BACF2AQCfAQAhhAEBAJ8BACGFAQIApAEAIYYBQAClAQAhAwAAAAcAIAEAAFQAMBsAAFUAIAMAAAAHACABAABDADACAABAACANAwAArwEAIHIAALIBADBzAAAJABB0AACyAQAwdQEArAEAIXYBAKwBACGFAQIArQEAIYYBQACuAQAhhwEAALEBACCIAQEArAEAIYkBAgCtAQAhigECAK0BACGLAQEArAEAIQEAAABYACABAAAAWAAgAQMAAN8BACADAAAACQAgAQAAWwAwAgAAWAAgAwAAAAkAIAEAAFsAMAIAAFgAIAMAAAAJACABAABbADACAABYACAJAwAA5gEAIHUBAAAAAXYBAAAAAYUBAgAAAAGGAUAAAAABiAEBAAAAAYkBAgAAAAGKAQIAAAABiwEBAAAAAQEPAABfACAIdQEAAAABdgEAAAABhQECAAAAAYYBQAAAAAGIAQEA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-AgAAAAF_AgAAAAGDAQIAqAEAIQh5CAAAAAF6CAAAAAR7CAAAAAR8CAAAAAF9CAAAAAF-CAAAAAF_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IJsBAAALACCcAQAACwAgCwMAAK8BACByAACrAQAwcwAADwAQdAAAqwEAMHUBAKwBACF2AQCsAQAhhAEBAKwBACGFAQIArQEAIYYBQACuAQAhnwEAAA8AIKABAAAPACADdQEAAAABdgEAAAABdwEAAAABCAMAAK8BACByAADKAQAwcwAACwAQdAAAygEAMHUBAKwBACF2AQCsAQAhdwEArAEAIXgBAKwBACEDdQEAAAABdgEAAAABjQEBAAAAARQDAACvAQAgcgAAzAEAMHMAAAMAEHQAAMwBADB1AQCsAQAhdgEArAEAIYQBAQCsAQAhhQECAK0BACGGAUAArgEAIYsBAQDOAQAhjAECAK0BACGNAQEArAEAIY4BAQCsAQAhjwEBAKwBACGQAQEArAEAIZEBAQCsAQAhkgEBAKwBACGTAQEArAEAIZQBIADNAQAhlQECAK0BACECeSAAAAABgwEgAL0BACELeQEAAAABegEAAAAFewEAAAAFfAEAAAABfQEAAAABfgEAAAABfwEAAAABgAEBAAAAAYEBAQAAAAGCAQEAAAABgwEBALsBACECdQEAAAABdgEAAAABAAAAAacBAQAAAAEFFgAAyAIAIBcAAMsCACChAQAAyQIAIKIBAADKAgAgpQEAAAEAIAMWAADIAgAgoQEAAMkCACClAQAAAQAgAAAAAAAFpwECAAAAAaoBAgAAAAGrAQIAAAABrAECAAAAAa0BAgAAAAEBpwFAAAAAAQUWAADDAgAgFwAAxgIAIKEBAADEAgAgogEAAMUCACClAQAAAQAgAxYAAMMCACChAQAAxAIAIKUBAAABACAFBAAArQIAIAUAAK4CACAGAACvAgAgBwAAsAIAIAgAALECACAAAAAAAAUWAAC-AgAgFwAAwQIAIKEBAAC_AgAgogEAAMACACClAQAAAQAgAxYAAL4CACChAQAAvwIAIKUBAAABACAAAAAAAAUWAAC5AgAgFwAAvAIAIKEBAAC6AgAgogEAALsCACClAQAAAQAgAxYAALkCACChAQAAugIAIKUBAAABACAAAAAAAAABpwEgAAAAAQGnAQEAAAABBRYAALQCACAXAAC3AgAgoQEAALUCACCiAQAAtgIAIKUBAAABACADFgAAtAIAIKEBAAC1AgAgpQEAAAEAIAAAAAGnAQAAAJcBAgsWAACcAgAwFwAAoQIAMKEBAACdAgAwogEAAJ4CADCjAQAAoAIAMKQBAACgAgAwpQEAAKACADCmAQAAnwIAIKcBAACgAgAwqAEAAKICADCpAQAAowIAMAcWAACXAgAgFwAAmgIAIKEBAACYAgAgogEAAJkCACCjAQAABwAgpAEAAAcAIKUBAABAACAHFgAAkgIAIBcAAJUCACChAQAAkwIAIKIBAACUAgAgowEAAAkAIKQBAAAJACClAQAAWAAgCxYAAIYCADAXAACLAgAwoQEAAIcCADCiAQAAiAIAMKMBAACKAgAwpAEAAIoCADClAQAAigIAMKYBAACJAgAgpwEAAIoCADCoAQAAjAIAMKkBAACNAgAwBxYAAIECACAXAACEAgAgoQEAAIICACCiAQAAgwIAIKMBAAAPACCkAQAADwAgpQEAAHAAIAOEAQEAAAABhQECAAAAAYYBQAAAAAECAAAAcAAgFgAAgQIAIAMAAAAPACAWAACBAgAgFwAAhQIAIAUAAAAPACAPAACFAgAghAEBANMBACGFAQIA2wEAIYYBQADcAQAhA4QBAQDTAQAhhQECANsBACGGAUAA3AEAIQJ3AQAAAAF4AQAAAAECAAAADQAgFgAAkQIAIAMAAAANACAWAACRAgAgFwAAkAIAIAEPAACzAgAwCQMAAK8BACByAADKAQAwcwAACwAQdAAAygEAMHUBAKwBACF2AQCsAQAhdwEArAEAIXgBAKwBACGdAQAAyQEAIAIAAAANACAPAACQAgAgAgAAAI4CACAPAACPAgAgB3IAAI0CADBzAACOAgAQdAAAjQIAMHUBAKwBACF2AQCsAQAhdwEArAEAIXgBAKwBACEHcgAAjQIAMHMAAI4CABB0AACNAgAwdQEArAEAIXYBAKwBACF3AQCsAQAheAEArAEA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_QEAIAYAAP4BACAHAAD_AQAgCAAAgAIAIA8AALgCACB1AQDTAQAhdgEA0wEAIYYBQADcAQAhlwEAAPsBlwEimAEBANMBACGZAUAA3AEAIQoFAAD9AQAgBgAA_gEAIAcAAP8BACAIAACAAgAgdQEA0wEAIXYBANMBACGGAUAA3AEAIZcBAAD7AZcBIpgBAQDTAQAhmQFAANwBACEKBAAAqAIAIAYAAKoCACAHAACrAgAgCAAArAIAIHUBAAAAAXYBAAAAAYYBQAAAAAGXAQAAAJcBApgBAQAAAAGZAUAAAAABAgAAAAEAIBYAALkCACADAAAAFAAgFgAAuQIAIBcAAL0CACAMAAAAFAAgBAAA_AEAIAYAAP4BACAHAAD_AQAgCAAAgAIAIA8AAL0CACB1AQDTAQAhdgEA0wEAIYYBQADcAQAhlwEAAPsBlwEimAEBANMBACGZAUAA3AEAIQoEAAD8AQAgBgAA_gEAIAcAAP8BACAIAACAAgAgdQEA0wEAIXYBANMBACGGAUAA3AEAIZcBAAD7AZcBIpgBAQDTAQAhmQFAANwBACEKBAAAqAIAIAUAAKkCACAHAACrAgAgCAAArAIAIHUBAAAAAXYBAAAAAYYBQAAAAAGXAQAAAJcBApgBAQAAAAGZAUAAAAABAgAAAAEAIBYAAL4CACADAAAAFAAgFgAAvgIAIBcAAMICACAMAAAAFAAgBAAA_AEAIAUAAP0BACAHAAD_AQAgCAAAgAIAIA8AAMICACB1AQDTAQAhdgEA0wEAIYYBQADcAQAhlwEAAPsBlwEimAEBANMBACGZAUAA3AEAIQoEAAD8AQAgBQAA_QEAIAcAAP8BACAIAACAAgAgdQEA0wEAIXYBANMBACGGAUAA3AEAIZcBAAD7AZcBIpgBAQDTAQAhmQFAANwBACEKBAAAqAIAIAUAAKkCACAGAACqAgAgBwAAqwIAIHUBAAAAAXYBAAAAAYYBQAAAAAGXAQAAAJcBApgBAQAAAAGZAUAAAAABAgAAAAEAIBYAAMMCACADAAAAFAAgFgAAwwIAIBcAAMcCACAMAAAAFAAgBAAA_AEAIAUAAP0BACAGAAD-AQAgBwAA_wEAIA8AAMcCACB1AQDTAQAhdgEA0wEAIYYBQADcAQAhlwEAAPsBlwEimAEBANMBACGZAUAA3AEAIQoEAAD8AQAgBQAA_QEAIAYAAP4BACAHAAD_AQAgdQEA0wEAIXYBANMBACGGAUAA3AEAIZcBAAD7AZcBIpgBAQDTAQAhmQFAANwBACEKBAAAqAIAIAUAAKkCACAGAACqAgAgCAAArAIAIHUBAAAAAXYBAAAAAYYBQAAAAAGXAQAAAJcBApgBAQAAAAGZAUAAAAABAgAAAAEAIBYAAMgCACADAAAAFAAgFgAAyAIAIBcAAMwCACAMAAAAFAAgBAAA_AEAIAUAAP0BACAGAAD-AQAgCAAAgAIAIA8AAMwCACB1AQDTAQAhdgEA0wEAIYYBQADcAQAhlwEAAPsBlwEimAEBANMBACGZAUAA3AEAIQoEAAD8AQAgBQAA_QEAIAYAAP4BACAIAACAAgAgdQEA0wEAIXYBANMBACGGAUAA3AEAIZcBAAD7AZcBIpgBAQDTAQAhmQFAANwBACEGBAYCBQgDBgoEBw4FCBAGCQAHAQMAAQEDAAEBAwABAQMAAQEDAAECBBEABxIAAAAAAwkADBwADR0ADgAAAAMJAAwcAA0dAA4BAwABAQMAAQUJABMcABYdABcuABQvABUAAAAAAAUJABMcABYdABcuABQvABUBAwABAQMAAQUJABwcAB8dACAuAB0vAB4AAAAAAAUJABwcAB8dACAuAB0vAB4BAwABAQMAAQUJACUcACgdACkuACYvACcAAAAAAAUJACUcACgdACkuACYvACcBAwABAQMAAQUJAC4cADEdADIuAC8vADAAAAAAAAUJAC4cADEdADIuAC8vADABAwABAQMAAQMJADccADgdADkAAAADCQA3HAA4HQA5CgIBCxMBDBYBDRcBDhgBEBoBERwIEh0JEx8BFCEIFSIKGCMBGSQBGiUIHigLHykPICoCISsCIiwCIy0CJC4CJTACJjIIJzMQKDUCKTcIKjgRKzkCLDoCLTsIMD4SMT8YMkEDM0IDNEQDNUUDNkYDN0gDOEoIOUsZOk0DO08IPFAaPVEDPlIDP1MIQFYbQVchQlkEQ1oERFwERV0ERl4ER2AESGIISWMiSmUES2cITGgjTWkETmoET2sIUG4kUW8qUnEGU3IGVHQGVXUGVnYGV3gGWHoIWXsrWn0GW38IXIABLF2BAQZeggEGX4MBCGCGAS1hhwEzYogBBWOJAQVkigEFZYsBBWaMAQVnjgEFaJABCGmRATRqkwEFa5UBCGyWATVtlwEFbpgBBW-ZAQhwnAE2cZ0BOg"
|
|
33
|
-
};
|
|
34
26
|
async function decodeBase64AsWasm(wasmBase64) {
|
|
35
27
|
const { Buffer } = await import('node:buffer');
|
|
36
28
|
const wasmArray = Buffer.from(wasmBase64, 'base64');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class.js","sourceRoot":"","sources":["../../../src/generated/internal/class.ts"],"names":[],"mappings":"AACA,qEAAqE;AACrE,oBAAoB;AACpB,wCAAwC;AACxC,eAAe;AACf;;;;;;GAMG;AAEH,OAAO,KAAK,OAAO,MAAM,+BAA+B,CAAA;AAIxD,MAAM,MAAM,GAAkC;IAC5C,iBAAiB,EAAE,EAAE;IACrB,eAAe,EAAE,OAAO;IACxB,eAAe,EAAE,0CAA0C;IAC3D,gBAAgB,EAAE,QAAQ;IAC1B,cAAc,EAAE,+lIAA+lI;IAC/mI,kBAAkB,EAAE;QAClB,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE;KACZ;
|
|
1
|
+
{"version":3,"file":"class.js","sourceRoot":"","sources":["../../../src/generated/internal/class.ts"],"names":[],"mappings":"AACA,qEAAqE;AACrE,oBAAoB;AACpB,wCAAwC;AACxC,eAAe;AACf;;;;;;GAMG;AAEH,OAAO,KAAK,OAAO,MAAM,+BAA+B,CAAA;AAIxD,MAAM,MAAM,GAAkC;IAC5C,iBAAiB,EAAE,EAAE;IACrB,eAAe,EAAE,OAAO;IACxB,eAAe,EAAE,0CAA0C;IAC3D,gBAAgB,EAAE,QAAQ;IAC1B,cAAc,EAAE,+lIAA+lI;IAC/mI,kBAAkB,EAAE;QAClB,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,EAAE;QACX,OAAO,EAAE,EAAE;KACZ;CACF,CAAA;AAED,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,8gIAA8gI,CAAC,CAAA;AAEpjI,KAAK,UAAU,kBAAkB,CAAC,UAAkB;IAClD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;IAC9C,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;IACnD,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;AAC1C,CAAC;AAED,MAAM,CAAC,YAAY,GAAG;IACpB,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,MAAM,CAAC,0DAA0D,CAAC;IAEhG,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,sEAAsE,CAAC,CAAA;QACrG,OAAO,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACvC,CAAC;IAED,UAAU,EAAE,6BAA6B;CAC1C,CAAA;AAgMD,MAAM,UAAU,oBAAoB;IAClC,OAAO,OAAO,CAAC,eAAe,CAAC,MAAM,CAAuC,CAAA;AAC9E,CAAC"}
|
|
@@ -46,8 +46,8 @@ export type PrismaVersion = {
|
|
|
46
46
|
engine: string;
|
|
47
47
|
};
|
|
48
48
|
/**
|
|
49
|
-
* Prisma Client JS version: 7.
|
|
50
|
-
* Query Engine version:
|
|
49
|
+
* Prisma Client JS version: 7.3.0
|
|
50
|
+
* Query Engine version: 9d6ad21cbbceab97458517b147a6a09ff43aa735
|
|
51
51
|
*/
|
|
52
52
|
export declare const prismaVersion: PrismaVersion;
|
|
53
53
|
/**
|
|
@@ -36,12 +36,12 @@ export const Sql = runtime.Sql;
|
|
|
36
36
|
export const Decimal = runtime.Decimal;
|
|
37
37
|
export const getExtensionContext = runtime.Extensions.getExtensionContext;
|
|
38
38
|
/**
|
|
39
|
-
* Prisma Client JS version: 7.
|
|
40
|
-
* Query Engine version:
|
|
39
|
+
* Prisma Client JS version: 7.3.0
|
|
40
|
+
* Query Engine version: 9d6ad21cbbceab97458517b147a6a09ff43aa735
|
|
41
41
|
*/
|
|
42
42
|
export const prismaVersion = {
|
|
43
|
-
client: "7.
|
|
44
|
-
engine: "
|
|
43
|
+
client: "7.3.0",
|
|
44
|
+
engine: "9d6ad21cbbceab97458517b147a6a09ff43aa735"
|
|
45
45
|
};
|
|
46
46
|
export const NullTypes = {
|
|
47
47
|
DbNull: runtime.NullTypes.DbNull,
|
package/dist/gmail-client.d.ts
CHANGED
|
@@ -251,7 +251,7 @@ export declare class GmailClient {
|
|
|
251
251
|
count: number;
|
|
252
252
|
} | AuthError | ApiError>;
|
|
253
253
|
listLabels(): Promise<{
|
|
254
|
-
parsed: ReturnType<
|
|
254
|
+
parsed: ReturnType<GmailClient['parseLabels']>;
|
|
255
255
|
raw: gmail_v1.Schema$Label[];
|
|
256
256
|
} | AuthError | ApiError>;
|
|
257
257
|
getLabel({ labelId }: {
|
|
@@ -301,13 +301,14 @@ export declare class GmailClient {
|
|
|
301
301
|
historyId: string;
|
|
302
302
|
} | AuthError | ApiError>;
|
|
303
303
|
/** Parse a raw gmail_v1.Schema$Thread (format: full) into ThreadData. */
|
|
304
|
-
|
|
304
|
+
parseThread(raw: gmail_v1.Schema$Thread): ThreadData;
|
|
305
305
|
/** Parse a raw gmail_v1.Schema$Message into ParsedMessage. */
|
|
306
|
-
|
|
307
|
-
/** Parse raw gmail_v1.Schema$Thread (format: metadata) into ThreadListItem.
|
|
308
|
-
|
|
306
|
+
parseMessage(message: gmail_v1.Schema$Message): ParsedMessage;
|
|
307
|
+
/** Parse raw gmail_v1.Schema$Thread (format: metadata) into ThreadListItem.
|
|
308
|
+
* Shows the other party in conversations where user sent the latest message. */
|
|
309
|
+
parseThreadListItem(raw: gmail_v1.Schema$Thread): ThreadListItem;
|
|
309
310
|
/** Parse raw gmail_v1.Schema$Label[] from labels.list into our label objects. */
|
|
310
|
-
|
|
311
|
+
parseLabels(rawLabels: gmail_v1.Schema$Label[]): {
|
|
311
312
|
id: string;
|
|
312
313
|
name: string;
|
|
313
314
|
type: "system" | "user";
|
|
@@ -319,13 +320,13 @@ export declare class GmailClient {
|
|
|
319
320
|
} | null;
|
|
320
321
|
}[];
|
|
321
322
|
/** Parse raw gmail_v1.Schema$Label[] (with counts) into label count objects. */
|
|
322
|
-
|
|
323
|
+
parseLabelCounts(rawLabels: gmail_v1.Schema$Label[], archiveEstimate: number | null): {
|
|
323
324
|
label: string;
|
|
324
325
|
count: number;
|
|
325
326
|
}[];
|
|
326
|
-
private
|
|
327
|
-
private
|
|
328
|
-
private
|
|
327
|
+
private extractBody;
|
|
328
|
+
private findBodyPart;
|
|
329
|
+
private extractAttachmentMeta;
|
|
329
330
|
getEmailAliases(): Promise<Array<{
|
|
330
331
|
email: string;
|
|
331
332
|
name?: string;
|
|
@@ -353,8 +354,6 @@ export declare class GmailClient {
|
|
|
353
354
|
}): AsyncGenerator<WatchEvent>;
|
|
354
355
|
/** Single poll tick from pre-fetched history — yields WatchEvents for new messages. */
|
|
355
356
|
private pollOnceFromHistory;
|
|
356
|
-
private parseMessage;
|
|
357
|
-
private parseThreadListItem;
|
|
358
357
|
private buildMimeMessage;
|
|
359
358
|
/** Look up a label ID by name. Returns null if not found (never creates). */
|
|
360
359
|
private lookupLabelId;
|
package/dist/gmail-client.js
CHANGED
|
@@ -226,7 +226,7 @@ export class GmailClient {
|
|
|
226
226
|
const cached = await this.getCachedThread(t.id);
|
|
227
227
|
if (cached && (!t.historyId || !cached.historyId || t.historyId === cached.historyId)) {
|
|
228
228
|
return {
|
|
229
|
-
parsed:
|
|
229
|
+
parsed: this.parseThreadListItem(cached),
|
|
230
230
|
raw: cached,
|
|
231
231
|
};
|
|
232
232
|
}
|
|
@@ -240,10 +240,10 @@ export class GmailClient {
|
|
|
240
240
|
return detail;
|
|
241
241
|
if (detail instanceof Error)
|
|
242
242
|
return null;
|
|
243
|
-
const parsed =
|
|
243
|
+
const parsed = this.parseThread(detail.data);
|
|
244
244
|
await this.cacheThreadData(t.id, detail.data, parsed);
|
|
245
245
|
return {
|
|
246
|
-
parsed:
|
|
246
|
+
parsed: this.parseThreadListItem(detail.data),
|
|
247
247
|
raw: detail.data,
|
|
248
248
|
};
|
|
249
249
|
});
|
|
@@ -262,14 +262,14 @@ export class GmailClient {
|
|
|
262
262
|
// Check cache
|
|
263
263
|
const cached = await this.getCachedThread(threadId);
|
|
264
264
|
if (cached) {
|
|
265
|
-
return { parsed:
|
|
265
|
+
return { parsed: this.parseThread(cached), raw: cached };
|
|
266
266
|
}
|
|
267
267
|
const res = await withRetry(() => this.gmail.users.threads.get({
|
|
268
268
|
userId: 'me',
|
|
269
269
|
id: threadId,
|
|
270
270
|
format: 'full',
|
|
271
271
|
}));
|
|
272
|
-
const parsed =
|
|
272
|
+
const parsed = this.parseThread(res.data);
|
|
273
273
|
const result = { parsed, raw: res.data };
|
|
274
274
|
// Write cache
|
|
275
275
|
await this.cacheThreadData(threadId, res.data, parsed);
|
|
@@ -618,7 +618,7 @@ export class GmailClient {
|
|
|
618
618
|
// Check cache
|
|
619
619
|
const cached = await this.getCachedLabels();
|
|
620
620
|
if (cached) {
|
|
621
|
-
return { parsed:
|
|
621
|
+
return { parsed: this.parseLabels(cached), raw: cached };
|
|
622
622
|
}
|
|
623
623
|
const res = await gmailBoundary(this.account?.email ?? 'unknown', () => withRetry(() => this.gmail.users.labels.list({ userId: 'me' })));
|
|
624
624
|
if (res instanceof Error)
|
|
@@ -626,7 +626,7 @@ export class GmailClient {
|
|
|
626
626
|
const rawLabels = res.data.labels ?? [];
|
|
627
627
|
// Write cache
|
|
628
628
|
await this.cacheLabelsData(rawLabels);
|
|
629
|
-
return { parsed:
|
|
629
|
+
return { parsed: this.parseLabels(rawLabels), raw: rawLabels };
|
|
630
630
|
}
|
|
631
631
|
async getLabel({ labelId }) {
|
|
632
632
|
const res = await withRetry(() => this.gmail.users.labels.get({
|
|
@@ -760,11 +760,11 @@ export class GmailClient {
|
|
|
760
760
|
return profile;
|
|
761
761
|
}
|
|
762
762
|
// =========================================================================
|
|
763
|
-
//
|
|
763
|
+
// Parsing: raw Google API responses → typed objects
|
|
764
764
|
// =========================================================================
|
|
765
765
|
/** Parse a raw gmail_v1.Schema$Thread (format: full) into ThreadData. */
|
|
766
|
-
|
|
767
|
-
const messages = (raw.messages ?? []).map((m) =>
|
|
766
|
+
parseThread(raw) {
|
|
767
|
+
const messages = (raw.messages ?? []).map((m) => this.parseMessage(m));
|
|
768
768
|
if (messages.length === 0) {
|
|
769
769
|
return {
|
|
770
770
|
id: raw.id ?? '',
|
|
@@ -795,7 +795,7 @@ export class GmailClient {
|
|
|
795
795
|
};
|
|
796
796
|
}
|
|
797
797
|
/** Parse a raw gmail_v1.Schema$Message into ParsedMessage. */
|
|
798
|
-
|
|
798
|
+
parseMessage(message) {
|
|
799
799
|
const headers = message.payload?.headers ?? [];
|
|
800
800
|
const labelIds = message.labelIds ?? [];
|
|
801
801
|
const getHeader = (name) => headers.find((h) => h.name?.toLowerCase() === name.toLowerCase())?.value ?? null;
|
|
@@ -805,7 +805,7 @@ export class GmailClient {
|
|
|
805
805
|
.filter((h) => h.name?.toLowerCase() === 'cc')
|
|
806
806
|
.map((h) => h.value ?? '')
|
|
807
807
|
.filter((v) => v.length > 0);
|
|
808
|
-
const { body, mimeType, textBody } =
|
|
808
|
+
const { body, mimeType, textBody } = this.extractBody(message.payload ?? {});
|
|
809
809
|
return {
|
|
810
810
|
id: message.id ?? '',
|
|
811
811
|
threadId: message.threadId ?? '',
|
|
@@ -830,30 +830,55 @@ export class GmailClient {
|
|
|
830
830
|
body,
|
|
831
831
|
mimeType,
|
|
832
832
|
textBody,
|
|
833
|
-
attachments:
|
|
833
|
+
attachments: this.extractAttachmentMeta(message.payload?.parts ?? []),
|
|
834
834
|
};
|
|
835
835
|
}
|
|
836
|
-
/** Parse raw gmail_v1.Schema$Thread (format: metadata) into ThreadListItem.
|
|
837
|
-
|
|
836
|
+
/** Parse raw gmail_v1.Schema$Thread (format: metadata) into ThreadListItem.
|
|
837
|
+
* Shows the other party in conversations where user sent the latest message. */
|
|
838
|
+
parseThreadListItem(raw) {
|
|
838
839
|
const messages = raw.messages ?? [];
|
|
839
|
-
const
|
|
840
|
+
const nonDraftMessages = messages.filter((m) => !m.labelIds?.includes('DRAFT'));
|
|
841
|
+
const latest = nonDraftMessages[nonDraftMessages.length - 1] ?? messages[messages.length - 1];
|
|
840
842
|
const headers = latest?.payload?.headers ?? [];
|
|
841
843
|
const allLabels = [...new Set(messages.flatMap((m) => m.labelIds ?? []))];
|
|
842
844
|
const getHeader = (name) => headers.find((h) => h.name?.toLowerCase() === name.toLowerCase())?.value ?? null;
|
|
845
|
+
// Determine display sender — show other party when user sent the latest message
|
|
846
|
+
let displayFrom = parseFrom(getHeader('from') ?? '');
|
|
847
|
+
const latestIsFromUser = latest?.labelIds?.includes('SENT') ?? false;
|
|
848
|
+
if (latestIsFromUser && this.account?.email) {
|
|
849
|
+
const getMsgHeader = (msg, name) => msg.payload?.headers?.find((h) => h.name?.toLowerCase() === name.toLowerCase())?.value ?? null;
|
|
850
|
+
// Find most recent message NOT from the user
|
|
851
|
+
const otherPartyMsg = nonDraftMessages.findLast((m) => !m.labelIds?.includes('SENT'));
|
|
852
|
+
if (otherPartyMsg) {
|
|
853
|
+
const fromHeader = getMsgHeader(otherPartyMsg, 'from');
|
|
854
|
+
if (fromHeader)
|
|
855
|
+
displayFrom = parseFrom(fromHeader);
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
// All messages from user — show first recipient
|
|
859
|
+
const firstMsg = nonDraftMessages[0] ?? messages[0];
|
|
860
|
+
if (firstMsg) {
|
|
861
|
+
const toHeader = getMsgHeader(firstMsg, 'to') ?? '';
|
|
862
|
+
const recipients = parseAddressList(toHeader);
|
|
863
|
+
if (recipients[0])
|
|
864
|
+
displayFrom = recipients[0];
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
843
868
|
return {
|
|
844
869
|
id: raw.id ?? '',
|
|
845
870
|
historyId: raw.historyId ?? null,
|
|
846
871
|
snippet: sanitizeSnippet(latest?.snippet ?? ''),
|
|
847
872
|
subject: (getHeader('subject') ?? '(no subject)').replace(/"/g, '').trim(),
|
|
848
|
-
from:
|
|
873
|
+
from: displayFrom,
|
|
849
874
|
date: getHeader('date') ?? '',
|
|
850
875
|
labelIds: allLabels,
|
|
851
876
|
unread: allLabels.includes('UNREAD'),
|
|
852
|
-
messageCount:
|
|
877
|
+
messageCount: nonDraftMessages.length,
|
|
853
878
|
};
|
|
854
879
|
}
|
|
855
880
|
/** Parse raw gmail_v1.Schema$Label[] from labels.list into our label objects. */
|
|
856
|
-
|
|
881
|
+
parseLabels(rawLabels) {
|
|
857
882
|
return rawLabels.map((label) => ({
|
|
858
883
|
id: label.id ?? '',
|
|
859
884
|
name: label.name ?? '',
|
|
@@ -869,9 +894,8 @@ export class GmailClient {
|
|
|
869
894
|
}));
|
|
870
895
|
}
|
|
871
896
|
/** Parse raw gmail_v1.Schema$Label[] (with counts) into label count objects. */
|
|
872
|
-
|
|
873
|
-
const result = rawLabels
|
|
874
|
-
.map((detail) => {
|
|
897
|
+
parseLabelCounts(rawLabels, archiveEstimate) {
|
|
898
|
+
const result = rawLabels.map((detail) => {
|
|
875
899
|
const labelName = (detail.name ?? detail.id ?? '').toLowerCase();
|
|
876
900
|
const isTotalLabel = labelName === 'draft' || labelName === 'sent';
|
|
877
901
|
return {
|
|
@@ -885,9 +909,9 @@ export class GmailClient {
|
|
|
885
909
|
return result;
|
|
886
910
|
}
|
|
887
911
|
// =========================================================================
|
|
888
|
-
// Private
|
|
912
|
+
// Private: body/attachment extraction
|
|
889
913
|
// =========================================================================
|
|
890
|
-
|
|
914
|
+
extractBody(payload) {
|
|
891
915
|
if (payload.body?.data) {
|
|
892
916
|
const mime = payload.mimeType ?? 'text/plain';
|
|
893
917
|
return {
|
|
@@ -899,8 +923,8 @@ export class GmailClient {
|
|
|
899
923
|
if (!payload.parts) {
|
|
900
924
|
return { body: '', mimeType: 'text/plain', textBody: null };
|
|
901
925
|
}
|
|
902
|
-
const htmlData =
|
|
903
|
-
const textData =
|
|
926
|
+
const htmlData = this.findBodyPart(payload.parts, 'text/html');
|
|
927
|
+
const textData = this.findBodyPart(payload.parts, 'text/plain');
|
|
904
928
|
const textBody = textData ? decodeBase64Url(textData) : null;
|
|
905
929
|
if (htmlData) {
|
|
906
930
|
return { body: decodeBase64Url(htmlData), mimeType: 'text/html', textBody };
|
|
@@ -910,27 +934,27 @@ export class GmailClient {
|
|
|
910
934
|
}
|
|
911
935
|
for (const part of payload.parts) {
|
|
912
936
|
if (part.parts) {
|
|
913
|
-
const nested =
|
|
937
|
+
const nested = this.extractBody(part);
|
|
914
938
|
if (nested.body)
|
|
915
939
|
return nested;
|
|
916
940
|
}
|
|
917
941
|
}
|
|
918
942
|
return { body: '', mimeType: 'text/plain', textBody: null };
|
|
919
943
|
}
|
|
920
|
-
|
|
944
|
+
findBodyPart(parts, mimeType) {
|
|
921
945
|
for (const part of parts) {
|
|
922
946
|
if (part.mimeType === mimeType && part.body?.data) {
|
|
923
947
|
return part.body.data;
|
|
924
948
|
}
|
|
925
949
|
if (part.parts) {
|
|
926
|
-
const found =
|
|
950
|
+
const found = this.findBodyPart(part.parts, mimeType);
|
|
927
951
|
if (found)
|
|
928
952
|
return found;
|
|
929
953
|
}
|
|
930
954
|
}
|
|
931
955
|
return null;
|
|
932
956
|
}
|
|
933
|
-
|
|
957
|
+
extractAttachmentMeta(parts) {
|
|
934
958
|
const results = [];
|
|
935
959
|
for (const part of parts) {
|
|
936
960
|
if (part.filename && part.filename.length > 0 && part.body?.attachmentId) {
|
|
@@ -947,7 +971,7 @@ export class GmailClient {
|
|
|
947
971
|
}
|
|
948
972
|
}
|
|
949
973
|
if (part.parts) {
|
|
950
|
-
results.push(...
|
|
974
|
+
results.push(...this.extractAttachmentMeta(part.parts));
|
|
951
975
|
}
|
|
952
976
|
}
|
|
953
977
|
return results;
|
|
@@ -1115,15 +1139,6 @@ export class GmailClient {
|
|
|
1115
1139
|
}
|
|
1116
1140
|
}
|
|
1117
1141
|
// =========================================================================
|
|
1118
|
-
// Private: message parsing (delegates to static methods)
|
|
1119
|
-
// =========================================================================
|
|
1120
|
-
parseMessage(message) {
|
|
1121
|
-
return GmailClient.parseRawMessage(message);
|
|
1122
|
-
}
|
|
1123
|
-
parseThreadListItem(threadId, thread) {
|
|
1124
|
-
return GmailClient.parseRawThreadListItem({ ...thread, id: threadId });
|
|
1125
|
-
}
|
|
1126
|
-
// =========================================================================
|
|
1127
1142
|
// Private: MIME message construction
|
|
1128
1143
|
// =========================================================================
|
|
1129
1144
|
buildMimeMessage({ to, subject, body, cc, bcc, inReplyTo, references, attachments, fromEmail, }) {
|