mcp-scraper 0.22.0 → 0.24.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.
@@ -35,7 +35,7 @@ import {
35
35
  sanitizeAttempts,
36
36
  sanitizeHarvestResult,
37
37
  transcribeMediaUrl
38
- } from "./chunk-3SQTNNGK.js";
38
+ } from "./chunk-SUPUHPJS.js";
39
39
  import {
40
40
  auditImages,
41
41
  buildLinkReport,
@@ -76,7 +76,7 @@ import {
76
76
  RawMapsOverviewSchema,
77
77
  RawMapsReviewStatsSchema
78
78
  } from "./chunk-XGIPATLV.js";
79
- import "./chunk-Q6GSQEE4.js";
79
+ import "./chunk-CDLHUCMT.js";
80
80
  import {
81
81
  completeExtractJob,
82
82
  countSuccessfulPages,
@@ -21463,6 +21463,130 @@ ${lines.length ? `${lines.join("\n")}
21463
21463
  };
21464
21464
  }
21465
21465
 
21466
+ // src/api/search-console-table-export.ts
21467
+ import { randomUUID as randomUUID8 } from "crypto";
21468
+ var SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS = 5e4;
21469
+ var SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE = 2e3;
21470
+ var SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES = 50 * 1024 * 1024;
21471
+ var SEARCH_CONSOLE_TABLE_COLUMNS = [
21472
+ "id",
21473
+ "provider_record_id",
21474
+ "connection_id",
21475
+ "site_url",
21476
+ "permission_level",
21477
+ "date",
21478
+ "query",
21479
+ "page",
21480
+ "country",
21481
+ "device",
21482
+ "clicks",
21483
+ "impressions",
21484
+ "ctr",
21485
+ "position",
21486
+ "captured_at",
21487
+ "content_hash",
21488
+ "created_at",
21489
+ "updated_at"
21490
+ ];
21491
+ var SearchConsoleTableExportValidationError = class extends Error {
21492
+ };
21493
+ function validateSearchConsoleTableExportRequest(args) {
21494
+ const tableName = typeof args.tableName === "string" ? args.tableName.trim() : "";
21495
+ if (!/^gsc_performance_[a-f0-9]{12}$/.test(tableName)) {
21496
+ throw new SearchConsoleTableExportValidationError("tableName must be a Search Console performance table returned by list_service_connections.");
21497
+ }
21498
+ const allowedColumns = new Set(SEARCH_CONSOLE_TABLE_COLUMNS);
21499
+ const allowedOps = /* @__PURE__ */ new Set(["eq", "neq", "gt", "gte", "lt", "lte", "like", "in"]);
21500
+ const rawFilters = args.filters === void 0 ? [] : args.filters;
21501
+ if (!Array.isArray(rawFilters) || rawFilters.length > 20) {
21502
+ throw new SearchConsoleTableExportValidationError("filters must be an array with at most 20 entries.");
21503
+ }
21504
+ const filters = rawFilters.map((value) => {
21505
+ const filter = value && typeof value === "object" && !Array.isArray(value) ? value : null;
21506
+ if (!filter || typeof filter.column !== "string" || !allowedColumns.has(filter.column) || typeof filter.op !== "string" || !allowedOps.has(filter.op)) {
21507
+ throw new SearchConsoleTableExportValidationError("Each filter must use a documented Search Console table column and supported operator.");
21508
+ }
21509
+ if (filter.op === "in" && !Array.isArray(filter.value)) {
21510
+ throw new SearchConsoleTableExportValidationError("The in filter operator requires an array value.");
21511
+ }
21512
+ return {
21513
+ column: filter.column,
21514
+ op: filter.op,
21515
+ value: filter.value
21516
+ };
21517
+ });
21518
+ let sort;
21519
+ if (args.sort !== void 0) {
21520
+ const raw = args.sort && typeof args.sort === "object" && !Array.isArray(args.sort) ? args.sort : null;
21521
+ if (!raw || typeof raw.column !== "string" || !allowedColumns.has(raw.column) || raw.direction !== void 0 && raw.direction !== "asc" && raw.direction !== "desc") {
21522
+ throw new SearchConsoleTableExportValidationError("sort must use a documented Search Console table column and asc or desc direction.");
21523
+ }
21524
+ sort = {
21525
+ column: raw.column,
21526
+ ...raw.direction ? { direction: raw.direction } : {}
21527
+ };
21528
+ }
21529
+ const maxRows = args.maxRows === void 0 ? 1e4 : Number(args.maxRows);
21530
+ if (!Number.isInteger(maxRows) || maxRows < 1 || maxRows > SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS) {
21531
+ throw new SearchConsoleTableExportValidationError(`maxRows must be an integer from 1 to ${SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS}.`);
21532
+ }
21533
+ return { tableName, filters, ...sort ? { sort } : {}, maxRows };
21534
+ }
21535
+ async function exportSearchConsoleTableData(args) {
21536
+ const lines = [];
21537
+ let bytes = 0;
21538
+ let offset = 0;
21539
+ let matchedRows = 0;
21540
+ let stoppedForBytes = false;
21541
+ while (offset < args.maxRows) {
21542
+ const limit = Math.min(SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE, args.maxRows - offset);
21543
+ const page = await args.queryPage({
21544
+ tableName: args.tableName,
21545
+ filters: args.filters,
21546
+ ...args.sort ? { sort: args.sort } : {},
21547
+ limit,
21548
+ offset
21549
+ });
21550
+ if (!page.ok) throw new Error(page.error || "Search Console table query failed.");
21551
+ const rows = Array.isArray(page.rows) ? page.rows : [];
21552
+ matchedRows = Number.isSafeInteger(page.count) && Number(page.count) >= 0 ? Number(page.count) : rows.length;
21553
+ for (const row of rows) {
21554
+ const line = `${JSON.stringify(row)}
21555
+ `;
21556
+ const lineBytes = Buffer.byteLength(line);
21557
+ if (bytes + lineBytes > SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES) {
21558
+ stoppedForBytes = true;
21559
+ break;
21560
+ }
21561
+ lines.push(line);
21562
+ bytes += lineBytes;
21563
+ }
21564
+ offset += rows.length;
21565
+ if (stoppedForBytes || rows.length < limit || offset >= matchedRows) break;
21566
+ }
21567
+ const exportId = randomUUID8();
21568
+ const artifact = await args.writeArtifact({
21569
+ ownerId: args.ownerId,
21570
+ exportId,
21571
+ filename: `search-console-filtered-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.jsonl`,
21572
+ content: lines.join("")
21573
+ });
21574
+ const complete = lines.length >= matchedRows;
21575
+ const warnings = [];
21576
+ if (!complete && lines.length >= args.maxRows) warnings.push("max_rows_reached");
21577
+ if (stoppedForBytes) warnings.push("artifact_size_limit_reached");
21578
+ warnings.push("search_console_source_returns_top_rows_not_guaranteed_exhaustive");
21579
+ return {
21580
+ ok: true,
21581
+ tableName: args.tableName,
21582
+ rowsExported: lines.length,
21583
+ matchedRows,
21584
+ complete,
21585
+ artifact,
21586
+ warnings
21587
+ };
21588
+ }
21589
+
21466
21590
  // src/api/credit-operations.ts
21467
21591
  async function applyMonthlyFreeRefresh(user) {
21468
21592
  return user;
@@ -23781,6 +23905,31 @@ app.post("/schedule-connections/actions/export", auth2, requireIntegrationsTier,
23781
23905
  return scheduleConnectionError(c, err, "Unable to export this connected service.");
23782
23906
  }
23783
23907
  });
23908
+ app.post("/schedule-connections/actions/export-search-console-table", auth2, requireIntegrationsTier, async (c) => {
23909
+ const user = c.get("user");
23910
+ const body = await c.req.json().catch(() => ({}));
23911
+ try {
23912
+ const request = validateSearchConsoleTableExportRequest(body);
23913
+ const { key, error } = await getOrCreateUserMemoryKey(user);
23914
+ if (!key) return c.json({ ok: false, error: error ?? "Memory table access is unavailable." }, 503);
23915
+ const result = await exportSearchConsoleTableData({
23916
+ ownerId: sha256Hex(user.api_key).slice(0, 24),
23917
+ ...request,
23918
+ queryPage: (input) => memoryCall("queryTableTool", input, key),
23919
+ writeArtifact: createConnectedDataArtifact
23920
+ });
23921
+ return c.json(result);
23922
+ } catch (err) {
23923
+ if (err instanceof SearchConsoleTableExportValidationError) {
23924
+ return c.json({ ok: false, error: err.message }, 400);
23925
+ }
23926
+ if (err instanceof Error && err.message === "connected_data_private_blob_not_configured") {
23927
+ return c.json({ ok: false, error: "Private connected-data artifact storage is not configured." }, 503);
23928
+ }
23929
+ console.error("[search-console-table-export]", err instanceof Error ? err.name : "unknown_error");
23930
+ return c.json({ ok: false, error: "Unable to export the persisted Search Console table." }, 502);
23931
+ }
23932
+ });
23784
23933
  app.post("/schedule-connections/actions/export-download", auth2, requireIntegrationsTier, async (c) => {
23785
23934
  const user = c.get("user");
23786
23935
  const body = await c.req.json().catch(() => ({}));
@@ -25042,4 +25191,4 @@ app.get("/blog/:slug/", (c) => {
25042
25191
  export {
25043
25192
  app
25044
25193
  };
25045
- //# sourceMappingURL=server-K6C7W7ED.js.map
25194
+ //# sourceMappingURL=server-I5U3OUZZ.js.map