anton-bakker-feedback 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/chunks/i18n-RpKqSWAT.js +309 -0
- package/dist/chunks/i18n-RpKqSWAT.js.map +1 -0
- package/dist/core/capture.d.ts +57 -0
- package/dist/core/capture.d.ts.map +1 -0
- package/dist/core/config.d.ts +107 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/errors.d.ts +80 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/i18n.d.ts +39 -0
- package/dist/core/i18n.d.ts.map +1 -0
- package/dist/core/index.d.ts +16 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/locales/en.d.ts +6 -0
- package/dist/core/locales/en.d.ts.map +1 -0
- package/dist/core/locales/nl.d.ts +6 -0
- package/dist/core/locales/nl.d.ts.map +1 -0
- package/dist/core/observability.d.ts +54 -0
- package/dist/core/observability.d.ts.map +1 -0
- package/dist/core/transforms.d.ts +57 -0
- package/dist/core/transforms.d.ts.map +1 -0
- package/dist/core/transport.d.ts +44 -0
- package/dist/core/transport.d.ts.map +1 -0
- package/dist/core/types.d.ts +130 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/validation.d.ts +48 -0
- package/dist/core/validation.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +455 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +2 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +2 -0
- package/dist/manifest.js.map +1 -0
- package/dist/react/FeedbackButton.d.ts +19 -0
- package/dist/react/FeedbackButton.d.ts.map +1 -0
- package/dist/react/FeedbackConfirm.d.ts +15 -0
- package/dist/react/FeedbackConfirm.d.ts.map +1 -0
- package/dist/react/FeedbackContext.d.ts +172 -0
- package/dist/react/FeedbackContext.d.ts.map +1 -0
- package/dist/react/FeedbackDialogue.d.ts +14 -0
- package/dist/react/FeedbackDialogue.d.ts.map +1 -0
- package/dist/react/FeedbackPanel.d.ts +10 -0
- package/dist/react/FeedbackPanel.d.ts.map +1 -0
- package/dist/react/FeedbackProvider.d.ts +28 -0
- package/dist/react/FeedbackProvider.d.ts.map +1 -0
- package/dist/react/FeedbackRecorder.d.ts +14 -0
- package/dist/react/FeedbackRecorder.d.ts.map +1 -0
- package/dist/react/index.d.ts +33 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/resolver/submitResolver.d.ts +60 -0
- package/dist/react/resolver/submitResolver.d.ts.map +1 -0
- package/dist/react/useFeedback.d.ts +27 -0
- package/dist/react/useFeedback.d.ts.map +1 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +1576 -0
- package/dist/react.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internationalisation utilities for the feedback package.
|
|
3
|
+
*
|
|
4
|
+
* t() falls back gracefully:
|
|
5
|
+
* - Unknown locale → English
|
|
6
|
+
* - Unknown key → returns the key itself (never undefined)
|
|
7
|
+
*
|
|
8
|
+
* Template interpolation: {{param}} → replaced with params values
|
|
9
|
+
*/
|
|
10
|
+
/** Supported locale codes */
|
|
11
|
+
export declare const SUPPORTED_LOCALES: readonly string[];
|
|
12
|
+
/** Default locale when unknown locale is requested */
|
|
13
|
+
export declare const DEFAULT_LOCALE = "en";
|
|
14
|
+
/**
|
|
15
|
+
* Looks up a translation key.
|
|
16
|
+
*
|
|
17
|
+
* Fallback chain:
|
|
18
|
+
* 1. customTranslations[locale][key]
|
|
19
|
+
* 2. BUILT_IN_TRANSLATIONS[locale][key]
|
|
20
|
+
* 3. BUILT_IN_TRANSLATIONS['en'][key]
|
|
21
|
+
* 4. key itself (never returns undefined or throws)
|
|
22
|
+
*
|
|
23
|
+
* Template interpolation: {{days}} → params.days (if params provided)
|
|
24
|
+
*
|
|
25
|
+
* @param key - Dot-notation key e.g. 'feedback.button.open'
|
|
26
|
+
* @param locale - BCP 47 locale code e.g. 'en', 'nl'
|
|
27
|
+
* @param customTranslations - Optional custom translations (overrides built-in)
|
|
28
|
+
* @param params - Optional template parameters e.g. { days: 7 }
|
|
29
|
+
*/
|
|
30
|
+
export declare function t(key: string, locale: string, customTranslations?: Record<string, Record<string, string>>, params?: Record<string, string | number>): string;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the locale to use.
|
|
33
|
+
* If preferredLocale is a supported locale → return it.
|
|
34
|
+
* Otherwise → return DEFAULT_LOCALE ('en').
|
|
35
|
+
*
|
|
36
|
+
* @param preferredLocale - BCP 47 locale code or undefined
|
|
37
|
+
*/
|
|
38
|
+
export declare function detectLocale(preferredLocale?: string): string;
|
|
39
|
+
//# sourceMappingURL=i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/core/i18n.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,6BAA6B;AAC7B,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAA0B,CAAC;AAE1E,sDAAsD;AACtD,eAAO,MAAM,cAAc,OAAO,CAAC;AAYnC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,CAAC,CACf,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACvC,MAAM,CAgCR;AAoBD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAK7D"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core barrel — re-exports everything from all core modules.
|
|
3
|
+
* This is the single import point for other slices.
|
|
4
|
+
*
|
|
5
|
+
* Usage: import { StoredFeedbackItem, processFeedbackCapture, t } from 'anton-bakker-feedback'
|
|
6
|
+
*/
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
export * from './config.js';
|
|
9
|
+
export * from './capture.js';
|
|
10
|
+
export * from './transport.js';
|
|
11
|
+
export * from './validation.js';
|
|
12
|
+
export * from './transforms.js';
|
|
13
|
+
export * from './observability.js';
|
|
14
|
+
export * from './i18n.js';
|
|
15
|
+
export * from './errors.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../src/core/locales/en.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiDrC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nl.d.ts","sourceRoot":"","sources":["../../../src/core/locales/nl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiDrC,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenTelemetry span helpers with zero AWS dependencies.
|
|
3
|
+
*
|
|
4
|
+
* @opentelemetry/api is declared as an optional peer dependency.
|
|
5
|
+
* If the consuming app has it installed, traces are emitted.
|
|
6
|
+
* If not, functions degrade gracefully to no-ops.
|
|
7
|
+
*
|
|
8
|
+
* CRITICAL: No hard import of '@opentelemetry/api' — only dynamic import.
|
|
9
|
+
* Dynamic import used for runtime availability check.
|
|
10
|
+
*/
|
|
11
|
+
interface OtelSpan {
|
|
12
|
+
setStatus(status: {
|
|
13
|
+
code: number;
|
|
14
|
+
message?: string;
|
|
15
|
+
}): void;
|
|
16
|
+
recordException(exception: Error): void;
|
|
17
|
+
end(): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Initialise the OTel tracer singleton.
|
|
21
|
+
* Idempotent — calling twice with the same appName is a no-op.
|
|
22
|
+
* Safe to call when @opentelemetry/api is not installed (no-op).
|
|
23
|
+
*/
|
|
24
|
+
export declare function initTracer(appName: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Wraps an async operation in an OTel span.
|
|
27
|
+
* If OTel is unavailable or initTracer not called → runs operation without span.
|
|
28
|
+
* The span argument passed to the operation callback is null when OTel is unavailable.
|
|
29
|
+
*
|
|
30
|
+
* Span name convention: feedback.{operation} (e.g., feedback.submit, feedback.dialogue)
|
|
31
|
+
* Required attributes: app (appName), environment, feedbackId (when available)
|
|
32
|
+
*/
|
|
33
|
+
export declare function withSpan<T>(operationName: string, attributes: Record<string, string | number | boolean>, operation: (span: OtelSpan | null) => Promise<T>): Promise<T>;
|
|
34
|
+
/**
|
|
35
|
+
* Records a feedback submission span event.
|
|
36
|
+
* No-op when OTel unavailable.
|
|
37
|
+
*/
|
|
38
|
+
export declare function recordSubmitEvent(feedbackId: string, appName: string, environment?: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Records a dialogue exchange span event.
|
|
41
|
+
* No-op when OTel unavailable.
|
|
42
|
+
*/
|
|
43
|
+
export declare function recordDialogueExchange(feedbackId: string, turnNumber: number, appName: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Emits a metric to CloudWatch (fire-and-forget).
|
|
46
|
+
*
|
|
47
|
+
* Only active when process.env.AWS_REGION is set AND
|
|
48
|
+
* @aws-sdk/client-cloudwatch is importable at runtime (dynamic import).
|
|
49
|
+
* If either condition is absent, logs to console.debug instead.
|
|
50
|
+
* NEVER throws.
|
|
51
|
+
*/
|
|
52
|
+
export declare function emitMetric(metricName: string, value: number, unit: 'Count' | 'Milliseconds' | 'Bytes', dimensions: Record<string, string>): void;
|
|
53
|
+
export {};
|
|
54
|
+
//# sourceMappingURL=observability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../src/core/observability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,UAAU,QAAQ;IAChB,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,eAAe,CAAC,SAAS,EAAE,KAAK,GAAG,IAAI,CAAC;IACxC,GAAG,IAAI,IAAI,CAAC;CACb;AAaD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAoBhD;AASD;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EACrD,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAC/C,OAAO,CAAC,CAAC,CAAC,CAqBZ;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAUN;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,IAAI,CAUN;AAMD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,OAAO,GAAG,cAAc,GAAG,OAAO,EACxC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,IAAI,CAmCN"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { FeedbackType, FeedbackStatus, StoredFeedbackItem, CorrectionEntry } from './types.js';
|
|
2
|
+
|
|
3
|
+
/** The six DynamoDB keys for a feedback item */
|
|
4
|
+
export interface FeedbackKeys {
|
|
5
|
+
PK: string;
|
|
6
|
+
SK: string;
|
|
7
|
+
GSI1PK: string;
|
|
8
|
+
GSI1SK: string;
|
|
9
|
+
GSI2PK: string;
|
|
10
|
+
GSI2SK: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Builds the six DynamoDB keys for a feedback item.
|
|
14
|
+
*
|
|
15
|
+
* @param appName - Application name (e.g. 'sagrosoft20')
|
|
16
|
+
* @param id - Feedback ID (e.g. 'FB-2026-07-25-abc12345')
|
|
17
|
+
* @param type - Feedback type
|
|
18
|
+
* @param status - Current status
|
|
19
|
+
* @param priority - Priority score 0–100
|
|
20
|
+
* @param timestamp - ISO 8601 timestamp
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildKeys(appName: string, id: string, type: FeedbackType, status: FeedbackStatus, priority: number, timestamp: string): FeedbackKeys;
|
|
23
|
+
/**
|
|
24
|
+
* Extracts timestamp and id from a composite SK.
|
|
25
|
+
* SK format: FB#{timestamp}#{id}
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseSK(sk: string): {
|
|
28
|
+
timestamp: string;
|
|
29
|
+
id: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Parses the GSI2PK into its component parts.
|
|
33
|
+
* GSI2PK format: TYPE#{type}#PROJECT#{appName}
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseGSI2PK(gsi2pk: string): {
|
|
36
|
+
type: FeedbackType;
|
|
37
|
+
appName: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Adds a reporter to an item.
|
|
41
|
+
* Returns new reporters array and updated reporterCount — does NOT mutate original.
|
|
42
|
+
*/
|
|
43
|
+
export declare function addReporter(item: StoredFeedbackItem, userId: string, addedContext?: string, nowIso?: string): Pick<StoredFeedbackItem, 'reporters' | 'reporterCount' | 'GSI1SK'>;
|
|
44
|
+
/**
|
|
45
|
+
* Appends a correction record to the corrections array.
|
|
46
|
+
* Returns a new array — does NOT mutate the original.
|
|
47
|
+
*/
|
|
48
|
+
export declare function appendCorrection(corrections: CorrectionEntry[], correction: Omit<CorrectionEntry, 'correctedAt'>, nowIso?: string): CorrectionEntry[];
|
|
49
|
+
/**
|
|
50
|
+
* Applies a status transition to an item.
|
|
51
|
+
* Returns updated key fields + lastModifiedAt (does NOT mutate original).
|
|
52
|
+
*
|
|
53
|
+
* When transitioning to 'resolved': sets resolvedAt = nowIso.
|
|
54
|
+
* When transitioning to any other status: resolvedAt is undefined.
|
|
55
|
+
*/
|
|
56
|
+
export declare function applyStatusTransition(item: StoredFeedbackItem, newStatus: FeedbackStatus, nowIso?: string): Pick<StoredFeedbackItem, 'status' | 'GSI1PK' | 'GSI1SK' | 'lastModifiedAt' | 'resolvedAt' | 'resolvedBy'>;
|
|
57
|
+
//# sourceMappingURL=transforms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transforms.d.ts","sourceRoot":"","sources":["../../src/core/transforms.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,eAAe,EAEhB,MAAM,YAAY,CAAC;AAMpB,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,YAAY,CAad;AAMD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAYrE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAYnF;AAMD;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CAAC,kBAAkB,EAAE,WAAW,GAAG,eAAe,GAAG,QAAQ,CAAC,CAmBpE;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,eAAe,EAAE,EAC9B,UAAU,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,EAChD,MAAM,CAAC,EAAE,MAAM,GACd,eAAe,EAAE,CAMnB;AAMD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,kBAAkB,EACxB,SAAS,EAAE,cAAc,EACzB,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CACL,kBAAkB,EAClB,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,gBAAgB,GAAG,YAAY,GAAG,YAAY,CAChF,CAmBA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { StoredFeedbackItem, SubmitResult, DialogueResponse, UploadResult, DialogueEntry } from './types.js';
|
|
2
|
+
|
|
3
|
+
/** What the React adapter calls at submit time */
|
|
4
|
+
export interface FeedbackSubmitTransport {
|
|
5
|
+
submit(item: StoredFeedbackItem): Promise<SubmitResult>;
|
|
6
|
+
}
|
|
7
|
+
/** What the dialogue UI calls on each exchange */
|
|
8
|
+
export interface FeedbackDialogueTransport {
|
|
9
|
+
exchange(feedbackId: string, message: string, history: DialogueEntry[]): Promise<DialogueResponse>;
|
|
10
|
+
}
|
|
11
|
+
/** What the screenshot capture calls after html2canvas */
|
|
12
|
+
export interface FeedbackScreenshotTransport {
|
|
13
|
+
upload(feedbackId: string, blob: Blob): Promise<UploadResult>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Composite transport — all three combined for full-feature transport.
|
|
17
|
+
* Dialogue and screenshot are optional so implementations can omit them.
|
|
18
|
+
*/
|
|
19
|
+
export interface FeedbackTransport extends FeedbackSubmitTransport, Partial<FeedbackDialogueTransport>, Partial<FeedbackScreenshotTransport> {
|
|
20
|
+
}
|
|
21
|
+
/** Memory transport with access to internal state for assertions */
|
|
22
|
+
export interface MemoryTransport extends FeedbackTransport {
|
|
23
|
+
/** All submitted items */
|
|
24
|
+
submissions: StoredFeedbackItem[];
|
|
25
|
+
/** Queue of dialogue responses to return in order */
|
|
26
|
+
dialogueResponses: DialogueResponse[];
|
|
27
|
+
/** Uploaded screenshot blobs */
|
|
28
|
+
uploadedScreenshots: Array<{
|
|
29
|
+
feedbackId: string;
|
|
30
|
+
blob: Blob;
|
|
31
|
+
}>;
|
|
32
|
+
/** Clear all stored state */
|
|
33
|
+
clear(): void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Creates an in-memory transport for testing.
|
|
37
|
+
*
|
|
38
|
+
* - submit(): stores the item and returns { success: true, feedbackId: item.id }
|
|
39
|
+
* - exchange(): returns the first queued response, or a default stub
|
|
40
|
+
* - upload(): records the blob reference
|
|
41
|
+
* - Does NOT import any AWS SDK
|
|
42
|
+
*/
|
|
43
|
+
export declare function createMemoryTransport(): MemoryTransport;
|
|
44
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/core/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACd,MAAM,YAAY,CAAC;AAMpB,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACzD;AAED,kDAAkD;AAClD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CACN,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,EAAE,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC9B;AAED,0DAA0D;AAC1D,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC/D;AAED;;;GAGG;AACH,MAAM,WAAW,iBACf,SAAQ,uBAAuB,EAC7B,OAAO,CAAC,yBAAyB,CAAC,EAClC,OAAO,CAAC,2BAA2B,CAAC;CAAG;AAM3C,oEAAoE;AACpE,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,0BAA0B;IAC1B,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAClC,qDAAqD;IACrD,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,gCAAgC;IAChC,mBAAmB,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IAC/D,6BAA6B;IAC7B,KAAK,IAAI,IAAI,CAAC;CACf;AAQD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CA2CvD"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for the anton-bakker-feedback package.
|
|
3
|
+
*
|
|
4
|
+
* ZERO IMPORTS — this file is the single source of truth for all data types.
|
|
5
|
+
* Every other module imports from this file; this file imports nothing.
|
|
6
|
+
*/
|
|
7
|
+
/** Type of feedback being submitted */
|
|
8
|
+
export type FeedbackType = 'bug' | 'feature' | 'ux' | 'other';
|
|
9
|
+
/**
|
|
10
|
+
* Lifecycle status of a feedback item.
|
|
11
|
+
* Exactly: 'open' | 'approved' | 'deferred' | 'resolved' | 'wontfix'
|
|
12
|
+
*/
|
|
13
|
+
export type FeedbackStatus = 'open' | 'approved' | 'deferred' | 'resolved' | 'wontfix';
|
|
14
|
+
/** Scope of the feedback issue */
|
|
15
|
+
export type FeedbackScope = 'isolated' | 'cross-cutting' | 'systemic';
|
|
16
|
+
/** Estimated size/effort for the feedback item */
|
|
17
|
+
export type FeedbackSize = 'trivial' | 'small' | 'medium' | 'large';
|
|
18
|
+
/** Environment where feedback was submitted */
|
|
19
|
+
export type FeedbackEnvironment = 'development' | 'staging' | 'production';
|
|
20
|
+
/** A reporter who submitted or upvoted a feedback item */
|
|
21
|
+
export interface Reporter {
|
|
22
|
+
userId: string;
|
|
23
|
+
addedAt: string;
|
|
24
|
+
addedContext?: string;
|
|
25
|
+
}
|
|
26
|
+
/** A single dialogue turn between user and assistant */
|
|
27
|
+
export interface DialogueEntry {
|
|
28
|
+
role: 'user' | 'assistant';
|
|
29
|
+
content: string;
|
|
30
|
+
timestamp: string;
|
|
31
|
+
}
|
|
32
|
+
/** A correction record tracking field changes */
|
|
33
|
+
export interface CorrectionEntry {
|
|
34
|
+
field: string;
|
|
35
|
+
before: unknown;
|
|
36
|
+
after: unknown;
|
|
37
|
+
correctedBy: string;
|
|
38
|
+
correctedAt: string;
|
|
39
|
+
reason?: string;
|
|
40
|
+
}
|
|
41
|
+
/** Browser and server context captured at submission time */
|
|
42
|
+
export interface FeedbackContext {
|
|
43
|
+
url: string;
|
|
44
|
+
pageTitle?: string;
|
|
45
|
+
userAgent?: string;
|
|
46
|
+
viewport?: {
|
|
47
|
+
width: number;
|
|
48
|
+
height: number;
|
|
49
|
+
};
|
|
50
|
+
locale?: string;
|
|
51
|
+
timezone?: string;
|
|
52
|
+
performanceMs?: number;
|
|
53
|
+
consoleErrors?: string[];
|
|
54
|
+
customFields?: Record<string, string | number | boolean>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The canonical DynamoDB row for a feedback item.
|
|
58
|
+
*
|
|
59
|
+
* Key patterns (must match 01-shared-infrastructure exactly):
|
|
60
|
+
* PK: PROJECT#{appName}
|
|
61
|
+
* SK: FB#{isoTimestamp}#{id}
|
|
62
|
+
* GSI1PK: STATUS#{status}
|
|
63
|
+
* GSI1SK: {inverted-priority-padded}#{id}
|
|
64
|
+
* GSI2PK: TYPE#{type}#PROJECT#{appName}
|
|
65
|
+
* GSI2SK: {isoTimestamp}
|
|
66
|
+
*/
|
|
67
|
+
export interface StoredFeedbackItem {
|
|
68
|
+
PK: string;
|
|
69
|
+
SK: string;
|
|
70
|
+
GSI1PK: string;
|
|
71
|
+
GSI1SK: string;
|
|
72
|
+
GSI2PK: string;
|
|
73
|
+
GSI2SK: string;
|
|
74
|
+
id: string;
|
|
75
|
+
appName: string;
|
|
76
|
+
type: FeedbackType;
|
|
77
|
+
status: FeedbackStatus;
|
|
78
|
+
scope?: FeedbackScope;
|
|
79
|
+
size?: FeedbackSize;
|
|
80
|
+
priority: number;
|
|
81
|
+
content: string;
|
|
82
|
+
context: FeedbackContext;
|
|
83
|
+
classification?: string;
|
|
84
|
+
hasScreenshot: boolean;
|
|
85
|
+
screenshotS3Key?: string;
|
|
86
|
+
submittedAt: string;
|
|
87
|
+
lastModifiedAt: string;
|
|
88
|
+
resolvedAt?: string;
|
|
89
|
+
resolvedBy?: string;
|
|
90
|
+
submittedBy: string;
|
|
91
|
+
assignedTo?: string;
|
|
92
|
+
reporters: Reporter[];
|
|
93
|
+
reporterCount: number;
|
|
94
|
+
dialogueHistory: DialogueEntry[];
|
|
95
|
+
corrections: CorrectionEntry[];
|
|
96
|
+
environment?: FeedbackEnvironment;
|
|
97
|
+
version?: string;
|
|
98
|
+
tags: string[];
|
|
99
|
+
traceId?: string;
|
|
100
|
+
linkedCommit?: string;
|
|
101
|
+
}
|
|
102
|
+
/** Result of a feedback submission */
|
|
103
|
+
export interface SubmitResult {
|
|
104
|
+
success: boolean;
|
|
105
|
+
feedbackId: string;
|
|
106
|
+
error?: string;
|
|
107
|
+
retryable?: boolean;
|
|
108
|
+
}
|
|
109
|
+
/** Response from a dialogue exchange */
|
|
110
|
+
export interface DialogueResponse {
|
|
111
|
+
success: boolean;
|
|
112
|
+
response?: string;
|
|
113
|
+
conversationComplete?: boolean;
|
|
114
|
+
classificationSuggested?: Partial<Pick<StoredFeedbackItem, 'type' | 'scope' | 'size'>>;
|
|
115
|
+
error?: string;
|
|
116
|
+
}
|
|
117
|
+
/** Result of a screenshot upload */
|
|
118
|
+
export interface UploadResult {
|
|
119
|
+
success: boolean;
|
|
120
|
+
s3Key?: string;
|
|
121
|
+
error?: string;
|
|
122
|
+
}
|
|
123
|
+
/** OpenTelemetry tracing context */
|
|
124
|
+
export interface TracingContext {
|
|
125
|
+
traceId: string;
|
|
126
|
+
spanId: string;
|
|
127
|
+
spanName: string;
|
|
128
|
+
startTimeMs: number;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,uCAAuC;AACvC,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC;AAE9D;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvF,kCAAkC;AAClC,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,eAAe,GAAG,UAAU,CAAC;AAEtE,kDAAkD;AAClD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEpE,+CAA+C;AAC/C,MAAM,MAAM,mBAAmB,GAAG,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;AAM3E,0DAA0D;AAC1D,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAMD,6DAA6D;AAC7D,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC1D;AAMD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IAEjC,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IAGf,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAGhB,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,IAAI,CAAC,EAAE,YAAY,CAAC;IAGpB,QAAQ,EAAE,MAAM,CAAC;IAGjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IAGtB,eAAe,EAAE,aAAa,EAAE,CAAC;IACjC,WAAW,EAAE,eAAe,EAAE,CAAC;IAG/B,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD,sCAAsC;AACtC,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC;IACvF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,oCAAoC;AACpC,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,oCAAoC;AACpC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { FeedbackContext } from './types.js';
|
|
2
|
+
import { CaptureInput } from './capture.js';
|
|
3
|
+
|
|
4
|
+
/** Immutable validation constants */
|
|
5
|
+
export declare const VALIDATION_RULES: {
|
|
6
|
+
readonly CONTENT_MIN_LENGTH: 10;
|
|
7
|
+
readonly CONTENT_MAX_LENGTH: 5000;
|
|
8
|
+
readonly TAG_MAX_COUNT: 10;
|
|
9
|
+
readonly TAG_PATTERN: RegExp;
|
|
10
|
+
readonly APP_NAME_PATTERN: RegExp;
|
|
11
|
+
readonly SCREENSHOT_MAX_BYTES: 5242880;
|
|
12
|
+
readonly CONSOLE_ERRORS_MAX: 20;
|
|
13
|
+
};
|
|
14
|
+
/** Validation result with user-facing messages */
|
|
15
|
+
export interface ValidationResult {
|
|
16
|
+
valid: boolean;
|
|
17
|
+
errors: string[];
|
|
18
|
+
warnings: string[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Validates feedback content.
|
|
22
|
+
* Fails below CONTENT_MIN_LENGTH ("Feedback must be at least 10 characters"),
|
|
23
|
+
* fails above CONTENT_MAX_LENGTH, warns if only whitespace.
|
|
24
|
+
*/
|
|
25
|
+
export declare function validateContent(content: string): ValidationResult;
|
|
26
|
+
/**
|
|
27
|
+
* Validates feedback tags.
|
|
28
|
+
* Fails if count exceeds TAG_MAX_COUNT or if any tag doesn't match TAG_PATTERN.
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateTags(tags: string[]): ValidationResult;
|
|
31
|
+
/**
|
|
32
|
+
* Validates an app name.
|
|
33
|
+
*/
|
|
34
|
+
export declare function validateAppName(appName: string): ValidationResult;
|
|
35
|
+
/**
|
|
36
|
+
* Validates screenshot size.
|
|
37
|
+
*/
|
|
38
|
+
export declare function validateScreenshotSize(sizeBytes: number): ValidationResult;
|
|
39
|
+
/**
|
|
40
|
+
* Validates browser context.
|
|
41
|
+
* Warns if url is empty; warns if consoleErrors exceeds 20 items.
|
|
42
|
+
*/
|
|
43
|
+
export declare function validateContext(context: FeedbackContext): ValidationResult;
|
|
44
|
+
/**
|
|
45
|
+
* Aggregate validator — runs all validators for a capture input.
|
|
46
|
+
*/
|
|
47
|
+
export declare function validateCaptureInput(input: Partial<CaptureInput>): ValidationResult;
|
|
48
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAMjD,qCAAqC;AACrC,eAAO,MAAM,gBAAgB;;;;;;;;CAQnB,CAAC;AAMX,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAUD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAiBjE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAmB7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAajE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAW1E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,gBAAgB,CAkB1E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,gBAAgB,CAiCnF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,iBAAiB,CAAC"}
|