react-native-nitro-fetch 1.4.0 → 1.4.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/src/index.js CHANGED
@@ -1,9 +1,24 @@
1
- export { nitroFetch as fetch, nitroFetchOnWorklet, prefetch, prefetchOnAppStart, removeFromAutoPrefetch, removeAllFromAutoprefetch, __readAutoPrefetchQueue, } from './fetch';
1
+ export {
2
+ nitroFetch as fetch,
3
+ nitroFetchOnWorklet,
4
+ prefetch,
5
+ prefetchOnAppStart,
6
+ removeFromAutoPrefetch,
7
+ removeAllFromAutoprefetch,
8
+ __readAutoPrefetchQueue,
9
+ } from './fetch';
2
10
  export { NitroHeaders as Headers } from './Headers';
3
11
  export { NitroResponse as Response } from './Response';
4
12
  export { NitroRequest as Request } from './Request';
5
13
  export { NitroFetch } from './NitroInstances';
6
- export { registerTokenRefresh, clearTokenRefresh, callRefreshEndpoint, getStoredTokenRefreshConfig, getNestedField, applyTemplate, } from './tokenRefresh';
14
+ export {
15
+ registerTokenRefresh,
16
+ clearTokenRefresh,
17
+ callRefreshEndpoint,
18
+ getStoredTokenRefreshConfig,
19
+ getNestedField,
20
+ applyTemplate,
21
+ } from './tokenRefresh';
7
22
  export { NetworkInspector } from './NetworkInspector';
8
23
  export { generateCurl } from './CurlGenerator';
9
24
  export { profileFetch } from './HermesProfiler';
package/src/index.web.js CHANGED
@@ -9,96 +9,98 @@ export { NetworkInspector } from './NetworkInspector';
9
9
  export { generateCurl } from './CurlGenerator';
10
10
  export { profileFetch } from './HermesProfiler';
