mcp-scraper 0.44.0 → 0.44.2
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 +1 -1
- package/dist/bin/api-server.cjs +70 -107
- 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 +13 -23
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +2 -2
- package/dist/{chunk-HH5CE5LP.js → chunk-M27QGXUM.js} +14 -24
- package/dist/chunk-M27QGXUM.js.map +1 -0
- package/dist/chunk-OEW4VBS2.js +7 -0
- package/dist/chunk-OEW4VBS2.js.map +1 -0
- package/dist/{server-75YGJWSI.js → server-RTQUTQZE.js} +57 -84
- package/dist/server-RTQUTQZE.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-HH5CE5LP.js.map +0 -1
- package/dist/chunk-RUDXFPKE.js +0 -7
- package/dist/chunk-RUDXFPKE.js.map +0 -1
- package/dist/server-75YGJWSI.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["export const PACKAGE_VERSION = '0.44.2'\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-M27QGXUM.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-OEW4VBS2.js";
|
|
146
146
|
import {
|
|
147
147
|
abandonExtractSettlement,
|
|
148
148
|
countSuccessfulPages,
|
|
@@ -11972,6 +11972,7 @@ function ensureLocalSourcebookSchema() {
|
|
|
11972
11972
|
metadata_json TEXT NOT NULL DEFAULT '{}',
|
|
11973
11973
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
11974
11974
|
)`);
|
|
11975
|
+
await publishEligibleEvidenceBackedLocalSourcebookRevisions(db);
|
|
11975
11976
|
})().catch((error) => {
|
|
11976
11977
|
schemaPromise2 = null;
|
|
11977
11978
|
schemaDb2 = null;
|
|
@@ -11979,6 +11980,19 @@ function ensureLocalSourcebookSchema() {
|
|
|
11979
11980
|
});
|
|
11980
11981
|
return schemaPromise2;
|
|
11981
11982
|
}
|
|
11983
|
+
async function publishEligibleEvidenceBackedLocalSourcebookRevisions(db = getDb()) {
|
|
11984
|
+
const result = await db.execute(`UPDATE local_sourcebook_submissions
|
|
11985
|
+
SET status = 'published', published_revision = draft_revision, updated_at = datetime('now')
|
|
11986
|
+
WHERE status = 'needs_review'
|
|
11987
|
+
AND EXISTS (
|
|
11988
|
+
SELECT 1 FROM local_sourcebook_revisions r
|
|
11989
|
+
WHERE r.submission_id = local_sourcebook_submissions.id
|
|
11990
|
+
AND r.revision = local_sourcebook_submissions.draft_revision
|
|
11991
|
+
AND r.actor_kind = 'system'
|
|
11992
|
+
AND r.actor_id = 'local-sourcebook-worker'
|
|
11993
|
+
)`);
|
|
11994
|
+
return Number(result.rowsAffected ?? 0);
|
|
11995
|
+
}
|
|
11982
11996
|
function rowValue(row, key) {
|
|
11983
11997
|
return row[key];
|
|
11984
11998
|
}
|
|
@@ -12048,23 +12062,12 @@ async function getLocalSourcebookDraft(id, ownerUserId) {
|
|
|
12048
12062
|
const result = await getDb().execute({ sql: `SELECT payload_json FROM local_sourcebook_revisions WHERE submission_id = ? AND revision = ?`, args: [id, submission.draftRevision] });
|
|
12049
12063
|
return result.rows[0] ? parseJson2(result.rows[0].payload_json) : null;
|
|
12050
12064
|
}
|
|
12051
|
-
async function reviseLocalSourcebookDraft(id, ownerUserId, payload, baseRevision) {
|
|
12052
|
-
const submission = await getLocalSourcebookSubmission(id, ownerUserId);
|
|
12053
|
-
if (!submission) return null;
|
|
12054
|
-
if (baseRevision !== void 0 && baseRevision !== submission.draftRevision) {
|
|
12055
|
-
throw new Error(`Draft revision conflict: current revision is ${submission.draftRevision}, but the write targeted ${baseRevision}.`);
|
|
12056
|
-
}
|
|
12057
|
-
const revision = submission.draftRevision + 1;
|
|
12058
|
-
await getDb().batch([
|
|
12059
|
-
{ sql: `INSERT INTO local_sourcebook_revisions (submission_id, revision, payload_json, actor_kind, actor_id) VALUES (?, ?, ?, 'owner', ?)`, args: [id, revision, JSON.stringify(payload), String(ownerUserId)] },
|
|
12060
|
-
{ sql: `UPDATE local_sourcebook_submissions SET draft_revision = ?, status = CASE WHEN status = 'published' THEN status ELSE 'needs_review' END, updated_at = datetime('now') WHERE id = ? AND owner_user_id = ?`, args: [revision, id, ownerUserId] }
|
|
12061
|
-
], "write");
|
|
12062
|
-
await event(id, "draft.revised", "owner", String(ownerUserId), { revision });
|
|
12063
|
-
return getLocalSourcebookSubmission(id, ownerUserId);
|
|
12064
|
-
}
|
|
12065
12065
|
async function queueLocalSourcebookRefresh(id, ownerUserId) {
|
|
12066
12066
|
const existing = await getLocalSourcebookSubmission(id, ownerUserId);
|
|
12067
12067
|
if (!existing) return null;
|
|
12068
|
+
if (existing.status === "rejected" || existing.status === "unpublished") {
|
|
12069
|
+
throw new Error(`A ${existing.status} Local Sourcebook listing cannot be refreshed by its owner.`);
|
|
12070
|
+
}
|
|
12068
12071
|
const coverage = { ...existing.coverage, refreshRequestedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
12069
12072
|
await getDb().execute({ sql: `UPDATE local_sourcebook_submissions SET status = 'queued', coverage_json = ?, acquisition_claimed_at = NULL, acquisition_error = NULL, updated_at = datetime('now') WHERE id = ? AND owner_user_id = ?`, args: [JSON.stringify(coverage), id, ownerUserId] });
|
|
12070
12073
|
await event(id, "enrichment.queued", "owner", String(ownerUserId));
|
|
@@ -12102,12 +12105,13 @@ async function completeLocalSourcebookAcquisition(id, payload, coverage, baseRev
|
|
|
12102
12105
|
WHERE EXISTS (SELECT 1 FROM local_sourcebook_submissions WHERE id = ? AND status = 'enriching' AND draft_revision = ?)`,
|
|
12103
12106
|
args: [id, revision, JSON.stringify(payload), id, expectedRevision]
|
|
12104
12107
|
},
|
|
12105
|
-
{ sql: `UPDATE local_sourcebook_submissions SET draft_revision = ?, status = '
|
|
12108
|
+
{ sql: `UPDATE local_sourcebook_submissions SET draft_revision = ?, published_revision = ?, status = 'published', coverage_json = ?, acquisition_claimed_at = NULL, acquisition_error = NULL, updated_at = datetime('now') WHERE id = ? AND status = 'enriching' AND draft_revision = ?`, args: [revision, revision, JSON.stringify(coverage), id, expectedRevision] }
|
|
12106
12109
|
], "write");
|
|
12107
12110
|
if (Number(results[0]?.rowsAffected ?? 0) !== 1 || Number(results[1]?.rowsAffected ?? 0) !== 1) {
|
|
12108
12111
|
throw new Error(`Local Sourcebook acquisition revision conflict: revision ${expectedRevision} changed before completion.`);
|
|
12109
12112
|
}
|
|
12110
12113
|
await event(id, "enrichment.completed", "system", "local-sourcebook-worker", { revision, coverage });
|
|
12114
|
+
await event(id, "publication.auto_published", "system", "local-sourcebook-worker", { revision });
|
|
12111
12115
|
return getLocalSourcebookSubmission(id);
|
|
12112
12116
|
}
|
|
12113
12117
|
async function failLocalSourcebookAcquisition(id, message) {
|
|
@@ -12130,6 +12134,15 @@ async function listQueuedLocalSourcebookSubmissionIds(limit = 25) {
|
|
|
12130
12134
|
async function publishLocalSourcebookSubmission(id) {
|
|
12131
12135
|
const submission = await getLocalSourcebookSubmission(id);
|
|
12132
12136
|
if (!submission) return null;
|
|
12137
|
+
const revision = await getDb().execute({
|
|
12138
|
+
sql: `SELECT actor_kind, actor_id FROM local_sourcebook_revisions WHERE submission_id = ? AND revision = ? LIMIT 1`,
|
|
12139
|
+
args: [id, submission.draftRevision]
|
|
12140
|
+
});
|
|
12141
|
+
const actorKind = revision.rows[0] ? String(revision.rows[0].actor_kind) : "";
|
|
12142
|
+
const actorId = revision.rows[0] ? String(revision.rows[0].actor_id) : "";
|
|
12143
|
+
if (actorKind !== "system" || actorId !== "local-sourcebook-worker") {
|
|
12144
|
+
throw new Error("Only a system-compiled Local Sourcebook revision can be published.");
|
|
12145
|
+
}
|
|
12133
12146
|
await getDb().execute({ sql: `UPDATE local_sourcebook_submissions SET status = 'published', published_revision = draft_revision, updated_at = datetime('now') WHERE id = ?`, args: [id] });
|
|
12134
12147
|
await event(id, "publication.published", "admin", "admin", { revision: submission.draftRevision });
|
|
12135
12148
|
return getLocalSourcebookSubmission(id);
|
|
@@ -13328,11 +13341,12 @@ async function runLocalSourcebookAcquisition(submission, provider = createDefaul
|
|
|
13328
13341
|
await logRequestEvent({ userId: submission.ownerUserId, source: "local_sourcebook_maps", status: "done", query: submission.businessName, location: submission.state.toUpperCase(), resultCount: maps.reviews.length, result: { submissionId: submission.id, placeUrl: maps.placeUrl, cid: maps.cidDecimal ?? maps.cid, reviewsStatus: maps.reviewsStatus, reviewsRetained: maps.reviews.length, services: maps.services.length, areasServed: maps.areasServed.length } });
|
|
13329
13342
|
} catch (error) {
|
|
13330
13343
|
mapsError = errorMessage2(error);
|
|
13344
|
+
maps = null;
|
|
13331
13345
|
await creditMcIdempotent(submission.ownerUserId, MC_COSTS.maps_place, LedgerOperation.REFUND, `Local Sourcebook failed exact-place acquisition: ${submission.id}`, `${billingCycle}:maps-failure-refund`);
|
|
13332
13346
|
mapsRefunded = true;
|
|
13333
13347
|
await logRequestEvent({ userId: submission.ownerUserId, source: "local_sourcebook_maps", status: "failed", query: submission.businessName, location: submission.state.toUpperCase(), error: mapsError });
|
|
13334
13348
|
}
|
|
13335
|
-
if (!
|
|
13349
|
+
if (!maps) throw new Error(`Exact-place acquisition is required before publication. Maps: ${mapsError || "not available"}. Website: ${siteError || (site ? "captured" : "not available")}.`);
|
|
13336
13350
|
const compiled = compileLocalSourcebookListing({
|
|
13337
13351
|
submission,
|
|
13338
13352
|
site,
|
|
@@ -21255,23 +21269,6 @@ var DirectoryIdentitySchema = z25.object({
|
|
|
21255
21269
|
tags: z25.array(z25.string().trim().min(1).max(60)).max(20).default([]),
|
|
21256
21270
|
idempotencyKey: z25.string().trim().min(8).max(200)
|
|
21257
21271
|
});
|
|
21258
|
-
var DirectoryListingDraftSchema = z25.object({
|
|
21259
|
-
id: z25.string().min(1),
|
|
21260
|
-
category: z25.enum(LOCAL_SOURCEBOOK_CATEGORIES),
|
|
21261
|
-
state: z25.string().trim().length(2),
|
|
21262
|
-
slug: z25.string().trim().min(1),
|
|
21263
|
-
name: z25.string().trim().min(2),
|
|
21264
|
-
summary: z25.string().trim().min(20),
|
|
21265
|
-
description: z25.string().trim().min(20),
|
|
21266
|
-
website: z25.url(),
|
|
21267
|
-
services: z25.array(z25.string()),
|
|
21268
|
-
products: z25.array(z25.string()),
|
|
21269
|
-
serviceAreas: z25.array(z25.string()),
|
|
21270
|
-
media: z25.array(z25.record(z25.string(), z25.unknown())),
|
|
21271
|
-
reviews: z25.array(z25.record(z25.string(), z25.unknown())),
|
|
21272
|
-
evidence: z25.array(z25.record(z25.string(), z25.unknown())),
|
|
21273
|
-
faq: z25.array(z25.object({ question: z25.string().min(3), answer: z25.string().min(12), evidenceIds: z25.array(z25.string()) }))
|
|
21274
|
-
}).passthrough();
|
|
21275
21272
|
function normalizeTag(value) {
|
|
21276
21273
|
return value.toLowerCase().trim().replace(/&/g, " and ").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
|
|
21277
21274
|
}
|
|
@@ -21352,18 +21349,18 @@ async function resolveLocalSourcebookTags(candidates) {
|
|
|
21352
21349
|
function getLocalSourcebookContract(category) {
|
|
21353
21350
|
return {
|
|
21354
21351
|
name: "Local Sourcebook listing",
|
|
21355
|
-
version: "
|
|
21352
|
+
version: "local_sourcebook_listing_v2",
|
|
21356
21353
|
purpose: "An owner-scoped, evidence-backed local business record with a separate public profile and complete captured-review archive.",
|
|
21357
21354
|
categories: LOCAL_SOURCEBOOK_CATEGORIES,
|
|
21358
21355
|
selectedCategory: category ?? null,
|
|
21359
21356
|
categoryTag: category ? CATEGORY_TAG[category] : null,
|
|
21360
21357
|
canonicalRoutes: { profile: "/{state}/{business-slug}/", reviews: "/{state}/{business-slug}/reviews" },
|
|
21361
21358
|
requiredCreateFields: ["category", "state", "businessName", "websiteUrl", "tags", "idempotencyKey"],
|
|
21362
|
-
|
|
21359
|
+
systemCompiledSections: ["identity", "services/products", "service areas/locations", "genuine media", "reviews and theme counts", "evidence", "answered FAQ", "collection receipts"],
|
|
21363
21360
|
workflow: ["list-local-sourcebook-tags", "get-local-sourcebook-contract", "prepare-local-sourcebook-write", "validate-local-sourcebook-write", "local-sourcebook-capture", "local_sourcebook_submission_status"],
|
|
21364
|
-
ownership: "Only the MCP Scraper account that captures a listing can read or
|
|
21361
|
+
ownership: "Only the MCP Scraper account that captures a listing can read it or request a paid evidence refresh.",
|
|
21365
21362
|
acquisition: { websitePagesMaximum: 100, reviewsMaximum: 500, exactMapsIdentityRequired: true, partialResultsRequireStoppingReasons: true },
|
|
21366
|
-
publication: { automatic: false, adminReviewRequired:
|
|
21363
|
+
publication: { automatic: true, evidenceCompiledOnly: true, ownerAuthoredClaimsAccepted: false, adminReviewRequired: false, lastPublishedRevisionRemainsPublicDuringRefresh: true },
|
|
21367
21364
|
tagPolicy: { inspectVocabularyFirst: true, minimum: 1, maximum: 20, newTagsRequire: ["central=true", "reusable=true", "description"], newTagsStartAs: "pending" }
|
|
21368
21365
|
};
|
|
21369
21366
|
}
|
|
@@ -21386,7 +21383,8 @@ async function prepareLocalSourcebookWrite(input) {
|
|
|
21386
21383
|
instructions: [
|
|
21387
21384
|
"Resolve every review candidate before capture; do not silently create a near-duplicate tag.",
|
|
21388
21385
|
"Call validate-local-sourcebook-write with the proposed identity, resolved tags, and any required tag decisions.",
|
|
21389
|
-
"Call local-sourcebook-capture only after validation returns valid=true. Capture
|
|
21386
|
+
"Call local-sourcebook-capture only after validation returns valid=true. Capture queues paid acquisition and automatically publishes the resulting system-compiled evidence revision.",
|
|
21387
|
+
"Owners cannot supply public listing claims directly. Request local_sourcebook_refresh when source-backed public facts need to be reacquired."
|
|
21390
21388
|
]
|
|
21391
21389
|
};
|
|
21392
21390
|
}
|
|
@@ -21394,17 +21392,9 @@ async function validateLocalSourcebookWrite(input) {
|
|
|
21394
21392
|
const errors = [];
|
|
21395
21393
|
const warnings = [];
|
|
21396
21394
|
let normalizedIdentity2;
|
|
21397
|
-
|
|
21398
|
-
if (
|
|
21399
|
-
|
|
21400
|
-
const parsedListing = DirectoryListingDraftSchema.safeParse(input.listing);
|
|
21401
|
-
if (!parsedListing.success) errors.push(...parsedListing.error.issues.map((issue) => `listing.${issue.path.join(".")}: ${issue.message}`));
|
|
21402
|
-
else normalizedListing = parsedListing.data;
|
|
21403
|
-
} else {
|
|
21404
|
-
const parsedIdentity = DirectoryIdentitySchema.safeParse(input.identity);
|
|
21405
|
-
if (!parsedIdentity.success) errors.push(...parsedIdentity.error.issues.map((issue) => `identity.${issue.path.join(".")}: ${issue.message}`));
|
|
21406
|
-
else normalizedIdentity2 = parsedIdentity.data;
|
|
21407
|
-
}
|
|
21395
|
+
const parsedIdentity = DirectoryIdentitySchema.safeParse(input.identity);
|
|
21396
|
+
if (!parsedIdentity.success) errors.push(...parsedIdentity.error.issues.map((issue) => `identity.${issue.path.join(".")}: ${issue.message}`));
|
|
21397
|
+
else normalizedIdentity2 = parsedIdentity.data;
|
|
21408
21398
|
const candidates = input.tagCandidates ?? (normalizedIdentity2?.tags.map((tag) => ({ tag })) ?? []);
|
|
21409
21399
|
const resolutions = await resolveLocalSourcebookTags(candidates);
|
|
21410
21400
|
const decisions = new Map((input.tagDecisions ?? []).map((decision) => [normalizeTag(decision.tag), decision]));
|
|
@@ -21423,12 +21413,12 @@ async function validateLocalSourcebookWrite(input) {
|
|
|
21423
21413
|
}
|
|
21424
21414
|
if (resolution.action === "omit") warnings.push(`Tag \u201C${resolution.candidate}\u201D will be omitted: ${resolution.reason}`);
|
|
21425
21415
|
}
|
|
21426
|
-
if (
|
|
21416
|
+
if (normalizedIdentity2) {
|
|
21427
21417
|
const categoryTag = CATEGORY_TAG[normalizedIdentity2.category];
|
|
21428
21418
|
if (!normalizedTags.includes(categoryTag)) normalizedTags.unshift(categoryTag);
|
|
21429
21419
|
}
|
|
21430
21420
|
if (!normalizedTags.length) errors.push("At least one canonical directory tag is required.");
|
|
21431
|
-
return { ok: true, valid: errors.length === 0, errors, warnings, normalizedIdentity: normalizedIdentity2,
|
|
21421
|
+
return { ok: true, valid: errors.length === 0, errors, warnings, normalizedIdentity: normalizedIdentity2, normalizedTags: [...new Set(normalizedTags)], tagResolutions: resolutions };
|
|
21432
21422
|
}
|
|
21433
21423
|
async function persistLocalSourcebookTags(submissionId, userId, tags, decisions = []) {
|
|
21434
21424
|
await ensureLocalSourcebookTags();
|
|
@@ -21445,11 +21435,6 @@ async function persistLocalSourcebookTags(submissionId, userId, tags, decisions
|
|
|
21445
21435
|
await db.execute({ sql: `INSERT OR IGNORE INTO local_sourcebook_submission_tags (submission_id, tag) VALUES (?, ?)`, args: [submissionId, tag] });
|
|
21446
21436
|
}
|
|
21447
21437
|
}
|
|
21448
|
-
async function replaceLocalSourcebookTags(submissionId, userId, tags, decisions = []) {
|
|
21449
|
-
await ensureLocalSourcebookTags();
|
|
21450
|
-
await getDb().execute({ sql: `DELETE FROM local_sourcebook_submission_tags WHERE submission_id = ?`, args: [submissionId] });
|
|
21451
|
-
await persistLocalSourcebookTags(submissionId, userId, tags, decisions);
|
|
21452
|
-
}
|
|
21453
21438
|
|
|
21454
21439
|
// src/api/local-sourcebook-routes.ts
|
|
21455
21440
|
var slug = (value) => value.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 100);
|
|
@@ -21461,13 +21446,9 @@ var SubmitSchema = z26.object({
|
|
|
21461
21446
|
slug: z26.string().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(100).optional(),
|
|
21462
21447
|
idempotencyKey: z26.string().trim().min(8).max(200).optional()
|
|
21463
21448
|
}).strict();
|
|
21464
|
-
var DraftSchema = z26.object({ payload: z26.record(z26.string(), z26.unknown()) }).strict();
|
|
21465
21449
|
var PrepareWriteSchema = DirectoryIdentitySchema.extend({ tagCandidates: z26.array(DirectoryTagCandidateSchema).max(20).optional() });
|
|
21466
21450
|
var ValidateWriteSchema = z26.object({
|
|
21467
21451
|
identity: DirectoryIdentitySchema.optional(),
|
|
21468
|
-
listing: z26.record(z26.string(), z26.unknown()).optional(),
|
|
21469
|
-
submissionId: z26.string().trim().min(1).optional(),
|
|
21470
|
-
baseRevision: z26.number().int().min(1).optional(),
|
|
21471
21452
|
tagCandidates: z26.array(DirectoryTagCandidateSchema).max(20).optional(),
|
|
21472
21453
|
tagDecisions: z26.array(DirectoryTagDecisionSchema).max(20).optional()
|
|
21473
21454
|
}).strict();
|
|
@@ -21477,7 +21458,7 @@ function acquisitionPlan(websiteUrl) {
|
|
|
21477
21458
|
website: { startUrl: websiteUrl, mode: "broad_site_crawl", capture: ["homepage", "services", "products", "locations", "service_areas", "about", "team_staff", "contact", "policies"] },
|
|
21478
21459
|
media: { requirement: "genuine_business_images_only", sources: ["business_website", "business_team_pages", "verified_business_profiles"] },
|
|
21479
21460
|
reviews: { mode: "exhaust_accessible_continuation", requirement: "retain_each_review_and_source", disclosure: "report captured count, reported available count, and exact stopping reason" },
|
|
21480
|
-
publication: { automatic:
|
|
21461
|
+
publication: { automatic: true, evidenceCompiledOnly: true, adminReviewRequired: false }
|
|
21481
21462
|
};
|
|
21482
21463
|
}
|
|
21483
21464
|
var localSourcebookApp = new Hono17();
|
|
@@ -21507,13 +21488,6 @@ localSourcebookApp.post("/capture", createApiKeyAuth(), async (c) => {
|
|
|
21507
21488
|
const validation = await validateLocalSourcebookWrite(parsed.data);
|
|
21508
21489
|
if (!validation.valid) return c.json({ error: "invalid_directory_write", ...validation }, 400);
|
|
21509
21490
|
try {
|
|
21510
|
-
if (parsed.data.submissionId) {
|
|
21511
|
-
const submission2 = await getLocalSourcebookSubmission(parsed.data.submissionId, Number(user.id));
|
|
21512
|
-
if (!submission2) return c.json({ error: "not_found" }, 404);
|
|
21513
|
-
const updated = await reviseLocalSourcebookDraft(submission2.id, Number(user.id), validation.normalizedListing, parsed.data.baseRevision);
|
|
21514
|
-
await replaceLocalSourcebookTags(submission2.id, Number(user.id), validation.normalizedTags, parsed.data.tagDecisions);
|
|
21515
|
-
return c.json({ ok: true, valid: true, submission: updated, normalizedTags: validation.normalizedTags, captured: "draft_revision", acquisitionQueued: false });
|
|
21516
|
-
}
|
|
21517
21491
|
const identity = validation.normalizedIdentity;
|
|
21518
21492
|
if (!parsed.data.idempotencyKey && !identity.idempotencyKey) {
|
|
21519
21493
|
return c.json({ error: "idempotency_key_required", message: "A stable idempotencyKey is required for a new Local Sourcebook capture." }, 400);
|
|
@@ -21591,22 +21565,21 @@ localSourcebookApp.get("/submissions/:id", createApiKeyAuth(), async (c) => {
|
|
|
21591
21565
|
if (!submission) return c.json({ error: "not_found" }, 404);
|
|
21592
21566
|
return c.json({ ok: true, submission, draft: await getLocalSourcebookDraft(submission.id, userId) });
|
|
21593
21567
|
});
|
|
21594
|
-
localSourcebookApp.on(["PATCH", "POST"], "/submissions/:id/draft", createApiKeyAuth(),
|
|
21595
|
-
|
|
21596
|
-
|
|
21597
|
-
|
|
21598
|
-
if (!parsed.success) return c.json({ error: "invalid_draft", issues: parsed.error.issues }, 400);
|
|
21599
|
-
const submission = await reviseLocalSourcebookDraft(c.req.param("id"), Number(user.id), parsed.data.payload);
|
|
21600
|
-
if (!submission) return c.json({ error: "not_found" }, 404);
|
|
21601
|
-
return c.json({ ok: true, submission });
|
|
21602
|
-
});
|
|
21568
|
+
localSourcebookApp.on(["PATCH", "POST"], "/submissions/:id/draft", createApiKeyAuth(), (c) => c.json({
|
|
21569
|
+
error: "evidence_refresh_required",
|
|
21570
|
+
message: "Owner-authored listing payloads are not accepted. Request a refresh so MCP Scraper can reacquire and compile the public evidence."
|
|
21571
|
+
}, 409));
|
|
21603
21572
|
localSourcebookApp.post("/submissions/:id/refresh", createApiKeyAuth(), async (c) => {
|
|
21604
21573
|
const user = c.get("user");
|
|
21605
21574
|
if (!user.subscription_tier) return c.json({ error: "subscription_required" }, 402);
|
|
21606
|
-
|
|
21607
|
-
|
|
21608
|
-
|
|
21609
|
-
|
|
21575
|
+
try {
|
|
21576
|
+
const submission = await queueLocalSourcebookRefresh(c.req.param("id"), Number(user.id));
|
|
21577
|
+
if (!submission) return c.json({ error: "not_found" }, 404);
|
|
21578
|
+
const dispatched = await dispatchLocalSourcebookAcquisition(submission.id).catch(() => false);
|
|
21579
|
+
return c.json({ ok: true, submission, acquisition: { queued: true, dispatched }, acquisitionPlan: acquisitionPlan(submission.websiteUrl) }, 202);
|
|
21580
|
+
} catch (error) {
|
|
21581
|
+
return c.json({ error: "moderated_listing", message: error instanceof Error ? error.message : String(error) }, 409);
|
|
21582
|
+
}
|
|
21610
21583
|
});
|
|
21611
21584
|
var publicLocalSourcebookApp = new Hono17();
|
|
21612
21585
|
publicLocalSourcebookApp.get("/:category/:state", async (c) => c.json({ ok: true, listings: await listPublicLocalSourcebook(c.req.param("category"), c.req.param("state").toLowerCase()) }));
|
|
@@ -40986,4 +40959,4 @@ app.get("/blog/:slug/", (c) => {
|
|
|
40986
40959
|
export {
|
|
40987
40960
|
app
|
|
40988
40961
|
};
|
|
40989
|
-
//# sourceMappingURL=server-
|
|
40962
|
+
//# sourceMappingURL=server-RTQUTQZE.js.map
|