mcp-scraper 0.57.2 → 0.58.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +2 -2
  3. package/dist/bin/api-server.cjs +151 -12
  4. package/dist/bin/api-server.cjs.map +1 -1
  5. package/dist/bin/api-server.js +2 -2
  6. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  7. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  8. package/dist/bin/mcp-scraper-cli.js +1 -1
  9. package/dist/bin/mcp-scraper-install.cjs +2 -2
  10. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  11. package/dist/bin/mcp-scraper-install.js +2 -2
  12. package/dist/bin/mcp-stdio-server.cjs +33 -6
  13. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  14. package/dist/bin/mcp-stdio-server.js +4 -4
  15. package/dist/{chunk-R6CO77BN.js → chunk-2U2ZDDSI.js} +3 -3
  16. package/dist/{chunk-R6CO77BN.js.map → chunk-2U2ZDDSI.js.map} +1 -1
  17. package/dist/chunk-EJ6KU4PC.js +7 -0
  18. package/dist/chunk-EJ6KU4PC.js.map +1 -0
  19. package/dist/{chunk-HU4R6BP2.js → chunk-IMBMDZUO.js} +2 -2
  20. package/dist/{chunk-HU4R6BP2.js.map → chunk-IMBMDZUO.js.map} +1 -1
  21. package/dist/{chunk-5XYBKE3X.js → chunk-KMGRM4FL.js} +2 -2
  22. package/dist/{chunk-67JUTUQD.js → chunk-P32KEY3D.js} +35 -7
  23. package/dist/chunk-P32KEY3D.js.map +1 -0
  24. package/dist/{extract-bundle-H7JEELY7.js → extract-bundle-XRRN6NAZ.js} +3 -3
  25. package/dist/{server-OZJXK7AB.js → server-J4YGBOTS.js} +126 -13
  26. package/dist/server-J4YGBOTS.js.map +1 -0
  27. package/dist/{site-extract-repository-CFMSWAVL.js → site-extract-repository-XAA2FVDN.js} +3 -3
  28. package/dist/{worker-S2WXELUC.js → worker-QFSOMF2N.js} +2 -2
  29. package/package.json +1 -1
  30. package/dist/chunk-67JUTUQD.js.map +0 -1
  31. package/dist/chunk-QN4W5SX6.js +0 -7
  32. package/dist/chunk-QN4W5SX6.js.map +0 -1
  33. package/dist/server-OZJXK7AB.js.map +0 -1
  34. /package/dist/{chunk-5XYBKE3X.js.map → chunk-KMGRM4FL.js.map} +0 -0
  35. /package/dist/{extract-bundle-H7JEELY7.js.map → extract-bundle-XRRN6NAZ.js.map} +0 -0
  36. /package/dist/{site-extract-repository-CFMSWAVL.js.map → site-extract-repository-XAA2FVDN.js.map} +0 -0
  37. /package/dist/{worker-S2WXELUC.js.map → worker-QFSOMF2N.js.map} +0 -0
@@ -10,8 +10,8 @@ import {
10
10
  } from "./chunk-2K74LVV7.js";
11
11
  import {
12
12
  extractJobLimitInfo
13
- } from "./chunk-5XYBKE3X.js";
14
- import "./chunk-R6CO77BN.js";
13
+ } from "./chunk-KMGRM4FL.js";
14
+ import "./chunk-2U2ZDDSI.js";
15
15
  import "./chunk-NDIAJIKQ.js";
