react-visual-feedback 1.4.9 → 2.2.1
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 +89 -3
- package/dist/index.esm.js +2 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/config.js +664 -0
- package/dist/integrations/config.js.map +1 -0
- package/dist/integrations/index.js +4 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/server/index.js +2907 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/jira.js +1565 -0
- package/dist/server/jira.js.map +1 -0
- package/dist/server/sheets.js +1448 -0
- package/dist/server/sheets.js.map +1 -0
- package/package.json +30 -3
|
@@ -0,0 +1,664 @@
|
|
|
1
|
+
function _arrayLikeToArray(r, a) {
|
|
2
|
+
(null == a || a > r.length) && (a = r.length);
|
|
3
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
4
|
+
return n;
|
|
5
|
+
}
|
|
6
|
+
function _arrayWithHoles(r) {
|
|
7
|
+
if (Array.isArray(r)) return r;
|
|
8
|
+
}
|
|
9
|
+
function _arrayWithoutHoles(r) {
|
|
10
|
+
if (Array.isArray(r)) return _arrayLikeToArray(r);
|
|
11
|
+
}
|
|
12
|
+
function _defineProperty(e, r, t) {
|
|
13
|
+
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
14
|
+
value: t,
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true
|
|
18
|
+
}) : e[r] = t, e;
|
|
19
|
+
}
|
|
20
|
+
function _iterableToArray(r) {
|
|
21
|
+
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
|
22
|
+
}
|
|
23
|
+
function _iterableToArrayLimit(r, l) {
|
|
24
|
+
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
25
|
+
if (null != t) {
|
|
26
|
+
var e,
|
|
27
|
+
n,
|
|
28
|
+
i,
|
|
29
|
+
u,
|
|
30
|
+
a = [],
|
|
31
|
+
f = true,
|
|
32
|
+
o = false;
|
|
33
|
+
try {
|
|
34
|
+
if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
|
35
|
+
} catch (r) {
|
|
36
|
+
o = true, n = r;
|
|
37
|
+
} finally {
|
|
38
|
+
try {
|
|
39
|
+
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
|
|
40
|
+
} finally {
|
|
41
|
+
if (o) throw n;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return a;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function _nonIterableRest() {
|
|
48
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
49
|
+
}
|
|
50
|
+
function _nonIterableSpread() {
|
|
51
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
52
|
+
}
|
|
53
|
+
function ownKeys(e, r) {
|
|
54
|
+
var t = Object.keys(e);
|
|
55
|
+
if (Object.getOwnPropertySymbols) {
|
|
56
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
57
|
+
r && (o = o.filter(function (r) {
|
|
58
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
59
|
+
})), t.push.apply(t, o);
|
|
60
|
+
}
|
|
61
|
+
return t;
|
|
62
|
+
}
|
|
63
|
+
function _objectSpread2(e) {
|
|
64
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
65
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
66
|
+
r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
|
|
67
|
+
_defineProperty(e, r, t[r]);
|
|
68
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
69
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return e;
|
|
73
|
+
}
|
|
74
|
+
function _slicedToArray(r, e) {
|
|
75
|
+
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
|
|
76
|
+
}
|
|
77
|
+
function _toConsumableArray(r) {
|
|
78
|
+
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
|
79
|
+
}
|
|
80
|
+
function _toPrimitive(t, r) {
|
|
81
|
+
if ("object" != typeof t || !t) return t;
|
|
82
|
+
var e = t[Symbol.toPrimitive];
|
|
83
|
+
if (void 0 !== e) {
|
|
84
|
+
var i = e.call(t, r);
|
|
85
|
+
if ("object" != typeof i) return i;
|
|
86
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
87
|
+
}
|
|
88
|
+
return ("string" === r ? String : Number)(t);
|
|
89
|
+
}
|
|
90
|
+
function _toPropertyKey(t) {
|
|
91
|
+
var i = _toPrimitive(t, "string");
|
|
92
|
+
return "symbol" == typeof i ? i : i + "";
|
|
93
|
+
}
|
|
94
|
+
function _typeof(o) {
|
|
95
|
+
"@babel/helpers - typeof";
|
|
96
|
+
|
|
97
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
|
|
98
|
+
return typeof o;
|
|
99
|
+
} : function (o) {
|
|
100
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
101
|
+
}, _typeof(o);
|
|
102
|
+
}
|
|
103
|
+
function _unsupportedIterableToArray(r, a) {
|
|
104
|
+
if (r) {
|
|
105
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
106
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
107
|
+
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Integration Configuration & Default Mappings
|
|
113
|
+
* Users can customize these by passing their own config
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
// ============================================
|
|
117
|
+
// ATLASSIAN DOCUMENT FORMAT (ADF) HELPER
|
|
118
|
+
// ============================================
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Convert plain text to Atlassian Document Format
|
|
122
|
+
* Jira Cloud requires descriptions in ADF format
|
|
123
|
+
*/
|
|
124
|
+
function textToADF(text) {
|
|
125
|
+
var lines = text.split('\n');
|
|
126
|
+
var content = [];
|
|
127
|
+
var currentParagraph = [];
|
|
128
|
+
var flushParagraph = function flushParagraph() {
|
|
129
|
+
if (currentParagraph.length > 0) {
|
|
130
|
+
content.push({
|
|
131
|
+
type: 'paragraph',
|
|
132
|
+
content: currentParagraph
|
|
133
|
+
});
|
|
134
|
+
currentParagraph = [];
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
lines.forEach(function (line, index) {
|
|
138
|
+
// Check if it's a section header (ALL CAPS)
|
|
139
|
+
if (line.match(/^[A-Z][A-Z\s]+$/) && line.trim().length > 0) {
|
|
140
|
+
flushParagraph();
|
|
141
|
+
content.push({
|
|
142
|
+
type: 'heading',
|
|
143
|
+
attrs: {
|
|
144
|
+
level: 3
|
|
145
|
+
},
|
|
146
|
+
content: [{
|
|
147
|
+
type: 'text',
|
|
148
|
+
text: line
|
|
149
|
+
}]
|
|
150
|
+
});
|
|
151
|
+
} else if (line === '---') {
|
|
152
|
+
// Horizontal rule
|
|
153
|
+
flushParagraph();
|
|
154
|
+
content.push({
|
|
155
|
+
type: 'rule'
|
|
156
|
+
});
|
|
157
|
+
} else if (line.trim() === '') {
|
|
158
|
+
// Empty line - flush paragraph
|
|
159
|
+
flushParagraph();
|
|
160
|
+
} else {
|
|
161
|
+
// Regular line
|
|
162
|
+
if (currentParagraph.length > 0) {
|
|
163
|
+
currentParagraph.push({
|
|
164
|
+
type: 'hardBreak'
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
currentParagraph.push({
|
|
168
|
+
type: 'text',
|
|
169
|
+
text: line
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
flushParagraph();
|
|
174
|
+
return {
|
|
175
|
+
type: 'doc',
|
|
176
|
+
version: 1,
|
|
177
|
+
content: content.length > 0 ? content : [{
|
|
178
|
+
type: 'paragraph',
|
|
179
|
+
content: [{
|
|
180
|
+
type: 'text',
|
|
181
|
+
text: ' '
|
|
182
|
+
}]
|
|
183
|
+
}]
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ============================================
|
|
188
|
+
// GOOGLE SHEETS COLUMN MAPPING
|
|
189
|
+
// ============================================
|
|
190
|
+
|
|
191
|
+
var DEFAULT_SHEET_COLUMNS = {
|
|
192
|
+
timestamp: {
|
|
193
|
+
key: 'timestamp',
|
|
194
|
+
header: 'Timestamp',
|
|
195
|
+
field: 'timestamp',
|
|
196
|
+
transform: function transform(value) {
|
|
197
|
+
return value || new Date().toISOString();
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
id: {
|
|
201
|
+
key: 'id',
|
|
202
|
+
header: 'Feedback ID',
|
|
203
|
+
field: 'id'
|
|
204
|
+
},
|
|
205
|
+
feedback: {
|
|
206
|
+
key: 'feedback',
|
|
207
|
+
header: 'Feedback',
|
|
208
|
+
field: 'feedback'
|
|
209
|
+
},
|
|
210
|
+
type: {
|
|
211
|
+
key: 'type',
|
|
212
|
+
header: 'Type',
|
|
213
|
+
field: 'type',
|
|
214
|
+
transform: function transform(value) {
|
|
215
|
+
return value || 'bug';
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
status: {
|
|
219
|
+
key: 'status',
|
|
220
|
+
header: 'Status',
|
|
221
|
+
field: 'status',
|
|
222
|
+
transform: function transform(value) {
|
|
223
|
+
return value || 'new';
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
userName: {
|
|
227
|
+
key: 'userName',
|
|
228
|
+
header: 'User Name',
|
|
229
|
+
field: 'userName',
|
|
230
|
+
transform: function transform(value) {
|
|
231
|
+
return value || 'Anonymous';
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
userEmail: {
|
|
235
|
+
key: 'userEmail',
|
|
236
|
+
header: 'User Email',
|
|
237
|
+
field: 'userEmail',
|
|
238
|
+
transform: function transform(value) {
|
|
239
|
+
return value || '';
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
url: {
|
|
243
|
+
key: 'url',
|
|
244
|
+
header: 'Page URL',
|
|
245
|
+
field: 'url'
|
|
246
|
+
},
|
|
247
|
+
viewport: {
|
|
248
|
+
key: 'viewport',
|
|
249
|
+
header: 'Viewport',
|
|
250
|
+
field: 'viewport',
|
|
251
|
+
transform: function transform(value) {
|
|
252
|
+
return value ? "".concat(value.width, "x").concat(value.height) : '';
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
userAgent: {
|
|
256
|
+
key: 'userAgent',
|
|
257
|
+
header: 'Browser',
|
|
258
|
+
field: 'userAgent',
|
|
259
|
+
transform: function transform(value) {
|
|
260
|
+
if (!value) return '';
|
|
261
|
+
// Simplify user agent
|
|
262
|
+
if (value.includes('Chrome')) return 'Chrome';
|
|
263
|
+
if (value.includes('Firefox')) return 'Firefox';
|
|
264
|
+
if (value.includes('Safari')) return 'Safari';
|
|
265
|
+
if (value.includes('Edge')) return 'Edge';
|
|
266
|
+
return value.substring(0, 50);
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
screenshot: {
|
|
270
|
+
key: 'screenshot',
|
|
271
|
+
header: 'Screenshot',
|
|
272
|
+
field: 'screenshot',
|
|
273
|
+
transform: function transform(value) {
|
|
274
|
+
return value ? 'Yes' : 'No';
|
|
275
|
+
} // Don't store base64 in sheets
|
|
276
|
+
},
|
|
277
|
+
video: {
|
|
278
|
+
key: 'video',
|
|
279
|
+
header: 'Video',
|
|
280
|
+
field: 'video',
|
|
281
|
+
transform: function transform(value) {
|
|
282
|
+
return value ? 'Yes' : 'No';
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
elementSelector: {
|
|
286
|
+
key: 'elementSelector',
|
|
287
|
+
header: 'Element',
|
|
288
|
+
field: 'elementInfo',
|
|
289
|
+
transform: function transform(value) {
|
|
290
|
+
return (value === null || value === void 0 ? void 0 : value.selector) || '';
|
|
291
|
+
}
|
|
292
|
+
},
|
|
293
|
+
componentName: {
|
|
294
|
+
key: 'componentName',
|
|
295
|
+
header: 'Component',
|
|
296
|
+
field: 'elementInfo',
|
|
297
|
+
transform: function transform(value) {
|
|
298
|
+
var _value$componentStack;
|
|
299
|
+
return (value === null || value === void 0 || (_value$componentStack = value.componentStack) === null || _value$componentStack === void 0 ? void 0 : _value$componentStack[0]) || '';
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
sourceFile: {
|
|
303
|
+
key: 'sourceFile',
|
|
304
|
+
header: 'Source File',
|
|
305
|
+
field: 'elementInfo',
|
|
306
|
+
transform: function transform(value) {
|
|
307
|
+
return (value === null || value === void 0 ? void 0 : value.sourceFile) || '';
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
jiraKey: {
|
|
311
|
+
key: 'jiraKey',
|
|
312
|
+
header: 'Jira Issue',
|
|
313
|
+
field: 'jiraKey',
|
|
314
|
+
transform: function transform(value) {
|
|
315
|
+
return value || '';
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// Default columns to include (order matters)
|
|
321
|
+
var DEFAULT_SHEET_COLUMN_ORDER = ['timestamp', 'id', 'feedback', 'type', 'status', 'userName', 'userEmail', 'url', 'viewport', 'screenshot', 'video', 'jiraKey'];
|
|
322
|
+
|
|
323
|
+
// ============================================
|
|
324
|
+
// JIRA FIELD MAPPING
|
|
325
|
+
// ============================================
|
|
326
|
+
|
|
327
|
+
var DEFAULT_JIRA_FIELDS = {
|
|
328
|
+
summary: {
|
|
329
|
+
key: 'summary',
|
|
330
|
+
source: 'feedback',
|
|
331
|
+
maxLength: 255,
|
|
332
|
+
prefix: '[Feedback] ',
|
|
333
|
+
transform: function transform(data) {
|
|
334
|
+
var prefix = '[Feedback] ';
|
|
335
|
+
var text = data.feedback || 'User Feedback';
|
|
336
|
+
var maxLen = 255 - prefix.length;
|
|
337
|
+
return prefix + (text.length > maxLen ? text.substring(0, maxLen - 3) + '...' : text);
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
description: {
|
|
341
|
+
key: 'description',
|
|
342
|
+
// Build description directly - no wiki markup, clean plain text for ADF
|
|
343
|
+
transform: function transform(data) {
|
|
344
|
+
var lines = [];
|
|
345
|
+
|
|
346
|
+
// Feedback Details
|
|
347
|
+
lines.push('FEEDBACK DETAILS');
|
|
348
|
+
lines.push("Feedback: ".concat(data.feedback || 'No feedback provided'));
|
|
349
|
+
lines.push("Type: ".concat(data.type || 'bug'));
|
|
350
|
+
lines.push("Status: ".concat(data.status || 'new'));
|
|
351
|
+
lines.push('');
|
|
352
|
+
|
|
353
|
+
// User Information
|
|
354
|
+
lines.push('USER INFORMATION');
|
|
355
|
+
lines.push("Name: ".concat(data.userName || 'Anonymous'));
|
|
356
|
+
lines.push("Email: ".concat(data.userEmail || 'Not provided'));
|
|
357
|
+
lines.push('');
|
|
358
|
+
|
|
359
|
+
// Technical Details
|
|
360
|
+
lines.push('TECHNICAL DETAILS');
|
|
361
|
+
lines.push("Page URL: ".concat(data.url || 'N/A'));
|
|
362
|
+
if (data.viewport) {
|
|
363
|
+
lines.push("Viewport: ".concat(data.viewport.width, "x").concat(data.viewport.height));
|
|
364
|
+
}
|
|
365
|
+
if (data.userAgent) {
|
|
366
|
+
// Simplify user agent
|
|
367
|
+
var browser = data.userAgent;
|
|
368
|
+
if (browser.includes('Chrome')) browser = 'Chrome';else if (browser.includes('Firefox')) browser = 'Firefox';else if (browser.includes('Safari')) browser = 'Safari';else if (browser.includes('Edge')) browser = 'Edge';
|
|
369
|
+
lines.push("Browser: ".concat(browser));
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Element info
|
|
373
|
+
if (data.elementInfo) {
|
|
374
|
+
var _data$elementInfo$com;
|
|
375
|
+
if (data.elementInfo.selector) {
|
|
376
|
+
lines.push("Element: ".concat(data.elementInfo.selector));
|
|
377
|
+
}
|
|
378
|
+
if ((_data$elementInfo$com = data.elementInfo.componentStack) !== null && _data$elementInfo$com !== void 0 && _data$elementInfo$com.length) {
|
|
379
|
+
lines.push("Component: ".concat(data.elementInfo.componentStack.join(' > ')));
|
|
380
|
+
}
|
|
381
|
+
if (data.elementInfo.sourceFile) {
|
|
382
|
+
lines.push("Source: ".concat(data.elementInfo.sourceFile, ":").concat(data.elementInfo.lineNumber || ''));
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
lines.push('');
|
|
386
|
+
|
|
387
|
+
// Attachments
|
|
388
|
+
var attachments = [];
|
|
389
|
+
if (data.screenshot) attachments.push('Screenshot');
|
|
390
|
+
if (data.video) attachments.push('Screen Recording');
|
|
391
|
+
if (attachments.length > 0) {
|
|
392
|
+
lines.push('ATTACHMENTS');
|
|
393
|
+
lines.push(attachments.join(', ') + ' attached');
|
|
394
|
+
lines.push('');
|
|
395
|
+
}
|
|
396
|
+
lines.push('---');
|
|
397
|
+
lines.push('Submitted via React Visual Feedback');
|
|
398
|
+
return lines.join('\n');
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
issuetype: {
|
|
402
|
+
key: 'issuetype',
|
|
403
|
+
// Default to 'Task' which exists in most Jira projects
|
|
404
|
+
// Can be overridden via JIRA_ISSUE_TYPE env var or config
|
|
405
|
+
value: 'Task',
|
|
406
|
+
// Map feedback types to Jira issue types (all default to Task for compatibility)
|
|
407
|
+
typeMapping: {
|
|
408
|
+
bug: 'Task',
|
|
409
|
+
feature: 'Task',
|
|
410
|
+
improvement: 'Task',
|
|
411
|
+
question: 'Task',
|
|
412
|
+
other: 'Task'
|
|
413
|
+
},
|
|
414
|
+
transform: function transform(data, config) {
|
|
415
|
+
var _process$env;
|
|
416
|
+
// Priority: env var > config value > type mapping > default
|
|
417
|
+
var envIssueType = typeof process !== 'undefined' ? (_process$env = process.env) === null || _process$env === void 0 ? void 0 : _process$env.JIRA_ISSUE_TYPE : null;
|
|
418
|
+
if (envIssueType) return envIssueType;
|
|
419
|
+
if (config !== null && config !== void 0 && config.value && config.value !== 'Task') return config.value;
|
|
420
|
+
var mapping = (config === null || config === void 0 ? void 0 : config.typeMapping) || DEFAULT_JIRA_FIELDS.issuetype.typeMapping;
|
|
421
|
+
return mapping[data.type] || (config === null || config === void 0 ? void 0 : config.value) || 'Task';
|
|
422
|
+
}
|
|
423
|
+
},
|
|
424
|
+
labels: {
|
|
425
|
+
key: 'labels',
|
|
426
|
+
value: ['user-feedback'],
|
|
427
|
+
transform: function transform(data, config) {
|
|
428
|
+
var labels = _toConsumableArray((config === null || config === void 0 ? void 0 : config.value) || ['user-feedback']);
|
|
429
|
+
if (data.type) labels.push("type-".concat(data.type));
|
|
430
|
+
return labels;
|
|
431
|
+
}
|
|
432
|
+
},
|
|
433
|
+
priority: {
|
|
434
|
+
key: 'priority',
|
|
435
|
+
// Map to Jira priority IDs (user can customize)
|
|
436
|
+
priorityMapping: {
|
|
437
|
+
bug: 'High',
|
|
438
|
+
feature: 'Medium',
|
|
439
|
+
improvement: 'Medium',
|
|
440
|
+
question: 'Low',
|
|
441
|
+
other: 'Low'
|
|
442
|
+
},
|
|
443
|
+
transform: function transform(data, config) {
|
|
444
|
+
var mapping = (config === null || config === void 0 ? void 0 : config.priorityMapping) || DEFAULT_JIRA_FIELDS.priority.priorityMapping;
|
|
445
|
+
return mapping[data.type] || 'Medium';
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
// ============================================
|
|
451
|
+
// JIRA STATUS MAPPING (Bidirectional sync)
|
|
452
|
+
// ============================================
|
|
453
|
+
|
|
454
|
+
var DEFAULT_JIRA_STATUS_MAPPING = {
|
|
455
|
+
// Our status -> Jira status
|
|
456
|
+
toJira: {
|
|
457
|
+
"new": 'To Do',
|
|
458
|
+
open: 'To Do',
|
|
459
|
+
inProgress: 'In Progress',
|
|
460
|
+
underReview: 'In Review',
|
|
461
|
+
onHold: 'On Hold',
|
|
462
|
+
resolved: 'Done',
|
|
463
|
+
closed: 'Done',
|
|
464
|
+
wontFix: 'Won\'t Do'
|
|
465
|
+
},
|
|
466
|
+
// Jira status -> Our status
|
|
467
|
+
fromJira: {
|
|
468
|
+
'To Do': 'open',
|
|
469
|
+
'Open': 'open',
|
|
470
|
+
'In Progress': 'inProgress',
|
|
471
|
+
'In Review': 'underReview',
|
|
472
|
+
'On Hold': 'onHold',
|
|
473
|
+
'Done': 'resolved',
|
|
474
|
+
'Closed': 'closed',
|
|
475
|
+
'Won\'t Do': 'wontFix',
|
|
476
|
+
'Resolved': 'resolved'
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
// ============================================
|
|
481
|
+
// INTEGRATION TYPES
|
|
482
|
+
// ============================================
|
|
483
|
+
|
|
484
|
+
var INTEGRATION_TYPES = {
|
|
485
|
+
JIRA: {
|
|
486
|
+
SERVER: 'server',
|
|
487
|
+
// Our server handler
|
|
488
|
+
AUTOMATION: 'jira-automation',
|
|
489
|
+
// Jira's built-in webhooks
|
|
490
|
+
ZAPIER: 'zapier' // Zapier webhook
|
|
491
|
+
},
|
|
492
|
+
SHEETS: {
|
|
493
|
+
SERVER: 'server',
|
|
494
|
+
// Our server handler (Service Account)
|
|
495
|
+
OAUTH: 'oauth',
|
|
496
|
+
// OAuth with refresh
|
|
497
|
+
APPS_SCRIPT: 'google-apps-script',
|
|
498
|
+
// Google Apps Script
|
|
499
|
+
ZAPIER: 'zapier' // Zapier webhook
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
// ============================================
|
|
504
|
+
// HELPER FUNCTIONS
|
|
505
|
+
// ============================================
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Merge user config with defaults
|
|
509
|
+
*/
|
|
510
|
+
function mergeSheetColumns() {
|
|
511
|
+
var userColumns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
512
|
+
var columnOrder = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
513
|
+
var merged = _objectSpread2({}, DEFAULT_SHEET_COLUMNS);
|
|
514
|
+
|
|
515
|
+
// Apply user overrides
|
|
516
|
+
Object.entries(userColumns).forEach(function (_ref) {
|
|
517
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
518
|
+
key = _ref2[0],
|
|
519
|
+
value = _ref2[1];
|
|
520
|
+
if (value === null || value === false) {
|
|
521
|
+
// Remove column
|
|
522
|
+
delete merged[key];
|
|
523
|
+
} else if (_typeof(value) === 'object') {
|
|
524
|
+
// Merge with default
|
|
525
|
+
merged[key] = _objectSpread2(_objectSpread2({}, merged[key]), value);
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
// Determine column order
|
|
530
|
+
var order = columnOrder || Object.keys(merged).filter(function (k) {
|
|
531
|
+
return DEFAULT_SHEET_COLUMN_ORDER.includes(k) || userColumns[k];
|
|
532
|
+
});
|
|
533
|
+
return {
|
|
534
|
+
columns: merged,
|
|
535
|
+
order: order
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Merge user Jira config with defaults
|
|
541
|
+
*/
|
|
542
|
+
function mergeJiraFields() {
|
|
543
|
+
var userFields = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
544
|
+
var merged = _objectSpread2({}, DEFAULT_JIRA_FIELDS);
|
|
545
|
+
Object.entries(userFields).forEach(function (_ref3) {
|
|
546
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
547
|
+
key = _ref4[0],
|
|
548
|
+
value = _ref4[1];
|
|
549
|
+
if (value === null || value === false) {
|
|
550
|
+
delete merged[key];
|
|
551
|
+
} else if (_typeof(value) === 'object') {
|
|
552
|
+
merged[key] = _objectSpread2(_objectSpread2({}, merged[key]), value);
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
return merged;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Transform feedback data to sheet row
|
|
560
|
+
*/
|
|
561
|
+
function feedbackToSheetRow(feedbackData) {
|
|
562
|
+
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
563
|
+
var _mergeSheetColumns = mergeSheetColumns(config.columns, config.columnOrder),
|
|
564
|
+
columns = _mergeSheetColumns.columns,
|
|
565
|
+
order = _mergeSheetColumns.order;
|
|
566
|
+
var row = order.map(function (key) {
|
|
567
|
+
var col = columns[key];
|
|
568
|
+
if (!col) return '';
|
|
569
|
+
var rawValue = feedbackData[col.field];
|
|
570
|
+
if (col.transform) {
|
|
571
|
+
return col.transform(rawValue) || '';
|
|
572
|
+
}
|
|
573
|
+
return rawValue || '';
|
|
574
|
+
});
|
|
575
|
+
return row;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Get sheet headers
|
|
580
|
+
*/
|
|
581
|
+
function getSheetHeaders() {
|
|
582
|
+
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
583
|
+
var _mergeSheetColumns2 = mergeSheetColumns(config.columns, config.columnOrder),
|
|
584
|
+
columns = _mergeSheetColumns2.columns,
|
|
585
|
+
order = _mergeSheetColumns2.order;
|
|
586
|
+
return order.map(function (key) {
|
|
587
|
+
var _columns$key;
|
|
588
|
+
return ((_columns$key = columns[key]) === null || _columns$key === void 0 ? void 0 : _columns$key.header) || key;
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Transform feedback data to Jira issue
|
|
594
|
+
*/
|
|
595
|
+
function feedbackToJiraIssue(feedbackData) {
|
|
596
|
+
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
597
|
+
var fields = mergeJiraFields(config.fields);
|
|
598
|
+
|
|
599
|
+
// Get plain text description and convert to ADF
|
|
600
|
+
var plainDescription = fields.description.transform(feedbackData, fields.description);
|
|
601
|
+
var adfDescription = textToADF(plainDescription);
|
|
602
|
+
var issue = {
|
|
603
|
+
fields: {
|
|
604
|
+
project: {
|
|
605
|
+
key: config.projectKey
|
|
606
|
+
},
|
|
607
|
+
summary: fields.summary.transform(feedbackData, fields.summary),
|
|
608
|
+
description: adfDescription,
|
|
609
|
+
issuetype: {
|
|
610
|
+
name: fields.issuetype.transform(feedbackData, fields.issuetype)
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
// Add labels if configured
|
|
616
|
+
if (fields.labels) {
|
|
617
|
+
issue.fields.labels = fields.labels.transform(feedbackData, fields.labels);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// Add priority if configured and user wants it
|
|
621
|
+
if (config.includePriority && fields.priority) {
|
|
622
|
+
issue.fields.priority = {
|
|
623
|
+
name: fields.priority.transform(feedbackData, fields.priority)
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// Add custom fields
|
|
628
|
+
if (config.customFields) {
|
|
629
|
+
Object.entries(config.customFields).forEach(function (_ref5) {
|
|
630
|
+
var _ref6 = _slicedToArray(_ref5, 2),
|
|
631
|
+
fieldId = _ref6[0],
|
|
632
|
+
fieldConfig = _ref6[1];
|
|
633
|
+
if (typeof fieldConfig === 'string') {
|
|
634
|
+
issue.fields[fieldId] = feedbackData[fieldConfig];
|
|
635
|
+
} else if (fieldConfig.transform) {
|
|
636
|
+
issue.fields[fieldId] = fieldConfig.transform(feedbackData);
|
|
637
|
+
} else if (fieldConfig.value) {
|
|
638
|
+
issue.fields[fieldId] = fieldConfig.value;
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
return issue;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Map Jira status to our status
|
|
647
|
+
*/
|
|
648
|
+
function mapJiraStatusToLocal(jiraStatus) {
|
|
649
|
+
var customMapping = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
650
|
+
var mapping = _objectSpread2(_objectSpread2({}, DEFAULT_JIRA_STATUS_MAPPING.fromJira), customMapping);
|
|
651
|
+
return mapping[jiraStatus] || 'open';
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* Map our status to Jira status
|
|
656
|
+
*/
|
|
657
|
+
function mapLocalStatusToJira(localStatus) {
|
|
658
|
+
var customMapping = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
659
|
+
var mapping = _objectSpread2(_objectSpread2({}, DEFAULT_JIRA_STATUS_MAPPING.toJira), customMapping);
|
|
660
|
+
return mapping[localStatus] || 'To Do';
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
export { DEFAULT_JIRA_FIELDS, DEFAULT_JIRA_STATUS_MAPPING, DEFAULT_SHEET_COLUMNS, DEFAULT_SHEET_COLUMN_ORDER, INTEGRATION_TYPES, feedbackToJiraIssue, feedbackToSheetRow, getSheetHeaders, mapJiraStatusToLocal, mapLocalStatusToJira, mergeJiraFields, mergeSheetColumns, textToADF };
|
|
664
|
+
//# sourceMappingURL=config.js.map
|