mcp-scraper 0.48.0 → 0.49.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.
- package/README.md +2 -2
- package/dist/bin/api-server.cjs +647 -195
- 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 +3 -3
- package/dist/bin/mcp-scraper-install.cjs.map +1 -1
- package/dist/bin/mcp-scraper-install.js +2 -2
- package/dist/bin/mcp-stdio-server.cjs +46 -3
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +3 -3
- package/dist/{chunk-PTABZABJ.js → chunk-64WBUDPC.js} +46 -2
- package/dist/chunk-64WBUDPC.js.map +1 -0
- package/dist/{chunk-QAH7WMYC.js → chunk-QH63IZTX.js} +3 -3
- package/dist/chunk-QH63IZTX.js.map +1 -0
- package/dist/chunk-XLEDHV3J.js +7 -0
- package/dist/chunk-XLEDHV3J.js.map +1 -0
- package/dist/{server-EVTCL3KB.js → server-JE7SLZLJ.js} +521 -117
- package/dist/server-JE7SLZLJ.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-IAXQIHNS.js +0 -7
- package/dist/chunk-IAXQIHNS.js.map +0 -1
- package/dist/chunk-PTABZABJ.js.map +0 -1
- package/dist/chunk-QAH7WMYC.js.map +0 -1
- package/dist/server-EVTCL3KB.js.map +0 -1
package/dist/bin/api-server.cjs
CHANGED
|
@@ -41371,7 +41371,7 @@ var PACKAGE_VERSION;
|
|
|
41371
41371
|
var init_version = __esm({
|
|
41372
41372
|
"src/version.ts"() {
|
|
41373
41373
|
"use strict";
|
|
41374
|
-
PACKAGE_VERSION = "0.
|
|
41374
|
+
PACKAGE_VERSION = "0.49.0";
|
|
41375
41375
|
}
|
|
41376
41376
|
});
|
|
41377
41377
|
|
|
@@ -41429,6 +41429,8 @@ seam is noted so you can chain them.
|
|
|
41429
41429
|
JSON-LD, media, citations, source metadata, related entities, trails, and saved account filters.
|
|
41430
41430
|
- Read one published entity -> **commons_get_entity**. It returns the Wikidata-style backend fields,
|
|
41431
41431
|
JSON-LD, source provenance, media, ledger, and the Wikipedia-style page projection.
|
|
41432
|
+
- Read its machine-verifiable governed relationships -> **commons_get_entity_linkset**. It returns the
|
|
41433
|
+
RFC 9264 linkset projection; do not infer claim status from loose See Also labels.
|
|
41432
41434
|
- List unresolved See Also concepts -> **commons_list_needs_links**. Use it to find concepts that appear
|
|
41433
41435
|
in public See Also sections but do not yet have a Commons entity ID or /wiki/ slug.
|
|
41434
41436
|
- Plan a new or edited entity -> **commons_prepare_entity**. This is the Commons equivalent of
|
|
@@ -42565,7 +42567,7 @@ var init_contracts = __esm({
|
|
|
42565
42567
|
});
|
|
42566
42568
|
|
|
42567
42569
|
// src/mcp/mcp-tool-schemas.ts
|
|
42568
|
-
var import_zod42, WEBSITE_URL_OR_DOMAIN_ERROR, WebsiteUrlOrDomainSchema, HarvestPaaInputSchema, ExtractUrlBaseInputSchema, ExtractUrlInputSchema, ExtractUrlLocalInputSchema, DiffPageBaseInputSchema, DiffPageInputSchema, DiffPageLocalInputSchema, MapSiteUrlsInputSchema, MapWaybackSnapshotsInputSchema, ExtractSiteInputSchema, AuditSiteInputSchema, CheckSiteExportInputSchema, ArchiveReadInputSchema, YoutubeHarvestInputSchema, YoutubeTranscribeInputSchema, FacebookPageIntelInputSchema, FacebookAdSearchInputSchema, RedditThreadInputSchema, RedditTrendingInputSchema, VideoFrameAnalysisInputSchema, VideoFrameAnalysisStatusInputSchema, FacebookAdTranscribeInputSchema, FacebookVideoTranscribeInputSchema, GoogleAdsSearchInputSchema, GoogleAdsPageIntelInputSchema, GoogleAdsTranscribeInputSchema, InstagramProfileContentInputSchema, InstagramMediaDownloadInputSchema, MapsPlaceIntelInputSchema, TrustpilotReviewsInputSchema, G2ReviewsInputSchema, ReviewCardSchema, MapsSearchInputSchema, DirectoryWorkflowInputSchema, LocationMarketsInputSchema, CommonsSearchEntitiesInputSchema, CommonsGetEntityInputSchema, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, DirectoryWorkflowStatusInputSchema, LocalSourcebookSubmitInputSchema, LocalSourcebookCategorySchema, LocalSourcebookSchemaTypeInputSchema, LocalSourcebookTagCandidateObjectSchema, LocalSourcebookTagDecisionObjectSchema, LocalSourcebookIdentityObjectSchema, GetLocalSourcebookContractInputSchema, ListLocalSourcebookTagsInputSchema, ResolveLocalSourcebookTagsInputSchema, PrepareLocalSourcebookWriteInputSchema, ValidateLocalSourcebookWriteInputSchema, LocalSourcebookCaptureInputSchema, LocalSourcebookSubmissionStatusInputSchema, LocalSourcebookRefreshInputSchema, LocalSourcebookOutputSchema, ArtifactPointerOutputSchema, EditorialReadingRoomSiteSchema, EditorialReadingRoomArticleSchema, EditorialReadingRoomGuideInputSchema, EditorialReadingRoomGuideOutputSchema, CreateEditorialReadingRoomInputSchema, EditorialReadingRoomArtifactSchema, CreateEditorialReadingRoomOutputSchema, RenewEditorialReadingRoomDownloadInputSchema, RenewEditorialReadingRoomDownloadOutputSchema, CommonsPublicationSubdomainSchema, CommonsPreparePublicationInputSchema, CommonsValidatePublicationInputSchema, CommonsClaimPublicationInputSchema, CommonsPublishEditorialInputSchema, CommonsGetPublicationInputSchema, RankTrackerModeSchema, RankTrackerBlueprintInputSchema, NullableString, MapsSearchAttemptOutput, MapsSearchOutputSchema, DirectoryMapsBusinessOutput, DirectoryCsvArtifactOutput, DirectoryWorkflowOutputSchema, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, ExtractUrlOutputSchema, DiffPageOutputSchema, ExtractSiteOutputSchema, AuditSiteOutputSchema, CheckSiteExportOutputSchema, ArchiveEntryOutputSchema, ArchiveReadOutputSchema, MapsPlaceIntelOutputSchema, TrustpilotReviewsOutputSchema, G2ReviewsOutputSchema, CreditsInfoOutputSchema, MapSiteUrlsOutputSchema, WaybackCaptureOutputSchema, MapWaybackSnapshotsOutputSchema, YoutubeHarvestOutputSchema, FacebookAdSearchOutputSchema, VideoFrameAnalysisOutputSchema, VideoFrameAnalysisStatusOutputSchema, RedditThreadOutputSchema, RedditTrendingOutputSchema, FacebookPageIntelOutputSchema, GoogleAdsSearchOutputSchema, GoogleAdsPageIntelOutputSchema, TranscriptSignalOutput, FacebookVideoTranscribeOutputSchema, TranscriptChunkOutput, InstagramBrowserOutput, InstagramPaginationOutput, InstagramProfileContentOutputSchema, InstagramMediaTrackOutput, InstagramDownloadOutput, InstagramMediaDownloadOutputSchema, YoutubeTranscribeOutputSchema, FacebookAdTranscribeOutputSchema, GoogleAdsTranscribeOutputSchema, CaptureSerpSnapshotOutputSchema, CaptureSerpPageSnapshotsOutputSchema, CreditsInfoInputSchema, WorkflowIdSchema2, WorkflowListInputSchema, WorkflowSuggestInputSchema, WorkflowRunInputSchema, WorkflowStepInputSchema, WorkflowStatusInputSchema, WorkflowArtifactReadInputSchema, WorkflowRecipeOutput, WorkflowDefinitionOutput, WorkflowArtifactOutput, WorkflowListOutputSchema, WorkflowSuggestOutputSchema, WorkflowRunOutputSchema, WorkflowStepOutputSchema, WorkflowStatusOutputSchema, WorkflowArtifactReadOutputSchema, SearchSerpInputSchema, CaptureSerpSnapshotInputSchema, ScreenshotInputSchema, CaptureSerpPageSnapshotsInputSchema, ReportArtifactReadInputSchema, ReportArtifactReadOutputSchema, ListServiceConnectionsInputSchema, ListServiceConnectionsOutputSchema, TestServiceConnectionInputSchema, TestServiceConnectionOutputSchema, ReadServiceConnectionInputSchema, ReadServiceConnectionOutputSchema, MetaAdCreativeMediaInputSchema, MetaAdCreativeMediaOutputSchema, ImportServiceConnectionToMemoryInputSchema, ImportServiceConnectionToMemoryOutputSchema, DescribeServiceConnectionToolInputSchema, DescribeServiceConnectionToolOutputSchema, ConnectedDataContinuationSchema, ExportConnectedServiceDataInputSchema, ConnectedDataArtifactSchema, ExportConnectedServiceDataOutputSchema, SearchConsoleTableColumnSchema, SearchConsoleTableFilterSchema, ExportSearchConsoleTableDataInputSchema, ExportSearchConsoleTableDataOutputSchema, RenewConnectedDataExportDownloadInputSchema, RenewConnectedDataExportDownloadOutputSchema, CallServiceConnectionActionInputSchema, CallServiceConnectionActionOutputSchema, SetScheduledActionConnectionsInputSchema, SetScheduledActionConnectionsOutputSchema, SlackSendMessageInputSchema, SlackSendMessageOutputSchema, GmailSendMessageInputSchema, GmailSendMessageOutputSchema, GmailSearchContactsInputSchema, GmailSearchContactsOutputSchema, GoogleCalendarCreateEventInputSchema, GoogleCalendarCreateEventOutputSchema, ZoomCreateMeetingInputSchema, ZoomCreateMeetingOutputSchema;
|
|
42570
|
+
var import_zod42, WEBSITE_URL_OR_DOMAIN_ERROR, WebsiteUrlOrDomainSchema, HarvestPaaInputSchema, ExtractUrlBaseInputSchema, ExtractUrlInputSchema, ExtractUrlLocalInputSchema, DiffPageBaseInputSchema, DiffPageInputSchema, DiffPageLocalInputSchema, MapSiteUrlsInputSchema, MapWaybackSnapshotsInputSchema, ExtractSiteInputSchema, AuditSiteInputSchema, CheckSiteExportInputSchema, ArchiveReadInputSchema, YoutubeHarvestInputSchema, YoutubeTranscribeInputSchema, FacebookPageIntelInputSchema, FacebookAdSearchInputSchema, RedditThreadInputSchema, RedditTrendingInputSchema, VideoFrameAnalysisInputSchema, VideoFrameAnalysisStatusInputSchema, FacebookAdTranscribeInputSchema, FacebookVideoTranscribeInputSchema, GoogleAdsSearchInputSchema, GoogleAdsPageIntelInputSchema, GoogleAdsTranscribeInputSchema, InstagramProfileContentInputSchema, InstagramMediaDownloadInputSchema, MapsPlaceIntelInputSchema, TrustpilotReviewsInputSchema, G2ReviewsInputSchema, ReviewCardSchema, MapsSearchInputSchema, DirectoryWorkflowInputSchema, LocationMarketsInputSchema, CommonsSearchEntitiesInputSchema, CommonsGetEntityInputSchema, CommonsGetEntityLinksetInputSchema, CommonsFeaturedImageInputSchema, CommonsMediaInputSchema, CommonsCitationInputSchema, CommonsSourceInputSchema, CommonsRelatedLinkInputSchema, CommonsClaimInputSchema, CommonsPrepareEntityInputSchema, CommonsSubmitEntityInputSchema, CommonsValidateEntityInputSchema, CommonsGetEntityLedgerInputSchema, CommonsSaveFilterInputSchema, CommonsListFiltersInputSchema, CommonsListNeedsLinksInputSchema, CommonsGenericOutputSchema, DirectoryWorkflowStatusInputSchema, LocalSourcebookSubmitInputSchema, LocalSourcebookCategorySchema, LocalSourcebookSchemaTypeInputSchema, LocalSourcebookTagCandidateObjectSchema, LocalSourcebookTagDecisionObjectSchema, LocalSourcebookIdentityObjectSchema, GetLocalSourcebookContractInputSchema, ListLocalSourcebookTagsInputSchema, ResolveLocalSourcebookTagsInputSchema, PrepareLocalSourcebookWriteInputSchema, ValidateLocalSourcebookWriteInputSchema, LocalSourcebookCaptureInputSchema, LocalSourcebookSubmissionStatusInputSchema, LocalSourcebookRefreshInputSchema, LocalSourcebookOutputSchema, ArtifactPointerOutputSchema, EditorialReadingRoomSiteSchema, EditorialReadingRoomArticleSchema, EditorialReadingRoomGuideInputSchema, EditorialReadingRoomGuideOutputSchema, CreateEditorialReadingRoomInputSchema, EditorialReadingRoomArtifactSchema, CreateEditorialReadingRoomOutputSchema, RenewEditorialReadingRoomDownloadInputSchema, RenewEditorialReadingRoomDownloadOutputSchema, CommonsPublicationSubdomainSchema, CommonsPreparePublicationInputSchema, CommonsValidatePublicationInputSchema, CommonsClaimPublicationInputSchema, CommonsPublishEditorialInputSchema, CommonsGetPublicationInputSchema, RankTrackerModeSchema, RankTrackerBlueprintInputSchema, NullableString, MapsSearchAttemptOutput, MapsSearchOutputSchema, DirectoryMapsBusinessOutput, DirectoryCsvArtifactOutput, DirectoryWorkflowOutputSchema, LocationDatasetProvenanceOutput, LocationMarketsOutputSchema, RankTrackerToolPlanOutput, RankTrackerTableOutput, RankTrackerCronJobOutput, RankTrackerBlueprintOutputSchema, OrganicResultOutput, AiOverviewOutput, EntityIdsOutput, HarvestPaaOutputSchema, SearchSerpOutputSchema, ExtractUrlOutputSchema, DiffPageOutputSchema, ExtractSiteOutputSchema, AuditSiteOutputSchema, CheckSiteExportOutputSchema, ArchiveEntryOutputSchema, ArchiveReadOutputSchema, MapsPlaceIntelOutputSchema, TrustpilotReviewsOutputSchema, G2ReviewsOutputSchema, CreditsInfoOutputSchema, MapSiteUrlsOutputSchema, WaybackCaptureOutputSchema, MapWaybackSnapshotsOutputSchema, YoutubeHarvestOutputSchema, FacebookAdSearchOutputSchema, VideoFrameAnalysisOutputSchema, VideoFrameAnalysisStatusOutputSchema, RedditThreadOutputSchema, RedditTrendingOutputSchema, FacebookPageIntelOutputSchema, GoogleAdsSearchOutputSchema, GoogleAdsPageIntelOutputSchema, TranscriptSignalOutput, FacebookVideoTranscribeOutputSchema, TranscriptChunkOutput, InstagramBrowserOutput, InstagramPaginationOutput, InstagramProfileContentOutputSchema, InstagramMediaTrackOutput, InstagramDownloadOutput, InstagramMediaDownloadOutputSchema, YoutubeTranscribeOutputSchema, FacebookAdTranscribeOutputSchema, GoogleAdsTranscribeOutputSchema, CaptureSerpSnapshotOutputSchema, CaptureSerpPageSnapshotsOutputSchema, CreditsInfoInputSchema, WorkflowIdSchema2, WorkflowListInputSchema, WorkflowSuggestInputSchema, WorkflowRunInputSchema, WorkflowStepInputSchema, WorkflowStatusInputSchema, WorkflowArtifactReadInputSchema, WorkflowRecipeOutput, WorkflowDefinitionOutput, WorkflowArtifactOutput, WorkflowListOutputSchema, WorkflowSuggestOutputSchema, WorkflowRunOutputSchema, WorkflowStepOutputSchema, WorkflowStatusOutputSchema, WorkflowArtifactReadOutputSchema, SearchSerpInputSchema, CaptureSerpSnapshotInputSchema, ScreenshotInputSchema, CaptureSerpPageSnapshotsInputSchema, ReportArtifactReadInputSchema, ReportArtifactReadOutputSchema, ListServiceConnectionsInputSchema, ListServiceConnectionsOutputSchema, TestServiceConnectionInputSchema, TestServiceConnectionOutputSchema, ReadServiceConnectionInputSchema, ReadServiceConnectionOutputSchema, MetaAdCreativeMediaInputSchema, MetaAdCreativeMediaOutputSchema, ImportServiceConnectionToMemoryInputSchema, ImportServiceConnectionToMemoryOutputSchema, DescribeServiceConnectionToolInputSchema, DescribeServiceConnectionToolOutputSchema, ConnectedDataContinuationSchema, ExportConnectedServiceDataInputSchema, ConnectedDataArtifactSchema, ExportConnectedServiceDataOutputSchema, SearchConsoleTableColumnSchema, SearchConsoleTableFilterSchema, ExportSearchConsoleTableDataInputSchema, ExportSearchConsoleTableDataOutputSchema, RenewConnectedDataExportDownloadInputSchema, RenewConnectedDataExportDownloadOutputSchema, CallServiceConnectionActionInputSchema, CallServiceConnectionActionOutputSchema, SetScheduledActionConnectionsInputSchema, SetScheduledActionConnectionsOutputSchema, SlackSendMessageInputSchema, SlackSendMessageOutputSchema, GmailSendMessageInputSchema, GmailSendMessageOutputSchema, GmailSearchContactsInputSchema, GmailSearchContactsOutputSchema, GoogleCalendarCreateEventInputSchema, GoogleCalendarCreateEventOutputSchema, ZoomCreateMeetingInputSchema, ZoomCreateMeetingOutputSchema;
|
|
42569
42571
|
var init_mcp_tool_schemas = __esm({
|
|
42570
42572
|
"src/mcp/mcp-tool-schemas.ts"() {
|
|
42571
42573
|
"use strict";
|
|
@@ -42870,6 +42872,9 @@ var init_mcp_tool_schemas = __esm({
|
|
|
42870
42872
|
idOrSlug: import_zod42.z.string().trim().min(1).max(180).describe("Transparent Public Wiki entity id such as TPW-Q... or a public /wiki/ slug."),
|
|
42871
42873
|
includeWikiPage: import_zod42.z.boolean().default(true).describe("Include the Wikipedia-style page projection used by transparent-commons.cc/wiki/.")
|
|
42872
42874
|
};
|
|
42875
|
+
CommonsGetEntityLinksetInputSchema = {
|
|
42876
|
+
idOrSlug: import_zod42.z.string().trim().min(1).max(180).describe("Transparent Commons TPW-Q entity id or /wiki/ slug whose governed RFC 9264 linkset should be read.")
|
|
42877
|
+
};
|
|
42873
42878
|
CommonsFeaturedImageInputSchema = import_zod42.z.object({
|
|
42874
42879
|
url: import_zod42.z.string().url().describe("Required public image URL for a publishable entity. Use extract_url includeFeaturedImage or preserved media when available."),
|
|
42875
42880
|
alt: import_zod42.z.string().trim().max(500).optional(),
|
|
@@ -42922,6 +42927,27 @@ var init_mcp_tool_schemas = __esm({
|
|
|
42922
42927
|
imageUrl: import_zod42.z.string().trim().max(2e3).optional().describe("Optional preview image for hover cards when available."),
|
|
42923
42928
|
needsLink: import_zod42.z.boolean().default(false).describe("Set true when the concept belongs in See Also but no existing Commons entity/page exists yet. The backend exposes these records through commons_list_needs_links.")
|
|
42924
42929
|
}).strict();
|
|
42930
|
+
CommonsClaimInputSchema = import_zod42.z.object({
|
|
42931
|
+
predicate: import_zod42.z.string().trim().min(1).max(500).describe("Registered link relation such as related, describedby, license, or type; alternatively an absolute HTTPS relation URI from a published vocabulary."),
|
|
42932
|
+
predicateLabel: import_zod42.z.string().trim().max(160).optional().describe("Human-readable label for display and review. It does not replace the machine predicate."),
|
|
42933
|
+
objectEntityId: import_zod42.z.string().trim().regex(/^TPW-Q[A-Za-z0-9._-]+$/).max(80).optional().describe("Existing Transparent Commons entity target. Use exactly one of objectEntityId or objectUrl."),
|
|
42934
|
+
objectUrl: import_zod42.z.string().url().refine((value) => value.startsWith("https://"), "objectUrl must use HTTPS.").optional().describe("External or third-party target. Use exactly one of objectUrl or objectEntityId."),
|
|
42935
|
+
title: import_zod42.z.string().trim().max(500).optional(),
|
|
42936
|
+
mediaType: import_zod42.z.string().trim().max(160).optional().describe("Optional RFC link target media type."),
|
|
42937
|
+
hreflang: import_zod42.z.array(import_zod42.z.string().trim().min(1).max(80)).max(20).optional().describe("Optional repeatable RFC link target language hints."),
|
|
42938
|
+
qualifiers: import_zod42.z.record(import_zod42.z.string().max(120), import_zod42.z.union([import_zod42.z.string(), import_zod42.z.number(), import_zod42.z.boolean(), import_zod42.z.null()])).optional(),
|
|
42939
|
+
references: import_zod42.z.array(CommonsCitationInputSchema).max(50).optional().describe("Evidence supporting the relationship assertion."),
|
|
42940
|
+
rank: import_zod42.z.enum(["preferred", "normal", "deprecated"]).default("normal"),
|
|
42941
|
+
confidence: import_zod42.z.number().min(0).max(1).default(1),
|
|
42942
|
+
confidenceReason: import_zod42.z.string().trim().max(1e3).optional(),
|
|
42943
|
+
disputeState: import_zod42.z.enum(["undisputed", "attributed", "disputed", "contested", "needs_review", "deprecated"]).default("undisputed"),
|
|
42944
|
+
validFrom: import_zod42.z.string().trim().max(80).optional(),
|
|
42945
|
+
validTo: import_zod42.z.string().trim().max(80).optional(),
|
|
42946
|
+
asOf: import_zod42.z.string().trim().max(80).optional(),
|
|
42947
|
+
sourceFamily: import_zod42.z.enum(["first_party", "partner", "independent", "community", "unknown"]).default("unknown")
|
|
42948
|
+
}).strict().refine((claim) => Boolean(claim.objectEntityId) !== Boolean(claim.objectUrl), {
|
|
42949
|
+
message: "Provide exactly one of objectEntityId or objectUrl."
|
|
42950
|
+
});
|
|
42925
42951
|
CommonsPrepareEntityInputSchema = {
|
|
42926
42952
|
title: import_zod42.z.string().trim().min(1).max(180).describe("Candidate public page title. Used to derive slug, choose a profile, and search duplicate entities."),
|
|
42927
42953
|
description: import_zod42.z.string().trim().max(600).optional().describe("Optional candidate summary. Include when known so the prepare pass can route and validate the article shape."),
|
|
@@ -42961,6 +42987,7 @@ var init_mcp_tool_schemas = __esm({
|
|
|
42961
42987
|
url: import_zod42.z.string().url().optional(),
|
|
42962
42988
|
description: import_zod42.z.string().trim().max(300).optional()
|
|
42963
42989
|
}).strict()).max(200).optional().describe("Related concepts, including trails. Existing entities should use entityId."),
|
|
42990
|
+
claims: import_zod42.z.array(CommonsClaimInputSchema).max(300).optional().describe("Governed relationship assertions. Supplying claims replaces the accepted claim set for this entity; omitting claims preserves it. Only approved, active, non-disputed claims project into the RFC 9264 linkset."),
|
|
42964
42991
|
bodyMarkdown: import_zod42.z.string().max(5e5).optional().describe("Structured encyclopedia body in neutral Markdown, not a raw scrape dump or blog essay. Use H2 for entity-profile sections and H3/H4/H5 for subtopics; every heading appears in the public page menu. Call commons_prepare_entity first for the live entity profile and commons_validate_entity before submit. Profile sections are adaptive: include History, Pricing, Reception, Timeline, Classification, or similar sections only when source evidence supports them; omit unsupported sections instead of adding empty/filler headings. Apply NPOV, verifiability, and no-original-research rules; self-published sources can support only uncontroversial source-owned facts."),
|
|
42965
42992
|
contentSections: import_zod42.z.array(import_zod42.z.object({
|
|
42966
42993
|
id: import_zod42.z.string().trim().max(180).optional(),
|
|
@@ -46230,6 +46257,19 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
|
|
|
46230
46257
|
openWorldHint: false
|
|
46231
46258
|
}
|
|
46232
46259
|
}, async (input) => executor.commonsGetEntity(input));
|
|
46260
|
+
server.registerTool("commons_get_entity_linkset", {
|
|
46261
|
+
title: "Transparent Commons RFC 9264 Linkset",
|
|
46262
|
+
description: "Read the governed RFC 9264 application/linkset+json projection for one published Transparent Commons entity. The anchor is the canonical /wiki/ page; only approved, active, non-disputed claims are included, while third-party targets remain explicit HTTPS links.",
|
|
46263
|
+
inputSchema: CommonsGetEntityLinksetInputSchema,
|
|
46264
|
+
outputSchema: recordOutputSchema("commons_get_entity_linkset", CommonsGenericOutputSchema),
|
|
46265
|
+
annotations: {
|
|
46266
|
+
title: "Transparent Commons RFC 9264 Linkset",
|
|
46267
|
+
readOnlyHint: true,
|
|
46268
|
+
destructiveHint: false,
|
|
46269
|
+
idempotentHint: true,
|
|
46270
|
+
openWorldHint: false
|
|
46271
|
+
}
|
|
46272
|
+
}, async (input) => executor.commonsGetEntityLinkset(input));
|
|
46233
46273
|
server.registerTool("commons_list_needs_links", {
|
|
46234
46274
|
title: "Transparent Commons Needs-Link Backlog",
|
|
46235
46275
|
description: "List unresolved See Also concepts from published Transparent Commons pages. Use this after search/lookup when an agent needs to grow the graph: each result names a concept that appears in See Also but does not yet have a resolved Commons entityId or /wiki/ slug. This is platform Commons graph data, not personal Memory storage.",
|
|
@@ -47299,6 +47339,9 @@ var init_http_mcp_tool_executor = __esm({
|
|
|
47299
47339
|
return result;
|
|
47300
47340
|
}
|
|
47301
47341
|
}
|
|
47342
|
+
commonsGetEntityLinkset(input) {
|
|
47343
|
+
return this.getJson(`/commons/entities/${encodeURIComponent(input.idOrSlug)}/linkset?envelope=true`);
|
|
47344
|
+
}
|
|
47302
47345
|
commonsPrepareEntity(input) {
|
|
47303
47346
|
return this.call("/commons/entities/prepare", input);
|
|
47304
47347
|
}
|
|
@@ -59404,6 +59447,189 @@ var init_editorial_reading_room_routes = __esm({
|
|
|
59404
59447
|
}
|
|
59405
59448
|
});
|
|
59406
59449
|
|
|
59450
|
+
// src/api/commons-linksets.ts
|
|
59451
|
+
function normalizeCommonsClaims(input) {
|
|
59452
|
+
if (input === void 0) return void 0;
|
|
59453
|
+
if (!Array.isArray(input)) throw new Error("claims must be an array.");
|
|
59454
|
+
if (input.length > 300) throw new Error("claims must contain no more than 300 assertions.");
|
|
59455
|
+
const seen = /* @__PURE__ */ new Set();
|
|
59456
|
+
return input.map((claim, index) => {
|
|
59457
|
+
const predicate = String(claim.predicate ?? "").trim();
|
|
59458
|
+
if (!isSupportedPredicate(predicate)) {
|
|
59459
|
+
throw new Error(`claims[${index}].predicate must be a supported registered relation or an absolute HTTPS relation URI.`);
|
|
59460
|
+
}
|
|
59461
|
+
const objectEntityId = optionalText(claim.objectEntityId, 80);
|
|
59462
|
+
const objectUrl = optionalHttpsUrl(claim.objectUrl, `claims[${index}].objectUrl`);
|
|
59463
|
+
if ((objectEntityId ? 1 : 0) + (objectUrl ? 1 : 0) !== 1) {
|
|
59464
|
+
throw new Error(`claims[${index}] must provide exactly one of objectEntityId or objectUrl.`);
|
|
59465
|
+
}
|
|
59466
|
+
if (objectEntityId && !/^TPW-Q[A-Za-z0-9._-]+$/.test(objectEntityId)) {
|
|
59467
|
+
throw new Error(`claims[${index}].objectEntityId must be a Transparent Commons TPW-Q identifier.`);
|
|
59468
|
+
}
|
|
59469
|
+
const confidence = claim.confidence ?? 1;
|
|
59470
|
+
if (!Number.isFinite(confidence) || confidence < 0 || confidence > 1) {
|
|
59471
|
+
throw new Error(`claims[${index}].confidence must be between 0 and 1.`);
|
|
59472
|
+
}
|
|
59473
|
+
const key = `${predicate}\0${objectEntityId ?? objectUrl}`;
|
|
59474
|
+
if (seen.has(key)) throw new Error(`claims[${index}] duplicates another predicate and object pair.`);
|
|
59475
|
+
seen.add(key);
|
|
59476
|
+
return {
|
|
59477
|
+
predicate,
|
|
59478
|
+
predicateLabel: optionalText(claim.predicateLabel, 160),
|
|
59479
|
+
objectEntityId,
|
|
59480
|
+
objectUrl,
|
|
59481
|
+
title: optionalText(claim.title, 500),
|
|
59482
|
+
mediaType: optionalText(claim.mediaType, 160),
|
|
59483
|
+
hreflang: normalizeHreflang(claim.hreflang),
|
|
59484
|
+
qualifiers: normalizeScalarRecord(claim.qualifiers),
|
|
59485
|
+
references: normalizeReferences(claim.references),
|
|
59486
|
+
rank: claim.rank ?? "normal",
|
|
59487
|
+
confidence,
|
|
59488
|
+
confidenceReason: optionalText(claim.confidenceReason, 1e3),
|
|
59489
|
+
disputeState: claim.disputeState ?? "undisputed",
|
|
59490
|
+
validFrom: optionalDate(claim.validFrom, `claims[${index}].validFrom`),
|
|
59491
|
+
validTo: optionalDate(claim.validTo, `claims[${index}].validTo`),
|
|
59492
|
+
asOf: optionalDate(claim.asOf, `claims[${index}].asOf`),
|
|
59493
|
+
sourceFamily: claim.sourceFamily ?? "unknown"
|
|
59494
|
+
};
|
|
59495
|
+
});
|
|
59496
|
+
}
|
|
59497
|
+
function claimIsPublic(claim, now = /* @__PURE__ */ new Date()) {
|
|
59498
|
+
if (claim.reviewState !== "approved" || claim.rank === "deprecated") return false;
|
|
59499
|
+
if (!["undisputed", "attributed"].includes(claim.disputeState ?? "undisputed")) return false;
|
|
59500
|
+
const timestamp2 = now.getTime();
|
|
59501
|
+
if (claim.validFrom && Date.parse(claim.validFrom) > timestamp2) return false;
|
|
59502
|
+
if (claim.validTo && Date.parse(claim.validTo) < timestamp2) return false;
|
|
59503
|
+
return true;
|
|
59504
|
+
}
|
|
59505
|
+
function buildCommonsLinkset(entity, claims) {
|
|
59506
|
+
const publicUrl = `${commonsPublicWikiBaseUrl()}/wiki/${encodeURIComponent(entity.slug)}`;
|
|
59507
|
+
const linksetUrl = commonsLinksetUrl(entity.id);
|
|
59508
|
+
const context = { anchor: publicUrl };
|
|
59509
|
+
const publicClaims = claims.filter((claim) => claimIsPublic(claim)).sort((a, b) => a.predicate.localeCompare(b.predicate) || a.href.localeCompare(b.href) || a.id.localeCompare(b.id));
|
|
59510
|
+
for (const claim of publicClaims) {
|
|
59511
|
+
const targets = context[claim.predicate] ?? [];
|
|
59512
|
+
const target = { href: claim.href };
|
|
59513
|
+
if (claim.mediaType) target.type = claim.mediaType;
|
|
59514
|
+
if (claim.hreflang) target.hreflang = claim.hreflang;
|
|
59515
|
+
if (claim.title) target.title = claim.title;
|
|
59516
|
+
targets.push(target);
|
|
59517
|
+
context[claim.predicate] = targets;
|
|
59518
|
+
}
|
|
59519
|
+
const document2 = { linkset: [context] };
|
|
59520
|
+
const etag = `"${(0, import_node_crypto34.createHash)("sha256").update(JSON.stringify(document2)).digest("hex")}"`;
|
|
59521
|
+
return { document: document2, etag, publicUrl, linksetUrl, profile: COMMONS_RELATIONSHIP_PROFILE };
|
|
59522
|
+
}
|
|
59523
|
+
function commonsLinksetDiscoveryHeader(idOrSlug) {
|
|
59524
|
+
const url = commonsLinksetUrl(idOrSlug);
|
|
59525
|
+
return `<${url}>; rel="linkset"; type="${COMMONS_LINKSET_MEDIA_TYPE}"; profile="${COMMONS_RELATIONSHIP_PROFILE}"`;
|
|
59526
|
+
}
|
|
59527
|
+
function commonsLinksetUrl(idOrSlug) {
|
|
59528
|
+
const base = (process.env.APP_URL?.trim() || "https://mcpscraper.dev").replace(/\/+$/, "");
|
|
59529
|
+
return `${base}/commons/entities/${encodeURIComponent(idOrSlug)}/linkset`;
|
|
59530
|
+
}
|
|
59531
|
+
function commonsClaimIdentityKey(claim) {
|
|
59532
|
+
return `${claim.predicate}\0${claim.objectEntityId ?? claim.objectUrl ?? ""}`;
|
|
59533
|
+
}
|
|
59534
|
+
function commonsPublicWikiBaseUrl() {
|
|
59535
|
+
return (process.env.TRANSPARENT_COMMONS_PUBLIC_BASE_URL?.trim() || "https://transparent-commons.cc").replace(/\/+$/, "");
|
|
59536
|
+
}
|
|
59537
|
+
function isSupportedPredicate(value) {
|
|
59538
|
+
if (REGISTERED_RELATIONS.has(value)) return true;
|
|
59539
|
+
try {
|
|
59540
|
+
const url = new URL(value);
|
|
59541
|
+
return url.protocol === "https:" && Boolean(url.hostname);
|
|
59542
|
+
} catch {
|
|
59543
|
+
return false;
|
|
59544
|
+
}
|
|
59545
|
+
}
|
|
59546
|
+
function optionalText(value, max) {
|
|
59547
|
+
const text2 = String(value ?? "").trim();
|
|
59548
|
+
return text2 ? text2.slice(0, max) : void 0;
|
|
59549
|
+
}
|
|
59550
|
+
function optionalHttpsUrl(value, field) {
|
|
59551
|
+
const text2 = optionalText(value, 2e3);
|
|
59552
|
+
if (!text2) return void 0;
|
|
59553
|
+
try {
|
|
59554
|
+
const url = new URL(text2);
|
|
59555
|
+
if (url.protocol !== "https:") throw new Error();
|
|
59556
|
+
url.hash = "";
|
|
59557
|
+
return url.href;
|
|
59558
|
+
} catch {
|
|
59559
|
+
throw new Error(`${field} must be an absolute HTTPS URL.`);
|
|
59560
|
+
}
|
|
59561
|
+
}
|
|
59562
|
+
function optionalDate(value, field) {
|
|
59563
|
+
const text2 = optionalText(value, 80);
|
|
59564
|
+
if (!text2) return void 0;
|
|
59565
|
+
const timestamp2 = Date.parse(text2);
|
|
59566
|
+
if (!Number.isFinite(timestamp2)) throw new Error(`${field} must be an ISO-compatible date.`);
|
|
59567
|
+
return new Date(timestamp2).toISOString();
|
|
59568
|
+
}
|
|
59569
|
+
function normalizeScalarRecord(value) {
|
|
59570
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
59571
|
+
return Object.fromEntries(Object.entries(value).slice(0, 50).map(([key, item]) => [key.slice(0, 120), item]));
|
|
59572
|
+
}
|
|
59573
|
+
function normalizeReferences(value) {
|
|
59574
|
+
if (!Array.isArray(value)) return void 0;
|
|
59575
|
+
return value.slice(0, 50).map((reference) => ({
|
|
59576
|
+
title: String(reference.title ?? "").trim().slice(0, 240),
|
|
59577
|
+
url: optionalHttpsUrl(reference.url, "claim reference URL"),
|
|
59578
|
+
source: optionalText(reference.source, 240),
|
|
59579
|
+
note: optionalText(reference.note, 1e3),
|
|
59580
|
+
accessedAt: optionalDate(reference.accessedAt, "claim reference accessedAt")
|
|
59581
|
+
})).filter((reference) => reference.title);
|
|
59582
|
+
}
|
|
59583
|
+
function normalizeHreflang(value) {
|
|
59584
|
+
if (!Array.isArray(value)) return void 0;
|
|
59585
|
+
const languages = [...new Set(value.map((item) => optionalText(item, 80)).filter((item) => Boolean(item)))];
|
|
59586
|
+
return languages.length ? languages : void 0;
|
|
59587
|
+
}
|
|
59588
|
+
var import_node_crypto34, COMMONS_LINKSET_MEDIA_TYPE, COMMONS_RELATIONSHIP_PROFILE, REGISTERED_RELATIONS;
|
|
59589
|
+
var init_commons_linksets = __esm({
|
|
59590
|
+
"src/api/commons-linksets.ts"() {
|
|
59591
|
+
"use strict";
|
|
59592
|
+
import_node_crypto34 = require("crypto");
|
|
59593
|
+
COMMONS_LINKSET_MEDIA_TYPE = "application/linkset+json";
|
|
59594
|
+
COMMONS_RELATIONSHIP_PROFILE = "https://mcpscraper.dev/commons/profiles/relationships/v1";
|
|
59595
|
+
REGISTERED_RELATIONS = /* @__PURE__ */ new Set([
|
|
59596
|
+
"about",
|
|
59597
|
+
"alternate",
|
|
59598
|
+
"author",
|
|
59599
|
+
"canonical",
|
|
59600
|
+
"cite-as",
|
|
59601
|
+
"collection",
|
|
59602
|
+
"contents",
|
|
59603
|
+
"copyright",
|
|
59604
|
+
"describedby",
|
|
59605
|
+
"describes",
|
|
59606
|
+
"first",
|
|
59607
|
+
"glossary",
|
|
59608
|
+
"help",
|
|
59609
|
+
"icon",
|
|
59610
|
+
"index",
|
|
59611
|
+
"item",
|
|
59612
|
+
"last",
|
|
59613
|
+
"latest-version",
|
|
59614
|
+
"license",
|
|
59615
|
+
"memento",
|
|
59616
|
+
"next",
|
|
59617
|
+
"original",
|
|
59618
|
+
"predecessor-version",
|
|
59619
|
+
"prev",
|
|
59620
|
+
"related",
|
|
59621
|
+
"replies",
|
|
59622
|
+
"service-desc",
|
|
59623
|
+
"service-doc",
|
|
59624
|
+
"successor-version",
|
|
59625
|
+
"terms-of-service",
|
|
59626
|
+
"type",
|
|
59627
|
+
"via",
|
|
59628
|
+
"version-history"
|
|
59629
|
+
]);
|
|
59630
|
+
}
|
|
59631
|
+
});
|
|
59632
|
+
|
|
59407
59633
|
// src/api/commons-repository.ts
|
|
59408
59634
|
async function ensureCommonsSchema() {
|
|
59409
59635
|
if (schemaReady2) return;
|
|
@@ -59453,6 +59679,42 @@ async function ensureCommonsSchema() {
|
|
|
59453
59679
|
{ sql: `CREATE INDEX IF NOT EXISTS commons_entities_status_updated ON commons_entities(status, updated_at DESC)`, args: [] },
|
|
59454
59680
|
{ sql: `CREATE INDEX IF NOT EXISTS commons_entities_type_updated ON commons_entities(entity_type, updated_at DESC)`, args: [] },
|
|
59455
59681
|
{ sql: `CREATE INDEX IF NOT EXISTS commons_entities_source_domain ON commons_entities(source_json)`, args: [] },
|
|
59682
|
+
{
|
|
59683
|
+
sql: `
|
|
59684
|
+
CREATE TABLE IF NOT EXISTS commons_claims (
|
|
59685
|
+
id TEXT PRIMARY KEY,
|
|
59686
|
+
subject_entity_id TEXT NOT NULL REFERENCES commons_entities(id),
|
|
59687
|
+
predicate TEXT NOT NULL,
|
|
59688
|
+
predicate_label TEXT,
|
|
59689
|
+
object_entity_id TEXT,
|
|
59690
|
+
object_url TEXT,
|
|
59691
|
+
title TEXT,
|
|
59692
|
+
media_type TEXT,
|
|
59693
|
+
hreflang TEXT,
|
|
59694
|
+
qualifiers_json TEXT NOT NULL DEFAULT '{}',
|
|
59695
|
+
references_json TEXT NOT NULL DEFAULT '[]',
|
|
59696
|
+
rank TEXT NOT NULL DEFAULT 'normal',
|
|
59697
|
+
confidence REAL NOT NULL DEFAULT 1,
|
|
59698
|
+
confidence_reason TEXT,
|
|
59699
|
+
dispute_state TEXT NOT NULL DEFAULT 'undisputed',
|
|
59700
|
+
valid_from TEXT,
|
|
59701
|
+
valid_to TEXT,
|
|
59702
|
+
as_of TEXT,
|
|
59703
|
+
source_family TEXT NOT NULL DEFAULT 'unknown',
|
|
59704
|
+
review_state TEXT NOT NULL DEFAULT 'approved',
|
|
59705
|
+
proposal_id TEXT NOT NULL REFERENCES commons_proposals(id),
|
|
59706
|
+
created_by_user_id INTEGER,
|
|
59707
|
+
updated_by_user_id INTEGER,
|
|
59708
|
+
created_at TEXT NOT NULL,
|
|
59709
|
+
updated_at TEXT NOT NULL,
|
|
59710
|
+
CHECK ((object_entity_id IS NOT NULL) != (object_url IS NOT NULL)),
|
|
59711
|
+
UNIQUE(subject_entity_id, predicate, object_entity_id, object_url)
|
|
59712
|
+
)
|
|
59713
|
+
`,
|
|
59714
|
+
args: []
|
|
59715
|
+
},
|
|
59716
|
+
{ sql: `CREATE INDEX IF NOT EXISTS commons_claims_subject_predicate ON commons_claims(subject_entity_id, predicate)`, args: [] },
|
|
59717
|
+
{ sql: `CREATE INDEX IF NOT EXISTS commons_claims_object_entity ON commons_claims(object_entity_id)`, args: [] },
|
|
59456
59718
|
{
|
|
59457
59719
|
sql: `
|
|
59458
59720
|
CREATE TABLE IF NOT EXISTS commons_proposals (
|
|
@@ -59613,8 +59875,15 @@ async function searchCommonsEntities(filters = {}, userId) {
|
|
|
59613
59875
|
args.push(jsonLikeValue(keyword));
|
|
59614
59876
|
}
|
|
59615
59877
|
if (mergedFilters.relatedEntityId) {
|
|
59616
|
-
clauses.push(
|
|
59617
|
-
|
|
59878
|
+
clauses.push(`(
|
|
59879
|
+
related_entities_json LIKE ?
|
|
59880
|
+
OR EXISTS (
|
|
59881
|
+
SELECT 1 FROM commons_claims
|
|
59882
|
+
WHERE commons_claims.subject_entity_id = commons_entities.id
|
|
59883
|
+
AND commons_claims.object_entity_id = ?
|
|
59884
|
+
)
|
|
59885
|
+
)`);
|
|
59886
|
+
args.push(jsonLikeValue(mergedFilters.relatedEntityId), mergedFilters.relatedEntityId);
|
|
59618
59887
|
}
|
|
59619
59888
|
if (mergedFilters.trailId) {
|
|
59620
59889
|
clauses.push("related_entities_json LIKE ?");
|
|
@@ -59636,8 +59905,16 @@ async function searchCommonsEntities(filters = {}, userId) {
|
|
|
59636
59905
|
}
|
|
59637
59906
|
const terms = tokenize(mergedFilters.query);
|
|
59638
59907
|
for (const term of terms) {
|
|
59639
|
-
clauses.push(
|
|
59640
|
-
|
|
59908
|
+
clauses.push(`(
|
|
59909
|
+
search_text LIKE ?
|
|
59910
|
+
OR EXISTS (
|
|
59911
|
+
SELECT 1 FROM commons_claims
|
|
59912
|
+
WHERE commons_claims.subject_entity_id = commons_entities.id
|
|
59913
|
+
AND (commons_claims.predicate LIKE ? OR commons_claims.predicate_label LIKE ? OR commons_claims.title LIKE ? OR commons_claims.object_url LIKE ?)
|
|
59914
|
+
)
|
|
59915
|
+
)`);
|
|
59916
|
+
const pattern = `%${escapeLike(term)}%`;
|
|
59917
|
+
args.push(pattern, pattern, pattern, pattern, pattern);
|
|
59641
59918
|
}
|
|
59642
59919
|
args.push(limit, offset);
|
|
59643
59920
|
const result = await getDb().execute({
|
|
@@ -59659,9 +59936,9 @@ async function searchCommonsEntities(filters = {}, userId) {
|
|
|
59659
59936
|
}
|
|
59660
59937
|
async function prepareCommonsEntity(input, user) {
|
|
59661
59938
|
await ensureCommonsSchema();
|
|
59662
|
-
const title =
|
|
59939
|
+
const title = optionalText2(input.title, 180) ?? "";
|
|
59663
59940
|
const slug2 = normalizeSlug(input.slug || title);
|
|
59664
|
-
const schemaOrgType =
|
|
59941
|
+
const schemaOrgType = optionalText2(input.schemaOrgType, 80);
|
|
59665
59942
|
const contract = commonsEntityProfileFor(input.entityType, schemaOrgType);
|
|
59666
59943
|
const entityType = contract.entityType;
|
|
59667
59944
|
const bodyMarkdown = safeCandidateBody(input.bodyMarkdown, input.contentSections);
|
|
@@ -59719,8 +59996,8 @@ async function validateCommonsEntity(input, user) {
|
|
|
59719
59996
|
await ensureCommonsSchema();
|
|
59720
59997
|
const errors = [];
|
|
59721
59998
|
const warnings = [];
|
|
59722
|
-
const title =
|
|
59723
|
-
const description =
|
|
59999
|
+
const title = optionalText2(input.title, 180);
|
|
60000
|
+
const description = optionalText2(input.description, 600);
|
|
59724
60001
|
const slug2 = normalizeSlug(input.slug || title || "");
|
|
59725
60002
|
const contract = commonsEntityProfileFor(input.entityType, input.seo?.schemaOrgType);
|
|
59726
60003
|
const source = normalizeSource(input.source);
|
|
@@ -59735,6 +60012,11 @@ async function validateCommonsEntity(input, user) {
|
|
|
59735
60012
|
maxCandidates: 8
|
|
59736
60013
|
});
|
|
59737
60014
|
const existing = slug2 || input.entityId ? await findEntityBySlugOrIdAnyStatus(slug2, input.entityId) : null;
|
|
60015
|
+
try {
|
|
60016
|
+
normalizeCommonsClaims(input.claims);
|
|
60017
|
+
} catch (error) {
|
|
60018
|
+
errors.push(error instanceof Error ? error.message : "Claims are invalid.");
|
|
60019
|
+
}
|
|
59738
60020
|
if (!title || title.length < 3) errors.push("title must be at least 3 characters.");
|
|
59739
60021
|
if (!description || description.length < 8) errors.push("description must be at least 8 characters.");
|
|
59740
60022
|
if (!slug2) errors.push("A Commons entity needs a URL slug.");
|
|
@@ -59824,9 +60106,10 @@ async function submitCommonsEntity(input, user) {
|
|
|
59824
60106
|
};
|
|
59825
60107
|
}
|
|
59826
60108
|
const existing = await findEntityBySlugOrIdAnyStatus(normalized.slug, normalized.entityId);
|
|
60109
|
+
const existingClaims = existing && normalized.claims !== void 0 ? await getCommonsClaimsByEntityId(existing.id) : [];
|
|
59827
60110
|
const safety = evaluatePublishSafety(normalized, existing);
|
|
59828
60111
|
const shouldApply = safety.safe && normalized.reviewPolicy !== "always_review";
|
|
59829
|
-
const proposalId = `commons-proposal-${(0,
|
|
60112
|
+
const proposalId = `commons-proposal-${(0, import_node_crypto35.randomUUID)()}`;
|
|
59830
60113
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
59831
60114
|
const entityId = existing?.id ?? normalized.entityId ?? allocateEntityId();
|
|
59832
60115
|
const proposalStatus = shouldApply ? "accepted" : "pending_review";
|
|
@@ -59868,6 +60151,10 @@ async function submitCommonsEntity(input, user) {
|
|
|
59868
60151
|
];
|
|
59869
60152
|
if (nextEntity) {
|
|
59870
60153
|
batch.push(entityUpsertStatement(nextEntity, existing));
|
|
60154
|
+
if (normalized.claims !== void 0) {
|
|
60155
|
+
batch.push({ sql: "DELETE FROM commons_claims WHERE subject_entity_id = ?", args: [nextEntity.id] });
|
|
60156
|
+
batch.push(...claimInsertStatements(normalized.claims, existingClaims, nextEntity.id, proposalId, Number(user.id), now));
|
|
60157
|
+
}
|
|
59871
60158
|
batch.push(...commonsIndexStatements(nextEntity, now));
|
|
59872
60159
|
batch.push({
|
|
59873
60160
|
sql: `
|
|
@@ -59877,17 +60164,26 @@ async function submitCommonsEntity(input, user) {
|
|
|
59877
60164
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
59878
60165
|
`,
|
|
59879
60166
|
args: [
|
|
59880
|
-
`commons-ledger-${(0,
|
|
60167
|
+
`commons-ledger-${(0, import_node_crypto35.randomUUID)()}`,
|
|
59881
60168
|
nextEntity.id,
|
|
59882
60169
|
proposalId,
|
|
59883
60170
|
user.id,
|
|
59884
60171
|
actorLabel(input, user),
|
|
59885
60172
|
normalized.actorChannel,
|
|
59886
60173
|
existing ? "entity_updated" : "entity_created",
|
|
59887
|
-
JSON.stringify(
|
|
60174
|
+
JSON.stringify([
|
|
60175
|
+
...changedFieldPaths(existing, nextEntity),
|
|
60176
|
+
...normalized.claims !== void 0 ? ["claims"] : []
|
|
60177
|
+
]),
|
|
59888
60178
|
normalized.changeSummary || (existing ? "Updated Commons entity." : "Created Commons entity."),
|
|
59889
|
-
existing ? JSON.stringify(
|
|
59890
|
-
|
|
60179
|
+
existing ? JSON.stringify({
|
|
60180
|
+
...entityLedgerSnapshot(existing),
|
|
60181
|
+
...normalized.claims !== void 0 ? { claims: existingClaims } : {}
|
|
60182
|
+
}) : null,
|
|
60183
|
+
JSON.stringify({
|
|
60184
|
+
...entityLedgerSnapshot(nextEntity),
|
|
60185
|
+
...normalized.claims !== void 0 ? { claims: normalized.claims } : {}
|
|
60186
|
+
}),
|
|
59891
60187
|
now
|
|
59892
60188
|
]
|
|
59893
60189
|
});
|
|
@@ -59938,17 +60234,41 @@ async function getCommonsEntityLedger(idOrSlug) {
|
|
|
59938
60234
|
ledger: result.rows.map((row) => rowToLedgerEntry(row))
|
|
59939
60235
|
};
|
|
59940
60236
|
}
|
|
60237
|
+
async function listCommonsClaims(idOrSlug) {
|
|
60238
|
+
await ensureCommonsSchema();
|
|
60239
|
+
const entity = await getCommonsEntity(idOrSlug);
|
|
60240
|
+
if (!entity) return null;
|
|
60241
|
+
return { entity, claims: await getCommonsClaimsByEntityId(entity.id) };
|
|
60242
|
+
}
|
|
60243
|
+
async function getCommonsEntityLinkset(idOrSlug) {
|
|
60244
|
+
const result = await listCommonsClaims(idOrSlug);
|
|
60245
|
+
if (!result) return null;
|
|
60246
|
+
const targetIds = [...new Set(result.claims.map((claim) => claim.objectEntityId).filter((id) => Boolean(id)))];
|
|
60247
|
+
const targetSlugs = /* @__PURE__ */ new Map();
|
|
60248
|
+
if (targetIds.length) {
|
|
60249
|
+
const targets = await getDb().execute({
|
|
60250
|
+
sql: `SELECT id, slug FROM commons_entities WHERE status = 'published' AND id IN (${targetIds.map(() => "?").join(", ")})`,
|
|
60251
|
+
args: targetIds
|
|
60252
|
+
});
|
|
60253
|
+
for (const row of targets.rows) targetSlugs.set(String(row.id), String(row.slug));
|
|
60254
|
+
}
|
|
60255
|
+
const resolved = result.claims.map((claim) => {
|
|
60256
|
+
const href = claim.objectUrl ?? (claim.objectEntityId && targetSlugs.has(claim.objectEntityId) ? publicUrlForSlug(targetSlugs.get(claim.objectEntityId)) : null);
|
|
60257
|
+
return href ? { ...claim, href } : null;
|
|
60258
|
+
}).filter((claim) => claim !== null);
|
|
60259
|
+
return { entity: result.entity, claims: result.claims, ...buildCommonsLinkset(result.entity, resolved) };
|
|
60260
|
+
}
|
|
59941
60261
|
async function saveCommonsFilter(input, user) {
|
|
59942
60262
|
await ensureCommonsSchema();
|
|
59943
60263
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
59944
60264
|
const name = requiredText(input.name, "name", 2, 80);
|
|
59945
|
-
const description =
|
|
60265
|
+
const description = optionalText2(input.description, 500);
|
|
59946
60266
|
const filter = sanitizeSearchFilters(input.filter);
|
|
59947
60267
|
const existing = await getDb().execute({
|
|
59948
60268
|
sql: "SELECT id FROM commons_saved_filters WHERE user_id = ? AND name = ? LIMIT 1",
|
|
59949
60269
|
args: [user.id, name]
|
|
59950
60270
|
});
|
|
59951
|
-
const id = existing.rows[0]?.id != null ? String(existing.rows[0].id) : `commons-filter-${(0,
|
|
60271
|
+
const id = existing.rows[0]?.id != null ? String(existing.rows[0].id) : `commons-filter-${(0, import_node_crypto35.randomUUID)()}`;
|
|
59952
60272
|
await getDb().execute({
|
|
59953
60273
|
sql: `
|
|
59954
60274
|
INSERT INTO commons_saved_filters (id, user_id, name, description, filter_json, created_at, updated_at)
|
|
@@ -60075,9 +60395,9 @@ function commonsDatabaseReport() {
|
|
|
60075
60395
|
conflictBehavior: "Existing entity edits require baseRevision. Otherwise the proposal is pending_review.",
|
|
60076
60396
|
billing: { validationCredits: 0, createCredits: LISTING_WRITE_RATE_POLICY.create.credits, editCredits: LISTING_WRITE_RATE_POLICY.edit.credits }
|
|
60077
60397
|
},
|
|
60078
|
-
searchCorpus: ["title", "disambiguationName", "description", "tags", "keywords", "relatedEntities", "bodyMarkdown", "sections", "media", "source metadata", "jsonLd"],
|
|
60398
|
+
searchCorpus: ["title", "disambiguationName", "description", "tags", "keywords", "relatedEntities", "relationship claims", "bodyMarkdown", "sections", "media", "source metadata", "jsonLd"],
|
|
60079
60399
|
indexing: commonsIndexingPolicy(),
|
|
60080
|
-
tables: ["commons_entities", "commons_proposals", "commons_ledger", "commons_saved_filters", "commons_index_documents"]
|
|
60400
|
+
tables: ["commons_entities", "commons_claims", "commons_proposals", "commons_ledger", "commons_saved_filters", "commons_index_documents"]
|
|
60081
60401
|
};
|
|
60082
60402
|
}
|
|
60083
60403
|
function entityToWikiPage(entity) {
|
|
@@ -60097,6 +60417,13 @@ function entityToWikiPage(entity) {
|
|
|
60097
60417
|
media: entity.media,
|
|
60098
60418
|
sections: entity.articleSections,
|
|
60099
60419
|
metadata: {
|
|
60420
|
+
linksetUrl: commonsLinksetUrl(entity.id),
|
|
60421
|
+
linksetDiscovery: {
|
|
60422
|
+
rel: "linkset",
|
|
60423
|
+
type: COMMONS_LINKSET_MEDIA_TYPE,
|
|
60424
|
+
profile: COMMONS_RELATIONSHIP_PROFILE,
|
|
60425
|
+
href: commonsLinksetUrl(entity.id)
|
|
60426
|
+
},
|
|
60100
60427
|
entityType: friendlyEntityType(entity.entityType),
|
|
60101
60428
|
disambiguationName: entity.disambiguationName,
|
|
60102
60429
|
keywords: entity.keywords,
|
|
@@ -60253,7 +60580,7 @@ async function commonsTagVocabulary() {
|
|
|
60253
60580
|
...parseJson3(record.tags_json, []),
|
|
60254
60581
|
...parseJson3(record.keywords_json, [])
|
|
60255
60582
|
]) {
|
|
60256
|
-
const cleaned =
|
|
60583
|
+
const cleaned = optionalText2(tag, 120);
|
|
60257
60584
|
if (!cleaned) continue;
|
|
60258
60585
|
counts.set(cleaned, (counts.get(cleaned) ?? 0) + 1);
|
|
60259
60586
|
}
|
|
@@ -60263,7 +60590,7 @@ async function commonsTagVocabulary() {
|
|
|
60263
60590
|
function resolveCommonsTags(candidates, vocabulary) {
|
|
60264
60591
|
const vocabularyByKey = new Map(vocabulary.map((entry) => [entry.tag.toLowerCase(), entry]));
|
|
60265
60592
|
return candidates.map((candidate) => {
|
|
60266
|
-
const cleaned =
|
|
60593
|
+
const cleaned = optionalText2(candidate, 120) ?? "";
|
|
60267
60594
|
const key = cleaned.toLowerCase();
|
|
60268
60595
|
const exact = vocabularyByKey.get(key);
|
|
60269
60596
|
if (!cleaned || cleaned.length < 2) {
|
|
@@ -60360,12 +60687,13 @@ function normalizeSubmitInput(input) {
|
|
|
60360
60687
|
slug: slug2,
|
|
60361
60688
|
entityId: normalizeEntityId(input.entityId),
|
|
60362
60689
|
entityType: normalizeEntityType(input.entityType),
|
|
60363
|
-
disambiguationName:
|
|
60690
|
+
disambiguationName: optionalText2(input.disambiguationName, 240) ?? void 0,
|
|
60364
60691
|
featuredImage: normalizeFeaturedImage(input.featuredImage),
|
|
60365
60692
|
source: normalizeSource(input.source),
|
|
60366
60693
|
tags: uniqueStrings(input.tags ?? []).slice(0, 24),
|
|
60367
60694
|
keywords: uniqueStrings(input.keywords ?? []).slice(0, 50),
|
|
60368
60695
|
relatedEntities: normalizeRelatedEntities(input.relatedEntities),
|
|
60696
|
+
claims: normalizeClaimsForRepository(input.claims),
|
|
60369
60697
|
bodyMarkdown: normalizeBody(input.bodyMarkdown, input.contentSections),
|
|
60370
60698
|
contentSections: normalizeContentSections(input.contentSections),
|
|
60371
60699
|
articleSections: normalizeArticleSections(input.articleSections),
|
|
@@ -60374,11 +60702,18 @@ function normalizeSubmitInput(input) {
|
|
|
60374
60702
|
seo: normalizeSeo(input.seo),
|
|
60375
60703
|
actorChannel: input.actorChannel ?? "mcp",
|
|
60376
60704
|
actorLabel: input.actorLabel ?? "",
|
|
60377
|
-
changeSummary:
|
|
60705
|
+
changeSummary: optionalText2(input.changeSummary, 500) ?? "",
|
|
60378
60706
|
reviewPolicy: input.reviewPolicy ?? "auto_publish_if_safe",
|
|
60379
60707
|
baseRevision: input.baseRevision
|
|
60380
60708
|
};
|
|
60381
60709
|
}
|
|
60710
|
+
function normalizeClaimsForRepository(input) {
|
|
60711
|
+
try {
|
|
60712
|
+
return normalizeCommonsClaims(input);
|
|
60713
|
+
} catch (error) {
|
|
60714
|
+
throw new CommonsRepositoryError("invalid_claims", error instanceof Error ? error.message : "Claims are invalid.");
|
|
60715
|
+
}
|
|
60716
|
+
}
|
|
60382
60717
|
function evaluatePublishSafety(input, existing) {
|
|
60383
60718
|
if (!input.featuredImage?.url) return { safe: false, reason: "A featured image is required before a Commons entity can publish." };
|
|
60384
60719
|
if (!input.bodyMarkdown.trim() && !input.source.originalUrl && !input.source.resolvedUrl) {
|
|
@@ -60524,6 +60859,84 @@ function entityStorageValues(entity) {
|
|
|
60524
60859
|
entity.revision
|
|
60525
60860
|
];
|
|
60526
60861
|
}
|
|
60862
|
+
function claimInsertStatements(claims, existingClaims, subjectEntityId, proposalId, userId, now) {
|
|
60863
|
+
const existingByIdentity = new Map(existingClaims.map((claim) => [commonsClaimIdentityKey(claim), claim]));
|
|
60864
|
+
return claims.map((claim) => {
|
|
60865
|
+
const existing = existingByIdentity.get(commonsClaimIdentityKey(claim));
|
|
60866
|
+
return {
|
|
60867
|
+
sql: `
|
|
60868
|
+
INSERT INTO commons_claims (
|
|
60869
|
+
id, subject_entity_id, predicate, predicate_label, object_entity_id, object_url,
|
|
60870
|
+
title, media_type, hreflang, qualifiers_json, references_json, rank, confidence,
|
|
60871
|
+
confidence_reason, dispute_state, valid_from, valid_to, as_of, source_family,
|
|
60872
|
+
review_state, proposal_id, created_by_user_id, updated_by_user_id, created_at, updated_at
|
|
60873
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'approved', ?, ?, ?, ?, ?)
|
|
60874
|
+
`,
|
|
60875
|
+
args: [
|
|
60876
|
+
existing?.id ?? allocateClaimId(),
|
|
60877
|
+
subjectEntityId,
|
|
60878
|
+
claim.predicate,
|
|
60879
|
+
claim.predicateLabel ?? null,
|
|
60880
|
+
claim.objectEntityId ?? null,
|
|
60881
|
+
claim.objectUrl ?? null,
|
|
60882
|
+
claim.title ?? null,
|
|
60883
|
+
claim.mediaType ?? null,
|
|
60884
|
+
claim.hreflang ? JSON.stringify(claim.hreflang) : null,
|
|
60885
|
+
JSON.stringify(claim.qualifiers ?? {}),
|
|
60886
|
+
JSON.stringify(claim.references ?? []),
|
|
60887
|
+
claim.rank ?? "normal",
|
|
60888
|
+
claim.confidence ?? 1,
|
|
60889
|
+
claim.confidenceReason ?? null,
|
|
60890
|
+
claim.disputeState ?? "undisputed",
|
|
60891
|
+
claim.validFrom ?? null,
|
|
60892
|
+
claim.validTo ?? null,
|
|
60893
|
+
claim.asOf ?? null,
|
|
60894
|
+
claim.sourceFamily ?? "unknown",
|
|
60895
|
+
proposalId,
|
|
60896
|
+
existing?.createdByUserId ?? userId,
|
|
60897
|
+
userId,
|
|
60898
|
+
existing?.createdAt ?? now,
|
|
60899
|
+
now
|
|
60900
|
+
]
|
|
60901
|
+
};
|
|
60902
|
+
});
|
|
60903
|
+
}
|
|
60904
|
+
async function getCommonsClaimsByEntityId(entityId) {
|
|
60905
|
+
const result = await getDb().execute({
|
|
60906
|
+
sql: "SELECT * FROM commons_claims WHERE subject_entity_id = ? ORDER BY predicate ASC, object_url ASC, object_entity_id ASC, id ASC",
|
|
60907
|
+
args: [entityId]
|
|
60908
|
+
});
|
|
60909
|
+
return result.rows.map((row) => rowToClaim(row));
|
|
60910
|
+
}
|
|
60911
|
+
function rowToClaim(row) {
|
|
60912
|
+
return {
|
|
60913
|
+
id: String(row.id),
|
|
60914
|
+
subjectEntityId: String(row.subject_entity_id),
|
|
60915
|
+
predicate: String(row.predicate),
|
|
60916
|
+
predicateLabel: row.predicate_label == null ? void 0 : String(row.predicate_label),
|
|
60917
|
+
objectEntityId: row.object_entity_id == null ? void 0 : String(row.object_entity_id),
|
|
60918
|
+
objectUrl: row.object_url == null ? void 0 : String(row.object_url),
|
|
60919
|
+
title: row.title == null ? void 0 : String(row.title),
|
|
60920
|
+
mediaType: row.media_type == null ? void 0 : String(row.media_type),
|
|
60921
|
+
hreflang: row.hreflang == null ? void 0 : parseJson3(row.hreflang, []),
|
|
60922
|
+
qualifiers: parseJson3(row.qualifiers_json, {}),
|
|
60923
|
+
references: parseJson3(row.references_json, []),
|
|
60924
|
+
rank: String(row.rank),
|
|
60925
|
+
confidence: Number(row.confidence),
|
|
60926
|
+
confidenceReason: row.confidence_reason == null ? void 0 : String(row.confidence_reason),
|
|
60927
|
+
disputeState: String(row.dispute_state),
|
|
60928
|
+
validFrom: row.valid_from == null ? void 0 : String(row.valid_from),
|
|
60929
|
+
validTo: row.valid_to == null ? void 0 : String(row.valid_to),
|
|
60930
|
+
asOf: row.as_of == null ? void 0 : String(row.as_of),
|
|
60931
|
+
sourceFamily: String(row.source_family),
|
|
60932
|
+
reviewState: String(row.review_state),
|
|
60933
|
+
proposalId: String(row.proposal_id),
|
|
60934
|
+
createdByUserId: row.created_by_user_id == null ? null : Number(row.created_by_user_id),
|
|
60935
|
+
updatedByUserId: row.updated_by_user_id == null ? null : Number(row.updated_by_user_id),
|
|
60936
|
+
createdAt: String(row.created_at),
|
|
60937
|
+
updatedAt: String(row.updated_at)
|
|
60938
|
+
};
|
|
60939
|
+
}
|
|
60527
60940
|
function commonsIndexStatements(entity, now) {
|
|
60528
60941
|
return commonsIndexDocuments(entity, now).map((document2) => ({
|
|
60529
60942
|
sql: `
|
|
@@ -60628,7 +61041,7 @@ function commonsIndexDocuments(entity, now) {
|
|
|
60628
61041
|
return documents;
|
|
60629
61042
|
}
|
|
60630
61043
|
function commonsIndexDocumentId(entityId, documentType, documentKey) {
|
|
60631
|
-
return `commons-index-${(0,
|
|
61044
|
+
return `commons-index-${(0, import_node_crypto35.createHash)("sha256").update(`${entityId}
|
|
60632
61045
|
${documentType}
|
|
60633
61046
|
${documentKey}`).digest("hex").slice(0, 32)}`;
|
|
60634
61047
|
}
|
|
@@ -60803,14 +61216,14 @@ function normalizeArticleSections(sections) {
|
|
|
60803
61216
|
return {
|
|
60804
61217
|
relatedLinks: normalizeRelatedLinks(sections?.relatedLinks),
|
|
60805
61218
|
notes: Array.isArray(sections?.notes) ? sections.notes.map((note) => ({
|
|
60806
|
-
marker:
|
|
61219
|
+
marker: optionalText2(note.marker, 20) ?? void 0,
|
|
60807
61220
|
body: requiredText(note.body, "notes.body", 1, 2e3)
|
|
60808
61221
|
})).slice(0, 100) : [],
|
|
60809
61222
|
citations: normalizeCitations(sections?.citations),
|
|
60810
61223
|
externalLinks: Array.isArray(sections?.externalLinks) ? sections.externalLinks.map((link2) => ({
|
|
60811
61224
|
title: requiredText(link2.title, "externalLinks.title", 1, 180),
|
|
60812
61225
|
url: requiredText(link2.url, "externalLinks.url", 1, 2e3),
|
|
60813
|
-
summary:
|
|
61226
|
+
summary: optionalText2(link2.summary, 300) ?? void 0
|
|
60814
61227
|
})).slice(0, 100) : [],
|
|
60815
61228
|
categories: uniqueStrings(sections?.categories ?? []).slice(0, 50)
|
|
60816
61229
|
};
|
|
@@ -60819,7 +61232,7 @@ function normalizeRelatedLinks(relatedLinks) {
|
|
|
60819
61232
|
if (!Array.isArray(relatedLinks)) return [];
|
|
60820
61233
|
return relatedLinks.map((link2) => {
|
|
60821
61234
|
const title = requiredText(link2.title, "relatedLinks.title", 1, 180);
|
|
60822
|
-
const url =
|
|
61235
|
+
const url = optionalText2(link2.url, 2e3);
|
|
60823
61236
|
const slug2 = link2.slug ? normalizeSlug(link2.slug) : void 0;
|
|
60824
61237
|
const entityId = normalizeEntityId(link2.entityId);
|
|
60825
61238
|
const needsLink = link2.needsLink === true || !url && !slug2 && !entityId;
|
|
@@ -60828,9 +61241,9 @@ function normalizeRelatedLinks(relatedLinks) {
|
|
|
60828
61241
|
url,
|
|
60829
61242
|
slug: slug2,
|
|
60830
61243
|
entityId,
|
|
60831
|
-
relationship:
|
|
60832
|
-
summary:
|
|
60833
|
-
imageUrl:
|
|
61244
|
+
relationship: optionalText2(link2.relationship, 120) ?? void 0,
|
|
61245
|
+
summary: optionalText2(link2.summary, 300) ?? void 0,
|
|
61246
|
+
imageUrl: optionalText2(link2.imageUrl, 2e3) ?? void 0,
|
|
60834
61247
|
needsLink
|
|
60835
61248
|
};
|
|
60836
61249
|
}).slice(0, 100);
|
|
@@ -60839,20 +61252,20 @@ function normalizeCitations(citations) {
|
|
|
60839
61252
|
if (!Array.isArray(citations)) return [];
|
|
60840
61253
|
return citations.map((citation) => ({
|
|
60841
61254
|
title: requiredText(citation.title, "citation.title", 1, 240),
|
|
60842
|
-
url:
|
|
60843
|
-
source:
|
|
60844
|
-
note:
|
|
60845
|
-
accessedAt:
|
|
61255
|
+
url: optionalText2(citation.url, 2e3) ?? void 0,
|
|
61256
|
+
source: optionalText2(citation.source, 240) ?? void 0,
|
|
61257
|
+
note: optionalText2(citation.note, 1e3) ?? void 0,
|
|
61258
|
+
accessedAt: optionalText2(citation.accessedAt, 80) ?? void 0
|
|
60846
61259
|
})).slice(0, 300);
|
|
60847
61260
|
}
|
|
60848
61261
|
function normalizeFeaturedImage(image) {
|
|
60849
61262
|
if (!image?.url) return void 0;
|
|
60850
61263
|
return {
|
|
60851
61264
|
url: requiredText(image.url, "featuredImage.url", 1, 2e3),
|
|
60852
|
-
alt:
|
|
60853
|
-
caption:
|
|
60854
|
-
sourceUrl:
|
|
60855
|
-
license:
|
|
61265
|
+
alt: optionalText2(image.alt, 500) ?? void 0,
|
|
61266
|
+
caption: optionalText2(image.caption, 1e3) ?? void 0,
|
|
61267
|
+
sourceUrl: optionalText2(image.sourceUrl, 2e3) ?? void 0,
|
|
61268
|
+
license: optionalText2(image.license, 240) ?? void 0,
|
|
60856
61269
|
width: positiveInt(image.width),
|
|
60857
61270
|
height: positiveInt(image.height)
|
|
60858
61271
|
};
|
|
@@ -60861,11 +61274,11 @@ function normalizeMedia(media, featuredImage) {
|
|
|
60861
61274
|
const normalized = Array.isArray(media) ? media.map((item) => ({
|
|
60862
61275
|
type: item.type,
|
|
60863
61276
|
url: requiredText(item.url, "media.url", 1, 2e3),
|
|
60864
|
-
alt:
|
|
60865
|
-
caption:
|
|
60866
|
-
posterUrl:
|
|
60867
|
-
sourceUrl:
|
|
60868
|
-
license:
|
|
61277
|
+
alt: optionalText2(item.alt, 500) ?? void 0,
|
|
61278
|
+
caption: optionalText2(item.caption, 1e3) ?? void 0,
|
|
61279
|
+
posterUrl: optionalText2(item.posterUrl, 2e3) ?? void 0,
|
|
61280
|
+
sourceUrl: optionalText2(item.sourceUrl, 2e3) ?? void 0,
|
|
61281
|
+
license: optionalText2(item.license, 240) ?? void 0,
|
|
60869
61282
|
width: positiveInt(item.width),
|
|
60870
61283
|
height: positiveInt(item.height),
|
|
60871
61284
|
durationSeconds: positiveInt(item.durationSeconds)
|
|
@@ -60895,28 +61308,28 @@ function normalizeMedia(media, featuredImage) {
|
|
|
60895
61308
|
}
|
|
60896
61309
|
function normalizeSource(source) {
|
|
60897
61310
|
return {
|
|
60898
|
-
originalUrl:
|
|
60899
|
-
resolvedUrl:
|
|
60900
|
-
sourceCanonicalUrl:
|
|
60901
|
-
relCanonicalHref:
|
|
60902
|
-
sourceByline:
|
|
60903
|
-
publisher:
|
|
61311
|
+
originalUrl: optionalText2(source?.originalUrl, 2e3) ?? void 0,
|
|
61312
|
+
resolvedUrl: optionalText2(source?.resolvedUrl, 2e3) ?? void 0,
|
|
61313
|
+
sourceCanonicalUrl: optionalText2(source?.sourceCanonicalUrl, 2e3) ?? void 0,
|
|
61314
|
+
relCanonicalHref: optionalText2(source?.relCanonicalHref, 2e3) ?? void 0,
|
|
61315
|
+
sourceByline: optionalText2(source?.sourceByline, 240) ?? void 0,
|
|
61316
|
+
publisher: optionalText2(source?.publisher, 240) ?? void 0,
|
|
60904
61317
|
authors: uniqueStrings(source?.authors ?? []).slice(0, 20),
|
|
60905
|
-
publishedAt:
|
|
60906
|
-
capturedAt:
|
|
60907
|
-
license:
|
|
60908
|
-
rightsSummary:
|
|
60909
|
-
contentHash:
|
|
61318
|
+
publishedAt: optionalText2(source?.publishedAt, 80) ?? void 0,
|
|
61319
|
+
capturedAt: optionalText2(source?.capturedAt, 80) ?? void 0,
|
|
61320
|
+
license: optionalText2(source?.license, 240) ?? void 0,
|
|
61321
|
+
rightsSummary: optionalText2(source?.rightsSummary, 1e3) ?? void 0,
|
|
61322
|
+
contentHash: optionalText2(source?.contentHash, 200) ?? void 0
|
|
60910
61323
|
};
|
|
60911
61324
|
}
|
|
60912
61325
|
function normalizeSeo(seo) {
|
|
60913
61326
|
return {
|
|
60914
|
-
canonicalUrl:
|
|
60915
|
-
relCanonical:
|
|
60916
|
-
metaTitle:
|
|
60917
|
-
metaDescription:
|
|
60918
|
-
ogImage:
|
|
60919
|
-
schemaOrgType:
|
|
61327
|
+
canonicalUrl: optionalText2(seo?.canonicalUrl, 2e3) ?? void 0,
|
|
61328
|
+
relCanonical: optionalText2(seo?.relCanonical, 2e3) ?? void 0,
|
|
61329
|
+
metaTitle: optionalText2(seo?.metaTitle, 240) ?? void 0,
|
|
61330
|
+
metaDescription: optionalText2(seo?.metaDescription, 500) ?? void 0,
|
|
61331
|
+
ogImage: optionalText2(seo?.ogImage, 2e3) ?? void 0,
|
|
61332
|
+
schemaOrgType: optionalText2(seo?.schemaOrgType, 80) ?? void 0,
|
|
60920
61333
|
noIndex: seo?.noIndex === true
|
|
60921
61334
|
};
|
|
60922
61335
|
}
|
|
@@ -60925,37 +61338,37 @@ function normalizeRelatedEntities(related) {
|
|
|
60925
61338
|
return related.map((item) => ({
|
|
60926
61339
|
entityId: normalizeEntityId(item.entityId),
|
|
60927
61340
|
title: requiredText(item.title, "relatedEntities.title", 1, 180),
|
|
60928
|
-
relationship:
|
|
61341
|
+
relationship: optionalText2(item.relationship, 120) ?? void 0,
|
|
60929
61342
|
slug: item.slug ? normalizeSlug(item.slug) : void 0,
|
|
60930
|
-
url:
|
|
60931
|
-
description:
|
|
61343
|
+
url: optionalText2(item.url, 2e3) ?? void 0,
|
|
61344
|
+
description: optionalText2(item.description, 300) ?? void 0
|
|
60932
61345
|
})).slice(0, 200);
|
|
60933
61346
|
}
|
|
60934
61347
|
function sanitizeSearchFilters(filters) {
|
|
60935
61348
|
return {
|
|
60936
|
-
query:
|
|
61349
|
+
query: optionalText2(filters.query, 300) ?? void 0,
|
|
60937
61350
|
entityType: filters.entityType ? normalizeEntityType(filters.entityType) : void 0,
|
|
60938
|
-
tag:
|
|
61351
|
+
tag: optionalText2(filters.tag, 80) ?? void 0,
|
|
60939
61352
|
tags: uniqueStrings(filters.tags ?? []).slice(0, 20),
|
|
60940
|
-
keyword:
|
|
61353
|
+
keyword: optionalText2(filters.keyword, 120) ?? void 0,
|
|
60941
61354
|
keywords: uniqueStrings(filters.keywords ?? []).slice(0, 20),
|
|
60942
61355
|
relatedEntityId: normalizeEntityId(filters.relatedEntityId),
|
|
60943
61356
|
trailId: normalizeEntityId(filters.trailId),
|
|
60944
|
-
sourceDomain:
|
|
61357
|
+
sourceDomain: optionalText2(filters.sourceDomain, 240) ?? void 0,
|
|
60945
61358
|
hasMedia: filters.hasMedia === true ? true : void 0,
|
|
60946
61359
|
hasVideo: filters.hasVideo === true ? true : void 0,
|
|
60947
|
-
publishedAfter:
|
|
60948
|
-
updatedAfter:
|
|
60949
|
-
filterId:
|
|
61360
|
+
publishedAfter: optionalText2(filters.publishedAfter, 80) ?? void 0,
|
|
61361
|
+
updatedAfter: optionalText2(filters.updatedAfter, 80) ?? void 0,
|
|
61362
|
+
filterId: optionalText2(filters.filterId, 200) ?? void 0,
|
|
60950
61363
|
limit: clampNumber(filters.limit, 1, 100, 20),
|
|
60951
61364
|
offset: clampNumber(filters.offset, 0, 1e4, 0)
|
|
60952
61365
|
};
|
|
60953
61366
|
}
|
|
60954
61367
|
function sanitizeNeedsLinkFilters(filters) {
|
|
60955
61368
|
return {
|
|
60956
|
-
query:
|
|
61369
|
+
query: optionalText2(filters.query, 300) ?? void 0,
|
|
60957
61370
|
entityType: filters.entityType ? normalizeEntityType(filters.entityType) : void 0,
|
|
60958
|
-
tag:
|
|
61371
|
+
tag: optionalText2(filters.tag, 80) ?? void 0,
|
|
60959
61372
|
tags: uniqueStrings(filters.tags ?? []).slice(0, 20),
|
|
60960
61373
|
sourceEntityId: normalizeEntityId(filters.sourceEntityId),
|
|
60961
61374
|
sourceSlug: filters.sourceSlug ? normalizeSlug(filters.sourceSlug) : void 0,
|
|
@@ -60976,7 +61389,7 @@ function commonsIndexingPolicy() {
|
|
|
60976
61389
|
storageScope: "platform_commons_graph",
|
|
60977
61390
|
countsAgainstUserStorage: false,
|
|
60978
61391
|
embedsPrivateUserVaults: false,
|
|
60979
|
-
corpus: ["published Commons article body", "tags", "keywords", "JSON-LD metadata", "related entities", "See Also concepts marked needsLink"],
|
|
61392
|
+
corpus: ["published Commons article body", "tags", "keywords", "JSON-LD metadata", "related entities", "governed relationship claims", "See Also concepts marked needsLink"],
|
|
60980
61393
|
excluded: ["comments", "comment threads", "reader alerts", "private reading-room state"],
|
|
60981
61394
|
retrievalPattern: {
|
|
60982
61395
|
lexicalFirst: ["title", "tags", "keywords", "source metadata", "article body", "See Also concepts"],
|
|
@@ -61052,7 +61465,7 @@ function searchableText(entity) {
|
|
|
61052
61465
|
].filter(Boolean).join("\n").toLowerCase();
|
|
61053
61466
|
}
|
|
61054
61467
|
function actorLabel(input, user) {
|
|
61055
|
-
return
|
|
61468
|
+
return optionalText2(input.actorLabel, 120) || optionalText2(user.name, 120) || `mcp-user-${user.id}`;
|
|
61056
61469
|
}
|
|
61057
61470
|
function publicBaseUrl() {
|
|
61058
61471
|
return (process.env.TRANSPARENT_COMMONS_PUBLIC_BASE_URL?.trim() || DEFAULT_COMMONS_BASE_URL).replace(/\/+$/, "");
|
|
@@ -61063,13 +61476,16 @@ function publicUrlForSlug(slug2) {
|
|
|
61063
61476
|
function allocateEntityId() {
|
|
61064
61477
|
return `TPW-Q${Date.now()}${Math.floor(Math.random() * 1e3).toString().padStart(3, "0")}`;
|
|
61065
61478
|
}
|
|
61479
|
+
function allocateClaimId() {
|
|
61480
|
+
return `TPW-S${Date.now()}${Math.floor(Math.random() * 1e6).toString().padStart(6, "0")}`;
|
|
61481
|
+
}
|
|
61066
61482
|
function normalizeEntityId(value) {
|
|
61067
|
-
const text2 =
|
|
61483
|
+
const text2 = optionalText2(value, 80);
|
|
61068
61484
|
if (!text2) return void 0;
|
|
61069
61485
|
return text2.replace(/\s+/g, "").toUpperCase();
|
|
61070
61486
|
}
|
|
61071
61487
|
function normalizeEntityType(value) {
|
|
61072
|
-
const raw =
|
|
61488
|
+
const raw = optionalText2(value, 120) || DEFAULT_ENTITY_TYPE;
|
|
61073
61489
|
const squashed = raw.replace(/[\s_-]+/g, "").toLowerCase();
|
|
61074
61490
|
if (squashed === "publicarticle" || squashed === "article" || squashed === "item") return DEFAULT_ENTITY_TYPE;
|
|
61075
61491
|
if (squashed === "trail" || squashed === "readingtrail") return "Trail";
|
|
@@ -61097,7 +61513,7 @@ function requiredText(value, field, min, max) {
|
|
|
61097
61513
|
if (text2.length < min) throw new CommonsRepositoryError(`${field.replaceAll(".", "_")}_required`, `${field} must be at least ${min} characters.`);
|
|
61098
61514
|
return text2.slice(0, max);
|
|
61099
61515
|
}
|
|
61100
|
-
function
|
|
61516
|
+
function optionalText2(value, max) {
|
|
61101
61517
|
const text2 = String(value ?? "").trim();
|
|
61102
61518
|
return text2 ? text2.slice(0, max) : void 0;
|
|
61103
61519
|
}
|
|
@@ -61117,7 +61533,7 @@ function uniqueStrings(values) {
|
|
|
61117
61533
|
const seen = /* @__PURE__ */ new Set();
|
|
61118
61534
|
const out = [];
|
|
61119
61535
|
for (const value of values) {
|
|
61120
|
-
const text2 =
|
|
61536
|
+
const text2 = optionalText2(value, 120);
|
|
61121
61537
|
if (!text2) continue;
|
|
61122
61538
|
const key = text2.toLowerCase();
|
|
61123
61539
|
if (seen.has(key)) continue;
|
|
@@ -61152,14 +61568,15 @@ function jsonLikeValue(value) {
|
|
|
61152
61568
|
function escapeLike(value) {
|
|
61153
61569
|
return value.replace(/[%_]/g, "");
|
|
61154
61570
|
}
|
|
61155
|
-
var
|
|
61571
|
+
var import_node_crypto35, COMMONS_SCHEMA_VERSION, DEFAULT_COMMONS_BASE_URL, DEFAULT_ENTITY_TYPE, COMMONS_ENTITY_PROFILES, schemaReady2, CommonsRepositoryError;
|
|
61156
61572
|
var init_commons_repository = __esm({
|
|
61157
61573
|
"src/api/commons-repository.ts"() {
|
|
61158
61574
|
"use strict";
|
|
61159
|
-
|
|
61575
|
+
import_node_crypto35 = require("crypto");
|
|
61160
61576
|
init_db();
|
|
61161
61577
|
init_rates();
|
|
61162
|
-
|
|
61578
|
+
init_commons_linksets();
|
|
61579
|
+
COMMONS_SCHEMA_VERSION = "2026-08-05.1";
|
|
61163
61580
|
DEFAULT_COMMONS_BASE_URL = "https://transparent-commons.cc";
|
|
61164
61581
|
DEFAULT_ENTITY_TYPE = "PublicArticle";
|
|
61165
61582
|
COMMONS_ENTITY_PROFILES = {
|
|
@@ -61410,7 +61827,7 @@ async function claimCommonsPublication(input, user) {
|
|
|
61410
61827
|
}
|
|
61411
61828
|
const existingName = await getCommonsPublicationBySubdomain(subdomain);
|
|
61412
61829
|
if (existingName) throw new CommonsPublicationError("publication_name_unavailable", "That publication name is already claimed.", 409);
|
|
61413
|
-
const id = `tcpub_${(0,
|
|
61830
|
+
const id = `tcpub_${(0, import_node_crypto36.randomUUID)()}`;
|
|
61414
61831
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
61415
61832
|
try {
|
|
61416
61833
|
await getDb().execute({
|
|
@@ -61462,7 +61879,7 @@ async function publishCommonsEditorial(input, user) {
|
|
|
61462
61879
|
const canonicalUrl = editionPublicUrl(subdomain, editionSlug);
|
|
61463
61880
|
const rendered = renderEditorialReadingRoom(editionInput);
|
|
61464
61881
|
const html = addPublicMetadata(rendered.html, canonicalUrl, publication.title);
|
|
61465
|
-
const editionId = `tced_${(0,
|
|
61882
|
+
const editionId = `tced_${(0, import_node_crypto36.randomUUID)()}`;
|
|
61466
61883
|
const revision = (latest?.revision ?? 0) + 1;
|
|
61467
61884
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
61468
61885
|
await getDb().batch([
|
|
@@ -61486,7 +61903,7 @@ async function publishCommonsEditorial(input, user) {
|
|
|
61486
61903
|
JSON.stringify(editionInput.articles),
|
|
61487
61904
|
html,
|
|
61488
61905
|
rendered.filename,
|
|
61489
|
-
(0,
|
|
61906
|
+
(0, import_node_crypto36.createHash)("sha256").update(html).digest("hex"),
|
|
61490
61907
|
rendered.articleCount,
|
|
61491
61908
|
rendered.wordCount,
|
|
61492
61909
|
Buffer.byteLength(html),
|
|
@@ -61672,11 +62089,11 @@ function addPublicMetadata(html, canonicalUrl, publicationTitle) {
|
|
|
61672
62089
|
"</head>"
|
|
61673
62090
|
].join("\n"));
|
|
61674
62091
|
}
|
|
61675
|
-
var
|
|
62092
|
+
var import_node_crypto36, PUBLICATION_ROOT_DOMAIN, RESERVED_SUBDOMAINS, CommonsPublicationError;
|
|
61676
62093
|
var init_commons_publication_repository = __esm({
|
|
61677
62094
|
"src/api/commons-publication-repository.ts"() {
|
|
61678
62095
|
"use strict";
|
|
61679
|
-
|
|
62096
|
+
import_node_crypto36 = require("crypto");
|
|
61680
62097
|
init_db();
|
|
61681
62098
|
init_commons_repository();
|
|
61682
62099
|
init_render();
|
|
@@ -61785,6 +62202,7 @@ var init_commons_routes = __esm({
|
|
|
61785
62202
|
import_zod51 = require("zod");
|
|
61786
62203
|
init_api_auth();
|
|
61787
62204
|
init_commons_repository();
|
|
62205
|
+
init_commons_linksets();
|
|
61788
62206
|
init_listing_write_billing();
|
|
61789
62207
|
init_commons_publication_repository();
|
|
61790
62208
|
init_mcp_tool_schemas();
|
|
@@ -61879,6 +62297,7 @@ var init_commons_routes = __esm({
|
|
|
61879
62297
|
url: import_zod51.z.string().url().optional(),
|
|
61880
62298
|
description: import_zod51.z.string().max(300).optional()
|
|
61881
62299
|
}).strict()).max(200).optional(),
|
|
62300
|
+
claims: import_zod51.z.array(CommonsClaimInputSchema).max(300).optional(),
|
|
61882
62301
|
bodyMarkdown: import_zod51.z.string().max(5e5).optional(),
|
|
61883
62302
|
contentSections: import_zod51.z.array(import_zod51.z.object({
|
|
61884
62303
|
id: import_zod51.z.string().max(180).optional(),
|
|
@@ -61956,6 +62375,17 @@ var init_commons_routes = __esm({
|
|
|
61956
62375
|
await ensureCommonsSchema();
|
|
61957
62376
|
return c.json({ ok: true, data: commonsDatabaseReport() });
|
|
61958
62377
|
});
|
|
62378
|
+
commonsApp.get("/profiles/relationships/v1", (c) => c.json({
|
|
62379
|
+
id: COMMONS_RELATIONSHIP_PROFILE,
|
|
62380
|
+
title: "Transparent Commons governed relationship linksets",
|
|
62381
|
+
mediaType: COMMONS_LINKSET_MEDIA_TYPE,
|
|
62382
|
+
claimAuthority: "MCP Scraper authenticated proposal and contribution ledger",
|
|
62383
|
+
anchorPolicy: "Every link context is an absolute canonical Transparent Commons wiki URL.",
|
|
62384
|
+
predicatePolicy: "Predicates are curated registered link relations or absolute HTTPS extension relation URIs.",
|
|
62385
|
+
publicationPolicy: "Only approved, active, non-deprecated claims whose dispute state is undisputed or attributed are projected.",
|
|
62386
|
+
trustPolicy: "A third-party target is an asserted relationship, not an endorsement or proof that the target agrees.",
|
|
62387
|
+
source: "https://www.rfc-editor.org/rfc/rfc9264.html"
|
|
62388
|
+
}));
|
|
61959
62389
|
commonsApp.post("/publications/prepare", auth2, async (c) => {
|
|
61960
62390
|
const parsed = PreparePublicationSchema.safeParse(await c.req.json().catch(() => ({})));
|
|
61961
62391
|
if (!parsed.success) return validationError(c, parsed.error);
|
|
@@ -62086,11 +62516,32 @@ var init_commons_routes = __esm({
|
|
|
62086
62516
|
commonsApp.get("/entities/:idOrSlug", async (c) => {
|
|
62087
62517
|
const entity = await getCommonsEntity(c.req.param("idOrSlug"));
|
|
62088
62518
|
if (!entity) return c.json({ ok: false, error: "entity_not_found", message: "No published Commons entity matched that id or slug." }, 404);
|
|
62519
|
+
c.header("Link", commonsLinksetDiscoveryHeader(entity.id));
|
|
62089
62520
|
return c.json({ ok: true, data: entity });
|
|
62090
62521
|
});
|
|
62522
|
+
commonsApp.get("/entities/:idOrSlug/claims", async (c) => {
|
|
62523
|
+
const result = await getCommonsEntityLinkset(c.req.param("idOrSlug"));
|
|
62524
|
+
if (!result) return c.json({ ok: false, error: "entity_not_found", message: "No published Commons entity matched that id or slug." }, 404);
|
|
62525
|
+
c.header("Link", commonsLinksetDiscoveryHeader(result.entity.id));
|
|
62526
|
+
return c.json({ ok: true, data: { entity: result.entity, claims: result.claims, linksetUrl: result.linksetUrl } });
|
|
62527
|
+
});
|
|
62528
|
+
commonsApp.get("/entities/:idOrSlug/linkset", async (c) => {
|
|
62529
|
+
const result = await getCommonsEntityLinkset(c.req.param("idOrSlug"));
|
|
62530
|
+
if (!result) return c.json({ ok: false, error: "entity_not_found", message: "No published Commons entity matched that id or slug." }, 404);
|
|
62531
|
+
c.header("Content-Type", `${COMMONS_LINKSET_MEDIA_TYPE}; profile="${COMMONS_RELATIONSHIP_PROFILE}"`);
|
|
62532
|
+
c.header("ETag", result.etag);
|
|
62533
|
+
c.header("Link", `<${COMMONS_RELATIONSHIP_PROFILE}>; rel="profile"`);
|
|
62534
|
+
c.header("Cache-Control", "public, max-age=60, s-maxage=300");
|
|
62535
|
+
if (c.req.header("If-None-Match") === result.etag) return c.body(null, 304);
|
|
62536
|
+
if (c.req.query("envelope") === "true") {
|
|
62537
|
+
return c.json({ ok: true, data: { ...result, document: result.document } });
|
|
62538
|
+
}
|
|
62539
|
+
return c.body(JSON.stringify(result.document));
|
|
62540
|
+
});
|
|
62091
62541
|
commonsApp.get("/entities/:idOrSlug/wiki-page", async (c) => {
|
|
62092
62542
|
const entity = await getCommonsEntity(c.req.param("idOrSlug"));
|
|
62093
62543
|
if (!entity) return c.json({ ok: false, error: "entity_not_found", message: "No published Commons entity matched that id or slug." }, 404);
|
|
62544
|
+
c.header("Link", commonsLinksetDiscoveryHeader(entity.id));
|
|
62094
62545
|
return c.json({ ok: true, data: entityToWikiPage(entity) });
|
|
62095
62546
|
});
|
|
62096
62547
|
commonsApp.get("/entities/:idOrSlug/json-ld", async (c) => {
|
|
@@ -62106,6 +62557,7 @@ var init_commons_routes = __esm({
|
|
|
62106
62557
|
commonsApp.get("/wiki/:slug", async (c) => {
|
|
62107
62558
|
const entity = await getCommonsEntity(c.req.param("slug"));
|
|
62108
62559
|
if (!entity) return c.json({ ok: false, error: "page_not_found", message: "No published Commons wiki page matched that slug." }, 404);
|
|
62560
|
+
c.header("Link", commonsLinksetDiscoveryHeader(entity.id));
|
|
62109
62561
|
return c.json({
|
|
62110
62562
|
ok: true,
|
|
62111
62563
|
data: {
|
|
@@ -62786,7 +63238,7 @@ async function migrateAnalytics() {
|
|
|
62786
63238
|
}
|
|
62787
63239
|
function normalizeSlug2(value) {
|
|
62788
63240
|
const slug2 = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
62789
|
-
return slug2 || `site-${(0,
|
|
63241
|
+
return slug2 || `site-${(0, import_node_crypto37.randomBytes)(4).toString("hex")}`;
|
|
62790
63242
|
}
|
|
62791
63243
|
function normalizeObservedHostname(origin) {
|
|
62792
63244
|
if (!origin || origin === "null") return null;
|
|
@@ -62799,7 +63251,7 @@ function normalizeObservedHostname(origin) {
|
|
|
62799
63251
|
}
|
|
62800
63252
|
}
|
|
62801
63253
|
function publicPixelId() {
|
|
62802
|
-
return `px_${(0,
|
|
63254
|
+
return `px_${(0, import_node_crypto37.randomBytes)(18).toString("base64url")}`;
|
|
62803
63255
|
}
|
|
62804
63256
|
function mapRows(rows) {
|
|
62805
63257
|
return rows;
|
|
@@ -62831,7 +63283,7 @@ async function requireEditor(client2, siteId, userId) {
|
|
|
62831
63283
|
async function createAnalyticsSite(input) {
|
|
62832
63284
|
const db = getAnalyticsPool();
|
|
62833
63285
|
const client2 = await db.connect();
|
|
62834
|
-
const id = (0,
|
|
63286
|
+
const id = (0, import_node_crypto37.randomUUID)();
|
|
62835
63287
|
const baseSlug = normalizeSlug2(input.slug || input.name);
|
|
62836
63288
|
try {
|
|
62837
63289
|
await client2.query("BEGIN");
|
|
@@ -62847,7 +63299,7 @@ async function createAnalyticsSite(input) {
|
|
|
62847
63299
|
} catch (error) {
|
|
62848
63300
|
const code = error.code;
|
|
62849
63301
|
if (code !== "23505" || attempt === 2) throw error;
|
|
62850
|
-
slug2 = `${baseSlug}-${(0,
|
|
63302
|
+
slug2 = `${baseSlug}-${(0, import_node_crypto37.randomBytes)(2).toString("hex")}`;
|
|
62851
63303
|
}
|
|
62852
63304
|
}
|
|
62853
63305
|
await client2.query(
|
|
@@ -63062,7 +63514,7 @@ async function createAnalyticsPixel(input) {
|
|
|
63062
63514
|
VALUES ($1, $2, $3, $4, $5)
|
|
63063
63515
|
RETURNING id, site_id, public_id, name, environment, status, created_at::text, NULL::text AS last_event_at`,
|
|
63064
63516
|
[
|
|
63065
|
-
(0,
|
|
63517
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
63066
63518
|
input.siteId,
|
|
63067
63519
|
publicPixelId(),
|
|
63068
63520
|
input.name.trim(),
|
|
@@ -63139,7 +63591,7 @@ async function setAnalyticsPixelDomainState(input) {
|
|
|
63139
63591
|
SELECT $1, p.id, $4, $5 FROM analytics_pixels p WHERE p.id = $2 AND p.site_id = $3
|
|
63140
63592
|
ON CONFLICT(pixel_id, hostname) DO UPDATE SET state = EXCLUDED.state, updated_at = now()
|
|
63141
63593
|
RETURNING id`,
|
|
63142
|
-
[(0,
|
|
63594
|
+
[(0, import_node_crypto37.randomUUID)(), input.pixelId, input.siteId, hostname, input.state]
|
|
63143
63595
|
);
|
|
63144
63596
|
if (!result.rowCount)
|
|
63145
63597
|
throw new AnalyticsRepositoryError(
|
|
@@ -63183,7 +63635,7 @@ function sanitizeAnalyticsProperties(value) {
|
|
|
63183
63635
|
}
|
|
63184
63636
|
async function ingestAnalyticsEvents(input) {
|
|
63185
63637
|
const db = getAnalyticsPool();
|
|
63186
|
-
const requestId = `air_${(0,
|
|
63638
|
+
const requestId = `air_${(0, import_node_crypto37.randomUUID)()}`;
|
|
63187
63639
|
const hostname = normalizeObservedHostname(input.origin);
|
|
63188
63640
|
const pixelResult = await db.query(
|
|
63189
63641
|
`SELECT p.id, p.site_id, p.status,
|
|
@@ -63204,7 +63656,7 @@ async function ingestAnalyticsEvents(input) {
|
|
|
63204
63656
|
`INSERT INTO analytics_ingestion_receipts(id, request_id, site_id, pixel_id, hostname, rejected_count, reason_codes)
|
|
63205
63657
|
VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)`,
|
|
63206
63658
|
[
|
|
63207
|
-
(0,
|
|
63659
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
63208
63660
|
requestId,
|
|
63209
63661
|
pixel?.site_id ?? null,
|
|
63210
63662
|
pixel?.id ?? null,
|
|
@@ -63229,7 +63681,7 @@ async function ingestAnalyticsEvents(input) {
|
|
|
63229
63681
|
`INSERT INTO analytics_ingestion_receipts(id, request_id, site_id, pixel_id, hostname, rejected_count, reason_codes)
|
|
63230
63682
|
VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)`,
|
|
63231
63683
|
[
|
|
63232
|
-
(0,
|
|
63684
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
63233
63685
|
requestId,
|
|
63234
63686
|
pixel.site_id,
|
|
63235
63687
|
pixel.id,
|
|
@@ -63254,7 +63706,7 @@ async function ingestAnalyticsEvents(input) {
|
|
|
63254
63706
|
`INSERT INTO analytics_ingestion_receipts(id, request_id, site_id, pixel_id, rejected_count, reason_codes)
|
|
63255
63707
|
VALUES ($1, $2, $3, $4, $5, $6::jsonb)`,
|
|
63256
63708
|
[
|
|
63257
|
-
(0,
|
|
63709
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
63258
63710
|
requestId,
|
|
63259
63711
|
pixel.site_id,
|
|
63260
63712
|
pixel.id,
|
|
@@ -63278,7 +63730,7 @@ async function ingestAnalyticsEvents(input) {
|
|
|
63278
63730
|
ON CONFLICT(pixel_id, hostname) DO UPDATE
|
|
63279
63731
|
SET last_seen_at = now(), updated_at = now()
|
|
63280
63732
|
RETURNING state`,
|
|
63281
|
-
[(0,
|
|
63733
|
+
[(0, import_node_crypto37.randomUUID)(), pixel.id, hostname]
|
|
63282
63734
|
);
|
|
63283
63735
|
if (domainResult.rows[0]?.state !== "approved") {
|
|
63284
63736
|
await db.query(
|
|
@@ -63292,7 +63744,7 @@ async function ingestAnalyticsEvents(input) {
|
|
|
63292
63744
|
`INSERT INTO analytics_ingestion_receipts(id, request_id, site_id, pixel_id, hostname, rejected_count, reason_codes)
|
|
63293
63745
|
VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)`,
|
|
63294
63746
|
[
|
|
63295
|
-
(0,
|
|
63747
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
63296
63748
|
requestId,
|
|
63297
63749
|
pixel.site_id,
|
|
63298
63750
|
pixel.id,
|
|
@@ -63341,7 +63793,7 @@ async function ingestAnalyticsEvents(input) {
|
|
|
63341
63793
|
$23, $24, $25, $26, $27, $28, $29, $30, $31
|
|
63342
63794
|
) ON CONFLICT(site_id, event_id) DO NOTHING`,
|
|
63343
63795
|
[
|
|
63344
|
-
(0,
|
|
63796
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
63345
63797
|
event2.eventId,
|
|
63346
63798
|
pixel.site_id,
|
|
63347
63799
|
pixel.id,
|
|
@@ -63397,7 +63849,7 @@ async function ingestAnalyticsEvents(input) {
|
|
|
63397
63849
|
id, request_id, site_id, pixel_id, hostname, accepted_count, rejected_count, reason_codes
|
|
63398
63850
|
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb)`,
|
|
63399
63851
|
[
|
|
63400
|
-
(0,
|
|
63852
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
63401
63853
|
requestId,
|
|
63402
63854
|
pixel.site_id,
|
|
63403
63855
|
pixel.id,
|
|
@@ -63429,7 +63881,7 @@ function normalizeGeographyCode(value, max) {
|
|
|
63429
63881
|
return normalized && /^[A-Z0-9-]+$/.test(normalized) ? normalized.slice(0, max) : null;
|
|
63430
63882
|
}
|
|
63431
63883
|
function pageFingerprint(scope, siteId, filters) {
|
|
63432
|
-
return (0,
|
|
63884
|
+
return (0, import_node_crypto37.createHash)("sha256").update(JSON.stringify({ scope, siteId, filters })).digest("base64url").slice(0, 18);
|
|
63433
63885
|
}
|
|
63434
63886
|
function decodePageOffset(cursor, fingerprint) {
|
|
63435
63887
|
if (!cursor) return 0;
|
|
@@ -63479,7 +63931,7 @@ async function createAnalyticsConversion(input) {
|
|
|
63479
63931
|
404
|
|
63480
63932
|
);
|
|
63481
63933
|
}
|
|
63482
|
-
const id = (0,
|
|
63934
|
+
const id = (0, import_node_crypto37.randomUUID)();
|
|
63483
63935
|
const resolvedPerson = input.sessionId ? await db.query(
|
|
63484
63936
|
`SELECT e.person_id FROM analytics_identity_nodes n JOIN analytics_identity_edges e ON e.identity_node_id = n.id
|
|
63485
63937
|
WHERE n.site_id = $1 AND n.kind = 'session_id' AND n.value_hmac = $2 ORDER BY e.confidence DESC LIMIT 1`,
|
|
@@ -64154,7 +64606,7 @@ async function createAnalyticsCampaignLink(input) {
|
|
|
64154
64606
|
404
|
|
64155
64607
|
);
|
|
64156
64608
|
}
|
|
64157
|
-
const shortCode = (input.shortCode?.trim().toLowerCase().replace(/[^a-z0-9_-]/g, "-") || (0,
|
|
64609
|
+
const shortCode = (input.shortCode?.trim().toLowerCase().replace(/[^a-z0-9_-]/g, "-") || (0, import_node_crypto37.randomBytes)(5).toString("base64url").toLowerCase()).slice(0, 48);
|
|
64158
64610
|
try {
|
|
64159
64611
|
const result = await db.query(
|
|
64160
64612
|
`INSERT INTO analytics_campaign_links(
|
|
@@ -64163,7 +64615,7 @@ async function createAnalyticsCampaignLink(input) {
|
|
|
64163
64615
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15)
|
|
64164
64616
|
RETURNING *, 0::int AS click_count`,
|
|
64165
64617
|
[
|
|
64166
|
-
(0,
|
|
64618
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
64167
64619
|
input.siteId,
|
|
64168
64620
|
input.pixelId ?? null,
|
|
64169
64621
|
input.name.trim(),
|
|
@@ -64234,7 +64686,7 @@ async function resolveAnalyticsCampaignLink(shortCode, referrer) {
|
|
|
64234
64686
|
if (!row) return null;
|
|
64235
64687
|
await db.query(
|
|
64236
64688
|
`INSERT INTO analytics_campaign_clicks(id, link_id, referrer) VALUES ($1, $2, $3)`,
|
|
64237
|
-
[(0,
|
|
64689
|
+
[(0, import_node_crypto37.randomUUID)(), row.id, normalizeAnalyticsUrl(referrer || void 0)]
|
|
64238
64690
|
);
|
|
64239
64691
|
return buildTaggedCampaignUrl(row);
|
|
64240
64692
|
}
|
|
@@ -64252,14 +64704,14 @@ async function createAnalyticsForm(input) {
|
|
|
64252
64704
|
404
|
|
64253
64705
|
);
|
|
64254
64706
|
const baseSlug = normalizeSlug2(input.name);
|
|
64255
|
-
const slug2 = `${baseSlug}-${(0,
|
|
64256
|
-
const publicId = `form_${(0,
|
|
64707
|
+
const slug2 = `${baseSlug}-${(0, import_node_crypto37.randomBytes)(3).toString("hex")}`;
|
|
64708
|
+
const publicId = `form_${(0, import_node_crypto37.randomBytes)(18).toString("base64url")}`;
|
|
64257
64709
|
const result = await db.query(
|
|
64258
64710
|
`INSERT INTO analytics_forms(id, public_id, site_id, pixel_id, name, slug, fields, brand, submit_label, success_message, redirect_url, consent_text, status, created_by_user_id)
|
|
64259
64711
|
VALUES ($1,$2,$3,$4,$5,$6,$7::jsonb,$8::jsonb,$9,$10,$11,$12,$13,$14)
|
|
64260
64712
|
RETURNING *, 0::int AS submission_count`,
|
|
64261
64713
|
[
|
|
64262
|
-
(0,
|
|
64714
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
64263
64715
|
publicId,
|
|
64264
64716
|
input.siteId,
|
|
64265
64717
|
input.pixelId,
|
|
@@ -64304,7 +64756,7 @@ async function getPublicAnalyticsForm(publicId) {
|
|
|
64304
64756
|
return result.rows[0] ?? null;
|
|
64305
64757
|
}
|
|
64306
64758
|
async function recordAnalyticsFormSubmission(input) {
|
|
64307
|
-
const id = (0,
|
|
64759
|
+
const id = (0, import_node_crypto37.randomUUID)();
|
|
64308
64760
|
await getAnalyticsPool().query(
|
|
64309
64761
|
`INSERT INTO analytics_form_submissions(id, form_id, site_id, pixel_id, visitor_id, session_id, crm_person_ref, source, medium, campaign, crm_delivery_status, click_ids)
|
|
64310
64762
|
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12::jsonb)`,
|
|
@@ -64335,7 +64787,7 @@ function sanitizeClickIds(value) {
|
|
|
64335
64787
|
return output;
|
|
64336
64788
|
}
|
|
64337
64789
|
function identityHmac(kind, value) {
|
|
64338
|
-
return (0,
|
|
64790
|
+
return (0, import_node_crypto37.createHmac)("sha256", getSessionSecret()).update(`${kind}:${value.trim().toLowerCase()}`).digest("hex");
|
|
64339
64791
|
}
|
|
64340
64792
|
async function linkAnalyticsFormIdentity(input) {
|
|
64341
64793
|
const client2 = await getAnalyticsPool().connect();
|
|
@@ -64344,7 +64796,7 @@ async function linkAnalyticsFormIdentity(input) {
|
|
|
64344
64796
|
const person = await client2.query(
|
|
64345
64797
|
`INSERT INTO analytics_people(id, site_id, crm_person_ref) VALUES ($1,$2,$3)
|
|
64346
64798
|
ON CONFLICT(site_id, crm_person_ref) DO UPDATE SET last_seen_at = now() RETURNING id`,
|
|
64347
|
-
[(0,
|
|
64799
|
+
[(0, import_node_crypto37.randomUUID)(), input.siteId, input.crmPersonRef]
|
|
64348
64800
|
);
|
|
64349
64801
|
const personId = person.rows[0].id;
|
|
64350
64802
|
const signals = [];
|
|
@@ -64391,7 +64843,7 @@ async function linkAnalyticsFormIdentity(input) {
|
|
|
64391
64843
|
`INSERT INTO analytics_identity_nodes(id, site_id, kind, value_hmac) VALUES ($1,$2,$3,$4)
|
|
64392
64844
|
ON CONFLICT(site_id, kind, value_hmac) DO UPDATE SET last_seen_at = now() RETURNING id`,
|
|
64393
64845
|
[
|
|
64394
|
-
(0,
|
|
64846
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
64395
64847
|
input.siteId,
|
|
64396
64848
|
signal.kind,
|
|
64397
64849
|
identityHmac(signal.kind, signal.value)
|
|
@@ -64402,7 +64854,7 @@ async function linkAnalyticsFormIdentity(input) {
|
|
|
64402
64854
|
VALUES ($1,$2,$3,$4,$5,$6)
|
|
64403
64855
|
ON CONFLICT(person_id, identity_node_id, evidence_kind) DO UPDATE SET last_seen_at = now(), confidence = greatest(analytics_identity_edges.confidence, EXCLUDED.confidence)`,
|
|
64404
64856
|
[
|
|
64405
|
-
(0,
|
|
64857
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
64406
64858
|
input.siteId,
|
|
64407
64859
|
personId,
|
|
64408
64860
|
node.rows[0].id,
|
|
@@ -64500,7 +64952,7 @@ async function createAnalyticsCrmImport(input) {
|
|
|
64500
64952
|
const db = getAnalyticsPool();
|
|
64501
64953
|
await requireEditor(db, input.siteId, input.userId);
|
|
64502
64954
|
const client2 = await db.connect();
|
|
64503
|
-
const id = (0,
|
|
64955
|
+
const id = (0, import_node_crypto37.randomUUID)();
|
|
64504
64956
|
try {
|
|
64505
64957
|
await client2.query("BEGIN");
|
|
64506
64958
|
await client2.query(
|
|
@@ -64520,7 +64972,7 @@ async function createAnalyticsCrmImport(input) {
|
|
|
64520
64972
|
await client2.query(
|
|
64521
64973
|
`INSERT INTO analytics_crm_import_rows(id, import_id, crm_person_ref, payload_ciphertext)
|
|
64522
64974
|
VALUES ($1,$2,$3,$4) ON CONFLICT(import_id, crm_person_ref) DO NOTHING`,
|
|
64523
|
-
[(0,
|
|
64975
|
+
[(0, import_node_crypto37.randomUUID)(), id, row.crmPersonRef, row.payloadCiphertext]
|
|
64524
64976
|
);
|
|
64525
64977
|
}
|
|
64526
64978
|
await client2.query("COMMIT");
|
|
@@ -64559,7 +65011,7 @@ async function createAnalyticsActivationDestination(input) {
|
|
|
64559
65011
|
`INSERT INTO analytics_activation_destinations(id, site_id, platform, name, connection_ref, external_dataset_id, event_mapping, created_by_user_id)
|
|
64560
65012
|
VALUES ($1,$2,$3,$4,$5,$6,$7::jsonb,$8) RETURNING *`,
|
|
64561
65013
|
[
|
|
64562
|
-
(0,
|
|
65014
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
64563
65015
|
input.siteId,
|
|
64564
65016
|
input.platform,
|
|
64565
65017
|
input.name.trim(),
|
|
@@ -64611,7 +65063,7 @@ async function queueAnalyticsActivation(input) {
|
|
|
64611
65063
|
`INSERT INTO analytics_activation_jobs(id, destination_id, conversion_id, person_id, payload_ciphertext)
|
|
64612
65064
|
VALUES ($1,$2,$3,$4,$5) ON CONFLICT(destination_id, conversion_id) DO NOTHING`,
|
|
64613
65065
|
[
|
|
64614
|
-
(0,
|
|
65066
|
+
(0, import_node_crypto37.randomUUID)(),
|
|
64615
65067
|
destination.id,
|
|
64616
65068
|
input.conversionId,
|
|
64617
65069
|
input.personId ?? null,
|
|
@@ -64623,7 +65075,7 @@ async function queueAnalyticsActivation(input) {
|
|
|
64623
65075
|
return queued;
|
|
64624
65076
|
}
|
|
64625
65077
|
async function queueAnalyticsFormDelivery(input) {
|
|
64626
|
-
const id = (0,
|
|
65078
|
+
const id = (0, import_node_crypto37.randomUUID)();
|
|
64627
65079
|
await getAnalyticsPool().query(
|
|
64628
65080
|
`INSERT INTO analytics_form_delivery_jobs(id, submission_id, owner_user_id, payload_ciphertext, last_error_code)
|
|
64629
65081
|
VALUES ($1,$2,$3,$4,$5)`,
|
|
@@ -64750,7 +65202,7 @@ async function analyticsHealth(siteId, userId) {
|
|
|
64750
65202
|
}
|
|
64751
65203
|
async function refreshAnalyticsDailyRollups(input) {
|
|
64752
65204
|
const db = getAnalyticsPool();
|
|
64753
|
-
const runId = (0,
|
|
65205
|
+
const runId = (0, import_node_crypto37.randomUUID)();
|
|
64754
65206
|
await db.query(
|
|
64755
65207
|
`INSERT INTO analytics_rollup_runs(id, window_start, window_end, status) VALUES ($1, $2, $3, 'running')`,
|
|
64756
65208
|
[runId, input.start, input.end]
|
|
@@ -64913,7 +65365,7 @@ async function createAnalyticsExport(input) {
|
|
|
64913
65365
|
`Generated ${(/* @__PURE__ */ new Date()).toISOString()} from the governed ${input.report} report contract.`
|
|
64914
65366
|
].join("\n");
|
|
64915
65367
|
}
|
|
64916
|
-
const id = (0,
|
|
65368
|
+
const id = (0, import_node_crypto37.randomUUID)();
|
|
64917
65369
|
const inserted = await getAnalyticsPool().query(
|
|
64918
65370
|
`INSERT INTO analytics_exports(id, site_id, requested_by_user_id, idempotency_key, report, format, filters, content)
|
|
64919
65371
|
VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb, $8)
|
|
@@ -64946,11 +65398,11 @@ async function createAnalyticsExport(input) {
|
|
|
64946
65398
|
}
|
|
64947
65399
|
return describeArtifact(replay.rows[0]);
|
|
64948
65400
|
}
|
|
64949
|
-
var
|
|
65401
|
+
var import_node_crypto37, import_pg, AnalyticsRepositoryError, pool2, blockedPropertyName, inferredFamilySql, clickIdKeys;
|
|
64950
65402
|
var init_analytics_repository = __esm({
|
|
64951
65403
|
"src/api/analytics-repository.ts"() {
|
|
64952
65404
|
"use strict";
|
|
64953
|
-
|
|
65405
|
+
import_node_crypto37 = require("crypto");
|
|
64954
65406
|
import_pg = require("pg");
|
|
64955
65407
|
init_session();
|
|
64956
65408
|
init_analytics_attribution();
|
|
@@ -65171,8 +65623,8 @@ function dashboardCallbackUrl() {
|
|
|
65171
65623
|
}
|
|
65172
65624
|
async function createThorbitConnectUrl(userId) {
|
|
65173
65625
|
if (!bridgeConfigured()) throw new Error("Thorbit X-Ray account bridge is not configured");
|
|
65174
|
-
const state = (0,
|
|
65175
|
-
const stateHash = (0,
|
|
65626
|
+
const state = (0, import_node_crypto38.randomBytes)(32).toString("base64url");
|
|
65627
|
+
const stateHash = (0, import_node_crypto38.createHash)("sha256").update(state).digest("hex");
|
|
65176
65628
|
await getAnalyticsPool().query(
|
|
65177
65629
|
`INSERT INTO analytics_thorbit_connect_states(state_hash,user_id,expires_at)
|
|
65178
65630
|
VALUES ($1,$2,now()+interval '10 minutes')
|
|
@@ -65187,9 +65639,9 @@ async function createThorbitConnectUrl(userId) {
|
|
|
65187
65639
|
function verifyThorbitAssertion(token4) {
|
|
65188
65640
|
const [encoded, signature] = token4.split(".");
|
|
65189
65641
|
if (!encoded || !signature || !bridgeConfigured()) throw new Error("Invalid Thorbit assertion");
|
|
65190
|
-
const expected = (0,
|
|
65642
|
+
const expected = (0, import_node_crypto38.createHmac)("sha256", bridgeSecret()).update(encoded).digest();
|
|
65191
65643
|
const actual = Buffer.from(signature, "base64url");
|
|
65192
|
-
if (actual.length !== expected.length || !(0,
|
|
65644
|
+
if (actual.length !== expected.length || !(0, import_node_crypto38.timingSafeEqual)(actual, expected)) {
|
|
65193
65645
|
throw new Error("Invalid Thorbit assertion signature");
|
|
65194
65646
|
}
|
|
65195
65647
|
const parsed = AssertionSchema.safeParse(
|
|
@@ -65201,7 +65653,7 @@ function verifyThorbitAssertion(token4) {
|
|
|
65201
65653
|
return parsed.data.entitlement;
|
|
65202
65654
|
}
|
|
65203
65655
|
async function consumeThorbitConnectCallback(input) {
|
|
65204
|
-
const stateHash = (0,
|
|
65656
|
+
const stateHash = (0, import_node_crypto38.createHash)("sha256").update(input.state).digest("hex");
|
|
65205
65657
|
const client2 = await getAnalyticsPool().connect();
|
|
65206
65658
|
try {
|
|
65207
65659
|
await client2.query("BEGIN");
|
|
@@ -65241,11 +65693,11 @@ async function disconnectAnalyticsEntitlement(userId) {
|
|
|
65241
65693
|
[userId]
|
|
65242
65694
|
);
|
|
65243
65695
|
}
|
|
65244
|
-
var
|
|
65696
|
+
var import_node_crypto38, import_zod52, THORBIT_PRODUCT_URL, REFRESH_INTERVAL_MS, ELIGIBLE_GRACE_MS, TRIAL_LENGTH_MS, ThorbitEntitlementSchema, AssertionSchema;
|
|
65245
65697
|
var init_analytics_entitlement = __esm({
|
|
65246
65698
|
"src/api/analytics-entitlement.ts"() {
|
|
65247
65699
|
"use strict";
|
|
65248
|
-
|
|
65700
|
+
import_node_crypto38 = require("crypto");
|
|
65249
65701
|
import_zod52 = require("zod");
|
|
65250
65702
|
init_analytics_repository();
|
|
65251
65703
|
THORBIT_PRODUCT_URL = "https://thorbit.ai";
|
|
@@ -65382,14 +65834,14 @@ function renderPublicForm(form, placementUrl) {
|
|
|
65382
65834
|
const brand = form.brand;
|
|
65383
65835
|
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style>:root{font-family:ui-sans-serif,system-ui;color:${escapeHtml7(brand.textColor)};background:${escapeHtml7(brand.backgroundColor)}}*{box-sizing:border-box}body{margin:0;padding:18px}form{display:grid;gap:14px}label{display:grid;gap:6px;font-size:13px;font-weight:650}.check{grid-template-columns:auto 1fr;align-items:center}.check span{grid-column:2}.check input{grid-column:1;grid-row:1}input,textarea,select{width:100%;min-height:44px;padding:10px 12px;border:1px solid #ccd3df;border-radius:${brand.radius}px;background:white;color:inherit;font:inherit}textarea{min-height:110px;resize:vertical}button{min-height:46px;border:0;border-radius:${brand.radius}px;color:white;background:${escapeHtml7(brand.primaryColor)};font:inherit;font-weight:750;cursor:pointer}.consent{margin:0;color:#667085;font-size:11px;line-height:1.45}.notice{display:none;padding:12px;border-radius:${brand.radius}px;background:#edf8f2;color:#17613c}.hp{position:absolute!important;left:-9999px!important}</style></head><body><form id="mcp-form">${fields}<label class="hp">Website<input name="website" autocomplete="off" tabindex="-1"></label>${form.consent_text ? `<p class="consent">${escapeHtml7(form.consent_text)}</p>` : ""}<button>${escapeHtml7(form.submit_label)}</button><div class="notice" role="status"></div></form><script>(()=>{const form=document.querySelector('#mcp-form'),notice=form.querySelector('.notice'),q=new URLSearchParams(location.search);form.addEventListener('submit',async event=>{event.preventDefault();const button=form.querySelector('button');button.disabled=true;const raw=Object.fromEntries(new FormData(form).entries()),website=String(raw.website||''),clickIds={};delete raw.website;for(const k of ['fbclid','gclid','gbraid','wbraid','ttclid','rdt_cid','msclkid']){const v=q.get(k);if(v)clickIds[k]=v}try{const response=await fetch('/analytics/forms/${escapeHtml7(form.public_id)}/submissions',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({data:raw,website,placementUrl:${JSON.stringify(placementUrl)},visitorId:q.get('visitor')||undefined,sessionId:q.get('session')||undefined,source:q.get('source')||undefined,medium:q.get('medium')||undefined,campaign:q.get('campaign')||undefined,clickIds})});if(!response.ok)throw new Error('submit');notice.textContent=${JSON.stringify(form.success_message)};notice.style.display='block';form.reset();${form.redirect_url ? `setTimeout(()=>{top.location.href=${JSON.stringify(form.redirect_url)}},700);` : ""}}catch{notice.textContent='Your response could not be submitted. Please try again.';notice.style.display='block'}finally{button.disabled=false}})})()</script></body></html>`;
|
|
65384
65836
|
}
|
|
65385
|
-
var import_hono32, import_factory6, import_zod53,
|
|
65837
|
+
var import_hono32, import_factory6, import_zod53, import_node_crypto39, import_papaparse4, analyticsApp, auth3, entitlementGuard, ThorbitApiKeySchema, ThorbitCallbackSchema, SiteInputSchema, PixelInputSchema, PixelUpdateSchema, EventSchema, IngestionSchema, ConversionSchema, ExportSchema2, CampaignLinkSchema, FormFieldSchema, FormInputSchema, FormSubmissionSchema, CrmImportSchema, ActivationDestinationSchema, BusinessModelSchema, AdSpendSchema;
|
|
65386
65838
|
var init_analytics_routes = __esm({
|
|
65387
65839
|
"src/api/analytics-routes.ts"() {
|
|
65388
65840
|
"use strict";
|
|
65389
65841
|
import_hono32 = require("hono");
|
|
65390
65842
|
import_factory6 = require("hono/factory");
|
|
65391
65843
|
import_zod53 = require("zod");
|
|
65392
|
-
|
|
65844
|
+
import_node_crypto39 = require("crypto");
|
|
65393
65845
|
import_papaparse4 = __toESM(require("papaparse"), 1);
|
|
65394
65846
|
init_api_auth();
|
|
65395
65847
|
init_db();
|
|
@@ -65718,7 +66170,7 @@ var init_analytics_routes = __esm({
|
|
|
65718
66170
|
const lastName = typeof data.last_name === "string" ? data.last_name.trim() : "";
|
|
65719
66171
|
const fullName = [firstName, lastName].filter(Boolean).join(" ") || (typeof data.name === "string" ? data.name.trim() : "") || email || "Website lead";
|
|
65720
66172
|
const identitySeed = email || `${fullName}:${Date.now()}`;
|
|
65721
|
-
const suffix2 = (0,
|
|
66173
|
+
const suffix2 = (0, import_node_crypto39.createHash)("sha256").update(identitySeed).digest("hex").slice(0, 12);
|
|
65722
66174
|
const path6 = `Leads/person-${suffix2}`;
|
|
65723
66175
|
const { key: memoryKey, error: memoryKeyError } = await getOrCreateUserMemoryKey(user);
|
|
65724
66176
|
const existing = memoryKey ? await memoryCall("getTool", { vault: "People", path: path6 }, memoryKey) : { ok: false, error: memoryKeyError || "memory_credential_unavailable" };
|
|
@@ -65817,9 +66269,9 @@ Submitted the published form.
|
|
|
65817
66269
|
occurredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
65818
66270
|
});
|
|
65819
66271
|
const match = {
|
|
65820
|
-
...email ? { emailSha256: (0,
|
|
66272
|
+
...email ? { emailSha256: (0, import_node_crypto39.createHash)("sha256").update(email).digest("hex") } : {},
|
|
65821
66273
|
...phone ? {
|
|
65822
|
-
phoneSha256: (0,
|
|
66274
|
+
phoneSha256: (0, import_node_crypto39.createHash)("sha256").update(phone.replace(/\D/g, "")).digest("hex")
|
|
65823
66275
|
} : {}
|
|
65824
66276
|
};
|
|
65825
66277
|
const activationQueued = await queueAnalyticsActivation({
|
|
@@ -66247,7 +66699,7 @@ Submitted the published form.
|
|
|
66247
66699
|
rejectedCount += 1;
|
|
66248
66700
|
continue;
|
|
66249
66701
|
}
|
|
66250
|
-
const digest2 = (0,
|
|
66702
|
+
const digest2 = (0, import_node_crypto39.createHash)("sha256").update(
|
|
66251
66703
|
`${parsed.data.sourceSystem}:${externalId || email || phone || `${fullName}:${index}`}`
|
|
66252
66704
|
).digest("hex").slice(0, 16);
|
|
66253
66705
|
const path6 = `Leads/person-${digest2}`;
|
|
@@ -66688,13 +67140,13 @@ var init_analytics_delivery = __esm({
|
|
|
66688
67140
|
|
|
66689
67141
|
// src/api/scheduled-artifact-owner.ts
|
|
66690
67142
|
function scheduledArtifactOwnerIdForApiKey(apiKey) {
|
|
66691
|
-
return (0,
|
|
67143
|
+
return (0, import_node_crypto40.createHash)("sha256").update(apiKey).digest("hex").slice(0, 24);
|
|
66692
67144
|
}
|
|
66693
|
-
var
|
|
67145
|
+
var import_node_crypto40;
|
|
66694
67146
|
var init_scheduled_artifact_owner = __esm({
|
|
66695
67147
|
"src/api/scheduled-artifact-owner.ts"() {
|
|
66696
67148
|
"use strict";
|
|
66697
|
-
|
|
67149
|
+
import_node_crypto40 = require("crypto");
|
|
66698
67150
|
}
|
|
66699
67151
|
});
|
|
66700
67152
|
|
|
@@ -66751,7 +67203,7 @@ async function ensureScheduledRunViewLinksSchema() {
|
|
|
66751
67203
|
schemaReady3 = true;
|
|
66752
67204
|
}
|
|
66753
67205
|
function tokenHash2(token4) {
|
|
66754
|
-
return (0,
|
|
67206
|
+
return (0, import_node_crypto41.createHash)("sha256").update(token4).digest("hex");
|
|
66755
67207
|
}
|
|
66756
67208
|
function mapRow(row) {
|
|
66757
67209
|
return {
|
|
@@ -66771,9 +67223,9 @@ function mapRow(row) {
|
|
|
66771
67223
|
async function createScheduledRunViewLink(input) {
|
|
66772
67224
|
await ensureScheduledRunViewLinksSchema();
|
|
66773
67225
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
66774
|
-
const token4 = (0,
|
|
67226
|
+
const token4 = (0, import_node_crypto41.randomBytes)(32).toString("base64url");
|
|
66775
67227
|
const record = {
|
|
66776
|
-
shareId: (0,
|
|
67228
|
+
shareId: (0, import_node_crypto41.randomUUID)(),
|
|
66777
67229
|
ownerId: input.ownerId,
|
|
66778
67230
|
runId: input.runId,
|
|
66779
67231
|
artifactId: input.artifactId,
|
|
@@ -66836,11 +67288,11 @@ async function revokeScheduledRunViewLink(ownerId, runId, shareId, now = /* @__P
|
|
|
66836
67288
|
});
|
|
66837
67289
|
return result.rowsAffected > 0;
|
|
66838
67290
|
}
|
|
66839
|
-
var
|
|
67291
|
+
var import_node_crypto41, schemaReady3;
|
|
66840
67292
|
var init_scheduled_run_view_links = __esm({
|
|
66841
67293
|
"src/api/scheduled-run-view-links.ts"() {
|
|
66842
67294
|
"use strict";
|
|
66843
|
-
|
|
67295
|
+
import_node_crypto41 = require("crypto");
|
|
66844
67296
|
init_db();
|
|
66845
67297
|
schemaReady3 = false;
|
|
66846
67298
|
}
|
|
@@ -66906,15 +67358,15 @@ ${section(flags.finalCta && Boolean(finalCta), `<section class="section cta" id=
|
|
|
66906
67358
|
html,
|
|
66907
67359
|
filename: `${input.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "personal-authority"}.html`,
|
|
66908
67360
|
bytes,
|
|
66909
|
-
sha256: (0,
|
|
67361
|
+
sha256: (0, import_node_crypto42.createHash)("sha256").update(html).digest("hex"),
|
|
66910
67362
|
generatedAt: generatedAtIso
|
|
66911
67363
|
};
|
|
66912
67364
|
}
|
|
66913
|
-
var
|
|
67365
|
+
var import_node_crypto42;
|
|
66914
67366
|
var init_render2 = __esm({
|
|
66915
67367
|
"src/personal-authority/render.ts"() {
|
|
66916
67368
|
"use strict";
|
|
66917
|
-
|
|
67369
|
+
import_node_crypto42 = require("crypto");
|
|
66918
67370
|
}
|
|
66919
67371
|
});
|
|
66920
67372
|
|
|
@@ -67024,15 +67476,15 @@ body{overflow-x:hidden}.lead-story__body,.lead-support__item,.story-card__body{m
|
|
|
67024
67476
|
@media(max-width:620px){.desk-section__grid--panorama,.desk-section__grid--mosaic,.desk-section__grid--tiles{grid-template-columns:1fr}.story-card--panorama{display:block}.story-card--panorama h3,.story-card--mosaic-lead h3{font-size:34px}.story-card--mosaic-lead{grid-column:auto;grid-row:auto}.desk-section__grid--tiles>.story-card:nth-child(3n+2){margin-top:0}}
|
|
67025
67477
|
</style></head><body data-theme="${escapeHtml9(config.theme)}" id="top" data-scheduled-renderer="newsroom_publisher_v1">${ticker}${masthead}${navigation}<main>${leadGrid}${latest}${sections}${newsletter}${pressRoom}${trustCenter}</main>${trustFooter}</body></html>`;
|
|
67026
67478
|
const bytes = Buffer.byteLength(html);
|
|
67027
|
-
const sha2563 = (0,
|
|
67479
|
+
const sha2563 = (0, import_node_crypto43.createHash)("sha256").update(html).digest("hex");
|
|
67028
67480
|
const filename = `${brand.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "newsroom"}-news-site.html`;
|
|
67029
67481
|
return { html, filename, bytes, sha256: sha2563, generatedAt: generatedAtIso };
|
|
67030
67482
|
}
|
|
67031
|
-
var
|
|
67483
|
+
var import_node_crypto43;
|
|
67032
67484
|
var init_render3 = __esm({
|
|
67033
67485
|
"src/newsroom-publisher/render.ts"() {
|
|
67034
67486
|
"use strict";
|
|
67035
|
-
|
|
67487
|
+
import_node_crypto43 = require("crypto");
|
|
67036
67488
|
}
|
|
67037
67489
|
});
|
|
67038
67490
|
|
|
@@ -67325,7 +67777,7 @@ function policy4() {
|
|
|
67325
67777
|
};
|
|
67326
67778
|
}
|
|
67327
67779
|
function runStorageSegment(runId) {
|
|
67328
|
-
return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${(0,
|
|
67780
|
+
return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${(0, import_node_crypto44.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}`;
|
|
67329
67781
|
}
|
|
67330
67782
|
async function createScheduledRunArtifact(args) {
|
|
67331
67783
|
if (args.rendered.bytes > SCHEDULED_RUN_ARTIFACT_MAX_BYTES) {
|
|
@@ -67366,12 +67818,12 @@ async function readScheduledRunArtifact(args) {
|
|
|
67366
67818
|
if (!window2 || window2.nextOffset !== null || window2.totalBytes > SCHEDULED_RUN_ARTIFACT_MAX_BYTES) return null;
|
|
67367
67819
|
return window2.text;
|
|
67368
67820
|
}
|
|
67369
|
-
var
|
|
67821
|
+
var import_node_crypto44, SCHEDULED_RUN_ARTIFACT_PREFIX, SCHEDULED_RUN_ARTIFACT_DOWNLOAD_TTL_MS, SCHEDULED_RUN_ARTIFACT_MAX_BYTES;
|
|
67370
67822
|
var init_scheduled_run_artifact_store = __esm({
|
|
67371
67823
|
"src/scheduled-artifacts/scheduled-run-artifact-store.ts"() {
|
|
67372
67824
|
"use strict";
|
|
67373
67825
|
init_private_artifacts();
|
|
67374
|
-
|
|
67826
|
+
import_node_crypto44 = require("crypto");
|
|
67375
67827
|
SCHEDULED_RUN_ARTIFACT_PREFIX = "scheduled-run-artifacts/";
|
|
67376
67828
|
SCHEDULED_RUN_ARTIFACT_DOWNLOAD_TTL_MS = 15 * 60 * 1e3;
|
|
67377
67829
|
SCHEDULED_RUN_ARTIFACT_MAX_BYTES = 2e6;
|
|
@@ -67589,7 +68041,7 @@ async function reconcileDiscoveredNangoConnections(identity, discovered) {
|
|
|
67589
68041
|
updated_at = excluded.updated_at
|
|
67590
68042
|
`,
|
|
67591
68043
|
args: [
|
|
67592
|
-
(0,
|
|
68044
|
+
(0, import_node_crypto45.randomUUID)(),
|
|
67593
68045
|
userId,
|
|
67594
68046
|
connection.providerConfigKey,
|
|
67595
68047
|
connection.provider,
|
|
@@ -67660,7 +68112,7 @@ async function recordServiceConnectionHealth(args) {
|
|
|
67660
68112
|
});
|
|
67661
68113
|
await getDb().execute({
|
|
67662
68114
|
sql: `INSERT INTO service_connection_health_events (id, connection_id, operational_status, failure_code, retryable, evidence_source) VALUES (?, ?, ?, ?, ?, ?)`,
|
|
67663
|
-
args: [(0,
|
|
68115
|
+
args: [(0, import_node_crypto45.randomUUID)(), args.connectionId, args.operationalStatus, args.failureCode ?? null, args.retryable == null ? null : args.retryable ? 1 : 0, args.evidenceSource]
|
|
67664
68116
|
});
|
|
67665
68117
|
}
|
|
67666
68118
|
async function setServiceConnectionActions(identity, connectionId, enabled) {
|
|
@@ -67700,7 +68152,7 @@ async function claimServiceConnectionAction(args) {
|
|
|
67700
68152
|
if (!connection) throw new Error("service_connection_not_found");
|
|
67701
68153
|
const inserted = await getDb().execute({
|
|
67702
68154
|
sql: `INSERT OR IGNORE INTO service_connection_action_audit (id, connection_id, user_id, tool, request_id, status, request_digest) VALUES (?, ?, ?, ?, ?, 'started', ?)`,
|
|
67703
|
-
args: [(0,
|
|
68155
|
+
args: [(0, import_node_crypto45.randomUUID)(), connection.id, connection.userId, args.tool, args.requestId, args.requestDigest]
|
|
67704
68156
|
});
|
|
67705
68157
|
if (Number(inserted.rowsAffected ?? 0) === 1) return { claimed: true };
|
|
67706
68158
|
const existing = await getDb().execute({
|
|
@@ -67725,11 +68177,11 @@ async function claimServiceConnectionAction(args) {
|
|
|
67725
68177
|
...result !== void 0 ? { result } : {}
|
|
67726
68178
|
};
|
|
67727
68179
|
}
|
|
67728
|
-
var
|
|
68180
|
+
var import_node_crypto45, schemaReady4, schemaDb4;
|
|
67729
68181
|
var init_service_connections = __esm({
|
|
67730
68182
|
"src/api/service-connections.ts"() {
|
|
67731
68183
|
"use strict";
|
|
67732
|
-
|
|
68184
|
+
import_node_crypto45 = require("crypto");
|
|
67733
68185
|
init_db();
|
|
67734
68186
|
schemaReady4 = null;
|
|
67735
68187
|
schemaDb4 = null;
|
|
@@ -67743,8 +68195,8 @@ function signingSecret() {
|
|
|
67743
68195
|
return secret2;
|
|
67744
68196
|
}
|
|
67745
68197
|
function schedulerIntegrationSignature(args) {
|
|
67746
|
-
const bodyHash = (0,
|
|
67747
|
-
return (0,
|
|
68198
|
+
const bodyHash = (0, import_node_crypto46.createHash)("sha256").update(args.body).digest("hex");
|
|
68199
|
+
return (0, import_node_crypto46.createHmac)("sha256", args.secret).update(`${args.method.toUpperCase()}
|
|
67748
68200
|
${args.path}
|
|
67749
68201
|
${args.timestamp}
|
|
67750
68202
|
${args.nonce}
|
|
@@ -67791,17 +68243,17 @@ async function verifySchedulerIntegrationRequest(request, rawBody) {
|
|
|
67791
68243
|
});
|
|
67792
68244
|
const suppliedBytes = Buffer.from(signature, "hex");
|
|
67793
68245
|
const expectedBytes = Buffer.from(expected, "hex");
|
|
67794
|
-
if (suppliedBytes.length !== expectedBytes.length || !(0,
|
|
68246
|
+
if (suppliedBytes.length !== expectedBytes.length || !(0, import_node_crypto46.timingSafeEqual)(suppliedBytes, expectedBytes)) {
|
|
67795
68247
|
throw new SchedulerIntegrationAuthError("invalid_signature");
|
|
67796
68248
|
}
|
|
67797
68249
|
await claimNonce(nonce, timestampMs);
|
|
67798
68250
|
return { requestId };
|
|
67799
68251
|
}
|
|
67800
|
-
var
|
|
68252
|
+
var import_node_crypto46, MAX_CLOCK_SKEW_MS, SchedulerIntegrationAuthError;
|
|
67801
68253
|
var init_scheduler_integration_auth = __esm({
|
|
67802
68254
|
"src/api/scheduler-integration-auth.ts"() {
|
|
67803
68255
|
"use strict";
|
|
67804
|
-
|
|
68256
|
+
import_node_crypto46 = require("crypto");
|
|
67805
68257
|
init_db();
|
|
67806
68258
|
init_service_connections();
|
|
67807
68259
|
MAX_CLOCK_SKEW_MS = 5 * 60 * 1e3;
|
|
@@ -68049,7 +68501,7 @@ var init_site_extract_reconciliation = __esm({
|
|
|
68049
68501
|
|
|
68050
68502
|
// src/api/page-diff.ts
|
|
68051
68503
|
function sha256Hex(value) {
|
|
68052
|
-
return (0,
|
|
68504
|
+
return (0, import_node_crypto47.createHash)("sha256").update(value).digest("hex");
|
|
68053
68505
|
}
|
|
68054
68506
|
function truncateForStorage(value, maxChars = MAX_SNAPSHOT_CONTENT_CHARS) {
|
|
68055
68507
|
if (value.length <= maxChars) return { value, truncated: false };
|
|
@@ -68106,11 +68558,11 @@ function diffPageContent(oldContent, newContent) {
|
|
|
68106
68558
|
totalChangedLineCount
|
|
68107
68559
|
};
|
|
68108
68560
|
}
|
|
68109
|
-
var
|
|
68561
|
+
var import_node_crypto47, import_diff, MAX_SNAPSHOT_CONTENT_CHARS, MAX_DIFF_HUNKS, MAX_DIFF_LINES_PER_RESPONSE;
|
|
68110
68562
|
var init_page_diff = __esm({
|
|
68111
68563
|
"src/api/page-diff.ts"() {
|
|
68112
68564
|
"use strict";
|
|
68113
|
-
|
|
68565
|
+
import_node_crypto47 = require("crypto");
|
|
68114
68566
|
import_diff = require("diff");
|
|
68115
68567
|
MAX_SNAPSHOT_CONTENT_CHARS = 25e4;
|
|
68116
68568
|
MAX_DIFF_HUNKS = 200;
|
|
@@ -68184,7 +68636,7 @@ var init_scrape_vault_sink = __esm({
|
|
|
68184
68636
|
|
|
68185
68637
|
// src/api/scrape-image-sink.ts
|
|
68186
68638
|
function idempotencyKey2(userId, vault, input) {
|
|
68187
|
-
return `scrape-image-${(0,
|
|
68639
|
+
return `scrape-image-${(0, import_node_crypto48.createHash)("sha256").update(`${userId}\0${vault}\0${input.sourceKind}\0${input.sourceUrl}\0${input.imageUrl ?? ""}\0${input.imageBase64 ?? ""}`).digest("hex")}`;
|
|
68188
68640
|
}
|
|
68189
68641
|
async function persistScrapeImagesToMemory(user, inputs, vault) {
|
|
68190
68642
|
const selected = inputs.slice(0, MAX_IMAGES_PER_SCRAPE);
|
|
@@ -68226,11 +68678,11 @@ async function persistScrapeImagesToMemory(user, inputs, vault) {
|
|
|
68226
68678
|
assets
|
|
68227
68679
|
};
|
|
68228
68680
|
}
|
|
68229
|
-
var
|
|
68681
|
+
var import_node_crypto48, MAX_IMAGES_PER_SCRAPE;
|
|
68230
68682
|
var init_scrape_image_sink = __esm({
|
|
68231
68683
|
"src/api/scrape-image-sink.ts"() {
|
|
68232
68684
|
"use strict";
|
|
68233
|
-
|
|
68685
|
+
import_node_crypto48 = require("crypto");
|
|
68234
68686
|
init_memory();
|
|
68235
68687
|
MAX_IMAGES_PER_SCRAPE = 25;
|
|
68236
68688
|
}
|
|
@@ -68683,7 +69135,7 @@ function canonicalJson(value) {
|
|
|
68683
69135
|
return JSON.stringify(value);
|
|
68684
69136
|
}
|
|
68685
69137
|
function sha2562(value) {
|
|
68686
|
-
return (0,
|
|
69138
|
+
return (0, import_node_crypto49.createHash)("sha256").update(value).digest("hex");
|
|
68687
69139
|
}
|
|
68688
69140
|
function sensitiveKey(key) {
|
|
68689
69141
|
const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
@@ -68898,11 +69350,11 @@ async function importServiceConnectionToMemory(identity, input, dependencies) {
|
|
|
68898
69350
|
...!searchReady ? { warning: "The snapshot was stored, but no search chunks were indexed yet." } : {}
|
|
68899
69351
|
};
|
|
68900
69352
|
}
|
|
68901
|
-
var
|
|
69353
|
+
var import_node_crypto49, CONNECTION_MEMORY_IMPORT_MAX_ARGS_BYTES, CONNECTION_MEMORY_IMPORT_MAX_RESULT_BYTES, CONNECTION_MEMORY_IMPORT_MAX_STRING_CHARS, CONNECTION_MEMORY_IMPORT_MAX_DEPTH, ConnectionMemoryImportError;
|
|
68902
69354
|
var init_connection_memory_import = __esm({
|
|
68903
69355
|
"src/api/connection-memory-import.ts"() {
|
|
68904
69356
|
"use strict";
|
|
68905
|
-
|
|
69357
|
+
import_node_crypto49 = require("crypto");
|
|
68906
69358
|
init_slugify();
|
|
68907
69359
|
CONNECTION_MEMORY_IMPORT_MAX_ARGS_BYTES = 64 * 1024;
|
|
68908
69360
|
CONNECTION_MEMORY_IMPORT_MAX_RESULT_BYTES = 1e6;
|
|
@@ -69120,7 +69572,7 @@ function finitePositive(value, fallback) {
|
|
|
69120
69572
|
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
69121
69573
|
}
|
|
69122
69574
|
async function collectConnectedDataExport(args) {
|
|
69123
|
-
const exportId = (0,
|
|
69575
|
+
const exportId = (0, import_node_crypto50.randomUUID)();
|
|
69124
69576
|
const now = args.now ?? Date.now;
|
|
69125
69577
|
const startedAt = now();
|
|
69126
69578
|
const budgetMs = finitePositive(CONNECTED_DATA_EXPORT_BUDGET_MS, 24e4);
|
|
@@ -69234,11 +69686,11 @@ ${lines.length ? `${lines.join("\n")}
|
|
|
69234
69686
|
untrustedContent: true
|
|
69235
69687
|
};
|
|
69236
69688
|
}
|
|
69237
|
-
var
|
|
69689
|
+
var import_node_crypto50, CONNECTED_DATA_INLINE_BUDGET_BYTES, CONNECTED_DATA_MAX_EXPORT_BYTES, CONNECTED_DATA_EXPORT_BUDGET_MS, CONNECTED_DATA_PAGE_START_HEADROOM_MS, CONNECTED_DATA_DATASETS, ConnectedDataExportValidationError;
|
|
69238
69690
|
var init_connected_data_export = __esm({
|
|
69239
69691
|
"src/api/connected-data-export.ts"() {
|
|
69240
69692
|
"use strict";
|
|
69241
|
-
|
|
69693
|
+
import_node_crypto50 = require("crypto");
|
|
69242
69694
|
CONNECTED_DATA_INLINE_BUDGET_BYTES = Number(
|
|
69243
69695
|
process.env.MCP_SCRAPER_CONNECTED_DATA_INLINE_BUDGET_BYTES ?? 5e4
|
|
69244
69696
|
);
|
|
@@ -69352,7 +69804,7 @@ async function exportSearchConsoleTableData(args) {
|
|
|
69352
69804
|
offset += rows.length;
|
|
69353
69805
|
if (stoppedForBytes || rows.length < limit || offset >= matchedRows) break;
|
|
69354
69806
|
}
|
|
69355
|
-
const exportId = (0,
|
|
69807
|
+
const exportId = (0, import_node_crypto51.randomUUID)();
|
|
69356
69808
|
const artifact = await args.writeArtifact({
|
|
69357
69809
|
ownerId: args.ownerId,
|
|
69358
69810
|
exportId,
|
|
@@ -69374,11 +69826,11 @@ async function exportSearchConsoleTableData(args) {
|
|
|
69374
69826
|
warnings
|
|
69375
69827
|
};
|
|
69376
69828
|
}
|
|
69377
|
-
var
|
|
69829
|
+
var import_node_crypto51, SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS, SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE, SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES, SEARCH_CONSOLE_TABLE_COLUMNS, SearchConsoleTableExportValidationError;
|
|
69378
69830
|
var init_search_console_table_export = __esm({
|
|
69379
69831
|
"src/api/search-console-table-export.ts"() {
|
|
69380
69832
|
"use strict";
|
|
69381
|
-
|
|
69833
|
+
import_node_crypto51 = require("crypto");
|
|
69382
69834
|
SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS = 5e4;
|
|
69383
69835
|
SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE = 2e3;
|
|
69384
69836
|
SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES = 50 * 1024 * 1024;
|
|
@@ -70557,7 +71009,7 @@ async function listNangoToolsDirect(identity, connectionId) {
|
|
|
70557
71009
|
});
|
|
70558
71010
|
const readTools = [...policies.values()].filter((policy5) => policy5.classification === "read").map((policy5) => policy5.name);
|
|
70559
71011
|
const actionTools = [...policies.values()].filter((policy5) => policy5.classification === "action").map((policy5) => policy5.name);
|
|
70560
|
-
const revision = (0,
|
|
71012
|
+
const revision = (0, import_node_crypto52.createHash)("sha256").update(JSON.stringify(tools.map((tool) => ({ name: tool.name, inputSchema: tool.inputSchema })))).digest("hex");
|
|
70561
71013
|
await updateServiceConnectionTools(connection.id, readTools, actionTools, revision);
|
|
70562
71014
|
const refreshed = await getOwnedServiceConnection(identity, connection.id);
|
|
70563
71015
|
return { connection: refreshed ?? { ...connection, readTools, actionTools, toolRevision: revision }, tools };
|
|
@@ -70584,8 +71036,8 @@ async function callNangoToolDirect(args) {
|
|
|
70584
71036
|
identity: args.identity,
|
|
70585
71037
|
ratePolicyVersion: CONNECTED_USAGE_RATE_POLICY_VERSION
|
|
70586
71038
|
});
|
|
70587
|
-
const requestId = args.requestId?.trim() || (0,
|
|
70588
|
-
const idempotencyKey3 = `main-nango:${(0,
|
|
71039
|
+
const requestId = args.requestId?.trim() || (0, import_node_crypto52.randomUUID)();
|
|
71040
|
+
const idempotencyKey3 = `main-nango:${(0, import_node_crypto52.createHash)("sha256").update(args.identity.toLowerCase()).update("\0").update(connection.id).update("\0").update(args.tool).update("\0").update(requestId).digest("hex")}`;
|
|
70589
71041
|
const startedAt = /* @__PURE__ */ new Date();
|
|
70590
71042
|
const started = performance.now();
|
|
70591
71043
|
let result;
|
|
@@ -70610,7 +71062,7 @@ async function callNangoToolDirect(args) {
|
|
|
70610
71062
|
toolName: args.tool,
|
|
70611
71063
|
operationKind: args.operationKind ?? args.classification,
|
|
70612
71064
|
outcome: providerError ? "error" : "partial",
|
|
70613
|
-
requestId: requestId.length <= 200 ? requestId : (0,
|
|
71065
|
+
requestId: requestId.length <= 200 ? requestId : (0, import_node_crypto52.createHash)("sha256").update(requestId).digest("hex"),
|
|
70614
71066
|
startedAt: startedAt.toISOString(),
|
|
70615
71067
|
completedAt: completedAt.toISOString()
|
|
70616
71068
|
}
|
|
@@ -70652,15 +71104,15 @@ async function describeNangoToolDirect(identity, connectionId, toolName) {
|
|
|
70652
71104
|
providerContractHash: MAIN_INTEGRATION_CONTRACT_HASH,
|
|
70653
71105
|
protocolVersion: null,
|
|
70654
71106
|
schemaSource: "live_tools_list",
|
|
70655
|
-
schemaHash: (0,
|
|
71107
|
+
schemaHash: (0, import_node_crypto52.createHash)("sha256").update(JSON.stringify(projected)).digest("hex"),
|
|
70656
71108
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
70657
71109
|
};
|
|
70658
71110
|
}
|
|
70659
|
-
var
|
|
71111
|
+
var import_node_crypto52, import_client13, DEFAULT_NANGO_MCP_URL, NANGO_TIMEOUT_MS, NANGO_CONNECTION_PAGE_SIZE, NANGO_CONNECTION_MAX_PAGES, MAIN_INTEGRATION_CONTRACT_VERSION, MAIN_INTEGRATION_CONTRACT_HASH, MainNangoTransportError;
|
|
70660
71112
|
var init_main_nango_transport = __esm({
|
|
70661
71113
|
"src/api/main-nango-transport.ts"() {
|
|
70662
71114
|
"use strict";
|
|
70663
|
-
|
|
71115
|
+
import_node_crypto52 = require("crypto");
|
|
70664
71116
|
import_client13 = require("@modelcontextprotocol/client");
|
|
70665
71117
|
init_service_connections();
|
|
70666
71118
|
init_connected_usage_billing();
|
|
@@ -71284,8 +71736,8 @@ async function setScheduleConnectionActionsEnabled(identity, connectionId, enabl
|
|
|
71284
71736
|
return data.connection.actionsEnabled === true;
|
|
71285
71737
|
}
|
|
71286
71738
|
async function callScheduleConnectionAction(identity, connectionId, input, tool, idempotencyKey3) {
|
|
71287
|
-
const requestId = `main-connected-action:${(0,
|
|
71288
|
-
const requestDigest = (0,
|
|
71739
|
+
const requestId = `main-connected-action:${(0, import_node_crypto53.createHash)("sha256").update(identity).update("\0").update(idempotencyKey3?.trim() || (0, import_node_crypto53.randomUUID)()).digest("hex")}`;
|
|
71740
|
+
const requestDigest = (0, import_node_crypto53.createHash)("sha256").update(connectionId).update("\0").update(tool?.trim() ?? "").update("\0").update(canonicalJson2(input)).digest("hex");
|
|
71289
71741
|
if (mainOwnsIntegrations()) {
|
|
71290
71742
|
const selectedTool = tool?.trim();
|
|
71291
71743
|
if (!selectedTool) throw new NangoControlError("An action tool is required.", 400, "invalid_request", false);
|
|
@@ -71436,7 +71888,7 @@ function canonicalJson2(value) {
|
|
|
71436
71888
|
return JSON.stringify(value);
|
|
71437
71889
|
}
|
|
71438
71890
|
function projectedToolSchemaHash(tool) {
|
|
71439
|
-
return (0,
|
|
71891
|
+
return (0, import_node_crypto53.createHash)("sha256").update(canonicalJson2(tool)).digest("hex");
|
|
71440
71892
|
}
|
|
71441
71893
|
async function describeNangoTool(identity, connectionId, tool, fresh) {
|
|
71442
71894
|
if (mainOwnsIntegrations()) {
|
|
@@ -71713,11 +72165,11 @@ async function callMainOwnedExportPage(identity, input) {
|
|
|
71713
72165
|
untrustedContent: true
|
|
71714
72166
|
};
|
|
71715
72167
|
}
|
|
71716
|
-
var
|
|
72168
|
+
var import_node_crypto53, DEFAULT_NANGO_CONTROL_URL, DISABLED_NANGO_TOOLS, CONNECTION_SYNC_REQUIRED_TOOLS, CONNECTION_SYNC_OPTIONAL_TOOLS, NangoControlError, ScheduleConnectionValidationError, SAFE_CONTROL_ERROR_CODES, FIXED_CONTROL_ERROR_MESSAGES, CONTROL_ERROR_CODE_ALIASES;
|
|
71717
72169
|
var init_nango_control = __esm({
|
|
71718
72170
|
"src/api/nango-control.ts"() {
|
|
71719
72171
|
"use strict";
|
|
71720
|
-
|
|
72172
|
+
import_node_crypto53 = require("crypto");
|
|
71721
72173
|
init_connected_data_export();
|
|
71722
72174
|
init_slack_connected_data_export();
|
|
71723
72175
|
init_main_nango_transport();
|
|
@@ -72073,7 +72525,7 @@ async function callResendRead(identity, connectionId, tool, args) {
|
|
|
72073
72525
|
return isRecord5(data) ? data.result ?? data : data;
|
|
72074
72526
|
}
|
|
72075
72527
|
async function callResendAction(identity, connectionId, tool, input, idempotencyKey3) {
|
|
72076
|
-
const requestId = `main-resend-action:${(0,
|
|
72528
|
+
const requestId = `main-resend-action:${(0, import_node_crypto54.createHash)("sha256").update(identity).update("\0").update(idempotencyKey3.trim()).digest("hex")}`;
|
|
72077
72529
|
const body = await controlRequest2("/api/internal/resend/actions/call", {
|
|
72078
72530
|
method: "POST",
|
|
72079
72531
|
headers: { "x-request-id": requestId },
|
|
@@ -72138,12 +72590,12 @@ async function callResendExportPage(identity, input) {
|
|
|
72138
72590
|
untrustedContent: true
|
|
72139
72591
|
};
|
|
72140
72592
|
}
|
|
72141
|
-
var
|
|
72593
|
+
var import_node_crypto54, DEFAULT_CONNECTION_CONTROL_URL, RESEND_PROVIDER_CONFIG_KEY, RESEND_LOGO_URL, RESEND_DOCS_URL, RESEND_ADMIN_BLOCKED_TOOLS, RESEND_CONNECTION_SYNC_REQUIRED_TOOLS, ResendControlError;
|
|
72142
72594
|
var init_resend_control = __esm({
|
|
72143
72595
|
"src/api/resend-control.ts"() {
|
|
72144
72596
|
"use strict";
|
|
72145
72597
|
init_connected_data_export();
|
|
72146
|
-
|
|
72598
|
+
import_node_crypto54 = require("crypto");
|
|
72147
72599
|
DEFAULT_CONNECTION_CONTROL_URL = "https://mcp-scraper-scheduler.vercel.app";
|
|
72148
72600
|
RESEND_PROVIDER_CONFIG_KEY = "resend";
|
|
72149
72601
|
RESEND_LOGO_URL = "https://cdn.resend.com/brand/resend-icon-black.svg";
|
|
@@ -72661,7 +73113,7 @@ async function chargeTierChangeNow(stripeClient, subscriptionId, customerId) {
|
|
|
72661
73113
|
return { ok: false, amountDue: 0, error: err instanceof Error ? err.message : "Unable to charge the plan change immediately." };
|
|
72662
73114
|
}
|
|
72663
73115
|
}
|
|
72664
|
-
var import_resend3,
|
|
73116
|
+
var import_resend3, import_node_crypto55, import_hono36, import_hono37, import_factory8, import_cookie2, import_stripe2, secureCookies2, isProduction2, sessionCookieOptions2, requireAllowedOrigin, auth4, sessionAuth, requireIntegrationsTier, requirePaidSchedulingTier, app, deploymentProfile, STRIPE_API_VERSION, SYNC_HARVEST_TIMEOUT_OVERRIDE_MS;
|
|
72665
73117
|
var init_server = __esm({
|
|
72666
73118
|
"src/api/server.ts"() {
|
|
72667
73119
|
"use strict";
|
|
@@ -72674,7 +73126,7 @@ var init_server = __esm({
|
|
|
72674
73126
|
init_og();
|
|
72675
73127
|
import_resend3 = require("resend");
|
|
72676
73128
|
init_url_utils();
|
|
72677
|
-
|
|
73129
|
+
import_node_crypto55 = require("crypto");
|
|
72678
73130
|
init_kpo_extractor();
|
|
72679
73131
|
init_screenshot();
|
|
72680
73132
|
init_media_extractor();
|
|
@@ -74209,7 +74661,7 @@ var init_server = __esm({
|
|
|
74209
74661
|
if (!harvestOk) return c.json(insufficientBalanceResponse(harvestBal, harvestCost), 402);
|
|
74210
74662
|
jobId2 = await createJob(user.id, options.query, { ...options, billingHoldMc: harvestCost }, body.callback_url);
|
|
74211
74663
|
} else {
|
|
74212
|
-
jobId2 = (0,
|
|
74664
|
+
jobId2 = (0, import_node_crypto55.randomUUID)();
|
|
74213
74665
|
const billingDebitKey = `paa-harvest:${jobId2}:hold`;
|
|
74214
74666
|
const description = `PAA harvest: ${options.query}`.slice(0, 500);
|
|
74215
74667
|
const hold = await debitMcIdempotent(
|