16
16
  import {
17
17
  getDb
@@ -565,4 +565,4 @@ export {
565
565
  SITE_EXTRACT_PAGE_CHUNK,
566
566
  assembleExtractArtifacts
567
567
  };
568
- //# sourceMappingURL=extract-bundle-H7JEELY7.js.map
568
+ //# sourceMappingURL=extract-bundle-XRRN6NAZ.js.map
@@ -115,6 +115,7 @@ import {
115
115
  CommonsClaimPublicationInputSchema,
116
116
  CommonsPreparePublicationInputSchema,
117
117
  CommonsPublishEditorialInputSchema,
118
+ CommonsUpdateEditorialArticleInputSchema,
118
119
  CommonsValidatePublicationInputSchema,
119
120
  CreateArtifactTemplateInputSchema,
120
121
  CreateEditorialReadingRoomInputSchema,
@@ -169,7 +170,7 @@ import {
169
170
  resolveDeploymentProfile,
170
171
  resolveLocalSourcebookSchemaType,
171
172
  transcribeMediaUrl
172
- } from "./chunk-67JUTUQD.js";
173
+ } from "./chunk-P32KEY3D.js";
173
174
  import {
174
175
  auditImageUrls,
175
176
  auditImages,
@@ -225,7 +226,7 @@ import {
225
226
  } from "./chunk-FG6LJGJ7.js";
226
227
  import {
227
228
  PACKAGE_VERSION
228
- } from "./chunk-QN4W5SX6.js";
229
+ } from "./chunk-EJ6KU4PC.js";
229
230
  import {
230
231
  abandonExtractSettlement,
231
232
  countSuccessfulPages,
@@ -248,7 +249,7 @@ import {
248
249
  setExtractJobTotal,
249
250
  settleExtractJob,
250
251
  terminalExtractJobStatus
251
- } from "./chunk-5XYBKE3X.js";
252
+ } from "./chunk-KMGRM4FL.js";
252
253
  import {
253
254
  BROWSER_OPEN_MIN_BALANCE_MC,
254
255
  CONCURRENCY_PACK_INVOICE_DESCRIPTION,
@@ -301,7 +302,7 @@ import {
301
302
  tierChangeLeavesPrivateOffer,
302
303
  tierCreditsPerInterval,
303
304
  vendorCostUsdToMc
304
- } from "./chunk-R6CO77BN.js";
305
+ } from "./chunk-2U2ZDDSI.js";
305
306
  import {
306
307
  CaptchaError,
307
308
  MapsSearchIncompletePageError,
@@ -9393,7 +9394,7 @@ var siteExtractFn = inngest.createFunction(
9393
9394
  });
9394
9395
  }) : null;
