react-native-qalink 0.3.0 → 0.3.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 (44) hide show
  1. package/README.md +10 -1
  2. package/dist/core/device.d.ts +14 -0
  3. package/dist/core/device.d.ts.map +1 -0
  4. package/dist/core/device.js +46 -27
  5. package/dist/core/device.js.map +1 -0
  6. package/dist/core/sanitize.d.ts +16 -0
  7. package/dist/core/sanitize.d.ts.map +1 -0
  8. package/dist/core/sanitize.js +96 -49
  9. package/dist/core/sanitize.js.map +1 -0
  10. package/dist/core/session.d.ts +0 -1
  11. package/dist/core/session.d.ts.map +1 -1
  12. package/dist/core/session.js +12 -27
  13. package/dist/core/session.js.map +1 -1
  14. package/dist/index.d.ts +6 -40
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +196 -164
  17. package/dist/index.js.map +1 -1
  18. package/dist/interceptors/axios.d.ts.map +1 -1
  19. package/dist/interceptors/axios.js +5 -4
  20. package/dist/interceptors/axios.js.map +1 -1
  21. package/dist/interceptors/console.d.ts.map +1 -1
  22. package/dist/interceptors/console.js +112 -67
  23. package/dist/interceptors/console.js.map +1 -1
  24. package/dist/interceptors/errors.d.ts.map +1 -1
  25. package/dist/interceptors/errors.js +4 -3
  26. package/dist/interceptors/errors.js.map +1 -1
  27. package/dist/interceptors/fetch.d.ts +1 -1
  28. package/dist/interceptors/fetch.d.ts.map +1 -1
  29. package/dist/interceptors/fetch.js +99 -96
  30. package/dist/interceptors/fetch.js.map +1 -1
  31. package/dist/interceptors/metro.d.ts +4 -0
  32. package/dist/interceptors/metro.d.ts.map +1 -0
  33. package/dist/interceptors/metro.js +174 -94
  34. package/dist/interceptors/metro.js.map +1 -0
  35. package/dist/interceptors/runtime.d.ts.map +1 -1
  36. package/dist/interceptors/runtime.js +55 -31
  37. package/dist/interceptors/runtime.js.map +1 -1
  38. package/dist/transport/websocket.d.ts +3 -2
  39. package/dist/transport/websocket.d.ts.map +1 -1
  40. package/dist/transport/websocket.js +16 -4
  41. package/dist/transport/websocket.js.map +1 -1
  42. package/dist/types/index.d.ts +66 -31
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/package.json +30 -7
package/README.md CHANGED
@@ -93,6 +93,7 @@ export default function App() {
93
93
  useEffect(() => {
94
94
  QALink.init({
95
95
  serverUrl: 'ws://192.168.1.100:3000',
96
+ apiKey: 'qlk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
96
97
  appVersion: '1.2.3',
97
98
  captureRuntimeErrors: true, // pantalla roja, yellow box
98
99
  console: {
@@ -120,6 +121,7 @@ para que el dashboard no se llene de ruido.
120
121
  ```tsx
121
122
  QALink.init({
122
123
  serverUrl: 'ws://192.168.1.100:3000',
124
+ apiKey: 'qlk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
123
125
  appVersion: '1.2.3',
124
126
  console: {
125
127
  captureLogs: true,
@@ -146,6 +148,7 @@ Si quieres que el QA vea únicamente los logs que tú marcas explícitamente:
146
148
  ```tsx
147
149
  QALink.init({
148
150
  serverUrl: 'ws://192.168.1.100:3000',
151
+ apiKey: 'qlk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
149
152
  appVersion: '1.2.3',
150
153
  console: {
151
154
  captureLogs: true,
@@ -172,7 +175,11 @@ export const apiPrincipal = axios.create({ baseURL: 'https://api.miapp.com/v1' }
172
175
  export const apiPagos = axios.create({ baseURL: 'https://pagos.miapp.com' });
173
176
 
174
177
  // App.tsx
175
- await QALink.init({ serverUrl: 'ws://192.168.1.100:3000', appVersion: '1.2.3' });
178
+ await QALink.init({
179
+ serverUrl: 'ws://192.168.1.100:3000',
180
+ apiKey: 'qlk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
181
+ appVersion: '1.2.3',
182
+ });
176
183
 
177
184
  QALink.interceptAxios(apiPrincipal);
178
185
  QALink.interceptAxios(apiPagos);
@@ -243,6 +250,7 @@ export async function initQALink() {
243
250
 
244
251
  await QALink.init({
245
252
  serverUrl: Config.QALINK_SERVER,
253
+ apiKey: Config.QALINK_API_KEY,
246
254
  appVersion: Config.VERSION_NAME ?? '0.0.0',
247
255
  logNetworkBodies: true,
248
256
  captureRuntimeErrors: true,
@@ -300,6 +308,7 @@ Cada sesión incluye una línea de tiempo unificada con todos los eventos:
300
308
  QALink.init({
301
309
  // — Requeridos —
302
310
  serverUrl: 'ws://192.168.1.100:3000',
311
+ apiKey: 'qlk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
303
312
  appVersion: '1.0.0',
304
313
 
305
314
  // — Red —
@@ -0,0 +1,14 @@
1
+ /**
2
+ * deviceId — Identificador único y persistente del dispositivo.
3
+ *
4
+ * Generamos un UUID la primera vez y lo guardamos en AsyncStorage
5
+ * (si está disponible). Si no hay AsyncStorage, usemos un ID de sesión
6
+ * que persiste en memoria mientras la app vive.
7
+ *
8
+ * El deviceId se envía en TODOS los eventos para que el dashboard
9
+ * pueda agrupar sesiones por dispositivo físico, no solo por session.
10
+ */
11
+ export declare function getDeviceId(): Promise<string>;
12
+ /** Para tests — permite resetear el deviceId */
13
+ export declare function resetDeviceId(): void;
14
+ //# sourceMappingURL=device.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/core/device.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAeH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAuBnD;AAED,gDAAgD;AAChD,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
@@ -1,35 +1,54 @@
1
1
  "use strict";
2
+ /**
3
+ * deviceId — Identificador único y persistente del dispositivo.
4
+ *
5
+ * Generamos un UUID la primera vez y lo guardamos en AsyncStorage
6
+ * (si está disponible). Si no hay AsyncStorage, usemos un ID de sesión
7
+ * que persiste en memoria mientras la app vive.
8
+ *
9
+ * El deviceId se envía en TODOS los eventos para que el dashboard
10
+ * pueda agrupar sesiones por dispositivo físico, no solo por session.
11
+ */
2
12
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resetDeviceId = exports.getDeviceId = void 0;
4
-
13
+ exports.getDeviceId = getDeviceId;
14
+ exports.resetDeviceId = resetDeviceId;
5
15
  let cachedDeviceId = null;
6
-
7
16
  function generateDeviceId() {
8
- return 'dev_xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
9
- const r = Math.random() * 16 | 0;
10
- const v = c === 'x' ? r : (r & 0x3 | 0x8);
11
- return v.toString(16);
12
- });
17
+ // UUID v4 simple sin dependencias
18
+ return 'dev_xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
19
+ const r = Math.random() * 16 | 0;
20
+ const v = c === 'x' ? r : (r & 0x3 | 0x8);
21
+ return v.toString(16);
22
+ });
13
23
  }
14
-
15
24
  const STORAGE_KEY = '@qalink_device_id';
16
-
17
25
  async function getDeviceId() {
18
- if (cachedDeviceId) return cachedDeviceId;
19
- try {
20
- const AsyncStorage = require('@react-native-async-storage/async-storage').default;
21
- const stored = await AsyncStorage.getItem(STORAGE_KEY);
22
- if (stored) { cachedDeviceId = stored; return cachedDeviceId; }
23
- const newId = generateDeviceId();
24
- await AsyncStorage.setItem(STORAGE_KEY, newId);
25
- cachedDeviceId = newId;
26
- return cachedDeviceId;
27
- } catch {
28
- if (!cachedDeviceId) cachedDeviceId = generateDeviceId();
29
- return cachedDeviceId;
30
- }
26
+ if (cachedDeviceId)
27
+ return cachedDeviceId;
28
+ try {
29
+ // Intentar leer de AsyncStorage si está disponible
30
+ const AsyncStorage = require('@react-native-async-storage/async-storage').default;
31
+ const stored = await AsyncStorage.getItem(STORAGE_KEY);
32
+ if (stored) {
33
+ cachedDeviceId = stored;
34
+ return cachedDeviceId !== null && cachedDeviceId !== void 0 ? cachedDeviceId : generateDeviceId();
35
+ }
36
+ // Primera vez: generar y guardar
37
+ const newId = generateDeviceId();
38
+ await AsyncStorage.setItem(STORAGE_KEY, newId);
39
+ cachedDeviceId = newId;
40
+ return cachedDeviceId !== null && cachedDeviceId !== void 0 ? cachedDeviceId : newId;
41
+ }
42
+ catch (_a) {
43
+ // AsyncStorage no disponible — usar ID en memoria (persiste en la sesión)
44
+ if (!cachedDeviceId) {
45
+ cachedDeviceId = generateDeviceId();
46
+ }
47
+ return cachedDeviceId !== null && cachedDeviceId !== void 0 ? cachedDeviceId : generateDeviceId();
48
+ }
31
49
  }
32
- exports.getDeviceId = getDeviceId;
33
-
34
- function resetDeviceId() { cachedDeviceId = null; }
35
- exports.resetDeviceId = resetDeviceId;
50
+ /** Para tests — permite resetear el deviceId */
51
+ function resetDeviceId() {
52
+ cachedDeviceId = null;
53
+ }
54
+ //# sourceMappingURL=device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/core/device.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAeH,kCAuBC;AAGD,sCAEC;AAzCD,IAAI,cAAc,GAAkB,IAAI,CAAC;AAEzC,SAAS,gBAAgB;IACvB,kCAAkC;IAClC,OAAO,0CAA0C,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;QACvE,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;QAC1C,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,WAAW,GAAG,mBAAmB,CAAC;AAEjC,KAAK,UAAU,WAAW;IAC/B,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAE1C,IAAI,CAAC;QACH,mDAAmD;QACnD,MAAM,YAAY,GAAG,OAAO,CAAC,2CAA2C,CAAC,CAAC,OAAO,CAAC;QAClF,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACvD,IAAI,MAAM,EAAE,CAAC;YACX,cAAc,GAAG,MAAM,CAAC;YACxB,OAAO,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,gBAAgB,EAAE,CAAC;QAC9C,CAAC;QACD,iCAAiC;QACjC,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;QACjC,MAAM,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QAC/C,cAAc,GAAG,KAAK,CAAC;QACvB,OAAO,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,KAAK,CAAC;IACjC,CAAC;IAAC,WAAM,CAAC;QACP,0EAA0E;QAC1E,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,cAAc,GAAG,gBAAgB,EAAE,CAAC;QACtC,CAAC;QACD,OAAO,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,gBAAgB,EAAE,CAAC;IAC9C,CAAC;AACH,CAAC;AAED,gDAAgD;AAChD,SAAgB,aAAa;IAC3B,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * sanitizePayload — Redacta campos sensibles de cualquier objeto/string.
3
+ *
4
+ * Detecta automáticamente campos como password, token, secret, etc.
5
+ * y los reemplaza con '[REDACTED]' antes de enviar al dashboard.
6
+ *
7
+ * También detecta si la URL es un endpoint de autenticación
8
+ * para redactar el body completo si es necesario.
9
+ */
10
+ export declare function isAuthUrl(url: string): boolean;
11
+ export declare function sanitizePayload(payload: unknown, extraSensitiveFields?: string[]): {
12
+ sanitized: unknown;
13
+ hadSensitiveData: boolean;
14
+ };
15
+ export declare function sanitizeHeaders(headers: Record<string, string>, sensitiveHeaders?: string[]): Record<string, string>;
16
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/core/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA8CH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG9C;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,OAAO,EAChB,oBAAoB,GAAE,MAAM,EAAO,GAClC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAA;CAAE,CA2CnD;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,gBAAgB,GAAE,MAAM,EAAO,GAC9B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUxB"}
@@ -1,62 +1,109 @@
1
1
  "use strict";
2
+ /**
3
+ * sanitizePayload — Redacta campos sensibles de cualquier objeto/string.
4
+ *
5
+ * Detecta automáticamente campos como password, token, secret, etc.
6
+ * y los reemplaza con '[REDACTED]' antes de enviar al dashboard.
7
+ *
8
+ * También detecta si la URL es un endpoint de autenticación
9
+ * para redactar el body completo si es necesario.
10
+ */
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sanitizeHeaders = exports.sanitizePayload = exports.isAuthUrl = void 0;
4
-
12
+ exports.isAuthUrl = isAuthUrl;
13
+ exports.sanitizePayload = sanitizePayload;
14
+ exports.sanitizeHeaders = sanitizeHeaders;
15
+ // Campos que SIEMPRE se redactan, sin importar el contexto
5
16
  const DEFAULT_SENSITIVE_FIELDS = [
6
- 'password','passwd','pass','secret','token','access_token','refresh_token',
7
- 'id_token','authorization','auth','api_key','apikey','api_secret',
8
- 'credit_card','card_number','cvv','cvc','ssn','social_security',
9
- 'pin','otp','private_key','client_secret',
17
+ 'password',
18
+ 'passwd',
19
+ 'pass',
20
+ 'secret',
21
+ 'token',
22
+ 'access_token',
23
+ 'refresh_token',
24
+ 'id_token',
25
+ 'authorization',
26
+ 'auth',
27
+ 'api_key',
28
+ 'apikey',
29
+ 'api_secret',
30
+ 'credit_card',
31
+ 'card_number',
32
+ 'cvv',
33
+ 'cvc',
34
+ 'ssn',
35
+ 'social_security',
36
+ 'pin',
37
+ 'otp',
38
+ 'private_key',
39
+ 'client_secret',
10
40
  ];
11
-
41
+ // Patrones de URL que indican endpoints de autenticación
42
+ // donde el body entero es sospechoso de tener datos sensibles
12
43
  const AUTH_URL_PATTERNS = [
13
- '/auth/','/login','/signin','/sign-in','/signup','/sign-up',
14
- '/register','/password','/token','/oauth','/credentials','/session',
44
+ '/auth/',
45
+ '/login',
46
+ '/signin',
47
+ '/sign-in',
48
+ '/signup',
49
+ '/sign-up',
50
+ '/register',
51
+ '/password',
52
+ '/token',
53
+ '/oauth',
54
+ '/credentials',
55
+ '/session',
15
56
  ];
16
-
17
57
  function isAuthUrl(url) {
18
- const lower = url.toLowerCase();
19
- return AUTH_URL_PATTERNS.some(p => lower.includes(p));
58
+ const lower = url.toLowerCase();
59
+ return AUTH_URL_PATTERNS.some(p => lower.includes(p));
20
60
  }
21
- exports.isAuthUrl = isAuthUrl;
22
-
23
61
  function sanitizePayload(payload, extraSensitiveFields = []) {
24
- if (!payload) return { sanitized: payload, hadSensitiveData: false };
25
- const allSensitive = [...DEFAULT_SENSITIVE_FIELDS, ...extraSensitiveFields.map(f => f.toLowerCase())];
26
- let hadSensitiveData = false;
27
-
28
- const sanitize = (obj) => {
29
- if (typeof obj === 'string') {
30
- try { const parsed = JSON.parse(obj); return JSON.stringify(sanitize(parsed)); } catch { return obj; }
31
- }
32
- if (Array.isArray(obj)) return obj.map(sanitize);
33
- if (obj !== null && typeof obj === 'object') {
34
- const result = {};
35
- for (const [key, value] of Object.entries(obj)) {
36
- if (allSensitive.includes(key.toLowerCase())) {
37
- result[key] = '[REDACTED]';
38
- hadSensitiveData = true;
39
- } else {
40
- result[key] = sanitize(value);
62
+ if (!payload)
63
+ return { sanitized: payload, hadSensitiveData: false };
64
+ const allSensitive = [
65
+ ...DEFAULT_SENSITIVE_FIELDS,
66
+ ...extraSensitiveFields.map(f => f.toLowerCase()),
67
+ ];
68
+ let hadSensitiveData = false;
69
+ const sanitize = (obj) => {
70
+ if (typeof obj === 'string') {
71
+ // Si es un JSON string, parsear y sanitizar
72
+ try {
73
+ const parsed = JSON.parse(obj);
74
+ const result = sanitize(parsed);
75
+ return JSON.stringify(result);
76
+ }
77
+ catch (_a) {
78
+ return obj;
79
+ }
41
80
  }
42
- }
43
- return result;
44
- }
45
- return obj;
46
- };
47
-
48
- return { sanitized: sanitize(payload), hadSensitiveData };
81
+ if (Array.isArray(obj)) {
82
+ return obj.map(sanitize);
83
+ }
84
+ if (obj !== null && typeof obj === 'object') {
85
+ const result = {};
86
+ for (const [key, value] of Object.entries(obj)) {
87
+ if (allSensitive.includes(key.toLowerCase())) {
88
+ result[key] = '[REDACTED]';
89
+ hadSensitiveData = true;
90
+ }
91
+ else {
92
+ result[key] = sanitize(value);
93
+ }
94
+ }
95
+ return result;
96
+ }
97
+ return obj;
98
+ };
99
+ return { sanitized: sanitize(payload), hadSensitiveData };
49
100
  }
50
- exports.sanitizePayload = sanitizePayload;
51
-
52
101
  function sanitizeHeaders(headers, sensitiveHeaders = []) {
53
- const defaultSensitive = ['authorization','x-api-key','cookie','set-cookie','x-auth-token'];
54
- const allSensitive = [...defaultSensitive, ...sensitiveHeaders.map(h => h.toLowerCase())];
55
- return Object.fromEntries(
56
- Object.entries(headers).map(([key, value]) => [
57
- key,
58
- allSensitive.includes(key.toLowerCase()) ? '[REDACTED]' : value,
59
- ])
60
- );
102
+ const defaultSensitive = ['authorization', 'x-api-key', 'cookie', 'set-cookie', 'x-auth-token'];
103
+ const allSensitive = [...defaultSensitive, ...sensitiveHeaders.map(h => h.toLowerCase())];
104
+ return Object.fromEntries(Object.entries(headers).map(([key, value]) => [
105
+ key,
106
+ allSensitive.includes(key.toLowerCase()) ? '[REDACTED]' : value,
107
+ ]));
61
108
  }
62
- exports.sanitizeHeaders = sanitizeHeaders;
109
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/core/sanitize.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,5 @@ export declare function generateId(): string;
3
3
  export declare function getSessionId(): string;
4
4
  export declare function resetSession(): string;
5
5
  export declare function getDeviceInfo(appVersion: string): Promise<DeviceInfo>;
6
- export declare function sanitizeHeaders(headers: Record<string, string>, sensitiveHeaders?: string[]): Record<string, string>;
7
6
  export declare function sanitizeBody(body: unknown, logBodies: boolean): unknown;
8
7
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAItC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAGrC;AAED,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAmB3E;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,gBAAgB,GAAE,MAAM,EAAO,GAC9B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUxB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAGvE"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAItC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAGrC;AAED,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAmB3E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAGvE"}
@@ -1,39 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sanitizeBody = exports.sanitizeHeaders = exports.getDeviceInfo = exports.resetSession = exports.getSessionId = exports.generateId = void 0;
4
-
3
+ exports.generateId = generateId;
4
+ exports.getSessionId = getSessionId;
5
+ exports.resetSession = resetSession;
6
+ exports.getDeviceInfo = getDeviceInfo;
7
+ exports.sanitizeBody = sanitizeBody;
5
8
  let currentSessionId = null;
6
-
7
9
  function generateId() {
8
10
  return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
9
11
  }
10
- exports.generateId = generateId;
11
-
12
12
  function getSessionId() {
13
13
  if (!currentSessionId) {
14
14
  currentSessionId = generateId();
15
15
  }
16
16
  return currentSessionId;
17
17
  }
18
- exports.getSessionId = getSessionId;
19
-
20
18
  function resetSession() {
21
19
  currentSessionId = generateId();
22
20
  return currentSessionId;
23
21
  }
24
- exports.resetSession = resetSession;
25
-
26
22
  async function getDeviceInfo(appVersion) {
23
+ var _a, _b;
27
24
  try {
28
25
  const { Platform } = require('react-native');
29
26
  return {
30
27
  platform: Platform.OS,
31
- osVersion: Platform.Version?.toString() ?? 'unknown',
28
+ osVersion: (_b = (_a = Platform.Version) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : 'unknown',
32
29
  appVersion,
33
30
  deviceModel: 'unknown',
34
31
  buildType: typeof __DEV__ !== 'undefined' && __DEV__ ? 'debug' : 'release',
35
32
  };
36
- } catch {
33
+ }
34
+ catch (_c) {
37
35
  return {
38
36
  platform: 'android',
39
37
  osVersion: 'unknown',
@@ -43,22 +41,9 @@ async function getDeviceInfo(appVersion) {
43
41
  };
44
42
  }
45
43
  }
46
- exports.getDeviceInfo = getDeviceInfo;
47
-
48
- function sanitizeHeaders(headers, sensitiveHeaders = []) {
49
- const defaultSensitive = ['authorization', 'x-api-key', 'cookie', 'set-cookie'];
50
- const allSensitive = [...defaultSensitive, ...sensitiveHeaders.map(h => h.toLowerCase())];
51
- return Object.fromEntries(
52
- Object.entries(headers).map(([key, value]) => [
53
- key,
54
- allSensitive.includes(key.toLowerCase()) ? '[REDACTED]' : value,
55
- ])
56
- );
57
- }
58
- exports.sanitizeHeaders = sanitizeHeaders;
59
-
60
44
  function sanitizeBody(body, logBodies) {
61
- if (!logBodies) return '[body omitted - enable logNetworkBodies]';
45
+ if (!logBodies)
46
+ return '[body omitted - enable logNetworkBodies]';
62
47
  return body;
63
48
  }
64
- exports.sanitizeBody = sanitizeBody;
49
+ //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":";;AAIA,gCAEC;AAED,oCAKC;AAED,oCAGC;AAED,sCAmBC;AAED,0CAaC;AAED,oCAGC;AAzDD,IAAI,gBAAgB,GAAkB,IAAI,CAAC;AAE3C,SAAgB,UAAU;IACxB,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,SAAgB,YAAY;IAC1B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,gBAAgB,GAAG,UAAU,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,SAAgB,YAAY;IAC1B,gBAAgB,GAAG,UAAU,EAAE,CAAC;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAEM,KAAK,UAAU,aAAa,CAAC,UAAkB;;IACpD,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QAC7C,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,EAAuB;YAC1C,SAAS,EAAE,MAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,QAAQ,EAAE,mCAAI,SAAS;YACpD,UAAU;YACV,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC3E,CAAC;IACJ,CAAC;IAAC,WAAM,CAAC;QACP,OAAO;YACL,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,SAAS;YACpB,UAAU;YACV,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,SAAS;SACrB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,eAAe,CAC7B,OAA+B,EAC/B,mBAA6B,EAAE;IAE/B,MAAM,gBAAgB,GAAG,CAAC,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAChF,MAAM,YAAY,GAAG,CAAC,GAAG,gBAAgB,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAE1F,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;QAC5C,GAAG;QACH,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK;KAChE,CAAC,CACH,CAAC;AACJ,CAAC;AAED,SAAgB,YAAY,CAAC,IAAa,EAAE,SAAkB;IAC5D,IAAI,CAAC,SAAS;QAAE,OAAO,0CAA0C,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/core/session.ts"],"names":[],"mappings":";;AAIA,gCAEC;AAED,oCAKC;AAED,oCAGC;AAED,sCAmBC;AAED,oCAGC;AA1CD,IAAI,gBAAgB,GAAkB,IAAI,CAAC;AAE3C,SAAgB,UAAU;IACxB,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AACpE,CAAC;AAED,SAAgB,YAAY;IAC1B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,gBAAgB,GAAG,UAAU,EAAE,CAAC;IAClC,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,SAAgB,YAAY;IAC1B,gBAAgB,GAAG,UAAU,EAAE,CAAC;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAEM,KAAK,UAAU,aAAa,CAAC,UAAkB;;IACpD,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QAC7C,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,EAAuB;YAC1C,SAAS,EAAE,MAAA,MAAA,QAAQ,CAAC,OAAO,0CAAE,QAAQ,EAAE,mCAAI,SAAS;YACpD,UAAU;YACV,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC3E,CAAC;IACJ,CAAC;IAAC,WAAM,CAAC;QACP,OAAO;YACL,QAAQ,EAAE,SAAS;YACnB,SAAS,EAAE,SAAS;YACpB,UAAU;YACV,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,SAAS;SACrB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,YAAY,CAAC,IAAa,EAAE,SAAkB;IAC5D,IAAI,CAAC,SAAS;QAAE,OAAO,0CAA0C,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,56 +1,22 @@
1
- import { QALinkConfig } from './types';
1
+ import { QALinkConfig, LogRequestOptions } from './types';
2
2
  declare class QALinkSDK {
3
3
  private transport;
4
4
  private config;
5
5
  private cleanups;
6
6
  private initialized;
7
7
  private currentScreen;
8
- /**
9
- * Inicializa el SDK. Llamar al inicio de la app, antes de cualquier request.
10
- *
11
- * @example
12
- * QALink.init({
13
- * serverUrl: 'ws://192.168.1.100:3000',
14
- * appVersion: '1.2.3',
15
- * captureRuntimeErrors: true,
16
- * console: {
17
- * captureLogs: true,
18
- * captureWarnings: true,
19
- * captureErrors: true,
20
- * ignorePatterns: ['[react-query]'],
21
- * },
22
- * });
23
- */
8
+ private _deviceId;
24
9
  init(config: QALinkConfig): Promise<void>;
25
- /**
26
- * Registra interceptor para una instancia específica de Axios.
27
- *
28
- * @example
29
- * import axios from 'axios';
30
- * QALink.interceptAxios(axios);
31
- *
32
- * // También con instancias custom:
33
- * const api = axios.create({ baseURL: 'https://api.miapp.com' });
34
- * QALink.interceptAxios(api);
35
- */
36
10
  interceptAxios(axiosInstance: any): void;
37
- /**
38
- * Registra una acción del usuario (breadcrumb).
39
- *
40
- * @example
41
- * QALink.addBreadcrumb('TAP → Confirmar Compra', { total: 150 });
42
- */
43
11
  addBreadcrumb(action: string, data?: Record<string, unknown>): void;
44
- /**
45
- * Registra la pantalla actual. Llamar en cada cambio de navegación.
46
- * Genera automáticamente un breadcrumb de navegación.
47
- */
12
+ logRequest(options: LogRequestOptions): void;
48
13
  setScreen(screenName: string): void;
49
- /** Estado actual de la conexión WebSocket */
14
+ getDeviceId(): string;
50
15
  getStatus(): string;
51
- /** Limpia todos los interceptores y desconecta. Útil en tests. */
52
16
  destroy(): void;
53
17
  private log;
18
+ private validateRequiredConfig;
19
+ private buildConnectionUrl;
54
20
  }
55
21
  export declare const QALink: QALinkSDK;
56
22
  export * from './types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAmD,MAAM,SAAS,CAAC;AASxF,cAAM,SAAS;IACb,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAa;IAElC;;;;;;;;;;;;;;;OAeG;IACG,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA0E/C;;;;;;;;;;OAUG;IACH,cAAc,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI;IASxC;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAiBnE;;;OAGG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAMnC,6CAA6C;IAC7C,SAAS,IAAI,MAAM;IAInB,kEAAkE;IAClE,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,GAAG;CAKZ;AAED,eAAO,MAAM,MAAM,WAAkB,CAAC;AAEtC,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAGZ,iBAAiB,EAGlB,MAAM,SAAS,CAAC;AAYjB,cAAM,SAAS;IACb,OAAO,CAAC,SAAS,CAAuC;IACxD,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,SAAS,CAA0B;IAErC,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA+E/C,cAAc,CAAC,aAAa,EAAE,GAAG,GAAG,IAAI;IASxC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAgBnE,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IA6C5C,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAMnC,WAAW,IAAI,MAAM;IACrB,SAAS,IAAM,MAAM;IAErB,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,kBAAkB;CAS3B;AAED,eAAO,MAAM,MAAM,WAAkB,CAAC;AAEtC,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC"}