@getpinax/widget 0.0.0-stage → 1.0.0-beta.2

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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +513 -2
  3. package/dist/a11y/scan.d.ts +25 -0
  4. package/dist/api.d.ts +83 -0
  5. package/dist/capture/breadcrumbs.d.ts +49 -0
  6. package/dist/capture/console.d.ts +17 -0
  7. package/dist/capture/env.d.ts +25 -0
  8. package/dist/capture/network.d.ts +23 -0
  9. package/dist/capture/ring.d.ts +14 -0
  10. package/dist/capture/signature.d.ts +7 -0
  11. package/dist/capture/text.d.ts +23 -0
  12. package/dist/capture/ua.d.ts +13 -0
  13. package/dist/chunks/editor-0Kr31Uly.mjs +1368 -0
  14. package/dist/chunks/privacy-B_b1_Y1n.mjs +39 -0
  15. package/dist/chunks/recorder-tu4yugLw.mjs +2874 -0
  16. package/dist/chunks/scan-CFQwrtAQ.mjs +46137 -0
  17. package/dist/chunks/text-D9SaDBT0.mjs +36 -0
  18. package/dist/chunks/widget-BpTBdX2R.mjs +1272 -0
  19. package/dist/editor/annotator.d.ts +20 -0
  20. package/dist/editor/capture.d.ts +28 -0
  21. package/dist/editor/encode.d.ts +7 -0
  22. package/dist/editor/index.d.ts +5 -0
  23. package/dist/editor/mask.d.ts +29 -0
  24. package/dist/editor/pii.d.ts +22 -0
  25. package/dist/editor/shapes.d.ts +31 -0
  26. package/dist/editor-loader.d.ts +9 -0
  27. package/dist/editor-loader.embed.d.ts +6 -0
  28. package/dist/fixcheck.d.ts +42 -0
  29. package/dist/index.d.ts +85 -0
  30. package/dist/known.d.ts +27 -0
  31. package/dist/mount.d.ts +8 -0
  32. package/dist/navigation.d.ts +1 -0
  33. package/dist/paths.d.ts +4 -0
  34. package/dist/pinax-axe.js +46167 -0
  35. package/dist/pinax-editor.js +1417 -0
  36. package/dist/pinax-recorder.js +2915 -0
  37. package/dist/pinax.js +135 -0
  38. package/dist/pinax.mjs +1270 -0
  39. package/dist/preview.d.ts +48 -0
  40. package/dist/preview.mjs +67 -0
  41. package/dist/privacy.d.ts +24 -0
  42. package/dist/queue.d.ts +10 -0
  43. package/dist/replay/buffer.d.ts +40 -0
  44. package/dist/replay/recorder.d.ts +25 -0
  45. package/dist/replay/sanitize.d.ts +19 -0
  46. package/dist/report.d.ts +128 -0
  47. package/dist/segment.d.ts +31 -0
  48. package/dist/settings.d.ts +40 -0
  49. package/dist/types.d.ts +247 -0
  50. package/dist/ui/color.d.ts +7 -0
  51. package/dist/ui/dom.d.ts +14 -0
  52. package/dist/ui/styles.d.ts +3 -0
  53. package/dist/ui/widget.d.ts +241 -0
  54. package/package.json +74 -4
