@cat-factory/integrations 0.6.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/LICENSE +21 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/datadog/DatadogClient.d.ts +54 -0
- package/dist/modules/datadog/DatadogClient.d.ts.map +1 -0
- package/dist/modules/datadog/DatadogClient.js +132 -0
- package/dist/modules/datadog/DatadogClient.js.map +1 -0
- package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts +30 -0
- package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts.map +1 -0
- package/dist/modules/datadog/DatadogReleaseHealthProvider.js +101 -0
- package/dist/modules/datadog/DatadogReleaseHealthProvider.js.map +1 -0
- package/dist/modules/datadog/datadog.logic.d.ts +37 -0
- package/dist/modules/datadog/datadog.logic.d.ts.map +1 -0
- package/dist/modules/datadog/datadog.logic.js +90 -0
- package/dist/modules/datadog/datadog.logic.js.map +1 -0
- package/dist/modules/documents/ConfluenceProvider.d.ts +29 -0
- package/dist/modules/documents/ConfluenceProvider.d.ts.map +1 -0
- package/dist/modules/documents/ConfluenceProvider.js +180 -0
- package/dist/modules/documents/ConfluenceProvider.js.map +1 -0
- package/dist/modules/documents/DocumentConnectionService.d.ts +30 -0
- package/dist/modules/documents/DocumentConnectionService.d.ts.map +1 -0
- package/dist/modules/documents/DocumentConnectionService.js +69 -0
- package/dist/modules/documents/DocumentConnectionService.js.map +1 -0
- package/dist/modules/documents/DocumentImportService.d.ts +34 -0
- package/dist/modules/documents/DocumentImportService.d.ts.map +1 -0
- package/dist/modules/documents/DocumentImportService.js +83 -0
- package/dist/modules/documents/DocumentImportService.js.map +1 -0
- package/dist/modules/documents/DocumentLinkService.d.ts +31 -0
- package/dist/modules/documents/DocumentLinkService.d.ts.map +1 -0
- package/dist/modules/documents/DocumentLinkService.js +75 -0
- package/dist/modules/documents/DocumentLinkService.js.map +1 -0
- package/dist/modules/documents/DocumentPlannerService.d.ts +23 -0
- package/dist/modules/documents/DocumentPlannerService.d.ts.map +1 -0
- package/dist/modules/documents/DocumentPlannerService.js +96 -0
- package/dist/modules/documents/DocumentPlannerService.js.map +1 -0
- package/dist/modules/documents/GitHubDocsProvider.d.ts +42 -0
- package/dist/modules/documents/GitHubDocsProvider.d.ts.map +1 -0
- package/dist/modules/documents/GitHubDocsProvider.js +86 -0
- package/dist/modules/documents/GitHubDocsProvider.js.map +1 -0
- package/dist/modules/documents/NotionProvider.d.ts +32 -0
- package/dist/modules/documents/NotionProvider.d.ts.map +1 -0
- package/dist/modules/documents/NotionProvider.js +221 -0
- package/dist/modules/documents/NotionProvider.js.map +1 -0
- package/dist/modules/documents/confluence.logic.d.ts +37 -0
- package/dist/modules/documents/confluence.logic.d.ts.map +1 -0
- package/dist/modules/documents/confluence.logic.js +133 -0
- package/dist/modules/documents/confluence.logic.js.map +1 -0
- package/dist/modules/documents/documents.logic.d.ts +22 -0
- package/dist/modules/documents/documents.logic.d.ts.map +1 -0
- package/dist/modules/documents/documents.logic.js +138 -0
- package/dist/modules/documents/documents.logic.js.map +1 -0
- package/dist/modules/documents/github-docs.logic.d.ts +52 -0
- package/dist/modules/documents/github-docs.logic.d.ts.map +1 -0
- package/dist/modules/documents/github-docs.logic.js +94 -0
- package/dist/modules/documents/github-docs.logic.js.map +1 -0
- package/dist/modules/documents/notion.logic.d.ts +31 -0
- package/dist/modules/documents/notion.logic.d.ts.map +1 -0
- package/dist/modules/documents/notion.logic.js +142 -0
- package/dist/modules/documents/notion.logic.js.map +1 -0
- package/dist/modules/email/EmailConnectionService.d.ts +34 -0
- package/dist/modules/email/EmailConnectionService.d.ts.map +1 -0
- package/dist/modules/email/EmailConnectionService.js +82 -0
- package/dist/modules/email/EmailConnectionService.js.map +1 -0
- package/dist/modules/email/adapters.d.ts +39 -0
- package/dist/modules/email/adapters.d.ts.map +1 -0
- package/dist/modules/email/adapters.js +79 -0
- package/dist/modules/email/adapters.js.map +1 -0
- package/dist/modules/environments/EnvironmentConnectionService.d.ts +42 -0
- package/dist/modules/environments/EnvironmentConnectionService.d.ts.map +1 -0
- package/dist/modules/environments/EnvironmentConnectionService.js +120 -0
- package/dist/modules/environments/EnvironmentConnectionService.js.map +1 -0
- package/dist/modules/environments/EnvironmentProvisioningService.d.ts +56 -0
- package/dist/modules/environments/EnvironmentProvisioningService.d.ts.map +1 -0
- package/dist/modules/environments/EnvironmentProvisioningService.js +153 -0
- package/dist/modules/environments/EnvironmentProvisioningService.js.map +1 -0
- package/dist/modules/environments/EnvironmentTeardownService.d.ts +24 -0
- package/dist/modules/environments/EnvironmentTeardownService.d.ts.map +1 -0
- package/dist/modules/environments/EnvironmentTeardownService.js +54 -0
- package/dist/modules/environments/EnvironmentTeardownService.js.map +1 -0
- package/dist/modules/environments/HttpEnvironmentProvider.d.ts +30 -0
- package/dist/modules/environments/HttpEnvironmentProvider.d.ts.map +1 -0
- package/dist/modules/environments/HttpEnvironmentProvider.js +316 -0
- package/dist/modules/environments/HttpEnvironmentProvider.js.map +1 -0
- package/dist/modules/environments/environments.logic.d.ts +50 -0
- package/dist/modules/environments/environments.logic.d.ts.map +1 -0
- package/dist/modules/environments/environments.logic.js +257 -0
- package/dist/modules/environments/environments.logic.js.map +1 -0
- package/dist/modules/github/GitHubInstallationService.d.ts +66 -0
- package/dist/modules/github/GitHubInstallationService.d.ts.map +1 -0
- package/dist/modules/github/GitHubInstallationService.js +143 -0
- package/dist/modules/github/GitHubInstallationService.js.map +1 -0
- package/dist/modules/github/GitHubService.d.ts +29 -0
- package/dist/modules/github/GitHubService.d.ts.map +1 -0
- package/dist/modules/github/GitHubService.js +61 -0
- package/dist/modules/github/GitHubService.js.map +1 -0
- package/dist/modules/github/GitHubSyncService.d.ts +97 -0
- package/dist/modules/github/GitHubSyncService.d.ts.map +1 -0
- package/dist/modules/github/GitHubSyncService.js +241 -0
- package/dist/modules/github/GitHubSyncService.js.map +1 -0
- package/dist/modules/github/RepoProvisioningService.d.ts +26 -0
- package/dist/modules/github/RepoProvisioningService.d.ts.map +1 -0
- package/dist/modules/github/RepoProvisioningService.js +36 -0
- package/dist/modules/github/RepoProvisioningService.js.map +1 -0
- package/dist/modules/github/WebhookService.d.ts +28 -0
- package/dist/modules/github/WebhookService.d.ts.map +1 -0
- package/dist/modules/github/WebhookService.js +156 -0
- package/dist/modules/github/WebhookService.js.map +1 -0
- package/dist/modules/github/projection.logic.d.ts +95 -0
- package/dist/modules/github/projection.logic.d.ts.map +1 -0
- package/dist/modules/github/projection.logic.js +94 -0
- package/dist/modules/github/projection.logic.js.map +1 -0
- package/dist/modules/github/provisioning.logic.d.ts +11 -0
- package/dist/modules/github/provisioning.logic.d.ts.map +1 -0
- package/dist/modules/github/provisioning.logic.js +18 -0
- package/dist/modules/github/provisioning.logic.js.map +1 -0
- package/dist/modules/incident/incident.logic.d.ts +16 -0
- package/dist/modules/incident/incident.logic.d.ts.map +1 -0
- package/dist/modules/incident/incident.logic.js +23 -0
- package/dist/modules/incident/incident.logic.js.map +1 -0
- package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts +26 -0
- package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts.map +1 -0
- package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js +84 -0
- package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js.map +1 -0
- package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts +27 -0
- package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts.map +1 -0
- package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js +65 -0
- package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js.map +1 -0
- package/dist/modules/providers/ApiKeyService.d.ts +73 -0
- package/dist/modules/providers/ApiKeyService.d.ts.map +1 -0
- package/dist/modules/providers/ApiKeyService.js +122 -0
- package/dist/modules/providers/ApiKeyService.js.map +1 -0
- package/dist/modules/providers/LocalModelEndpointService.d.ts +52 -0
- package/dist/modules/providers/LocalModelEndpointService.d.ts.map +1 -0
- package/dist/modules/providers/LocalModelEndpointService.js +131 -0
- package/dist/modules/providers/LocalModelEndpointService.js.map +1 -0
- package/dist/modules/providers/PersonalSubscriptionService.d.ts +94 -0
- package/dist/modules/providers/PersonalSubscriptionService.d.ts.map +1 -0
- package/dist/modules/providers/PersonalSubscriptionService.js +218 -0
- package/dist/modules/providers/PersonalSubscriptionService.js.map +1 -0
- package/dist/modules/providers/ProviderSubscriptionService.d.ts +75 -0
- package/dist/modules/providers/ProviderSubscriptionService.d.ts.map +1 -0
- package/dist/modules/providers/ProviderSubscriptionService.js +130 -0
- package/dist/modules/providers/ProviderSubscriptionService.js.map +1 -0
- package/dist/modules/providers/localModelUrl.d.ts +7 -0
- package/dist/modules/providers/localModelUrl.d.ts.map +1 -0
- package/dist/modules/providers/localModelUrl.js +67 -0
- package/dist/modules/providers/localModelUrl.js.map +1 -0
- package/dist/modules/providers/providers.logic.d.ts +23 -0
- package/dist/modules/providers/providers.logic.d.ts.map +1 -0
- package/dist/modules/providers/providers.logic.js +46 -0
- package/dist/modules/providers/providers.logic.js.map +1 -0
- package/dist/modules/runners/HttpRunnerPoolProvider.d.ts +51 -0
- package/dist/modules/runners/HttpRunnerPoolProvider.d.ts.map +1 -0
- package/dist/modules/runners/HttpRunnerPoolProvider.js +304 -0
- package/dist/modules/runners/HttpRunnerPoolProvider.js.map +1 -0
- package/dist/modules/runners/RunnerPoolConnectionService.d.ts +47 -0
- package/dist/modules/runners/RunnerPoolConnectionService.d.ts.map +1 -0
- package/dist/modules/runners/RunnerPoolConnectionService.js +98 -0
- package/dist/modules/runners/RunnerPoolConnectionService.js.map +1 -0
- package/dist/modules/runners/RunnerPoolTransport.d.ts +11 -0
- package/dist/modules/runners/RunnerPoolTransport.d.ts.map +1 -0
- package/dist/modules/runners/RunnerPoolTransport.js +61 -0
- package/dist/modules/runners/RunnerPoolTransport.js.map +1 -0
- package/dist/modules/runners/runners.logic.d.ts +16 -0
- package/dist/modules/runners/runners.logic.d.ts.map +1 -0
- package/dist/modules/runners/runners.logic.js +52 -0
- package/dist/modules/runners/runners.logic.js.map +1 -0
- package/dist/modules/slack/SlackApiClient.d.ts +67 -0
- package/dist/modules/slack/SlackApiClient.d.ts.map +1 -0
- package/dist/modules/slack/SlackApiClient.js +132 -0
- package/dist/modules/slack/SlackApiClient.js.map +1 -0
- package/dist/modules/slack/SlackConnectionService.d.ts +41 -0
- package/dist/modules/slack/SlackConnectionService.d.ts.map +1 -0
- package/dist/modules/slack/SlackConnectionService.js +136 -0
- package/dist/modules/slack/SlackConnectionService.js.map +1 -0
- package/dist/modules/slack/SlackMemberMappingService.d.ts +17 -0
- package/dist/modules/slack/SlackMemberMappingService.d.ts.map +1 -0
- package/dist/modules/slack/SlackMemberMappingService.js +28 -0
- package/dist/modules/slack/SlackMemberMappingService.js.map +1 -0
- package/dist/modules/slack/SlackNotificationChannel.d.ts +45 -0
- package/dist/modules/slack/SlackNotificationChannel.d.ts.map +1 -0
- package/dist/modules/slack/SlackNotificationChannel.js +84 -0
- package/dist/modules/slack/SlackNotificationChannel.js.map +1 -0
- package/dist/modules/slack/SlackSettingsService.d.ts +16 -0
- package/dist/modules/slack/SlackSettingsService.d.ts.map +1 -0
- package/dist/modules/slack/SlackSettingsService.js +41 -0
- package/dist/modules/slack/SlackSettingsService.js.map +1 -0
- package/dist/modules/slack/slack.logic.d.ts +55 -0
- package/dist/modules/slack/slack.logic.d.ts.map +1 -0
- package/dist/modules/slack/slack.logic.js +149 -0
- package/dist/modules/slack/slack.logic.js.map +1 -0
- package/dist/modules/tasks/GitHubIssuesProvider.d.ts +50 -0
- package/dist/modules/tasks/GitHubIssuesProvider.d.ts.map +1 -0
- package/dist/modules/tasks/GitHubIssuesProvider.js +92 -0
- package/dist/modules/tasks/GitHubIssuesProvider.js.map +1 -0
- package/dist/modules/tasks/JiraProvider.d.ts +29 -0
- package/dist/modules/tasks/JiraProvider.d.ts.map +1 -0
- package/dist/modules/tasks/JiraProvider.js +114 -0
- package/dist/modules/tasks/JiraProvider.js.map +1 -0
- package/dist/modules/tasks/TaskConnectionService.d.ts +30 -0
- package/dist/modules/tasks/TaskConnectionService.d.ts.map +1 -0
- package/dist/modules/tasks/TaskConnectionService.js +69 -0
- package/dist/modules/tasks/TaskConnectionService.js.map +1 -0
- package/dist/modules/tasks/TaskImportService.d.ts +34 -0
- package/dist/modules/tasks/TaskImportService.d.ts.map +1 -0
- package/dist/modules/tasks/TaskImportService.js +96 -0
- package/dist/modules/tasks/TaskImportService.js.map +1 -0
- package/dist/modules/tasks/TaskLinkService.d.ts +30 -0
- package/dist/modules/tasks/TaskLinkService.d.ts.map +1 -0
- package/dist/modules/tasks/TaskLinkService.js +56 -0
- package/dist/modules/tasks/TaskLinkService.js.map +1 -0
- package/dist/modules/tasks/github-issues.logic.d.ts +35 -0
- package/dist/modules/tasks/github-issues.logic.d.ts.map +1 -0
- package/dist/modules/tasks/github-issues.logic.js +67 -0
- package/dist/modules/tasks/github-issues.logic.js.map +1 -0
- package/dist/modules/tasks/jira.logic.d.ts +28 -0
- package/dist/modules/tasks/jira.logic.d.ts.map +1 -0
- package/dist/modules/tasks/jira.logic.js +151 -0
- package/dist/modules/tasks/jira.logic.js.map +1 -0
- package/dist/modules/tasks/tasks.logic.d.ts +12 -0
- package/dist/modules/tasks/tasks.logic.d.ts.map +1 -0
- package/dist/modules/tasks/tasks.logic.js +17 -0
- package/dist/modules/tasks/tasks.logic.js.map +1 -0
- package/dist/modules/tracker/TicketTrackerService.d.ts +45 -0
- package/dist/modules/tracker/TicketTrackerService.d.ts.map +1 -0
- package/dist/modules/tracker/TicketTrackerService.js +52 -0
- package/dist/modules/tracker/TicketTrackerService.js.map +1 -0
- package/dist/modules/tracker/base64.d.ts +2 -0
- package/dist/modules/tracker/base64.d.ts.map +1 -0
- package/dist/modules/tracker/base64.js +18 -0
- package/dist/modules/tracker/base64.js.map +1 -0
- package/dist/modules/tracker/github.create.logic.d.ts +16 -0
- package/dist/modules/tracker/github.create.logic.d.ts.map +1 -0
- package/dist/modules/tracker/github.create.logic.js +25 -0
- package/dist/modules/tracker/github.create.logic.js.map +1 -0
- package/dist/modules/tracker/jira.create.logic.d.ts +31 -0
- package/dist/modules/tracker/jira.create.logic.d.ts.map +1 -0
- package/dist/modules/tracker/jira.create.logic.js +59 -0
- package/dist/modules/tracker/jira.create.logic.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { DocumentSearchResult, DocumentSourceDescriptor } from '@cat-factory/kernel';
|
|
2
|
+
/** What the connect UI renders, and which credentials the provider needs. */
|
|
3
|
+
export declare const CONFLUENCE_DESCRIPTOR: DocumentSourceDescriptor;
|
|
4
|
+
/**
|
|
5
|
+
* Build the CQL for a free-text page search: match the term anywhere in a page's
|
|
6
|
+
* text, newest first. Confluence's `text ~` is a fuzzy/word search, which is
|
|
7
|
+
* exactly what a "find a page" box wants.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildConfluenceSearchCql(query: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Map a Confluence search response into lean hits. The endpoint nests the page
|
|
12
|
+
* under `content` (search API) or returns it flat (content/search API); we read
|
|
13
|
+
* either. URLs are resolved against the response's `base`, falling back to the
|
|
14
|
+
* site's `/wiki` base when absent.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseConfluenceSearchResults(json: unknown, fallbackBase: string): DocumentSearchResult[];
|
|
17
|
+
/** Drop a trailing slash and a trailing `/wiki` so we can build paths uniformly. */
|
|
18
|
+
export declare function normalizeBaseUrl(baseUrl: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a Confluence page id from raw user input: a bare numeric id, a modern
|
|
21
|
+
* `/wiki/spaces/…/pages/<id>/…` URL, or a legacy `?pageId=<id>` URL.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseConfluenceRef(input: string): string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Validate a (normalized) Confluence base URL before it is stored and later
|
|
26
|
+
* fetched. Delegates to the shared Atlassian guard (`https`-only, no embedded
|
|
27
|
+
* credentials, no internal/private hosts), throwing {@link ValidationError} on
|
|
28
|
+
* anything unsafe.
|
|
29
|
+
*/
|
|
30
|
+
export declare function assertSafeConfluenceBaseUrl(baseUrl: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Convert Confluence storage-format XHTML into the lightweight Markdown the
|
|
33
|
+
* generic planner/excerpt logic consumes: headings become `#`/`##`/`###`, list
|
|
34
|
+
* items become `- `, and block boundaries become newlines.
|
|
35
|
+
*/
|
|
36
|
+
export declare function confluenceStorageToMarkdown(html: string): string;
|
|
37
|
+
//# sourceMappingURL=confluence.logic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confluence.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/confluence.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AASzF,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,EAAE,wBAuBnC,CAAA;AAOD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE9D;AAYD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,OAAO,EACb,YAAY,EAAE,MAAM,GACnB,oBAAoB,EAAE,CAkBxB;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ/D;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEjE;AAaD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAWhE"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { assertSafeAtlassianBaseUrl, normalizeAtlassianBaseUrl } from '@cat-factory/kernel';
|
|
2
|
+
// Confluence-specific pure logic, kept out of the worker so it is unit-testable
|
|
3
|
+
// without a live site: parsing a page id out of user input, validating/securing
|
|
4
|
+
// the site base URL, and converting storage-format XHTML into the lightweight
|
|
5
|
+
// Markdown the generic planner consumes. The fetch itself lives in the worker's
|
|
6
|
+
// ConfluenceProvider.
|
|
7
|
+
/** What the connect UI renders, and which credentials the provider needs. */
|
|
8
|
+
export const CONFLUENCE_DESCRIPTOR = {
|
|
9
|
+
source: 'confluence',
|
|
10
|
+
label: 'Confluence',
|
|
11
|
+
icon: 'i-lucide-book-open',
|
|
12
|
+
credentialFields: [
|
|
13
|
+
{
|
|
14
|
+
key: 'baseUrl',
|
|
15
|
+
label: 'Site URL',
|
|
16
|
+
placeholder: 'https://your-team.atlassian.net',
|
|
17
|
+
help: 'e.g. https://your-team.atlassian.net',
|
|
18
|
+
},
|
|
19
|
+
{ key: 'accountEmail', label: 'Account email', placeholder: 'you@company.com' },
|
|
20
|
+
{
|
|
21
|
+
key: 'apiToken',
|
|
22
|
+
label: 'API token',
|
|
23
|
+
secret: true,
|
|
24
|
+
placeholder: 'Paste a Confluence API token',
|
|
25
|
+
help: 'Create one at id.atlassian.com → Security → API tokens',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
refLabel: 'Page URL or ID',
|
|
29
|
+
refPlaceholder: 'https://…/pages/12345/Title or 12345',
|
|
30
|
+
searchable: true,
|
|
31
|
+
};
|
|
32
|
+
/** Escape a user string for embedding inside a CQL double-quoted literal. */
|
|
33
|
+
function escapeCql(query) {
|
|
34
|
+
return query.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Build the CQL for a free-text page search: match the term anywhere in a page's
|
|
38
|
+
* text, newest first. Confluence's `text ~` is a fuzzy/word search, which is
|
|
39
|
+
* exactly what a "find a page" box wants.
|
|
40
|
+
*/
|
|
41
|
+
export function buildConfluenceSearchCql(query) {
|
|
42
|
+
return `type = page AND text ~ "${escapeCql(query.trim())}" ORDER BY lastmodified DESC`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Map a Confluence search response into lean hits. The endpoint nests the page
|
|
46
|
+
* under `content` (search API) or returns it flat (content/search API); we read
|
|
47
|
+
* either. URLs are resolved against the response's `base`, falling back to the
|
|
48
|
+
* site's `/wiki` base when absent.
|
|
49
|
+
*/
|
|
50
|
+
export function parseConfluenceSearchResults(json, fallbackBase) {
|
|
51
|
+
const body = (json ?? {});
|
|
52
|
+
const base = body._links?.base ?? `${fallbackBase.replace(/\/+$/, '')}/wiki`;
|
|
53
|
+
const out = [];
|
|
54
|
+
for (const row of Array.isArray(body.results) ? body.results : []) {
|
|
55
|
+
const content = row.content ?? row;
|
|
56
|
+
const id = content.id;
|
|
57
|
+
if (!id)
|
|
58
|
+
continue;
|
|
59
|
+
const webui = row._links?.webui ?? '';
|
|
60
|
+
out.push({
|
|
61
|
+
source: 'confluence',
|
|
62
|
+
externalId: id,
|
|
63
|
+
title: content.title ?? '(untitled)',
|
|
64
|
+
url: webui ? `${base}${webui}` : `${base}/pages/${id}`,
|
|
65
|
+
excerpt: '',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
/** Drop a trailing slash and a trailing `/wiki` so we can build paths uniformly. */
|
|
71
|
+
export function normalizeBaseUrl(baseUrl) {
|
|
72
|
+
return normalizeAtlassianBaseUrl(baseUrl);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Resolve a Confluence page id from raw user input: a bare numeric id, a modern
|
|
76
|
+
* `/wiki/spaces/…/pages/<id>/…` URL, or a legacy `?pageId=<id>` URL.
|
|
77
|
+
*/
|
|
78
|
+
export function parseConfluenceRef(input) {
|
|
79
|
+
const trimmed = input.trim();
|
|
80
|
+
if (/^\d+$/.test(trimmed))
|
|
81
|
+
return trimmed;
|
|
82
|
+
const pageIdParam = trimmed.match(/[?&]pageId=(\d+)/);
|
|
83
|
+
if (pageIdParam)
|
|
84
|
+
return pageIdParam[1];
|
|
85
|
+
const pathMatch = trimmed.match(/\/pages\/(?:[a-z-]+\/)?(\d+)/i);
|
|
86
|
+
if (pathMatch)
|
|
87
|
+
return pathMatch[1];
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Validate a (normalized) Confluence base URL before it is stored and later
|
|
92
|
+
* fetched. Delegates to the shared Atlassian guard (`https`-only, no embedded
|
|
93
|
+
* credentials, no internal/private hosts), throwing {@link ValidationError} on
|
|
94
|
+
* anything unsafe.
|
|
95
|
+
*/
|
|
96
|
+
export function assertSafeConfluenceBaseUrl(baseUrl) {
|
|
97
|
+
assertSafeAtlassianBaseUrl(baseUrl);
|
|
98
|
+
}
|
|
99
|
+
/** Decode the handful of XHTML entities Confluence storage format emits. */
|
|
100
|
+
function decodeEntities(text) {
|
|
101
|
+
return text
|
|
102
|
+
.replace(/ /gi, ' ')
|
|
103
|
+
.replace(/&/gi, '&')
|
|
104
|
+
.replace(/</gi, '<')
|
|
105
|
+
.replace(/>/gi, '>')
|
|
106
|
+
.replace(/"/gi, '"')
|
|
107
|
+
.replace(/?9;|'/gi, "'");
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Convert Confluence storage-format XHTML into the lightweight Markdown the
|
|
111
|
+
* generic planner/excerpt logic consumes: headings become `#`/`##`/`###`, list
|
|
112
|
+
* items become `- `, and block boundaries become newlines.
|
|
113
|
+
*/
|
|
114
|
+
export function confluenceStorageToMarkdown(html) {
|
|
115
|
+
const withMarkers = html
|
|
116
|
+
.replace(/<h1\b[^>]*>([\s\S]*?)<\/h1>/gi, (_m, c) => `\n# ${stripTags(c)}\n`)
|
|
117
|
+
.replace(/<h2\b[^>]*>([\s\S]*?)<\/h2>/gi, (_m, c) => `\n## ${stripTags(c)}\n`)
|
|
118
|
+
.replace(/<h[3-6]\b[^>]*>([\s\S]*?)<\/h[3-6]>/gi, (_m, c) => `\n### ${stripTags(c)}\n`)
|
|
119
|
+
.replace(/<li\b[^>]*>([\s\S]*?)<\/li>/gi, (_m, c) => `\n- ${stripTags(c)}\n`)
|
|
120
|
+
.replace(/<\s*(br|\/p|\/div)\s*\/?>/gi, '\n');
|
|
121
|
+
return decodeEntities(stripTags(withMarkers))
|
|
122
|
+
.replace(/[ \t]+\n/g, '\n')
|
|
123
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
124
|
+
.trim();
|
|
125
|
+
}
|
|
126
|
+
/** Strip any remaining tags and collapse intra-line whitespace. */
|
|
127
|
+
function stripTags(html) {
|
|
128
|
+
return html
|
|
129
|
+
.replace(/<[^>]+>/g, ' ')
|
|
130
|
+
.replace(/[ \t]+/g, ' ')
|
|
131
|
+
.trim();
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=confluence.logic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confluence.logic.js","sourceRoot":"","sources":["../../../src/modules/documents/confluence.logic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { DocumentSourceKind } from '@cat-factory/kernel';
|
|
2
|
+
import type { DocumentBoardPlan } from '@cat-factory/kernel';
|
|
3
|
+
import type { DocumentSourceProvider, DocumentSourceRegistry } from '@cat-factory/kernel';
|
|
4
|
+
import { buildExcerpt, markdownToText, MapSourceRegistry } from '@cat-factory/kernel';
|
|
5
|
+
export { buildExcerpt, markdownToText };
|
|
6
|
+
/** A trivial in-memory provider registry built from the wired providers. */
|
|
7
|
+
export declare class MapDocumentSourceRegistry extends MapSourceRegistry<DocumentSourceKind, DocumentSourceProvider> implements DocumentSourceRegistry {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Deterministic fallback planner: map the document's heading outline onto the
|
|
11
|
+
* board. h1 → a service frame, h2 → a module within it, h3 → a task within the
|
|
12
|
+
* current module (or directly in the frame). Used whenever no LLM is configured,
|
|
13
|
+
* and as the safety net when an LLM response can't be parsed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function planFromHeadings(source: DocumentSourceKind, externalId: string, title: string, body: string): DocumentBoardPlan;
|
|
16
|
+
/**
|
|
17
|
+
* Coerce an LLM's parsed JSON into a well-formed {@link DocumentBoardPlan},
|
|
18
|
+
* dropping anything malformed. Returns null when nothing usable remains, so the
|
|
19
|
+
* caller can fall back to the heading parser.
|
|
20
|
+
*/
|
|
21
|
+
export declare function coercePlan(source: DocumentSourceKind, externalId: string, parsed: unknown): DocumentBoardPlan | null;
|
|
22
|
+
//# sourceMappingURL=documents.logic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documents.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/documents.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAmC,MAAM,qBAAqB,CAAA;AAC7F,OAAO,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AACzF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAKrF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,CAAA;AAmBvC,4EAA4E;AAC5E,qBAAa,yBACX,SAAQ,iBAAiB,CAAC,kBAAkB,EAAE,sBAAsB,CACpE,YAAW,sBAAsB;CAAG;AAmBtC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,iBAAiB,CAiCnB;AAiBD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,kBAAkB,EAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GACd,iBAAiB,GAAG,IAAI,CAiC1B"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { buildExcerpt, markdownToText, MapSourceRegistry } from '@cat-factory/kernel';
|
|
2
|
+
// `markdownToText`/`buildExcerpt` now live in the shared markdown helpers (also
|
|
3
|
+
// used by the task-source integration); re-exported here so existing
|
|
4
|
+
// `documentsLogic.*` consumers are unchanged.
|
|
5
|
+
export { buildExcerpt, markdownToText };
|
|
6
|
+
// Source-agnostic helpers shared by every document source: deriving a plain-text
|
|
7
|
+
// excerpt from a Markdown body, the deterministic heading-based planner, and
|
|
8
|
+
// coercion of an LLM's JSON into a well-formed board plan. Providers normalize
|
|
9
|
+
// their page bodies to lightweight Markdown so these stay independent of any one
|
|
10
|
+
// source's format. Keeping them pure makes the planner deterministic and
|
|
11
|
+
// trivially testable without a live source or an LLM.
|
|
12
|
+
const BLOCK_TYPES = [
|
|
13
|
+
'frontend',
|
|
14
|
+
'service',
|
|
15
|
+
'api',
|
|
16
|
+
'database',
|
|
17
|
+
'queue',
|
|
18
|
+
'integration',
|
|
19
|
+
'external',
|
|
20
|
+
];
|
|
21
|
+
/** A trivial in-memory provider registry built from the wired providers. */
|
|
22
|
+
export class MapDocumentSourceRegistry extends MapSourceRegistry {
|
|
23
|
+
}
|
|
24
|
+
/** Extract `#`/`##`/`###` headings (clamped to 1–3), in document order. */
|
|
25
|
+
function extractHeadings(markdown) {
|
|
26
|
+
const headings = [];
|
|
27
|
+
const re = /^[ \t]*(#{1,6})[ \t]+(.+?)[ \t]*#*$/gm;
|
|
28
|
+
let m;
|
|
29
|
+
while ((m = re.exec(markdown)) !== null) {
|
|
30
|
+
const text = m[2].trim();
|
|
31
|
+
if (text)
|
|
32
|
+
headings.push({ level: Math.min(m[1].length, 3), text });
|
|
33
|
+
}
|
|
34
|
+
return headings;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Deterministic fallback planner: map the document's heading outline onto the
|
|
38
|
+
* board. h1 → a service frame, h2 → a module within it, h3 → a task within the
|
|
39
|
+
* current module (or directly in the frame). Used whenever no LLM is configured,
|
|
40
|
+
* and as the safety net when an LLM response can't be parsed.
|
|
41
|
+
*/
|
|
42
|
+
export function planFromHeadings(source, externalId, title, body) {
|
|
43
|
+
const headings = extractHeadings(body);
|
|
44
|
+
const frames = [];
|
|
45
|
+
let frame = null;
|
|
46
|
+
let module = null;
|
|
47
|
+
const ensureFrame = () => {
|
|
48
|
+
if (!frame) {
|
|
49
|
+
frame = { type: 'service', title, modules: [], tasks: [] };
|
|
50
|
+
frames.push(frame);
|
|
51
|
+
}
|
|
52
|
+
return frame;
|
|
53
|
+
};
|
|
54
|
+
for (const heading of headings) {
|
|
55
|
+
if (heading.level === 1) {
|
|
56
|
+
frame = { type: 'service', title: heading.text, modules: [], tasks: [] };
|
|
57
|
+
frames.push(frame);
|
|
58
|
+
module = null;
|
|
59
|
+
}
|
|
60
|
+
else if (heading.level === 2) {
|
|
61
|
+
module = { name: heading.text, tasks: [] };
|
|
62
|
+
ensureFrame().modules.push(module);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
const task = { title: heading.text };
|
|
66
|
+
if (module)
|
|
67
|
+
module.tasks.push(task);
|
|
68
|
+
else
|
|
69
|
+
ensureFrame().tasks.push(task);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (frames.length === 0) {
|
|
73
|
+
frames.push({ type: 'service', title, modules: [], tasks: [] });
|
|
74
|
+
}
|
|
75
|
+
return { source, externalId, planner: 'headings', frames };
|
|
76
|
+
}
|
|
77
|
+
function asString(value) {
|
|
78
|
+
return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined;
|
|
79
|
+
}
|
|
80
|
+
function coerceTask(value) {
|
|
81
|
+
if (typeof value !== 'object' || value === null)
|
|
82
|
+
return null;
|
|
83
|
+
const obj = value;
|
|
84
|
+
const title = asString(obj.title);
|
|
85
|
+
if (!title)
|
|
86
|
+
return null;
|
|
87
|
+
const task = { title };
|
|
88
|
+
const description = asString(obj.description);
|
|
89
|
+
if (description)
|
|
90
|
+
task.description = description;
|
|
91
|
+
return task;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Coerce an LLM's parsed JSON into a well-formed {@link DocumentBoardPlan},
|
|
95
|
+
* dropping anything malformed. Returns null when nothing usable remains, so the
|
|
96
|
+
* caller can fall back to the heading parser.
|
|
97
|
+
*/
|
|
98
|
+
export function coercePlan(source, externalId, parsed) {
|
|
99
|
+
const root = parsed;
|
|
100
|
+
const rawFrames = Array.isArray(root?.frames) ? root.frames : [];
|
|
101
|
+
const frames = [];
|
|
102
|
+
for (const raw of rawFrames) {
|
|
103
|
+
if (typeof raw !== 'object' || raw === null)
|
|
104
|
+
continue;
|
|
105
|
+
const obj = raw;
|
|
106
|
+
const title = asString(obj.title);
|
|
107
|
+
if (!title)
|
|
108
|
+
continue;
|
|
109
|
+
const type = BLOCK_TYPES.includes(obj.type)
|
|
110
|
+
? obj.type
|
|
111
|
+
: 'service';
|
|
112
|
+
const modules = [];
|
|
113
|
+
for (const rawModule of Array.isArray(obj.modules) ? obj.modules : []) {
|
|
114
|
+
if (typeof rawModule !== 'object' || rawModule === null)
|
|
115
|
+
continue;
|
|
116
|
+
const mod = rawModule;
|
|
117
|
+
const name = asString(mod.name);
|
|
118
|
+
if (!name)
|
|
119
|
+
continue;
|
|
120
|
+
const tasks = (Array.isArray(mod.tasks) ? mod.tasks : [])
|
|
121
|
+
.map(coerceTask)
|
|
122
|
+
.filter((t) => t !== null);
|
|
123
|
+
modules.push({ name, tasks });
|
|
124
|
+
}
|
|
125
|
+
const tasks = (Array.isArray(obj.tasks) ? obj.tasks : [])
|
|
126
|
+
.map(coerceTask)
|
|
127
|
+
.filter((t) => t !== null);
|
|
128
|
+
const frame = { type, title, modules, tasks };
|
|
129
|
+
const description = asString(obj.description);
|
|
130
|
+
if (description)
|
|
131
|
+
frame.description = description;
|
|
132
|
+
frames.push(frame);
|
|
133
|
+
}
|
|
134
|
+
if (frames.length === 0)
|
|
135
|
+
return null;
|
|
136
|
+
return { source, externalId, planner: 'llm', frames };
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=documents.logic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documents.logic.js","sourceRoot":"","sources":["../../../src/modules/documents/documents.logic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { DocumentSourceDescriptor } from '@cat-factory/kernel';
|
|
2
|
+
/**
|
|
3
|
+
* What the connect UI renders. GitHub docs piggyback on the workspace's existing
|
|
4
|
+
* GitHub App installation, so there are NO credential fields — the connect form
|
|
5
|
+
* is just a confirmation, and `normalizeConnection` accepts an empty bag.
|
|
6
|
+
*/
|
|
7
|
+
export declare const GITHUB_DOCS_DESCRIPTOR: DocumentSourceDescriptor;
|
|
8
|
+
/** The parts of a GitHub doc external id (`owner/repo:path`). */
|
|
9
|
+
export interface GitHubDocExternalId {
|
|
10
|
+
owner: string;
|
|
11
|
+
repo: string;
|
|
12
|
+
/** Path relative to the repo root, e.g. `docs/architecture.md`. */
|
|
13
|
+
path: string;
|
|
14
|
+
}
|
|
15
|
+
/** Build the canonical `owner/repo:path` external id from its parts. */
|
|
16
|
+
export declare function githubDocExternalId(id: GitHubDocExternalId): string;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a GitHub repo-doc reference from raw user input into the canonical
|
|
19
|
+
* `owner/repo:path` external id. Accepts:
|
|
20
|
+
* - a blob URL: `https://github.com/octo/repo/blob/main/docs/x.md`
|
|
21
|
+
* - a raw URL: `https://raw.githubusercontent.com/octo/repo/main/docs/x.md`
|
|
22
|
+
* - the shorthand `octo/repo:docs/x.md`
|
|
23
|
+
* The branch/ref in a URL is dropped — the provider reads the default branch — so
|
|
24
|
+
* the external id (and thus a re-import's identity) is branch-stable. Returns
|
|
25
|
+
* null when nothing parses. Owner/repo/path are kept verbatim (case-preserving).
|
|
26
|
+
*
|
|
27
|
+
* KNOWN LIMITATION: a URL whose branch name itself contains a slash
|
|
28
|
+
* (`…/blob/feature/x/README.md`) is ambiguous — the branch/path boundary cannot
|
|
29
|
+
* be recovered from the URL alone, so the first segment after `blob/` (or the
|
|
30
|
+
* ref slot of a raw URL) is assumed to be the whole ref and the rest the path.
|
|
31
|
+
* For files on a slash-named branch, use the unambiguous `owner/repo:path`
|
|
32
|
+
* shorthand instead. (The default branch is what the provider actually reads.)
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseGitHubDocRef(input: string): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Split a stored `owner/repo:path` external id back into its parts. Returns null
|
|
37
|
+
* if the id is malformed (defensive — ids are produced by
|
|
38
|
+
* {@link parseGitHubDocRef}, but a stale/hand-edited row should not throw).
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseGitHubDocExternalId(externalId: string): GitHubDocExternalId | null;
|
|
41
|
+
/** The canonical web URL for a doc external id (default branch via `HEAD`). */
|
|
42
|
+
export declare function githubDocUrl(id: GitHubDocExternalId): string;
|
|
43
|
+
/** A human title for a doc: its file base name (e.g. `architecture.md`). */
|
|
44
|
+
export declare function githubDocTitle(path: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Build a GitHub code-search query scoped to one account. GitHub's code-search
|
|
47
|
+
* API rejects unscoped queries, so we append an `org:`/`user:` qualifier chosen
|
|
48
|
+
* from the installation's target type. The free text is trimmed and the account
|
|
49
|
+
* login is taken verbatim (GitHub logins have no special search chars).
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildGitHubCodeSearchQuery(query: string, account: string, targetType: 'Organization' | 'User'): string;
|
|
52
|
+
//# sourceMappingURL=github-docs.logic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-docs.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/github-docs.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAWnE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,wBASpC,CAAA;AAMD,iEAAiE;AACjE,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;CACb;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,mBAAmB,GAAG,MAAM,CAEnE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW9D;AAOD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAIvF;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,EAAE,EAAE,mBAAmB,GAAG,MAAM,CAE5D;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,cAAc,GAAG,MAAM,GAClC,MAAM,CAGR"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// GitHub repo-doc document-source pure logic, kept out of the worker so it is
|
|
2
|
+
// unit-testable without a live API: parsing a file reference out of user input
|
|
3
|
+
// and round-tripping the `owner/repo:path` external id the provider stores. Like
|
|
4
|
+
// the GitHub-issues task source, the provider reuses the workspace's installed
|
|
5
|
+
// GitHub App, so this source needs no credentials of its own. A repo doc is a
|
|
6
|
+
// single Markdown/text file (a README, an RFC under `docs/`, an architecture
|
|
7
|
+
// note) linked to a task as context; the file body is already Markdown-ish, so
|
|
8
|
+
// there is no body-conversion step here.
|
|
9
|
+
/**
|
|
10
|
+
* What the connect UI renders. GitHub docs piggyback on the workspace's existing
|
|
11
|
+
* GitHub App installation, so there are NO credential fields — the connect form
|
|
12
|
+
* is just a confirmation, and `normalizeConnection` accepts an empty bag.
|
|
13
|
+
*/
|
|
14
|
+
export const GITHUB_DOCS_DESCRIPTOR = {
|
|
15
|
+
source: 'github',
|
|
16
|
+
label: 'GitHub Docs',
|
|
17
|
+
icon: 'i-lucide-file-code-2',
|
|
18
|
+
credentialFields: [],
|
|
19
|
+
refLabel: 'File URL or owner/repo:path',
|
|
20
|
+
refPlaceholder: 'octo/repo:docs/architecture.md or https://github.com/octo/repo/blob/main/README.md',
|
|
21
|
+
searchable: true,
|
|
22
|
+
};
|
|
23
|
+
// An owner/repo segment: letters, digits, '.', '_' and '-'. Mirrors the GitHub
|
|
24
|
+
// issues source's segment grammar.
|
|
25
|
+
const SEG = '[A-Za-z0-9._-]+';
|
|
26
|
+
/** Build the canonical `owner/repo:path` external id from its parts. */
|
|
27
|
+
export function githubDocExternalId(id) {
|
|
28
|
+
return `${id.owner}/${id.repo}:${id.path}`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolve a GitHub repo-doc reference from raw user input into the canonical
|
|
32
|
+
* `owner/repo:path` external id. Accepts:
|
|
33
|
+
* - a blob URL: `https://github.com/octo/repo/blob/main/docs/x.md`
|
|
34
|
+
* - a raw URL: `https://raw.githubusercontent.com/octo/repo/main/docs/x.md`
|
|
35
|
+
* - the shorthand `octo/repo:docs/x.md`
|
|
36
|
+
* The branch/ref in a URL is dropped — the provider reads the default branch — so
|
|
37
|
+
* the external id (and thus a re-import's identity) is branch-stable. Returns
|
|
38
|
+
* null when nothing parses. Owner/repo/path are kept verbatim (case-preserving).
|
|
39
|
+
*
|
|
40
|
+
* KNOWN LIMITATION: a URL whose branch name itself contains a slash
|
|
41
|
+
* (`…/blob/feature/x/README.md`) is ambiguous — the branch/path boundary cannot
|
|
42
|
+
* be recovered from the URL alone, so the first segment after `blob/` (or the
|
|
43
|
+
* ref slot of a raw URL) is assumed to be the whole ref and the rest the path.
|
|
44
|
+
* For files on a slash-named branch, use the unambiguous `owner/repo:path`
|
|
45
|
+
* shorthand instead. (The default branch is what the provider actually reads.)
|
|
46
|
+
*/
|
|
47
|
+
export function parseGitHubDocRef(input) {
|
|
48
|
+
const trimmed = input.trim();
|
|
49
|
+
const blob = trimmed.match(new RegExp(`github\\.com/(${SEG})/(${SEG})/blob/[^/]+/(.+)$`));
|
|
50
|
+
if (blob)
|
|
51
|
+
return `${blob[1]}/${blob[2]}:${stripQuery(blob[3])}`;
|
|
52
|
+
const raw = trimmed.match(new RegExp(`raw\\.githubusercontent\\.com/(${SEG})/(${SEG})/[^/]+/(.+)$`));
|
|
53
|
+
if (raw)
|
|
54
|
+
return `${raw[1]}/${raw[2]}:${stripQuery(raw[3])}`;
|
|
55
|
+
const short = trimmed.match(new RegExp(`^(${SEG})/(${SEG}):(.+)$`));
|
|
56
|
+
if (short)
|
|
57
|
+
return `${short[1]}/${short[2]}:${short[3].replace(/^\/+/, '')}`;
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
/** Drop any `?query`/`#hash` and leading slashes from a URL path tail. */
|
|
61
|
+
function stripQuery(path) {
|
|
62
|
+
return path.split(/[?#]/)[0].replace(/^\/+/, '');
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Split a stored `owner/repo:path` external id back into its parts. Returns null
|
|
66
|
+
* if the id is malformed (defensive — ids are produced by
|
|
67
|
+
* {@link parseGitHubDocRef}, but a stale/hand-edited row should not throw).
|
|
68
|
+
*/
|
|
69
|
+
export function parseGitHubDocExternalId(externalId) {
|
|
70
|
+
const m = externalId.match(new RegExp(`^(${SEG})/(${SEG}):(.+)$`));
|
|
71
|
+
if (!m)
|
|
72
|
+
return null;
|
|
73
|
+
return { owner: m[1], repo: m[2], path: m[3] };
|
|
74
|
+
}
|
|
75
|
+
/** The canonical web URL for a doc external id (default branch via `HEAD`). */
|
|
76
|
+
export function githubDocUrl(id) {
|
|
77
|
+
return `https://github.com/${id.owner}/${id.repo}/blob/HEAD/${id.path}`;
|
|
78
|
+
}
|
|
79
|
+
/** A human title for a doc: its file base name (e.g. `architecture.md`). */
|
|
80
|
+
export function githubDocTitle(path) {
|
|
81
|
+
const base = path.split('/').filter(Boolean).pop();
|
|
82
|
+
return base && base.length > 0 ? base : path;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Build a GitHub code-search query scoped to one account. GitHub's code-search
|
|
86
|
+
* API rejects unscoped queries, so we append an `org:`/`user:` qualifier chosen
|
|
87
|
+
* from the installation's target type. The free text is trimmed and the account
|
|
88
|
+
* login is taken verbatim (GitHub logins have no special search chars).
|
|
89
|
+
*/
|
|
90
|
+
export function buildGitHubCodeSearchQuery(query, account, targetType) {
|
|
91
|
+
const qualifier = targetType === 'Organization' ? 'org' : 'user';
|
|
92
|
+
return `${query.trim()} ${qualifier}:${account}`;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=github-docs.logic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-docs.logic.js","sourceRoot":"","sources":["../../../src/modules/documents/github-docs.logic.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,+EAA+E;AAC/E,iFAAiF;AACjF,+EAA+E;AAC/E,8EAA8E;AAC9E,6EAA6E;AAC7E,+EAA+E;AAC/E,yCAAyC;AAEzC;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA6B;IAC9D,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,aAAa;IACpB,IAAI,EAAE,sBAAsB;IAC5B,gBAAgB,EAAE,EAAE;IACpB,QAAQ,EAAE,6BAA6B;IACvC,cAAc,EACZ,sFAAsF;IACxF,UAAU,EAAE,IAAI;CACjB,CAAA;AAED,+EAA+E;AAC/E,mCAAmC;AACnC,MAAM,GAAG,GAAG,iBAAiB,CAAA;AAU7B,wEAAwE;AACxE,MAAM,UAAU,mBAAmB,CAAC,EAAuB;IACzD,OAAO,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,CAAA;AAC5C,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,iBAAiB,GAAG,MAAM,GAAG,oBAAoB,CAAC,CAAC,CAAA;IACzF,IAAI,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,EAAE,CAAA;IAChE,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CACvB,IAAI,MAAM,CAAC,kCAAkC,GAAG,MAAM,GAAG,eAAe,CAAC,CAC1E,CAAA;IACD,IAAI,GAAG;QAAE,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,EAAE,CAAA;IAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;IACnE,IAAI,KAAK;QAAE,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAA;IAC5E,OAAO,IAAI,CAAA;AACb,CAAC;AAED,0EAA0E;AAC1E,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,UAAkB;IACzD,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC,CAAC,CAAA;IAClE,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IACnB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAA;AACnD,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,YAAY,CAAC,EAAuB;IAClD,OAAO,sBAAsB,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,cAAc,EAAE,CAAC,IAAI,EAAE,CAAA;AACzE,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAA;IAClD,OAAO,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAa,EACb,OAAe,EACf,UAAmC;IAEnC,MAAM,SAAS,GAAG,UAAU,KAAK,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAA;IAChE,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,SAAS,IAAI,OAAO,EAAE,CAAA;AAClD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { DocumentSearchResult, DocumentSourceDescriptor } from '@cat-factory/kernel';
|
|
2
|
+
/** What the connect UI renders, and which credentials the provider needs. */
|
|
3
|
+
export declare const NOTION_DESCRIPTOR: DocumentSourceDescriptor;
|
|
4
|
+
/**
|
|
5
|
+
* Map a Notion `/v1/search` response into lean hits, keeping only pages (the API
|
|
6
|
+
* also returns databases). The page title is read from its `properties` exactly
|
|
7
|
+
* as the single-page fetch does, so list + import titles agree.
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseNotionSearchResults(json: unknown): DocumentSearchResult[];
|
|
10
|
+
/** Format 32 hex chars as a canonical dashed Notion/UUID id. */
|
|
11
|
+
export declare function formatNotionId(hex32: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a Notion page id from raw user input: a bare id (dashed UUID or 32 hex
|
|
14
|
+
* chars), or any Notion URL whose last path segment ends in the id. Returns the
|
|
15
|
+
* canonical dashed id, or null if none is found.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseNotionRef(input: string): string | null;
|
|
18
|
+
/** The subset of a Notion block we read; the type key holds the rich text. */
|
|
19
|
+
export interface NotionBlock {
|
|
20
|
+
type?: string;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Convert a Notion page's top-level blocks into the lightweight Markdown the
|
|
25
|
+
* generic planner/excerpt logic consumes: headings become `#`/`##`/`###`, list
|
|
26
|
+
* items / to-dos become `- `, and other text blocks become plain lines.
|
|
27
|
+
*/
|
|
28
|
+
export declare function notionBlocksToMarkdown(blocks: NotionBlock[]): string;
|
|
29
|
+
/** Extract a page title from a Notion page object's `properties`. */
|
|
30
|
+
export declare function notionPageTitle(properties: Record<string, unknown> | undefined): string;
|
|
31
|
+
//# sourceMappingURL=notion.logic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notion.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/documents/notion.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAQzF,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,EAAE,wBAgB/B,CAAA;AAWD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,oBAAoB,EAAE,CAgB9E;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW3D;AAQD,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAcD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAkCpE;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAavF"}
|