emulate 0.4.0 → 0.5.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/README.md +59 -10
- package/dist/api.d.ts +2 -1
- package/dist/api.js +232 -96
- package/dist/api.js.map +1 -1
- package/dist/{chunk-TEPNEZ63.js → chunk-AQ2CLRU3.js} +26 -23
- package/dist/chunk-AQ2CLRU3.js.map +1 -0
- package/dist/chunk-WVQMFHQM.js +83 -0
- package/dist/chunk-WVQMFHQM.js.map +1 -0
- package/dist/{dist-RDFBZ5O6.js → dist-4X2KPMAJ.js} +212 -47
- package/dist/dist-4X2KPMAJ.js.map +1 -0
- package/dist/{dist-OTJZRQ3Q.js → dist-5JVGPOL3.js} +217 -75
- package/dist/dist-5JVGPOL3.js.map +1 -0
- package/dist/{dist-G7WQPZ3Y.js → dist-CE6BUCWQ.js} +211 -60
- package/dist/dist-CE6BUCWQ.js.map +1 -0
- package/dist/{dist-6JFNJPUU.js → dist-CFST4X4K.js} +172 -22
- package/dist/dist-CFST4X4K.js.map +1 -0
- package/dist/{dist-YOVM5HEY.js → dist-ENKE2S7V.js} +521 -60
- package/dist/dist-ENKE2S7V.js.map +1 -0
- package/dist/{dist-RMK3BS5M.js → dist-ETHHYBGF.js} +197 -33
- package/dist/dist-ETHHYBGF.js.map +1 -0
- package/dist/{dist-QMOJM6DV.js → dist-IBXD3O6A.js} +239 -54
- package/dist/dist-IBXD3O6A.js.map +1 -0
- package/dist/dist-J6LHUR52.js +1899 -0
- package/dist/dist-J6LHUR52.js.map +1 -0
- package/dist/{dist-6EW7SSOZ.js → dist-KKTYBE5S.js} +391 -222
- package/dist/dist-KKTYBE5S.js.map +1 -0
- package/dist/{dist-VVXVP5EZ.js → dist-LDUHEJAN.js} +553 -91
- package/dist/dist-LDUHEJAN.js.map +1 -0
- package/dist/{dist-B674PYKV.js → dist-PWGOAQC6.js} +22 -43
- package/dist/dist-PWGOAQC6.js.map +1 -0
- package/dist/{dist-H6JYGQM4.js → dist-REDHDZ3V.js} +272 -157
- package/dist/dist-REDHDZ3V.js.map +1 -0
- package/dist/fonts/favicon.ico +0 -0
- package/dist/helpers-LXLP3DFE-LBOTATT5.js +17 -0
- package/dist/helpers-LXLP3DFE-LBOTATT5.js.map +1 -0
- package/dist/index.js +365 -108
- package/dist/index.js.map +1 -1
- package/package.json +17 -14
- package/dist/chunk-TEPNEZ63.js.map +0 -1
- package/dist/dist-6EW7SSOZ.js.map +0 -1
- package/dist/dist-6JFNJPUU.js.map +0 -1
- package/dist/dist-B674PYKV.js.map +0 -1
- package/dist/dist-G7WQPZ3Y.js.map +0 -1
- package/dist/dist-H6JYGQM4.js.map +0 -1
- package/dist/dist-OTJZRQ3Q.js.map +0 -1
- package/dist/dist-QMOJM6DV.js.map +0 -1
- package/dist/dist-RDFBZ5O6.js.map +0 -1
- package/dist/dist-RMK3BS5M.js.map +0 -1
- package/dist/dist-VVXVP5EZ.js.map +0 -1
- package/dist/dist-YOVM5HEY.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SignJWT
|
|
3
3
|
} from "./chunk-D6EKRYGP.js";
|
|
4
|
-
import "./chunk-
|
|
4
|
+
import "./chunk-AQ2CLRU3.js";
|
|
5
5
|
|
|
6
6
|
// ../@emulators/google/dist/index.js
|
|
7
7
|
import { randomBytes } from "crypto";
|
|
@@ -134,9 +134,7 @@ function parseBooleanParam(value) {
|
|
|
134
134
|
return value === "true" || value === "1";
|
|
135
135
|
}
|
|
136
136
|
function ensureSystemLabels(gs, userEmail) {
|
|
137
|
-
const existingIds = new Set(
|
|
138
|
-
gs.labels.findBy("user_email", userEmail).map((row) => row.gmail_id)
|
|
139
|
-
);
|
|
137
|
+
const existingIds = new Set(gs.labels.findBy("user_email", userEmail).map((row) => row.gmail_id));
|
|
140
138
|
for (const label of SYSTEM_LABELS) {
|
|
141
139
|
if (existingIds.has(label.gmail_id)) continue;
|
|
142
140
|
gs.labels.insert({
|
|
@@ -481,9 +479,7 @@ function getCurrentHistoryId(gs, userEmail) {
|
|
|
481
479
|
...gs.history.findBy("user_email", userEmail).map((event) => event.gmail_id)
|
|
482
480
|
].filter(Boolean);
|
|
483
481
|
if (historyIds.length === 0) return "0";
|
|
484
|
-
return historyIds.reduce(
|
|
485
|
-
(latest, current) => compareHistoryIds(current, latest) > 0 ? current : latest
|
|
486
|
-
);
|
|
482
|
+
return historyIds.reduce((latest, current) => compareHistoryIds(current, latest) > 0 ? current : latest);
|
|
487
483
|
}
|
|
488
484
|
function listHistoryForUser(gs, userEmail, options) {
|
|
489
485
|
const requestedTypes = options.historyTypes?.length ? new Set(options.historyTypes) : null;
|
|
@@ -1066,10 +1062,7 @@ function buildPayload(gs, message, headers, format) {
|
|
|
1066
1062
|
filename: "",
|
|
1067
1063
|
headers,
|
|
1068
1064
|
body: { size: 0 },
|
|
1069
|
-
parts: [
|
|
1070
|
-
createTextBodyPart("0", "text/plain", textBody),
|
|
1071
|
-
createTextBodyPart("1", "text/html", htmlBody)
|
|
1072
|
-
]
|
|
1065
|
+
parts: [createTextBodyPart("0", "text/plain", textBody), createTextBodyPart("1", "text/html", htmlBody)]
|
|
1073
1066
|
};
|
|
1074
1067
|
}
|
|
1075
1068
|
if (htmlBody) return createTextBodyPart("", "text/html", htmlBody, headers);
|
|
@@ -1090,10 +1083,7 @@ function buildPayload(gs, message, headers, format) {
|
|
|
1090
1083
|
filename: "",
|
|
1091
1084
|
headers: [],
|
|
1092
1085
|
body: { size: 0 },
|
|
1093
|
-
parts: [
|
|
1094
|
-
createTextBodyPart("0.0", "text/plain", textBody),
|
|
1095
|
-
createTextBodyPart("0.1", "text/html", htmlBody)
|
|
1096
|
-
]
|
|
1086
|
+
parts: [createTextBodyPart("0.0", "text/plain", textBody), createTextBodyPart("0.1", "text/html", htmlBody)]
|
|
1097
1087
|
});
|
|
1098
1088
|
} else if (htmlBody) {
|
|
1099
1089
|
parts.push(createTextBodyPart("0", "text/html", htmlBody));
|
|
@@ -1191,18 +1181,10 @@ function buildMimeBodyPart(input) {
|
|
|
1191
1181
|
].join("\r\n");
|
|
1192
1182
|
}
|
|
1193
1183
|
if (input.body_html) {
|
|
1194
|
-
return [
|
|
1195
|
-
"Content-Type: text/html; charset=utf-8",
|
|
1196
|
-
"",
|
|
1197
|
-
input.body_html
|
|
1198
|
-
].join("\r\n");
|
|
1184
|
+
return ["Content-Type: text/html; charset=utf-8", "", input.body_html].join("\r\n");
|
|
1199
1185
|
}
|
|
1200
1186
|
if (input.body_text) {
|
|
1201
|
-
return [
|
|
1202
|
-
"Content-Type: text/plain; charset=utf-8",
|
|
1203
|
-
"",
|
|
1204
|
-
input.body_text
|
|
1205
|
-
].join("\r\n");
|
|
1187
|
+
return ["Content-Type: text/plain; charset=utf-8", "", input.body_text].join("\r\n");
|
|
1206
1188
|
}
|
|
1207
1189
|
return null;
|
|
1208
1190
|
}
|
|
@@ -1798,7 +1780,7 @@ function requireGmailUser(c) {
|
|
|
1798
1780
|
if (authEmail instanceof Response) {
|
|
1799
1781
|
return authEmail;
|
|
1800
1782
|
}
|
|
1801
|
-
if (!matchesRequestedUser(c.req.param("userId"), authEmail)) {
|
|
1783
|
+
if (!matchesRequestedUser(c.req.param("userId") ?? "", authEmail)) {
|
|
1802
1784
|
return googleApiError(c, 404, "Requested entity was not found.", "notFound", "NOT_FOUND");
|
|
1803
1785
|
}
|
|
1804
1786
|
return authEmail;
|
|
@@ -1928,14 +1910,25 @@ function getGoogleStore(store) {
|
|
|
1928
1910
|
oauthClients: store.collection("google.oauth_clients", ["client_id"]),
|
|
1929
1911
|
messages: store.collection("google.messages", ["gmail_id", "thread_id", "user_email"]),
|
|
1930
1912
|
drafts: store.collection("google.drafts", ["gmail_id", "message_gmail_id", "user_email"]),
|
|
1931
|
-
attachments: store.collection("google.attachments", [
|
|
1913
|
+
attachments: store.collection("google.attachments", [
|
|
1914
|
+
"gmail_id",
|
|
1915
|
+
"message_gmail_id",
|
|
1916
|
+
"user_email"
|
|
1917
|
+
]),
|
|
1932
1918
|
history: store.collection("google.history", ["gmail_id", "message_gmail_id", "user_email"]),
|
|
1933
1919
|
labels: store.collection("google.labels", ["gmail_id", "user_email", "name"]),
|
|
1934
1920
|
filters: store.collection("google.filters", ["gmail_id", "user_email"]),
|
|
1935
|
-
forwardingAddresses: store.collection("google.forwarding_addresses", [
|
|
1921
|
+
forwardingAddresses: store.collection("google.forwarding_addresses", [
|
|
1922
|
+
"user_email",
|
|
1923
|
+
"forwarding_email"
|
|
1924
|
+
]),
|
|
1936
1925
|
sendAs: store.collection("google.send_as", ["user_email", "send_as_email"]),
|
|
1937
1926
|
calendars: store.collection("google.calendars", ["google_id", "user_email"]),
|
|
1938
|
-
calendarEvents: store.collection("google.calendar_events", [
|
|
1927
|
+
calendarEvents: store.collection("google.calendar_events", [
|
|
1928
|
+
"google_id",
|
|
1929
|
+
"calendar_google_id",
|
|
1930
|
+
"user_email"
|
|
1931
|
+
]),
|
|
1939
1932
|
driveItems: store.collection("google.drive_items", ["google_id", "user_email", "mime_type"])
|
|
1940
1933
|
};
|
|
1941
1934
|
}
|
|
@@ -2037,13 +2030,7 @@ function draftRoutes({ app, store }) {
|
|
|
2037
2030
|
});
|
|
2038
2031
|
return c.json(formatDraftResource(gs, draft, "full"));
|
|
2039
2032
|
} catch {
|
|
2040
|
-
return googleApiError(
|
|
2041
|
-
c,
|
|
2042
|
-
400,
|
|
2043
|
-
"Invalid raw MIME message payload.",
|
|
2044
|
-
"invalidArgument",
|
|
2045
|
-
"INVALID_ARGUMENT"
|
|
2046
|
-
);
|
|
2033
|
+
return googleApiError(c, 400, "Invalid raw MIME message payload.", "invalidArgument", "INVALID_ARGUMENT");
|
|
2047
2034
|
}
|
|
2048
2035
|
};
|
|
2049
2036
|
const sendHandler = async (c) => {
|
|
@@ -2133,13 +2120,7 @@ function draftRoutes({ app, store }) {
|
|
|
2133
2120
|
}
|
|
2134
2121
|
return c.json(formatDraftResource(gs, updated.draft, "full"));
|
|
2135
2122
|
} catch {
|
|
2136
|
-
return googleApiError(
|
|
2137
|
-
c,
|
|
2138
|
-
400,
|
|
2139
|
-
"Invalid raw MIME message payload.",
|
|
2140
|
-
"invalidArgument",
|
|
2141
|
-
"INVALID_ARGUMENT"
|
|
2142
|
-
);
|
|
2123
|
+
return googleApiError(c, 400, "Invalid raw MIME message payload.", "invalidArgument", "INVALID_ARGUMENT");
|
|
2143
2124
|
}
|
|
2144
2125
|
});
|
|
2145
2126
|
app.post("/gmail/v1/users/:userId/drafts/send", sendHandler);
|
|
@@ -2273,7 +2254,13 @@ function historyRoutes({ app, store }) {
|
|
|
2273
2254
|
const labelIds = getStringArray(body, "labelIds");
|
|
2274
2255
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, labelIds);
|
|
2275
2256
|
if (missingLabelIds.length > 0) {
|
|
2276
|
-
return googleApiError(
|
|
2257
|
+
return googleApiError(
|
|
2258
|
+
c,
|
|
2259
|
+
400,
|
|
2260
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
2261
|
+
"invalidArgument",
|
|
2262
|
+
"INVALID_ARGUMENT"
|
|
2263
|
+
);
|
|
2277
2264
|
}
|
|
2278
2265
|
const expiration = String(Date.now() + 24 * 60 * 60 * 1e3);
|
|
2279
2266
|
const states = store.getData(WATCH_STATE_KEY) ?? /* @__PURE__ */ new Map();
|
|
@@ -2325,13 +2312,7 @@ function labelRoutes({ app, store }) {
|
|
|
2325
2312
|
return googleApiError(c, 400, "Invalid label name", "invalidArgument", "INVALID_ARGUMENT");
|
|
2326
2313
|
}
|
|
2327
2314
|
if (findLabelByName(gs, authEmail, name)) {
|
|
2328
|
-
return googleApiError(
|
|
2329
|
-
c,
|
|
2330
|
-
400,
|
|
2331
|
-
"Label name exists or conflicts",
|
|
2332
|
-
"failedPrecondition",
|
|
2333
|
-
"FAILED_PRECONDITION"
|
|
2334
|
-
);
|
|
2315
|
+
return googleApiError(c, 400, "Label name exists or conflicts", "failedPrecondition", "FAILED_PRECONDITION");
|
|
2335
2316
|
}
|
|
2336
2317
|
const color = body.color && typeof body.color === "object" && !Array.isArray(body.color) ? body.color : void 0;
|
|
2337
2318
|
const label = createLabelRecord(gs, {
|
|
@@ -2389,13 +2370,7 @@ async function saveLabel(c, gs, replaceMissingFields) {
|
|
|
2389
2370
|
if (name) {
|
|
2390
2371
|
const conflicting = findLabelByName(gs, authEmail, name);
|
|
2391
2372
|
if (conflicting && conflicting.gmail_id !== label.gmail_id) {
|
|
2392
|
-
return googleApiError(
|
|
2393
|
-
c,
|
|
2394
|
-
400,
|
|
2395
|
-
"Label name exists or conflicts",
|
|
2396
|
-
"failedPrecondition",
|
|
2397
|
-
"FAILED_PRECONDITION"
|
|
2398
|
-
);
|
|
2373
|
+
return googleApiError(c, 400, "Label name exists or conflicts", "failedPrecondition", "FAILED_PRECONDITION");
|
|
2399
2374
|
}
|
|
2400
2375
|
}
|
|
2401
2376
|
const updated = updateLabelRecord(gs, label, {
|
|
@@ -2417,7 +2392,13 @@ function messageRoutes({ app, store }) {
|
|
|
2417
2392
|
const defaultLabelIds = mode === "send" ? dedupeLabelIds([...labelIds, "SENT"]) : labelIds.length > 0 ? labelIds : mode === "import" ? ["INBOX", "UNREAD"] : [];
|
|
2418
2393
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, defaultLabelIds);
|
|
2419
2394
|
if (missingLabelIds.length > 0) {
|
|
2420
|
-
return googleApiError(
|
|
2395
|
+
return googleApiError(
|
|
2396
|
+
c,
|
|
2397
|
+
400,
|
|
2398
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
2399
|
+
"invalidArgument",
|
|
2400
|
+
"INVALID_ARGUMENT"
|
|
2401
|
+
);
|
|
2421
2402
|
}
|
|
2422
2403
|
const messageInput = parseMessageInputFromBody(body, {
|
|
2423
2404
|
from: mode === "send" ? authEmail : void 0
|
|
@@ -2439,13 +2420,7 @@ function messageRoutes({ app, store }) {
|
|
|
2439
2420
|
});
|
|
2440
2421
|
return c.json(formatMessageResource(gs, message, "full"));
|
|
2441
2422
|
} catch {
|
|
2442
|
-
return googleApiError(
|
|
2443
|
-
c,
|
|
2444
|
-
400,
|
|
2445
|
-
"Invalid raw MIME message payload.",
|
|
2446
|
-
"invalidArgument",
|
|
2447
|
-
"INVALID_ARGUMENT"
|
|
2448
|
-
);
|
|
2423
|
+
return googleApiError(c, 400, "Invalid raw MIME message payload.", "invalidArgument", "INVALID_ARGUMENT");
|
|
2449
2424
|
}
|
|
2450
2425
|
};
|
|
2451
2426
|
app.get("/gmail/v1/users/:userId/messages", (c) => {
|
|
@@ -2479,16 +2454,18 @@ function messageRoutes({ app, store }) {
|
|
|
2479
2454
|
const removeLabelIds = getStringArray(body, "removeLabelIds");
|
|
2480
2455
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, [...addLabelIds, ...removeLabelIds]);
|
|
2481
2456
|
if (missingLabelIds.length > 0) {
|
|
2482
|
-
return googleApiError(
|
|
2457
|
+
return googleApiError(
|
|
2458
|
+
c,
|
|
2459
|
+
400,
|
|
2460
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
2461
|
+
"invalidArgument",
|
|
2462
|
+
"INVALID_ARGUMENT"
|
|
2463
|
+
);
|
|
2483
2464
|
}
|
|
2484
2465
|
for (const messageId of ids) {
|
|
2485
2466
|
const message = getMessageById(gs, authEmail, messageId);
|
|
2486
2467
|
if (!message) continue;
|
|
2487
|
-
markMessageModified(
|
|
2488
|
-
gs,
|
|
2489
|
-
message,
|
|
2490
|
-
applyLabelMutation(message.label_ids, addLabelIds, removeLabelIds)
|
|
2491
|
-
);
|
|
2468
|
+
markMessageModified(gs, message, applyLabelMutation(message.label_ids, addLabelIds, removeLabelIds));
|
|
2492
2469
|
}
|
|
2493
2470
|
return c.body(null, 204);
|
|
2494
2471
|
});
|
|
@@ -2555,7 +2532,13 @@ function messageRoutes({ app, store }) {
|
|
|
2555
2532
|
const removeLabelIds = getStringArray(body, "removeLabelIds");
|
|
2556
2533
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, [...addLabelIds, ...removeLabelIds]);
|
|
2557
2534
|
if (missingLabelIds.length > 0) {
|
|
2558
|
-
return googleApiError(
|
|
2535
|
+
return googleApiError(
|
|
2536
|
+
c,
|
|
2537
|
+
400,
|
|
2538
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
2539
|
+
"invalidArgument",
|
|
2540
|
+
"INVALID_ARGUMENT"
|
|
2541
|
+
);
|
|
2559
2542
|
}
|
|
2560
2543
|
const updated = markMessageModified(
|
|
2561
2544
|
gs,
|
|
@@ -2571,7 +2554,9 @@ function messageRoutes({ app, store }) {
|
|
|
2571
2554
|
if (!message) {
|
|
2572
2555
|
return googleApiError(c, 404, "Requested entity was not found.", "notFound", "NOT_FOUND");
|
|
2573
2556
|
}
|
|
2574
|
-
return c.json(
|
|
2557
|
+
return c.json(
|
|
2558
|
+
formatMessageResource(gs, markMessageModified(gs, message, trashLabelIds(message.label_ids)), "full")
|
|
2559
|
+
);
|
|
2575
2560
|
});
|
|
2576
2561
|
app.post("/gmail/v1/users/:userId/messages/:id/untrash", (c) => {
|
|
2577
2562
|
const authEmail = requireGmailUser(c);
|
|
@@ -2580,7 +2565,9 @@ function messageRoutes({ app, store }) {
|
|
|
2580
2565
|
if (!message) {
|
|
2581
2566
|
return googleApiError(c, 404, "Requested entity was not found.", "notFound", "NOT_FOUND");
|
|
2582
2567
|
}
|
|
2583
|
-
return c.json(
|
|
2568
|
+
return c.json(
|
|
2569
|
+
formatMessageResource(gs, markMessageModified(gs, message, untrashLabelIds(message.label_ids)), "full")
|
|
2570
|
+
);
|
|
2584
2571
|
});
|
|
2585
2572
|
app.delete("/gmail/v1/users/:userId/messages/:id", (c) => {
|
|
2586
2573
|
const authEmail = requireGmailUser(c);
|
|
@@ -2613,6 +2600,7 @@ var FONTS = {
|
|
|
2613
2600
|
"geist-sans.woff2": readFileSync(join(__dirname, "fonts", "geist-sans.woff2")),
|
|
2614
2601
|
"GeistPixel-Square.woff2": readFileSync(join(__dirname, "fonts", "GeistPixel-Square.woff2"))
|
|
2615
2602
|
};
|
|
2603
|
+
var FAVICON = readFileSync(join(__dirname, "fonts", "favicon.ico"));
|
|
2616
2604
|
function escapeHtml(s) {
|
|
2617
2605
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
2618
2606
|
}
|
|
@@ -2764,6 +2752,132 @@ body{
|
|
|
2764
2752
|
.app-link-name{font-weight:600;font-size:.875rem;color:#33ff00;}
|
|
2765
2753
|
.app-link-scopes{font-size:.6875rem;color:#1a8c00;margin-top:1px;}
|
|
2766
2754
|
.empty{color:#1a8c00;text-align:center;padding:28px 0;font-size:.875rem;}
|
|
2755
|
+
|
|
2756
|
+
.inspector-layout{max-width:960px;margin:0 auto;padding:28px 20px;}
|
|
2757
|
+
.inspector-tabs{display:flex;gap:4px;margin-bottom:20px;}
|
|
2758
|
+
.inspector-tabs a{
|
|
2759
|
+
padding:7px 16px;border-radius:6px;text-decoration:none;
|
|
2760
|
+
font-size:.8125rem;color:#1a8c00;border:1px solid transparent;
|
|
2761
|
+
transition:color .15s,border-color .15s;
|
|
2762
|
+
}
|
|
2763
|
+
.inspector-tabs a:hover{color:#33ff00;}
|
|
2764
|
+
.inspector-tabs a.active{color:#33ff00;font-weight:600;border-color:#0a3300;background:#0a3300;}
|
|
2765
|
+
.inspector-section{margin-bottom:24px;}
|
|
2766
|
+
.inspector-section h2{
|
|
2767
|
+
font-family:'Geist Pixel',monospace;
|
|
2768
|
+
font-size:1rem;font-weight:600;color:#33ff00;margin-bottom:10px;
|
|
2769
|
+
}
|
|
2770
|
+
.inspector-section h3{
|
|
2771
|
+
font-family:'Geist Pixel',monospace;
|
|
2772
|
+
font-size:.875rem;font-weight:600;color:#1a8c00;margin:16px 0 8px;
|
|
2773
|
+
}
|
|
2774
|
+
.inspector-table{width:100%;border-collapse:collapse;margin-bottom:12px;}
|
|
2775
|
+
.inspector-table th,.inspector-table td{
|
|
2776
|
+
text-align:left;padding:8px 12px;border-bottom:1px solid #0a3300;
|
|
2777
|
+
font-size:.8125rem;
|
|
2778
|
+
}
|
|
2779
|
+
.inspector-table th{color:#1a8c00;font-weight:600;font-size:.75rem;text-transform:uppercase;letter-spacing:.04em;}
|
|
2780
|
+
.inspector-table td{color:#33ff00;}
|
|
2781
|
+
.inspector-table tbody tr{transition:background .1s;}
|
|
2782
|
+
.inspector-table tbody tr:hover{background:#0a3300;}
|
|
2783
|
+
.inspector-empty{color:#1a8c00;text-align:center;padding:20px 0;font-size:.8125rem;}
|
|
2784
|
+
|
|
2785
|
+
.checkout-layout{
|
|
2786
|
+
display:flex;min-height:calc(100vh - 42px);
|
|
2787
|
+
}
|
|
2788
|
+
.checkout-summary{
|
|
2789
|
+
flex:1;background:#020;padding:48px 40px 48px 10%;
|
|
2790
|
+
display:flex;flex-direction:column;justify-content:center;
|
|
2791
|
+
border-right:1px solid #0a3300;
|
|
2792
|
+
}
|
|
2793
|
+
.checkout-form-side{
|
|
2794
|
+
flex:1;background:#000;padding:48px 10% 48px 40px;
|
|
2795
|
+
display:flex;flex-direction:column;justify-content:center;
|
|
2796
|
+
}
|
|
2797
|
+
.checkout-merchant{
|
|
2798
|
+
display:flex;align-items:center;gap:10px;margin-bottom:6px;
|
|
2799
|
+
}
|
|
2800
|
+
.checkout-merchant-name{
|
|
2801
|
+
font-family:'Geist Pixel',monospace;
|
|
2802
|
+
font-size:.9375rem;font-weight:600;color:#33ff00;
|
|
2803
|
+
}
|
|
2804
|
+
.checkout-test-badge{
|
|
2805
|
+
font-size:.625rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
|
|
2806
|
+
background:#0a3300;color:#1a8c00;padding:2px 8px;border-radius:4px;
|
|
2807
|
+
}
|
|
2808
|
+
.checkout-total{
|
|
2809
|
+
font-family:'Geist Pixel',monospace;
|
|
2810
|
+
font-size:2rem;font-weight:700;color:#33ff00;margin:8px 0 28px;
|
|
2811
|
+
}
|
|
2812
|
+
.checkout-line-item{
|
|
2813
|
+
display:flex;align-items:center;gap:14px;padding:14px 0;
|
|
2814
|
+
border-bottom:1px solid #0a3300;
|
|
2815
|
+
}
|
|
2816
|
+
.checkout-line-item:first-child{border-top:1px solid #0a3300;}
|
|
2817
|
+
.checkout-item-icon{
|
|
2818
|
+
width:42px;height:42px;border-radius:6px;background:#0a3300;
|
|
2819
|
+
display:flex;align-items:center;justify-content:center;flex-shrink:0;
|
|
2820
|
+
font-family:'Geist Pixel',monospace;font-size:.875rem;font-weight:700;color:#116600;
|
|
2821
|
+
}
|
|
2822
|
+
.checkout-item-details{flex:1;min-width:0;}
|
|
2823
|
+
.checkout-item-name{font-size:.875rem;font-weight:600;color:#33ff00;}
|
|
2824
|
+
.checkout-item-qty{font-size:.75rem;color:#1a8c00;margin-top:2px;}
|
|
2825
|
+
.checkout-item-price{
|
|
2826
|
+
font-size:.875rem;font-weight:600;color:#33ff00;text-align:right;white-space:nowrap;
|
|
2827
|
+
}
|
|
2828
|
+
.checkout-item-unit{font-size:.6875rem;color:#1a8c00;text-align:right;margin-top:2px;}
|
|
2829
|
+
.checkout-totals{margin-top:20px;}
|
|
2830
|
+
.checkout-totals-row{
|
|
2831
|
+
display:flex;justify-content:space-between;padding:6px 0;
|
|
2832
|
+
font-size:.8125rem;color:#1a8c00;
|
|
2833
|
+
}
|
|
2834
|
+
.checkout-totals-row.total{
|
|
2835
|
+
border-top:1px solid #0a3300;margin-top:8px;padding-top:14px;
|
|
2836
|
+
font-size:.9375rem;font-weight:600;color:#33ff00;
|
|
2837
|
+
}
|
|
2838
|
+
.checkout-form-section{margin-bottom:24px;}
|
|
2839
|
+
.checkout-form-label{
|
|
2840
|
+
font-size:.8125rem;font-weight:600;color:#33ff00;margin-bottom:8px;display:block;
|
|
2841
|
+
}
|
|
2842
|
+
.checkout-input{
|
|
2843
|
+
width:100%;padding:10px 12px;border:1px solid #0a3300;border-radius:6px;
|
|
2844
|
+
background:#020;color:#33ff00;font:inherit;font-size:.875rem;
|
|
2845
|
+
transition:border-color .15s;outline:none;
|
|
2846
|
+
}
|
|
2847
|
+
.checkout-input:focus{border-color:#33ff00;}
|
|
2848
|
+
.checkout-input::placeholder{color:#116600;}
|
|
2849
|
+
.checkout-card-box{
|
|
2850
|
+
border:1px solid #0a3300;border-radius:6px;padding:14px;
|
|
2851
|
+
background:#020;
|
|
2852
|
+
}
|
|
2853
|
+
.checkout-card-row{
|
|
2854
|
+
display:flex;gap:12px;margin-top:10px;
|
|
2855
|
+
}
|
|
2856
|
+
.checkout-card-row .checkout-input{flex:1;}
|
|
2857
|
+
.checkout-sim-note{
|
|
2858
|
+
font-size:.6875rem;color:#1a8c00;margin-top:10px;text-align:center;
|
|
2859
|
+
font-style:italic;
|
|
2860
|
+
}
|
|
2861
|
+
.checkout-pay-btn{
|
|
2862
|
+
width:100%;padding:14px;border:none;border-radius:8px;
|
|
2863
|
+
background:#33ff00;color:#000;font:inherit;font-size:.9375rem;font-weight:700;
|
|
2864
|
+
cursor:pointer;transition:background .15s;
|
|
2865
|
+
font-family:'Geist Pixel',monospace;
|
|
2866
|
+
}
|
|
2867
|
+
.checkout-pay-btn:hover{background:#44ff22;}
|
|
2868
|
+
.checkout-cancel{
|
|
2869
|
+
text-align:center;margin-top:14px;
|
|
2870
|
+
}
|
|
2871
|
+
.checkout-cancel a{
|
|
2872
|
+
color:#1a8c00;text-decoration:none;font-size:.8125rem;
|
|
2873
|
+
transition:color .15s;
|
|
2874
|
+
}
|
|
2875
|
+
.checkout-cancel a:hover{color:#33ff00;}
|
|
2876
|
+
@media(max-width:768px){
|
|
2877
|
+
.checkout-layout{flex-direction:column;}
|
|
2878
|
+
.checkout-summary{padding:32px 20px;border-right:none;border-bottom:1px solid #0a3300;}
|
|
2879
|
+
.checkout-form-side{padding:32px 20px;}
|
|
2880
|
+
}
|
|
2767
2881
|
`;
|
|
2768
2882
|
var POWERED_BY = `<div class="powered-by">Powered by <a href="https://emulate.dev" target="_blank" rel="noopener">emulate</a></div>`;
|
|
2769
2883
|
function emuBar(service) {
|
|
@@ -2783,6 +2897,7 @@ function head(title) {
|
|
|
2783
2897
|
<head>
|
|
2784
2898
|
<meta charset="utf-8"/>
|
|
2785
2899
|
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
2900
|
+
<link rel="icon" href="/_emulate/favicon.ico"/>
|
|
2786
2901
|
<title>${escapeHtml(title)} | emulate</title>
|
|
2787
2902
|
<style>${CSS}</style>
|
|
2788
2903
|
</head>`;
|
|
@@ -2884,6 +2999,7 @@ async function createIdToken(user, clientId, nonce, baseUrl) {
|
|
|
2884
2999
|
family_name: user.family_name,
|
|
2885
3000
|
picture: user.picture,
|
|
2886
3001
|
locale: user.locale,
|
|
3002
|
+
...user.hd ? { hd: user.hd } : {},
|
|
2887
3003
|
...nonce ? { nonce } : {}
|
|
2888
3004
|
}).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuer(baseUrl).setAudience(clientId).setIssuedAt().setExpirationTime("1h");
|
|
2889
3005
|
return builder.sign(JWT_SECRET);
|
|
@@ -2911,7 +3027,8 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
2911
3027
|
"given_name",
|
|
2912
3028
|
"family_name",
|
|
2913
3029
|
"picture",
|
|
2914
|
-
"locale"
|
|
3030
|
+
"locale",
|
|
3031
|
+
"hd"
|
|
2915
3032
|
],
|
|
2916
3033
|
code_challenge_methods_supported: ["plain", "S256"]
|
|
2917
3034
|
});
|
|
@@ -2939,7 +3056,11 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
2939
3056
|
}
|
|
2940
3057
|
if (redirect_uri && !matchesRedirectUri(redirect_uri, client.redirect_uris)) {
|
|
2941
3058
|
return c.html(
|
|
2942
|
-
renderErrorPage(
|
|
3059
|
+
renderErrorPage(
|
|
3060
|
+
"Redirect URI mismatch",
|
|
3061
|
+
"The redirect_uri is not registered for this application.",
|
|
3062
|
+
SERVICE_LABEL
|
|
3063
|
+
),
|
|
2943
3064
|
400
|
|
2944
3065
|
);
|
|
2945
3066
|
}
|
|
@@ -3051,7 +3172,13 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
3051
3172
|
});
|
|
3052
3173
|
}
|
|
3053
3174
|
if (grant_type !== "authorization_code") {
|
|
3054
|
-
return c.json(
|
|
3175
|
+
return c.json(
|
|
3176
|
+
{
|
|
3177
|
+
error: "unsupported_grant_type",
|
|
3178
|
+
error_description: "Only authorization_code and refresh_token are supported."
|
|
3179
|
+
},
|
|
3180
|
+
400
|
|
3181
|
+
);
|
|
3055
3182
|
}
|
|
3056
3183
|
const pendingMap = getPendingCodes(store);
|
|
3057
3184
|
const pending = pendingMap.get(code);
|
|
@@ -3124,7 +3251,8 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
3124
3251
|
given_name: user.given_name,
|
|
3125
3252
|
family_name: user.family_name,
|
|
3126
3253
|
picture: user.picture,
|
|
3127
|
-
locale: user.locale
|
|
3254
|
+
locale: user.locale,
|
|
3255
|
+
...user.hd ? { hd: user.hd } : {}
|
|
3128
3256
|
});
|
|
3129
3257
|
});
|
|
3130
3258
|
app.post("/oauth2/revoke", async (c) => {
|
|
@@ -3174,7 +3302,13 @@ function settingsRoutes({ app, store }) {
|
|
|
3174
3302
|
}
|
|
3175
3303
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, [...addLabelIds, ...removeLabelIds]);
|
|
3176
3304
|
if (missingLabelIds.length > 0) {
|
|
3177
|
-
return googleApiError(
|
|
3305
|
+
return googleApiError(
|
|
3306
|
+
c,
|
|
3307
|
+
400,
|
|
3308
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
3309
|
+
"invalidArgument",
|
|
3310
|
+
"INVALID_ARGUMENT"
|
|
3311
|
+
);
|
|
3178
3312
|
}
|
|
3179
3313
|
if (findMatchingFilter(gs, {
|
|
3180
3314
|
user_email: authEmail,
|
|
@@ -3277,14 +3411,16 @@ function threadRoutes({ app, store }) {
|
|
|
3277
3411
|
const removeLabelIds = getStringArray(body, "removeLabelIds");
|
|
3278
3412
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, [...addLabelIds, ...removeLabelIds]);
|
|
3279
3413
|
if (missingLabelIds.length > 0) {
|
|
3280
|
-
return googleApiError(
|
|
3414
|
+
return googleApiError(
|
|
3415
|
+
c,
|
|
3416
|
+
400,
|
|
3417
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
3418
|
+
"invalidArgument",
|
|
3419
|
+
"INVALID_ARGUMENT"
|
|
3420
|
+
);
|
|
3281
3421
|
}
|
|
3282
3422
|
const updated = messages.map(
|
|
3283
|
-
(message) => markMessageModified(
|
|
3284
|
-
gs,
|
|
3285
|
-
message,
|
|
3286
|
-
applyLabelMutation(message.label_ids, addLabelIds, removeLabelIds)
|
|
3287
|
-
)
|
|
3423
|
+
(message) => markMessageModified(gs, message, applyLabelMutation(message.label_ids, addLabelIds, removeLabelIds))
|
|
3288
3424
|
);
|
|
3289
3425
|
return c.json(formatThreadResource(gs, updated, "full"));
|
|
3290
3426
|
});
|
|
@@ -3333,120 +3469,148 @@ function seedDefaults(store, _baseUrl) {
|
|
|
3333
3469
|
family_name: "User",
|
|
3334
3470
|
picture: null,
|
|
3335
3471
|
email_verified: true,
|
|
3336
|
-
locale: "en"
|
|
3472
|
+
locale: "en",
|
|
3473
|
+
hd: null
|
|
3337
3474
|
});
|
|
3338
3475
|
}
|
|
3339
3476
|
ensureSystemLabels(gs, defaultEmail);
|
|
3340
|
-
seedCalendars(
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3477
|
+
seedCalendars(
|
|
3478
|
+
store,
|
|
3479
|
+
[
|
|
3480
|
+
{
|
|
3481
|
+
id: "primary",
|
|
3482
|
+
user_email: defaultEmail,
|
|
3483
|
+
summary: defaultEmail,
|
|
3484
|
+
primary: true,
|
|
3485
|
+
selected: true,
|
|
3486
|
+
time_zone: "UTC"
|
|
3487
|
+
},
|
|
3488
|
+
{
|
|
3489
|
+
id: "cal_team",
|
|
3490
|
+
user_email: defaultEmail,
|
|
3491
|
+
summary: "Team Calendar",
|
|
3492
|
+
description: "Shared team events",
|
|
3493
|
+
selected: true,
|
|
3494
|
+
time_zone: "UTC"
|
|
3495
|
+
}
|
|
3496
|
+
],
|
|
3497
|
+
defaultEmail
|
|
3498
|
+
);
|
|
3499
|
+
seedCalendarEvents(
|
|
3500
|
+
store,
|
|
3501
|
+
[
|
|
3502
|
+
{
|
|
3503
|
+
id: "evt_standup",
|
|
3504
|
+
user_email: defaultEmail,
|
|
3505
|
+
calendar_id: "primary",
|
|
3506
|
+
summary: "Daily Standup",
|
|
3507
|
+
description: "Team sync",
|
|
3508
|
+
start_date_time: new Date(Date.now() + 60 * 60 * 1e3).toISOString(),
|
|
3509
|
+
end_date_time: new Date(Date.now() + 90 * 60 * 1e3).toISOString(),
|
|
3510
|
+
attendees: [
|
|
3511
|
+
{ email: defaultEmail, display_name: "Test User" },
|
|
3512
|
+
{ email: "teammate@example.com", display_name: "Teammate" }
|
|
3513
|
+
],
|
|
3514
|
+
conference_entry_points: [
|
|
3515
|
+
{
|
|
3516
|
+
entry_point_type: "video",
|
|
3517
|
+
uri: "https://meet.google.com/emulate-standup",
|
|
3518
|
+
label: "Google Meet"
|
|
3519
|
+
}
|
|
3520
|
+
],
|
|
3521
|
+
hangout_link: "https://meet.google.com/emulate-standup"
|
|
3522
|
+
}
|
|
3523
|
+
],
|
|
3524
|
+
defaultEmail
|
|
3525
|
+
);
|
|
3526
|
+
seedDriveItems(
|
|
3527
|
+
store,
|
|
3528
|
+
[
|
|
3529
|
+
{
|
|
3530
|
+
id: "drv_root_receipts",
|
|
3531
|
+
user_email: defaultEmail,
|
|
3532
|
+
name: "Receipts",
|
|
3533
|
+
mime_type: "application/vnd.google-apps.folder",
|
|
3534
|
+
parent_ids: ["root"]
|
|
3535
|
+
},
|
|
3536
|
+
{
|
|
3537
|
+
id: "drv_receipt_pdf",
|
|
3538
|
+
user_email: defaultEmail,
|
|
3539
|
+
name: "March Receipt.pdf",
|
|
3540
|
+
mime_type: "application/pdf",
|
|
3541
|
+
parent_ids: ["drv_root_receipts"],
|
|
3542
|
+
data: "receipt-pdf-data"
|
|
3543
|
+
}
|
|
3544
|
+
],
|
|
3545
|
+
defaultEmail
|
|
3546
|
+
);
|
|
3547
|
+
seedMessages(
|
|
3548
|
+
store,
|
|
3549
|
+
[
|
|
3550
|
+
{
|
|
3551
|
+
id: "msg_welcome",
|
|
3552
|
+
thread_id: "thr_welcome",
|
|
3553
|
+
user_email: defaultEmail,
|
|
3554
|
+
from: "Welcome Team <welcome@example.com>",
|
|
3555
|
+
to: defaultEmail,
|
|
3556
|
+
subject: "Welcome to your local Gmail emulator",
|
|
3557
|
+
snippet: "Your OAuth flow is set up and Gmail message, thread, and label APIs are ready.",
|
|
3558
|
+
body_text: "Your OAuth flow is set up and Gmail message, thread, and label APIs are ready.\n\nUse this inbox to test Gmail automations locally.",
|
|
3559
|
+
label_ids: ["INBOX", "UNREAD", "CATEGORY_UPDATES"],
|
|
3560
|
+
date: new Date(Date.now() - 60 * 60 * 1e3).toISOString()
|
|
3561
|
+
},
|
|
3562
|
+
{
|
|
3563
|
+
id: "msg_build",
|
|
3564
|
+
thread_id: "thr_build",
|
|
3565
|
+
user_email: defaultEmail,
|
|
3566
|
+
from: "Build Bot <builds@example.com>",
|
|
3567
|
+
to: defaultEmail,
|
|
3568
|
+
subject: "Nightly build finished successfully",
|
|
3569
|
+
snippet: "The latest build completed successfully in 6 minutes.",
|
|
3570
|
+
body_text: "The latest build completed successfully in 6 minutes.\n\nArtifact upload finished and smoke checks passed.",
|
|
3571
|
+
label_ids: ["INBOX", "CATEGORY_UPDATES"],
|
|
3572
|
+
date: new Date(Date.now() - 2 * 60 * 60 * 1e3).toISOString()
|
|
3573
|
+
},
|
|
3574
|
+
{
|
|
3575
|
+
id: "msg_build_reply",
|
|
3576
|
+
thread_id: "thr_build",
|
|
3577
|
+
user_email: defaultEmail,
|
|
3578
|
+
from: defaultEmail,
|
|
3579
|
+
to: "Build Bot <builds@example.com>",
|
|
3580
|
+
subject: "Re: Nightly build finished successfully",
|
|
3581
|
+
snippet: "Thanks, I will review the artifact after lunch.",
|
|
3582
|
+
body_text: "Thanks, I will review the artifact after lunch.",
|
|
3583
|
+
label_ids: ["SENT"],
|
|
3584
|
+
date: new Date(Date.now() - 90 * 60 * 1e3).toISOString(),
|
|
3585
|
+
in_reply_to: "<msg_build@emulate.google.local>",
|
|
3586
|
+
references: "<msg_build@emulate.google.local>"
|
|
3587
|
+
},
|
|
3588
|
+
{
|
|
3589
|
+
id: "msg_draft",
|
|
3590
|
+
thread_id: "thr_draft",
|
|
3591
|
+
user_email: defaultEmail,
|
|
3592
|
+
from: defaultEmail,
|
|
3593
|
+
to: "someone@example.com",
|
|
3594
|
+
subject: "Draft follow-up",
|
|
3595
|
+
snippet: "Checking in on the open question from yesterday.",
|
|
3596
|
+
body_text: "Checking in on the open question from yesterday.",
|
|
3597
|
+
label_ids: ["DRAFT"],
|
|
3598
|
+
date: new Date(Date.now() - 30 * 60 * 1e3).toISOString()
|
|
3599
|
+
}
|
|
3600
|
+
],
|
|
3601
|
+
defaultEmail
|
|
3602
|
+
);
|
|
3603
|
+
}
|
|
3604
|
+
var CONSUMER_EMAIL_DOMAINS = /* @__PURE__ */ new Set(["gmail.com", "googlemail.com"]);
|
|
3605
|
+
function deriveHd(email) {
|
|
3606
|
+
const domain = email.split("@")[1]?.toLowerCase();
|
|
3607
|
+
if (!domain) return null;
|
|
3608
|
+
if (CONSUMER_EMAIL_DOMAINS.has(domain)) return null;
|
|
3609
|
+
return domain;
|
|
3610
|
+
}
|
|
3611
|
+
function resolveHd(user) {
|
|
3612
|
+
if (user.hd !== void 0) return user.hd || null;
|
|
3613
|
+
return deriveHd(user.email);
|
|
3450
3614
|
}
|
|
3451
3615
|
function seedFromConfig(store, _baseUrl, config) {
|
|
3452
3616
|
const gs = getGoogleStore(store);
|
|
@@ -3463,7 +3627,8 @@ function seedFromConfig(store, _baseUrl, config) {
|
|
|
3463
3627
|
family_name: user.family_name ?? nameParts.slice(1).join(" "),
|
|
3464
3628
|
picture: user.picture ?? null,
|
|
3465
3629
|
email_verified: user.email_verified ?? true,
|
|
3466
|
-
locale: user.locale ?? "en"
|
|
3630
|
+
locale: user.locale ?? "en",
|
|
3631
|
+
hd: resolveHd(user)
|
|
3467
3632
|
});
|
|
3468
3633
|
}
|
|
3469
3634
|
ensureSystemLabels(gs, user.email);
|
|
@@ -3524,29 +3689,33 @@ function seedMessages(store, messages, fallbackEmail) {
|
|
|
3524
3689
|
const userEmail = message.user_email ?? fallbackEmail;
|
|
3525
3690
|
ensureSystemLabels(gs, userEmail);
|
|
3526
3691
|
if (message.id && gs.messages.findOneBy("gmail_id", message.id)) continue;
|
|
3527
|
-
createStoredMessage(
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3692
|
+
createStoredMessage(
|
|
3693
|
+
gs,
|
|
3694
|
+
{
|
|
3695
|
+
gmail_id: message.id,
|
|
3696
|
+
thread_id: message.thread_id,
|
|
3697
|
+
user_email: userEmail,
|
|
3698
|
+
raw: message.raw ?? null,
|
|
3699
|
+
from: message.from,
|
|
3700
|
+
to: message.to,
|
|
3701
|
+
cc: message.cc ?? null,
|
|
3702
|
+
bcc: message.bcc ?? null,
|
|
3703
|
+
reply_to: message.reply_to ?? null,
|
|
3704
|
+
subject: message.subject,
|
|
3705
|
+
snippet: message.snippet,
|
|
3706
|
+
body_text: message.body_text ?? null,
|
|
3707
|
+
body_html: message.body_html ?? null,
|
|
3708
|
+
label_ids: message.label_ids ?? ["INBOX", "UNREAD"],
|
|
3709
|
+
date: message.date,
|
|
3710
|
+
internal_date: message.internal_date,
|
|
3711
|
+
message_id: message.message_id,
|
|
3712
|
+
references: message.references ?? null,
|
|
3713
|
+
in_reply_to: message.in_reply_to ?? null
|
|
3714
|
+
},
|
|
3715
|
+
{
|
|
3716
|
+
createMissingCustomLabels: true
|
|
3717
|
+
}
|
|
3718
|
+
);
|
|
3550
3719
|
}
|
|
3551
3720
|
}
|
|
3552
3721
|
function seedCalendars(store, calendars, fallbackEmail) {
|
|
@@ -3638,4 +3807,4 @@ export {
|
|
|
3638
3807
|
googlePlugin,
|
|
3639
3808
|
seedFromConfig
|
|
3640
3809
|
};
|
|
3641
|
-
//# sourceMappingURL=dist-
|
|
3810
|
+
//# sourceMappingURL=dist-KKTYBE5S.js.map
|