@@ -0,0 +1,49 @@
1
+ import type { RingBuffer } from './ring';
2
+ /**
3
+ * AI-11: what the visitor did just before sending. The backend's schema is
4
+ * `breadcrumbs` in `backend/src/modules/widget/widget.validator.ts`.
5
+ */
6
+ export type Breadcrumb = {
7
+ kind: 'click' | 'navigation' | 'input';
8
+ at: string;
9
+ path: string;
10
+ /** Short, privacy-safe description of the target, e.g. button "Book a table". */
11
+ target?: string;
12
+ };
13
+ export declare const MAX_BREADCRUMBS = 20;
14
+ export declare const MAX_NAME = 60;
15
+ /** A password or payment card field: not even its label is kept. */
16
+ export declare function isSecretField(el: Element): boolean;
17
+ export declare function roleOf(el: Element): string;
18
+ /**
19
+ * Visible text of `el`, skipping form fields, editable areas and anything
20
+ * the owner masked. Images contribute their alt text.
21
+ */
22
+ export declare function safeText(el: Element, max?: number): string;
23
+ /** The accessible name, as far as it can be read without visitor data. */
24
+ export declare function nameOf(el: Element): string;
25
+ /**
26
+ * A short, privacy-safe description of what was clicked or typed in:
27
+ * `button "Book a table"`, `link "Menu"`, `textbox "Email"`,
28
+ * `password field`. Names are cut to 60 characters. A click on anything
29
+ * that isn't a control (a paragraph, a table cell, an order summary) keeps
30
+ * only its role or tag: its text may be the visitor's own details.
31
+ */
32
+ export declare function describeTarget(start: Element): string;
33
+ /** The page as breadcrumbs record it: path and query keys (values hidden), no fragment. */
34
+ export declare function currentPath(href?: string): string;
35
+ type Options = {
36
+ /** Events from inside the widget itself are left out. */
37
+ ignore?: (target: EventTarget | null) => boolean;
38
+ doc?: Document;
39
+ };
40
+ /**
41
+ * Records clicks and typing (never what was typed) into `buffer`. Page views
42
+ * are added by the caller through `navigated()`, so they share the one
43
+ * history watcher. Never throws into the page.
44
+ */
45
+ export declare function captureBreadcrumbs(buffer: RingBuffer<Breadcrumb>, options?: Options): {
46
+ navigated: () => void;
47
+ stop: () => void;
48
+ };
49
+ export {};
@@ -0,0 +1,17 @@
1
+ import type { RingBuffer } from './ring';
2
+ export type ConsoleLevel = 'error' | 'warn' | 'log' | 'info' | 'debug';
3
+ export type ConsoleEntry = {
4
+ level: ConsoleLevel;
5
+ message: string;
6
+ stack?: string;
7
+ at: string;
8
+ };
9
+ export declare const MAX_MESSAGE = 2000;
10
+ export declare const MAX_STACK = 4000;
11
+ export declare function formatArgs(args: unknown[]): string;
12
+ /**
13
+ * C-04: wraps console methods and listens for uncaught errors and rejected
14
+ * promises. Never throws into the page; if the host replaces `console` later,
15
+ * capture just stops for the replaced methods.
16
+ */
17
+ export declare function captureConsole(buffer: RingBuffer<ConsoleEntry>, target?: Window & typeof globalThis): () => void;
@@ -0,0 +1,25 @@
1
+ import { type DeviceType } from './ua';
2
+ export type Environment = {
3
+ userAgent: string;
4
+ browser?: string;
5
+ browserVersion?: string;
6
+ os?: string;
7
+ deviceType: DeviceType;
8
+ deviceModel?: string;
9
+ screen: {
10
+ w: number;
11
+ h: number;
12
+ };
13
+ viewport: {
14
+ w: number;
15
+ h: number;
16
+ };
17
+ pixelRatio: number;
18
+ timeZone: string;
19
+ language?: string;
20
+ occurredAt: string;
21
+ };
22
+ /** Local time with its UTC offset, e.g. 2026-11-04T15:20:01.123+01:00 (C-01). */
23
+ export declare function localIsoTime(date?: Date): string;
24
+ /** C-01 to C-03, read at the moment the visitor sends. */
25
+ export declare function readEnvironment(win?: Window): Environment;
@@ -0,0 +1,23 @@
1
+ import type { RingBuffer } from './ring';
2
+ export type NetworkEntry = {
3
+ method: string;
4
+ url: string;
5
+ status: number;
6
+ durationMs: number;
7
+ at: string;
8
+ };
9
+ /** C-05: a request is kept when it fails or takes longer than this. */
10
+ export declare const SLOW_MS = 2000;
11
+ export declare function shouldRecord(status: number, durationMs: number): boolean;
12
+ type Options = {
13
+ /** Requests to these URL prefixes (Pinax's own API) are never recorded. */
14
+ ignore?: (url: string) => boolean;
15
+ now?: () => number;
16
+ };
17
+ /**
18
+ * C-05/C-06: wraps fetch and XMLHttpRequest and records only failed or slow
19
+ * requests: method, URL (query values hidden), status (0 = network error),
20
+ * duration and time. Headers and bodies are never read.
21
+ */
22
+ export declare function captureNetwork(buffer: RingBuffer<NetworkEntry>, target?: Window, options?: Options): () => void;
23
+ export {};
@@ -0,0 +1,14 @@
1
+ /** A fixed-size buffer that keeps only the newest `capacity` items (C-04, C-05). */
2
+ export declare class RingBuffer<T> {
3
+ readonly capacity: number;
4
+ private items;
5
+ private listeners;
6
+ constructor(capacity: number);
7
+ push(item: T): void;
8
+ /** Called with every new item (AI-17 fix check). Returns an unsubscribe. */
9
+ subscribe(listener: (item: T) => void): () => void;
10
+ /** Oldest first. Returns a copy. */
11
+ toArray(): T[];
12
+ clear(): void;
13
+ get size(): number;
14
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Emails and phone numbers are starred out first, as in the report's console
3
+ * text, so a signature never carries them (it's published in the site's
4
+ * config) and matches whether the text was starred out already or not.
5
+ */
6
+ export declare function normalise(text: string): string;
7
+ export declare function errorSignature(consoleLogs: unknown, networkLogs: unknown): string | null;
@@ -0,0 +1,23 @@
1
+ /** Cuts a string to `max` characters, marking the cut with an ellipsis. */
2
+ export declare function clip(value: string, max: number): string;
3
+ /**
4
+ * C-06: drops the fragment, credentials and secret-looking query values from a
5
+ * URL before it is kept. The backend masks again (defence in depth). For
6
+ * what is sent, `logUrl` and `pageUrl` (report.ts) also hide query values.
7
+ */
8
+ export declare function safeUrl(raw: string, base?: string): string;
9
+ /**
10
+ * Query parameters whose values a report's page address keeps: campaign and
11
+ * view state, never anything a visitor typed. Everything else becomes `…`.
12
+ * Mirrors `PAGE_PARAM` in `backend/src/modules/widget/widget.sanitise.ts`.
13
+ */
14
+ export declare const PAGE_PARAM: RegExp;
15
+ /**
16
+ * Personal data hides in query strings (`?email=`, `?name=`, search terms),
17
+ * so every value becomes `…` and only the keys stay, except those `keep`
18
+ * names. Works on the string, so `…` isn't percent-encoded, and keys,
19
+ * order and key-only parameters (`?debug`) are kept as they were.
20
+ */
21
+ export declare function maskQuery(url: string, keep?: RegExp): string;
22
+ /** Network log and breadcrumb URLs: `safeUrl`, then every query value hidden. */
23
+ export declare function logUrl(raw: string, base?: string): string;
@@ -0,0 +1,13 @@
1
+ export type DeviceType = 'desktop' | 'mobile' | 'tablet';
2
+ export type ParsedUA = {
3
+ browser?: string;
4
+ browserVersion?: string;
5
+ os?: string;
6
+ deviceType: DeviceType;
7
+ deviceModel?: string;
8
+ };
9
+ /**
10
+ * C-02: a small hand-written user-agent parser. `maxTouchPoints` tells iPads
11
+ * in desktop mode (which claim to be a Mac) apart from real Macs.
12
+ */
13
+ export declare function parseUserAgent(ua: string, maxTouchPoints?: number): ParsedUA;