@journai/feedback-core 0.1.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/src/cards/categoryCard.d.ts +2 -0
- package/dist/src/cards/categoryCard.js +27 -0
- package/dist/src/cards/categoryCard.js.map +1 -0
- package/dist/src/cards/confirmationCard.d.ts +2 -0
- package/dist/src/cards/confirmationCard.js +15 -0
- package/dist/src/cards/confirmationCard.js.map +1 -0
- package/dist/src/cards/detailsCard.d.ts +2 -0
- package/dist/src/cards/detailsCard.js +45 -0
- package/dist/src/cards/detailsCard.js.map +1 -0
- package/dist/src/cards/index.d.ts +5 -0
- package/dist/src/cards/index.js +7 -0
- package/dist/src/cards/index.js.map +1 -0
- package/dist/src/cards/inlineButtons.d.ts +2 -0
- package/dist/src/cards/inlineButtons.js +16 -0
- package/dist/src/cards/inlineButtons.js.map +1 -0
- package/dist/src/cards/undoneCard.d.ts +2 -0
- package/dist/src/cards/undoneCard.js +11 -0
- package/dist/src/cards/undoneCard.js.map +1 -0
- package/dist/src/client.d.ts +9 -0
- package/dist/src/client.js +44 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/flow.d.ts +49 -0
- package/dist/src/flow.js +104 -0
- package/dist/src/flow.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/screenshot.d.ts +11 -0
- package/dist/src/screenshot.js +24 -0
- package/dist/src/screenshot.js.map +1 -0
- package/dist/src/types.d.ts +68 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/wrap.d.ts +4 -0
- package/dist/src/wrap.js +13 -0
- package/dist/src/wrap.js.map +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function buildCategoryCard(entryPath) {
|
|
2
|
+
const actions = [
|
|
3
|
+
{ type: 'Action.Submit', title: '🐛 Fehler', style: 'default', data: { feedbackAction: 'selectCategory', category: 'bug' } },
|
|
4
|
+
{ type: 'Action.Submit', title: '🔄 Änderung', style: 'default', data: { feedbackAction: 'selectCategory', category: 'change' } },
|
|
5
|
+
{ type: 'Action.Submit', title: '💡 Idee', style: 'default', data: { feedbackAction: 'selectCategory', category: 'idea' } },
|
|
6
|
+
];
|
|
7
|
+
if (entryPath === 'general') {
|
|
8
|
+
actions.push({ type: 'Action.Submit', title: '❓ Sonstiges', style: 'default', data: { feedbackAction: 'selectCategory', category: 'other' } });
|
|
9
|
+
}
|
|
10
|
+
return {
|
|
11
|
+
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
12
|
+
type: 'AdaptiveCard',
|
|
13
|
+
version: '1.5',
|
|
14
|
+
body: [
|
|
15
|
+
{ type: 'TextBlock', text: '📋 Was möchtest du uns mitteilen?', weight: 'Bolder', size: 'Medium' },
|
|
16
|
+
{
|
|
17
|
+
type: 'TextBlock',
|
|
18
|
+
text: 'Bezieht sich auf die markierte Antwort. Der Verlauf wird automatisch mitgesendet.',
|
|
19
|
+
isSubtle: true,
|
|
20
|
+
wrap: true,
|
|
21
|
+
isVisible: entryPath === 'marker',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
actions,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=categoryCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"categoryCard.js","sourceRoot":"","sources":["../../../src/cards/categoryCard.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAAC,SAAoB;IACpD,MAAM,OAAO,GAAwF;QACnG,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC5H,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;QACjI,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;KAC5H,CAAC;IAEF,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;IACjJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,KAAK;QACd,IAAI,EAAE;YACJ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,mCAAmC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;YAClG;gBACE,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,mFAAmF;gBACzF,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,IAAI;gBACV,SAAS,EAAE,SAAS,KAAK,QAAQ;aAClC;SACF;QACD,OAAO;KACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function buildConfirmationCard(feedbackId, undoToken) {
|
|
2
|
+
return {
|
|
3
|
+
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
4
|
+
type: 'AdaptiveCard',
|
|
5
|
+
version: '1.5',
|
|
6
|
+
body: [
|
|
7
|
+
{ type: 'TextBlock', text: '✓ Danke für deine Rückmeldung!', weight: 'Bolder', size: 'Medium' },
|
|
8
|
+
{ type: 'TextBlock', text: 'Wir schauen uns das an.', isSubtle: true, wrap: true },
|
|
9
|
+
],
|
|
10
|
+
actions: [
|
|
11
|
+
{ type: 'Action.Submit', title: '↩️ Zurücknehmen', style: 'default', data: { feedbackAction: 'undoFeedback', feedbackId, undoToken } },
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=confirmationCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirmationCard.js","sourceRoot":"","sources":["../../../src/cards/confirmationCard.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,qBAAqB,CAAC,UAAkB,EAAE,SAAiB;IACzE,OAAO;QACL,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,KAAK;QACd,IAAI,EAAE;YACJ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,gCAAgC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/F,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,yBAAyB,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;SACnF;QACD,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE;SACvI;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const CATEGORY_LABELS = {
|
|
2
|
+
bug: '🐛 Fehler',
|
|
3
|
+
change: '🔄 Änderung',
|
|
4
|
+
idea: '💡 Idee',
|
|
5
|
+
other: '❓ Sonstiges',
|
|
6
|
+
};
|
|
7
|
+
export function buildDetailsCard(category) {
|
|
8
|
+
return {
|
|
9
|
+
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
10
|
+
type: 'AdaptiveCard',
|
|
11
|
+
version: '1.5',
|
|
12
|
+
body: [
|
|
13
|
+
{ type: 'TextBlock', text: '📋 Deine Rückmeldung', weight: 'Bolder', size: 'Medium' },
|
|
14
|
+
{ type: 'TextBlock', text: `Kategorie: ${CATEGORY_LABELS[category]} ✓`, isSubtle: true },
|
|
15
|
+
{
|
|
16
|
+
type: 'Input.Text',
|
|
17
|
+
id: 'description',
|
|
18
|
+
label: 'Beschreibe das Problem (optional):',
|
|
19
|
+
placeholder: 'z.B. "Die Antwort enthält falsche Zahlen"',
|
|
20
|
+
isMultiline: true,
|
|
21
|
+
maxLength: 500,
|
|
22
|
+
isRequired: false,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
type: 'Input.Toggle',
|
|
26
|
+
id: 'wantsScreenshot',
|
|
27
|
+
title: 'Ich möchte einen Screenshot anfügen',
|
|
28
|
+
value: 'false',
|
|
29
|
+
valueOn: 'true',
|
|
30
|
+
valueOff: 'false',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: 'TextBlock',
|
|
34
|
+
text: 'ℹ️ Nach dem Absenden kannst du den Screenshot direkt als Bild in diesen Chat senden. 💡 Tipp: Windows+Shift+S',
|
|
35
|
+
isSubtle: true,
|
|
36
|
+
wrap: true,
|
|
37
|
+
size: 'Small',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
actions: [
|
|
41
|
+
{ type: 'Action.Submit', title: '📤 Absenden', style: 'positive', data: { feedbackAction: 'submitFeedback', category } },
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=detailsCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detailsCard.js","sourceRoot":"","sources":["../../../src/cards/detailsCard.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GAAqC;IACxD,GAAG,EAAE,WAAW;IAChB,MAAM,EAAE,aAAa;IACrB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,aAAa;CACrB,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,QAA0B;IACzD,OAAO;QACL,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,KAAK;QACd,IAAI,EAAE;YACJ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,sBAAsB,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;YACrF,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,eAAe,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;YACxF;gBACE,IAAI,EAAE,YAAY;gBAClB,EAAE,EAAE,aAAa;gBACjB,KAAK,EAAE,oCAAoC;gBAC3C,WAAW,EAAE,2CAA2C;gBACxD,WAAW,EAAE,IAAI;gBACjB,SAAS,EAAE,GAAG;gBACd,UAAU,EAAE,KAAK;aAClB;YACD;gBACE,IAAI,EAAE,cAAc;gBACpB,EAAE,EAAE,iBAAiB;gBACrB,KAAK,EAAE,qCAAqC;gBAC5C,KAAK,EAAE,OAAO;gBACd,OAAO,EAAE,MAAM;gBACf,QAAQ,EAAE,OAAO;aAClB;YACD;gBACE,IAAI,EAAE,WAAW;gBACjB,IAAI,EAAE,+GAA+G;gBACrH,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,OAAO;aACd;SACF;QACD,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE;SACzH;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { buildCategoryCard } from './categoryCard.js';
|
|
2
|
+
export { buildDetailsCard } from './detailsCard.js';
|
|
3
|
+
export { buildConfirmationCard } from './confirmationCard.js';
|
|
4
|
+
export { buildUndoneCard } from './undoneCard.js';
|
|
5
|
+
export { buildInlineButtons } from './inlineButtons.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Card builder exports — no SDK dependency
|
|
2
|
+
export { buildCategoryCard } from './categoryCard.js';
|
|
3
|
+
export { buildDetailsCard } from './detailsCard.js';
|
|
4
|
+
export { buildConfirmationCard } from './confirmationCard.js';
|
|
5
|
+
export { buildUndoneCard } from './undoneCard.js';
|
|
6
|
+
export { buildInlineButtons } from './inlineButtons.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cards/index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function buildInlineButtons(botResponseText) {
|
|
2
|
+
return {
|
|
3
|
+
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
4
|
+
type: 'AdaptiveCard',
|
|
5
|
+
version: '1.5',
|
|
6
|
+
body: [
|
|
7
|
+
{ type: 'TextBlock', text: botResponseText, wrap: true },
|
|
8
|
+
],
|
|
9
|
+
actions: [
|
|
10
|
+
{ type: 'Action.Submit', title: '⚑ Stimmt nicht', style: 'default', data: { feedbackAction: 'reportIssue', entryPath: 'marker' } },
|
|
11
|
+
{ type: 'Action.Submit', title: '💬 Anders erklären', style: 'default', data: { feedbackAction: 'explainDifferently' } },
|
|
12
|
+
{ type: 'Action.Submit', title: '🔄 Nochmal', style: 'default', data: { feedbackAction: 'regenerate' } },
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=inlineButtons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inlineButtons.js","sourceRoot":"","sources":["../../../src/cards/inlineButtons.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,kBAAkB,CAAC,eAAuB;IACxD,OAAO;QACL,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,KAAK;QACd,IAAI,EAAE;YACJ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE;SACzD;QACD,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE;YAClI,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,oBAAoB,EAAE,EAAE;YACxH,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,EAAE;SACzG;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function buildUndoneCard() {
|
|
2
|
+
return {
|
|
3
|
+
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
4
|
+
type: 'AdaptiveCard',
|
|
5
|
+
version: '1.5',
|
|
6
|
+
body: [
|
|
7
|
+
{ type: 'TextBlock', text: '↩️ Feedback wurde zurückgenommen.', wrap: true },
|
|
8
|
+
],
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=undoneCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undoneCard.js","sourceRoot":"","sources":["../../../src/cards/undoneCard.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,KAAK;QACd,IAAI,EAAE;YACJ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,mCAAmC,EAAE,IAAI,EAAE,IAAI,EAAE;SAC7E;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SubmitFeedbackPayload, SubmitFeedbackResponse, UndoFeedbackResponse, UploadScreenshotResponse } from './types.js';
|
|
2
|
+
export declare class FeedbackClient {
|
|
3
|
+
private apiEndpoint;
|
|
4
|
+
private apiKey;
|
|
5
|
+
constructor(apiEndpoint: string, apiKey: string);
|
|
6
|
+
submitFeedback(payload: SubmitFeedbackPayload): Promise<SubmitFeedbackResponse>;
|
|
7
|
+
undoFeedback(feedbackId: string, undoToken: string): Promise<UndoFeedbackResponse>;
|
|
8
|
+
uploadScreenshot(feedbackId: string, imageBuffer: Buffer, contentType: string): Promise<UploadScreenshotResponse>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export class FeedbackClient {
|
|
2
|
+
apiEndpoint;
|
|
3
|
+
apiKey;
|
|
4
|
+
constructor(apiEndpoint, apiKey) {
|
|
5
|
+
this.apiEndpoint = apiEndpoint;
|
|
6
|
+
this.apiKey = apiKey;
|
|
7
|
+
}
|
|
8
|
+
async submitFeedback(payload) {
|
|
9
|
+
const res = await fetch(`${this.apiEndpoint}/feedback`, {
|
|
10
|
+
method: 'POST',
|
|
11
|
+
headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey },
|
|
12
|
+
body: JSON.stringify(payload),
|
|
13
|
+
});
|
|
14
|
+
if (!res.ok) {
|
|
15
|
+
const err = await res.json().catch(() => ({}));
|
|
16
|
+
throw new Error(`Submit failed (${res.status}): ${err.error ?? 'Unknown'}`);
|
|
17
|
+
}
|
|
18
|
+
return res.json();
|
|
19
|
+
}
|
|
20
|
+
async undoFeedback(feedbackId, undoToken) {
|
|
21
|
+
const res = await fetch(`${this.apiEndpoint}/feedback/${feedbackId}/undo`, {
|
|
22
|
+
method: 'DELETE',
|
|
23
|
+
headers: { 'x-undo-token': undoToken, 'x-api-key': this.apiKey },
|
|
24
|
+
});
|
|
25
|
+
if (res.status === 200)
|
|
26
|
+
return { success: true, expired: false };
|
|
27
|
+
if (res.status === 410)
|
|
28
|
+
return { success: false, expired: true };
|
|
29
|
+
return { success: false, expired: false };
|
|
30
|
+
}
|
|
31
|
+
async uploadScreenshot(feedbackId, imageBuffer, contentType) {
|
|
32
|
+
const res = await fetch(`${this.apiEndpoint}/feedback/${feedbackId}/screenshot`, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: { 'Content-Type': contentType, 'x-api-key': this.apiKey },
|
|
35
|
+
body: new Uint8Array(imageBuffer),
|
|
36
|
+
});
|
|
37
|
+
if (!res.ok) {
|
|
38
|
+
const err = await res.json().catch(() => ({}));
|
|
39
|
+
throw new Error(`Screenshot upload failed (${res.status}): ${err.error ?? 'Unknown'}`);
|
|
40
|
+
}
|
|
41
|
+
return res.json();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,cAAc;IACL;IAA6B;IAAjD,YAAoB,WAAmB,EAAU,MAAc;QAA3C,gBAAW,GAAX,WAAW,CAAQ;QAAU,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAEnE,KAAK,CAAC,cAAc,CAAC,OAA8B;QACjD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,WAAW,WAAW,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE;YACzE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,MAAM,MAAO,GAA0B,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC;QACtG,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAAqC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,UAAkB,EAAE,SAAiB;QACtD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,WAAW,aAAa,UAAU,OAAO,EAAE;YACzE,MAAM,EAAE,QAAQ;YAChB,OAAO,EAAE,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE;SACjE,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACjE,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACjE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,UAAkB,EAAE,WAAmB,EAAE,WAAmB;QACjF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,WAAW,aAAa,UAAU,aAAa,EAAE;YAC/E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE;YAClE,IAAI,EAAE,IAAI,UAAU,CAAC,WAAW,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,MAAM,MAAO,GAA0B,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC;QACjH,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,EAAuC,CAAC;IACzD,CAAC;CACF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { FeedbackAction, ChannelType, SubmitFeedbackPayload, AdaptiveCard } from './types.js';
|
|
2
|
+
import type { FeedbackClient } from './client.js';
|
|
3
|
+
import type { ScreenshotTracker } from './screenshot.js';
|
|
4
|
+
export interface FeedbackContext {
|
|
5
|
+
userId: string;
|
|
6
|
+
userName?: string;
|
|
7
|
+
conversationId: string;
|
|
8
|
+
channelType: ChannelType;
|
|
9
|
+
agentName?: string;
|
|
10
|
+
markedMessageText?: string;
|
|
11
|
+
recentMessages?: Array<{
|
|
12
|
+
role: string;
|
|
13
|
+
text: string;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
export interface FeedbackFlowResult {
|
|
17
|
+
/** Adaptive Card JSON to send */
|
|
18
|
+
card?: AdaptiveCard;
|
|
19
|
+
/** Plain text message to send (e.g., screenshot prompt) */
|
|
20
|
+
message?: string;
|
|
21
|
+
screenshotPending?: boolean;
|
|
22
|
+
feedbackId?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether the card should replace (update) the previous card in the conversation.
|
|
25
|
+
* True for selectCategory, submitFeedback, undoFeedback.
|
|
26
|
+
* False for reportIssue (always new card).
|
|
27
|
+
* Consumers that support updateActivity should use this flag.
|
|
28
|
+
*/
|
|
29
|
+
replacesPreviousCard?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface HandleFeedbackOptions {
|
|
32
|
+
/**
|
|
33
|
+
* Called before submitting feedback to allow SDK layers to inject
|
|
34
|
+
* SDK-specific fields like conversationReference and correlation.
|
|
35
|
+
*/
|
|
36
|
+
enrichPayload?: (payload: SubmitFeedbackPayload) => SubmitFeedbackPayload;
|
|
37
|
+
/** Screenshot tracker for managing pending screenshot uploads. */
|
|
38
|
+
screenshotTracker?: ScreenshotTracker;
|
|
39
|
+
/** Timeout in ms for pending screenshot uploads. Defaults to 60000. */
|
|
40
|
+
screenshotTimeoutMs?: number;
|
|
41
|
+
}
|
|
42
|
+
/** Type guard: checks if value is a FeedbackAction with a feedbackAction string. */
|
|
43
|
+
export declare function isFeedbackAction(value: unknown): value is FeedbackAction;
|
|
44
|
+
/**
|
|
45
|
+
* SDK-agnostic feedback flow handler.
|
|
46
|
+
* Processes a feedback action and returns the result card/message to send.
|
|
47
|
+
* Does NOT call context.sendActivity — the consumer does that.
|
|
48
|
+
*/
|
|
49
|
+
export declare function handleFeedbackAction(action: FeedbackAction, client: FeedbackClient, context: FeedbackContext, options?: HandleFeedbackOptions): Promise<FeedbackFlowResult>;
|
package/dist/src/flow.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { buildCategoryCard } from './cards/categoryCard.js';
|
|
2
|
+
import { buildDetailsCard } from './cards/detailsCard.js';
|
|
3
|
+
import { buildConfirmationCard } from './cards/confirmationCard.js';
|
|
4
|
+
import { buildUndoneCard } from './cards/undoneCard.js';
|
|
5
|
+
/** Type guard: checks if value is a FeedbackAction with a feedbackAction string. */
|
|
6
|
+
export function isFeedbackAction(value) {
|
|
7
|
+
return (typeof value === 'object' &&
|
|
8
|
+
value !== null &&
|
|
9
|
+
'feedbackAction' in value &&
|
|
10
|
+
typeof value['feedbackAction'] === 'string');
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* SDK-agnostic feedback flow handler.
|
|
14
|
+
* Processes a feedback action and returns the result card/message to send.
|
|
15
|
+
* Does NOT call context.sendActivity — the consumer does that.
|
|
16
|
+
*/
|
|
17
|
+
export async function handleFeedbackAction(action, client, context, options) {
|
|
18
|
+
switch (action.feedbackAction) {
|
|
19
|
+
case 'reportIssue':
|
|
20
|
+
return { card: buildCategoryCard(action.entryPath ?? 'marker'), replacesPreviousCard: false };
|
|
21
|
+
case 'selectCategory':
|
|
22
|
+
return { card: buildDetailsCard((action.category ?? 'bug')), replacesPreviousCard: true };
|
|
23
|
+
case 'submitFeedback':
|
|
24
|
+
return handleSubmitFeedback(action, client, context, options);
|
|
25
|
+
case 'undoFeedback':
|
|
26
|
+
return handleUndoFeedback(action, client, context, options);
|
|
27
|
+
default:
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function handleSubmitFeedback(action, client, context, options) {
|
|
32
|
+
let payload = {
|
|
33
|
+
category: (action.category ?? 'bug'),
|
|
34
|
+
entryPath: action.entryPath ?? 'marker',
|
|
35
|
+
description: action.description,
|
|
36
|
+
userId: context.userId,
|
|
37
|
+
userName: context.userName,
|
|
38
|
+
conversationId: context.conversationId,
|
|
39
|
+
channelType: context.channelType,
|
|
40
|
+
topicName: context.agentName,
|
|
41
|
+
markedMessageText: context.markedMessageText,
|
|
42
|
+
};
|
|
43
|
+
if (options?.enrichPayload) {
|
|
44
|
+
payload = options.enrichPayload(payload);
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
const result = await client.submitFeedback(payload);
|
|
48
|
+
const wantsScreenshot = action.wantsScreenshot === true || action.wantsScreenshot === 'true';
|
|
49
|
+
if (wantsScreenshot && options?.screenshotTracker) {
|
|
50
|
+
const timeoutMs = options.screenshotTimeoutMs ?? 60_000;
|
|
51
|
+
options.screenshotTracker.registerPending(context.conversationId, result.feedbackId, timeoutMs);
|
|
52
|
+
}
|
|
53
|
+
const flowResult = {
|
|
54
|
+
card: buildConfirmationCard(result.feedbackId, result.undoToken),
|
|
55
|
+
screenshotPending: wantsScreenshot,
|
|
56
|
+
feedbackId: result.feedbackId,
|
|
57
|
+
replacesPreviousCard: true,
|
|
58
|
+
};
|
|
59
|
+
if (wantsScreenshot) {
|
|
60
|
+
flowResult.message = 'Sende jetzt deinen Screenshot als Bild in diesen Chat.';
|
|
61
|
+
}
|
|
62
|
+
return flowResult;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return { message: 'Entschuldigung, beim Senden ist ein Fehler aufgetreten. Bitte versuche es später nochmal.' };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function handleUndoFeedback(action, client, context, options) {
|
|
69
|
+
if (!action.feedbackId || !action.undoToken) {
|
|
70
|
+
return { message: 'Undo konnte nicht durchgeführt werden. Bitte versuche es später nochmal.' };
|
|
71
|
+
}
|
|
72
|
+
let result;
|
|
73
|
+
try {
|
|
74
|
+
result = await client.undoFeedback(action.feedbackId, action.undoToken);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return { message: 'Undo konnte nicht durchgeführt werden. Bitte versuche es später nochmal.' };
|
|
78
|
+
}
|
|
79
|
+
if (result.success) {
|
|
80
|
+
options?.screenshotTracker?.clearPending(context.conversationId);
|
|
81
|
+
return { card: buildUndoneCard(), replacesPreviousCard: true };
|
|
82
|
+
}
|
|
83
|
+
if (result.expired) {
|
|
84
|
+
return {
|
|
85
|
+
card: {
|
|
86
|
+
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
87
|
+
type: 'AdaptiveCard',
|
|
88
|
+
version: '1.5',
|
|
89
|
+
body: [{ type: 'TextBlock', text: '⏱️ Das Undo-Fenster ist abgelaufen. Das Feedback bleibt gespeichert.', wrap: true }],
|
|
90
|
+
},
|
|
91
|
+
replacesPreviousCard: true,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
card: {
|
|
96
|
+
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
97
|
+
type: 'AdaptiveCard',
|
|
98
|
+
version: '1.5',
|
|
99
|
+
body: [{ type: 'TextBlock', text: 'Undo konnte nicht durchgeführt werden.', wrap: true }],
|
|
100
|
+
},
|
|
101
|
+
replacesPreviousCard: true,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface PendingScreenshot {
|
|
2
|
+
feedbackId: string;
|
|
3
|
+
expiresAt: number;
|
|
4
|
+
}
|
|
5
|
+
/** Pure state tracker for pending screenshot uploads. No SDK dependency. */
|
|
6
|
+
export declare class ScreenshotTracker {
|
|
7
|
+
private pending;
|
|
8
|
+
registerPending(conversationId: string, feedbackId: string, timeoutMs: number): void;
|
|
9
|
+
getPending(conversationId: string): PendingScreenshot | undefined;
|
|
10
|
+
clearPending(conversationId: string): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Pure state tracker for pending screenshot uploads. No SDK dependency. */
|
|
2
|
+
export class ScreenshotTracker {
|
|
3
|
+
pending = new Map();
|
|
4
|
+
registerPending(conversationId, feedbackId, timeoutMs) {
|
|
5
|
+
this.pending.set(conversationId, {
|
|
6
|
+
feedbackId,
|
|
7
|
+
expiresAt: Date.now() + timeoutMs,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
getPending(conversationId) {
|
|
11
|
+
const entry = this.pending.get(conversationId);
|
|
12
|
+
if (!entry)
|
|
13
|
+
return undefined;
|
|
14
|
+
if (Date.now() >= entry.expiresAt) {
|
|
15
|
+
this.pending.delete(conversationId);
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
return entry;
|
|
19
|
+
}
|
|
20
|
+
clearPending(conversationId) {
|
|
21
|
+
this.pending.delete(conversationId);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=screenshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/screenshot.ts"],"names":[],"mappings":"AAKA,4EAA4E;AAC5E,MAAM,OAAO,iBAAiB;IACpB,OAAO,GAAG,IAAI,GAAG,EAA6B,CAAC;IAEvD,eAAe,CAAC,cAAsB,EAAE,UAAkB,EAAE,SAAiB;QAC3E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE;YAC/B,UAAU;YACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;SAClC,CAAC,CAAC;IACL,CAAC;IAED,UAAU,CAAC,cAAsB;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YACpC,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY,CAAC,cAAsB;QACjC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACtC,CAAC;CACF"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** Minimal Adaptive Card schema shared by all card builder functions. */
|
|
2
|
+
export interface AdaptiveCard {
|
|
3
|
+
$schema: string;
|
|
4
|
+
type: 'AdaptiveCard';
|
|
5
|
+
version: string;
|
|
6
|
+
body: unknown[];
|
|
7
|
+
actions?: unknown[];
|
|
8
|
+
}
|
|
9
|
+
export interface FeedbackOptions {
|
|
10
|
+
apiEndpoint: string;
|
|
11
|
+
apiKey: string;
|
|
12
|
+
agentName?: string;
|
|
13
|
+
undoWindowSeconds?: number;
|
|
14
|
+
screenshotTimeoutSeconds?: number;
|
|
15
|
+
enableScreenshots?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export type FeedbackCategory = 'bug' | 'change' | 'idea' | 'other';
|
|
18
|
+
export type EntryPath = 'marker' | 'general';
|
|
19
|
+
export type ChannelType = 'personal' | 'channel' | 'groupChat';
|
|
20
|
+
export interface FeedbackAction {
|
|
21
|
+
feedbackAction: string;
|
|
22
|
+
category?: FeedbackCategory;
|
|
23
|
+
entryPath?: EntryPath;
|
|
24
|
+
description?: string;
|
|
25
|
+
wantsScreenshot?: boolean | string;
|
|
26
|
+
feedbackId?: string;
|
|
27
|
+
undoToken?: string;
|
|
28
|
+
feedbackFlowId?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface SubmitFeedbackPayload {
|
|
31
|
+
category: FeedbackCategory;
|
|
32
|
+
entryPath: EntryPath;
|
|
33
|
+
description?: string;
|
|
34
|
+
userId: string;
|
|
35
|
+
userName?: string;
|
|
36
|
+
userEmail?: string;
|
|
37
|
+
conversationId: string;
|
|
38
|
+
channelType: ChannelType;
|
|
39
|
+
conversationReference?: object;
|
|
40
|
+
markedMessageText?: string;
|
|
41
|
+
conversationContext?: object[];
|
|
42
|
+
topicName?: string;
|
|
43
|
+
correlation?: CorrelationContext;
|
|
44
|
+
}
|
|
45
|
+
export interface CorrelationContext {
|
|
46
|
+
markedActivityId?: string;
|
|
47
|
+
userActivityId?: string;
|
|
48
|
+
feedbackActivityId?: string;
|
|
49
|
+
appInsightsOpId?: string;
|
|
50
|
+
appInsightsResourceId?: string;
|
|
51
|
+
copilotSessionId?: string;
|
|
52
|
+
copilotTraceId?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface SubmitFeedbackResponse {
|
|
55
|
+
feedbackId: string;
|
|
56
|
+
undoToken: string;
|
|
57
|
+
undoExpiresAt: string;
|
|
58
|
+
message: string;
|
|
59
|
+
}
|
|
60
|
+
export interface UndoFeedbackResponse {
|
|
61
|
+
success: boolean;
|
|
62
|
+
expired: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface UploadScreenshotResponse {
|
|
65
|
+
screenshotId: string;
|
|
66
|
+
index: number;
|
|
67
|
+
remaining: number;
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Wraps bot response text in an AdaptiveCard with inline feedback buttons. */
|
|
2
|
+
export declare function wrapWithFeedbackButtons(text: string): object;
|
|
3
|
+
/** Wraps an AdaptiveCard JSON object in a bot attachment envelope. */
|
|
4
|
+
export declare function createCardAttachment(card: object): object;
|
package/dist/src/wrap.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { buildInlineButtons } from './cards/inlineButtons.js';
|
|
2
|
+
/** Wraps bot response text in an AdaptiveCard with inline feedback buttons. */
|
|
3
|
+
export function wrapWithFeedbackButtons(text) {
|
|
4
|
+
return buildInlineButtons(text);
|
|
5
|
+
}
|
|
6
|
+
/** Wraps an AdaptiveCard JSON object in a bot attachment envelope. */
|
|
7
|
+
export function createCardAttachment(card) {
|
|
8
|
+
return {
|
|
9
|
+
contentType: 'application/vnd.microsoft.card.adaptive',
|
|
10
|
+
content: card,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=wrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrap.js","sourceRoot":"","sources":["../../src/wrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,+EAA+E;AAC/E,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO;QACL,WAAW,EAAE,yCAAyC;QACtD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@journai/feedback-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SDK-agnostic feedback flow core for AI agent bots",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": ["dist"],
|
|
7
|
+
"main": "dist/src/index.js",
|
|
8
|
+
"types": "dist/src/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/src/index.js",
|
|
12
|
+
"types": "./dist/src/index.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"./cards": {
|
|
15
|
+
"import": "./dist/src/cards/index.js",
|
|
16
|
+
"types": "./dist/src/cards/index.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"clean": "rm -rf dist",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^22.0.0",
|
|
27
|
+
"typescript": "^5.7.0",
|
|
28
|
+
"vitest": "^3.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|