@tra-bilisim/report-issue 0.1.0 → 0.1.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 CHANGED
@@ -40,6 +40,7 @@ const adapter: ReportIssueAdapter = {
40
40
  getMetadata: () => ({ userId: currentUser.id, roles: currentUser.roles }),
41
41
  getCurrentUrl: () => window.location.href,
42
42
  pageOptions: [{ value: 'https://app/x', label: '/x' }],
43
+ pageInputMode: 'select', // 'select' (default, uses pageOptions) | 'input' (free-text URL)
43
44
  environmentResolver: url => (url.includes('localhost') ? 'Locale' : 'Prod'),
44
45
  t: key => i18n.translate(key), // English keys are the default fallback text
45
46
  locale: 'tr',
@@ -58,15 +59,82 @@ function App() {
58
59
 
59
60
  ## Network log capture (optional)
60
61
 
61
- Feed your axios instance into the shared log store with one call:
62
+ `attachAxiosNetworkLogging(instance, options?)` installs request/response
63
+ interceptors on your axios instance that feed the shared report-issue log store.
64
+ The captured requests are attached to a report as `networkLogs` automatically.
65
+
66
+ Call it **once**, at module scope where you create your axios instance — not inside
67
+ a React component (that would re-attach on every render):
62
68
 
63
69
  ```ts
70
+ // src/api/http.ts
71
+ import axios from 'axios';
64
72
  import { attachAxiosNetworkLogging } from '@tra-bilisim/report-issue/adapters/axios';
65
- attachAxiosNetworkLogging(myAxiosInstance);
73
+
74
+ export const http = axios.create({ baseURL: '/api' });
75
+
76
+ // One call — done. Every request through `http` is now logged.
77
+ attachAxiosNetworkLogging(http);
78
+ ```
79
+
80
+ `attachAxiosNetworkLogging` returns a **detach** function that removes the
81
+ interceptors (useful in tests or HMR):
82
+
83
+ ```ts
84
+ const detach = attachAxiosNetworkLogging(http);
85
+ // ...later
86
+ detach();
87
+ ```
88
+
89
+ ### Options
90
+
91
+ Both options are optional — the defaults cover common API shapes.
92
+
93
+ ```ts
94
+ attachAxiosNetworkLogging(http, {
95
+ // Pull a human-readable message out of the response body for the log entry.
96
+ // Default looks for { message | Message | errorMessage | ErrorMessage }.
97
+ getMessage: data => (data as any)?.error?.detail,
98
+
99
+ // Decide whether a response counts as an error in the log.
100
+ // Default: any status < 200 or >= 300.
101
+ isErrorResponse: (status, data) =>
102
+ status >= 400 || (data as any)?.success === false,
103
+ });
66
104
  ```
67
105
 
68
- Or wire your own transport by calling the primitives from `@tra-bilisim/report-issue/core`:
69
- `beginNetworkRequest`, `completeNetworkRequest`, `failNetworkRequest`.
106
+ ### Request correlation header
107
+
108
+ Each logged request is tagged with an `X-Request-Tracking-Id` header. If your
109
+ backend already sets/echoes this header, the adapter **reuses** it; otherwise it
110
+ generates one (`rpi_<time>_<rand>`). This lets you cross-reference a captured
111
+ request with your server logs.
112
+
113
+ ### Custom transport (no axios)
114
+
115
+ Using `fetch` or another client? Skip the adapter and call the core primitives
116
+ directly from `@tra-bilisim/report-issue/core`:
117
+
118
+ ```ts
119
+ import {
120
+ beginNetworkRequest,
121
+ completeNetworkRequest,
122
+ failNetworkRequest,
123
+ } from '@tra-bilisim/report-issue/core';
124
+
125
+ async function loggedFetch(url: string, init?: RequestInit) {
126
+ const id = crypto.randomUUID();
127
+ beginNetworkRequest(id, init?.method ?? 'GET', url);
128
+ try {
129
+ const res = await fetch(url, init);
130
+ completeNetworkRequest(id, res.status, !res.ok);
131
+ return res;
132
+ } catch (err) {
133
+ failNetworkRequest(id, undefined, (err as Error).message);
134
+ throw err;
135
+ }
136
+ }
137
+ ```
70
138
 
71
139
  ## Wire contract (`submit`)
72
140
 
@@ -80,6 +80,12 @@ interface ReportIssueAdapter {
80
80
  getCurrentUrl?: () => string;
81
81
  /** Options for the "which page" dropdown. Function form is re-read on open. */
82
82
  pageOptions?: PageOption[] | (() => PageOption[]);
83
+ /**
84
+ * How the "which page" field is rendered when "current page" is unchecked:
85
+ * - `'select'` (default): searchable dropdown fed by `pageOptions`.
86
+ * - `'input'`: free-text field for an arbitrary URL/path (`pageOptions` ignored).
87
+ */
88
+ pageInputMode?: 'select' | 'input';
83
89
  /** Maps a page URL to an environment label (e.g. Locale/Test/Prod). */
84
90
  environmentResolver?: (url: string) => string;
85
91
  /** i18n. Defaults to identity (returns the key, which is English text). */
package/dist/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as CONSENT_VERSION, a as CaptureType, b as ConsoleEntry, N as NetworkEntry, P as PageOption, R as RecorderStartResult, c as RecordingConsent, d as ReportCategoryOption, e as ReportIssueAdapter, f as ReportIssueToast, g as ReportMetadata, h as ReportSubmitPayload, i as ReportSubmitResult, V as VideoRecorderCallbacks, j as VideoRecorderController, k as beginNetworkRequest, l as completeNetworkRequest, m as createConsent, n as createVideoRecorder, o as failNetworkRequest, p as getConsoleLogs, q as getNetworkLogs, r as patchConsole, s as pushConsoleLog } from './consent-DmS4DxOf.js';
1
+ export { C as CONSENT_VERSION, a as CaptureType, b as ConsoleEntry, N as NetworkEntry, P as PageOption, R as RecorderStartResult, c as RecordingConsent, d as ReportCategoryOption, e as ReportIssueAdapter, f as ReportIssueToast, g as ReportMetadata, h as ReportSubmitPayload, i as ReportSubmitResult, V as VideoRecorderCallbacks, j as VideoRecorderController, k as beginNetworkRequest, l as completeNetworkRequest, m as createConsent, n as createVideoRecorder, o as failNetworkRequest, p as getConsoleLogs, q as getNetworkLogs, r as patchConsole, s as pushConsoleLog } from './consent-CfFPLwnF.js';
2
2
 
3
3
  declare function applyInputMask(targetDoc?: Document): void;
4
4
  declare function applyMask(): void;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { e as ReportIssueAdapter, f as ReportIssueToast, a as CaptureType, c as RecordingConsent, b as ConsoleEntry, N as NetworkEntry, R as RecorderStartResult } from './consent-DmS4DxOf.js';
4
- export { C as CONSENT_VERSION, P as PageOption, d as ReportCategoryOption, g as ReportMetadata, h as ReportSubmitPayload, i as ReportSubmitResult, p as getConsoleLogs, q as getNetworkLogs, r as patchConsole } from './consent-DmS4DxOf.js';
3
+ import { e as ReportIssueAdapter, f as ReportIssueToast, a as CaptureType, c as RecordingConsent, b as ConsoleEntry, N as NetworkEntry, R as RecorderStartResult } from './consent-CfFPLwnF.js';
4
+ export { C as CONSENT_VERSION, P as PageOption, d as ReportCategoryOption, g as ReportMetadata, h as ReportSubmitPayload, i as ReportSubmitResult, p as getConsoleLogs, q as getNetworkLogs, r as patchConsole } from './consent-CfFPLwnF.js';
5
5
 
6
6
  /** Adapter with every optional field filled in — what components actually read. */
7
7
  interface ResolvedConfig {
package/dist/index.js CHANGED
@@ -567,7 +567,15 @@ var ReportIssueDialog = ({ open, onOpenChange }) => {
567
567
  label: `${t("Current page")}: ${currentUrl}`
568
568
  }
569
569
  ),
570
- pageOptions.length > 0 && /* @__PURE__ */ jsx(
570
+ adapter.pageInputMode === "input" ? /* @__PURE__ */ jsx(
571
+ Input,
572
+ {
573
+ placeholder: t("Enter the page where the issue occurred"),
574
+ value: customPage,
575
+ onChange: (e) => setCustomPage(e.target.value),
576
+ disabled: useCurrentPage
577
+ }
578
+ ) : pageOptions.length > 0 && /* @__PURE__ */ jsx(
571
579
  Select,
572
580
  {
573
581
  placeholder: t("Enter the page where the issue occurred"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tra-bilisim/report-issue",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Headless-core + React UI \"Report an Issue\" widget: masked screenshot/annotation, tab-only screen recording, console/network log capture and KVKK consent.",
5
5
  "license": "MIT",
6
6
  "author": "TRA Bilişim",