9395
9396
  const finalized = await step.run("finalize", async () => {
9396
- const { assembleExtractArtifacts } = await import("./extract-bundle-H7JEELY7.js");
9397
+ const { assembleExtractArtifacts } = await import("./extract-bundle-XRRN6NAZ.js");
9397
9398
  const current = await getExtractJob(jobId2);
9398
9399
  if (!current) throw new Error("extract job disappeared before finalization");
9399
9400
  const stored = await assembleExtractArtifacts(current, { branding, imageAudit });
@@ -12884,6 +12885,7 @@ function mapSubmission(row) {
12884
12885
  businessName: String(rowValue(row, "business_name")),
12885
12886
  websiteUrl: String(rowValue(row, "website_url")),
12886
12887
  status: String(rowValue(row, "status")),
12888
+ acquisitionError: rowValue(row, "acquisition_error") == null ? null : String(rowValue(row, "acquisition_error")),
12887
12889
  draftRevision: Number(rowValue(row, "draft_revision")),
12888
12890
  publishedRevision: rowValue(row, "published_revision") == null ? null : Number(rowValue(row, "published_revision")),
12889
12891
  coverage: parseJson2(rowValue(row, "coverage_json")),
@@ -14576,6 +14578,15 @@ function nameOverlap(left, right) {
14576
14578
  const intersection = [...a].filter((token6) => b.has(token6)).length;
14577
14579
  return intersection / Math.max(a.size, b.size);
14578
14580
  }
14581
+ function nameContainment(left, right) {
14582
+ const a = tokens(left);
14583
+ const b = tokens(right);
14584
+ if (!a.size || !b.size) return 0;
14585
+ const smaller = a.size <= b.size ? a : b;
14586
+ if (smaller.size < 2) return 0;
14587
+ const intersection = [...a].filter((token6) => b.has(token6)).length;
14588
+ return intersection / smaller.size;
14589
+ }
14579
14590
  function validateLocalSourcebookMapsIdentity(submission, maps) {
14580
14591
  const expectedHost = host(submission.websiteUrl);
14581
14592
  const mapsHost = host(maps.website);
@@ -14585,7 +14596,9 @@ function validateLocalSourcebookMapsIdentity(submission, maps) {
14585
14596
  if (mapsHost && expectedHost && mapsHost !== expectedHost && !mapsHost.endsWith(`.${expectedHost}`) && !expectedHost.endsWith(`.${mapsHost}`)) {
14586
14597
  throw new Error(`Exact-place match rejected: Google Maps linked ${mapsHost}, not the submitted domain ${expectedHost}.`);
14587
14598
  }
14588
- if (overlap < 0.6) {
14599
+ const containment = nameContainment(submission.businessName, actualName);
14600
+ const domainConfirmsIdentity = Boolean(mapsHost && expectedHost);
14601
+ if (overlap < 0.6 && containment < 0.9 && !domainConfirmsIdentity) {
14589
14602
  throw new Error(`Exact-place match rejected: Google Maps returned \u201C${actualName},\u201D which does not sufficiently match \u201C${submission.businessName}.\u201D`);
14590
14603
  }
14591
14604
  if (addressState && addressState !== submission.state.toLowerCase()) {
@@ -35905,6 +35918,92 @@ async function publishCommonsEditorial(input, user) {
35905
35918
  if (!edition) throw new CommonsPublicationError("publication_publish_failed", "The published edition was not persisted.");
35906
35919
  return publicationResult({ ...publication, latestEditionId: editionId, updatedAt: now }, edition, false);
35907
35920
  }
35921
+ async function updateCommonsEditorialArticle(input, user) {
35922
+ await ensureCommonsSchema();
35923
+ const subdomain = normalizePublicationSubdomain(input.publicationSubdomain);
35924
+ const publication = await getCommonsPublicationBySubdomain(subdomain);
35925
+ if (!publication) throw new CommonsPublicationError("publication_not_found", "Claim this publication name before editing an edition.", 404);
35926
+ if (publication.ownerUserId !== Number(user.id)) {
35927
+ throw new CommonsPublicationError("publication_not_owned", "Only the account that claimed this publication can edit it.", 404);
35928
+ }
35929
+ const idempotencyKey3 = requiredIdempotencyKey(input.idempotencyKey);
35930
+ const replay = await getEditionByIdempotency(Number(user.id), idempotencyKey3);
35931
+ if (replay) return publicationResult(publication, replay, true);
35932
+ const latestOverall = publication.latestEditionId ? await getPublicationEditionById(publication.latestEditionId) : null;
35933
+ const editionSlug = normalizeEditionSlug(input.editionSlug || latestOverall?.editionSlug || "");
35934
+ if (!editionSlug) throw new CommonsPublicationError("publication_edition_required", "This publication has no edition yet; publish one before editing an article.", 409);
35935
+ const latest = await getLatestEdition(publication.id, editionSlug);
35936
+ if (!latest) throw new CommonsPublicationError("publication_edition_not_found", `Edition ${editionSlug} does not exist.`, 404);
35937
+ if (input.baseRevision !== latest.revision) {
35938
+ throw new CommonsPublicationError("publication_revision_conflict", `Edition ${editionSlug} is revision ${latest.revision}; read it again before editing.`, 409);
35939
+ }
35940
+ const articles = latest.articles;
35941
+ const index = articles.findIndex((article) => article.slug === input.articleSlug);
35942
+ if (index === -1) {
35943
+ throw new CommonsPublicationError("publication_article_not_found", `Edition ${editionSlug} has no article with slug ${input.articleSlug}. Known slugs: ${articles.map((article) => article.slug).join(", ")}.`, 404);
35944
+ }
35945
+ const current = articles[index];
35946
+ const nextArticles = [...articles];
35947
+ nextArticles[index] = {
35948
+ ...current,
35949
+ ...input.markdown === void 0 ? {} : { markdown: input.markdown },
35950
+ ...input.title === void 0 ? {} : { title: input.title },
35951
+ ...input.summary === void 0 ? {} : { summary: input.summary },
35952
+ ...input.category === void 0 ? {} : { category: input.category },
35953
+ ...input.kicker === void 0 ? {} : { kicker: input.kicker },
35954
+ ...input.order === void 0 ? {} : { order: input.order }
35955
+ };
35956
+ const editionInput = { site: latest.site, deck: latest.deck, articles: nextArticles };
35957
+ const canonicalUrl = editionPublicUrl(subdomain, editionSlug);
35958
+ const rendered = renderEditorialReadingRoom(editionInput);
35959
+ const html = addPublicMetadata(rendered.html, canonicalUrl, publication.title);
35960
+ const editionId = `tced_${randomUUID18()}`;
35961
+ const revision = latest.revision + 1;
35962
+ const now = (/* @__PURE__ */ new Date()).toISOString();
35963
+ await getDb().batch([
35964
+ {
35965
+ sql: `
35966
+ INSERT INTO commons_publication_editions (
35967
+ id, publication_id, owner_user_id, edition_slug, revision, title, site_json, deck,
35968
+ articles_json, html, filename, sha256, article_count, word_count, bytes, warnings_json,
35969
+ idempotency_key, created_at, published_at
35970
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
35971
+ `,
35972
+ args: [
35973
+ editionId,
35974
+ publication.id,
35975
+ Number(user.id),
35976
+ editionSlug,
35977
+ revision,
35978
+ latest.site.title,
35979
+ JSON.stringify(latest.site),
35980
+ latest.deck,
35981
+ JSON.stringify(nextArticles),
35982
+ html,
35983
+ rendered.filename,
35984
+ createHash16("sha256").update(html).digest("hex"),
35985
+ rendered.articleCount,
35986
+ rendered.wordCount,
35987
+ Buffer.byteLength(html),
35988
+ JSON.stringify(rendered.warnings),
35989
+ idempotencyKey3,
35990
+ now,
35991
+ now
35992
+ ]
35993
+ },
35994
+ {
35995
+ sql: "UPDATE commons_publications SET latest_edition_id = ?, updated_at = ? WHERE id = ? AND owner_user_id = ?",
35996
+ args: [editionId, now, publication.id, Number(user.id)]
35997
+ }
35998
+ ], "write");
35999
+ const edition = await getPublicationEditionById(editionId);
36000
+ if (!edition) throw new CommonsPublicationError("publication_publish_failed", "The edited edition was not persisted.");
36001
+ return {
36002
+ ...publicationResult({ ...publication, latestEditionId: editionId, updatedAt: now }, edition, false),
36003
+ updatedArticle: { slug: input.articleSlug, previousRevision: latest.revision, revision },
36004
+ unchangedArticles: articles.length - 1
36005
+ };
36006
+ }
35908
36007
  async function getCommonsPublicationBySubdomain(subdomainInput) {
35909
36008
  await ensureCommonsSchema();
35910
36009
  const subdomain = normalizePublicationSubdomain(subdomainInput);
@@ -36002,6 +36101,7 @@ function rowToEdition(row, subdomain) {
36002
36101
  revision: Number(row.revision),
36003
36102
  title: String(row.title),
36004
36103
  site: parseJson4(row.site_json, {}),
36104
+ articles: parseJson4(row.articles_json, []),
36005
36105
  deck: String(row.deck),
36006
36106
  filename: String(row.filename),
36007
36107
  sha256: String(row.sha256),
@@ -36239,6 +36339,7 @@ var PreparePublicationSchema = z32.object(CommonsPreparePublicationInputSchema).
36239
36339
  var ValidatePublicationSchema = z32.object(CommonsValidatePublicationInputSchema).strict();
36240
36340
  var ClaimPublicationSchema = z32.object(CommonsClaimPublicationInputSchema).strict();
36241
36341
  var PublishEditorialSchema = z32.object(CommonsPublishEditorialInputSchema).strict();
36342
+ var UpdateEditorialArticleSchema = z32.object(CommonsUpdateEditorialArticleInputSchema).strict();
36242
36343
  commonsApp.get("/health", async (c) => {
36243
36344
  await ensureCommonsSchema();
36244
36345
  return c.json({ ok: true, data: commonsDatabaseReport() });
@@ -36274,11 +36375,16 @@ commonsApp.post("/publications/publish", auth2, async (c) => {
36274
36375
  if (!parsed.success) return validationError(c, parsed.error);
36275
36376
  return publicationOperation(c, () => publishCommonsEditorial(parsed.data, c.get("user")), 201);
36276
36377
  });
36378
+ commonsApp.post("/publications/articles", auth2, async (c) => {
36379
+ const parsed = UpdateEditorialArticleSchema.safeParse(await c.req.json().catch(() => ({})));
36380
+ if (!parsed.success) return validationError(c, parsed.error);
36381
+ return publicationOperation(c, () => updateCommonsEditorialArticle(parsed.data, c.get("user")), 201);
36382
+ });
36277
36383
  commonsApp.get("/publications/me", auth2, async (c) => {
36278
36384
  const publication = await getCommonsPublicationForOwner(Number(c.get("user").id));
36279
36385
  if (!publication) return c.json({ ok: false, error: "publication_not_found", message: "This account has not claimed a Commons publication yet." }, 404);
36280
36386
  const editions = c.req.query("includeEditions") === "false" ? [] : await listCommonsPublicationEditions(publication.id);
36281
- return c.json({ ok: true, data: { publication, editions } });
36387
+ return c.json({ ok: true, data: { publication, editions: withArticleSources(editions, c.req.query("includeArticles") === "true") } });
36282
36388
  });
36283
36389
  commonsApp.get("/publications/:subdomain/site", async (c) => {
36284
36390
  try {
@@ -36318,7 +36424,7 @@ commonsApp.get("/publications/:subdomain", async (c) => {
36318
36424
  const publication = await getCommonsPublicationBySubdomain(c.req.param("subdomain"));
36319
36425
  if (!publication) return c.json({ ok: false, error: "publication_not_found", message: "No Commons publication matched that name." }, 404);
36320
36426
  const editions = c.req.query("includeEditions") === "false" ? [] : await listCommonsPublicationEditions(publication.id);
36321
- return c.json({ ok: true, data: { publication, editions } });
36427
+ return c.json({ ok: true, data: { publication, editions: withArticleSources(editions, false) } });
36322
36428
  } catch (error) {
36323
36429
  return publicationError(c, error);
36324
36430
  }
@@ -36549,6 +36655,13 @@ function publicationError(c, error) {
36549
36655
  }
36550
36656
  throw error;
36551
36657
  }
36658
+ function withArticleSources(editions, include) {
36659
+ if (include) return editions;
36660
+ return editions.map((edition) => {
36661
+ const { articles: _articles, ...rest } = edition;
36662
+ return rest;
36663
+ });
36664
+ }
36552
36665
  function xmlEscape(value) {
36553
36666
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
36554
36667
  }
@@ -47179,7 +47292,7 @@ app.get("/cron/tick", async (c) => {
47179
47292
  return c.json({ error: "Unauthorized" }, 401);
47180
47293
  }
47181
47294
  const startedAt = Date.now();
47182
- const { drainQueue } = await import("./worker-S2WXELUC.js");
47295
+ const { drainQueue } = await import("./worker-QFSOMF2N.js");
47183
47296
  const budget = { maxJobs: 10, deadlineMs: startedAt + CRON_TICK_DRAIN_BUDGET_MS };
47184
47297
  const origin = `${new URL(c.req.url).protocol}//${new URL(c.req.url).host}`;
47185
47298
  const unfinished = [];
@@ -47249,8 +47362,8 @@ app.post("/api/internal/extract-refinalize/:id", async (c) => {
47249
47362
  finishExtractJob: finishExtractJob2,
47250
47363
  terminalExtractJobStatus: terminalExtractJobStatus2,
47251
47364
  extractJobLimitInfo: extractJobLimitInfo2
47252
- } = await import("./site-extract-repository-CFMSWAVL.js");
47253
- const { assembleExtractArtifacts } = await import("./extract-bundle-H7JEELY7.js");
47365
+ } = await import("./site-extract-repository-XAA2FVDN.js");
47366
+ const { assembleExtractArtifacts } = await import("./extract-bundle-XRRN6NAZ.js");
47254
47367
  const existing = await getExtractJob2(jobId2);
47255
47368
  if (!existing) return c.json({ error: "job not found" }, 404);
47256
47369
  if (existing.status !== "failed") {
@@ -47277,7 +47390,7 @@ app.post("/api/internal/extract-refinalize/:id", async (c) => {
47277
47390
  if (!updated) return c.json({ error: "job state changed during re-finalization" }, 409);
47278
47391
  let settlement = "already_settled_or_refunded";
47279
47392
  if (job.billedMc == null && job.userId != null) {
47280
- const { settleExtractJob: settleExtractJob3, countSuccessfulPages: countSuccessfulPages2 } = await import("./site-extract-repository-CFMSWAVL.js");
47393
+ const { settleExtractJob: settleExtractJob3, countSuccessfulPages: countSuccessfulPages2 } = await import("./site-extract-repository-XAA2FVDN.js");
47281
47394
  const heldMc = Number(job.options.heldMc ?? 0);
47282
47395
  const successful = await countSuccessfulPages2(jobId2);
47283
47396
  const usedMc = Math.min(successful * MC_COSTS.page_scrape, heldMc);
@@ -47462,4 +47575,4 @@ app.get("/blog/:slug/", (c) => {
47462
47575
  export {
47463
47576
  app
47464
47577
  };
47465
- //# sourceMappingURL=server-OZJXK7AB.js.map
47578
+ //# sourceMappingURL=server-J4YGBOTS.js.map