@taodigital/connectors 0.0.0-stage → 1.2.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/dist/github.js ADDED
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ /**
3
+ * GitHub connector — credentials passed in, never read from env.
4
+ * Token is stored encrypted in Connector.config per project.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.testConnection = testConnection;
8
+ exports.listRecentCommits = listRecentCommits;
9
+ exports.createIssue = createIssue;
10
+ exports.listPullRequests = listPullRequests;
11
+ exports.pushFile = pushFile;
12
+ const core_1 = require("@taodigital/core");
13
+ /** Test that the stored credentials actually work. */
14
+ async function testConnection(creds) {
15
+ try {
16
+ await (0, core_1.assertResolvesToPublicAddress)('https://api.github.com');
17
+ const res = await fetch('https://api.github.com/user', {
18
+ headers: { Authorization: `Bearer ${creds.token}`, 'User-Agent': 'zeta-ai' },
19
+ });
20
+ if (!res.ok)
21
+ return { ok: false, error: `GitHub returned ${res.status}` };
22
+ const data = (await res.json());
23
+ return { ok: true, login: data.login };
24
+ }
25
+ catch (err) {
26
+ return { ok: false, error: String(err) };
27
+ }
28
+ }
29
+ async function listRecentCommits(creds, branch) {
30
+ await (0, core_1.assertResolvesToPublicAddress)('https://api.github.com');
31
+ const { getSystemConfig } = await import('@taodigital/core');
32
+ const ghCfg = await getSystemConfig('connectors_github');
33
+ const pageSize = parseInt(String(ghCfg?.pageSize ?? '10'), 10);
34
+ const ref = branch ?? creds.defaultBranch ?? 'main';
35
+ const res = await fetch(`https://api.github.com/repos/${creds.repo}/commits?sha=${ref}&per_page=${pageSize}`, { headers: { Authorization: `Bearer ${creds.token}`, 'User-Agent': 'zeta-ai' } });
36
+ if (!res.ok)
37
+ throw new Error(`GitHub error: ${res.status}`);
38
+ const commits = (await res.json());
39
+ return commits.map((c) => ({
40
+ sha: c.sha?.slice(0, 7),
41
+ message: c.commit?.message?.split('\n')[0],
42
+ author: c.commit?.author?.name,
43
+ date: c.commit?.author?.date,
44
+ }));
45
+ }
46
+ async function createIssue(creds, title, body, labels, opts) {
47
+ await (0, core_1.assertResolvesToPublicAddress)('https://api.github.com');
48
+ const res = await fetch(`https://api.github.com/repos/${creds.repo}/issues`, {
49
+ method: 'POST',
50
+ headers: {
51
+ Authorization: `Bearer ${creds.token}`,
52
+ 'User-Agent': 'zeta-ai',
53
+ 'Content-Type': 'application/json',
54
+ },
55
+ body: JSON.stringify({ title, body, labels: labels ?? opts?.defaultLabels ?? [] }),
56
+ });
57
+ if (!res.ok)
58
+ throw new Error(`GitHub error: ${res.status}`);
59
+ const issue = (await res.json());
60
+ return { number: issue.number, url: issue.html_url, title: issue.title };
61
+ }
62
+ async function listPullRequests(creds, state = 'open') {
63
+ await (0, core_1.assertResolvesToPublicAddress)('https://api.github.com');
64
+ const { getSystemConfig } = await import('@taodigital/core');
65
+ const ghCfg = await getSystemConfig('connectors_github');
66
+ const pageSize = parseInt(String(ghCfg?.pageSize ?? '10'), 10);
67
+ const res = await fetch(`https://api.github.com/repos/${creds.repo}/pulls?state=${state}&per_page=${pageSize}`, { headers: { Authorization: `Bearer ${creds.token}`, 'User-Agent': 'zeta-ai' } });
68
+ if (!res.ok)
69
+ throw new Error(`GitHub error: ${res.status}`);
70
+ const prs = (await res.json());
71
+ return prs.map((p) => ({
72
+ number: p.number,
73
+ title: p.title,
74
+ state: p.state,
75
+ branch: p.head?.ref,
76
+ url: p.html_url,
77
+ }));
78
+ }
79
+ /**
80
+ * Push (create or update) a single file in a GitHub repository.
81
+ * Uses the GitHub Contents API (PUT /repos/:owner/:repo/contents/:path).
82
+ */
83
+ async function pushFile(creds, filePath, content, commitMessage, branch) {
84
+ await (0, core_1.assertResolvesToPublicAddress)('https://api.github.com');
85
+ const targetBranch = branch ?? creds.defaultBranch ?? 'main';
86
+ const apiBase = 'https://api.github.com';
87
+ const headers = {
88
+ Authorization: `Bearer ${creds.token}`,
89
+ Accept: 'application/vnd.github.v3+json',
90
+ 'Content-Type': 'application/json',
91
+ 'User-Agent': 'zeta-ai',
92
+ };
93
+ const encodedContent = Buffer.from(content, 'utf8').toString('base64');
94
+ // Fetch existing file SHA (required by GitHub API to update an existing file)
95
+ let sha;
96
+ const existing = await fetch(`${apiBase}/repos/${creds.repo}/contents/${filePath}?ref=${targetBranch}`, { headers }).then((r) => (r.ok ? r.json() : null)).catch(() => null);
97
+ if (existing?.sha)
98
+ sha = existing.sha;
99
+ const body = {
100
+ message: commitMessage,
101
+ content: encodedContent,
102
+ branch: targetBranch,
103
+ };
104
+ if (sha)
105
+ body.sha = sha;
106
+ const res = await fetch(`${apiBase}/repos/${creds.repo}/contents/${filePath}`, {
107
+ method: 'PUT',
108
+ headers,
109
+ body: JSON.stringify(body),
110
+ });
111
+ if (!res.ok) {
112
+ const err = await res.json().catch(() => ({}));
113
+ throw new Error(`GitHub push failed: ${err.message ?? res.statusText}`);
114
+ }
115
+ const data = await res.json();
116
+ return {
117
+ url: data.content?.html_url ?? `https://github.com/${creds.repo}/blob/${targetBranch}/${filePath}`,
118
+ sha: data.content?.sha ?? '',
119
+ };
120
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * GitLab connector — credentials passed in, never read from env.
3
+ * Token (Personal Access Token or project token) stored encrypted
4
+ * in Connector.config per project. Supports gitlab.com and self-hosted.
5
+ */
6
+ export interface GitLabCredentials {
7
+ token: string;
8
+ projectPath: string;
9
+ baseUrl?: string;
10
+ defaultBranch?: string;
11
+ }
12
+ export declare function testConnection(creds: GitLabCredentials): Promise<{
13
+ ok: boolean;
14
+ login?: string;
15
+ error?: string;
16
+ }>;
17
+ export declare function listRecentCommits(creds: GitLabCredentials, branch?: string): Promise<{
18
+ sha: any;
19
+ message: any;
20
+ author: any;
21
+ date: any;
22
+ }[]>;
23
+ export declare function createIssue(creds: GitLabCredentials, title: string, body: string, labels?: string[]): Promise<{
24
+ number: number;
25
+ url: string;
26
+ title: string;
27
+ }>;
28
+ export declare function listMergeRequests(creds: GitLabCredentials, state?: 'opened' | 'closed' | 'merged' | 'all'): Promise<{
29
+ number: any;
30
+ title: any;
31
+ state: any;
32
+ branch: any;
33
+ url: any;
34
+ }[]>;
35
+ /**
36
+ * Push (create or update) a single file in a GitLab repository.
37
+ * Uses the GitLab Repository Files API.
38
+ */
39
+ export declare function pushFile(creds: GitLabCredentials, filePath: string, content: string, commitMessage: string, branch?: string): Promise<{
40
+ url: string;
41
+ sha: string;
42
+ }>;
package/dist/gitlab.js ADDED
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ /**
3
+ * GitLab connector — credentials passed in, never read from env.
4
+ * Token (Personal Access Token or project token) stored encrypted
5
+ * in Connector.config per project. Supports gitlab.com and self-hosted.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.testConnection = testConnection;
9
+ exports.listRecentCommits = listRecentCommits;
10
+ exports.createIssue = createIssue;
11
+ exports.listMergeRequests = listMergeRequests;
12
+ exports.pushFile = pushFile;
13
+ const core_1 = require("@taodigital/core");
14
+ function apiBase(creds) {
15
+ const host = (creds.baseUrl ?? 'https://gitlab.com').replace(/\/$/, '');
16
+ return `${host}/api/v4`;
17
+ }
18
+ function authHeaders(token) {
19
+ return { 'PRIVATE-TOKEN': token, 'Content-Type': 'application/json' };
20
+ }
21
+ /** URL-encode a project path for use in GitLab API paths. */
22
+ function encodeProject(projectPath) {
23
+ return encodeURIComponent(projectPath);
24
+ }
25
+ async function testConnection(creds) {
26
+ try {
27
+ const host = creds.baseUrl ?? 'https://gitlab.com';
28
+ await (0, core_1.assertResolvesToPublicAddress)(host);
29
+ const base = apiBase(creds);
30
+ const res = await fetch(`${base}/projects/${encodeProject(creds.projectPath)}`, {
31
+ headers: authHeaders(creds.token),
32
+ signal: AbortSignal.timeout(10_000),
33
+ });
34
+ if (res.status === 401)
35
+ return { ok: false, error: 'Invalid GitLab token.' };
36
+ if (res.status === 404)
37
+ return { ok: false, error: `Project "${creds.projectPath}" not found or token lacks access.` };
38
+ if (!res.ok)
39
+ return { ok: false, error: `GitLab returned ${res.status}.` };
40
+ const project = (await res.json());
41
+ return { ok: true, login: project.path_with_namespace ?? creds.projectPath };
42
+ }
43
+ catch (err) {
44
+ return { ok: false, error: err?.message ?? 'Could not reach GitLab.' };
45
+ }
46
+ }
47
+ async function listRecentCommits(creds, branch) {
48
+ const host = creds.baseUrl ?? 'https://gitlab.com';
49
+ await (0, core_1.assertResolvesToPublicAddress)(host);
50
+ const { getSystemConfig } = await import('@taodigital/core');
51
+ const cfg = await getSystemConfig('connectors_gitlab');
52
+ const pageSize = parseInt(String(cfg?.pageSize ?? '10'), 10);
53
+ const ref = branch ?? creds.defaultBranch ?? 'main';
54
+ const base = apiBase(creds);
55
+ const res = await fetch(`${base}/projects/${encodeProject(creds.projectPath)}/repository/commits?ref_name=${encodeURIComponent(ref)}&per_page=${pageSize}`, { headers: authHeaders(creds.token), signal: AbortSignal.timeout(15_000) });
56
+ if (!res.ok)
57
+ throw new Error(`GitLab error: ${res.status}`);
58
+ const commits = (await res.json());
59
+ return commits.map((c) => ({
60
+ sha: c.id?.slice(0, 7),
61
+ message: c.title ?? c.message?.split('\n')[0],
62
+ author: c.author_name,
63
+ date: c.created_at,
64
+ }));
65
+ }
66
+ async function createIssue(creds, title, body, labels) {
67
+ const host = creds.baseUrl ?? 'https://gitlab.com';
68
+ await (0, core_1.assertResolvesToPublicAddress)(host);
69
+ const base = apiBase(creds);
70
+ const res = await fetch(`${base}/projects/${encodeProject(creds.projectPath)}/issues`, {
71
+ method: 'POST',
72
+ headers: authHeaders(creds.token),
73
+ body: JSON.stringify({ title, description: body, labels: labels?.join(',') }),
74
+ signal: AbortSignal.timeout(15_000),
75
+ });
76
+ if (!res.ok)
77
+ throw new Error(`GitLab error: ${res.status}`);
78
+ const issue = (await res.json());
79
+ return { number: issue.iid, url: issue.web_url, title: issue.title };
80
+ }
81
+ async function listMergeRequests(creds, state = 'opened') {
82
+ const host = creds.baseUrl ?? 'https://gitlab.com';
83
+ await (0, core_1.assertResolvesToPublicAddress)(host);
84
+ const { getSystemConfig } = await import('@taodigital/core');
85
+ const cfg = await getSystemConfig('connectors_gitlab');
86
+ const pageSize = parseInt(String(cfg?.pageSize ?? '10'), 10);
87
+ const base = apiBase(creds);
88
+ const res = await fetch(`${base}/projects/${encodeProject(creds.projectPath)}/merge_requests?state=${state}&per_page=${pageSize}`, { headers: authHeaders(creds.token), signal: AbortSignal.timeout(15_000) });
89
+ if (!res.ok)
90
+ throw new Error(`GitLab error: ${res.status}`);
91
+ const mrs = (await res.json());
92
+ return mrs.map((m) => ({
93
+ number: m.iid,
94
+ title: m.title,
95
+ state: m.state,
96
+ branch: m.source_branch,
97
+ url: m.web_url,
98
+ }));
99
+ }
100
+ /**
101
+ * Push (create or update) a single file in a GitLab repository.
102
+ * Uses the GitLab Repository Files API.
103
+ */
104
+ async function pushFile(creds, filePath, content, commitMessage, branch) {
105
+ const host = creds.baseUrl ?? 'https://gitlab.com';
106
+ await (0, core_1.assertResolvesToPublicAddress)(host);
107
+ const targetBranch = branch ?? creds.defaultBranch ?? 'main';
108
+ const base = apiBase(creds);
109
+ const encodedProject = encodeProject(creds.projectPath);
110
+ const encodedPath = encodeURIComponent(filePath);
111
+ const encodedContent = Buffer.from(content, 'utf8').toString('base64');
112
+ // Check if file exists to decide between POST (create) and PUT (update)
113
+ const existing = await fetch(`${base}/projects/${encodedProject}/repository/files/${encodedPath}?ref=${encodeURIComponent(targetBranch)}`, { headers: authHeaders(creds.token), signal: AbortSignal.timeout(10_000) }).catch(() => null);
114
+ const fileExists = existing?.ok ?? false;
115
+ const method = fileExists ? 'PUT' : 'POST';
116
+ const res = await fetch(`${base}/projects/${encodedProject}/repository/files/${encodedPath}`, {
117
+ method,
118
+ headers: authHeaders(creds.token),
119
+ body: JSON.stringify({
120
+ branch: targetBranch,
121
+ content: encodedContent,
122
+ encoding: 'base64',
123
+ commit_message: commitMessage,
124
+ }),
125
+ signal: AbortSignal.timeout(20_000),
126
+ });
127
+ if (!res.ok) {
128
+ const err = await res.json().catch(() => ({}));
129
+ throw new Error(`GitLab push failed: ${err.message ?? res.statusText}`);
130
+ }
131
+ const data = (await res.json());
132
+ const glBase = (creds.baseUrl ?? 'https://gitlab.com').replace(/\/$/, '');
133
+ return {
134
+ url: `${glBase}/${creds.projectPath}/-/blob/${targetBranch}/${filePath}`,
135
+ sha: data.file_path ?? filePath,
136
+ };
137
+ }
@@ -0,0 +1,9 @@
1
+ export * as github from './github.js';
2
+ export * as gitlab from './gitlab.js';
3
+ export * as azuredevops from './azuredevops.js';
4
+ export * as jira from './jira.js';
5
+ export * as figma from './figma.js';
6
+ export * as confluence from './confluence.js';
7
+ export * as pagerduty from './pagerduty.js';
8
+ export * as servicenow from './servicenow.js';
9
+ export * as salesforce from './salesforce.js';
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.salesforce = exports.servicenow = exports.pagerduty = exports.confluence = exports.figma = exports.jira = exports.azuredevops = exports.gitlab = exports.github = void 0;
37
+ exports.github = __importStar(require("./github.js"));
38
+ exports.gitlab = __importStar(require("./gitlab.js"));
39
+ exports.azuredevops = __importStar(require("./azuredevops.js"));
40
+ exports.jira = __importStar(require("./jira.js"));
41
+ exports.figma = __importStar(require("./figma.js"));
42
+ exports.confluence = __importStar(require("./confluence.js"));
43
+ exports.pagerduty = __importStar(require("./pagerduty.js"));
44
+ exports.servicenow = __importStar(require("./servicenow.js"));
45
+ exports.salesforce = __importStar(require("./salesforce.js"));
package/dist/jira.d.ts ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ * JIRA connector — credentials passed in, never read from env.
3
+ * baseUrl and email stored as-is; apiToken stored encrypted.
4
+ */
5
+ export interface JiraCredentials {
6
+ baseUrl: string;
7
+ email: string;
8
+ apiToken: string;
9
+ password?: string;
10
+ projectKey?: string;
11
+ bearerToken?: string;
12
+ proxyUrl?: string;
13
+ }
14
+ export declare function testConnection(creds: JiraCredentials): Promise<{
15
+ ok: boolean;
16
+ displayName?: string;
17
+ error?: string;
18
+ }>;
19
+ export declare function listProjects(creds: JiraCredentials): Promise<{
20
+ key: any;
21
+ name: any;
22
+ id: any;
23
+ }[]>;
24
+ export declare function listRecentIssues(creds: JiraCredentials, maxResults?: number): Promise<any>;
25
+ export interface GetIssueOptions {
26
+ acceptanceCriteriaFieldId?: string;
27
+ }
28
+ export declare function getIssue(creds: JiraCredentials, issueKey: string, options?: GetIssueOptions): Promise<{
29
+ key: any;
30
+ summary: any;
31
+ description: any;
32
+ status: any;
33
+ priority: any;
34
+ issueType: any;
35
+ acceptanceCriteria: any;
36
+ labels: any;
37
+ components: any;
38
+ epic: {
39
+ key: any;
40
+ summary: any;
41
+ } | null;
42
+ links: any;
43
+ subtasks: any;
44
+ url: string;
45
+ }>;
46
+ export declare function createBug(creds: JiraCredentials, opts: {
47
+ summary: string;
48
+ description: string;
49
+ priority?: 'Highest' | 'High' | 'Medium' | 'Low' | 'Lowest';
50
+ labels?: string[];
51
+ defaultBugPriority?: string;
52
+ defaultBugLabel?: string;
53
+ }): Promise<{
54
+ key: any;
55
+ url: string;
56
+ }>;
57
+ export interface ListUserStoriesOptions {
58
+ acceptanceCriteriaFieldId?: string;
59
+ }
60
+ export declare function listUserStories(creds: JiraCredentials, sprintId?: string, maxResults?: number, options?: ListUserStoriesOptions): Promise<{
61
+ stories: {
62
+ key: any;
63
+ summary: any;
64
+ description: any;
65
+ acceptanceCriteria: any;
66
+ status: any;
67
+ priority: any;
68
+ issueType: any;
69
+ labels: any;
70
+ components: any;
71
+ epic: {
72
+ key: any;
73
+ summary: any;
74
+ } | null;
75
+ links: any;
76
+ subtasks: any;
77
+ url: string;
78
+ }[];
79
+ truncated: boolean;
80
+ }>;
81
+ export declare function createTestCase(creds: JiraCredentials, opts: {
82
+ summary: string;
83
+ stepsHtml: string;
84
+ priority?: 'Highest' | 'High' | 'Medium' | 'Low' | 'Lowest';
85
+ labels?: string[];
86
+ defaultIssueType?: string;
87
+ defaultTestCaseLabel?: string;
88
+ }): Promise<{
89
+ key: string;
90
+ url: string;
91
+ }>;
92
+ /** Free-text search — finds issues that mention a screen URL or name. */
93
+ export declare function searchIssues(creds: JiraCredentials, text: string, maxResults?: number): Promise<any>;