@generacy-ai/generacy-plugin-jira 0.0.0-preview-20260304013206
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 +191 -0
- package/dist/client.d.ts +81 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +163 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/operations/comments.d.ts +35 -0
- package/dist/operations/comments.d.ts.map +1 -0
- package/dist/operations/comments.js +128 -0
- package/dist/operations/comments.js.map +1 -0
- package/dist/operations/custom-fields.d.ts +48 -0
- package/dist/operations/custom-fields.d.ts.map +1 -0
- package/dist/operations/custom-fields.js +184 -0
- package/dist/operations/custom-fields.js.map +1 -0
- package/dist/operations/issues.d.ts +34 -0
- package/dist/operations/issues.d.ts.map +1 -0
- package/dist/operations/issues.js +215 -0
- package/dist/operations/issues.js.map +1 -0
- package/dist/operations/search.d.ts +47 -0
- package/dist/operations/search.d.ts.map +1 -0
- package/dist/operations/search.js +174 -0
- package/dist/operations/search.js.map +1 -0
- package/dist/operations/sprints.d.ts +54 -0
- package/dist/operations/sprints.d.ts.map +1 -0
- package/dist/operations/sprints.js +196 -0
- package/dist/operations/sprints.js.map +1 -0
- package/dist/operations/transitions.d.ts +41 -0
- package/dist/operations/transitions.d.ts.map +1 -0
- package/dist/operations/transitions.js +135 -0
- package/dist/operations/transitions.js.map +1 -0
- package/dist/plugin.d.ts +221 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +403 -0
- package/dist/plugin.js.map +1 -0
- package/dist/types/config.d.ts +149 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +33 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/custom-fields.d.ts +48 -0
- package/dist/types/custom-fields.d.ts.map +1 -0
- package/dist/types/custom-fields.js +2 -0
- package/dist/types/custom-fields.js.map +1 -0
- package/dist/types/events.d.ts +250 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +2 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/issues.d.ts +139 -0
- package/dist/types/issues.d.ts.map +1 -0
- package/dist/types/issues.js +2 -0
- package/dist/types/issues.js.map +1 -0
- package/dist/types/projects.d.ts +48 -0
- package/dist/types/projects.d.ts.map +1 -0
- package/dist/types/projects.js +2 -0
- package/dist/types/projects.js.map +1 -0
- package/dist/types/sprints.d.ts +26 -0
- package/dist/types/sprints.d.ts.map +1 -0
- package/dist/types/sprints.js +2 -0
- package/dist/types/sprints.js.map +1 -0
- package/dist/types/workflows.d.ts +60 -0
- package/dist/types/workflows.d.ts.map +1 -0
- package/dist/types/workflows.js +2 -0
- package/dist/types/workflows.js.map +1 -0
- package/dist/utils/adf.d.ts +26 -0
- package/dist/utils/adf.d.ts.map +1 -0
- package/dist/utils/adf.js +104 -0
- package/dist/utils/adf.js.map +1 -0
- package/dist/utils/errors.d.ts +60 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +117 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/jql-builder.d.ts +148 -0
- package/dist/utils/jql-builder.d.ts.map +1 -0
- package/dist/utils/jql-builder.js +264 -0
- package/dist/utils/jql-builder.js.map +1 -0
- package/dist/utils/validation.d.ts +31 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +75 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/webhooks/handler.d.ts +80 -0
- package/dist/webhooks/handler.d.ts.map +1 -0
- package/dist/webhooks/handler.js +130 -0
- package/dist/webhooks/handler.js.map +1 -0
- package/dist/webhooks/parser.d.ts +34 -0
- package/dist/webhooks/parser.d.ts.map +1 -0
- package/dist/webhooks/parser.js +155 -0
- package/dist/webhooks/parser.js.map +1 -0
- package/dist/webhooks/types.d.ts +94 -0
- package/dist/webhooks/types.d.ts.map +1 -0
- package/dist/webhooks/types.js +2 -0
- package/dist/webhooks/types.js.map +1 -0
- package/dist/webhooks/verify.d.ts +53 -0
- package/dist/webhooks/verify.d.ts.map +1 -0
- package/dist/webhooks/verify.js +140 -0
- package/dist/webhooks/verify.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JQL query builder for constructing type-safe JQL queries
|
|
3
|
+
*/
|
|
4
|
+
export class JqlBuilder {
|
|
5
|
+
conditions = [];
|
|
6
|
+
orderByClause = [];
|
|
7
|
+
/**
|
|
8
|
+
* Add a condition for project
|
|
9
|
+
*/
|
|
10
|
+
project(key) {
|
|
11
|
+
this.conditions.push(`project = "${this.escape(key)}"`);
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Add a condition for projects (multiple)
|
|
16
|
+
*/
|
|
17
|
+
projects(keys) {
|
|
18
|
+
const escaped = keys.map((k) => `"${this.escape(k)}"`).join(', ');
|
|
19
|
+
this.conditions.push(`project IN (${escaped})`);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Add a condition for issue type
|
|
24
|
+
*/
|
|
25
|
+
issueType(type) {
|
|
26
|
+
this.conditions.push(`issuetype = "${this.escape(type)}"`);
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Add a condition for issue types (multiple)
|
|
31
|
+
*/
|
|
32
|
+
issueTypes(types) {
|
|
33
|
+
const escaped = types.map((t) => `"${this.escape(t)}"`).join(', ');
|
|
34
|
+
this.conditions.push(`issuetype IN (${escaped})`);
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Add a condition for status
|
|
39
|
+
*/
|
|
40
|
+
status(name) {
|
|
41
|
+
this.conditions.push(`status = "${this.escape(name)}"`);
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Add a condition for statuses (multiple)
|
|
46
|
+
*/
|
|
47
|
+
statuses(names) {
|
|
48
|
+
const escaped = names.map((n) => `"${this.escape(n)}"`).join(', ');
|
|
49
|
+
this.conditions.push(`status IN (${escaped})`);
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Add a condition for status category
|
|
54
|
+
*/
|
|
55
|
+
statusCategory(category) {
|
|
56
|
+
const categoryMap = {
|
|
57
|
+
new: 'To Do',
|
|
58
|
+
indeterminate: 'In Progress',
|
|
59
|
+
done: 'Done',
|
|
60
|
+
};
|
|
61
|
+
this.conditions.push(`statusCategory = "${categoryMap[category]}"`);
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Add a condition for assignee
|
|
66
|
+
*/
|
|
67
|
+
assignee(accountId) {
|
|
68
|
+
this.conditions.push(`assignee = "${this.escape(accountId)}"`);
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Add a condition for unassigned issues
|
|
73
|
+
*/
|
|
74
|
+
unassigned() {
|
|
75
|
+
this.conditions.push('assignee IS EMPTY');
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Add a condition for reporter
|
|
80
|
+
*/
|
|
81
|
+
reporter(accountId) {
|
|
82
|
+
this.conditions.push(`reporter = "${this.escape(accountId)}"`);
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Add a condition for current user
|
|
87
|
+
*/
|
|
88
|
+
assignedToCurrentUser() {
|
|
89
|
+
this.conditions.push('assignee = currentUser()');
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Add a condition for sprint
|
|
94
|
+
*/
|
|
95
|
+
sprint(sprintId) {
|
|
96
|
+
this.conditions.push(`sprint = ${sprintId}`);
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Add a condition for active sprint
|
|
101
|
+
*/
|
|
102
|
+
activeSprint() {
|
|
103
|
+
this.conditions.push('sprint in openSprints()');
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Add a condition for future sprints
|
|
108
|
+
*/
|
|
109
|
+
futureSprints() {
|
|
110
|
+
this.conditions.push('sprint in futureSprints()');
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Add a condition for labels
|
|
115
|
+
*/
|
|
116
|
+
label(label) {
|
|
117
|
+
this.conditions.push(`labels = "${this.escape(label)}"`);
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Add a condition for labels (multiple, any match)
|
|
122
|
+
*/
|
|
123
|
+
labels(labels) {
|
|
124
|
+
const escaped = labels.map((l) => `"${this.escape(l)}"`).join(', ');
|
|
125
|
+
this.conditions.push(`labels IN (${escaped})`);
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Add a condition for priority
|
|
130
|
+
*/
|
|
131
|
+
priority(name) {
|
|
132
|
+
this.conditions.push(`priority = "${this.escape(name)}"`);
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Add a condition for priorities (multiple)
|
|
137
|
+
*/
|
|
138
|
+
priorities(names) {
|
|
139
|
+
const escaped = names.map((n) => `"${this.escape(n)}"`).join(', ');
|
|
140
|
+
this.conditions.push(`priority IN (${escaped})`);
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Add a condition for parent issue (epic)
|
|
145
|
+
*/
|
|
146
|
+
parent(parentKey) {
|
|
147
|
+
this.conditions.push(`parent = "${this.escape(parentKey)}"`);
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Add a condition for epic link
|
|
152
|
+
*/
|
|
153
|
+
epicLink(epicKey) {
|
|
154
|
+
this.conditions.push(`"Epic Link" = "${this.escape(epicKey)}"`);
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Add a condition for created date
|
|
159
|
+
*/
|
|
160
|
+
createdAfter(date) {
|
|
161
|
+
this.conditions.push(`created >= "${this.formatDate(date)}"`);
|
|
162
|
+
return this;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Add a condition for created date
|
|
166
|
+
*/
|
|
167
|
+
createdBefore(date) {
|
|
168
|
+
this.conditions.push(`created <= "${this.formatDate(date)}"`);
|
|
169
|
+
return this;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Add a condition for updated date
|
|
173
|
+
*/
|
|
174
|
+
updatedAfter(date) {
|
|
175
|
+
this.conditions.push(`updated >= "${this.formatDate(date)}"`);
|
|
176
|
+
return this;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Add a condition for updated date
|
|
180
|
+
*/
|
|
181
|
+
updatedBefore(date) {
|
|
182
|
+
this.conditions.push(`updated <= "${this.formatDate(date)}"`);
|
|
183
|
+
return this;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Add a condition for due date
|
|
187
|
+
*/
|
|
188
|
+
dueBefore(date) {
|
|
189
|
+
this.conditions.push(`due <= "${this.formatDate(date)}"`);
|
|
190
|
+
return this;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Add a condition for overdue issues
|
|
194
|
+
*/
|
|
195
|
+
overdue() {
|
|
196
|
+
this.conditions.push('due < now()');
|
|
197
|
+
return this;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Add a text search condition
|
|
201
|
+
*/
|
|
202
|
+
text(query) {
|
|
203
|
+
this.conditions.push(`text ~ "${this.escape(query)}"`);
|
|
204
|
+
return this;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Add a summary search condition
|
|
208
|
+
*/
|
|
209
|
+
summaryContains(text) {
|
|
210
|
+
this.conditions.push(`summary ~ "${this.escape(text)}"`);
|
|
211
|
+
return this;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Add a raw JQL condition
|
|
215
|
+
*/
|
|
216
|
+
raw(condition) {
|
|
217
|
+
this.conditions.push(condition);
|
|
218
|
+
return this;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Add order by clause
|
|
222
|
+
*/
|
|
223
|
+
orderBy(field, direction = 'ASC') {
|
|
224
|
+
this.orderByClause.push(`${field} ${direction}`);
|
|
225
|
+
return this;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Build the JQL query string
|
|
229
|
+
*/
|
|
230
|
+
build() {
|
|
231
|
+
let jql = this.conditions.join(' AND ');
|
|
232
|
+
if (this.orderByClause.length > 0) {
|
|
233
|
+
jql += ` ORDER BY ${this.orderByClause.join(', ')}`;
|
|
234
|
+
}
|
|
235
|
+
return jql;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Reset the builder
|
|
239
|
+
*/
|
|
240
|
+
reset() {
|
|
241
|
+
this.conditions = [];
|
|
242
|
+
this.orderByClause = [];
|
|
243
|
+
return this;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Escape special characters in JQL values
|
|
247
|
+
*/
|
|
248
|
+
escape(value) {
|
|
249
|
+
return value.replace(/"/g, '\\"');
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Format date for JQL
|
|
253
|
+
*/
|
|
254
|
+
formatDate(date) {
|
|
255
|
+
return date.toISOString().split('T')[0] ?? '';
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Create a new JQL builder
|
|
260
|
+
*/
|
|
261
|
+
export function jql() {
|
|
262
|
+
return new JqlBuilder();
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=jql-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jql-builder.js","sourceRoot":"","sources":["../../src/utils/jql-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { JiraConfig, ValidatedJiraConfig } from '../types/config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validate Jira configuration
|
|
4
|
+
* @throws {JiraValidationError} if configuration is invalid
|
|
5
|
+
*/
|
|
6
|
+
export declare function validateConfig(config: JiraConfig): ValidatedJiraConfig;
|
|
7
|
+
/**
|
|
8
|
+
* Validate an issue key format (e.g., "PROJ-123")
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateIssueKey(key: string): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Validate a project key format (e.g., "PROJ")
|
|
13
|
+
*/
|
|
14
|
+
export declare function validateProjectKey(key: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Validate JQL query (basic syntax check)
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateJql(jql: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Validate a date string (YYYY-MM-DD format)
|
|
21
|
+
*/
|
|
22
|
+
export declare function validateDateString(date: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Ensure a value is an issue key, throwing if invalid
|
|
25
|
+
*/
|
|
26
|
+
export declare function ensureIssueKey(key: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Ensure a value is a project key, throwing if invalid
|
|
29
|
+
*/
|
|
30
|
+
export declare function ensureProjectKey(key: string): string;
|
|
31
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI1E;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,mBAAmB,CAiBtE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQhD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOpD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { ZodError } from 'zod';
|
|
2
|
+
import { JiraConfigSchema } from '../types/config.js';
|
|
3
|
+
import { JiraValidationError } from './errors.js';
|
|
4
|
+
/**
|
|
5
|
+
* Validate Jira configuration
|
|
6
|
+
* @throws {JiraValidationError} if configuration is invalid
|
|
7
|
+
*/
|
|
8
|
+
export function validateConfig(config) {
|
|
9
|
+
try {
|
|
10
|
+
return JiraConfigSchema.parse(config);
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
if (error instanceof ZodError) {
|
|
14
|
+
const details = {};
|
|
15
|
+
for (const issue of error.issues) {
|
|
16
|
+
const path = issue.path.join('.');
|
|
17
|
+
if (!details[path]) {
|
|
18
|
+
details[path] = [];
|
|
19
|
+
}
|
|
20
|
+
details[path].push(issue.message);
|
|
21
|
+
}
|
|
22
|
+
throw new JiraValidationError('Invalid Jira configuration', details);
|
|
23
|
+
}
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Validate an issue key format (e.g., "PROJ-123")
|
|
29
|
+
*/
|
|
30
|
+
export function validateIssueKey(key) {
|
|
31
|
+
return /^[A-Z][A-Z0-9]+-\d+$/.test(key);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Validate a project key format (e.g., "PROJ")
|
|
35
|
+
*/
|
|
36
|
+
export function validateProjectKey(key) {
|
|
37
|
+
return /^[A-Z][A-Z0-9_]*$/.test(key);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate JQL query (basic syntax check)
|
|
41
|
+
*/
|
|
42
|
+
export function validateJql(jql) {
|
|
43
|
+
// Basic validation - not empty and doesn't contain obvious injection attempts
|
|
44
|
+
if (!jql.trim()) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
// Jira JQL doesn't allow certain special characters in specific contexts
|
|
48
|
+
// This is a basic sanity check, Jira API will provide full validation
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Validate a date string (YYYY-MM-DD format)
|
|
53
|
+
*/
|
|
54
|
+
export function validateDateString(date) {
|
|
55
|
+
return /^\d{4}-\d{2}-\d{2}$/.test(date);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Ensure a value is an issue key, throwing if invalid
|
|
59
|
+
*/
|
|
60
|
+
export function ensureIssueKey(key) {
|
|
61
|
+
if (!validateIssueKey(key)) {
|
|
62
|
+
throw new JiraValidationError(`Invalid issue key format: ${key}. Expected format: PROJECT-123`);
|
|
63
|
+
}
|
|
64
|
+
return key;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Ensure a value is a project key, throwing if invalid
|
|
68
|
+
*/
|
|
69
|
+
export function ensureProjectKey(key) {
|
|
70
|
+
if (!validateProjectKey(key)) {
|
|
71
|
+
throw new JiraValidationError(`Invalid project key format: ${key}. Must start with uppercase letter.`);
|
|
72
|
+
}
|
|
73
|
+
return key;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAE/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAkB;IAC/C,IAAI,CAAC;QACH,OAAO,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,MAAM,OAAO,GAA6B,EAAE,CAAC;YAC7C,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnB,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACrB,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,IAAI,mBAAmB,CAAC,4BAA4B,EAAE,OAAO,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,OAAO,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,8EAA8E;IAC9E,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,yEAAyE;IACzE,sEAAsE;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAO,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,mBAAmB,CAC3B,6BAA6B,GAAG,gCAAgC,CACjE,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,mBAAmB,CAC3B,+BAA+B,GAAG,qCAAqC,CACxE,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { JiraWebhookEvent, JiraEventType, WebhookAction, WebhookActionType, WebhookHandler } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for webhook handler
|
|
4
|
+
*/
|
|
5
|
+
export interface JiraWebhookHandlerConfig {
|
|
6
|
+
/** Optional webhook secret for verification */
|
|
7
|
+
webhookSecret?: string;
|
|
8
|
+
/** Whether to log events */
|
|
9
|
+
logEvents?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Result of processing a webhook event
|
|
13
|
+
*/
|
|
14
|
+
export interface WebhookProcessResult {
|
|
15
|
+
success: boolean;
|
|
16
|
+
action: WebhookAction;
|
|
17
|
+
handlersExecuted: number;
|
|
18
|
+
errors: Error[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Jira webhook event handler
|
|
22
|
+
*/
|
|
23
|
+
export declare class JiraWebhookHandler {
|
|
24
|
+
private handlers;
|
|
25
|
+
private readonly config;
|
|
26
|
+
constructor(config?: JiraWebhookHandlerConfig);
|
|
27
|
+
/**
|
|
28
|
+
* Register a handler for specific event types
|
|
29
|
+
*/
|
|
30
|
+
on(eventTypes: JiraEventType | JiraEventType[], handler: WebhookHandler): this;
|
|
31
|
+
/**
|
|
32
|
+
* Register a handler for specific action types
|
|
33
|
+
*/
|
|
34
|
+
onAction(actionTypes: WebhookActionType | WebhookActionType[], handler: WebhookHandler): this;
|
|
35
|
+
/**
|
|
36
|
+
* Register a handler for issue created events
|
|
37
|
+
*/
|
|
38
|
+
onIssueCreated(handler: WebhookHandler): this;
|
|
39
|
+
/**
|
|
40
|
+
* Register a handler for issue updated events
|
|
41
|
+
*/
|
|
42
|
+
onIssueUpdated(handler: WebhookHandler): this;
|
|
43
|
+
/**
|
|
44
|
+
* Register a handler for issue transitioned events
|
|
45
|
+
*/
|
|
46
|
+
onIssueTransitioned(handler: WebhookHandler): this;
|
|
47
|
+
/**
|
|
48
|
+
* Register a handler for issue assigned events
|
|
49
|
+
*/
|
|
50
|
+
onIssueAssigned(handler: WebhookHandler): this;
|
|
51
|
+
/**
|
|
52
|
+
* Register a handler for comment created events
|
|
53
|
+
*/
|
|
54
|
+
onCommentCreated(handler: WebhookHandler): this;
|
|
55
|
+
/**
|
|
56
|
+
* Process a raw webhook payload
|
|
57
|
+
*/
|
|
58
|
+
handle(payload: unknown): Promise<WebhookProcessResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Process a typed webhook event
|
|
61
|
+
*/
|
|
62
|
+
processEvent(event: JiraWebhookEvent): Promise<WebhookProcessResult>;
|
|
63
|
+
/**
|
|
64
|
+
* Find handlers that match the event and action
|
|
65
|
+
*/
|
|
66
|
+
private findMatchingHandlers;
|
|
67
|
+
/**
|
|
68
|
+
* Clear all registered handlers
|
|
69
|
+
*/
|
|
70
|
+
clearHandlers(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Get the number of registered handlers
|
|
73
|
+
*/
|
|
74
|
+
get handlerCount(): number;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create a new webhook handler instance
|
|
78
|
+
*/
|
|
79
|
+
export declare function createWebhookHandler(config?: JiraWebhookHandlerConfig): JiraWebhookHandler;
|
|
80
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/webhooks/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,cAAc,EAEf,MAAM,YAAY,CAAC;AAGpB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,+CAA+C;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,KAAK,EAAE,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAoC;IACpD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;gBAEtC,MAAM,GAAE,wBAA6B;IAIjD;;OAEG;IACH,EAAE,CACA,UAAU,EAAE,aAAa,GAAG,aAAa,EAAE,EAC3C,OAAO,EAAE,cAAc,GACtB,IAAI;IAMP;;OAEG;IACH,QAAQ,CACN,WAAW,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,EACpD,OAAO,EAAE,cAAc,GACtB,IAAI;IAUP;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAI7C;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAI7C;;OAEG;IACH,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIlD;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAI9C;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAI/C;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAK7D;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA6B1E;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAoB5B;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;CACF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,CAAC,EAAE,wBAAwB,GAChC,kBAAkB,CAEpB"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { parseWebhookPayload, parseWebhookAction } from './parser.js';
|
|
2
|
+
/**
|
|
3
|
+
* Jira webhook event handler
|
|
4
|
+
*/
|
|
5
|
+
export class JiraWebhookHandler {
|
|
6
|
+
handlers = [];
|
|
7
|
+
config;
|
|
8
|
+
constructor(config = {}) {
|
|
9
|
+
this.config = config;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Register a handler for specific event types
|
|
13
|
+
*/
|
|
14
|
+
on(eventTypes, handler) {
|
|
15
|
+
const types = Array.isArray(eventTypes) ? eventTypes : [eventTypes];
|
|
16
|
+
this.handlers.push({ eventTypes: types, handler });
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Register a handler for specific action types
|
|
21
|
+
*/
|
|
22
|
+
onAction(actionTypes, handler) {
|
|
23
|
+
const types = Array.isArray(actionTypes) ? actionTypes : [actionTypes];
|
|
24
|
+
this.handlers.push({
|
|
25
|
+
eventTypes: [], // Will match any event type
|
|
26
|
+
actionTypes: types,
|
|
27
|
+
handler,
|
|
28
|
+
});
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Register a handler for issue created events
|
|
33
|
+
*/
|
|
34
|
+
onIssueCreated(handler) {
|
|
35
|
+
return this.on('jira:issue_created', handler);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Register a handler for issue updated events
|
|
39
|
+
*/
|
|
40
|
+
onIssueUpdated(handler) {
|
|
41
|
+
return this.on('jira:issue_updated', handler);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Register a handler for issue transitioned events
|
|
45
|
+
*/
|
|
46
|
+
onIssueTransitioned(handler) {
|
|
47
|
+
return this.onAction('issue_transitioned', handler);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Register a handler for issue assigned events
|
|
51
|
+
*/
|
|
52
|
+
onIssueAssigned(handler) {
|
|
53
|
+
return this.onAction('issue_assigned', handler);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Register a handler for comment created events
|
|
57
|
+
*/
|
|
58
|
+
onCommentCreated(handler) {
|
|
59
|
+
return this.on('comment_created', handler);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Process a raw webhook payload
|
|
63
|
+
*/
|
|
64
|
+
async handle(payload) {
|
|
65
|
+
const event = parseWebhookPayload(payload);
|
|
66
|
+
return this.processEvent(event);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Process a typed webhook event
|
|
70
|
+
*/
|
|
71
|
+
async processEvent(event) {
|
|
72
|
+
const action = parseWebhookAction(event);
|
|
73
|
+
if (this.config.logEvents) {
|
|
74
|
+
console.log(`[JiraWebhook] ${event.webhookEvent} -> ${action.type}`, {
|
|
75
|
+
issueKey: action.issueKey,
|
|
76
|
+
userId: action.userId,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const matchingHandlers = this.findMatchingHandlers(event, action);
|
|
80
|
+
const errors = [];
|
|
81
|
+
for (const registration of matchingHandlers) {
|
|
82
|
+
try {
|
|
83
|
+
await registration.handler(event, action);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
errors.push(error instanceof Error ? error : new Error(String(error)));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
success: errors.length === 0,
|
|
91
|
+
action,
|
|
92
|
+
handlersExecuted: matchingHandlers.length,
|
|
93
|
+
errors,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Find handlers that match the event and action
|
|
98
|
+
*/
|
|
99
|
+
findMatchingHandlers(event, action) {
|
|
100
|
+
return this.handlers.filter((registration) => {
|
|
101
|
+
// Check event type match
|
|
102
|
+
const eventTypeMatch = registration.eventTypes.length === 0 ||
|
|
103
|
+
registration.eventTypes.includes(event.webhookEvent);
|
|
104
|
+
// Check action type match
|
|
105
|
+
const actionTypeMatch = !registration.actionTypes ||
|
|
106
|
+
registration.actionTypes.length === 0 ||
|
|
107
|
+
registration.actionTypes.includes(action.type);
|
|
108
|
+
return eventTypeMatch && actionTypeMatch;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Clear all registered handlers
|
|
113
|
+
*/
|
|
114
|
+
clearHandlers() {
|
|
115
|
+
this.handlers = [];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get the number of registered handlers
|
|
119
|
+
*/
|
|
120
|
+
get handlerCount() {
|
|
121
|
+
return this.handlers.length;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Create a new webhook handler instance
|
|
126
|
+
*/
|
|
127
|
+
export function createWebhookHandler(config) {
|
|
128
|
+
return new JiraWebhookHandler(config);
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/webhooks/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { JiraWebhookEvent, WebhookAction, ChangelogItem, Changelog } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a raw webhook payload into a typed event
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseWebhookPayload(payload: unknown): JiraWebhookEvent;
|
|
6
|
+
/**
|
|
7
|
+
* Extract changes from a changelog
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractChanges(changelog?: Changelog): ChangelogItem[];
|
|
10
|
+
/**
|
|
11
|
+
* Check if a specific field was changed
|
|
12
|
+
*/
|
|
13
|
+
export declare function hasFieldChange(changelog: Changelog | undefined, fieldName: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Get the change for a specific field
|
|
16
|
+
*/
|
|
17
|
+
export declare function getFieldChange(changelog: Changelog | undefined, fieldName: string): ChangelogItem | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Parse webhook event into a normalized action
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseWebhookAction(event: JiraWebhookEvent): WebhookAction;
|
|
22
|
+
/**
|
|
23
|
+
* Check if an event is for a specific issue
|
|
24
|
+
*/
|
|
25
|
+
export declare function isEventForIssue(event: JiraWebhookEvent, issueKey: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Check if an event involves a specific user
|
|
28
|
+
*/
|
|
29
|
+
export declare function isEventByUser(event: JiraWebhookEvent, accountId: string): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Get the issue key from any webhook event
|
|
32
|
+
*/
|
|
33
|
+
export declare function getIssueKeyFromEvent(event: JiraWebhookEvent): string | null;
|
|
34
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/webhooks/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAGhB,aAAa,EAEb,aAAa,EACb,SAAS,EACV,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,CActE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,aAAa,EAAE,CAErE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,SAAS,EAAE,MAAM,GAChB,OAAO,CAIT;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,SAAS,EAAE,MAAM,GAChB,aAAa,GAAG,SAAS,CAI3B;AAoDD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,aAAa,CA0DzE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,gBAAgB,EACvB,QAAQ,EAAE,MAAM,GACf,OAAO,CAKT;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAK3E"}
|