emulate 0.4.1 → 0.6.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 +198 -27
- package/dist/api.d.ts +2 -1
- package/dist/api.js +675 -103
- package/dist/api.js.map +1 -1
- package/dist/chunk-WVQMFHQM.js +83 -0
- package/dist/chunk-WVQMFHQM.js.map +1 -0
- package/dist/{dist-B674PYKV.js → dist-2ZZGNPJI.js} +22 -43
- package/dist/dist-2ZZGNPJI.js.map +1 -0
- package/dist/{dist-RDFBZ5O6.js → dist-CXRPM6BK.js} +211 -48
- package/dist/dist-CXRPM6BK.js.map +1 -0
- package/dist/{dist-VVXVP5EZ.js → dist-DSJSF3GY.js} +551 -91
- package/dist/dist-DSJSF3GY.js.map +1 -0
- package/dist/{dist-RMK3BS5M.js → dist-IFULY5LE.js} +196 -33
- package/dist/dist-IFULY5LE.js.map +1 -0
- package/dist/dist-IRUBHCZU.js +1898 -0
- package/dist/dist-IRUBHCZU.js.map +1 -0
- package/dist/{dist-YOVM5HEY.js → dist-NJJLJT2N.js} +520 -61
- package/dist/dist-NJJLJT2N.js.map +1 -0
- package/dist/dist-OGSAVJ25.js +4874 -0
- package/dist/dist-OGSAVJ25.js.map +1 -0
- package/dist/{dist-H6JYGQM4.js → dist-PO4CL5SJ.js} +271 -158
- package/dist/dist-PO4CL5SJ.js.map +1 -0
- package/dist/{dist-QMOJM6DV.js → dist-R3TNKUIE.js} +238 -55
- package/dist/dist-R3TNKUIE.js.map +1 -0
- package/dist/{dist-6JFNJPUU.js → dist-WACHAAVU.js} +171 -22
- package/dist/dist-WACHAAVU.js.map +1 -0
- package/dist/{dist-OTJZRQ3Q.js → dist-XWWZVLQQ.js} +216 -75
- package/dist/dist-XWWZVLQQ.js.map +1 -0
- package/dist/{dist-6EW7SSOZ.js → dist-ZY5SZSJ2.js} +397 -223
- package/dist/dist-ZY5SZSJ2.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 +812 -117
- package/dist/index.js.map +1 -1
- package/package.json +17 -15
- package/dist/chunk-TEPNEZ63.js +0 -2143
- 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 +0 -1287
- 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,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SignJWT
|
|
3
3
|
} from "./chunk-D6EKRYGP.js";
|
|
4
|
-
import "./chunk-TEPNEZ63.js";
|
|
5
4
|
|
|
6
5
|
// ../@emulators/google/dist/index.js
|
|
7
6
|
import { randomBytes } from "crypto";
|
|
@@ -76,6 +75,7 @@ var LABEL_ALIASES = {
|
|
|
76
75
|
updates: "CATEGORY_UPDATES",
|
|
77
76
|
forums: "CATEGORY_FORUMS"
|
|
78
77
|
};
|
|
78
|
+
var lastGeneratedHistoryId = 0n;
|
|
79
79
|
function generateUid(prefix = "") {
|
|
80
80
|
const id = randomBytes(12).toString("base64url").slice(0, 20);
|
|
81
81
|
return prefix ? `${prefix}_${id}` : id;
|
|
@@ -86,7 +86,12 @@ function generateDraftId() {
|
|
|
86
86
|
}
|
|
87
87
|
function generateHistoryId() {
|
|
88
88
|
const entropy = randomBytes(3).readUIntBE(0, 3).toString().padStart(8, "0");
|
|
89
|
-
|
|
89
|
+
let next = BigInt(`${Date.now()}${entropy}`);
|
|
90
|
+
if (next <= lastGeneratedHistoryId) {
|
|
91
|
+
next = lastGeneratedHistoryId + 1n;
|
|
92
|
+
}
|
|
93
|
+
lastGeneratedHistoryId = next;
|
|
94
|
+
return next.toString();
|
|
90
95
|
}
|
|
91
96
|
function getAuthenticatedEmail(c) {
|
|
92
97
|
const authUser = c.get("authUser");
|
|
@@ -134,9 +139,7 @@ function parseBooleanParam(value) {
|
|
|
134
139
|
return value === "true" || value === "1";
|
|
135
140
|
}
|
|
136
141
|
function ensureSystemLabels(gs, userEmail) {
|
|
137
|
-
const existingIds = new Set(
|
|
138
|
-
gs.labels.findBy("user_email", userEmail).map((row) => row.gmail_id)
|
|
139
|
-
);
|
|
142
|
+
const existingIds = new Set(gs.labels.findBy("user_email", userEmail).map((row) => row.gmail_id));
|
|
140
143
|
for (const label of SYSTEM_LABELS) {
|
|
141
144
|
if (existingIds.has(label.gmail_id)) continue;
|
|
142
145
|
gs.labels.insert({
|
|
@@ -481,9 +484,7 @@ function getCurrentHistoryId(gs, userEmail) {
|
|
|
481
484
|
...gs.history.findBy("user_email", userEmail).map((event) => event.gmail_id)
|
|
482
485
|
].filter(Boolean);
|
|
483
486
|
if (historyIds.length === 0) return "0";
|
|
484
|
-
return historyIds.reduce(
|
|
485
|
-
(latest, current) => compareHistoryIds(current, latest) > 0 ? current : latest
|
|
486
|
-
);
|
|
487
|
+
return historyIds.reduce((latest, current) => compareHistoryIds(current, latest) > 0 ? current : latest);
|
|
487
488
|
}
|
|
488
489
|
function listHistoryForUser(gs, userEmail, options) {
|
|
489
490
|
const requestedTypes = options.historyTypes?.length ? new Set(options.historyTypes) : null;
|
|
@@ -1066,10 +1067,7 @@ function buildPayload(gs, message, headers, format) {
|
|
|
1066
1067
|
filename: "",
|
|
1067
1068
|
headers,
|
|
1068
1069
|
body: { size: 0 },
|
|
1069
|
-
parts: [
|
|
1070
|
-
createTextBodyPart("0", "text/plain", textBody),
|
|
1071
|
-
createTextBodyPart("1", "text/html", htmlBody)
|
|
1072
|
-
]
|
|
1070
|
+
parts: [createTextBodyPart("0", "text/plain", textBody), createTextBodyPart("1", "text/html", htmlBody)]
|
|
1073
1071
|
};
|
|
1074
1072
|
}
|
|
1075
1073
|
if (htmlBody) return createTextBodyPart("", "text/html", htmlBody, headers);
|
|
@@ -1090,10 +1088,7 @@ function buildPayload(gs, message, headers, format) {
|
|
|
1090
1088
|
filename: "",
|
|
1091
1089
|
headers: [],
|
|
1092
1090
|
body: { size: 0 },
|
|
1093
|
-
parts: [
|
|
1094
|
-
createTextBodyPart("0.0", "text/plain", textBody),
|
|
1095
|
-
createTextBodyPart("0.1", "text/html", htmlBody)
|
|
1096
|
-
]
|
|
1091
|
+
parts: [createTextBodyPart("0.0", "text/plain", textBody), createTextBodyPart("0.1", "text/html", htmlBody)]
|
|
1097
1092
|
});
|
|
1098
1093
|
} else if (htmlBody) {
|
|
1099
1094
|
parts.push(createTextBodyPart("0", "text/html", htmlBody));
|
|
@@ -1191,18 +1186,10 @@ function buildMimeBodyPart(input) {
|
|
|
1191
1186
|
].join("\r\n");
|
|
1192
1187
|
}
|
|
1193
1188
|
if (input.body_html) {
|
|
1194
|
-
return [
|
|
1195
|
-
"Content-Type: text/html; charset=utf-8",
|
|
1196
|
-
"",
|
|
1197
|
-
input.body_html
|
|
1198
|
-
].join("\r\n");
|
|
1189
|
+
return ["Content-Type: text/html; charset=utf-8", "", input.body_html].join("\r\n");
|
|
1199
1190
|
}
|
|
1200
1191
|
if (input.body_text) {
|
|
1201
|
-
return [
|
|
1202
|
-
"Content-Type: text/plain; charset=utf-8",
|
|
1203
|
-
"",
|
|
1204
|
-
input.body_text
|
|
1205
|
-
].join("\r\n");
|
|
1192
|
+
return ["Content-Type: text/plain; charset=utf-8", "", input.body_text].join("\r\n");
|
|
1206
1193
|
}
|
|
1207
1194
|
return null;
|
|
1208
1195
|
}
|
|
@@ -1798,7 +1785,7 @@ function requireGmailUser(c) {
|
|
|
1798
1785
|
if (authEmail instanceof Response) {
|
|
1799
1786
|
return authEmail;
|
|
1800
1787
|
}
|
|
1801
|
-
if (!matchesRequestedUser(c.req.param("userId"), authEmail)) {
|
|
1788
|
+
if (!matchesRequestedUser(c.req.param("userId") ?? "", authEmail)) {
|
|
1802
1789
|
return googleApiError(c, 404, "Requested entity was not found.", "notFound", "NOT_FOUND");
|
|
1803
1790
|
}
|
|
1804
1791
|
return authEmail;
|
|
@@ -1928,14 +1915,25 @@ function getGoogleStore(store) {
|
|
|
1928
1915
|
oauthClients: store.collection("google.oauth_clients", ["client_id"]),
|
|
1929
1916
|
messages: store.collection("google.messages", ["gmail_id", "thread_id", "user_email"]),
|
|
1930
1917
|
drafts: store.collection("google.drafts", ["gmail_id", "message_gmail_id", "user_email"]),
|
|
1931
|
-
attachments: store.collection("google.attachments", [
|
|
1918
|
+
attachments: store.collection("google.attachments", [
|
|
1919
|
+
"gmail_id",
|
|
1920
|
+
"message_gmail_id",
|
|
1921
|
+
"user_email"
|
|
1922
|
+
]),
|
|
1932
1923
|
history: store.collection("google.history", ["gmail_id", "message_gmail_id", "user_email"]),
|
|
1933
1924
|
labels: store.collection("google.labels", ["gmail_id", "user_email", "name"]),
|
|
1934
1925
|
filters: store.collection("google.filters", ["gmail_id", "user_email"]),
|
|
1935
|
-
forwardingAddresses: store.collection("google.forwarding_addresses", [
|
|
1926
|
+
forwardingAddresses: store.collection("google.forwarding_addresses", [
|
|
1927
|
+
"user_email",
|
|
1928
|
+
"forwarding_email"
|
|
1929
|
+
]),
|
|
1936
1930
|
sendAs: store.collection("google.send_as", ["user_email", "send_as_email"]),
|
|
1937
1931
|
calendars: store.collection("google.calendars", ["google_id", "user_email"]),
|
|
1938
|
-
calendarEvents: store.collection("google.calendar_events", [
|
|
1932
|
+
calendarEvents: store.collection("google.calendar_events", [
|
|
1933
|
+
"google_id",
|
|
1934
|
+
"calendar_google_id",
|
|
1935
|
+
"user_email"
|
|
1936
|
+
]),
|
|
1939
1937
|
driveItems: store.collection("google.drive_items", ["google_id", "user_email", "mime_type"])
|
|
1940
1938
|
};
|
|
1941
1939
|
}
|
|
@@ -2037,13 +2035,7 @@ function draftRoutes({ app, store }) {
|
|
|
2037
2035
|
});
|
|
2038
2036
|
return c.json(formatDraftResource(gs, draft, "full"));
|
|
2039
2037
|
} catch {
|
|
2040
|
-
return googleApiError(
|
|
2041
|
-
c,
|
|
2042
|
-
400,
|
|
2043
|
-
"Invalid raw MIME message payload.",
|
|
2044
|
-
"invalidArgument",
|
|
2045
|
-
"INVALID_ARGUMENT"
|
|
2046
|
-
);
|
|
2038
|
+
return googleApiError(c, 400, "Invalid raw MIME message payload.", "invalidArgument", "INVALID_ARGUMENT");
|
|
2047
2039
|
}
|
|
2048
2040
|
};
|
|
2049
2041
|
const sendHandler = async (c) => {
|
|
@@ -2133,13 +2125,7 @@ function draftRoutes({ app, store }) {
|
|
|
2133
2125
|
}
|
|
2134
2126
|
return c.json(formatDraftResource(gs, updated.draft, "full"));
|
|
2135
2127
|
} catch {
|
|
2136
|
-
return googleApiError(
|
|
2137
|
-
c,
|
|
2138
|
-
400,
|
|
2139
|
-
"Invalid raw MIME message payload.",
|
|
2140
|
-
"invalidArgument",
|
|
2141
|
-
"INVALID_ARGUMENT"
|
|
2142
|
-
);
|
|
2128
|
+
return googleApiError(c, 400, "Invalid raw MIME message payload.", "invalidArgument", "INVALID_ARGUMENT");
|
|
2143
2129
|
}
|
|
2144
2130
|
});
|
|
2145
2131
|
app.post("/gmail/v1/users/:userId/drafts/send", sendHandler);
|
|
@@ -2273,7 +2259,13 @@ function historyRoutes({ app, store }) {
|
|
|
2273
2259
|
const labelIds = getStringArray(body, "labelIds");
|
|
2274
2260
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, labelIds);
|
|
2275
2261
|
if (missingLabelIds.length > 0) {
|
|
2276
|
-
return googleApiError(
|
|
2262
|
+
return googleApiError(
|
|
2263
|
+
c,
|
|
2264
|
+
400,
|
|
2265
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
2266
|
+
"invalidArgument",
|
|
2267
|
+
"INVALID_ARGUMENT"
|
|
2268
|
+
);
|
|
2277
2269
|
}
|
|
2278
2270
|
const expiration = String(Date.now() + 24 * 60 * 60 * 1e3);
|
|
2279
2271
|
const states = store.getData(WATCH_STATE_KEY) ?? /* @__PURE__ */ new Map();
|
|
@@ -2325,13 +2317,7 @@ function labelRoutes({ app, store }) {
|
|
|
2325
2317
|
return googleApiError(c, 400, "Invalid label name", "invalidArgument", "INVALID_ARGUMENT");
|
|
2326
2318
|
}
|
|
2327
2319
|
if (findLabelByName(gs, authEmail, name)) {
|
|
2328
|
-
return googleApiError(
|
|
2329
|
-
c,
|
|
2330
|
-
400,
|
|
2331
|
-
"Label name exists or conflicts",
|
|
2332
|
-
"failedPrecondition",
|
|
2333
|
-
"FAILED_PRECONDITION"
|
|
2334
|
-
);
|
|
2320
|
+
return googleApiError(c, 400, "Label name exists or conflicts", "failedPrecondition", "FAILED_PRECONDITION");
|
|
2335
2321
|
}
|
|
2336
2322
|
const color = body.color && typeof body.color === "object" && !Array.isArray(body.color) ? body.color : void 0;
|
|
2337
2323
|
const label = createLabelRecord(gs, {
|
|
@@ -2389,13 +2375,7 @@ async function saveLabel(c, gs, replaceMissingFields) {
|
|
|
2389
2375
|
if (name) {
|
|
2390
2376
|
const conflicting = findLabelByName(gs, authEmail, name);
|
|
2391
2377
|
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
|
-
);
|
|
2378
|
+
return googleApiError(c, 400, "Label name exists or conflicts", "failedPrecondition", "FAILED_PRECONDITION");
|
|
2399
2379
|
}
|
|
2400
2380
|
}
|
|
2401
2381
|
const updated = updateLabelRecord(gs, label, {
|
|
@@ -2417,7 +2397,13 @@ function messageRoutes({ app, store }) {
|
|
|
2417
2397
|
const defaultLabelIds = mode === "send" ? dedupeLabelIds([...labelIds, "SENT"]) : labelIds.length > 0 ? labelIds : mode === "import" ? ["INBOX", "UNREAD"] : [];
|
|
2418
2398
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, defaultLabelIds);
|
|
2419
2399
|
if (missingLabelIds.length > 0) {
|
|
2420
|
-
return googleApiError(
|
|
2400
|
+
return googleApiError(
|
|
2401
|
+
c,
|
|
2402
|
+
400,
|
|
2403
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
2404
|
+
"invalidArgument",
|
|
2405
|
+
"INVALID_ARGUMENT"
|
|
2406
|
+
);
|
|
2421
2407
|
}
|
|
2422
2408
|
const messageInput = parseMessageInputFromBody(body, {
|
|
2423
2409
|
from: mode === "send" ? authEmail : void 0
|
|
@@ -2439,13 +2425,7 @@ function messageRoutes({ app, store }) {
|
|
|
2439
2425
|
});
|
|
2440
2426
|
return c.json(formatMessageResource(gs, message, "full"));
|
|
2441
2427
|
} catch {
|
|
2442
|
-
return googleApiError(
|
|
2443
|
-
c,
|
|
2444
|
-
400,
|
|
2445
|
-
"Invalid raw MIME message payload.",
|
|
2446
|
-
"invalidArgument",
|
|
2447
|
-
"INVALID_ARGUMENT"
|
|
2448
|
-
);
|
|
2428
|
+
return googleApiError(c, 400, "Invalid raw MIME message payload.", "invalidArgument", "INVALID_ARGUMENT");
|
|
2449
2429
|
}
|
|
2450
2430
|
};
|
|
2451
2431
|
app.get("/gmail/v1/users/:userId/messages", (c) => {
|
|
@@ -2479,16 +2459,18 @@ function messageRoutes({ app, store }) {
|
|
|
2479
2459
|
const removeLabelIds = getStringArray(body, "removeLabelIds");
|
|
2480
2460
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, [...addLabelIds, ...removeLabelIds]);
|
|
2481
2461
|
if (missingLabelIds.length > 0) {
|
|
2482
|
-
return googleApiError(
|
|
2462
|
+
return googleApiError(
|
|
2463
|
+
c,
|
|
2464
|
+
400,
|
|
2465
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
2466
|
+
"invalidArgument",
|
|
2467
|
+
"INVALID_ARGUMENT"
|
|
2468
|
+
);
|
|
2483
2469
|
}
|
|
2484
2470
|
for (const messageId of ids) {
|
|
2485
2471
|
const message = getMessageById(gs, authEmail, messageId);
|
|
2486
2472
|
if (!message) continue;
|
|
2487
|
-
markMessageModified(
|
|
2488
|
-
gs,
|
|
2489
|
-
message,
|
|
2490
|
-
applyLabelMutation(message.label_ids, addLabelIds, removeLabelIds)
|
|
2491
|
-
);
|
|
2473
|
+
markMessageModified(gs, message, applyLabelMutation(message.label_ids, addLabelIds, removeLabelIds));
|
|
2492
2474
|
}
|
|
2493
2475
|
return c.body(null, 204);
|
|
2494
2476
|
});
|
|
@@ -2555,7 +2537,13 @@ function messageRoutes({ app, store }) {
|
|
|
2555
2537
|
const removeLabelIds = getStringArray(body, "removeLabelIds");
|
|
2556
2538
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, [...addLabelIds, ...removeLabelIds]);
|
|
2557
2539
|
if (missingLabelIds.length > 0) {
|
|
2558
|
-
return googleApiError(
|
|
2540
|
+
return googleApiError(
|
|
2541
|
+
c,
|
|
2542
|
+
400,
|
|
2543
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
2544
|
+
"invalidArgument",
|
|
2545
|
+
"INVALID_ARGUMENT"
|
|
2546
|
+
);
|
|
2559
2547
|
}
|
|
2560
2548
|
const updated = markMessageModified(
|
|
2561
2549
|
gs,
|
|
@@ -2571,7 +2559,9 @@ function messageRoutes({ app, store }) {
|
|
|
2571
2559
|
if (!message) {
|
|
2572
2560
|
return googleApiError(c, 404, "Requested entity was not found.", "notFound", "NOT_FOUND");
|
|
2573
2561
|
}
|
|
2574
|
-
return c.json(
|
|
2562
|
+
return c.json(
|
|
2563
|
+
formatMessageResource(gs, markMessageModified(gs, message, trashLabelIds(message.label_ids)), "full")
|
|
2564
|
+
);
|
|
2575
2565
|
});
|
|
2576
2566
|
app.post("/gmail/v1/users/:userId/messages/:id/untrash", (c) => {
|
|
2577
2567
|
const authEmail = requireGmailUser(c);
|
|
@@ -2580,7 +2570,9 @@ function messageRoutes({ app, store }) {
|
|
|
2580
2570
|
if (!message) {
|
|
2581
2571
|
return googleApiError(c, 404, "Requested entity was not found.", "notFound", "NOT_FOUND");
|
|
2582
2572
|
}
|
|
2583
|
-
return c.json(
|
|
2573
|
+
return c.json(
|
|
2574
|
+
formatMessageResource(gs, markMessageModified(gs, message, untrashLabelIds(message.label_ids)), "full")
|
|
2575
|
+
);
|
|
2584
2576
|
});
|
|
2585
2577
|
app.delete("/gmail/v1/users/:userId/messages/:id", (c) => {
|
|
2586
2578
|
const authEmail = requireGmailUser(c);
|
|
@@ -2613,6 +2605,7 @@ var FONTS = {
|
|
|
2613
2605
|
"geist-sans.woff2": readFileSync(join(__dirname, "fonts", "geist-sans.woff2")),
|
|
2614
2606
|
"GeistPixel-Square.woff2": readFileSync(join(__dirname, "fonts", "GeistPixel-Square.woff2"))
|
|
2615
2607
|
};
|
|
2608
|
+
var FAVICON = readFileSync(join(__dirname, "fonts", "favicon.ico"));
|
|
2616
2609
|
function escapeHtml(s) {
|
|
2617
2610
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
2618
2611
|
}
|
|
@@ -2764,6 +2757,132 @@ body{
|
|
|
2764
2757
|
.app-link-name{font-weight:600;font-size:.875rem;color:#33ff00;}
|
|
2765
2758
|
.app-link-scopes{font-size:.6875rem;color:#1a8c00;margin-top:1px;}
|
|
2766
2759
|
.empty{color:#1a8c00;text-align:center;padding:28px 0;font-size:.875rem;}
|
|
2760
|
+
|
|
2761
|
+
.inspector-layout{max-width:960px;margin:0 auto;padding:28px 20px;}
|
|
2762
|
+
.inspector-tabs{display:flex;gap:4px;margin-bottom:20px;}
|
|
2763
|
+
.inspector-tabs a{
|
|
2764
|
+
padding:7px 16px;border-radius:6px;text-decoration:none;
|
|
2765
|
+
font-size:.8125rem;color:#1a8c00;border:1px solid transparent;
|
|
2766
|
+
transition:color .15s,border-color .15s;
|
|
2767
|
+
}
|
|
2768
|
+
.inspector-tabs a:hover{color:#33ff00;}
|
|
2769
|
+
.inspector-tabs a.active{color:#33ff00;font-weight:600;border-color:#0a3300;background:#0a3300;}
|
|
2770
|
+
.inspector-section{margin-bottom:24px;}
|
|
2771
|
+
.inspector-section h2{
|
|
2772
|
+
font-family:'Geist Pixel',monospace;
|
|
2773
|
+
font-size:1rem;font-weight:600;color:#33ff00;margin-bottom:10px;
|
|
2774
|
+
}
|
|
2775
|
+
.inspector-section h3{
|
|
2776
|
+
font-family:'Geist Pixel',monospace;
|
|
2777
|
+
font-size:.875rem;font-weight:600;color:#1a8c00;margin:16px 0 8px;
|
|
2778
|
+
}
|
|
2779
|
+
.inspector-table{width:100%;border-collapse:collapse;margin-bottom:12px;}
|
|
2780
|
+
.inspector-table th,.inspector-table td{
|
|
2781
|
+
text-align:left;padding:8px 12px;border-bottom:1px solid #0a3300;
|
|
2782
|
+
font-size:.8125rem;
|
|
2783
|
+
}
|
|
2784
|
+
.inspector-table th{color:#1a8c00;font-weight:600;font-size:.75rem;text-transform:uppercase;letter-spacing:.04em;}
|
|
2785
|
+
.inspector-table td{color:#33ff00;}
|
|
2786
|
+
.inspector-table tbody tr{transition:background .1s;}
|
|
2787
|
+
.inspector-table tbody tr:hover{background:#0a3300;}
|
|
2788
|
+
.inspector-empty{color:#1a8c00;text-align:center;padding:20px 0;font-size:.8125rem;}
|
|
2789
|
+
|
|
2790
|
+
.checkout-layout{
|
|
2791
|
+
display:flex;min-height:calc(100vh - 42px);
|
|
2792
|
+
}
|
|
2793
|
+
.checkout-summary{
|
|
2794
|
+
flex:1;background:#020;padding:48px 40px 48px 10%;
|
|
2795
|
+
display:flex;flex-direction:column;justify-content:center;
|
|
2796
|
+
border-right:1px solid #0a3300;
|
|
2797
|
+
}
|
|
2798
|
+
.checkout-form-side{
|
|
2799
|
+
flex:1;background:#000;padding:48px 10% 48px 40px;
|
|
2800
|
+
display:flex;flex-direction:column;justify-content:center;
|
|
2801
|
+
}
|
|
2802
|
+
.checkout-merchant{
|
|
2803
|
+
display:flex;align-items:center;gap:10px;margin-bottom:6px;
|
|
2804
|
+
}
|
|
2805
|
+
.checkout-merchant-name{
|
|
2806
|
+
font-family:'Geist Pixel',monospace;
|
|
2807
|
+
font-size:.9375rem;font-weight:600;color:#33ff00;
|
|
2808
|
+
}
|
|
2809
|
+
.checkout-test-badge{
|
|
2810
|
+
font-size:.625rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
|
|
2811
|
+
background:#0a3300;color:#1a8c00;padding:2px 8px;border-radius:4px;
|
|
2812
|
+
}
|
|
2813
|
+
.checkout-total{
|
|
2814
|
+
font-family:'Geist Pixel',monospace;
|
|
2815
|
+
font-size:2rem;font-weight:700;color:#33ff00;margin:8px 0 28px;
|
|
2816
|
+
}
|
|
2817
|
+
.checkout-line-item{
|
|
2818
|
+
display:flex;align-items:center;gap:14px;padding:14px 0;
|
|
2819
|
+
border-bottom:1px solid #0a3300;
|
|
2820
|
+
}
|
|
2821
|
+
.checkout-line-item:first-child{border-top:1px solid #0a3300;}
|
|
2822
|
+
.checkout-item-icon{
|
|
2823
|
+
width:42px;height:42px;border-radius:6px;background:#0a3300;
|
|
2824
|
+
display:flex;align-items:center;justify-content:center;flex-shrink:0;
|
|
2825
|
+
font-family:'Geist Pixel',monospace;font-size:.875rem;font-weight:700;color:#116600;
|
|
2826
|
+
}
|
|
2827
|
+
.checkout-item-details{flex:1;min-width:0;}
|
|
2828
|
+
.checkout-item-name{font-size:.875rem;font-weight:600;color:#33ff00;}
|
|
2829
|
+
.checkout-item-qty{font-size:.75rem;color:#1a8c00;margin-top:2px;}
|
|
2830
|
+
.checkout-item-price{
|
|
2831
|
+
font-size:.875rem;font-weight:600;color:#33ff00;text-align:right;white-space:nowrap;
|
|
2832
|
+
}
|
|
2833
|
+
.checkout-item-unit{font-size:.6875rem;color:#1a8c00;text-align:right;margin-top:2px;}
|
|
2834
|
+
.checkout-totals{margin-top:20px;}
|
|
2835
|
+
.checkout-totals-row{
|
|
2836
|
+
display:flex;justify-content:space-between;padding:6px 0;
|
|
2837
|
+
font-size:.8125rem;color:#1a8c00;
|
|
2838
|
+
}
|
|
2839
|
+
.checkout-totals-row.total{
|
|
2840
|
+
border-top:1px solid #0a3300;margin-top:8px;padding-top:14px;
|
|
2841
|
+
font-size:.9375rem;font-weight:600;color:#33ff00;
|
|
2842
|
+
}
|
|
2843
|
+
.checkout-form-section{margin-bottom:24px;}
|
|
2844
|
+
.checkout-form-label{
|
|
2845
|
+
font-size:.8125rem;font-weight:600;color:#33ff00;margin-bottom:8px;display:block;
|
|
2846
|
+
}
|
|
2847
|
+
.checkout-input{
|
|
2848
|
+
width:100%;padding:10px 12px;border:1px solid #0a3300;border-radius:6px;
|
|
2849
|
+
background:#020;color:#33ff00;font:inherit;font-size:.875rem;
|
|
2850
|
+
transition:border-color .15s;outline:none;
|
|
2851
|
+
}
|
|
2852
|
+
.checkout-input:focus{border-color:#33ff00;}
|
|
2853
|
+
.checkout-input::placeholder{color:#116600;}
|
|
2854
|
+
.checkout-card-box{
|
|
2855
|
+
border:1px solid #0a3300;border-radius:6px;padding:14px;
|
|
2856
|
+
background:#020;
|
|
2857
|
+
}
|
|
2858
|
+
.checkout-card-row{
|
|
2859
|
+
display:flex;gap:12px;margin-top:10px;
|
|
2860
|
+
}
|
|
2861
|
+
.checkout-card-row .checkout-input{flex:1;}
|
|
2862
|
+
.checkout-sim-note{
|
|
2863
|
+
font-size:.6875rem;color:#1a8c00;margin-top:10px;text-align:center;
|
|
2864
|
+
font-style:italic;
|
|
2865
|
+
}
|
|
2866
|
+
.checkout-pay-btn{
|
|
2867
|
+
width:100%;padding:14px;border:none;border-radius:8px;
|
|
2868
|
+
background:#33ff00;color:#000;font:inherit;font-size:.9375rem;font-weight:700;
|
|
2869
|
+
cursor:pointer;transition:background .15s;
|
|
2870
|
+
font-family:'Geist Pixel',monospace;
|
|
2871
|
+
}
|
|
2872
|
+
.checkout-pay-btn:hover{background:#44ff22;}
|
|
2873
|
+
.checkout-cancel{
|
|
2874
|
+
text-align:center;margin-top:14px;
|
|
2875
|
+
}
|
|
2876
|
+
.checkout-cancel a{
|
|
2877
|
+
color:#1a8c00;text-decoration:none;font-size:.8125rem;
|
|
2878
|
+
transition:color .15s;
|
|
2879
|
+
}
|
|
2880
|
+
.checkout-cancel a:hover{color:#33ff00;}
|
|
2881
|
+
@media(max-width:768px){
|
|
2882
|
+
.checkout-layout{flex-direction:column;}
|
|
2883
|
+
.checkout-summary{padding:32px 20px;border-right:none;border-bottom:1px solid #0a3300;}
|
|
2884
|
+
.checkout-form-side{padding:32px 20px;}
|
|
2885
|
+
}
|
|
2767
2886
|
`;
|
|
2768
2887
|
var POWERED_BY = `<div class="powered-by">Powered by <a href="https://emulate.dev" target="_blank" rel="noopener">emulate</a></div>`;
|
|
2769
2888
|
function emuBar(service) {
|
|
@@ -2783,6 +2902,7 @@ function head(title) {
|
|
|
2783
2902
|
<head>
|
|
2784
2903
|
<meta charset="utf-8"/>
|
|
2785
2904
|
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
2905
|
+
<link rel="icon" href="/_emulate/favicon.ico"/>
|
|
2786
2906
|
<title>${escapeHtml(title)} | emulate</title>
|
|
2787
2907
|
<style>${CSS}</style>
|
|
2788
2908
|
</head>`;
|
|
@@ -2884,6 +3004,7 @@ async function createIdToken(user, clientId, nonce, baseUrl) {
|
|
|
2884
3004
|
family_name: user.family_name,
|
|
2885
3005
|
picture: user.picture,
|
|
2886
3006
|
locale: user.locale,
|
|
3007
|
+
...user.hd ? { hd: user.hd } : {},
|
|
2887
3008
|
...nonce ? { nonce } : {}
|
|
2888
3009
|
}).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuer(baseUrl).setAudience(clientId).setIssuedAt().setExpirationTime("1h");
|
|
2889
3010
|
return builder.sign(JWT_SECRET);
|
|
@@ -2911,7 +3032,8 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
2911
3032
|
"given_name",
|
|
2912
3033
|
"family_name",
|
|
2913
3034
|
"picture",
|
|
2914
|
-
"locale"
|
|
3035
|
+
"locale",
|
|
3036
|
+
"hd"
|
|
2915
3037
|
],
|
|
2916
3038
|
code_challenge_methods_supported: ["plain", "S256"]
|
|
2917
3039
|
});
|
|
@@ -2939,7 +3061,11 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
2939
3061
|
}
|
|
2940
3062
|
if (redirect_uri && !matchesRedirectUri(redirect_uri, client.redirect_uris)) {
|
|
2941
3063
|
return c.html(
|
|
2942
|
-
renderErrorPage(
|
|
3064
|
+
renderErrorPage(
|
|
3065
|
+
"Redirect URI mismatch",
|
|
3066
|
+
"The redirect_uri is not registered for this application.",
|
|
3067
|
+
SERVICE_LABEL
|
|
3068
|
+
),
|
|
2943
3069
|
400
|
|
2944
3070
|
);
|
|
2945
3071
|
}
|
|
@@ -3051,7 +3177,13 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
3051
3177
|
});
|
|
3052
3178
|
}
|
|
3053
3179
|
if (grant_type !== "authorization_code") {
|
|
3054
|
-
return c.json(
|
|
3180
|
+
return c.json(
|
|
3181
|
+
{
|
|
3182
|
+
error: "unsupported_grant_type",
|
|
3183
|
+
error_description: "Only authorization_code and refresh_token are supported."
|
|
3184
|
+
},
|
|
3185
|
+
400
|
|
3186
|
+
);
|
|
3055
3187
|
}
|
|
3056
3188
|
const pendingMap = getPendingCodes(store);
|
|
3057
3189
|
const pending = pendingMap.get(code);
|
|
@@ -3124,7 +3256,8 @@ function oauthRoutes({ app, store, baseUrl, tokenMap }) {
|
|
|
3124
3256
|
given_name: user.given_name,
|
|
3125
3257
|
family_name: user.family_name,
|
|
3126
3258
|
picture: user.picture,
|
|
3127
|
-
locale: user.locale
|
|
3259
|
+
locale: user.locale,
|
|
3260
|
+
...user.hd ? { hd: user.hd } : {}
|
|
3128
3261
|
});
|
|
3129
3262
|
});
|
|
3130
3263
|
app.post("/oauth2/revoke", async (c) => {
|
|
@@ -3174,7 +3307,13 @@ function settingsRoutes({ app, store }) {
|
|
|
3174
3307
|
}
|
|
3175
3308
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, [...addLabelIds, ...removeLabelIds]);
|
|
3176
3309
|
if (missingLabelIds.length > 0) {
|
|
3177
|
-
return googleApiError(
|
|
3310
|
+
return googleApiError(
|
|
3311
|
+
c,
|
|
3312
|
+
400,
|
|
3313
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
3314
|
+
"invalidArgument",
|
|
3315
|
+
"INVALID_ARGUMENT"
|
|
3316
|
+
);
|
|
3178
3317
|
}
|
|
3179
3318
|
if (findMatchingFilter(gs, {
|
|
3180
3319
|
user_email: authEmail,
|
|
@@ -3277,14 +3416,16 @@ function threadRoutes({ app, store }) {
|
|
|
3277
3416
|
const removeLabelIds = getStringArray(body, "removeLabelIds");
|
|
3278
3417
|
const missingLabelIds = findMissingLabelIds(gs, authEmail, [...addLabelIds, ...removeLabelIds]);
|
|
3279
3418
|
if (missingLabelIds.length > 0) {
|
|
3280
|
-
return googleApiError(
|
|
3419
|
+
return googleApiError(
|
|
3420
|
+
c,
|
|
3421
|
+
400,
|
|
3422
|
+
`Invalid label IDs: ${missingLabelIds.join(", ")}`,
|
|
3423
|
+
"invalidArgument",
|
|
3424
|
+
"INVALID_ARGUMENT"
|
|
3425
|
+
);
|
|
3281
3426
|
}
|
|
3282
3427
|
const updated = messages.map(
|
|
3283
|
-
(message) => markMessageModified(
|
|
3284
|
-
gs,
|
|
3285
|
-
message,
|
|
3286
|
-
applyLabelMutation(message.label_ids, addLabelIds, removeLabelIds)
|
|
3287
|
-
)
|
|
3428
|
+
(message) => markMessageModified(gs, message, applyLabelMutation(message.label_ids, addLabelIds, removeLabelIds))
|
|
3288
3429
|
);
|
|
3289
3430
|
return c.json(formatThreadResource(gs, updated, "full"));
|
|
3290
3431
|
});
|
|
@@ -3333,120 +3474,148 @@ function seedDefaults(store, _baseUrl) {
|
|
|
3333
3474
|
family_name: "User",
|
|
3334
3475
|
picture: null,
|
|
3335
3476
|
email_verified: true,
|
|
3336
|
-
locale: "en"
|
|
3477
|
+
locale: "en",
|
|
3478
|
+
hd: null
|
|
3337
3479
|
});
|
|
3338
3480
|
}
|
|
3339
3481
|
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
|
-
|
|
3482
|
+
seedCalendars(
|
|
3483
|
+
store,
|
|
3484
|
+
[
|
|
3485
|
+
{
|
|
3486
|
+
id: "primary",
|
|
3487
|
+
user_email: defaultEmail,
|
|
3488
|
+
summary: defaultEmail,
|
|
3489
|
+
primary: true,
|
|
3490
|
+
selected: true,
|
|
3491
|
+
time_zone: "UTC"
|
|
3492
|
+
},
|
|
3493
|
+
{
|
|
3494
|
+
id: "cal_team",
|
|
3495
|
+
user_email: defaultEmail,
|
|
3496
|
+
summary: "Team Calendar",
|
|
3497
|
+
description: "Shared team events",
|
|
3498
|
+
selected: true,
|
|
3499
|
+
time_zone: "UTC"
|
|
3500
|
+
}
|
|
3501
|
+
],
|
|
3502
|
+
defaultEmail
|
|
3503
|
+
);
|
|
3504
|
+
seedCalendarEvents(
|
|
3505
|
+
store,
|
|
3506
|
+
[
|
|
3507
|
+
{
|
|
3508
|
+
id: "evt_standup",
|
|
3509
|
+
user_email: defaultEmail,
|
|
3510
|
+
calendar_id: "primary",
|
|
3511
|
+
summary: "Daily Standup",
|
|
3512
|
+
description: "Team sync",
|
|
3513
|
+
start_date_time: new Date(Date.now() + 60 * 60 * 1e3).toISOString(),
|
|
3514
|
+
end_date_time: new Date(Date.now() + 90 * 60 * 1e3).toISOString(),
|
|
3515
|
+
attendees: [
|
|
3516
|
+
{ email: defaultEmail, display_name: "Test User" },
|
|
3517
|
+
{ email: "teammate@example.com", display_name: "Teammate" }
|
|
3518
|
+
],
|
|
3519
|
+
conference_entry_points: [
|
|
3520
|
+
{
|
|
3521
|
+
entry_point_type: "video",
|
|
3522
|
+
uri: "https://meet.google.com/emulate-standup",
|
|
3523
|
+
label: "Google Meet"
|
|
3524
|
+
}
|
|
3525
|
+
],
|
|
3526
|
+
hangout_link: "https://meet.google.com/emulate-standup"
|
|
3527
|
+
}
|
|
3528
|
+
],
|
|
3529
|
+
defaultEmail
|
|
3530
|
+
);
|
|
3531
|
+
seedDriveItems(
|
|
3532
|
+
store,
|
|
3533
|
+
[
|
|
3534
|
+
{
|
|
3535
|
+
id: "drv_root_receipts",
|
|
3536
|
+
user_email: defaultEmail,
|
|
3537
|
+
name: "Receipts",
|
|
3538
|
+
mime_type: "application/vnd.google-apps.folder",
|
|
3539
|
+
parent_ids: ["root"]
|
|
3540
|
+
},
|
|
3541
|
+
{
|
|
3542
|
+
id: "drv_receipt_pdf",
|
|
3543
|
+
user_email: defaultEmail,
|
|
3544
|
+
name: "March Receipt.pdf",
|
|
3545
|
+
mime_type: "application/pdf",
|
|
3546
|
+
parent_ids: ["drv_root_receipts"],
|
|
3547
|
+
data: "receipt-pdf-data"
|
|
3548
|
+
}
|
|
3549
|
+
],
|
|
3550
|
+
defaultEmail
|
|
3551
|
+
);
|
|
3552
|
+
seedMessages(
|
|
3553
|
+
store,
|
|
3554
|
+
[
|
|
3555
|
+
{
|
|
3556
|
+
id: "msg_welcome",
|
|
3557
|
+
thread_id: "thr_welcome",
|
|
3558
|
+
user_email: defaultEmail,
|
|
3559
|
+
from: "Welcome Team <welcome@example.com>",
|
|
3560
|
+
to: defaultEmail,
|
|
3561
|
+
subject: "Welcome to your local Gmail emulator",
|
|
3562
|
+
snippet: "Your OAuth flow is set up and Gmail message, thread, and label APIs are ready.",
|
|
3563
|
+
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.",
|
|
3564
|
+
label_ids: ["INBOX", "UNREAD", "CATEGORY_UPDATES"],
|
|
3565
|
+
date: new Date(Date.now() - 60 * 60 * 1e3).toISOString()
|
|
3566
|
+
},
|
|
3567
|
+
{
|
|
3568
|
+
id: "msg_build",
|
|
3569
|
+
thread_id: "thr_build",
|
|
3570
|
+
user_email: defaultEmail,
|
|
3571
|
+
from: "Build Bot <builds@example.com>",
|
|
3572
|
+
to: defaultEmail,
|
|
3573
|
+
subject: "Nightly build finished successfully",
|
|
3574
|
+
snippet: "The latest build completed successfully in 6 minutes.",
|
|
3575
|
+
body_text: "The latest build completed successfully in 6 minutes.\n\nArtifact upload finished and smoke checks passed.",
|
|
3576
|
+
label_ids: ["INBOX", "CATEGORY_UPDATES"],
|
|
3577
|
+
date: new Date(Date.now() - 2 * 60 * 60 * 1e3).toISOString()
|
|
3578
|
+
},
|
|
3579
|
+
{
|
|
3580
|
+
id: "msg_build_reply",
|
|
3581
|
+
thread_id: "thr_build",
|
|
3582
|
+
user_email: defaultEmail,
|
|
3583
|
+
from: defaultEmail,
|
|
3584
|
+
to: "Build Bot <builds@example.com>",
|
|
3585
|
+
subject: "Re: Nightly build finished successfully",
|
|
3586
|
+
snippet: "Thanks, I will review the artifact after lunch.",
|
|
3587
|
+
body_text: "Thanks, I will review the artifact after lunch.",
|
|
3588
|
+
label_ids: ["SENT"],
|
|
3589
|
+
date: new Date(Date.now() - 90 * 60 * 1e3).toISOString(),
|
|
3590
|
+
in_reply_to: "<msg_build@emulate.google.local>",
|
|
3591
|
+
references: "<msg_build@emulate.google.local>"
|
|
3592
|
+
},
|
|
3593
|
+
{
|
|
3594
|
+
id: "msg_draft",
|
|
3595
|
+
thread_id: "thr_draft",
|
|
3596
|
+
user_email: defaultEmail,
|
|
3597
|
+
from: defaultEmail,
|
|
3598
|
+
to: "someone@example.com",
|
|
3599
|
+
subject: "Draft follow-up",
|
|
3600
|
+
snippet: "Checking in on the open question from yesterday.",
|
|
3601
|
+
body_text: "Checking in on the open question from yesterday.",
|
|
3602
|
+
label_ids: ["DRAFT"],
|
|
3603
|
+
date: new Date(Date.now() - 30 * 60 * 1e3).toISOString()
|
|
3604
|
+
}
|
|
3605
|
+
],
|
|
3606
|
+
defaultEmail
|
|
3607
|
+
);
|
|
3608
|
+
}
|
|
3609
|
+
var CONSUMER_EMAIL_DOMAINS = /* @__PURE__ */ new Set(["gmail.com", "googlemail.com"]);
|
|
3610
|
+
function deriveHd(email) {
|
|
3611
|
+
const domain = email.split("@")[1]?.toLowerCase();
|
|
3612
|
+
if (!domain) return null;
|
|
3613
|
+
if (CONSUMER_EMAIL_DOMAINS.has(domain)) return null;
|
|
3614
|
+
return domain;
|
|
3615
|
+
}
|
|
3616
|
+
function resolveHd(user) {
|
|
3617
|
+
if (user.hd !== void 0) return user.hd || null;
|
|
3618
|
+
return deriveHd(user.email);
|
|
3450
3619
|
}
|
|
3451
3620
|
function seedFromConfig(store, _baseUrl, config) {
|
|
3452
3621
|
const gs = getGoogleStore(store);
|
|
@@ -3463,7 +3632,8 @@ function seedFromConfig(store, _baseUrl, config) {
|
|
|
3463
3632
|
family_name: user.family_name ?? nameParts.slice(1).join(" "),
|
|
3464
3633
|
picture: user.picture ?? null,
|
|
3465
3634
|
email_verified: user.email_verified ?? true,
|
|
3466
|
-
locale: user.locale ?? "en"
|
|
3635
|
+
locale: user.locale ?? "en",
|
|
3636
|
+
hd: resolveHd(user)
|
|
3467
3637
|
});
|
|
3468
3638
|
}
|
|
3469
3639
|
ensureSystemLabels(gs, user.email);
|
|
@@ -3524,29 +3694,33 @@ function seedMessages(store, messages, fallbackEmail) {
|
|
|
3524
3694
|
const userEmail = message.user_email ?? fallbackEmail;
|
|
3525
3695
|
ensureSystemLabels(gs, userEmail);
|
|
3526
3696
|
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
|
-
|
|
3697
|
+
createStoredMessage(
|
|
3698
|
+
gs,
|
|
3699
|
+
{
|
|
3700
|
+
gmail_id: message.id,
|
|
3701
|
+
thread_id: message.thread_id,
|
|
3702
|
+
user_email: userEmail,
|
|
3703
|
+
raw: message.raw ?? null,
|
|
3704
|
+
from: message.from,
|
|
3705
|
+
to: message.to,
|
|
3706
|
+
cc: message.cc ?? null,
|
|
3707
|
+
bcc: message.bcc ?? null,
|
|
3708
|
+
reply_to: message.reply_to ?? null,
|
|
3709
|
+
subject: message.subject,
|
|
3710
|
+
snippet: message.snippet,
|
|
3711
|
+
body_text: message.body_text ?? null,
|
|
3712
|
+
body_html: message.body_html ?? null,
|
|
3713
|
+
label_ids: message.label_ids ?? ["INBOX", "UNREAD"],
|
|
3714
|
+
date: message.date,
|
|
3715
|
+
internal_date: message.internal_date,
|
|
3716
|
+
message_id: message.message_id,
|
|
3717
|
+
references: message.references ?? null,
|
|
3718
|
+
in_reply_to: message.in_reply_to ?? null
|
|
3719
|
+
},
|
|
3720
|
+
{
|
|
3721
|
+
createMissingCustomLabels: true
|
|
3722
|
+
}
|
|
3723
|
+
);
|
|
3550
3724
|
}
|
|
3551
3725
|
}
|
|
3552
3726
|
function seedCalendars(store, calendars, fallbackEmail) {
|
|
@@ -3638,4 +3812,4 @@ export {
|
|
|
3638
3812
|
googlePlugin,
|
|
3639
3813
|
seedFromConfig
|
|
3640
3814
|
};
|
|
3641
|
-
//# sourceMappingURL=dist-
|
|
3815
|
+
//# sourceMappingURL=dist-ZY5SZSJ2.js.map
|