mcp-scraper 0.45.0 → 0.46.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 +6 -2
- package/dist/bin/api-server.cjs +695 -64
- 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 -2
- 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 +103 -2
- package/dist/bin/mcp-stdio-server.cjs.map +1 -1
- package/dist/bin/mcp-stdio-server.js +3 -3
- package/dist/{chunk-FQIICRR4.js → chunk-BP2IUIAH.js} +106 -2
- package/dist/chunk-BP2IUIAH.js.map +1 -0
- package/dist/{chunk-GRODXRUY.js → chunk-QSUGPYGQ.js} +3 -2
- package/dist/chunk-QSUGPYGQ.js.map +1 -0
- package/dist/chunk-TQKQK7OV.js +7 -0
- package/dist/chunk-TQKQK7OV.js.map +1 -0
- package/dist/{server-7B75SDNG.js → server-SMEHT3OU.js} +565 -41
- package/dist/server-SMEHT3OU.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-CEZ3NFBP.js +0 -7
- package/dist/chunk-CEZ3NFBP.js.map +0 -1
- package/dist/chunk-FQIICRR4.js.map +0 -1
- package/dist/chunk-GRODXRUY.js.map +0 -1
- package/dist/server-7B75SDNG.js.map +0 -1
package/dist/bin/api-server.cjs
CHANGED
|
@@ -33664,7 +33664,7 @@ async function extractAISurfacesFromDocument(config) {
|
|
|
33664
33664
|
}
|
|
33665
33665
|
return null;
|
|
33666
33666
|
}
|
|
33667
|
-
function
|
|
33667
|
+
function cleanText2(target) {
|
|
33668
33668
|
if (!target) return null;
|
|
33669
33669
|
const clone = target.cloneNode(true);
|
|
33670
33670
|
clone.querySelectorAll([
|
|
@@ -33791,14 +33791,14 @@ async function extractAISurfacesFromDocument(config) {
|
|
|
33791
33791
|
const contentSubtree = aioRoot.querySelector(selectors.aio.contentSubtree);
|
|
33792
33792
|
const showMore = aioRoot.querySelector(selectors.aio.showMoreButton);
|
|
33793
33793
|
aioFullyExpanded = controller?.getAttribute("data-trnct") === "false" || showMore?.getAttribute("aria-expanded") === "true" || !showMore;
|
|
33794
|
-
aioText =
|
|
33794
|
+
aioText = cleanText2(contentSubtree ?? controller ?? aioRoot);
|
|
33795
33795
|
aioSections = (aioText ?? "").split("\n").map((line) => line.trim()).filter((line) => /^\d+\.\s+.+/.test(line));
|
|
33796
33796
|
aioCitations = extractCitations(aioRoot);
|
|
33797
33797
|
}
|
|
33798
33798
|
const aimRoot = document.querySelector(selectors.aim.root);
|
|
33799
33799
|
const aimRootDetected = surface === "aim" && !!aimRoot;
|
|
33800
33800
|
const aimContainer = aimRoot?.closest(selectors.aim.wrapper) ?? aimRoot;
|
|
33801
|
-
const rawAimText = aimRootDetected ?
|
|
33801
|
+
const rawAimText = aimRootDetected ? cleanText2(aimContainer) : null;
|
|
33802
33802
|
const aimDetected = aimRootDetected && hasSubstantiveContent(rawAimText);
|
|
33803
33803
|
const aimText = aimDetected ? rawAimText : null;
|
|
33804
33804
|
const aimCitations = aimDetected ? extractCitations(aimContainer) : [];
|
|
@@ -33872,7 +33872,7 @@ var init_PAAExtractor = __esm({
|
|
|
33872
33872
|
async extractVisibleItems(page) {
|
|
33873
33873
|
const sels = PAASelectors;
|
|
33874
33874
|
const raw = await page.evaluate((selectors) => {
|
|
33875
|
-
function
|
|
33875
|
+
function cleanText2(el2) {
|
|
33876
33876
|
if (!el2) return "";
|
|
33877
33877
|
const parts = [];
|
|
33878
33878
|
for (const n of el2.childNodes) {
|
|
@@ -33882,7 +33882,7 @@ var init_PAAExtractor = __esm({
|
|
|
33882
33882
|
} else if (n.tagName === "STYLE" || n.tagName === "SCRIPT") {
|
|
33883
33883
|
continue;
|
|
33884
33884
|
} else {
|
|
33885
|
-
const text2 =
|
|
33885
|
+
const text2 = cleanText2(n);
|
|
33886
33886
|
if (text2) parts.push(text2);
|
|
33887
33887
|
}
|
|
33888
33888
|
}
|
|
@@ -33936,7 +33936,7 @@ var init_PAAExtractor = __esm({
|
|
|
33936
33936
|
}
|
|
33937
33937
|
return {
|
|
33938
33938
|
question: pair.getAttribute(selectors.itemDataQ) || pair.getAttribute(selectors.itemDataInitQ) || pair.querySelector(selectors.itemQuestionEl)?.innerText?.trim() || "",
|
|
33939
|
-
answer:
|
|
33939
|
+
answer: cleanText2(answerElement) || void 0,
|
|
33940
33940
|
sourceTitle,
|
|
33941
33941
|
sourceSite,
|
|
33942
33942
|
sourceCite
|
|
@@ -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.46.0";
|
|
41375
41375
|
}
|
|
41376
41376
|
});
|
|
41377
41377
|
|
|
@@ -41454,6 +41454,18 @@ seam is noted so you can chain them.
|
|
|
41454
41454
|
Use saved filters when a person wants their MCP to operate inside a reading room, trail, source scope,
|
|
41455
41455
|
category, tag bundle, media constraint, or other personalized subset of the shared Commons graph.
|
|
41456
41456
|
|
|
41457
|
+
## Transparent Commons user publications
|
|
41458
|
+
- A user-owned editorial publication is separate from the neutral public wiki. Start with
|
|
41459
|
+
**commons_prepare_publication** to normalize the requested subdomain, check availability, and read the live
|
|
41460
|
+
ownership contract. Then call **commons_validate_publication** with operation \`claim\` before
|
|
41461
|
+
**commons_claim_publication**.
|
|
41462
|
+
- Each account may claim one stable name at \`https://{name}.transparent-commons.cc\`. Claims require an
|
|
41463
|
+
idempotency key and never publish content by themselves.
|
|
41464
|
+
- To publish, use **editorial_reading_room_guide** when needed, research and author the complete source-grounded
|
|
41465
|
+
edition, validate it with **commons_validate_publication** operation \`publish\`, then call
|
|
41466
|
+
**commons_publish_editorial**. The publish result returns the permanent publication, archive, and edition URLs.
|
|
41467
|
+
- Use **commons_get_publication** to recover the caller's publication and current edition revisions. Existing
|
|
41468
|
+
edition edits require the returned baseRevision. Only the account that claimed the subdomain can publish to it.
|
|
41457
41469
|
|
|
41458
41470
|
## Google Maps
|
|
41459
41471
|
- Find multiple places/competitors/prospects -> **maps_search** (returns \`results[]\` with name,
|
|
@@ -42175,7 +42187,7 @@ var init_contracts = __esm({
|
|
|
42175
42187
|
});
|
|
42176
42188
|
|
|
42177
42189
|
// src/mcp/mcp-tool-schemas.ts
|
|
42178
|
-
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, 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;
|
|
42190
|
+
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;
|
|
42179
42191
|
var init_mcp_tool_schemas = __esm({
|
|
42180
42192
|
"src/mcp/mcp-tool-schemas.ts"() {
|
|
42181
42193
|
"use strict";
|
|
@@ -42794,6 +42806,37 @@ var init_mcp_tool_schemas = __esm({
|
|
|
42794
42806
|
downloadUrlExpiresAt: import_zod42.z.string(),
|
|
42795
42807
|
expiresAt: import_zod42.z.string()
|
|
42796
42808
|
};
|
|
42809
|
+
CommonsPublicationSubdomainSchema = import_zod42.z.string().trim().min(3).max(50).describe("Requested publication name under transparent-commons.cc. The server normalizes spaces to hyphens, rejects reserved names, and enforces one globally unique name per account.");
|
|
42810
|
+
CommonsPreparePublicationInputSchema = {
|
|
42811
|
+
requestedSubdomain: CommonsPublicationSubdomainSchema,
|
|
42812
|
+
title: import_zod42.z.string().trim().min(1).max(140).optional().describe("Reader-facing publication title. Omit to derive it from the chosen subdomain."),
|
|
42813
|
+
description: import_zod42.z.string().trim().max(500).optional().describe("Short description used on the publication archive and discovery surfaces.")
|
|
42814
|
+
};
|
|
42815
|
+
CommonsValidatePublicationInputSchema = {
|
|
42816
|
+
operation: import_zod42.z.enum(["claim", "publish"]).describe("Validate either a new name claim or a finished editorial edition without writing."),
|
|
42817
|
+
requestedSubdomain: CommonsPublicationSubdomainSchema.optional().describe("Publication name to validate when operation is claim."),
|
|
42818
|
+
publicationSubdomain: CommonsPublicationSubdomainSchema.optional().describe("Already claimed publication name to validate when operation is publish."),
|
|
42819
|
+
title: import_zod42.z.string().trim().min(1).max(140).optional(),
|
|
42820
|
+
description: import_zod42.z.string().trim().max(500).optional(),
|
|
42821
|
+
edition: import_zod42.z.object(CreateEditorialReadingRoomInputSchema).strict().optional().describe("Complete source-grounded reading-room payload to validate when operation is publish."),
|
|
42822
|
+
editionSlug: import_zod42.z.string().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(80).optional().describe("Stable public edition slug. Defaults to edition.site.slug."),
|
|
42823
|
+
baseRevision: import_zod42.z.number().int().positive().optional().describe("Current edition revision when validating an edit.")
|
|
42824
|
+
};
|
|
42825
|
+
CommonsClaimPublicationInputSchema = {
|
|
42826
|
+
...CommonsPreparePublicationInputSchema,
|
|
42827
|
+
idempotencyKey: import_zod42.z.string().trim().min(8).max(200).describe("Unique key for this intended claim. Reuse it only when retrying the same claim.")
|
|
42828
|
+
};
|
|
42829
|
+
CommonsPublishEditorialInputSchema = {
|
|
42830
|
+
publicationSubdomain: CommonsPublicationSubdomainSchema.describe("Publication owned by the authenticated account."),
|
|
42831
|
+
editionSlug: import_zod42.z.string().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(80).optional().describe("Stable public edition slug. Defaults to site.slug."),
|
|
42832
|
+
idempotencyKey: import_zod42.z.string().trim().min(8).max(200).describe("Unique key for this intended publish. Reuse it only when retrying the same revision."),
|
|
42833
|
+
baseRevision: import_zod42.z.number().int().positive().optional().describe("Required when revising an existing edition; use the current revision from commons_get_publication."),
|
|
42834
|
+
...CreateEditorialReadingRoomInputSchema
|
|
42835
|
+
};
|
|
42836
|
+
CommonsGetPublicationInputSchema = {
|
|
42837
|
+
subdomain: CommonsPublicationSubdomainSchema.optional().describe("Public publication name to inspect. Omit to return the publication owned by the authenticated account."),
|
|
42838
|
+
includeEditions: import_zod42.z.boolean().default(true).describe("Include the latest revision of every published edition.")
|
|
42839
|
+
};
|
|
42797
42840
|
RankTrackerModeSchema = import_zod42.z.enum(["maps", "organic", "ai_overview", "paa"]);
|
|
42798
42841
|
RankTrackerBlueprintInputSchema = {
|
|
42799
42842
|
projectName: import_zod42.z.string().min(1).optional().describe("Optional name for the rank tracker project, client, or campaign."),
|
|
@@ -45614,6 +45657,41 @@ function registerPaaExtractorMcpTools(server, executor, options = {}) {
|
|
|
45614
45657
|
openWorldHint: false
|
|
45615
45658
|
}
|
|
45616
45659
|
}, async (input) => executor.commonsListFilters(input));
|
|
45660
|
+
server.registerTool("commons_prepare_publication", {
|
|
45661
|
+
title: "Prepare Transparent Commons Publication",
|
|
45662
|
+
description: "Check and normalize a subscriber-chosen Transparent Commons publication name before any write. Returns name availability, the caller's existing publication, permanent URL shape, ownership rules, and the required validate/claim/publish workflow. This is for a user-owned editorial publication, not a neutral /wiki/ entity.",
|
|
45663
|
+
inputSchema: CommonsPreparePublicationInputSchema,
|
|
45664
|
+
outputSchema: recordOutputSchema("commons_prepare_publication", CommonsGenericOutputSchema),
|
|
45665
|
+
annotations: { title: "Prepare Transparent Commons Publication", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
|
|
45666
|
+
}, async (input) => executor.commonsPreparePublication(input));
|
|
45667
|
+
server.registerTool("commons_validate_publication", {
|
|
45668
|
+
title: "Validate Transparent Commons Publication",
|
|
45669
|
+
description: "Validate a publication name claim or a complete source-grounded editorial edition without writing. Use operation claim before commons_claim_publication and operation publish before commons_publish_editorial. This uses the editorial reading-room contract and checks ownership plus revision conflicts.",
|
|
45670
|
+
inputSchema: CommonsValidatePublicationInputSchema,
|
|
45671
|
+
outputSchema: recordOutputSchema("commons_validate_publication", CommonsGenericOutputSchema),
|
|
45672
|
+
annotations: { title: "Validate Transparent Commons Publication", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
|
|
45673
|
+
}, async (input) => executor.commonsValidatePublication(input));
|
|
45674
|
+
server.registerTool("commons_claim_publication", {
|
|
45675
|
+
title: "Claim Transparent Commons Publication",
|
|
45676
|
+
description: "Permanently claim one globally unique publication subdomain for the authenticated MCP Scraper account. Call commons_prepare_publication and commons_validate_publication first. This creates public identity state but does not publish an edition. Requires an idempotencyKey; retries with the same intended claim are safe.",
|
|
45677
|
+
inputSchema: CommonsClaimPublicationInputSchema,
|
|
45678
|
+
outputSchema: recordOutputSchema("commons_claim_publication", CommonsGenericOutputSchema),
|
|
45679
|
+
annotations: { title: "Claim Transparent Commons Publication", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true }
|
|
45680
|
+
}, async (input) => executor.commonsClaimPublication(input));
|
|
45681
|
+
server.registerTool("commons_publish_editorial", {
|
|
45682
|
+
title: "Publish Transparent Commons Editorial Edition",
|
|
45683
|
+
description: "Publish a fully authored editorial reading-room edition to the caller-owned Transparent Commons subdomain and return permanent root, archive, and edition URLs. The calling AI must research and author the source-grounded edition first; this tool validates, renders, and persists it. For an existing edition, pass its current baseRevision. Requires an idempotencyKey; this is not the neutral wiki write tool.",
|
|
45684
|
+
inputSchema: CommonsPublishEditorialInputSchema,
|
|
45685
|
+
outputSchema: recordOutputSchema("commons_publish_editorial", CommonsGenericOutputSchema),
|
|
45686
|
+
annotations: { title: "Publish Transparent Commons Editorial Edition", readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true }
|
|
45687
|
+
}, async (input) => executor.commonsPublishEditorial(input));
|
|
45688
|
+
server.registerTool("commons_get_publication", {
|
|
45689
|
+
title: "Get Transparent Commons Publication",
|
|
45690
|
+
description: "Read a Transparent Commons publication and its latest edition revisions. Omit subdomain to inspect the caller-owned publication; pass a name to inspect a public publication. Returns the permanent public and archive URLs needed for sharing or later edits.",
|
|
45691
|
+
inputSchema: CommonsGetPublicationInputSchema,
|
|
45692
|
+
outputSchema: recordOutputSchema("commons_get_publication", CommonsGenericOutputSchema),
|
|
45693
|
+
annotations: { title: "Get Transparent Commons Publication", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false }
|
|
45694
|
+
}, async (input) => executor.commonsGetPublication(input));
|
|
45617
45695
|
server.registerTool("directory_workflow", {
|
|
45618
45696
|
title: "Directory Workflow: Markets + Maps",
|
|
45619
45697
|
description: `Start a durable directory/prospecting job: selects US city markets from versioned hosted Census-place data, optionally joins the active hosted ZIP dataset, then runs Google Maps business searches per city. Pass a new idempotencyKey for each intended job and reuse it only when retrying that call. Production does not read server-local location CSVs. Always returns a background jobId; poll with directory_workflow_status. ${fileBehavior("Saves a CSV of results per city.", "Completed jobs return an owner-scoped CSV artifact.")}`,
|
|
@@ -46482,6 +46560,28 @@ var init_http_mcp_tool_executor = __esm({
|
|
|
46482
46560
|
commonsListNeedsLinks(input) {
|
|
46483
46561
|
return this.call("/commons/needs-links/search", input);
|
|
46484
46562
|
}
|
|
46563
|
+
commonsPreparePublication(input) {
|
|
46564
|
+
return this.call("/commons/publications/prepare", input);
|
|
46565
|
+
}
|
|
46566
|
+
commonsValidatePublication(input) {
|
|
46567
|
+
return this.call("/commons/publications/validate", input);
|
|
46568
|
+
}
|
|
46569
|
+
commonsClaimPublication(input) {
|
|
46570
|
+
const { idempotencyKey: idempotencyKey3, ...body } = input;
|
|
46571
|
+
return this.call("/commons/publications/claim", { ...body, idempotencyKey: idempotencyKey3 }, this.timeoutMs, "POST", {
|
|
46572
|
+
"Idempotency-Key": `commons-publication-claim-${(0, import_node_crypto26.createHash)("sha256").update(idempotencyKey3).digest("hex")}`
|
|
46573
|
+
});
|
|
46574
|
+
}
|
|
46575
|
+
commonsPublishEditorial(input) {
|
|
46576
|
+
const { idempotencyKey: idempotencyKey3, ...body } = input;
|
|
46577
|
+
return this.call("/commons/publications/publish", { ...body, idempotencyKey: idempotencyKey3 }, this.timeoutMs, "POST", {
|
|
46578
|
+
"Idempotency-Key": `commons-publication-publish-${(0, import_node_crypto26.createHash)("sha256").update(idempotencyKey3).digest("hex")}`
|
|
46579
|
+
});
|
|
46580
|
+
}
|
|
46581
|
+
commonsGetPublication(input) {
|
|
46582
|
+
const query = new URLSearchParams({ includeEditions: String(input.includeEditions ?? true) });
|
|
46583
|
+
return this.getJson(input.subdomain ? `/commons/publications/${encodeURIComponent(input.subdomain)}?${query}` : `/commons/publications/me?${query}`);
|
|
46584
|
+
}
|
|
46485
46585
|
async captureSerpSnapshot(input) {
|
|
46486
46586
|
const fingerprint = (0, import_node_crypto26.createHash)("sha256").update(JSON.stringify(input)).digest("hex");
|
|
46487
46587
|
const now = Date.now();
|
|
@@ -58451,6 +58551,54 @@ async function ensureCommonsSchema() {
|
|
|
58451
58551
|
},
|
|
58452
58552
|
{ sql: `CREATE INDEX IF NOT EXISTS commons_index_documents_status_updated ON commons_index_documents(embedding_status, updated_at DESC)`, args: [] },
|
|
58453
58553
|
{ sql: `CREATE INDEX IF NOT EXISTS commons_index_documents_entity_type ON commons_index_documents(entity_id, document_type)`, args: [] },
|
|
58554
|
+
{
|
|
58555
|
+
sql: `
|
|
58556
|
+
CREATE TABLE IF NOT EXISTS commons_publications (
|
|
58557
|
+
id TEXT PRIMARY KEY,
|
|
58558
|
+
owner_user_id INTEGER NOT NULL REFERENCES users(id),
|
|
58559
|
+
subdomain TEXT NOT NULL UNIQUE,
|
|
58560
|
+
title TEXT NOT NULL,
|
|
58561
|
+
description TEXT NOT NULL DEFAULT '',
|
|
58562
|
+
claim_idempotency_key TEXT NOT NULL,
|
|
58563
|
+
latest_edition_id TEXT,
|
|
58564
|
+
created_at TEXT NOT NULL,
|
|
58565
|
+
updated_at TEXT NOT NULL,
|
|
58566
|
+
UNIQUE(owner_user_id),
|
|
58567
|
+
UNIQUE(owner_user_id, claim_idempotency_key)
|
|
58568
|
+
)
|
|
58569
|
+
`,
|
|
58570
|
+
args: []
|
|
58571
|
+
},
|
|
58572
|
+
{ sql: `CREATE INDEX IF NOT EXISTS commons_publications_updated ON commons_publications(updated_at DESC)`, args: [] },
|
|
58573
|
+
{
|
|
58574
|
+
sql: `
|
|
58575
|
+
CREATE TABLE IF NOT EXISTS commons_publication_editions (
|
|
58576
|
+
id TEXT PRIMARY KEY,
|
|
58577
|
+
publication_id TEXT NOT NULL REFERENCES commons_publications(id),
|
|
58578
|
+
owner_user_id INTEGER NOT NULL REFERENCES users(id),
|
|
58579
|
+
edition_slug TEXT NOT NULL,
|
|
58580
|
+
revision INTEGER NOT NULL,
|
|
58581
|
+
title TEXT NOT NULL,
|
|
58582
|
+
site_json TEXT NOT NULL,
|
|
58583
|
+
deck TEXT NOT NULL,
|
|
58584
|
+
articles_json TEXT NOT NULL,
|
|
58585
|
+
html TEXT NOT NULL,
|
|
58586
|
+
filename TEXT NOT NULL,
|
|
58587
|
+
sha256 TEXT NOT NULL,
|
|
58588
|
+
article_count INTEGER NOT NULL,
|
|
58589
|
+
word_count INTEGER NOT NULL,
|
|
58590
|
+
bytes INTEGER NOT NULL,
|
|
58591
|
+
warnings_json TEXT NOT NULL DEFAULT '[]',
|
|
58592
|
+
idempotency_key TEXT NOT NULL,
|
|
58593
|
+
created_at TEXT NOT NULL,
|
|
58594
|
+
published_at TEXT NOT NULL,
|
|
58595
|
+
UNIQUE(publication_id, edition_slug, revision),
|
|
58596
|
+
UNIQUE(owner_user_id, idempotency_key)
|
|
58597
|
+
)
|
|
58598
|
+
`,
|
|
58599
|
+
args: []
|
|
58600
|
+
},
|
|
58601
|
+
{ sql: `CREATE INDEX IF NOT EXISTS commons_publication_editions_publication_published ON commons_publication_editions(publication_id, published_at DESC)`, args: [] },
|
|
58454
58602
|
{
|
|
58455
58603
|
sql: "INSERT OR IGNORE INTO schema_migrations (version) VALUES (?)",
|
|
58456
58604
|
args: [COMMONS_SCHEMA_VERSION]
|
|
@@ -60024,7 +60172,7 @@ var init_commons_repository = __esm({
|
|
|
60024
60172
|
import_node_crypto34 = require("crypto");
|
|
60025
60173
|
init_db();
|
|
60026
60174
|
init_rates();
|
|
60027
|
-
COMMONS_SCHEMA_VERSION = "2026-08-04.
|
|
60175
|
+
COMMONS_SCHEMA_VERSION = "2026-08-04.3";
|
|
60028
60176
|
DEFAULT_COMMONS_BASE_URL = "https://transparent-commons.cc";
|
|
60029
60177
|
DEFAULT_ENTITY_TYPE = "PublicArticle";
|
|
60030
60178
|
COMMONS_ENTITY_PROFILES = {
|
|
@@ -60186,6 +60334,401 @@ var init_commons_repository = __esm({
|
|
|
60186
60334
|
}
|
|
60187
60335
|
});
|
|
60188
60336
|
|
|
60337
|
+
// src/api/commons-publication-repository.ts
|
|
60338
|
+
async function prepareCommonsPublication(input, user) {
|
|
60339
|
+
await ensureCommonsSchema();
|
|
60340
|
+
const subdomain = normalizePublicationSubdomain(input.requestedSubdomain);
|
|
60341
|
+
const [owned, claimed] = await Promise.all([
|
|
60342
|
+
getCommonsPublicationForOwner(Number(user.id)),
|
|
60343
|
+
getCommonsPublicationBySubdomain(subdomain)
|
|
60344
|
+
]);
|
|
60345
|
+
const availability = claimed ? claimed.ownerUserId === Number(user.id) ? "owned_by_caller" : "unavailable" : "available";
|
|
60346
|
+
return {
|
|
60347
|
+
requestedSubdomain: input.requestedSubdomain,
|
|
60348
|
+
normalizedSubdomain: subdomain,
|
|
60349
|
+
availability,
|
|
60350
|
+
requestedPublicUrl: publicationPublicUrl(subdomain),
|
|
60351
|
+
currentPublication: owned,
|
|
60352
|
+
contract: {
|
|
60353
|
+
ownership: "One publication per authenticated MCP Scraper account.",
|
|
60354
|
+
permanence: "Claimed names are stable and globally unique.",
|
|
60355
|
+
renderer: "Published editions use the MCP Scraper editorial reading-room renderer.",
|
|
60356
|
+
revisionRule: "Editing an existing edition requires its current baseRevision.",
|
|
60357
|
+
publicRoutes: ["/", "/archive", "/editions/{editionSlug}"],
|
|
60358
|
+
workflow: [
|
|
60359
|
+
"commons_prepare_publication",
|
|
60360
|
+
"commons_validate_publication",
|
|
60361
|
+
"commons_claim_publication",
|
|
60362
|
+
"commons_publish_editorial"
|
|
60363
|
+
]
|
|
60364
|
+
},
|
|
60365
|
+
proposed: {
|
|
60366
|
+
title: cleanText(input.title, 140) || publicationTitleFromSubdomain(subdomain),
|
|
60367
|
+
description: cleanText(input.description, 500)
|
|
60368
|
+
}
|
|
60369
|
+
};
|
|
60370
|
+
}
|
|
60371
|
+
async function validateCommonsPublication(input, user) {
|
|
60372
|
+
await ensureCommonsSchema();
|
|
60373
|
+
const errors = [];
|
|
60374
|
+
const warnings = [];
|
|
60375
|
+
let subdomain = "";
|
|
60376
|
+
try {
|
|
60377
|
+
subdomain = normalizePublicationSubdomain(input.requestedSubdomain || input.publicationSubdomain || "");
|
|
60378
|
+
} catch (error) {
|
|
60379
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
60380
|
+
}
|
|
60381
|
+
const publication = subdomain ? await getCommonsPublicationBySubdomain(subdomain) : null;
|
|
60382
|
+
if (input.operation === "claim") {
|
|
60383
|
+
const owned = await getCommonsPublicationForOwner(Number(user.id));
|
|
60384
|
+
if (publication && publication.ownerUserId !== Number(user.id)) errors.push("That publication name is already claimed by another account.");
|
|
60385
|
+
if (owned && owned.subdomain !== subdomain) errors.push(`This account already owns ${owned.publicUrl}.`);
|
|
60386
|
+
if (!cleanText(input.title, 140)) warnings.push("No display title was supplied; the publication name will be title-cased.");
|
|
60387
|
+
} else {
|
|
60388
|
+
if (!publication) errors.push("Claim this publication name before publishing an edition.");
|
|
60389
|
+
else if (publication.ownerUserId !== Number(user.id)) errors.push("Only the account that claimed this publication can publish to it.");
|
|
60390
|
+
if (!input.edition) errors.push("A complete editorial reading-room edition is required for publish validation.");
|
|
60391
|
+
if (input.edition) {
|
|
60392
|
+
try {
|
|
60393
|
+
renderEditorialReadingRoom(input.edition);
|
|
60394
|
+
} catch (error) {
|
|
60395
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
60396
|
+
}
|
|
60397
|
+
const slug2 = normalizeEditionSlug(input.editionSlug || input.edition.site.slug);
|
|
60398
|
+
const latest = publication ? await getLatestEdition(publication.id, slug2) : null;
|
|
60399
|
+
if (latest && input.baseRevision === void 0) errors.push(`Edition ${slug2} already exists at revision ${latest.revision}; supply baseRevision to edit it.`);
|
|
60400
|
+
if (latest && input.baseRevision !== void 0 && latest.revision !== input.baseRevision) {
|
|
60401
|
+
errors.push(`Edition ${slug2} is revision ${latest.revision}; the proposed edit targeted ${input.baseRevision}.`);
|
|
60402
|
+
}
|
|
60403
|
+
}
|
|
60404
|
+
}
|
|
60405
|
+
return {
|
|
60406
|
+
valid: errors.length === 0,
|
|
60407
|
+
operation: input.operation,
|
|
60408
|
+
normalizedSubdomain: subdomain || null,
|
|
60409
|
+
publicUrl: subdomain ? publicationPublicUrl(subdomain) : null,
|
|
60410
|
+
errors,
|
|
60411
|
+
warnings,
|
|
60412
|
+
publication
|
|
60413
|
+
};
|
|
60414
|
+
}
|
|
60415
|
+
async function claimCommonsPublication(input, user) {
|
|
60416
|
+
await ensureCommonsSchema();
|
|
60417
|
+
const subdomain = normalizePublicationSubdomain(input.requestedSubdomain);
|
|
60418
|
+
const userId = Number(user.id);
|
|
60419
|
+
const existingOwned = await getCommonsPublicationForOwner(userId);
|
|
60420
|
+
if (existingOwned) {
|
|
60421
|
+
if (existingOwned.subdomain === subdomain) return { publication: existingOwned, idempotentReplay: true };
|
|
60422
|
+
throw new CommonsPublicationError("publication_already_claimed", `This account already owns ${existingOwned.publicUrl}.`, 409);
|
|
60423
|
+
}
|
|
60424
|
+
const existingName = await getCommonsPublicationBySubdomain(subdomain);
|
|
60425
|
+
if (existingName) throw new CommonsPublicationError("publication_name_unavailable", "That publication name is already claimed.", 409);
|
|
60426
|
+
const id = `tcpub_${(0, import_node_crypto35.randomUUID)()}`;
|
|
60427
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
60428
|
+
try {
|
|
60429
|
+
await getDb().execute({
|
|
60430
|
+
sql: `
|
|
60431
|
+
INSERT INTO commons_publications (
|
|
60432
|
+
id, owner_user_id, subdomain, title, description, claim_idempotency_key, created_at, updated_at
|
|
60433
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
60434
|
+
`,
|
|
60435
|
+
args: [
|
|
60436
|
+
id,
|
|
60437
|
+
userId,
|
|
60438
|
+
subdomain,
|
|
60439
|
+
cleanText(input.title, 140) || publicationTitleFromSubdomain(subdomain),
|
|
60440
|
+
cleanText(input.description, 500),
|
|
60441
|
+
requiredIdempotencyKey(input.idempotencyKey),
|
|
60442
|
+
now,
|
|
60443
|
+
now
|
|
60444
|
+
]
|
|
60445
|
+
});
|
|
60446
|
+
} catch (error) {
|
|
60447
|
+
const replay = await getCommonsPublicationForOwner(userId);
|
|
60448
|
+
if (replay?.subdomain === subdomain) return { publication: replay, idempotentReplay: true };
|
|
60449
|
+
throw error;
|
|
60450
|
+
}
|
|
60451
|
+
const publication = await getCommonsPublicationBySubdomain(subdomain);
|
|
60452
|
+
if (!publication) throw new CommonsPublicationError("publication_claim_failed", "The publication claim was not persisted.");
|
|
60453
|
+
return { publication, idempotentReplay: false };
|
|
60454
|
+
}
|
|
60455
|
+
async function publishCommonsEditorial(input, user) {
|
|
60456
|
+
await ensureCommonsSchema();
|
|
60457
|
+
const subdomain = normalizePublicationSubdomain(input.publicationSubdomain);
|
|
60458
|
+
const publication = await getCommonsPublicationBySubdomain(subdomain);
|
|
60459
|
+
if (!publication) throw new CommonsPublicationError("publication_not_found", "Claim this publication name before publishing an edition.", 404);
|
|
60460
|
+
if (publication.ownerUserId !== Number(user.id)) {
|
|
60461
|
+
throw new CommonsPublicationError("publication_not_owned", "Only the account that claimed this publication can publish to it.", 404);
|
|
60462
|
+
}
|
|
60463
|
+
const idempotencyKey3 = requiredIdempotencyKey(input.idempotencyKey);
|
|
60464
|
+
const replay = await getEditionByIdempotency(Number(user.id), idempotencyKey3);
|
|
60465
|
+
if (replay) return publicationResult(publication, replay, true);
|
|
60466
|
+
const editionSlug = normalizeEditionSlug(input.editionSlug || input.site.slug);
|
|
60467
|
+
const latest = await getLatestEdition(publication.id, editionSlug);
|
|
60468
|
+
if (latest && input.baseRevision === void 0) {
|
|
60469
|
+
throw new CommonsPublicationError("publication_base_revision_required", `Edition ${editionSlug} already exists at revision ${latest.revision}; supply baseRevision to edit it.`, 409);
|
|
60470
|
+
}
|
|
60471
|
+
if (latest && input.baseRevision !== latest.revision) {
|
|
60472
|
+
throw new CommonsPublicationError("publication_revision_conflict", `Edition ${editionSlug} is revision ${latest.revision}; refresh it before publishing an edit.`, 409);
|
|
60473
|
+
}
|
|
60474
|
+
const { publicationSubdomain: _publicationSubdomain, editionSlug: _editionSlug, idempotencyKey: _idempotencyKey, baseRevision: _baseRevision, ...editionInput } = input;
|
|
60475
|
+
const canonicalUrl = editionPublicUrl(subdomain, editionSlug);
|
|
60476
|
+
const rendered = renderEditorialReadingRoom(editionInput);
|
|
60477
|
+
const html = addPublicMetadata(rendered.html, canonicalUrl, publication.title);
|
|
60478
|
+
const editionId = `tced_${(0, import_node_crypto35.randomUUID)()}`;
|
|
60479
|
+
const revision = (latest?.revision ?? 0) + 1;
|
|
60480
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
60481
|
+
await getDb().batch([
|
|
60482
|
+
{
|
|
60483
|
+
sql: `
|
|
60484
|
+
INSERT INTO commons_publication_editions (
|
|
60485
|
+
id, publication_id, owner_user_id, edition_slug, revision, title, site_json, deck,
|
|
60486
|
+
articles_json, html, filename, sha256, article_count, word_count, bytes, warnings_json,
|
|
60487
|
+
idempotency_key, created_at, published_at
|
|
60488
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
60489
|
+
`,
|
|
60490
|
+
args: [
|
|
60491
|
+
editionId,
|
|
60492
|
+
publication.id,
|
|
60493
|
+
Number(user.id),
|
|
60494
|
+
editionSlug,
|
|
60495
|
+
revision,
|
|
60496
|
+
editionInput.site.title,
|
|
60497
|
+
JSON.stringify(editionInput.site),
|
|
60498
|
+
editionInput.deck,
|
|
60499
|
+
JSON.stringify(editionInput.articles),
|
|
60500
|
+
html,
|
|
60501
|
+
rendered.filename,
|
|
60502
|
+
(0, import_node_crypto35.createHash)("sha256").update(html).digest("hex"),
|
|
60503
|
+
rendered.articleCount,
|
|
60504
|
+
rendered.wordCount,
|
|
60505
|
+
Buffer.byteLength(html),
|
|
60506
|
+
JSON.stringify(rendered.warnings),
|
|
60507
|
+
idempotencyKey3,
|
|
60508
|
+
now,
|
|
60509
|
+
now
|
|
60510
|
+
]
|
|
60511
|
+
},
|
|
60512
|
+
{
|
|
60513
|
+
sql: "UPDATE commons_publications SET latest_edition_id = ?, updated_at = ? WHERE id = ? AND owner_user_id = ?",
|
|
60514
|
+
args: [editionId, now, publication.id, Number(user.id)]
|
|
60515
|
+
}
|
|
60516
|
+
], "write");
|
|
60517
|
+
const edition = await getPublicationEditionById(editionId);
|
|
60518
|
+
if (!edition) throw new CommonsPublicationError("publication_publish_failed", "The published edition was not persisted.");
|
|
60519
|
+
return publicationResult({ ...publication, latestEditionId: editionId, updatedAt: now }, edition, false);
|
|
60520
|
+
}
|
|
60521
|
+
async function getCommonsPublicationBySubdomain(subdomainInput) {
|
|
60522
|
+
await ensureCommonsSchema();
|
|
60523
|
+
const subdomain = normalizePublicationSubdomain(subdomainInput);
|
|
60524
|
+
const result = await getDb().execute({ sql: "SELECT * FROM commons_publications WHERE subdomain = ? LIMIT 1", args: [subdomain] });
|
|
60525
|
+
return result.rows[0] ? rowToPublication(result.rows[0]) : null;
|
|
60526
|
+
}
|
|
60527
|
+
async function getCommonsPublicationForOwner(userId) {
|
|
60528
|
+
await ensureCommonsSchema();
|
|
60529
|
+
const result = await getDb().execute({ sql: "SELECT * FROM commons_publications WHERE owner_user_id = ? LIMIT 1", args: [userId] });
|
|
60530
|
+
return result.rows[0] ? rowToPublication(result.rows[0]) : null;
|
|
60531
|
+
}
|
|
60532
|
+
async function listCommonsPublicationEditions(publicationId) {
|
|
60533
|
+
await ensureCommonsSchema();
|
|
60534
|
+
const result = await getDb().execute({
|
|
60535
|
+
sql: `
|
|
60536
|
+
SELECT edition.* FROM commons_publication_editions edition
|
|
60537
|
+
JOIN (
|
|
60538
|
+
SELECT edition_slug, MAX(revision) AS revision
|
|
60539
|
+
FROM commons_publication_editions WHERE publication_id = ? GROUP BY edition_slug
|
|
60540
|
+
) latest ON latest.edition_slug = edition.edition_slug AND latest.revision = edition.revision
|
|
60541
|
+
WHERE edition.publication_id = ? ORDER BY edition.published_at DESC
|
|
60542
|
+
`,
|
|
60543
|
+
args: [publicationId, publicationId]
|
|
60544
|
+
});
|
|
60545
|
+
const publication = await getPublicationById(publicationId);
|
|
60546
|
+
if (!publication) return [];
|
|
60547
|
+
return result.rows.map((row) => rowToEdition(row, publication.subdomain));
|
|
60548
|
+
}
|
|
60549
|
+
async function getCommonsPublicationEditionHtml(subdomainInput, editionSlugInput) {
|
|
60550
|
+
const publication = await getCommonsPublicationBySubdomain(subdomainInput);
|
|
60551
|
+
if (!publication) return null;
|
|
60552
|
+
const result = editionSlugInput ? await getDb().execute({
|
|
60553
|
+
sql: "SELECT * FROM commons_publication_editions WHERE publication_id = ? AND edition_slug = ? ORDER BY revision DESC LIMIT 1",
|
|
60554
|
+
args: [publication.id, normalizeEditionSlug(editionSlugInput)]
|
|
60555
|
+
}) : await getDb().execute({
|
|
60556
|
+
sql: "SELECT * FROM commons_publication_editions WHERE id = ? AND publication_id = ? LIMIT 1",
|
|
60557
|
+
args: [publication.latestEditionId || "", publication.id]
|
|
60558
|
+
});
|
|
60559
|
+
if (!result.rows[0]) return null;
|
|
60560
|
+
const record = result.rows[0];
|
|
60561
|
+
return { publication, edition: rowToEdition(record, publication.subdomain), html: String(record.html || "") };
|
|
60562
|
+
}
|
|
60563
|
+
async function getPublicationById(id) {
|
|
60564
|
+
const result = await getDb().execute({ sql: "SELECT * FROM commons_publications WHERE id = ? LIMIT 1", args: [id] });
|
|
60565
|
+
return result.rows[0] ? rowToPublication(result.rows[0]) : null;
|
|
60566
|
+
}
|
|
60567
|
+
async function getLatestEdition(publicationId, editionSlug) {
|
|
60568
|
+
const publication = await getPublicationById(publicationId);
|
|
60569
|
+
if (!publication) return null;
|
|
60570
|
+
const result = await getDb().execute({
|
|
60571
|
+
sql: "SELECT * FROM commons_publication_editions WHERE publication_id = ? AND edition_slug = ? ORDER BY revision DESC LIMIT 1",
|
|
60572
|
+
args: [publicationId, editionSlug]
|
|
60573
|
+
});
|
|
60574
|
+
return result.rows[0] ? rowToEdition(result.rows[0], publication.subdomain) : null;
|
|
60575
|
+
}
|
|
60576
|
+
async function getEditionByIdempotency(userId, idempotencyKey3) {
|
|
60577
|
+
const result = await getDb().execute({
|
|
60578
|
+
sql: `SELECT edition.*, publication.subdomain FROM commons_publication_editions edition JOIN commons_publications publication ON publication.id = edition.publication_id WHERE edition.owner_user_id = ? AND edition.idempotency_key = ? LIMIT 1`,
|
|
60579
|
+
args: [userId, idempotencyKey3]
|
|
60580
|
+
});
|
|
60581
|
+
if (!result.rows[0]) return null;
|
|
60582
|
+
const record = result.rows[0];
|
|
60583
|
+
return rowToEdition(record, String(record.subdomain));
|
|
60584
|
+
}
|
|
60585
|
+
async function getPublicationEditionById(id) {
|
|
60586
|
+
const result = await getDb().execute({
|
|
60587
|
+
sql: `SELECT edition.*, publication.subdomain FROM commons_publication_editions edition JOIN commons_publications publication ON publication.id = edition.publication_id WHERE edition.id = ? LIMIT 1`,
|
|
60588
|
+
args: [id]
|
|
60589
|
+
});
|
|
60590
|
+
if (!result.rows[0]) return null;
|
|
60591
|
+
const record = result.rows[0];
|
|
60592
|
+
return rowToEdition(record, String(record.subdomain));
|
|
60593
|
+
}
|
|
60594
|
+
function rowToPublication(row) {
|
|
60595
|
+
const subdomain = String(row.subdomain);
|
|
60596
|
+
return {
|
|
60597
|
+
id: String(row.id),
|
|
60598
|
+
ownerUserId: Number(row.owner_user_id),
|
|
60599
|
+
subdomain,
|
|
60600
|
+
title: String(row.title),
|
|
60601
|
+
description: String(row.description || ""),
|
|
60602
|
+
latestEditionId: row.latest_edition_id ? String(row.latest_edition_id) : null,
|
|
60603
|
+
createdAt: String(row.created_at),
|
|
60604
|
+
updatedAt: String(row.updated_at),
|
|
60605
|
+
publicUrl: publicationPublicUrl(subdomain),
|
|
60606
|
+
archiveUrl: `${publicationPublicUrl(subdomain)}/archive`
|
|
60607
|
+
};
|
|
60608
|
+
}
|
|
60609
|
+
function rowToEdition(row, subdomain) {
|
|
60610
|
+
const editionSlug = String(row.edition_slug);
|
|
60611
|
+
return {
|
|
60612
|
+
id: String(row.id),
|
|
60613
|
+
publicationId: String(row.publication_id),
|
|
60614
|
+
editionSlug,
|
|
60615
|
+
revision: Number(row.revision),
|
|
60616
|
+
title: String(row.title),
|
|
60617
|
+
site: parseJson4(row.site_json, {}),
|
|
60618
|
+
deck: String(row.deck),
|
|
60619
|
+
filename: String(row.filename),
|
|
60620
|
+
sha256: String(row.sha256),
|
|
60621
|
+
articleCount: Number(row.article_count),
|
|
60622
|
+
wordCount: Number(row.word_count),
|
|
60623
|
+
bytes: Number(row.bytes),
|
|
60624
|
+
warnings: parseJson4(row.warnings_json, []),
|
|
60625
|
+
createdAt: String(row.created_at),
|
|
60626
|
+
publishedAt: String(row.published_at),
|
|
60627
|
+
publicUrl: editionPublicUrl(subdomain, editionSlug)
|
|
60628
|
+
};
|
|
60629
|
+
}
|
|
60630
|
+
function publicationResult(publication, edition, idempotentReplay) {
|
|
60631
|
+
return {
|
|
60632
|
+
publication,
|
|
60633
|
+
edition,
|
|
60634
|
+
publicUrl: publication.publicUrl,
|
|
60635
|
+
archiveUrl: publication.archiveUrl,
|
|
60636
|
+
editionUrl: edition.publicUrl,
|
|
60637
|
+
idempotentReplay
|
|
60638
|
+
};
|
|
60639
|
+
}
|
|
60640
|
+
function normalizePublicationSubdomain(value) {
|
|
60641
|
+
const normalized = String(value || "").trim().toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
60642
|
+
if (!/^[a-z0-9](?:[a-z0-9-]{1,48}[a-z0-9])$/.test(normalized)) {
|
|
60643
|
+
throw new CommonsPublicationError("publication_name_invalid", "Choose a publication name between 3 and 50 characters using letters, numbers, and interior hyphens.");
|
|
60644
|
+
}
|
|
60645
|
+
if (RESERVED_SUBDOMAINS.has(normalized)) throw new CommonsPublicationError("publication_name_reserved", "That publication name is reserved; choose a more specific name.", 409);
|
|
60646
|
+
return normalized;
|
|
60647
|
+
}
|
|
60648
|
+
function normalizeEditionSlug(value) {
|
|
60649
|
+
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 80);
|
|
60650
|
+
if (!normalized) throw new CommonsPublicationError("edition_slug_invalid", "A published edition needs a stable slug.");
|
|
60651
|
+
return normalized;
|
|
60652
|
+
}
|
|
60653
|
+
function requiredIdempotencyKey(value) {
|
|
60654
|
+
const normalized = cleanText(value, 200);
|
|
60655
|
+
if (normalized.length < 8) throw new CommonsPublicationError("idempotency_key_invalid", "Use an idempotency key of at least 8 characters and reuse it only when retrying the same write.");
|
|
60656
|
+
return normalized;
|
|
60657
|
+
}
|
|
60658
|
+
function publicationPublicUrl(subdomain) {
|
|
60659
|
+
return `https://${subdomain}.${PUBLICATION_ROOT_DOMAIN}`;
|
|
60660
|
+
}
|
|
60661
|
+
function editionPublicUrl(subdomain, editionSlug) {
|
|
60662
|
+
return `${publicationPublicUrl(subdomain)}/editions/${encodeURIComponent(editionSlug)}`;
|
|
60663
|
+
}
|
|
60664
|
+
function publicationTitleFromSubdomain(subdomain) {
|
|
60665
|
+
return subdomain.split("-").map((part) => part ? `${part[0]?.toUpperCase()}${part.slice(1)}` : "").join(" ");
|
|
60666
|
+
}
|
|
60667
|
+
function cleanText(value, max) {
|
|
60668
|
+
return String(value || "").replace(/\s+/g, " ").trim().slice(0, max);
|
|
60669
|
+
}
|
|
60670
|
+
function parseJson4(value, fallback) {
|
|
60671
|
+
try {
|
|
60672
|
+
return JSON.parse(String(value || ""));
|
|
60673
|
+
} catch {
|
|
60674
|
+
return fallback;
|
|
60675
|
+
}
|
|
60676
|
+
}
|
|
60677
|
+
function addPublicMetadata(html, canonicalUrl, publicationTitle) {
|
|
60678
|
+
const escapedUrl = canonicalUrl.replace(/&/g, "&").replace(/"/g, """);
|
|
60679
|
+
const escapedTitle = publicationTitle.replace(/&/g, "&").replace(/"/g, """);
|
|
60680
|
+
return html.replace("</head>", [
|
|
60681
|
+
` <link rel="canonical" href="${escapedUrl}">`,
|
|
60682
|
+
` <meta property="og:url" content="${escapedUrl}">`,
|
|
60683
|
+
` <meta property="og:site_name" content="${escapedTitle}">`,
|
|
60684
|
+
' <meta name="robots" content="index,follow">',
|
|
60685
|
+
"</head>"
|
|
60686
|
+
].join("\n"));
|
|
60687
|
+
}
|
|
60688
|
+
var import_node_crypto35, PUBLICATION_ROOT_DOMAIN, RESERVED_SUBDOMAINS, CommonsPublicationError;
|
|
60689
|
+
var init_commons_publication_repository = __esm({
|
|
60690
|
+
"src/api/commons-publication-repository.ts"() {
|
|
60691
|
+
"use strict";
|
|
60692
|
+
import_node_crypto35 = require("crypto");
|
|
60693
|
+
init_db();
|
|
60694
|
+
init_commons_repository();
|
|
60695
|
+
init_render();
|
|
60696
|
+
PUBLICATION_ROOT_DOMAIN = process.env.COMMONS_PUBLICATION_ROOT_DOMAIN || "transparent-commons.cc";
|
|
60697
|
+
RESERVED_SUBDOMAINS = /* @__PURE__ */ new Set([
|
|
60698
|
+
"admin",
|
|
60699
|
+
"api",
|
|
60700
|
+
"app",
|
|
60701
|
+
"assets",
|
|
60702
|
+
"auth",
|
|
60703
|
+
"blog",
|
|
60704
|
+
"cdn",
|
|
60705
|
+
"docs",
|
|
60706
|
+
"help",
|
|
60707
|
+
"login",
|
|
60708
|
+
"mail",
|
|
60709
|
+
"mcp",
|
|
60710
|
+
"signup",
|
|
60711
|
+
"sitemap",
|
|
60712
|
+
"static",
|
|
60713
|
+
"support",
|
|
60714
|
+
"transparent-commons",
|
|
60715
|
+
"transparentcommons",
|
|
60716
|
+
"www",
|
|
60717
|
+
"wiki"
|
|
60718
|
+
]);
|
|
60719
|
+
CommonsPublicationError = class extends Error {
|
|
60720
|
+
constructor(code, message, httpStatus = 400) {
|
|
60721
|
+
super(message);
|
|
60722
|
+
this.code = code;
|
|
60723
|
+
this.httpStatus = httpStatus;
|
|
60724
|
+
this.name = "CommonsPublicationError";
|
|
60725
|
+
}
|
|
60726
|
+
code;
|
|
60727
|
+
httpStatus;
|
|
60728
|
+
};
|
|
60729
|
+
}
|
|
60730
|
+
});
|
|
60731
|
+
|
|
60189
60732
|
// src/api/commons-routes.ts
|
|
60190
60733
|
function filtersFromQuery(query) {
|
|
60191
60734
|
return {
|
|
@@ -60231,10 +60774,23 @@ function repositoryStatus(error) {
|
|
|
60231
60774
|
if (error.httpStatus === 409) return 409;
|
|
60232
60775
|
return 400;
|
|
60233
60776
|
}
|
|
60777
|
+
async function publicationOperation(c, operation, successStatus = 200) {
|
|
60778
|
+
try {
|
|
60779
|
+
return c.json({ ok: true, data: await operation() }, successStatus);
|
|
60780
|
+
} catch (error) {
|
|
60781
|
+
return publicationError(c, error);
|
|
60782
|
+
}
|
|
60783
|
+
}
|
|
60784
|
+
function publicationError(c, error) {
|
|
60785
|
+
if (error instanceof CommonsPublicationError) {
|
|
60786
|
+
return c.json({ ok: false, error: error.code, message: error.message }, error.httpStatus);
|
|
60787
|
+
}
|
|
60788
|
+
throw error;
|
|
60789
|
+
}
|
|
60234
60790
|
function xmlEscape(value) {
|
|
60235
60791
|
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
60236
60792
|
}
|
|
60237
|
-
var import_hono31, import_zod50, commonsApp, auth2, SearchBodySchema, FeaturedImageSchema, MediaSchema, CitationSchema, RelatedLinkSchema, SubmitEntitySchema, PrepareEntitySchema, ValidateEntitySchema, SaveFilterSchema, NeedsLinkBodySchema;
|
|
60793
|
+
var import_hono31, import_zod50, commonsApp, auth2, SearchBodySchema, FeaturedImageSchema, MediaSchema, CitationSchema, RelatedLinkSchema, SubmitEntitySchema, PrepareEntitySchema, ValidateEntitySchema, SaveFilterSchema, NeedsLinkBodySchema, PreparePublicationSchema, ValidatePublicationSchema, ClaimPublicationSchema, PublishEditorialSchema;
|
|
60238
60794
|
var init_commons_routes = __esm({
|
|
60239
60795
|
"src/api/commons-routes.ts"() {
|
|
60240
60796
|
"use strict";
|
|
@@ -60243,6 +60799,8 @@ var init_commons_routes = __esm({
|
|
|
60243
60799
|
init_api_auth();
|
|
60244
60800
|
init_commons_repository();
|
|
60245
60801
|
init_listing_write_billing();
|
|
60802
|
+
init_commons_publication_repository();
|
|
60803
|
+
init_mcp_tool_schemas();
|
|
60246
60804
|
commonsApp = new import_hono31.Hono();
|
|
60247
60805
|
auth2 = createApiKeyAuth();
|
|
60248
60806
|
SearchBodySchema = import_zod50.z.object({
|
|
@@ -60403,10 +60961,83 @@ var init_commons_routes = __esm({
|
|
|
60403
60961
|
limit: import_zod50.z.number().int().min(1).max(100).optional(),
|
|
60404
60962
|
offset: import_zod50.z.number().int().min(0).max(1e4).optional()
|
|
60405
60963
|
}).strict();
|
|
60964
|
+
PreparePublicationSchema = import_zod50.z.object(CommonsPreparePublicationInputSchema).strict();
|
|
60965
|
+
ValidatePublicationSchema = import_zod50.z.object(CommonsValidatePublicationInputSchema).strict();
|
|
60966
|
+
ClaimPublicationSchema = import_zod50.z.object(CommonsClaimPublicationInputSchema).strict();
|
|
60967
|
+
PublishEditorialSchema = import_zod50.z.object(CommonsPublishEditorialInputSchema).strict();
|
|
60406
60968
|
commonsApp.get("/health", async (c) => {
|
|
60407
60969
|
await ensureCommonsSchema();
|
|
60408
60970
|
return c.json({ ok: true, data: commonsDatabaseReport() });
|
|
60409
60971
|
});
|
|
60972
|
+
commonsApp.post("/publications/prepare", auth2, async (c) => {
|
|
60973
|
+
const parsed = PreparePublicationSchema.safeParse(await c.req.json().catch(() => ({})));
|
|
60974
|
+
if (!parsed.success) return validationError(c, parsed.error);
|
|
60975
|
+
return publicationOperation(c, () => prepareCommonsPublication(parsed.data, c.get("user")));
|
|
60976
|
+
});
|
|
60977
|
+
commonsApp.post("/publications/validate", auth2, async (c) => {
|
|
60978
|
+
const parsed = ValidatePublicationSchema.safeParse(await c.req.json().catch(() => ({})));
|
|
60979
|
+
if (!parsed.success) return validationError(c, parsed.error);
|
|
60980
|
+
return publicationOperation(c, () => validateCommonsPublication(parsed.data, c.get("user")));
|
|
60981
|
+
});
|
|
60982
|
+
commonsApp.post("/publications/claim", auth2, async (c) => {
|
|
60983
|
+
const parsed = ClaimPublicationSchema.safeParse(await c.req.json().catch(() => ({})));
|
|
60984
|
+
if (!parsed.success) return validationError(c, parsed.error);
|
|
60985
|
+
return publicationOperation(c, () => claimCommonsPublication(parsed.data, c.get("user")), 201);
|
|
60986
|
+
});
|
|
60987
|
+
commonsApp.post("/publications/publish", auth2, async (c) => {
|
|
60988
|
+
const parsed = PublishEditorialSchema.safeParse(await c.req.json().catch(() => ({})));
|
|
60989
|
+
if (!parsed.success) return validationError(c, parsed.error);
|
|
60990
|
+
return publicationOperation(c, () => publishCommonsEditorial(parsed.data, c.get("user")), 201);
|
|
60991
|
+
});
|
|
60992
|
+
commonsApp.get("/publications/me", auth2, async (c) => {
|
|
60993
|
+
const publication = await getCommonsPublicationForOwner(Number(c.get("user").id));
|
|
60994
|
+
if (!publication) return c.json({ ok: false, error: "publication_not_found", message: "This account has not claimed a Commons publication yet." }, 404);
|
|
60995
|
+
const editions = c.req.query("includeEditions") === "false" ? [] : await listCommonsPublicationEditions(publication.id);
|
|
60996
|
+
return c.json({ ok: true, data: { publication, editions } });
|
|
60997
|
+
});
|
|
60998
|
+
commonsApp.get("/publications/:subdomain/site", async (c) => {
|
|
60999
|
+
try {
|
|
61000
|
+
const result = await getCommonsPublicationEditionHtml(c.req.param("subdomain"));
|
|
61001
|
+
if (!result) return c.json({ ok: false, error: "publication_not_published", message: "No published edition exists for this publication." }, 404);
|
|
61002
|
+
return c.html(result.html, 200, {
|
|
61003
|
+
"cache-control": "public, max-age=60, s-maxage=300",
|
|
61004
|
+
"x-robots-tag": "index, follow"
|
|
61005
|
+
});
|
|
61006
|
+
} catch (error) {
|
|
61007
|
+
return publicationError(c, error);
|
|
61008
|
+
}
|
|
61009
|
+
});
|
|
61010
|
+
commonsApp.get("/publications/:subdomain/editions/:editionSlug/site", async (c) => {
|
|
61011
|
+
try {
|
|
61012
|
+
const result = await getCommonsPublicationEditionHtml(c.req.param("subdomain"), c.req.param("editionSlug"));
|
|
61013
|
+
if (!result) return c.json({ ok: false, error: "edition_not_found", message: "No published edition matched that publication and slug." }, 404);
|
|
61014
|
+
return c.html(result.html, 200, {
|
|
61015
|
+
"cache-control": "public, max-age=60, s-maxage=300",
|
|
61016
|
+
"x-robots-tag": "index, follow"
|
|
61017
|
+
});
|
|
61018
|
+
} catch (error) {
|
|
61019
|
+
return publicationError(c, error);
|
|
61020
|
+
}
|
|
61021
|
+
});
|
|
61022
|
+
commonsApp.get("/publications/:subdomain/editions", async (c) => {
|
|
61023
|
+
try {
|
|
61024
|
+
const publication = await getCommonsPublicationBySubdomain(c.req.param("subdomain"));
|
|
61025
|
+
if (!publication) return c.json({ ok: false, error: "publication_not_found", message: "No Commons publication matched that name." }, 404);
|
|
61026
|
+
return c.json({ ok: true, data: { publication, editions: await listCommonsPublicationEditions(publication.id) } });
|
|
61027
|
+
} catch (error) {
|
|
61028
|
+
return publicationError(c, error);
|
|
61029
|
+
}
|
|
61030
|
+
});
|
|
61031
|
+
commonsApp.get("/publications/:subdomain", async (c) => {
|
|
61032
|
+
try {
|
|
61033
|
+
const publication = await getCommonsPublicationBySubdomain(c.req.param("subdomain"));
|
|
61034
|
+
if (!publication) return c.json({ ok: false, error: "publication_not_found", message: "No Commons publication matched that name." }, 404);
|
|
61035
|
+
const editions = c.req.query("includeEditions") === "false" ? [] : await listCommonsPublicationEditions(publication.id);
|
|
61036
|
+
return c.json({ ok: true, data: { publication, editions } });
|
|
61037
|
+
} catch (error) {
|
|
61038
|
+
return publicationError(c, error);
|
|
61039
|
+
}
|
|
61040
|
+
});
|
|
60410
61041
|
commonsApp.get("/entities", async (c) => {
|
|
60411
61042
|
const result = await searchCommonsEntities(filtersFromQuery(c.req.query()));
|
|
60412
61043
|
return c.json({ ok: true, data: result });
|
|
@@ -60529,13 +61160,13 @@ ${urls.join("\n")}
|
|
|
60529
61160
|
|
|
60530
61161
|
// src/api/scheduled-artifact-owner.ts
|
|
60531
61162
|
function scheduledArtifactOwnerIdForApiKey(apiKey) {
|
|
60532
|
-
return (0,
|
|
61163
|
+
return (0, import_node_crypto36.createHash)("sha256").update(apiKey).digest("hex").slice(0, 24);
|
|
60533
61164
|
}
|
|
60534
|
-
var
|
|
61165
|
+
var import_node_crypto36;
|
|
60535
61166
|
var init_scheduled_artifact_owner = __esm({
|
|
60536
61167
|
"src/api/scheduled-artifact-owner.ts"() {
|
|
60537
61168
|
"use strict";
|
|
60538
|
-
|
|
61169
|
+
import_node_crypto36 = require("crypto");
|
|
60539
61170
|
}
|
|
60540
61171
|
});
|
|
60541
61172
|
|
|
@@ -60569,7 +61200,7 @@ async function ensureScheduledRunViewLinksSchema() {
|
|
|
60569
61200
|
schemaReady3 = true;
|
|
60570
61201
|
}
|
|
60571
61202
|
function tokenHash2(token4) {
|
|
60572
|
-
return (0,
|
|
61203
|
+
return (0, import_node_crypto37.createHash)("sha256").update(token4).digest("hex");
|
|
60573
61204
|
}
|
|
60574
61205
|
function mapRow(row) {
|
|
60575
61206
|
return {
|
|
@@ -60589,9 +61220,9 @@ function mapRow(row) {
|
|
|
60589
61220
|
async function createScheduledRunViewLink(input) {
|
|
60590
61221
|
await ensureScheduledRunViewLinksSchema();
|
|
60591
61222
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
60592
|
-
const token4 = (0,
|
|
61223
|
+
const token4 = (0, import_node_crypto37.randomBytes)(32).toString("base64url");
|
|
60593
61224
|
const record = {
|
|
60594
|
-
shareId: (0,
|
|
61225
|
+
shareId: (0, import_node_crypto37.randomUUID)(),
|
|
60595
61226
|
ownerId: input.ownerId,
|
|
60596
61227
|
runId: input.runId,
|
|
60597
61228
|
artifactId: input.artifactId,
|
|
@@ -60654,11 +61285,11 @@ async function revokeScheduledRunViewLink(ownerId, runId, shareId, now = /* @__P
|
|
|
60654
61285
|
});
|
|
60655
61286
|
return result.rowsAffected > 0;
|
|
60656
61287
|
}
|
|
60657
|
-
var
|
|
61288
|
+
var import_node_crypto37, schemaReady3;
|
|
60658
61289
|
var init_scheduled_run_view_links = __esm({
|
|
60659
61290
|
"src/api/scheduled-run-view-links.ts"() {
|
|
60660
61291
|
"use strict";
|
|
60661
|
-
|
|
61292
|
+
import_node_crypto37 = require("crypto");
|
|
60662
61293
|
init_db();
|
|
60663
61294
|
schemaReady3 = false;
|
|
60664
61295
|
}
|
|
@@ -60859,7 +61490,7 @@ function policy4() {
|
|
|
60859
61490
|
};
|
|
60860
61491
|
}
|
|
60861
61492
|
function runStorageSegment(runId) {
|
|
60862
|
-
return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${(0,
|
|
61493
|
+
return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${(0, import_node_crypto38.createHash)("sha256").update(runId).digest("hex").slice(0, 32)}`;
|
|
60863
61494
|
}
|
|
60864
61495
|
async function createScheduledRunArtifact(args) {
|
|
60865
61496
|
if (args.rendered.bytes > SCHEDULED_RUN_ARTIFACT_MAX_BYTES) {
|
|
@@ -60900,12 +61531,12 @@ async function readScheduledRunArtifact(args) {
|
|
|
60900
61531
|
if (!window2 || window2.nextOffset !== null || window2.totalBytes > SCHEDULED_RUN_ARTIFACT_MAX_BYTES) return null;
|
|
60901
61532
|
return window2.text;
|
|
60902
61533
|
}
|
|
60903
|
-
var
|
|
61534
|
+
var import_node_crypto38, SCHEDULED_RUN_ARTIFACT_PREFIX, SCHEDULED_RUN_ARTIFACT_DOWNLOAD_TTL_MS, SCHEDULED_RUN_ARTIFACT_MAX_BYTES;
|
|
60904
61535
|
var init_scheduled_run_artifact_store = __esm({
|
|
60905
61536
|
"src/scheduled-artifacts/scheduled-run-artifact-store.ts"() {
|
|
60906
61537
|
"use strict";
|
|
60907
61538
|
init_private_artifacts();
|
|
60908
|
-
|
|
61539
|
+
import_node_crypto38 = require("crypto");
|
|
60909
61540
|
SCHEDULED_RUN_ARTIFACT_PREFIX = "scheduled-run-artifacts/";
|
|
60910
61541
|
SCHEDULED_RUN_ARTIFACT_DOWNLOAD_TTL_MS = 15 * 60 * 1e3;
|
|
60911
61542
|
SCHEDULED_RUN_ARTIFACT_MAX_BYTES = 2e6;
|
|
@@ -61123,7 +61754,7 @@ async function reconcileDiscoveredNangoConnections(identity, discovered) {
|
|
|
61123
61754
|
updated_at = excluded.updated_at
|
|
61124
61755
|
`,
|
|
61125
61756
|
args: [
|
|
61126
|
-
(0,
|
|
61757
|
+
(0, import_node_crypto39.randomUUID)(),
|
|
61127
61758
|
userId,
|
|
61128
61759
|
connection.providerConfigKey,
|
|
61129
61760
|
connection.provider,
|
|
@@ -61194,7 +61825,7 @@ async function recordServiceConnectionHealth(args) {
|
|
|
61194
61825
|
});
|
|
61195
61826
|
await getDb().execute({
|
|
61196
61827
|
sql: `INSERT INTO service_connection_health_events (id, connection_id, operational_status, failure_code, retryable, evidence_source) VALUES (?, ?, ?, ?, ?, ?)`,
|
|
61197
|
-
args: [(0,
|
|
61828
|
+
args: [(0, import_node_crypto39.randomUUID)(), args.connectionId, args.operationalStatus, args.failureCode ?? null, args.retryable == null ? null : args.retryable ? 1 : 0, args.evidenceSource]
|
|
61198
61829
|
});
|
|
61199
61830
|
}
|
|
61200
61831
|
async function setServiceConnectionActions(identity, connectionId, enabled) {
|
|
@@ -61234,7 +61865,7 @@ async function claimServiceConnectionAction(args) {
|
|
|
61234
61865
|
if (!connection) throw new Error("service_connection_not_found");
|
|
61235
61866
|
const inserted = await getDb().execute({
|
|
61236
61867
|
sql: `INSERT OR IGNORE INTO service_connection_action_audit (id, connection_id, user_id, tool, request_id, status, request_digest) VALUES (?, ?, ?, ?, ?, 'started', ?)`,
|
|
61237
|
-
args: [(0,
|
|
61868
|
+
args: [(0, import_node_crypto39.randomUUID)(), connection.id, connection.userId, args.tool, args.requestId, args.requestDigest]
|
|
61238
61869
|
});
|
|
61239
61870
|
if (Number(inserted.rowsAffected ?? 0) === 1) return { claimed: true };
|
|
61240
61871
|
const existing = await getDb().execute({
|
|
@@ -61259,11 +61890,11 @@ async function claimServiceConnectionAction(args) {
|
|
|
61259
61890
|
...result !== void 0 ? { result } : {}
|
|
61260
61891
|
};
|
|
61261
61892
|
}
|
|
61262
|
-
var
|
|
61893
|
+
var import_node_crypto39, schemaReady4, schemaDb4;
|
|
61263
61894
|
var init_service_connections = __esm({
|
|
61264
61895
|
"src/api/service-connections.ts"() {
|
|
61265
61896
|
"use strict";
|
|
61266
|
-
|
|
61897
|
+
import_node_crypto39 = require("crypto");
|
|
61267
61898
|
init_db();
|
|
61268
61899
|
schemaReady4 = null;
|
|
61269
61900
|
schemaDb4 = null;
|
|
@@ -61277,8 +61908,8 @@ function signingSecret() {
|
|
|
61277
61908
|
return secret2;
|
|
61278
61909
|
}
|
|
61279
61910
|
function schedulerIntegrationSignature(args) {
|
|
61280
|
-
const bodyHash = (0,
|
|
61281
|
-
return (0,
|
|
61911
|
+
const bodyHash = (0, import_node_crypto40.createHash)("sha256").update(args.body).digest("hex");
|
|
61912
|
+
return (0, import_node_crypto40.createHmac)("sha256", args.secret).update(`${args.method.toUpperCase()}
|
|
61282
61913
|
${args.path}
|
|
61283
61914
|
${args.timestamp}
|
|
61284
61915
|
${args.nonce}
|
|
@@ -61325,17 +61956,17 @@ async function verifySchedulerIntegrationRequest(request, rawBody) {
|
|
|
61325
61956
|
});
|
|
61326
61957
|
const suppliedBytes = Buffer.from(signature, "hex");
|
|
61327
61958
|
const expectedBytes = Buffer.from(expected, "hex");
|
|
61328
|
-
if (suppliedBytes.length !== expectedBytes.length || !(0,
|
|
61959
|
+
if (suppliedBytes.length !== expectedBytes.length || !(0, import_node_crypto40.timingSafeEqual)(suppliedBytes, expectedBytes)) {
|
|
61329
61960
|
throw new SchedulerIntegrationAuthError("invalid_signature");
|
|
61330
61961
|
}
|
|
61331
61962
|
await claimNonce(nonce, timestampMs);
|
|
61332
61963
|
return { requestId };
|
|
61333
61964
|
}
|
|
61334
|
-
var
|
|
61965
|
+
var import_node_crypto40, MAX_CLOCK_SKEW_MS, SchedulerIntegrationAuthError;
|
|
61335
61966
|
var init_scheduler_integration_auth = __esm({
|
|
61336
61967
|
"src/api/scheduler-integration-auth.ts"() {
|
|
61337
61968
|
"use strict";
|
|
61338
|
-
|
|
61969
|
+
import_node_crypto40 = require("crypto");
|
|
61339
61970
|
init_db();
|
|
61340
61971
|
init_service_connections();
|
|
61341
61972
|
MAX_CLOCK_SKEW_MS = 5 * 60 * 1e3;
|
|
@@ -61619,7 +62250,7 @@ var init_site_extract_reconciliation = __esm({
|
|
|
61619
62250
|
|
|
61620
62251
|
// src/api/page-diff.ts
|
|
61621
62252
|
function sha256Hex(value) {
|
|
61622
|
-
return (0,
|
|
62253
|
+
return (0, import_node_crypto41.createHash)("sha256").update(value).digest("hex");
|
|
61623
62254
|
}
|
|
61624
62255
|
function truncateForStorage(value, maxChars = MAX_SNAPSHOT_CONTENT_CHARS) {
|
|
61625
62256
|
if (value.length <= maxChars) return { value, truncated: false };
|
|
@@ -61676,11 +62307,11 @@ function diffPageContent(oldContent, newContent) {
|
|
|
61676
62307
|
totalChangedLineCount
|
|
61677
62308
|
};
|
|
61678
62309
|
}
|
|
61679
|
-
var
|
|
62310
|
+
var import_node_crypto41, import_diff, MAX_SNAPSHOT_CONTENT_CHARS, MAX_DIFF_HUNKS, MAX_DIFF_LINES_PER_RESPONSE;
|
|
61680
62311
|
var init_page_diff = __esm({
|
|
61681
62312
|
"src/api/page-diff.ts"() {
|
|
61682
62313
|
"use strict";
|
|
61683
|
-
|
|
62314
|
+
import_node_crypto41 = require("crypto");
|
|
61684
62315
|
import_diff = require("diff");
|
|
61685
62316
|
MAX_SNAPSHOT_CONTENT_CHARS = 25e4;
|
|
61686
62317
|
MAX_DIFF_HUNKS = 200;
|
|
@@ -61754,7 +62385,7 @@ var init_scrape_vault_sink = __esm({
|
|
|
61754
62385
|
|
|
61755
62386
|
// src/api/scrape-image-sink.ts
|
|
61756
62387
|
function idempotencyKey2(userId, vault, input) {
|
|
61757
|
-
return `scrape-image-${(0,
|
|
62388
|
+
return `scrape-image-${(0, import_node_crypto42.createHash)("sha256").update(`${userId}\0${vault}\0${input.sourceKind}\0${input.sourceUrl}\0${input.imageUrl ?? ""}\0${input.imageBase64 ?? ""}`).digest("hex")}`;
|
|
61758
62389
|
}
|
|
61759
62390
|
async function persistScrapeImagesToMemory(user, inputs, vault) {
|
|
61760
62391
|
const selected = inputs.slice(0, MAX_IMAGES_PER_SCRAPE);
|
|
@@ -61796,11 +62427,11 @@ async function persistScrapeImagesToMemory(user, inputs, vault) {
|
|
|
61796
62427
|
assets
|
|
61797
62428
|
};
|
|
61798
62429
|
}
|
|
61799
|
-
var
|
|
62430
|
+
var import_node_crypto42, MAX_IMAGES_PER_SCRAPE;
|
|
61800
62431
|
var init_scrape_image_sink = __esm({
|
|
61801
62432
|
"src/api/scrape-image-sink.ts"() {
|
|
61802
62433
|
"use strict";
|
|
61803
|
-
|
|
62434
|
+
import_node_crypto42 = require("crypto");
|
|
61804
62435
|
init_memory();
|
|
61805
62436
|
MAX_IMAGES_PER_SCRAPE = 25;
|
|
61806
62437
|
}
|
|
@@ -62253,7 +62884,7 @@ function canonicalJson(value) {
|
|
|
62253
62884
|
return JSON.stringify(value);
|
|
62254
62885
|
}
|
|
62255
62886
|
function sha2562(value) {
|
|
62256
|
-
return (0,
|
|
62887
|
+
return (0, import_node_crypto43.createHash)("sha256").update(value).digest("hex");
|
|
62257
62888
|
}
|
|
62258
62889
|
function sensitiveKey(key) {
|
|
62259
62890
|
const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
@@ -62468,11 +63099,11 @@ async function importServiceConnectionToMemory(identity, input, dependencies) {
|
|
|
62468
63099
|
...!searchReady ? { warning: "The snapshot was stored, but no search chunks were indexed yet." } : {}
|
|
62469
63100
|
};
|
|
62470
63101
|
}
|
|
62471
|
-
var
|
|
63102
|
+
var import_node_crypto43, CONNECTION_MEMORY_IMPORT_MAX_ARGS_BYTES, CONNECTION_MEMORY_IMPORT_MAX_RESULT_BYTES, CONNECTION_MEMORY_IMPORT_MAX_STRING_CHARS, CONNECTION_MEMORY_IMPORT_MAX_DEPTH, ConnectionMemoryImportError;
|
|
62472
63103
|
var init_connection_memory_import = __esm({
|
|
62473
63104
|
"src/api/connection-memory-import.ts"() {
|
|
62474
63105
|
"use strict";
|
|
62475
|
-
|
|
63106
|
+
import_node_crypto43 = require("crypto");
|
|
62476
63107
|
init_slugify();
|
|
62477
63108
|
CONNECTION_MEMORY_IMPORT_MAX_ARGS_BYTES = 64 * 1024;
|
|
62478
63109
|
CONNECTION_MEMORY_IMPORT_MAX_RESULT_BYTES = 1e6;
|
|
@@ -62690,7 +63321,7 @@ function finitePositive(value, fallback) {
|
|
|
62690
63321
|
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
62691
63322
|
}
|
|
62692
63323
|
async function collectConnectedDataExport(args) {
|
|
62693
|
-
const exportId = (0,
|
|
63324
|
+
const exportId = (0, import_node_crypto44.randomUUID)();
|
|
62694
63325
|
const now = args.now ?? Date.now;
|
|
62695
63326
|
const startedAt = now();
|
|
62696
63327
|
const budgetMs = finitePositive(CONNECTED_DATA_EXPORT_BUDGET_MS, 24e4);
|
|
@@ -62804,11 +63435,11 @@ ${lines.length ? `${lines.join("\n")}
|
|
|
62804
63435
|
untrustedContent: true
|
|
62805
63436
|
};
|
|
62806
63437
|
}
|
|
62807
|
-
var
|
|
63438
|
+
var import_node_crypto44, 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;
|
|
62808
63439
|
var init_connected_data_export = __esm({
|
|
62809
63440
|
"src/api/connected-data-export.ts"() {
|
|
62810
63441
|
"use strict";
|
|
62811
|
-
|
|
63442
|
+
import_node_crypto44 = require("crypto");
|
|
62812
63443
|
CONNECTED_DATA_INLINE_BUDGET_BYTES = Number(
|
|
62813
63444
|
process.env.MCP_SCRAPER_CONNECTED_DATA_INLINE_BUDGET_BYTES ?? 5e4
|
|
62814
63445
|
);
|
|
@@ -62922,7 +63553,7 @@ async function exportSearchConsoleTableData(args) {
|
|
|
62922
63553
|
offset += rows.length;
|
|
62923
63554
|
if (stoppedForBytes || rows.length < limit || offset >= matchedRows) break;
|
|
62924
63555
|
}
|
|
62925
|
-
const exportId = (0,
|
|
63556
|
+
const exportId = (0, import_node_crypto45.randomUUID)();
|
|
62926
63557
|
const artifact = await args.writeArtifact({
|
|
62927
63558
|
ownerId: args.ownerId,
|
|
62928
63559
|
exportId,
|
|
@@ -62944,11 +63575,11 @@ async function exportSearchConsoleTableData(args) {
|
|
|
62944
63575
|
warnings
|
|
62945
63576
|
};
|
|
62946
63577
|
}
|
|
62947
|
-
var
|
|
63578
|
+
var import_node_crypto45, SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS, SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE, SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES, SEARCH_CONSOLE_TABLE_COLUMNS, SearchConsoleTableExportValidationError;
|
|
62948
63579
|
var init_search_console_table_export = __esm({
|
|
62949
63580
|
"src/api/search-console-table-export.ts"() {
|
|
62950
63581
|
"use strict";
|
|
62951
|
-
|
|
63582
|
+
import_node_crypto45 = require("crypto");
|
|
62952
63583
|
SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS = 5e4;
|
|
62953
63584
|
SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE = 2e3;
|
|
62954
63585
|
SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES = 50 * 1024 * 1024;
|
|
@@ -64127,7 +64758,7 @@ async function listNangoToolsDirect(identity, connectionId) {
|
|
|
64127
64758
|
});
|
|
64128
64759
|
const readTools = [...policies.values()].filter((policy5) => policy5.classification === "read").map((policy5) => policy5.name);
|
|
64129
64760
|
const actionTools = [...policies.values()].filter((policy5) => policy5.classification === "action").map((policy5) => policy5.name);
|
|
64130
|
-
const revision = (0,
|
|
64761
|
+
const revision = (0, import_node_crypto46.createHash)("sha256").update(JSON.stringify(tools.map((tool) => ({ name: tool.name, inputSchema: tool.inputSchema })))).digest("hex");
|
|
64131
64762
|
await updateServiceConnectionTools(connection.id, readTools, actionTools, revision);
|
|
64132
64763
|
const refreshed = await getOwnedServiceConnection(identity, connection.id);
|
|
64133
64764
|
return { connection: refreshed ?? { ...connection, readTools, actionTools, toolRevision: revision }, tools };
|
|
@@ -64154,8 +64785,8 @@ async function callNangoToolDirect(args) {
|
|
|
64154
64785
|
identity: args.identity,
|
|
64155
64786
|
ratePolicyVersion: CONNECTED_USAGE_RATE_POLICY_VERSION
|
|
64156
64787
|
});
|
|
64157
|
-
const requestId = args.requestId?.trim() || (0,
|
|
64158
|
-
const idempotencyKey3 = `main-nango:${(0,
|
|
64788
|
+
const requestId = args.requestId?.trim() || (0, import_node_crypto46.randomUUID)();
|
|
64789
|
+
const idempotencyKey3 = `main-nango:${(0, import_node_crypto46.createHash)("sha256").update(args.identity.toLowerCase()).update("\0").update(connection.id).update("\0").update(args.tool).update("\0").update(requestId).digest("hex")}`;
|
|
64159
64790
|
const startedAt = /* @__PURE__ */ new Date();
|
|
64160
64791
|
const started = performance.now();
|
|
64161
64792
|
let result;
|
|
@@ -64180,7 +64811,7 @@ async function callNangoToolDirect(args) {
|
|
|
64180
64811
|
toolName: args.tool,
|
|
64181
64812
|
operationKind: args.operationKind ?? args.classification,
|
|
64182
64813
|
outcome: providerError ? "error" : "partial",
|
|
64183
|
-
requestId: requestId.length <= 200 ? requestId : (0,
|
|
64814
|
+
requestId: requestId.length <= 200 ? requestId : (0, import_node_crypto46.createHash)("sha256").update(requestId).digest("hex"),
|
|
64184
64815
|
startedAt: startedAt.toISOString(),
|
|
64185
64816
|
completedAt: completedAt.toISOString()
|
|
64186
64817
|
}
|
|
@@ -64222,15 +64853,15 @@ async function describeNangoToolDirect(identity, connectionId, toolName) {
|
|
|
64222
64853
|
providerContractHash: MAIN_INTEGRATION_CONTRACT_HASH,
|
|
64223
64854
|
protocolVersion: null,
|
|
64224
64855
|
schemaSource: "live_tools_list",
|
|
64225
|
-
schemaHash: (0,
|
|
64856
|
+
schemaHash: (0, import_node_crypto46.createHash)("sha256").update(JSON.stringify(projected)).digest("hex"),
|
|
64226
64857
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
64227
64858
|
};
|
|
64228
64859
|
}
|
|
64229
|
-
var
|
|
64860
|
+
var import_node_crypto46, 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;
|
|
64230
64861
|
var init_main_nango_transport = __esm({
|
|
64231
64862
|
"src/api/main-nango-transport.ts"() {
|
|
64232
64863
|
"use strict";
|
|
64233
|
-
|
|
64864
|
+
import_node_crypto46 = require("crypto");
|
|
64234
64865
|
import_client13 = require("@modelcontextprotocol/client");
|
|
64235
64866
|
init_service_connections();
|
|
64236
64867
|
init_connected_usage_billing();
|
|
@@ -64854,8 +65485,8 @@ async function setScheduleConnectionActionsEnabled(identity, connectionId, enabl
|
|
|
64854
65485
|
return data.connection.actionsEnabled === true;
|
|
64855
65486
|
}
|
|
64856
65487
|
async function callScheduleConnectionAction(identity, connectionId, input, tool, idempotencyKey3) {
|
|
64857
|
-
const requestId = `main-connected-action:${(0,
|
|
64858
|
-
const requestDigest = (0,
|
|
65488
|
+
const requestId = `main-connected-action:${(0, import_node_crypto47.createHash)("sha256").update(identity).update("\0").update(idempotencyKey3?.trim() || (0, import_node_crypto47.randomUUID)()).digest("hex")}`;
|
|
65489
|
+
const requestDigest = (0, import_node_crypto47.createHash)("sha256").update(connectionId).update("\0").update(tool?.trim() ?? "").update("\0").update(canonicalJson2(input)).digest("hex");
|
|
64859
65490
|
if (mainOwnsIntegrations()) {
|
|
64860
65491
|
const selectedTool = tool?.trim();
|
|
64861
65492
|
if (!selectedTool) throw new NangoControlError("An action tool is required.", 400, "invalid_request", false);
|
|
@@ -65006,7 +65637,7 @@ function canonicalJson2(value) {
|
|
|
65006
65637
|
return JSON.stringify(value);
|
|
65007
65638
|
}
|
|
65008
65639
|
function projectedToolSchemaHash(tool) {
|
|
65009
|
-
return (0,
|
|
65640
|
+
return (0, import_node_crypto47.createHash)("sha256").update(canonicalJson2(tool)).digest("hex");
|
|
65010
65641
|
}
|
|
65011
65642
|
async function describeNangoTool(identity, connectionId, tool, fresh) {
|
|
65012
65643
|
if (mainOwnsIntegrations()) {
|
|
@@ -65283,11 +65914,11 @@ async function callMainOwnedExportPage(identity, input) {
|
|
|
65283
65914
|
untrustedContent: true
|
|
65284
65915
|
};
|
|
65285
65916
|
}
|
|
65286
|
-
var
|
|
65917
|
+
var import_node_crypto47, 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;
|
|
65287
65918
|
var init_nango_control = __esm({
|
|
65288
65919
|
"src/api/nango-control.ts"() {
|
|
65289
65920
|
"use strict";
|
|
65290
|
-
|
|
65921
|
+
import_node_crypto47 = require("crypto");
|
|
65291
65922
|
init_connected_data_export();
|
|
65292
65923
|
init_slack_connected_data_export();
|
|
65293
65924
|
init_main_nango_transport();
|
|
@@ -65643,7 +66274,7 @@ async function callResendRead(identity, connectionId, tool, args) {
|
|
|
65643
66274
|
return isRecord5(data) ? data.result ?? data : data;
|
|
65644
66275
|
}
|
|
65645
66276
|
async function callResendAction(identity, connectionId, tool, input, idempotencyKey3) {
|
|
65646
|
-
const requestId = `main-resend-action:${(0,
|
|
66277
|
+
const requestId = `main-resend-action:${(0, import_node_crypto48.createHash)("sha256").update(identity).update("\0").update(idempotencyKey3.trim()).digest("hex")}`;
|
|
65647
66278
|
const body = await controlRequest2("/api/internal/resend/actions/call", {
|
|
65648
66279
|
method: "POST",
|
|
65649
66280
|
headers: { "x-request-id": requestId },
|
|
@@ -65708,12 +66339,12 @@ async function callResendExportPage(identity, input) {
|
|
|
65708
66339
|
untrustedContent: true
|
|
65709
66340
|
};
|
|
65710
66341
|
}
|
|
65711
|
-
var
|
|
66342
|
+
var import_node_crypto48, DEFAULT_CONNECTION_CONTROL_URL, RESEND_PROVIDER_CONFIG_KEY, RESEND_LOGO_URL, RESEND_DOCS_URL, RESEND_ADMIN_BLOCKED_TOOLS, RESEND_CONNECTION_SYNC_REQUIRED_TOOLS, ResendControlError;
|
|
65712
66343
|
var init_resend_control = __esm({
|
|
65713
66344
|
"src/api/resend-control.ts"() {
|
|
65714
66345
|
"use strict";
|
|
65715
66346
|
init_connected_data_export();
|
|
65716
|
-
|
|
66347
|
+
import_node_crypto48 = require("crypto");
|
|
65717
66348
|
DEFAULT_CONNECTION_CONTROL_URL = "https://mcp-scraper-scheduler.vercel.app";
|
|
65718
66349
|
RESEND_PROVIDER_CONFIG_KEY = "resend";
|
|
65719
66350
|
RESEND_LOGO_URL = "https://cdn.resend.com/brand/resend-icon-black.svg";
|
|
@@ -66231,7 +66862,7 @@ async function chargeTierChangeNow(stripeClient, subscriptionId, customerId) {
|
|
|
66231
66862
|
return { ok: false, amountDue: 0, error: err instanceof Error ? err.message : "Unable to charge the plan change immediately." };
|
|
66232
66863
|
}
|
|
66233
66864
|
}
|
|
66234
|
-
var import_resend3,
|
|
66865
|
+
var import_resend3, import_node_crypto49, import_hono35, import_hono36, import_factory7, import_cookie2, import_stripe2, secureCookies2, isProduction2, sessionCookieOptions2, requireAllowedOrigin, auth3, sessionAuth, requireIntegrationsTier, requirePaidSchedulingTier, app, deploymentProfile, STRIPE_API_VERSION, SYNC_HARVEST_TIMEOUT_OVERRIDE_MS;
|
|
66235
66866
|
var init_server = __esm({
|
|
66236
66867
|
"src/api/server.ts"() {
|
|
66237
66868
|
"use strict";
|
|
@@ -66244,7 +66875,7 @@ var init_server = __esm({
|
|
|
66244
66875
|
init_og();
|
|
66245
66876
|
import_resend3 = require("resend");
|
|
66246
66877
|
init_url_utils();
|
|
66247
|
-
|
|
66878
|
+
import_node_crypto49 = require("crypto");
|
|
66248
66879
|
init_kpo_extractor();
|
|
66249
66880
|
init_screenshot();
|
|
66250
66881
|
init_media_extractor();
|
|
@@ -67776,7 +68407,7 @@ var init_server = __esm({
|
|
|
67776
68407
|
if (!harvestOk) return c.json(insufficientBalanceResponse(harvestBal, harvestCost), 402);
|
|
67777
68408
|
jobId2 = await createJob(user.id, options.query, { ...options, billingHoldMc: harvestCost }, body.callback_url);
|
|
67778
68409
|
} else {
|
|
67779
|
-
jobId2 = (0,
|
|
68410
|
+
jobId2 = (0, import_node_crypto49.randomUUID)();
|
|
67780
68411
|
const billingDebitKey = `paa-harvest:${jobId2}:hold`;
|
|
67781
68412
|
const description = `PAA harvest: ${options.query}`.slice(0, 500);
|
|
67782
68413
|
const hold = await debitMcIdempotent(
|