patchwork-os 0.2.0-alpha.21 → 0.2.0-alpha.22
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 +26 -12
- package/deploy/bootstrap-vps.sh +184 -0
- package/dist/approvalHttp.js +6 -1
- package/dist/approvalHttp.js.map +1 -1
- package/dist/automation.d.ts +20 -0
- package/dist/automation.js +35 -0
- package/dist/automation.js.map +1 -1
- package/dist/bridge.js +22 -4
- package/dist/bridge.js.map +1 -1
- package/dist/bridgeToken.js +57 -19
- package/dist/bridgeToken.js.map +1 -1
- package/dist/commands/recipe.d.ts +256 -0
- package/dist/commands/recipe.js +1313 -0
- package/dist/commands/recipe.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +9 -0
- package/dist/config.js.map +1 -1
- package/dist/connectors/baseConnector.d.ts +117 -0
- package/dist/connectors/baseConnector.js +213 -0
- package/dist/connectors/baseConnector.js.map +1 -0
- package/dist/connectors/confluence.d.ts +111 -0
- package/dist/connectors/confluence.js +406 -0
- package/dist/connectors/confluence.js.map +1 -0
- package/dist/connectors/fixtureLibrary.d.ts +21 -0
- package/dist/connectors/fixtureLibrary.js +70 -0
- package/dist/connectors/fixtureLibrary.js.map +1 -0
- package/dist/connectors/fixtureRecorder.d.ts +1 -0
- package/dist/connectors/fixtureRecorder.js +35 -0
- package/dist/connectors/fixtureRecorder.js.map +1 -0
- package/dist/connectors/github.js +2 -11
- package/dist/connectors/github.js.map +1 -1
- package/dist/connectors/gmail.js +23 -7
- package/dist/connectors/gmail.js.map +1 -1
- package/dist/connectors/googleCalendar.js +23 -7
- package/dist/connectors/googleCalendar.js.map +1 -1
- package/dist/connectors/jira.d.ts +98 -0
- package/dist/connectors/jira.js +379 -0
- package/dist/connectors/jira.js.map +1 -0
- package/dist/connectors/linear.js +2 -11
- package/dist/connectors/linear.js.map +1 -1
- package/dist/connectors/mcpOAuth.d.ts +1 -0
- package/dist/connectors/mcpOAuth.js +30 -4
- package/dist/connectors/mcpOAuth.js.map +1 -1
- package/dist/connectors/mockConnector.d.ts +28 -0
- package/dist/connectors/mockConnector.js +81 -0
- package/dist/connectors/mockConnector.js.map +1 -0
- package/dist/connectors/notion.d.ts +143 -0
- package/dist/connectors/notion.js +424 -0
- package/dist/connectors/notion.js.map +1 -0
- package/dist/connectors/sentry.js +2 -11
- package/dist/connectors/sentry.js.map +1 -1
- package/dist/connectors/slack.js +50 -15
- package/dist/connectors/slack.js.map +1 -1
- package/dist/connectors/tokenStorage.d.ts +35 -0
- package/dist/connectors/tokenStorage.js +394 -0
- package/dist/connectors/tokenStorage.js.map +1 -0
- package/dist/connectors/zendesk.d.ts +104 -0
- package/dist/connectors/zendesk.js +424 -0
- package/dist/connectors/zendesk.js.map +1 -0
- package/dist/featureFlags.d.ts +73 -0
- package/dist/featureFlags.js +203 -0
- package/dist/featureFlags.js.map +1 -0
- package/dist/fp/automationInterpreter.js +1 -0
- package/dist/fp/automationInterpreter.js.map +1 -1
- package/dist/fp/automationProgram.d.ts +1 -1
- package/dist/fp/automationProgram.js.map +1 -1
- package/dist/fp/policyParser.js +17 -0
- package/dist/fp/policyParser.js.map +1 -1
- package/dist/index.js +508 -36
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts +4 -1
- package/dist/oauth.js +50 -14
- package/dist/oauth.js.map +1 -1
- package/dist/recipes/chainedRunner.d.ts +104 -0
- package/dist/recipes/chainedRunner.js +359 -0
- package/dist/recipes/chainedRunner.js.map +1 -0
- package/dist/recipes/dependencyGraph.d.ts +39 -0
- package/dist/recipes/dependencyGraph.js +199 -0
- package/dist/recipes/dependencyGraph.js.map +1 -0
- package/dist/recipes/legacyRecipeCompat.d.ts +1 -0
- package/dist/recipes/legacyRecipeCompat.js +97 -0
- package/dist/recipes/legacyRecipeCompat.js.map +1 -0
- package/dist/recipes/nestedRecipeStep.d.ts +58 -0
- package/dist/recipes/nestedRecipeStep.js +95 -0
- package/dist/recipes/nestedRecipeStep.js.map +1 -0
- package/dist/recipes/outputRegistry.d.ts +28 -0
- package/dist/recipes/outputRegistry.js +52 -0
- package/dist/recipes/outputRegistry.js.map +1 -0
- package/dist/recipes/schemaGenerator.d.ts +28 -0
- package/dist/recipes/schemaGenerator.js +484 -0
- package/dist/recipes/schemaGenerator.js.map +1 -0
- package/dist/recipes/templateEngine.d.ts +62 -0
- package/dist/recipes/templateEngine.js +182 -0
- package/dist/recipes/templateEngine.js.map +1 -0
- package/dist/recipes/toolRegistry.d.ts +181 -0
- package/dist/recipes/toolRegistry.js +300 -0
- package/dist/recipes/toolRegistry.js.map +1 -0
- package/dist/recipes/tools/calendar.d.ts +6 -0
- package/dist/recipes/tools/calendar.js +61 -0
- package/dist/recipes/tools/calendar.js.map +1 -0
- package/dist/recipes/tools/confluence.d.ts +6 -0
- package/dist/recipes/tools/confluence.js +254 -0
- package/dist/recipes/tools/confluence.js.map +1 -0
- package/dist/recipes/tools/diagnostics.d.ts +6 -0
- package/dist/recipes/tools/diagnostics.js +36 -0
- package/dist/recipes/tools/diagnostics.js.map +1 -0
- package/dist/recipes/tools/file.d.ts +6 -0
- package/dist/recipes/tools/file.js +170 -0
- package/dist/recipes/tools/file.js.map +1 -0
- package/dist/recipes/tools/git.d.ts +6 -0
- package/dist/recipes/tools/git.js +63 -0
- package/dist/recipes/tools/git.js.map +1 -0
- package/dist/recipes/tools/github.d.ts +6 -0
- package/dist/recipes/tools/github.js +91 -0
- package/dist/recipes/tools/github.js.map +1 -0
- package/dist/recipes/tools/gmail.d.ts +6 -0
- package/dist/recipes/tools/gmail.js +210 -0
- package/dist/recipes/tools/gmail.js.map +1 -0
- package/dist/recipes/tools/index.d.ts +18 -0
- package/dist/recipes/tools/index.js +21 -0
- package/dist/recipes/tools/index.js.map +1 -0
- package/dist/recipes/tools/linear.d.ts +6 -0
- package/dist/recipes/tools/linear.js +83 -0
- package/dist/recipes/tools/linear.js.map +1 -0
- package/dist/recipes/tools/notion.d.ts +6 -0
- package/dist/recipes/tools/notion.js +278 -0
- package/dist/recipes/tools/notion.js.map +1 -0
- package/dist/recipes/tools/slack.d.ts +6 -0
- package/dist/recipes/tools/slack.js +72 -0
- package/dist/recipes/tools/slack.js.map +1 -0
- package/dist/recipes/tools/zendesk.d.ts +6 -0
- package/dist/recipes/tools/zendesk.js +245 -0
- package/dist/recipes/tools/zendesk.js.map +1 -0
- package/dist/recipes/yamlRunner.d.ts +71 -7
- package/dist/recipes/yamlRunner.js +406 -439
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/riskTier.js +1 -0
- package/dist/riskTier.js.map +1 -1
- package/dist/runLog.d.ts +18 -0
- package/dist/runLog.js +5 -0
- package/dist/runLog.js.map +1 -1
- package/dist/server.d.ts +4 -0
- package/dist/server.js +224 -0
- package/dist/server.js.map +1 -1
- package/dist/streamableHttp.js +2 -0
- package/dist/streamableHttp.js.map +1 -1
- package/dist/tools/github/actions.js +4 -2
- package/dist/tools/github/actions.js.map +1 -1
- package/dist/tools/github/composite.d.ts +339 -0
- package/dist/tools/github/composite.js +343 -0
- package/dist/tools/github/composite.js.map +1 -0
- package/dist/tools/github/index.d.ts +1 -0
- package/dist/tools/github/index.js +1 -0
- package/dist/tools/github/index.js.map +1 -1
- package/dist/tools/github/issues.js +8 -4
- package/dist/tools/github/issues.js.map +1 -1
- package/dist/tools/github/pr.js +14 -7
- package/dist/tools/github/pr.js.map +1 -1
- package/dist/tools/index.js +10 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/searchTools.js +1 -1
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/transport.d.ts +7 -1
- package/dist/transport.js +85 -11
- package/dist/transport.js.map +1 -1
- package/package.json +1 -1
- package/templates/automation-policies/recipe-authoring.json +25 -0
- package/templates/automation-policy.example.json +6 -0
- package/templates/recipes/lint-on-save.yaml +1 -2
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confluence connector — read/write Confluence pages via Atlassian REST API v2.
|
|
3
|
+
*
|
|
4
|
+
* Auth: API token + email + instance URL (same credential shape as Jira).
|
|
5
|
+
* - Env vars: CONFLUENCE_API_TOKEN, CONFLUENCE_INSTANCE_URL, CONFLUENCE_EMAIL
|
|
6
|
+
* - Stored: getSecretJsonSync("confluence") → ConfluenceTokens
|
|
7
|
+
*
|
|
8
|
+
* Tools: getPage, search, createPage, appendToPage, listSpaces
|
|
9
|
+
*
|
|
10
|
+
* Extends BaseConnector for unified auth, retry, rate-limit, error handling.
|
|
11
|
+
*/
|
|
12
|
+
import { type AuthContext, BaseConnector, type ConnectorError, type ConnectorStatus } from "./baseConnector.js";
|
|
13
|
+
export interface ConfluenceTokens {
|
|
14
|
+
accessToken: string;
|
|
15
|
+
email: string;
|
|
16
|
+
instanceUrl: string;
|
|
17
|
+
connected_at: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ConfluencePage {
|
|
20
|
+
id: string;
|
|
21
|
+
title: string;
|
|
22
|
+
status: string;
|
|
23
|
+
spaceId: string;
|
|
24
|
+
parentId?: string;
|
|
25
|
+
version: {
|
|
26
|
+
number: number;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
};
|
|
29
|
+
body?: {
|
|
30
|
+
storage?: {
|
|
31
|
+
value: string;
|
|
32
|
+
representation: "storage";
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
_links: {
|
|
36
|
+
webui: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface ConfluenceSpace {
|
|
40
|
+
id: string;
|
|
41
|
+
key: string;
|
|
42
|
+
name: string;
|
|
43
|
+
type: string;
|
|
44
|
+
status: string;
|
|
45
|
+
_links: {
|
|
46
|
+
webui: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface ConfluenceSearchResult {
|
|
50
|
+
results: Array<{
|
|
51
|
+
content: {
|
|
52
|
+
id: string;
|
|
53
|
+
type: string;
|
|
54
|
+
title: string;
|
|
55
|
+
_links: {
|
|
56
|
+
webui: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
excerpt: string;
|
|
60
|
+
url: string;
|
|
61
|
+
lastModified: string;
|
|
62
|
+
}>;
|
|
63
|
+
totalSize: number;
|
|
64
|
+
start: number;
|
|
65
|
+
limit: number;
|
|
66
|
+
}
|
|
67
|
+
export declare class ConfluenceConnector extends BaseConnector {
|
|
68
|
+
readonly providerName = "confluence";
|
|
69
|
+
private tokens;
|
|
70
|
+
protected getOAuthConfig(): null;
|
|
71
|
+
authenticate(): Promise<AuthContext>;
|
|
72
|
+
healthCheck(): Promise<{
|
|
73
|
+
ok: boolean;
|
|
74
|
+
error?: ConnectorError;
|
|
75
|
+
}>;
|
|
76
|
+
normalizeError(error: unknown): ConnectorError;
|
|
77
|
+
getStatus(): ConnectorStatus;
|
|
78
|
+
getPage(pageId: string, includeBody?: boolean): Promise<ConfluencePage | null>;
|
|
79
|
+
search(query: string, limit?: number): Promise<ConfluenceSearchResult>;
|
|
80
|
+
createPage(params: {
|
|
81
|
+
spaceId: string;
|
|
82
|
+
title: string;
|
|
83
|
+
body: string;
|
|
84
|
+
parentId?: string;
|
|
85
|
+
}): Promise<ConfluencePage>;
|
|
86
|
+
appendToPage(pageId: string, content: string): Promise<ConfluencePage>;
|
|
87
|
+
listSpaces(limit?: number): Promise<ConfluenceSpace[]>;
|
|
88
|
+
private buildHeaders;
|
|
89
|
+
}
|
|
90
|
+
export declare function loadTokens(): ConfluenceTokens | null;
|
|
91
|
+
export declare function saveTokens(tokens: ConfluenceTokens): void;
|
|
92
|
+
export declare function clearTokens(): void;
|
|
93
|
+
export declare function getConfluenceConnector(): ConfluenceConnector;
|
|
94
|
+
export { getConfluenceConnector as confluence };
|
|
95
|
+
export interface ConnectorHandlerResult {
|
|
96
|
+
status: number;
|
|
97
|
+
body: string;
|
|
98
|
+
contentType?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* POST /connections/confluence/connect { token, email, instanceUrl }
|
|
102
|
+
*/
|
|
103
|
+
export declare function handleConfluenceConnect(body: string): Promise<ConnectorHandlerResult>;
|
|
104
|
+
/**
|
|
105
|
+
* POST /connections/confluence/test
|
|
106
|
+
*/
|
|
107
|
+
export declare function handleConfluenceTest(): Promise<ConnectorHandlerResult>;
|
|
108
|
+
/**
|
|
109
|
+
* DELETE /connections/confluence
|
|
110
|
+
*/
|
|
111
|
+
export declare function handleConfluenceDisconnect(): ConnectorHandlerResult;
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confluence connector — read/write Confluence pages via Atlassian REST API v2.
|
|
3
|
+
*
|
|
4
|
+
* Auth: API token + email + instance URL (same credential shape as Jira).
|
|
5
|
+
* - Env vars: CONFLUENCE_API_TOKEN, CONFLUENCE_INSTANCE_URL, CONFLUENCE_EMAIL
|
|
6
|
+
* - Stored: getSecretJsonSync("confluence") → ConfluenceTokens
|
|
7
|
+
*
|
|
8
|
+
* Tools: getPage, search, createPage, appendToPage, listSpaces
|
|
9
|
+
*
|
|
10
|
+
* Extends BaseConnector for unified auth, retry, rate-limit, error handling.
|
|
11
|
+
*/
|
|
12
|
+
import { BaseConnector, } from "./baseConnector.js";
|
|
13
|
+
import { deleteSecretJsonSync, getSecretJsonSync, storeSecretJsonSync, } from "./tokenStorage.js";
|
|
14
|
+
// Confluence Cloud REST API v2
|
|
15
|
+
const CONFLUENCE_API_V2 = "/wiki/api/v2";
|
|
16
|
+
export class ConfluenceConnector extends BaseConnector {
|
|
17
|
+
providerName = "confluence";
|
|
18
|
+
tokens = null;
|
|
19
|
+
getOAuthConfig() {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
async authenticate() {
|
|
23
|
+
const tokens = loadTokens();
|
|
24
|
+
if (!tokens) {
|
|
25
|
+
throw new Error("Confluence not connected. Run: patchwork-os connect confluence or set CONFLUENCE_API_TOKEN");
|
|
26
|
+
}
|
|
27
|
+
this.tokens = tokens;
|
|
28
|
+
return {
|
|
29
|
+
token: tokens.accessToken,
|
|
30
|
+
scopes: ["read:confluence-content.all", "write:confluence-content"],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async healthCheck() {
|
|
34
|
+
try {
|
|
35
|
+
const result = await this.apiCall(async (token) => {
|
|
36
|
+
const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/spaces?limit=1`;
|
|
37
|
+
const res = await fetch(url, {
|
|
38
|
+
headers: this.buildHeaders(token),
|
|
39
|
+
});
|
|
40
|
+
if (!res.ok)
|
|
41
|
+
throw new Error(`HTTP ${res.status}`);
|
|
42
|
+
return res.json();
|
|
43
|
+
});
|
|
44
|
+
if ("error" in result)
|
|
45
|
+
return { ok: false, error: result.error };
|
|
46
|
+
return { ok: true };
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
return { ok: false, error: this.normalizeError(err) };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
normalizeError(error) {
|
|
53
|
+
if (error instanceof Response) {
|
|
54
|
+
const s = error.status;
|
|
55
|
+
if (s === 401)
|
|
56
|
+
return {
|
|
57
|
+
code: "auth_expired",
|
|
58
|
+
message: "Confluence authentication expired — reconnect",
|
|
59
|
+
retryable: false,
|
|
60
|
+
suggestedAction: "patchwork-os connect confluence",
|
|
61
|
+
};
|
|
62
|
+
if (s === 403)
|
|
63
|
+
return {
|
|
64
|
+
code: "permission_denied",
|
|
65
|
+
message: "Insufficient Confluence permissions",
|
|
66
|
+
retryable: false,
|
|
67
|
+
};
|
|
68
|
+
if (s === 404)
|
|
69
|
+
return {
|
|
70
|
+
code: "not_found",
|
|
71
|
+
message: "Confluence page or space not found",
|
|
72
|
+
retryable: false,
|
|
73
|
+
};
|
|
74
|
+
if (s === 429)
|
|
75
|
+
return {
|
|
76
|
+
code: "rate_limited",
|
|
77
|
+
message: "Confluence API rate limit exceeded",
|
|
78
|
+
retryable: true,
|
|
79
|
+
suggestedAction: "Wait and retry",
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
code: "provider_error",
|
|
83
|
+
message: `Confluence API error: HTTP ${s}`,
|
|
84
|
+
retryable: s >= 500,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (error instanceof Error) {
|
|
88
|
+
if (error.message.includes("ENOTFOUND") ||
|
|
89
|
+
error.message.includes("ECONNREFUSED")) {
|
|
90
|
+
return {
|
|
91
|
+
code: "network_error",
|
|
92
|
+
message: `Cannot connect to Confluence: ${error.message}`,
|
|
93
|
+
retryable: true,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
code: "provider_error",
|
|
99
|
+
message: error instanceof Error ? error.message : String(error),
|
|
100
|
+
retryable: false,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
getStatus() {
|
|
104
|
+
const tokens = loadTokens();
|
|
105
|
+
return {
|
|
106
|
+
id: "confluence",
|
|
107
|
+
status: tokens ? "connected" : "disconnected",
|
|
108
|
+
lastSync: tokens?.connected_at,
|
|
109
|
+
workspace: tokens?.instanceUrl,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// ── API Methods ────────────────────────────────────────────────────────────
|
|
113
|
+
async getPage(pageId, includeBody = true) {
|
|
114
|
+
const result = await this.apiCall(async (token) => {
|
|
115
|
+
const bodyParam = includeBody ? "&body-format=storage" : "";
|
|
116
|
+
const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/pages/${pageId}?${bodyParam}`;
|
|
117
|
+
const res = await fetch(url, { headers: this.buildHeaders(token) });
|
|
118
|
+
this.updateRateLimitFromHeaders({
|
|
119
|
+
"x-ratelimit-remaining": res.headers.get("x-ratelimit-remaining") ?? undefined,
|
|
120
|
+
"retry-after": res.headers.get("retry-after") ?? undefined,
|
|
121
|
+
});
|
|
122
|
+
if (res.status === 404)
|
|
123
|
+
return null;
|
|
124
|
+
if (!res.ok)
|
|
125
|
+
throw res;
|
|
126
|
+
return res.json();
|
|
127
|
+
});
|
|
128
|
+
if ("error" in result)
|
|
129
|
+
throw new Error(result.error.message);
|
|
130
|
+
return result.data;
|
|
131
|
+
}
|
|
132
|
+
async search(query, limit = 25) {
|
|
133
|
+
const result = await this.apiCall(async (token) => {
|
|
134
|
+
// Use legacy v1 search which supports full-text CQL
|
|
135
|
+
const cql = encodeURIComponent(`text ~ "${query}" AND type = page`);
|
|
136
|
+
const url = `${this.tokens?.instanceUrl}/wiki/rest/api/search?cql=${cql}&limit=${limit}&expand=content.space`;
|
|
137
|
+
const res = await fetch(url, { headers: this.buildHeaders(token) });
|
|
138
|
+
if (!res.ok)
|
|
139
|
+
throw res;
|
|
140
|
+
return res.json();
|
|
141
|
+
});
|
|
142
|
+
if ("error" in result)
|
|
143
|
+
throw new Error(result.error.message);
|
|
144
|
+
return result.data;
|
|
145
|
+
}
|
|
146
|
+
async createPage(params) {
|
|
147
|
+
const result = await this.apiCall(async (token) => {
|
|
148
|
+
const payload = {
|
|
149
|
+
spaceId: params.spaceId,
|
|
150
|
+
status: "current",
|
|
151
|
+
title: params.title,
|
|
152
|
+
body: {
|
|
153
|
+
representation: "storage",
|
|
154
|
+
value: params.body,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
if (params.parentId) {
|
|
158
|
+
payload.parentId = params.parentId;
|
|
159
|
+
}
|
|
160
|
+
const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/pages`;
|
|
161
|
+
const res = await fetch(url, {
|
|
162
|
+
method: "POST",
|
|
163
|
+
headers: {
|
|
164
|
+
...this.buildHeaders(token),
|
|
165
|
+
"Content-Type": "application/json",
|
|
166
|
+
},
|
|
167
|
+
body: JSON.stringify(payload),
|
|
168
|
+
});
|
|
169
|
+
if (!res.ok)
|
|
170
|
+
throw res;
|
|
171
|
+
return res.json();
|
|
172
|
+
});
|
|
173
|
+
if ("error" in result)
|
|
174
|
+
throw new Error(result.error.message);
|
|
175
|
+
return result.data;
|
|
176
|
+
}
|
|
177
|
+
async appendToPage(pageId, content) {
|
|
178
|
+
// Fetch current page to get version number and existing body
|
|
179
|
+
const page = await this.getPage(pageId, true);
|
|
180
|
+
if (!page)
|
|
181
|
+
throw new Error(`Page ${pageId} not found`);
|
|
182
|
+
const existing = page.body?.storage?.value ?? "";
|
|
183
|
+
const newBody = `${existing}\n${content}`;
|
|
184
|
+
const nextVersion = page.version.number + 1;
|
|
185
|
+
const result = await this.apiCall(async (token) => {
|
|
186
|
+
const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/pages/${pageId}`;
|
|
187
|
+
const res = await fetch(url, {
|
|
188
|
+
method: "PUT",
|
|
189
|
+
headers: {
|
|
190
|
+
...this.buildHeaders(token),
|
|
191
|
+
"Content-Type": "application/json",
|
|
192
|
+
},
|
|
193
|
+
body: JSON.stringify({
|
|
194
|
+
id: pageId,
|
|
195
|
+
status: "current",
|
|
196
|
+
title: page.title,
|
|
197
|
+
version: { number: nextVersion },
|
|
198
|
+
body: { representation: "storage", value: newBody },
|
|
199
|
+
}),
|
|
200
|
+
});
|
|
201
|
+
if (!res.ok)
|
|
202
|
+
throw res;
|
|
203
|
+
return res.json();
|
|
204
|
+
});
|
|
205
|
+
if ("error" in result)
|
|
206
|
+
throw new Error(result.error.message);
|
|
207
|
+
return result.data;
|
|
208
|
+
}
|
|
209
|
+
async listSpaces(limit = 50) {
|
|
210
|
+
const result = await this.apiCall(async (token) => {
|
|
211
|
+
const url = `${this.tokens?.instanceUrl}${CONFLUENCE_API_V2}/spaces?limit=${limit}&status=current`;
|
|
212
|
+
const res = await fetch(url, { headers: this.buildHeaders(token) });
|
|
213
|
+
if (!res.ok)
|
|
214
|
+
throw res;
|
|
215
|
+
const data = (await res.json());
|
|
216
|
+
return data.results;
|
|
217
|
+
});
|
|
218
|
+
if ("error" in result)
|
|
219
|
+
throw new Error(result.error.message);
|
|
220
|
+
return result.data;
|
|
221
|
+
}
|
|
222
|
+
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
223
|
+
buildHeaders(token) {
|
|
224
|
+
const email = this.tokens?.email ?? "";
|
|
225
|
+
const basic = Buffer.from(`${email}:${token}`).toString("base64");
|
|
226
|
+
return {
|
|
227
|
+
Authorization: `Basic ${basic}`,
|
|
228
|
+
Accept: "application/json",
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// ── Token persistence ────────────────────────────────────────────────────────
|
|
233
|
+
export function loadTokens() {
|
|
234
|
+
const envToken = process.env.CONFLUENCE_API_TOKEN;
|
|
235
|
+
const envUrl = process.env.CONFLUENCE_INSTANCE_URL;
|
|
236
|
+
const envEmail = process.env.CONFLUENCE_EMAIL;
|
|
237
|
+
if (envToken && envUrl && envEmail) {
|
|
238
|
+
return {
|
|
239
|
+
accessToken: envToken,
|
|
240
|
+
email: envEmail,
|
|
241
|
+
instanceUrl: envUrl.replace(/\/$/, ""),
|
|
242
|
+
connected_at: new Date().toISOString(),
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
return getSecretJsonSync("confluence");
|
|
246
|
+
}
|
|
247
|
+
export function saveTokens(tokens) {
|
|
248
|
+
storeSecretJsonSync("confluence", tokens);
|
|
249
|
+
}
|
|
250
|
+
export function clearTokens() {
|
|
251
|
+
try {
|
|
252
|
+
deleteSecretJsonSync("confluence");
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// ignore
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// ── Singleton instance ───────────────────────────────────────────────────────
|
|
259
|
+
let _instance = null;
|
|
260
|
+
function resetConfluenceConnector() {
|
|
261
|
+
_instance = null;
|
|
262
|
+
}
|
|
263
|
+
export function getConfluenceConnector() {
|
|
264
|
+
if (!_instance) {
|
|
265
|
+
_instance = new ConfluenceConnector();
|
|
266
|
+
}
|
|
267
|
+
return _instance;
|
|
268
|
+
}
|
|
269
|
+
export { getConfluenceConnector as confluence };
|
|
270
|
+
/**
|
|
271
|
+
* POST /connections/confluence/connect { token, email, instanceUrl }
|
|
272
|
+
*/
|
|
273
|
+
export async function handleConfluenceConnect(body) {
|
|
274
|
+
let token;
|
|
275
|
+
let email;
|
|
276
|
+
let instanceUrl;
|
|
277
|
+
try {
|
|
278
|
+
const parsed = JSON.parse(body);
|
|
279
|
+
if (typeof parsed.token !== "string" || !parsed.token) {
|
|
280
|
+
return {
|
|
281
|
+
status: 400,
|
|
282
|
+
contentType: "application/json",
|
|
283
|
+
body: JSON.stringify({ ok: false, error: "token is required" }),
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
if (typeof parsed.email !== "string" || !parsed.email) {
|
|
287
|
+
return {
|
|
288
|
+
status: 400,
|
|
289
|
+
contentType: "application/json",
|
|
290
|
+
body: JSON.stringify({ ok: false, error: "email is required" }),
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
if (typeof parsed.instanceUrl !== "string" || !parsed.instanceUrl) {
|
|
294
|
+
return {
|
|
295
|
+
status: 400,
|
|
296
|
+
contentType: "application/json",
|
|
297
|
+
body: JSON.stringify({
|
|
298
|
+
ok: false,
|
|
299
|
+
error: "instanceUrl is required (e.g. https://myteam.atlassian.net)",
|
|
300
|
+
}),
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
token = parsed.token;
|
|
304
|
+
email = parsed.email;
|
|
305
|
+
instanceUrl = parsed.instanceUrl.replace(/\/$/, "");
|
|
306
|
+
}
|
|
307
|
+
catch {
|
|
308
|
+
return {
|
|
309
|
+
status: 400,
|
|
310
|
+
contentType: "application/json",
|
|
311
|
+
body: JSON.stringify({ ok: false, error: "Invalid JSON body" }),
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
// Verify credentials by hitting spaces endpoint
|
|
315
|
+
try {
|
|
316
|
+
const basic = Buffer.from(`${email}:${token}`).toString("base64");
|
|
317
|
+
const res = await fetch(`${instanceUrl}${CONFLUENCE_API_V2}/spaces?limit=1`, {
|
|
318
|
+
headers: {
|
|
319
|
+
Authorization: `Basic ${basic}`,
|
|
320
|
+
Accept: "application/json",
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
if (!res.ok) {
|
|
324
|
+
return {
|
|
325
|
+
status: 401,
|
|
326
|
+
contentType: "application/json",
|
|
327
|
+
body: JSON.stringify({
|
|
328
|
+
ok: false,
|
|
329
|
+
error: `Credentials rejected by Confluence (HTTP ${res.status}) — check token and email`,
|
|
330
|
+
}),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
const tokens = {
|
|
334
|
+
accessToken: token,
|
|
335
|
+
email,
|
|
336
|
+
instanceUrl,
|
|
337
|
+
connected_at: new Date().toISOString(),
|
|
338
|
+
};
|
|
339
|
+
saveTokens(tokens);
|
|
340
|
+
resetConfluenceConnector();
|
|
341
|
+
return {
|
|
342
|
+
status: 200,
|
|
343
|
+
contentType: "application/json",
|
|
344
|
+
body: JSON.stringify({
|
|
345
|
+
ok: true,
|
|
346
|
+
instanceUrl,
|
|
347
|
+
connectedAt: tokens.connected_at,
|
|
348
|
+
}),
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
catch (err) {
|
|
352
|
+
return {
|
|
353
|
+
status: 500,
|
|
354
|
+
contentType: "application/json",
|
|
355
|
+
body: JSON.stringify({
|
|
356
|
+
ok: false,
|
|
357
|
+
error: err instanceof Error ? err.message : String(err),
|
|
358
|
+
}),
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* POST /connections/confluence/test
|
|
364
|
+
*/
|
|
365
|
+
export async function handleConfluenceTest() {
|
|
366
|
+
const tokens = loadTokens();
|
|
367
|
+
if (!tokens) {
|
|
368
|
+
return {
|
|
369
|
+
status: 400,
|
|
370
|
+
contentType: "application/json",
|
|
371
|
+
body: JSON.stringify({ ok: false, error: "Confluence not connected" }),
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
try {
|
|
375
|
+
const connector = getConfluenceConnector();
|
|
376
|
+
const check = await connector.healthCheck();
|
|
377
|
+
return {
|
|
378
|
+
status: check.ok ? 200 : 401,
|
|
379
|
+
contentType: "application/json",
|
|
380
|
+
body: JSON.stringify(check.ok ? { ok: true } : { ok: false, error: check.error?.message }),
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
catch (err) {
|
|
384
|
+
return {
|
|
385
|
+
status: 500,
|
|
386
|
+
contentType: "application/json",
|
|
387
|
+
body: JSON.stringify({
|
|
388
|
+
ok: false,
|
|
389
|
+
error: err instanceof Error ? err.message : String(err),
|
|
390
|
+
}),
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* DELETE /connections/confluence
|
|
396
|
+
*/
|
|
397
|
+
export function handleConfluenceDisconnect() {
|
|
398
|
+
clearTokens();
|
|
399
|
+
resetConfluenceConnector();
|
|
400
|
+
return {
|
|
401
|
+
status: 200,
|
|
402
|
+
contentType: "application/json",
|
|
403
|
+
body: JSON.stringify({ ok: true }),
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
//# sourceMappingURL=confluence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confluence.js","sourceRoot":"","sources":["../../src/connectors/confluence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface FixtureError {
|
|
2
|
+
code?: string;
|
|
3
|
+
message: string;
|
|
4
|
+
retryable?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface FixtureEntry {
|
|
7
|
+
operation: string;
|
|
8
|
+
input?: unknown;
|
|
9
|
+
output?: unknown;
|
|
10
|
+
error?: FixtureError;
|
|
11
|
+
}
|
|
12
|
+
export interface FixtureLibrary {
|
|
13
|
+
version: 1;
|
|
14
|
+
provider: string;
|
|
15
|
+
fixtures: FixtureEntry[];
|
|
16
|
+
}
|
|
17
|
+
export declare function createFixtureLibrary(provider: string): FixtureLibrary;
|
|
18
|
+
export declare function loadFixtureLibrary(filePath: string): FixtureLibrary | null;
|
|
19
|
+
export declare function saveFixtureLibrary(filePath: string, library: FixtureLibrary): void;
|
|
20
|
+
export declare function recordFixture(filePath: string, provider: string, entry: FixtureEntry): FixtureLibrary;
|
|
21
|
+
export declare function findFixture(library: FixtureLibrary, operation: string, input?: unknown): FixtureEntry | null;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
export function createFixtureLibrary(provider) {
|
|
4
|
+
return {
|
|
5
|
+
version: 1,
|
|
6
|
+
provider,
|
|
7
|
+
fixtures: [],
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function loadFixtureLibrary(filePath) {
|
|
11
|
+
if (!existsSync(filePath)) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
16
|
+
const parsed = JSON.parse(raw);
|
|
17
|
+
if (parsed.version !== 1 ||
|
|
18
|
+
typeof parsed.provider !== "string" ||
|
|
19
|
+
!Array.isArray(parsed.fixtures)) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
version: 1,
|
|
24
|
+
provider: parsed.provider,
|
|
25
|
+
fixtures: parsed.fixtures,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function saveFixtureLibrary(filePath, library) {
|
|
33
|
+
const dir = dirname(filePath);
|
|
34
|
+
if (!existsSync(dir)) {
|
|
35
|
+
mkdirSync(dir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
writeFileSync(filePath, JSON.stringify(library, null, 2));
|
|
38
|
+
}
|
|
39
|
+
export function recordFixture(filePath, provider, entry) {
|
|
40
|
+
const library = loadFixtureLibrary(filePath) ?? createFixtureLibrary(provider);
|
|
41
|
+
library.fixtures.push(entry);
|
|
42
|
+
saveFixtureLibrary(filePath, library);
|
|
43
|
+
return library;
|
|
44
|
+
}
|
|
45
|
+
export function findFixture(library, operation, input) {
|
|
46
|
+
const target = stableStringify(input ?? null);
|
|
47
|
+
for (const fixture of library.fixtures) {
|
|
48
|
+
if (fixture.operation !== operation) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (stableStringify(fixture.input ?? null) === target) {
|
|
52
|
+
return fixture;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
function stableStringify(value) {
|
|
58
|
+
return JSON.stringify(sortValue(value));
|
|
59
|
+
}
|
|
60
|
+
function sortValue(value) {
|
|
61
|
+
if (Array.isArray(value)) {
|
|
62
|
+
return value.map(sortValue);
|
|
63
|
+
}
|
|
64
|
+
if (value && typeof value === "object") {
|
|
65
|
+
const entries = Object.entries(value).sort(([a], [b]) => a.localeCompare(b));
|
|
66
|
+
return Object.fromEntries(entries.map(([key, nested]) => [key, sortValue(nested)]));
|
|
67
|
+
}
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=fixtureLibrary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixtureLibrary.js","sourceRoot":"","sources":["../../src/connectors/fixtureLibrary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function captureFixture<TOutput>(filePath: string, provider: string, operation: string, input: unknown, fn: () => Promise<TOutput>): Promise<TOutput>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { recordFixture } from "./fixtureLibrary.js";
|
|
2
|
+
export async function captureFixture(filePath, provider, operation, input, fn) {
|
|
3
|
+
try {
|
|
4
|
+
const output = await fn();
|
|
5
|
+
recordFixture(filePath, provider, {
|
|
6
|
+
operation,
|
|
7
|
+
input,
|
|
8
|
+
output,
|
|
9
|
+
});
|
|
10
|
+
return output;
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
recordFixture(filePath, provider, toErrorFixture(operation, input, error));
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function toErrorFixture(operation, input, error) {
|
|
18
|
+
if (error instanceof Error) {
|
|
19
|
+
return {
|
|
20
|
+
operation,
|
|
21
|
+
input,
|
|
22
|
+
error: {
|
|
23
|
+
message: error.message,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
operation,
|
|
29
|
+
input,
|
|
30
|
+
error: {
|
|
31
|
+
message: String(error),
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=fixtureRecorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixtureRecorder.js","sourceRoot":"","sources":["../../src/connectors/fixtureRecorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEvE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,QAAgB,EAChB,SAAiB,EACjB,KAAc,EACd,EAA0B;IAE1B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;QAC1B,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE;YAChC,SAAS;YACT,KAAK;YACL,MAAM;SACP,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,cAAc,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;QAC3E,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CACrB,SAAiB,EACjB,KAAc,EACd,KAAc;IAEd,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO;YACL,SAAS;YACT,KAAK;YACL,KAAK,EAAE;gBACL,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,SAAS;QACT,KAAK;QACL,KAAK,EAAE;YACL,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;SACvB;KACF,CAAC;AACJ,CAAC"}
|