mcp-scraper 0.44.2 → 0.44.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.
- package/README.md +2 -2
- package/dist/bin/api-server.cjs +80 -12
- package/dist/bin/api-server.cjs.map +1 -1
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/mcp-scraper-cli.cjs +1 -1
- package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-install.cjs +1 -1
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.cjs +6 -4
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/{chunk-M27QGXUM.js → chunk-2SE4GYCS.js} +7 -5
- package/dist/chunk-2SE4GYCS.js.map +1 -0
- package/dist/chunk-32Z52OE4.js +7 -0
- package/dist/chunk-32Z52OE4.js.map +1 -0
- package/dist/{server-RTQUTQZE.js → server-JJLFY46K.js} +70 -11
- package/dist/server-JJLFY46K.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-M27QGXUM.js.map +0 -1
- package/dist/chunk-OEW4VBS2.js +0 -7
- package/dist/chunk-OEW4VBS2.js.map +0 -1
- package/dist/server-RTQUTQZE.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const PACKAGE_VERSION = '0.44.3'\n"],"mappings":";AAAO,IAAM,kBAAkB;","names":[]}
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
renewDirectoryArtifactDownload,
|
|
87
87
|
resolveDeploymentProfile,
|
|
88
88
|
transcribeMediaUrl
|
|
89
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-2SE4GYCS.js";
|
|
90
90
|
import {
|
|
91
91
|
auditImageUrls,
|
|
92
92
|
auditImages,
|
|
@@ -142,7 +142,7 @@ import {
|
|
|
142
142
|
} from "./chunk-3ZUBQQPQ.js";
|
|
143
143
|
import {
|
|
144
144
|
PACKAGE_VERSION
|
|
145
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-32Z52OE4.js";
|
|
146
146
|
import {
|
|
147
147
|
abandonExtractSettlement,
|
|
148
148
|
countSuccessfulPages,
|
|
@@ -12159,6 +12159,14 @@ async function listPublicLocalSourcebook(category, state) {
|
|
|
12159
12159
|
const result = await getDb().execute({ sql: `SELECT r.payload_json FROM local_sourcebook_submissions s JOIN local_sourcebook_revisions r ON r.submission_id = s.id AND r.revision = s.published_revision WHERE s.category = ? AND s.state = ? AND s.published_revision IS NOT NULL AND s.status NOT IN ('unpublished', 'rejected') ORDER BY s.business_name`, args: [category, state] });
|
|
12160
12160
|
return result.rows.map((row) => parseJson2(row.payload_json));
|
|
12161
12161
|
}
|
|
12162
|
+
async function listAllPublicLocalSourcebook(category) {
|
|
12163
|
+
await ensureLocalSourcebookSchema();
|
|
12164
|
+
const result = category ? await getDb().execute({
|
|
12165
|
+
sql: `SELECT r.payload_json FROM local_sourcebook_submissions s JOIN local_sourcebook_revisions r ON r.submission_id = s.id AND r.revision = s.published_revision WHERE s.category = ? AND s.published_revision IS NOT NULL AND s.status NOT IN ('unpublished', 'rejected') ORDER BY s.state, s.business_name`,
|
|
12166
|
+
args: [category]
|
|
12167
|
+
}) : await getDb().execute(`SELECT r.payload_json FROM local_sourcebook_submissions s JOIN local_sourcebook_revisions r ON r.submission_id = s.id AND r.revision = s.published_revision WHERE s.published_revision IS NOT NULL AND s.status NOT IN ('unpublished', 'rejected') ORDER BY s.category, s.state, s.business_name`);
|
|
12168
|
+
return result.rows.map((row) => parseJson2(row.payload_json));
|
|
12169
|
+
}
|
|
12162
12170
|
async function getPublicLocalSourcebook(category, state, slug2) {
|
|
12163
12171
|
await ensureLocalSourcebookSchema();
|
|
12164
12172
|
const result = await getDb().execute({ sql: `SELECT r.payload_json FROM local_sourcebook_submissions s JOIN local_sourcebook_revisions r ON r.submission_id = s.id AND r.revision = s.published_revision WHERE s.category = ? AND s.state = ? AND s.slug = ? AND s.published_revision IS NOT NULL AND s.status NOT IN ('unpublished', 'rejected') LIMIT 1`, args: [category, state, slug2] });
|
|
@@ -12768,6 +12776,37 @@ var MapsExtractor = class {
|
|
|
12768
12776
|
|
|
12769
12777
|
// src/api/local-sourcebook-compiler.ts
|
|
12770
12778
|
import { createHash as createHash3 } from "crypto";
|
|
12779
|
+
|
|
12780
|
+
// src/api/local-sourcebook-public-urls.ts
|
|
12781
|
+
var DEFAULT_ROOT_DOMAIN = "localsourcebook.com";
|
|
12782
|
+
function rootDomain() {
|
|
12783
|
+
const configured = process.env.LOCAL_SOURCEBOOK_PUBLIC_ROOT_DOMAIN?.trim() || DEFAULT_ROOT_DOMAIN;
|
|
12784
|
+
return configured.replace(/^https?:\/\//i, "").replace(/^www\./i, "").replace(/\/.*$/, "").replace(/\.+$/, "").toLowerCase();
|
|
12785
|
+
}
|
|
12786
|
+
function localSourcebookPublicUrls(category, state, slug2) {
|
|
12787
|
+
const categoryUrl = `https://${category}.${rootDomain()}`;
|
|
12788
|
+
const statePath = `/${state.toLowerCase()}`;
|
|
12789
|
+
const profilePath = `${statePath}/${slug2}/`;
|
|
12790
|
+
const reviewsPath = `${statePath}/${slug2}/reviews`;
|
|
12791
|
+
return {
|
|
12792
|
+
categoryUrl,
|
|
12793
|
+
nationwideDirectoryUrl: `${categoryUrl}/directory`,
|
|
12794
|
+
stateUrl: `${categoryUrl}${statePath}`,
|
|
12795
|
+
profileUrl: `${categoryUrl}${profilePath}`,
|
|
12796
|
+
reviewsUrl: `${categoryUrl}${reviewsPath}`,
|
|
12797
|
+
profilePath,
|
|
12798
|
+
reviewsPath
|
|
12799
|
+
};
|
|
12800
|
+
}
|
|
12801
|
+
function localSourcebookPublicationLinks(submission) {
|
|
12802
|
+
return {
|
|
12803
|
+
...localSourcebookPublicUrls(submission.category, submission.state, submission.slug),
|
|
12804
|
+
publicationStatus: submission.status,
|
|
12805
|
+
isLive: submission.status === "published" && submission.publishedRevision !== null
|
|
12806
|
+
};
|
|
12807
|
+
}
|
|
12808
|
+
|
|
12809
|
+
// src/api/local-sourcebook-compiler.ts
|
|
12771
12810
|
var CATEGORY_LABELS = {
|
|
12772
12811
|
home: "Home & property services",
|
|
12773
12812
|
professional: "Professional services",
|
|
@@ -13120,6 +13159,7 @@ function compileLocalSourcebookListing(input) {
|
|
|
13120
13159
|
evidenceIds: mapsEvidenceId ? [mapsEvidenceId] : []
|
|
13121
13160
|
}
|
|
13122
13161
|
];
|
|
13162
|
+
const publicUrls = localSourcebookPublicUrls(input.submission.category, input.submission.state, input.submission.slug);
|
|
13123
13163
|
const listing = {
|
|
13124
13164
|
id: input.submission.id,
|
|
13125
13165
|
publicationRevision: input.submission.draftRevision + 1,
|
|
@@ -13128,6 +13168,14 @@ function compileLocalSourcebookListing(input) {
|
|
|
13128
13168
|
state: input.submission.state.toLowerCase(),
|
|
13129
13169
|
stateName: STATE_NAMES[input.submission.state.toUpperCase()] ?? input.submission.state.toUpperCase(),
|
|
13130
13170
|
slug: input.submission.slug,
|
|
13171
|
+
canonicalPaths: {
|
|
13172
|
+
profile: publicUrls.profilePath,
|
|
13173
|
+
reviews: publicUrls.reviewsPath
|
|
13174
|
+
},
|
|
13175
|
+
canonicalUrls: {
|
|
13176
|
+
profile: publicUrls.profileUrl,
|
|
13177
|
+
reviews: publicUrls.reviewsUrl
|
|
13178
|
+
},
|
|
13131
13179
|
name: maps?.name || input.submission.businessName,
|
|
13132
13180
|
summary,
|
|
13133
13181
|
description,
|
|
@@ -21354,7 +21402,11 @@ function getLocalSourcebookContract(category) {
|
|
|
21354
21402
|
categories: LOCAL_SOURCEBOOK_CATEGORIES,
|
|
21355
21403
|
selectedCategory: category ?? null,
|
|
21356
21404
|
categoryTag: category ? CATEGORY_TAG[category] : null,
|
|
21357
|
-
canonicalRoutes: {
|
|
21405
|
+
canonicalRoutes: {
|
|
21406
|
+
nationwideDirectory: "https://{category}.localsourcebook.com/directory",
|
|
21407
|
+
profile: "https://{category}.localsourcebook.com/{state}/{business-slug}/",
|
|
21408
|
+
reviews: "https://{category}.localsourcebook.com/{state}/{business-slug}/reviews"
|
|
21409
|
+
},
|
|
21358
21410
|
requiredCreateFields: ["category", "state", "businessName", "websiteUrl", "tags", "idempotencyKey"],
|
|
21359
21411
|
systemCompiledSections: ["identity", "services/products", "service areas/locations", "genuine media", "reviews and theme counts", "evidence", "answered FAQ", "collection receipts"],
|
|
21360
21412
|
workflow: ["list-local-sourcebook-tags", "get-local-sourcebook-contract", "prepare-local-sourcebook-write", "validate-local-sourcebook-write", "local-sourcebook-capture", "local_sourcebook_submission_status"],
|
|
@@ -21374,9 +21426,10 @@ async function prepareLocalSourcebookWrite(input) {
|
|
|
21374
21426
|
...parsed.tags.filter((tag) => tag !== categoryTag).map((tag) => ({ tag }))
|
|
21375
21427
|
];
|
|
21376
21428
|
const tagResolutions = await resolveLocalSourcebookTags(candidates);
|
|
21429
|
+
const publicUrls = localSourcebookPublicUrls(parsed.category, parsed.state, slug2);
|
|
21377
21430
|
return {
|
|
21378
21431
|
ok: true,
|
|
21379
|
-
route: { category: parsed.category, state: parsed.state, slug: slug2,
|
|
21432
|
+
route: { category: parsed.category, state: parsed.state, slug: slug2, ...publicUrls },
|
|
21380
21433
|
proposedWrite: { ...parsed, slug: slug2, tags: tagResolutions.filter((item) => item.action === "reuse").map((item) => item.tag) },
|
|
21381
21434
|
contract: getLocalSourcebookContract(parsed.category),
|
|
21382
21435
|
tagResolutions,
|
|
@@ -21493,6 +21546,7 @@ localSourcebookApp.post("/capture", createApiKeyAuth(), async (c) => {
|
|
|
21493
21546
|
return c.json({ error: "idempotency_key_required", message: "A stable idempotencyKey is required for a new Local Sourcebook capture." }, 400);
|
|
21494
21547
|
}
|
|
21495
21548
|
const listingSlug = identity.slug ?? slug(identity.businessName);
|
|
21549
|
+
const publicUrls = localSourcebookPublicUrls(identity.category, identity.state, listingSlug);
|
|
21496
21550
|
const submission = await createLocalSourcebookSubmission({
|
|
21497
21551
|
ownerUserId: Number(user.id),
|
|
21498
21552
|
category: identity.category,
|
|
@@ -21509,7 +21563,8 @@ localSourcebookApp.post("/capture", createApiKeyAuth(), async (c) => {
|
|
|
21509
21563
|
name: identity.businessName,
|
|
21510
21564
|
websiteUrl: identity.websiteUrl,
|
|
21511
21565
|
tags: validation.normalizedTags,
|
|
21512
|
-
canonicalPaths: { profile:
|
|
21566
|
+
canonicalPaths: { profile: publicUrls.profilePath, reviews: publicUrls.reviewsPath },
|
|
21567
|
+
canonicalUrls: { profile: publicUrls.profileUrl, reviews: publicUrls.reviewsUrl },
|
|
21513
21568
|
verificationState: "submitted",
|
|
21514
21569
|
acquisitionPlan: acquisitionPlan(identity.websiteUrl),
|
|
21515
21570
|
evidence: [],
|
|
@@ -21519,7 +21574,7 @@ localSourcebookApp.post("/capture", createApiKeyAuth(), async (c) => {
|
|
|
21519
21574
|
});
|
|
21520
21575
|
await persistLocalSourcebookTags(submission.id, Number(user.id), validation.normalizedTags, parsed.data.tagDecisions);
|
|
21521
21576
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
21522
|
-
return c.json({ ok: true, valid: true, submission, normalizedTags: validation.normalizedTags, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(identity.websiteUrl) }, 202);
|
|
21577
|
+
return c.json({ ok: true, valid: true, submission, publicUrls: localSourcebookPublicationLinks(submission), normalizedTags: validation.normalizedTags, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(identity.websiteUrl) }, 202);
|
|
21523
21578
|
} catch (error) {
|
|
21524
21579
|
const message = error instanceof Error ? error.message : String(error);
|
|
21525
21580
|
const conflict = message.includes("revision conflict") ? "revision_conflict" : message.includes("idempotency key conflicts") ? "idempotency_conflict" : null;
|
|
@@ -21533,6 +21588,7 @@ localSourcebookApp.post("/submissions", createApiKeyAuth(), async (c) => {
|
|
|
21533
21588
|
if (!parsed.success) return c.json({ error: "invalid_submission", issues: parsed.error.issues }, 400);
|
|
21534
21589
|
const input = parsed.data;
|
|
21535
21590
|
const listingSlug = input.slug ?? slug(input.businessName);
|
|
21591
|
+
const publicUrls = localSourcebookPublicUrls(input.category, input.state, listingSlug);
|
|
21536
21592
|
try {
|
|
21537
21593
|
const submission = await createLocalSourcebookSubmission({
|
|
21538
21594
|
ownerUserId: Number(user.id),
|
|
@@ -21545,7 +21601,8 @@ localSourcebookApp.post("/submissions", createApiKeyAuth(), async (c) => {
|
|
|
21545
21601
|
slug: listingSlug,
|
|
21546
21602
|
name: input.businessName,
|
|
21547
21603
|
websiteUrl: input.websiteUrl,
|
|
21548
|
-
canonicalPaths: { profile:
|
|
21604
|
+
canonicalPaths: { profile: publicUrls.profilePath, reviews: publicUrls.reviewsPath },
|
|
21605
|
+
canonicalUrls: { profile: publicUrls.profileUrl, reviews: publicUrls.reviewsUrl },
|
|
21549
21606
|
verificationState: "submitted",
|
|
21550
21607
|
acquisitionPlan: acquisitionPlan(input.websiteUrl),
|
|
21551
21608
|
evidence: [],
|
|
@@ -21554,7 +21611,7 @@ localSourcebookApp.post("/submissions", createApiKeyAuth(), async (c) => {
|
|
|
21554
21611
|
}
|
|
21555
21612
|
});
|
|
21556
21613
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
21557
|
-
return c.json({ ok: true, submission, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(input.websiteUrl) }, 202);
|
|
21614
|
+
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(input.websiteUrl) }, 202);
|
|
21558
21615
|
} catch (error) {
|
|
21559
21616
|
return c.json({ error: "submission_conflict", message: error instanceof Error ? error.message : String(error) }, 409);
|
|
21560
21617
|
}
|
|
@@ -21563,7 +21620,7 @@ localSourcebookApp.get("/submissions/:id", createApiKeyAuth(), async (c) => {
|
|
|
21563
21620
|
const userId = Number(c.get("user").id);
|
|
21564
21621
|
const submission = await getLocalSourcebookSubmission(c.req.param("id"), userId);
|
|
21565
21622
|
if (!submission) return c.json({ error: "not_found" }, 404);
|
|
21566
|
-
return c.json({ ok: true, submission, draft: await getLocalSourcebookDraft(submission.id, userId) });
|
|
21623
|
+
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), draft: await getLocalSourcebookDraft(submission.id, userId) });
|
|
21567
21624
|
});
|
|
21568
21625
|
localSourcebookApp.on(["PATCH", "POST"], "/submissions/:id/draft", createApiKeyAuth(), (c) => c.json({
|
|
21569
21626
|
error: "evidence_refresh_required",
|
|
@@ -21576,12 +21633,14 @@ localSourcebookApp.post("/submissions/:id/refresh", createApiKeyAuth(), async (c
|
|
|
21576
21633
|
const submission = await queueLocalSourcebookRefresh(c.req.param("id"), Number(user.id));
|
|
21577
21634
|
if (!submission) return c.json({ error: "not_found" }, 404);
|
|
21578
21635
|
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
21579
|
-
return c.json({ ok: true, submission, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl) }, 202);
|
|
21636
|
+
return c.json({ ok: true, submission, publicUrls: localSourcebookPublicationLinks(submission), acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl) }, 202);
|
|
21580
21637
|
} catch (error) {
|
|
21581
21638
|
return c.json({ error: "moderated_listing", message: error instanceof Error ? error.message : String(error) }, 409);
|
|
21582
21639
|
}
|
|
21583
21640
|
});
|
|
21584
21641
|
var publicLocalSourcebookApp = new Hono17();
|
|
21642
|
+
publicLocalSourcebookApp.get("/", async (c) => c.json({ ok: true, listings: await listAllPublicLocalSourcebook() }));
|
|
21643
|
+
publicLocalSourcebookApp.get("/:category", async (c) => c.json({ ok: true, listings: await listAllPublicLocalSourcebook(c.req.param("category")) }));
|
|
21585
21644
|
publicLocalSourcebookApp.get("/:category/:state", async (c) => c.json({ ok: true, listings: await listPublicLocalSourcebook(c.req.param("category"), c.req.param("state").toLowerCase()) }));
|
|
21586
21645
|
publicLocalSourcebookApp.get("/:category/:state/:slug", async (c) => {
|
|
21587
21646
|
const listing = await getPublicLocalSourcebook(c.req.param("category"), c.req.param("state").toLowerCase(), c.req.param("slug"));
|
|
@@ -40959,4 +41018,4 @@ app.get("/blog/:slug/", (c) => {
|
|
|
40959
41018
|
export {
|
|
40960
41019
|
app
|
|
40961
41020
|
};
|
|
40962
|
-
//# sourceMappingURL=server-
|
|
41021
|
+
//# sourceMappingURL=server-JJLFY46K.js.map
|