11
11
  export async function fetch(input, init) {
12
- let resolvedInput = input;
13
- let resolvedInit = init;
14
- if (input instanceof NitroRequestClass) {
15
- const method = (init?.method ?? input.method).toUpperCase();
16
- const hasBodyMethod = method !== 'GET' && method !== 'HEAD';
17
- let body = init?.body;
18
- if (body === undefined && hasBodyMethod) {
19
- const bytes = await input.arrayBuffer().catch(() => undefined);
20
- body = bytes && bytes.byteLength > 0 ? bytes : null;
21
- }
22
- resolvedInput = input.url;
23
- resolvedInit = {
24
- ...init,
25
- method,
26
- headers: (init?.headers ??
27
- input.headers),
28
- body,
29
- redirect: init?.redirect ?? input.redirect,
30
- cache: init?.cache ?? input.cache,
31
- signal: init?.signal ?? input.signal,
32
- };
12
+ let resolvedInput = input;
13
+ let resolvedInit = init;
14
+ if (input instanceof NitroRequestClass) {
15
+ const method = (init?.method ?? input.method).toUpperCase();
16
+ const hasBodyMethod = method !== 'GET' && method !== 'HEAD';
17
+ let body = init?.body;
18
+ if (body === undefined && hasBodyMethod) {
19
+ const bytes = await input.arrayBuffer().catch(() => undefined);
20
+ body = bytes && bytes.byteLength > 0 ? bytes : null;
33
21
  }
34
- return globalThis.fetch(resolvedInput, resolvedInit);
22
+ resolvedInput = input.url;
23
+ resolvedInit = {
24
+ ...init,
25
+ method,
26
+ headers: init?.headers ?? input.headers,
27
+ body,
28
+ redirect: init?.redirect ?? input.redirect,
29
+ cache: init?.cache ?? input.cache,
30
+ signal: init?.signal ?? input.signal,
31
+ };
32
+ }
33
+ return globalThis.fetch(resolvedInput, resolvedInit);
35
34
  }
36
35
  export async function nitroFetchOnWorklet(input, init, mapWorklet, _options) {
37
- console.warn('nitroFetchOnWorklet: worklets are not available on web; running on the JS thread');
38
- const res = await globalThis.fetch(input, init);
39
- const bodyBytes = await res.clone().arrayBuffer();
40
- let bodyString;
41
- try {
42
- bodyString = await res.clone().text();
43
- }
44
- catch {
45
- bodyString = undefined;
46
- }
47
- const headers = [];
48
- res.headers.forEach((v, k) => headers.push({ key: k, value: v }));
49
- return mapWorklet({
50
- url: res.url,
51
- status: res.status,
52
- statusText: res.statusText,
53
- ok: res.ok,
54
- redirected: res.redirected ?? false,
55
- headers,
56
- bodyBytes,
57
- bodyString,
58
- });
36
+ console.warn(
37
+ 'nitroFetchOnWorklet: worklets are not available on web; running on the JS thread'
38
+ );
39
+ const res = await globalThis.fetch(input, init);
40
+ const bodyBytes = await res.clone().arrayBuffer();
41
+ let bodyString;
42
+ try {
43
+ bodyString = await res.clone().text();
44
+ } catch {
45
+ bodyString = undefined;
46
+ }
47
+ const headers = [];
48
+ res.headers.forEach((v, k) => headers.push({ key: k, value: v }));
49
+ return mapWorklet({
50
+ url: res.url,
51
+ status: res.status,
52
+ statusText: res.statusText,
53
+ ok: res.ok,
54
+ redirected: res.redirected ?? false,
55
+ headers,
56
+ bodyBytes,
57
+ bodyString,
58
+ });
59
59
  }
60
60
  export async function prefetch(_input, _init) {
61
- console.warn('prefetch is not available on web');
61
+ console.warn('prefetch is not available on web');
62
62
  }
63
63
  export async function prefetchOnAppStart(_input, _init) {
64
- console.warn('prefetchOnAppStart is not available on web');
64
+ console.warn('prefetchOnAppStart is not available on web');
65
65
  }
66
66
  export async function removeFromAutoPrefetch(_prefetchKey) {
67
- console.warn('removeFromAutoPrefetch is not available on web');
67
+ console.warn('removeFromAutoPrefetch is not available on web');
68
68
  }
69
69
  export async function removeAllFromAutoprefetch() {
70
- console.warn('removeAllFromAutoprefetch is not available on web');
70
+ console.warn('removeAllFromAutoprefetch is not available on web');
71
71
  }
72
- export const NitroFetch = new Proxy({}, {
72
+ export const NitroFetch = new Proxy(
73
+ {},
74
+ {
73
75
  get(_target, prop) {
74
- console.warn(`NitroFetch.${String(prop)} is not available on web`);
75
- return undefined;
76
+ console.warn(`NitroFetch.${String(prop)} is not available on web`);
77
+ return undefined;
76
78
  },
77
- });
79
+ }
80
+ );
78
81
  export function registerTokenRefresh(_options) {
79
- console.warn('registerTokenRefresh is not available on web');
82
+ console.warn('registerTokenRefresh is not available on web');
80
83
  }
81
84
  export function clearTokenRefresh(_target) {
82
- console.warn('clearTokenRefresh is not available on web');
85
+ console.warn('clearTokenRefresh is not available on web');
83
86
  }
84
87
  export async function callRefreshEndpoint(_config) {
85
- console.warn('callRefreshEndpoint is not available on web');
86
- return {};
88
+ console.warn('callRefreshEndpoint is not available on web');
89
+ return {};
87
90
  }
88
91
  export function getStoredTokenRefreshConfig(_target) {
89
- console.warn('getStoredTokenRefreshConfig is not available on web');
90
- return null;
92
+ console.warn('getStoredTokenRefreshConfig is not available on web');
93
+ return null;
91
94
  }
92
95
  export function getNestedField(obj, dotPath) {
93
- const parts = dotPath.split('.');
94
- let current = obj;
95
- for (const part of parts) {
96
- if (current == null || typeof current !== 'object')
97
- return undefined;
98
- current = current[part];
99
- }
100
- return current != null ? String(current) : undefined;
96
+ const parts = dotPath.split('.');
97
+ let current = obj;
98
+ for (const part of parts) {
99
+ if (current == null || typeof current !== 'object') return undefined;
100
+ current = current[part];
101
+ }
102
+ return current != null ? String(current) : undefined;
101
103
  }
102
104
  export function applyTemplate(template, value) {
103
- return template.replace(/\{\{value\}\}/g, value);
105
+ return template.replace(/\{\{value\}\}/g, value);
104
106
  }
@@ -9,96 +9,94 @@ const KEY_FETCH_CACHE = 'nitro_token_refresh_fetch_cache';
9
9
  * Resolve a dot-notation path inside a parsed JSON object.
10
10
  */
11
11
  export function getNestedField(obj, dotPath) {
12
- const parts = dotPath.split('.');
13
- let current = obj;
14
- for (const part of parts) {
15
- if (current == null || typeof current !== 'object')
16
- return undefined;
17
- current = current[part];
18
- }
19
- return current != null ? String(current) : undefined;
12
+ const parts = dotPath.split('.');
13
+ let current = obj;
14
+ for (const part of parts) {
15
+ if (current == null || typeof current !== 'object') return undefined;
16
+ current = current[part];
17
+ }
18
+ return current != null ? String(current) : undefined;
20
19
  }
21
20
  export function applyTemplate(template, value) {
22
- return template.replace(/\{\{value\}\}/g, value);
21
+ return template.replace(/\{\{value\}\}/g, value);
23
22
  }
24
23
  function applyCompositeTemplate(template, values) {
25
- return template.replace(/\{\{(\w+)\}\}/g, (_, key) => values[key] ?? '');
24
+ return template.replace(/\{\{(\w+)\}\}/g, (_, key) => values[key] ?? '');
26
25
  }
27
26
  export async function callRefreshEndpoint(config) {
28
- const method = config.method ?? 'POST';
29
- const response = await fetch(config.url, {
30
- method,
31
- headers: config.headers,
32
- body: config.body,
33
- });
34
- if (!response.ok) {
35
- throw new Error(`Token refresh failed: ${response.status} ${response.statusText}`);
36
- }
37
- const headers = {};
38
- if (config.responseType === 'text') {
39
- const text = await response.text();
40
- if (config.textHeader) {
41
- headers[config.textHeader] = config.textTemplate
42
- ? applyTemplate(config.textTemplate, text)
43
- : text;
44
- }
45
- return headers;
27
+ const method = config.method ?? 'POST';
28
+ const response = await fetch(config.url, {
29
+ method,
30
+ headers: config.headers,
31
+ body: config.body,
32
+ });
33
+ if (!response.ok) {
34
+ throw new Error(
35
+ `Token refresh failed: ${response.status} ${response.statusText}`
36
+ );
37
+ }
38
+ const headers = {};
39
+ if (config.responseType === 'text') {
40
+ const text = await response.text();
41
+ if (config.textHeader) {
42
+ headers[config.textHeader] = config.textTemplate
43
+ ? applyTemplate(config.textTemplate, text)
44
+ : text;
46
45
  }
47
- // Default: json
48
- const json = await response.json();
49
- if (config.mappings) {
50
- for (const mapping of config.mappings) {
51
- const value = getNestedField(json, mapping.jsonPath);
52
- if (value != null) {
53
- headers[mapping.header] = mapping.valueTemplate
54
- ? applyTemplate(mapping.valueTemplate, value)
55
- : value;
56
- }
57
- }
46
+ return headers;
47
+ }
48
+ // Default: json
49
+ const json = await response.json();
50
+ if (config.mappings) {
51
+ for (const mapping of config.mappings) {
52
+ const value = getNestedField(json, mapping.jsonPath);
53
+ if (value != null) {
54
+ headers[mapping.header] = mapping.valueTemplate
55
+ ? applyTemplate(mapping.valueTemplate, value)
56
+ : value;
57
+ }
58
58
  }
59
- if (config.compositeHeaders) {
60
- for (const comp of config.compositeHeaders) {
61
- const values = {};
62
- for (const [placeholder, jsonPath] of Object.entries(comp.paths)) {
63
- const val = getNestedField(json, jsonPath);
64
- if (val != null)
65
- values[placeholder] = val;
66
- }
67
- headers[comp.header] = applyCompositeTemplate(comp.template, values);
68
- }
59
+ }
60
+ if (config.compositeHeaders) {
61
+ for (const comp of config.compositeHeaders) {
62
+ const values = {};
63
+ for (const [placeholder, jsonPath] of Object.entries(comp.paths)) {
64
+ const val = getNestedField(json, jsonPath);
65
+ if (val != null) values[placeholder] = val;
66
+ }
67
+ headers[comp.header] = applyCompositeTemplate(comp.template, values);
69
68
  }
70
- return headers;
69
+ }
70
+ return headers;
71
71
  }
72
72
  export function registerTokenRefresh(options) {
73
- const { target, ...config } = options;
74
- const raw = JSON.stringify(config);
75
- if (target === 'websocket' || target === 'all') {
76
- NativeStorageSingleton.setSecureString(KEY_WS, raw);
77
- }
78
- if (target === 'fetch' || target === 'all') {
79
- NativeStorageSingleton.setSecureString(KEY_FETCH, raw);
80
- }
73
+ const { target, ...config } = options;
74
+ const raw = JSON.stringify(config);
75
+ if (target === 'websocket' || target === 'all') {
76
+ NativeStorageSingleton.setSecureString(KEY_WS, raw);
77
+ }
78
+ if (target === 'fetch' || target === 'all') {
79
+ NativeStorageSingleton.setSecureString(KEY_FETCH, raw);
80
+ }
81
81
  }
82
82
  export function clearTokenRefresh(target) {
83
- const t = target ?? 'all';
84
- if (t === 'websocket' || t === 'all') {
85
- NativeStorageSingleton.removeSecureString(KEY_WS);
86
- NativeStorageSingleton.removeSecureString(KEY_WS_CACHE);
87
- }
88
- if (t === 'fetch' || t === 'all') {
89
- NativeStorageSingleton.removeSecureString(KEY_FETCH);
90
- NativeStorageSingleton.removeSecureString(KEY_FETCH_CACHE);
91
- }
83
+ const t = target ?? 'all';
84
+ if (t === 'websocket' || t === 'all') {
85
+ NativeStorageSingleton.removeSecureString(KEY_WS);
86
+ NativeStorageSingleton.removeSecureString(KEY_WS_CACHE);
87
+ }
88
+ if (t === 'fetch' || t === 'all') {
89
+ NativeStorageSingleton.removeSecureString(KEY_FETCH);
90
+ NativeStorageSingleton.removeSecureString(KEY_FETCH_CACHE);
91
+ }
92
92
  }
93
93
  export function getStoredTokenRefreshConfig(target) {
94
- const key = target === 'websocket' ? KEY_WS : KEY_FETCH;
95
- try {
96
- const raw = NativeStorageSingleton.getSecureString(key);
97
- if (!raw)
98
- return null;
99
- return JSON.parse(raw);
100
- }
101
- catch {
102
- return null;
103
- }
94
+ const key = target === 'websocket' ? KEY_WS : KEY_FETCH;
95
+ try {
96
+ const raw = NativeStorageSingleton.getSecureString(key);
97
+ if (!raw) return null;
98
+ return JSON.parse(raw);
99
+ } catch {
100
+ return null;
101
+ }
104
102
  }
package/src/utf8.js CHANGED
@@ -2,39 +2,40 @@ let _TextEncoder;
2
2
  let _TextDecoder;
3
3
  const NITRO_TEXT_DECODER_PKG = 'react-native-nitro-text-decoder';
4
4
  function loadOptionalTextCodec() {
5
- try {
6
- // Hide require from the bundler so the package stays truly optional.
7
- // eslint-disable-next-line no-new-func
8
- const dynamicRequire = new Function('mod', 'return require(mod);');
9
- return dynamicRequire(NITRO_TEXT_DECODER_PKG);
10
- }
11
- catch {
12
- return {};
13
- }
5
+ try {
6
+ // Hide require from the bundler so the package stays truly optional.
7
+ // eslint-disable-next-line no-new-func
8
+ const dynamicRequire = new Function('mod', 'return require(mod);');
9
+ return dynamicRequire(NITRO_TEXT_DECODER_PKG);
10
+ } catch {
11
+ return {};
12
+ }
14
13
  }
15
14
  if (typeof TextEncoder !== 'undefined') {
16
- _TextEncoder = TextEncoder;
17
- }
18
- else {
19
- _TextEncoder = loadOptionalTextCodec().TextEncoder;
15
+ _TextEncoder = TextEncoder;
16
+ } else {
17
+ _TextEncoder = loadOptionalTextCodec().TextEncoder;
20
18
  }
21
19
  if (typeof TextDecoder !== 'undefined') {
22
- _TextDecoder = TextDecoder;
23
- }
24
- else {
25
- _TextDecoder = loadOptionalTextCodec().TextDecoder;
20
+ _TextDecoder = TextDecoder;
21
+ } else {
22
+ _TextDecoder = loadOptionalTextCodec().TextDecoder;
26
23
  }
27
24
  export function stringToUTF8(str) {
28
- if (!_TextEncoder) {
29
- console.warn('stringToUTF8: TextEncoder not available. Install react-native-nitro-text-decoder.');
30
- return new Uint8Array(0);
31
- }
32
- return new _TextEncoder().encode(str);
25
+ if (!_TextEncoder) {
26
+ console.warn(
27
+ 'stringToUTF8: TextEncoder not available. Install react-native-nitro-text-decoder.'
28
+ );
29
+ return new Uint8Array(0);
30
+ }
31
+ return new _TextEncoder().encode(str);
33
32
  }
34
33
  export function utf8ToString(bytes) {
35
- if (!_TextDecoder) {
36
- console.warn('utf8ToString: TextDecoder not available. Install react-native-nitro-text-decoder.');
37
- return '';
38
- }
39
- return new _TextDecoder().decode(bytes);
34
+ if (!_TextDecoder) {
35
+ console.warn(
36
+ 'utf8ToString: TextDecoder not available. Install react-native-nitro-text-decoder.'
37
+ );
38
+ return '';
39
+ }
40
+ return new _TextDecoder().decode(bytes);
40
41
  }