@anuma/sdk 6.31.2 → 6.31.3

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.
@@ -277,12 +277,16 @@ function buildUpdateEventBody(args) {
277
277
  }
278
278
  return eventBody;
279
279
  }
280
+ var CALENDAR_EVENT_ID = /^[A-Za-z0-9_]+$/;
280
281
  async function updateCalendarEvent(accessToken, args) {
281
282
  const { eventId } = args;
283
+ if (typeof eventId !== "string" || !CALENDAR_EVENT_ID.test(eventId)) {
284
+ return `Error: Invalid event ID: ${String(eventId)}`;
285
+ }
282
286
  const eventBody = buildUpdateEventBody(args);
283
287
  try {
284
288
  const response = await fetch(
285
- `https://www.googleapis.com/calendar/v3/calendars/primary/events/${eventId}`,
289
+ `https://www.googleapis.com/calendar/v3/calendars/primary/events/${encodeURIComponent(eventId)}`,
286
290
  {
287
291
  method: "PATCH",
288
292
  headers: {
@@ -1151,55 +1155,40 @@ function createWeatherTool(options, weatherOptions) {
1151
1155
 
1152
1156
  // src/lib/connectors/errors.ts
1153
1157
  var CONNECTOR_ERROR_MARKER = "__anuma_connector_error_v1";
1154
- function buildConnectorErrorResult(code, provider, connectUrl, extras) {
1158
+ function buildConnectorErrorResult(code, provider, extras) {
1155
1159
  const payload = {
1156
1160
  __anuma_connector_error_v1: true,
1157
1161
  code,
1158
1162
  provider,
1159
- connect_url: connectUrl,
1160
1163
  missing_scopes: extras?.missingScopes,
1161
1164
  required: extras?.required
1162
1165
  };
1163
1166
  return JSON.stringify(payload);
1164
1167
  }
1165
1168
 
1166
- // src/lib/logger.ts
1167
- var consoleLogger = {
1168
- debug: console.log.bind(console),
1169
- info: console.info.bind(console),
1170
- warn: console.warn.bind(console),
1171
- error: console.error.bind(console)
1172
- };
1173
- var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
1174
- var loggerGlobal = globalThis;
1175
- var fallbackLoggerState = { logger: consoleLogger };
1176
- var fallbackWarned = false;
1177
- function getLoggerState() {
1178
- try {
1179
- return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
1180
- } catch {
1181
- if (!fallbackWarned) {
1182
- fallbackWarned = true;
1183
- fallbackLoggerState.logger.warn(
1184
- "@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
1185
- );
1186
- }
1187
- return fallbackLoggerState;
1188
- }
1189
- }
1190
- function getLogger() {
1191
- return getLoggerState().logger;
1192
- }
1193
-
1194
1169
  // src/tools/googleDrive.ts
1195
1170
  var DRIVE_PROVIDER = "gdrive";
1171
+ var DRIVE_FILE_ID = /^[A-Za-z0-9_-]+$/;
1172
+ var DRIVE_MIME_TYPE = /^[\w.+-]+\/[\w.+-]+$/;
1173
+ function invalidFileIdError(fileId) {
1174
+ return `Error: Invalid file ID: ${String(fileId)}`;
1175
+ }
1176
+ function escapeDriveQueryValue(value) {
1177
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
1178
+ }
1179
+ function withMimeTypeFilter(driveQuery, mimeType) {
1180
+ if (!mimeType) return driveQuery;
1181
+ if (!DRIVE_MIME_TYPE.test(mimeType)) return { error: `Error: Invalid mimeType: ${mimeType}` };
1182
+ return `${driveQuery} and mimeType = '${escapeDriveQueryValue(mimeType)}'`;
1183
+ }
1196
1184
  async function searchDriveFiles(accessToken, args) {
1197
1185
  const { query, maxResults = 10, mimeType } = args;
1198
- let driveQuery = `fullText contains '${query.replace(/'/g, "\\'")}'`;
1199
- if (mimeType) {
1200
- driveQuery += ` and mimeType = '${mimeType}'`;
1201
- }
1202
- driveQuery += " and trashed = false";
1186
+ const filtered = withMimeTypeFilter(
1187
+ `fullText contains '${escapeDriveQueryValue(query)}'`,
1188
+ mimeType
1189
+ );
1190
+ if (typeof filtered !== "string") return filtered.error;
1191
+ const driveQuery = `${filtered} and trashed = false`;
1203
1192
  const params = new URLSearchParams({
1204
1193
  q: driveQuery,
1205
1194
  pageSize: String(maxResults),
@@ -1292,10 +1281,8 @@ function createGoogleDriveSearchTool(getAccessToken, requestDriveAccess) {
1292
1281
  }
1293
1282
  async function listRecentDriveFiles(accessToken, args) {
1294
1283
  const { maxResults = 10, mimeType } = args;
1295
- let driveQuery = "trashed = false";
1296
- if (mimeType) {
1297
- driveQuery += ` and mimeType = '${mimeType}'`;
1298
- }
1284
+ const driveQuery = withMimeTypeFilter("trashed = false", mimeType);
1285
+ if (typeof driveQuery !== "string") return driveQuery.error;
1299
1286
  const params = new URLSearchParams({
1300
1287
  q: driveQuery,
1301
1288
  pageSize: String(maxResults),
@@ -1382,7 +1369,7 @@ function createGoogleDriveListRecentTool(getAccessToken, requestDriveAccess) {
1382
1369
  };
1383
1370
  }
1384
1371
  async function findFileByName(accessToken, fileName) {
1385
- const driveQuery = `name contains '${fileName.replace(/'/g, "\\'")}' and trashed = false`;
1372
+ const driveQuery = `name contains '${escapeDriveQueryValue(fileName)}' and trashed = false`;
1386
1373
  const params = new URLSearchParams({
1387
1374
  q: driveQuery,
1388
1375
  pageSize: "1",
@@ -1412,24 +1399,22 @@ var GOOGLE_DOCS_EXPORT_TYPES = {
1412
1399
  var MAX_CONTENT_LENGTH = 5e4;
1413
1400
  async function resolveFileId(accessToken, fileId, fileName) {
1414
1401
  if (fileId) {
1415
- return { fileId };
1402
+ return DRIVE_FILE_ID.test(fileId) ? { fileId } : { error: invalidFileIdError(fileId) };
1416
1403
  }
1417
1404
  if (fileName) {
1418
- getLogger().debug("[google_drive_get_content] Searching for file by name:", fileName);
1419
1405
  const foundId = await findFileByName(accessToken, fileName);
1420
1406
  if (!foundId) {
1421
1407
  return {
1422
1408
  error: `Error: Could not find a file matching "${fileName}". Please check the file name and try again.`
1423
1409
  };
1424
1410
  }
1425
- getLogger().debug("[google_drive_get_content] Found file ID:", foundId);
1426
- return { fileId: foundId };
1411
+ return DRIVE_FILE_ID.test(foundId) ? { fileId: foundId } : { error: invalidFileIdError(foundId) };
1427
1412
  }
1428
1413
  return { error: "Error: Please provide either a fileId or fileName to get file content." };
1429
1414
  }
1430
1415
  async function fetchFileMetadata(accessToken, fileId) {
1431
1416
  const response = await fetch(
1432
- `https://www.googleapis.com/drive/v3/files/${fileId}?fields=id,name,mimeType,webViewLink&supportsAllDrives=true`,
1417
+ `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}?fields=id,name,mimeType,webViewLink&supportsAllDrives=true`,
1433
1418
  { headers: { Authorization: `Bearer ${accessToken}` } }
1434
1419
  );
1435
1420
  if (!response.ok) {
@@ -1447,13 +1432,13 @@ function getContentUrl(fileId, mimeType) {
1447
1432
  if (GOOGLE_DOCS_EXPORT_TYPES[mimeType]) {
1448
1433
  const exportMimeType = GOOGLE_DOCS_EXPORT_TYPES[mimeType];
1449
1434
  return {
1450
- url: `https://www.googleapis.com/drive/v3/files/${fileId}/export?mimeType=${encodeURIComponent(exportMimeType)}&supportsAllDrives=true`,
1435
+ url: `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}/export?mimeType=${encodeURIComponent(exportMimeType)}&supportsAllDrives=true`,
1451
1436
  isExport: true
1452
1437
  };
1453
1438
  }
1454
1439
  if (mimeType.startsWith("text/") || mimeType === "application/json" || mimeType === "application/xml") {
1455
1440
  return {
1456
- url: `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media&supportsAllDrives=true`,
1441
+ url: `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}?alt=media&supportsAllDrives=true`,
1457
1442
  isExport: false
1458
1443
  };
1459
1444
  }
@@ -1470,7 +1455,7 @@ Type: PDF${linkInfo}
1470
1455
  Note: PDF content cannot be extracted directly in the browser. The user can click the link above to view the PDF in Google Drive.`;
1471
1456
  }
1472
1457
  if (mimeType.startsWith("image/")) {
1473
- const directUrl = `https://drive.google.com/uc?export=view&id=${fileId}`;
1458
+ const directUrl = `https://drive.google.com/uc?export=view&id=${encodeURIComponent(fileId)}`;
1474
1459
  return `File: ${name}
1475
1460
  Type: ${mimeType}${linkInfo}
1476
1461
  Direct image URL: ${directUrl}
@@ -1505,7 +1490,6 @@ Type: ${metadata.mimeType}${isExport ? " (exported as text)" : ""}
1505
1490
  return header + displayContent + footer;
1506
1491
  }
1507
1492
  async function getDriveFileContent(accessToken, args) {
1508
- getLogger().debug("[google_drive_get_content] Starting with:", args);
1509
1493
  const fileIdResult = await resolveFileId(accessToken, args.fileId, args.fileName);
1510
1494
  if ("error" in fileIdResult) {
1511
1495
  return fileIdResult.error;
@@ -1517,7 +1501,6 @@ async function getDriveFileContent(accessToken, args) {
1517
1501
  return metadataResult.error;
1518
1502
  }
1519
1503
  const { metadata } = metadataResult;
1520
- getLogger().debug("[google_drive_get_content] File metadata:", metadata);
1521
1504
  const contentUrlResult = getContentUrl(fileId, metadata.mimeType);
1522
1505
  if (!contentUrlResult) {
1523
1506
  return formatNonTextFileResponse(fileId, metadata);
@@ -1554,10 +1537,8 @@ function createGoogleDriveGetContentTool(getAccessToken, requestDriveAccess) {
1554
1537
  }
1555
1538
  },
1556
1539
  executor: async (args) => {
1557
- getLogger().debug("[google_drive_get_content] Executor called with args:", args);
1558
1540
  let token = getAccessToken();
1559
1541
  if (!token) {
1560
- getLogger().debug("[google_drive_get_content] No token, requesting access...");
1561
1542
  try {
1562
1543
  token = await requestDriveAccess();
1563
1544
  } catch {
@@ -1571,14 +1552,7 @@ function createGoogleDriveGetContentTool(getAccessToken, requestDriveAccess) {
1571
1552
  fileId: args.fileId,
1572
1553
  fileName: args.fileName
1573
1554
  };
1574
- const result = await getDriveFileContent(token, typedArgs);
1575
- getLogger().debug(
1576
- "[google_drive_get_content] Result length:",
1577
- result.length,
1578
- "First 200 chars:",
1579
- result.slice(0, 200)
1580
- );
1581
- return result;
1555
+ return getDriveFileContent(token, typedArgs);
1582
1556
  }
1583
1557
  };
1584
1558
  }
@@ -1679,6 +1653,9 @@ function createGoogleDriveCreateFileTool(getAccessToken, requestDriveAccess) {
1679
1653
  };
1680
1654
  }
1681
1655
  async function updateDriveFile(accessToken, args) {
1656
+ if (typeof args.fileId !== "string" || !DRIVE_FILE_ID.test(args.fileId)) {
1657
+ return invalidFileIdError(args.fileId);
1658
+ }
1682
1659
  const mimeType = (args.mimeType || "text/plain").replace(/[\r\n]/g, "");
1683
1660
  if (NATIVE_GOOGLE_MIME_TYPE.test(mimeType)) {
1684
1661
  return NATIVE_GOOGLE_MIME_ERROR;
@@ -2357,22 +2334,17 @@ function notionConnectorError(status, json) {
2357
2334
  return buildConnectorErrorResult(
2358
2335
  "scope_not_covered",
2359
2336
  NOTION_PROVIDER,
2360
- readString(json, "connect_url"),
2361
2337
  Array.isArray(missingScopes) ? { missingScopes } : void 0
2362
2338
  );
2363
2339
  }
2364
2340
  case "insufficient_scope":
2365
- return buildConnectorErrorResult("insufficient_scope", NOTION_PROVIDER, void 0, {
2341
+ return buildConnectorErrorResult("insufficient_scope", NOTION_PROVIDER, {
2366
2342
  required: readString(json, "required")
2367
2343
  });
2368
2344
  case "upstream_unavailable":
2369
2345
  return buildConnectorErrorResult("upstream_unavailable", NOTION_PROVIDER);
2370
2346
  default:
2371
- return buildConnectorErrorResult(
2372
- "connector_not_connected",
2373
- NOTION_PROVIDER,
2374
- readString(json, "connect_url")
2375
- );
2347
+ return buildConnectorErrorResult("connector_not_connected", NOTION_PROVIDER);
2376
2348
  }
2377
2349
  }
2378
2350
  function proxyRunner(callMcp) {
@@ -2888,6 +2860,34 @@ async function callNotionMCPTool(accessToken, toolName, args) {
2888
2860
  return callMCPTool(accessToken, toolName, args);
2889
2861
  }
2890
2862
 
2863
+ // src/lib/logger.ts
2864
+ var consoleLogger = {
2865
+ debug: console.log.bind(console),
2866
+ info: console.info.bind(console),
2867
+ warn: console.warn.bind(console),
2868
+ error: console.error.bind(console)
2869
+ };
2870
+ var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
2871
+ var loggerGlobal = globalThis;
2872
+ var fallbackLoggerState = { logger: consoleLogger };
2873
+ var fallbackWarned = false;
2874
+ function getLoggerState() {
2875
+ try {
2876
+ return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
2877
+ } catch {
2878
+ if (!fallbackWarned) {
2879
+ fallbackWarned = true;
2880
+ fallbackLoggerState.logger.warn(
2881
+ "@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
2882
+ );
2883
+ }
2884
+ return fallbackLoggerState;
2885
+ }
2886
+ }
2887
+ function getLogger() {
2888
+ return getLoggerState().logger;
2889
+ }
2890
+
2891
2891
  // src/tools/github.ts
2892
2892
  var GITHUB_API = "https://api.github.com";
2893
2893
  var FETCH_TIMEOUT_MS = 3e4;
@@ -3131,13 +3131,13 @@ function maybeConnectorError(status) {
3131
3131
  function connectorMintErrorToToolResult(err, provider) {
3132
3132
  switch (err.code) {
3133
3133
  case "connector_not_connected":
3134
- return buildConnectorErrorResult("connector_not_connected", err.provider, err.connectUrl);
3134
+ return buildConnectorErrorResult("connector_not_connected", err.provider);
3135
3135
  case "scope_not_covered":
3136
- return buildConnectorErrorResult("scope_not_covered", err.provider, err.connectUrl, {
3136
+ return buildConnectorErrorResult("scope_not_covered", err.provider, {
3137
3137
  missingScopes: err.missingScopes
3138
3138
  });
3139
3139
  case "insufficient_scope":
3140
- return buildConnectorErrorResult("insufficient_scope", provider, void 0, {
3140
+ return buildConnectorErrorResult("insufficient_scope", provider, {
3141
3141
  required: err.required
3142
3142
  });
3143
3143
  case "upstream_unavailable":
@@ -3880,7 +3880,7 @@ function maybeConnectorError4(status, body) {
3880
3880
  return buildConnectorErrorResult("connector_not_connected", SLACK_PROVIDER);
3881
3881
  }
3882
3882
  if (body && body.ok === false && body.error === "missing_scope") {
3883
- return buildConnectorErrorResult("insufficient_scope", SLACK_PROVIDER, void 0, {
3883
+ return buildConnectorErrorResult("insufficient_scope", SLACK_PROVIDER, {
3884
3884
  required: body.needed
3885
3885
  });
3886
3886
  }
@@ -1015,12 +1015,12 @@ type ConnectorMintResult = {
1015
1015
  type ConnectorMintError = {
1016
1016
  code: "connector_not_connected";
1017
1017
  provider: string;
1018
- connectUrl: string;
1018
+ connectUrl?: string;
1019
1019
  } | {
1020
1020
  code: "scope_not_covered";
1021
1021
  provider: string;
1022
1022
  missingScopes: string[];
1023
- connectUrl: string;
1023
+ connectUrl?: string;
1024
1024
  } | {
1025
1025
  code: "insufficient_scope";
1026
1026
  required: string;
@@ -1106,11 +1106,10 @@ interface ConnectorErrorExtras {
1106
1106
  *
1107
1107
  * @param code One of the recognized {@link ConnectorErrorCode} values.
1108
1108
  * @param provider Logical provider name (`"gmail"`, `"gdrive"`, etc.).
1109
- * @param connectUrl Optional connect URL surfaced to the user via the LLM reply.
1110
1109
  * @param extras Optional `missingScopes` / `required` fields lifted by the
1111
1110
  * runtime parser into `ToolErrorInfo`.
1112
1111
  */
1113
- declare function buildConnectorErrorResult(code: ConnectorErrorCode, provider: string, connectUrl?: string, extras?: ConnectorErrorExtras): string;
1112
+ declare function buildConnectorErrorResult(code: ConnectorErrorCode, provider: string, extras?: ConnectorErrorExtras): string;
1114
1113
 
1115
1114
  /**
1116
1115
  * Gmail tool factory for the chat system.
@@ -1015,12 +1015,12 @@ type ConnectorMintResult = {
1015
1015
  type ConnectorMintError = {
1016
1016
  code: "connector_not_connected";
1017
1017
  provider: string;
1018
- connectUrl: string;
1018
+ connectUrl?: string;
1019
1019
  } | {
1020
1020
  code: "scope_not_covered";
1021
1021
  provider: string;
1022
1022
  missingScopes: string[];
1023
- connectUrl: string;
1023
+ connectUrl?: string;
1024
1024
  } | {
1025
1025
  code: "insufficient_scope";
1026
1026
  required: string;
@@ -1106,11 +1106,10 @@ interface ConnectorErrorExtras {
1106
1106
  *
1107
1107
  * @param code One of the recognized {@link ConnectorErrorCode} values.
1108
1108
  * @param provider Logical provider name (`"gmail"`, `"gdrive"`, etc.).
1109
- * @param connectUrl Optional connect URL surfaced to the user via the LLM reply.
1110
1109
  * @param extras Optional `missingScopes` / `required` fields lifted by the
1111
1110
  * runtime parser into `ToolErrorInfo`.
1112
1111
  */
1113
- declare function buildConnectorErrorResult(code: ConnectorErrorCode, provider: string, connectUrl?: string, extras?: ConnectorErrorExtras): string;
1112
+ declare function buildConnectorErrorResult(code: ConnectorErrorCode, provider: string, extras?: ConnectorErrorExtras): string;
1114
1113
 
1115
1114
  /**
1116
1115
  * Gmail tool factory for the chat system.
@@ -121,12 +121,16 @@ function buildUpdateEventBody(args) {
121
121
  }
122
122
  return eventBody;
123
123
  }
124
+ var CALENDAR_EVENT_ID = /^[A-Za-z0-9_]+$/;
124
125
  async function updateCalendarEvent(accessToken, args) {
125
126
  const { eventId } = args;
127
+ if (typeof eventId !== "string" || !CALENDAR_EVENT_ID.test(eventId)) {
128
+ return `Error: Invalid event ID: ${String(eventId)}`;
129
+ }
126
130
  const eventBody = buildUpdateEventBody(args);
127
131
  try {
128
132
  const response = await fetch(
129
- `https://www.googleapis.com/calendar/v3/calendars/primary/events/${eventId}`,
133
+ `https://www.googleapis.com/calendar/v3/calendars/primary/events/${encodeURIComponent(eventId)}`,
130
134
  {
131
135
  method: "PATCH",
132
136
  headers: {
@@ -995,55 +999,40 @@ function createWeatherTool(options, weatherOptions) {
995
999
 
996
1000
  // src/lib/connectors/errors.ts
997
1001
  var CONNECTOR_ERROR_MARKER = "__anuma_connector_error_v1";
998
- function buildConnectorErrorResult(code, provider, connectUrl, extras) {
1002
+ function buildConnectorErrorResult(code, provider, extras) {
999
1003
  const payload = {
1000
1004
  __anuma_connector_error_v1: true,
1001
1005
  code,
1002
1006
  provider,
1003
- connect_url: connectUrl,
1004
1007
  missing_scopes: extras?.missingScopes,
1005
1008
  required: extras?.required
1006
1009
  };
1007
1010
  return JSON.stringify(payload);
1008
1011
  }
1009
1012
 
1010
- // src/lib/logger.ts
1011
- var consoleLogger = {
1012
- debug: console.log.bind(console),
1013
- info: console.info.bind(console),
1014
- warn: console.warn.bind(console),
1015
- error: console.error.bind(console)
1016
- };
1017
- var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
1018
- var loggerGlobal = globalThis;
1019
- var fallbackLoggerState = { logger: consoleLogger };
1020
- var fallbackWarned = false;
1021
- function getLoggerState() {
1022
- try {
1023
- return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
1024
- } catch {
1025
- if (!fallbackWarned) {
1026
- fallbackWarned = true;
1027
- fallbackLoggerState.logger.warn(
1028
- "@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
1029
- );
1030
- }
1031
- return fallbackLoggerState;
1032
- }
1033
- }
1034
- function getLogger() {
1035
- return getLoggerState().logger;
1036
- }
1037
-
1038
1013
  // src/tools/googleDrive.ts
1039
1014
  var DRIVE_PROVIDER = "gdrive";
1015
+ var DRIVE_FILE_ID = /^[A-Za-z0-9_-]+$/;
1016
+ var DRIVE_MIME_TYPE = /^[\w.+-]+\/[\w.+-]+$/;
1017
+ function invalidFileIdError(fileId) {
1018
+ return `Error: Invalid file ID: ${String(fileId)}`;
1019
+ }
1020
+ function escapeDriveQueryValue(value) {
1021
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
1022
+ }
1023
+ function withMimeTypeFilter(driveQuery, mimeType) {
1024
+ if (!mimeType) return driveQuery;
1025
+ if (!DRIVE_MIME_TYPE.test(mimeType)) return { error: `Error: Invalid mimeType: ${mimeType}` };
1026
+ return `${driveQuery} and mimeType = '${escapeDriveQueryValue(mimeType)}'`;
1027
+ }
1040
1028
  async function searchDriveFiles(accessToken, args) {
1041
1029
  const { query, maxResults = 10, mimeType } = args;
1042
- let driveQuery = `fullText contains '${query.replace(/'/g, "\\'")}'`;
1043
- if (mimeType) {
1044
- driveQuery += ` and mimeType = '${mimeType}'`;
1045
- }
1046
- driveQuery += " and trashed = false";
1030
+ const filtered = withMimeTypeFilter(
1031
+ `fullText contains '${escapeDriveQueryValue(query)}'`,
1032
+ mimeType
1033
+ );
1034
+ if (typeof filtered !== "string") return filtered.error;
1035
+ const driveQuery = `${filtered} and trashed = false`;
1047
1036
  const params = new URLSearchParams({
1048
1037
  q: driveQuery,
1049
1038
  pageSize: String(maxResults),
@@ -1136,10 +1125,8 @@ function createGoogleDriveSearchTool(getAccessToken, requestDriveAccess) {
1136
1125
  }
1137
1126
  async function listRecentDriveFiles(accessToken, args) {
1138
1127
  const { maxResults = 10, mimeType } = args;
1139
- let driveQuery = "trashed = false";
1140
- if (mimeType) {
1141
- driveQuery += ` and mimeType = '${mimeType}'`;
1142
- }
1128
+ const driveQuery = withMimeTypeFilter("trashed = false", mimeType);
1129
+ if (typeof driveQuery !== "string") return driveQuery.error;
1143
1130
  const params = new URLSearchParams({
1144
1131
  q: driveQuery,
1145
1132
  pageSize: String(maxResults),
@@ -1226,7 +1213,7 @@ function createGoogleDriveListRecentTool(getAccessToken, requestDriveAccess) {
1226
1213
  };
1227
1214
  }
1228
1215
  async function findFileByName(accessToken, fileName) {
1229
- const driveQuery = `name contains '${fileName.replace(/'/g, "\\'")}' and trashed = false`;
1216
+ const driveQuery = `name contains '${escapeDriveQueryValue(fileName)}' and trashed = false`;
1230
1217
  const params = new URLSearchParams({
1231
1218
  q: driveQuery,
1232
1219
  pageSize: "1",
@@ -1256,24 +1243,22 @@ var GOOGLE_DOCS_EXPORT_TYPES = {
1256
1243
  var MAX_CONTENT_LENGTH = 5e4;
1257
1244
  async function resolveFileId(accessToken, fileId, fileName) {
1258
1245
  if (fileId) {
1259
- return { fileId };
1246
+ return DRIVE_FILE_ID.test(fileId) ? { fileId } : { error: invalidFileIdError(fileId) };
1260
1247
  }
1261
1248
  if (fileName) {
1262
- getLogger().debug("[google_drive_get_content] Searching for file by name:", fileName);
1263
1249
  const foundId = await findFileByName(accessToken, fileName);
1264
1250
  if (!foundId) {
1265
1251
  return {
1266
1252
  error: `Error: Could not find a file matching "${fileName}". Please check the file name and try again.`
1267
1253
  };
1268
1254
  }
1269
- getLogger().debug("[google_drive_get_content] Found file ID:", foundId);
1270
- return { fileId: foundId };
1255
+ return DRIVE_FILE_ID.test(foundId) ? { fileId: foundId } : { error: invalidFileIdError(foundId) };
1271
1256
  }
1272
1257
  return { error: "Error: Please provide either a fileId or fileName to get file content." };
1273
1258
  }
1274
1259
  async function fetchFileMetadata(accessToken, fileId) {
1275
1260
  const response = await fetch(
1276
- `https://www.googleapis.com/drive/v3/files/${fileId}?fields=id,name,mimeType,webViewLink&supportsAllDrives=true`,
1261
+ `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}?fields=id,name,mimeType,webViewLink&supportsAllDrives=true`,
1277
1262
  { headers: { Authorization: `Bearer ${accessToken}` } }
1278
1263
  );
1279
1264
  if (!response.ok) {
@@ -1291,13 +1276,13 @@ function getContentUrl(fileId, mimeType) {
1291
1276
  if (GOOGLE_DOCS_EXPORT_TYPES[mimeType]) {
1292
1277
  const exportMimeType = GOOGLE_DOCS_EXPORT_TYPES[mimeType];
1293
1278
  return {
1294
- url: `https://www.googleapis.com/drive/v3/files/${fileId}/export?mimeType=${encodeURIComponent(exportMimeType)}&supportsAllDrives=true`,
1279
+ url: `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}/export?mimeType=${encodeURIComponent(exportMimeType)}&supportsAllDrives=true`,
1295
1280
  isExport: true
1296
1281
  };
1297
1282
  }
1298
1283
  if (mimeType.startsWith("text/") || mimeType === "application/json" || mimeType === "application/xml") {
1299
1284
  return {
1300
- url: `https://www.googleapis.com/drive/v3/files/${fileId}?alt=media&supportsAllDrives=true`,
1285
+ url: `https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}?alt=media&supportsAllDrives=true`,
1301
1286
  isExport: false
1302
1287
  };
1303
1288
  }
@@ -1314,7 +1299,7 @@ Type: PDF${linkInfo}
1314
1299
  Note: PDF content cannot be extracted directly in the browser. The user can click the link above to view the PDF in Google Drive.`;
1315
1300
  }
1316
1301
  if (mimeType.startsWith("image/")) {
1317
- const directUrl = `https://drive.google.com/uc?export=view&id=${fileId}`;
1302
+ const directUrl = `https://drive.google.com/uc?export=view&id=${encodeURIComponent(fileId)}`;
1318
1303
  return `File: ${name}
1319
1304
  Type: ${mimeType}${linkInfo}
1320
1305
  Direct image URL: ${directUrl}
@@ -1349,7 +1334,6 @@ Type: ${metadata.mimeType}${isExport ? " (exported as text)" : ""}
1349
1334
  return header + displayContent + footer;
1350
1335
  }
1351
1336
  async function getDriveFileContent(accessToken, args) {
1352
- getLogger().debug("[google_drive_get_content] Starting with:", args);
1353
1337
  const fileIdResult = await resolveFileId(accessToken, args.fileId, args.fileName);
1354
1338
  if ("error" in fileIdResult) {
1355
1339
  return fileIdResult.error;
@@ -1361,7 +1345,6 @@ async function getDriveFileContent(accessToken, args) {
1361
1345
  return metadataResult.error;
1362
1346
  }
1363
1347
  const { metadata } = metadataResult;
1364
- getLogger().debug("[google_drive_get_content] File metadata:", metadata);
1365
1348
  const contentUrlResult = getContentUrl(fileId, metadata.mimeType);
1366
1349
  if (!contentUrlResult) {
1367
1350
  return formatNonTextFileResponse(fileId, metadata);
@@ -1398,10 +1381,8 @@ function createGoogleDriveGetContentTool(getAccessToken, requestDriveAccess) {
1398
1381
  }
1399
1382
  },
1400
1383
  executor: async (args) => {
1401
- getLogger().debug("[google_drive_get_content] Executor called with args:", args);
1402
1384
  let token = getAccessToken();
1403
1385
  if (!token) {
1404
- getLogger().debug("[google_drive_get_content] No token, requesting access...");
1405
1386
  try {
1406
1387
  token = await requestDriveAccess();
1407
1388
  } catch {
@@ -1415,14 +1396,7 @@ function createGoogleDriveGetContentTool(getAccessToken, requestDriveAccess) {
1415
1396
  fileId: args.fileId,
1416
1397
  fileName: args.fileName
1417
1398
  };
1418
- const result = await getDriveFileContent(token, typedArgs);
1419
- getLogger().debug(
1420
- "[google_drive_get_content] Result length:",
1421
- result.length,
1422
- "First 200 chars:",
1423
- result.slice(0, 200)
1424
- );
1425
- return result;
1399
+ return getDriveFileContent(token, typedArgs);
1426
1400
  }
1427
1401
  };
1428
1402
  }
@@ -1523,6 +1497,9 @@ function createGoogleDriveCreateFileTool(getAccessToken, requestDriveAccess) {
1523
1497
  };
1524
1498
  }
1525
1499
  async function updateDriveFile(accessToken, args) {
1500
+ if (typeof args.fileId !== "string" || !DRIVE_FILE_ID.test(args.fileId)) {
1501
+ return invalidFileIdError(args.fileId);
1502
+ }
1526
1503
  const mimeType = (args.mimeType || "text/plain").replace(/[\r\n]/g, "");
1527
1504
  if (NATIVE_GOOGLE_MIME_TYPE.test(mimeType)) {
1528
1505
  return NATIVE_GOOGLE_MIME_ERROR;
@@ -2201,22 +2178,17 @@ function notionConnectorError(status, json) {
2201
2178
  return buildConnectorErrorResult(
2202
2179
  "scope_not_covered",
2203
2180
  NOTION_PROVIDER,
2204
- readString(json, "connect_url"),
2205
2181
  Array.isArray(missingScopes) ? { missingScopes } : void 0
2206
2182
  );
2207
2183
  }
2208
2184
  case "insufficient_scope":
2209
- return buildConnectorErrorResult("insufficient_scope", NOTION_PROVIDER, void 0, {
2185
+ return buildConnectorErrorResult("insufficient_scope", NOTION_PROVIDER, {
2210
2186
  required: readString(json, "required")
2211
2187
  });
2212
2188
  case "upstream_unavailable":
2213
2189
  return buildConnectorErrorResult("upstream_unavailable", NOTION_PROVIDER);
2214
2190
  default:
2215
- return buildConnectorErrorResult(
2216
- "connector_not_connected",
2217
- NOTION_PROVIDER,
2218
- readString(json, "connect_url")
2219
- );
2191
+ return buildConnectorErrorResult("connector_not_connected", NOTION_PROVIDER);
2220
2192
  }
2221
2193
  }
2222
2194
  function proxyRunner(callMcp) {
@@ -2732,6 +2704,34 @@ async function callNotionMCPTool(accessToken, toolName, args) {
2732
2704
  return callMCPTool(accessToken, toolName, args);
2733
2705
  }
2734
2706
 
2707
+ // src/lib/logger.ts
2708
+ var consoleLogger = {
2709
+ debug: console.log.bind(console),
2710
+ info: console.info.bind(console),
2711
+ warn: console.warn.bind(console),
2712
+ error: console.error.bind(console)
2713
+ };
2714
+ var LOGGER_STATE_KEY = /* @__PURE__ */ Symbol.for("@anuma/sdk/logger/v1");
2715
+ var loggerGlobal = globalThis;
2716
+ var fallbackLoggerState = { logger: consoleLogger };
2717
+ var fallbackWarned = false;
2718
+ function getLoggerState() {
2719
+ try {
2720
+ return loggerGlobal[LOGGER_STATE_KEY] ?? (loggerGlobal[LOGGER_STATE_KEY] = fallbackLoggerState);
2721
+ } catch {
2722
+ if (!fallbackWarned) {
2723
+ fallbackWarned = true;
2724
+ fallbackLoggerState.logger.warn(
2725
+ "@anuma/sdk: the global object rejects new properties. This entrypoint keeps its own logger, so setLogger does not reach other entrypoints."
2726
+ );
2727
+ }
2728
+ return fallbackLoggerState;
2729
+ }
2730
+ }
2731
+ function getLogger() {
2732
+ return getLoggerState().logger;
2733
+ }
2734
+
2735
2735
  // src/tools/github.ts
2736
2736
  var GITHUB_API = "https://api.github.com";
2737
2737
  var FETCH_TIMEOUT_MS = 3e4;
@@ -2975,13 +2975,13 @@ function maybeConnectorError(status) {
2975
2975
  function connectorMintErrorToToolResult(err, provider) {
2976
2976
  switch (err.code) {
2977
2977
  case "connector_not_connected":
2978
- return buildConnectorErrorResult("connector_not_connected", err.provider, err.connectUrl);
2978
+ return buildConnectorErrorResult("connector_not_connected", err.provider);
2979
2979
  case "scope_not_covered":
2980
- return buildConnectorErrorResult("scope_not_covered", err.provider, err.connectUrl, {
2980
+ return buildConnectorErrorResult("scope_not_covered", err.provider, {
2981
2981
  missingScopes: err.missingScopes
2982
2982
  });
2983
2983
  case "insufficient_scope":
2984
- return buildConnectorErrorResult("insufficient_scope", provider, void 0, {
2984
+ return buildConnectorErrorResult("insufficient_scope", provider, {
2985
2985
  required: err.required
2986
2986
  });
2987
2987
  case "upstream_unavailable":
@@ -3724,7 +3724,7 @@ function maybeConnectorError4(status, body) {
3724
3724
  return buildConnectorErrorResult("connector_not_connected", SLACK_PROVIDER);
3725
3725
  }
3726
3726
  if (body && body.ok === false && body.error === "missing_scope") {
3727
- return buildConnectorErrorResult("insufficient_scope", SLACK_PROVIDER, void 0, {
3727
+ return buildConnectorErrorResult("insufficient_scope", SLACK_PROVIDER, {
3728
3728
  required: body.needed
3729
3729
  });
3730
3730
  }