@mahmulp/feedback-sdk 0.0.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/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/index.cjs +1714 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +252 -0
- package/dist/index.d.ts +252 -0
- package/dist/index.global.js +397 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +1701 -0
- package/dist/index.js.map +1 -0
- package/dist/mock.cjs +98 -0
- package/dist/mock.cjs.map +1 -0
- package/dist/mock.d.cts +111 -0
- package/dist/mock.d.ts +111 -0
- package/dist/mock.js +96 -0
- package/dist/mock.js.map +1 -0
- package/dist/svelte.d.ts +192 -0
- package/dist/svelte.js +1753 -0
- package/dist/svelte.js.map +1 -0
- package/package.json +89 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types shared between the SDK, the API, and the dashboard.
|
|
3
|
+
*
|
|
4
|
+
* NOTE: This file is the SDK's authoritative copy. The same shapes also live
|
|
5
|
+
* in `packages/shared-types/src/index.ts` for the API and dashboard. Keep
|
|
6
|
+
* them in sync when the wire format evolves.
|
|
7
|
+
*/
|
|
8
|
+
type FeedbackStatus = "open" | "resolved" | "archived";
|
|
9
|
+
/** Pin coordinates: percentage-based (for re-rendering) and pixel (fallback). */
|
|
10
|
+
interface FeedbackCoordinates {
|
|
11
|
+
/** 0..1, x position relative to the target element's bounding box. */
|
|
12
|
+
xPercent: number;
|
|
13
|
+
/** 0..1, y position relative to the target element's bounding box. */
|
|
14
|
+
yPercent: number;
|
|
15
|
+
/** Absolute x position in page pixels at capture time. */
|
|
16
|
+
xPx: number;
|
|
17
|
+
/** Absolute y position in page pixels at capture time. */
|
|
18
|
+
yPx: number;
|
|
19
|
+
}
|
|
20
|
+
interface ViewportInfo {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
devicePixelRatio: number;
|
|
24
|
+
}
|
|
25
|
+
interface FeedbackAuthor {
|
|
26
|
+
name: string;
|
|
27
|
+
email?: string;
|
|
28
|
+
}
|
|
29
|
+
interface FeedbackComment {
|
|
30
|
+
id: string;
|
|
31
|
+
author: FeedbackAuthor;
|
|
32
|
+
body: string;
|
|
33
|
+
createdAt: string;
|
|
34
|
+
}
|
|
35
|
+
/** A pin/feedback record as seen on the wire. */
|
|
36
|
+
interface Feedback {
|
|
37
|
+
id: string;
|
|
38
|
+
projectId: string;
|
|
39
|
+
pageUrl: string;
|
|
40
|
+
selector: string;
|
|
41
|
+
coordinates: FeedbackCoordinates;
|
|
42
|
+
viewport: ViewportInfo;
|
|
43
|
+
/** Storage key returned by the API after upload. Absent until a screenshot is uploaded. */
|
|
44
|
+
screenshotKey?: string;
|
|
45
|
+
status: FeedbackStatus;
|
|
46
|
+
thread: FeedbackComment[];
|
|
47
|
+
createdAt: string;
|
|
48
|
+
updatedAt: string;
|
|
49
|
+
}
|
|
50
|
+
/** Payload the SDK sends to create a new pin. The server fills in id/timestamps/status/thread. */
|
|
51
|
+
interface CreateFeedbackInput {
|
|
52
|
+
projectId: string;
|
|
53
|
+
pageUrl: string;
|
|
54
|
+
selector: string;
|
|
55
|
+
coordinates: FeedbackCoordinates;
|
|
56
|
+
viewport: ViewportInfo;
|
|
57
|
+
/** Optional first comment posted alongside the pin. */
|
|
58
|
+
comment?: {
|
|
59
|
+
author: FeedbackAuthor;
|
|
60
|
+
body: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
interface ListFeedbackQuery {
|
|
64
|
+
projectId: string;
|
|
65
|
+
pageUrl?: string;
|
|
66
|
+
status?: FeedbackStatus;
|
|
67
|
+
}
|
|
68
|
+
interface ListFeedbackResult {
|
|
69
|
+
items: Feedback[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Transport contract used by the SDK to talk to "something that persists feedback".
|
|
73
|
+
* Default HTTP implementation lives in `transport.ts`. The mock transport in `mock.ts`
|
|
74
|
+
* is useful for local demos and tests.
|
|
75
|
+
*/
|
|
76
|
+
interface FeedbackTransport {
|
|
77
|
+
list(query: ListFeedbackQuery): Promise<ListFeedbackResult>;
|
|
78
|
+
create(input: CreateFeedbackInput): Promise<Feedback>;
|
|
79
|
+
reply(feedbackId: string, comment: {
|
|
80
|
+
author: FeedbackAuthor;
|
|
81
|
+
body: string;
|
|
82
|
+
}): Promise<Feedback>;
|
|
83
|
+
setStatus(feedbackId: string, status: FeedbackStatus): Promise<Feedback>;
|
|
84
|
+
/** Move a pin: persist new percent + pixel coordinates after a drag. */
|
|
85
|
+
move?(feedbackId: string, coordinates: FeedbackCoordinates): Promise<Feedback>;
|
|
86
|
+
/** Upload a screenshot blob for an already-created feedback. Returns the updated record. */
|
|
87
|
+
uploadScreenshot?(feedbackId: string, blob: Blob): Promise<Feedback>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface InitFeedbackOptions {
|
|
91
|
+
/** Base URL of the API (used when no `transport` is provided). */
|
|
92
|
+
apiUrl?: string;
|
|
93
|
+
/** Per-project ingest key (sent as `x-feedback-key` to the API). Required when using the HTTP transport. */
|
|
94
|
+
apiKey?: string;
|
|
95
|
+
/** Custom transport override. Useful for tests, mocks, or non-HTTP backends. */
|
|
96
|
+
transport?: FeedbackTransport;
|
|
97
|
+
/**
|
|
98
|
+
* Identifier used for client-side caching (author identity per project).
|
|
99
|
+
* Defaults to `apiKey`'s prefix when omitted; safe to leave unset.
|
|
100
|
+
*/
|
|
101
|
+
cacheNamespace?: string;
|
|
102
|
+
/** Start with feedback mode enabled. Defaults to `false` (caller toggles via UI). */
|
|
103
|
+
enabled?: boolean;
|
|
104
|
+
/** Override how the page URL is captured. Defaults to `window.location.pathname + search`. */
|
|
105
|
+
getPageUrl?: () => string;
|
|
106
|
+
/**
|
|
107
|
+
* Modifier key used to "select parent" while picking a target.
|
|
108
|
+
* Defaults to "Alt".
|
|
109
|
+
*/
|
|
110
|
+
selectParentModifier?: "Alt" | "Shift" | "Meta" | "Control";
|
|
111
|
+
/** Override how the author identity is read. Defaults to a localStorage cache. */
|
|
112
|
+
getAuthor?: () => FeedbackAuthor | null;
|
|
113
|
+
/** Override how the author identity is persisted after a successful submit. */
|
|
114
|
+
setAuthor?: (author: FeedbackAuthor) => void;
|
|
115
|
+
/** Capture a screenshot when a new pin is created. Defaults to `true`. */
|
|
116
|
+
captureScreenshots?: boolean;
|
|
117
|
+
/** Override the screenshot capture function. Returns null to skip silently. */
|
|
118
|
+
captureScreenshot?: () => Promise<Blob | null>;
|
|
119
|
+
/** Render the floating launcher widget. Defaults to `true`. */
|
|
120
|
+
showLauncher?: boolean;
|
|
121
|
+
/** Initial pin visibility. Defaults to `true`. */
|
|
122
|
+
pinsVisible?: boolean;
|
|
123
|
+
/** Called when a pin is clicked in display mode. Use to render a thread popover. */
|
|
124
|
+
onPinClick?: (feedback: Feedback) => void;
|
|
125
|
+
/** Called after a new pin is created. */
|
|
126
|
+
onPinCreate?: (feedback: Feedback) => void;
|
|
127
|
+
/** Called when an error happens during a SDK action. */
|
|
128
|
+
onError?: (err: unknown) => void;
|
|
129
|
+
}
|
|
130
|
+
interface FeedbackController {
|
|
131
|
+
/** Toggle / set feedback creation mode. */
|
|
132
|
+
setEnabled(enabled: boolean): void;
|
|
133
|
+
/** Read the current enabled state. */
|
|
134
|
+
isEnabled(): boolean;
|
|
135
|
+
/** Show or hide all pins (the floating launcher's eye toggle calls this). */
|
|
136
|
+
setPinsVisible(visible: boolean): void;
|
|
137
|
+
/** Show or hide the floating launcher widget. */
|
|
138
|
+
setLauncherVisible(visible: boolean): void;
|
|
139
|
+
/** Trigger a fresh fetch of feedback for the current project. */
|
|
140
|
+
refresh(): Promise<void>;
|
|
141
|
+
/** Tear down: remove DOM, listeners, and observers. Idempotent. */
|
|
142
|
+
destroy(): void;
|
|
143
|
+
}
|
|
144
|
+
declare function initFeedback(options: InitFeedbackOptions): FeedbackController;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* DOM selector utilities. Deterministic and side-effect-free.
|
|
148
|
+
*
|
|
149
|
+
* Selector priority (see `.kiro/steering/feedback-data-model.md`):
|
|
150
|
+
* 1. data-feedback-id on the target or any ancestor
|
|
151
|
+
* 2. id="…" if it looks stable (no hashes, no auto-generated suffixes)
|
|
152
|
+
* 3. structural tag + nth-child chain, capped at MAX_DEPTH levels
|
|
153
|
+
* 4. tag.classname (single semantic class) as a last resort
|
|
154
|
+
*/
|
|
155
|
+
/**
|
|
156
|
+
* Build the most stable selector we can for the given element.
|
|
157
|
+
*/
|
|
158
|
+
declare function resolveSelector(target: Element): string;
|
|
159
|
+
/**
|
|
160
|
+
* Resolve a previously-stored selector back to an Element. Returns null if not found.
|
|
161
|
+
* Never throws on malformed selectors.
|
|
162
|
+
*/
|
|
163
|
+
declare function findElement(selector: string, root?: ParentNode): Element | null;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Compute pin coordinates for a click on a target element.
|
|
167
|
+
*
|
|
168
|
+
* - xPercent / yPercent are relative to the target's bounding box (clamped 0..1),
|
|
169
|
+
* used to re-render the pin after layout changes.
|
|
170
|
+
* - xPx / yPx are absolute page coordinates, used as the orphaned-pin fallback.
|
|
171
|
+
*/
|
|
172
|
+
declare function computeCoordinates(target: Element, clientX: number, clientY: number): FeedbackCoordinates;
|
|
173
|
+
declare function getViewportInfo(): ViewportInfo;
|
|
174
|
+
/**
|
|
175
|
+
* Project stored coordinates back onto a (possibly resolved) target element.
|
|
176
|
+
* If `target` is null (orphaned), fall back to absolute page pixels.
|
|
177
|
+
*
|
|
178
|
+
* Returns coordinates in the **page** coordinate space (account for scroll separately
|
|
179
|
+
* when positioning fixed-overlay elements).
|
|
180
|
+
*/
|
|
181
|
+
declare function projectCoordinates(target: Element | null, coords: FeedbackCoordinates): {
|
|
182
|
+
x: number;
|
|
183
|
+
y: number;
|
|
184
|
+
orphaned: boolean;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Default HTTP transport: talks to the API at `apiUrl` using a per-project
|
|
189
|
+
* API key (`apiKey`, sent as `x-feedback-key`).
|
|
190
|
+
*
|
|
191
|
+
* GET /v1/feedback?pageUrl=…&status=…
|
|
192
|
+
* POST /v1/feedback
|
|
193
|
+
* POST /v1/feedback/:id/comments
|
|
194
|
+
* PATCH /v1/feedback/:id { status } (admin-only; SDK rarely calls this)
|
|
195
|
+
* PATCH /v1/feedback/:id/coordinates { coordinates } (drag-to-move)
|
|
196
|
+
* POST /v1/feedback/:id/screenshot (multipart, field "file")
|
|
197
|
+
*
|
|
198
|
+
* The SDK never sends `projectId` — the server resolves the project from
|
|
199
|
+
* the API key.
|
|
200
|
+
*/
|
|
201
|
+
interface HttpTransportOptions {
|
|
202
|
+
apiUrl: string;
|
|
203
|
+
/** Per-project ingest key sent as `x-feedback-key`. Required. */
|
|
204
|
+
apiKey: string;
|
|
205
|
+
fetch?: typeof fetch;
|
|
206
|
+
headers?: Record<string, string>;
|
|
207
|
+
}
|
|
208
|
+
declare function createHttpTransport(options: HttpTransportOptions): FeedbackTransport;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Optional screenshot capture for new pins.
|
|
212
|
+
*
|
|
213
|
+
* `html2canvas` is **dynamically imported** so prototypes that never create
|
|
214
|
+
* a pin don't pay for it. Capture is best-effort: any failure logs and
|
|
215
|
+
* resolves to null rather than blocking pin creation.
|
|
216
|
+
*/
|
|
217
|
+
interface CaptureOptions {
|
|
218
|
+
/** Output mime type. Defaults to image/png. */
|
|
219
|
+
mimeType?: "image/png" | "image/jpeg" | "image/webp";
|
|
220
|
+
/** Quality (0..1) used for jpeg/webp. Ignored for png. */
|
|
221
|
+
quality?: number;
|
|
222
|
+
/** Viewport scale. Defaults to 1 to keep file sizes small. */
|
|
223
|
+
scale?: number;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Capture a screenshot of the current viewport.
|
|
227
|
+
*
|
|
228
|
+
* Hides the SDK's own overlay host before capture and restores it after,
|
|
229
|
+
* so the screenshot reflects the prototype, not the SDK chrome.
|
|
230
|
+
*/
|
|
231
|
+
declare function captureViewport(options?: CaptureOptions): Promise<Blob | null>;
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Public entry — framework-agnostic core.
|
|
235
|
+
*
|
|
236
|
+
* import { initFeedback } from '@mahmulp/feedback-sdk'
|
|
237
|
+
*
|
|
238
|
+
* Svelte users may prefer the adapter at `@mahmulp/feedback-sdk/svelte`.
|
|
239
|
+
* For local development without a backend, see `@mahmulp/feedback-sdk/mock`.
|
|
240
|
+
*/
|
|
241
|
+
|
|
242
|
+
/** @internal */
|
|
243
|
+
declare function _setGlobalController(c: FeedbackController | null): void;
|
|
244
|
+
declare function setFeedbackEnabled(enabled: boolean): void;
|
|
245
|
+
declare function destroyFeedback(): void;
|
|
246
|
+
/**
|
|
247
|
+
* Wrapper that captures the most recently created controller, so the
|
|
248
|
+
* `setFeedbackEnabled` / `destroyFeedback` shortcuts work for the common case.
|
|
249
|
+
*/
|
|
250
|
+
declare function initFeedbackGlobal(options: InitFeedbackOptions): FeedbackController;
|
|
251
|
+
|
|
252
|
+
export { type CaptureOptions, type CreateFeedbackInput, type Feedback, type FeedbackAuthor, type FeedbackComment, type FeedbackController, type FeedbackCoordinates, type FeedbackStatus, type FeedbackTransport, type HttpTransportOptions, type InitFeedbackOptions, type ListFeedbackQuery, type ListFeedbackResult, type ViewportInfo, _setGlobalController, captureViewport, computeCoordinates, createHttpTransport, destroyFeedback, findElement, getViewportInfo, initFeedback, initFeedbackGlobal, projectCoordinates, resolveSelector, setFeedbackEnabled };
|