@wutiange/log-listener-plugin 2.0.1-alpha.3 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +163 -163
  3. package/dist/src/HTTPInterceptor.js +2 -1
  4. package/dist/src/HTTPInterceptor.js.map +1 -1
  5. package/dist/src/__tests__/Server.test.js +4 -4
  6. package/dist/src/__tests__/Server.test.js.map +1 -1
  7. package/dist/src/__tests__/console.test.d.ts +1 -0
  8. package/dist/src/__tests__/console.test.js +29 -0
  9. package/dist/src/__tests__/console.test.js.map +1 -0
  10. package/dist/src/__tests__/utils.test.js +5 -1
  11. package/dist/src/__tests__/utils.test.js.map +1 -1
  12. package/dist/src/common.d.ts +1 -7
  13. package/dist/src/common.js +2 -14
  14. package/dist/src/common.js.map +1 -1
  15. package/dist/src/logPlugin.js +22 -17
  16. package/dist/src/logPlugin.js.map +1 -1
  17. package/dist/src/server.d.ts +21 -0
  18. package/dist/src/{Server.js → server.js} +47 -31
  19. package/dist/src/server.js.map +1 -0
  20. package/dist/src/utils.js +4 -4
  21. package/dist/src/utils.js.map +1 -1
  22. package/index.ts +3 -3
  23. package/package.json +59 -59
  24. package/src/HTTPInterceptor.ts +340 -339
  25. package/src/Server.ts +178 -167
  26. package/src/__mocks__/react-native/Libraries/Blob/FileReader.js +44 -44
  27. package/src/__mocks__/react-native/Libraries/Network/XHRInterceptor.js +39 -39
  28. package/src/__tests__/HTTPInterceptor.test.ts +322 -322
  29. package/src/__tests__/Server.test.ts +149 -149
  30. package/src/__tests__/utils.test.ts +113 -112
  31. package/src/common.ts +57 -70
  32. package/src/logPlugin.ts +231 -224
  33. package/src/logger.ts +14 -14
  34. package/src/utils.ts +112 -112
  35. package/tsconfig.json +26 -26
  36. package/dist/src/Server.d.ts +0 -20
  37. package/dist/src/Server.js.map +0 -1
@@ -1,150 +1,150 @@
1
- import Server from '../Server';
2
- import { sleep } from '../utils';
3
-
4
- // Mock dependencies
5
- jest.mock('../utils', () => {
6
- const actual = jest.requireActual('../utils');
7
- return {
8
- ...actual, // 保留所有真实实现
9
- sleep: jest.fn() // 只模拟 sleep 函数
10
- };
11
- });
12
-
13
-
14
- // Mock require for react-native-zeroconf
15
- jest.mock('react-native-zeroconf', () => undefined, { virtual: true });
16
-
17
- // Mock fetch
18
- global.fetch = jest.fn();
19
-
20
- describe('Server', () => {
21
- let server: Server;
22
-
23
- beforeEach(() => {
24
- // Clear all mocks before each test
25
- jest.clearAllMocks();
26
- (global.fetch as jest.Mock).mockReset();
27
- });
28
-
29
- describe('Constructor and URL Management', () => {
30
- it('should initialize with default values', () => {
31
- server = new Server();
32
- expect(server.getUrls()).toEqual([]);
33
- });
34
-
35
- it('should initialize with custom URL', () => {
36
- server = new Server('localhost:8080');
37
- expect(server.getUrls()).toEqual(['http://localhost:8080']);
38
- });
39
-
40
- it('should handle URLs with and without http prefix', () => {
41
- server = new Server();
42
- server.updateUrl('localhost:8080');
43
- expect(server.getUrls()).toEqual(['http://localhost:8080']);
44
-
45
- server.updateUrl('http://localhost:8080');
46
- expect(server.getUrls()).toEqual(['http://localhost:8080']);
47
- });
48
- });
49
-
50
- describe('ZeroConf Handling', () => {
51
- it('should handle case when zeroconf is not available', () => {
52
- server = new Server();
53
- const mockListener = jest.fn();
54
- server.addUrlsListener(mockListener);
55
-
56
- // Since Zeroconf is not available, the listener should not be called
57
- expect(mockListener).not.toHaveBeenCalled();
58
- });
59
-
60
- // Test with mock Zeroconf implementation
61
- it('should handle case when zeroconf is available', () => {
62
- // Temporarily mock require to return a mock Zeroconf implementation
63
- const mockZeroconfInstance = {
64
- on: jest.fn(),
65
- scan: jest.fn()
66
- };
67
-
68
- jest.doMock('react-native-zeroconf', () => ({
69
- __esModule: true,
70
- default: jest.fn(() => mockZeroconfInstance)
71
- }), { virtual: true });
72
-
73
- server = new Server();
74
- const mockListener = jest.fn();
75
- server.addUrlsListener(mockListener);
76
-
77
- // Verify that Zeroconf methods were not called since module is mocked as undefined
78
- expect(mockListener).not.toHaveBeenCalled();
79
- });
80
- });
81
-
82
- describe('Data Sending', () => {
83
- beforeEach(() => {
84
- server = new Server('localhost:8080');
85
- (global.fetch as jest.Mock).mockImplementation(() =>
86
- Promise.resolve({ ok: true })
87
- );
88
- });
89
-
90
- it('should send log data', async () => {
91
- const testData = { message: 'test log' };
92
- await server.log(testData);
93
-
94
- expect(global.fetch).toHaveBeenCalledWith(
95
- 'http://localhost:8080/log',
96
- expect.objectContaining({
97
- method: 'POST',
98
- headers: {
99
- 'Content-Type': 'application/json;charset=utf-8'
100
- },
101
- body: expect.any(String)
102
- })
103
- );
104
- });
105
-
106
- it('should send network data', async () => {
107
- const testData = { url: 'test.com' };
108
- await server.network(testData);
109
-
110
- expect(global.fetch).toHaveBeenCalledWith(
111
- 'http://localhost:8080/network',
112
- expect.objectContaining({
113
- method: 'POST',
114
- headers: {
115
- 'Content-Type': 'application/json;charset=utf-8'
116
- },
117
- body: expect.any(String)
118
- })
119
- );
120
- });
121
-
122
- it('should handle timeout', async () => {
123
- server.updateTimeout(100);
124
- (sleep as jest.Mock).mockImplementation(() => Promise.reject(new Error('Timeout')));
125
-
126
- const testData = { message: 'test' };
127
- await server.log(testData);
128
-
129
- expect(global.fetch).toHaveBeenCalled();
130
- expect(sleep).toHaveBeenCalledWith(100, true);
131
- });
132
- });
133
-
134
- describe('Base Data Management', () => {
135
- it('should update base data', async () => {
136
- server = new Server('localhost:8080');
137
- const baseData = { userId: '123' };
138
- server.updateBaseData(baseData);
139
-
140
- await server.log({ message: 'test' });
141
-
142
- expect(global.fetch).toHaveBeenCalledWith(
143
- expect.any(String),
144
- expect.objectContaining({
145
- body: expect.stringContaining('"userId":"123"')
146
- })
147
- );
148
- });
149
- });
1
+ import Server from '../Server';
2
+ import { sleep } from '../utils';
3
+
4
+ // Mock dependencies
5
+ jest.mock('../utils', () => {
6
+ const actual = jest.requireActual('../utils');
7
+ return {
8
+ ...actual, // 保留所有真实实现
9
+ sleep: jest.fn() // 只模拟 sleep 函数
10
+ };
11
+ });
12
+
13
+
14
+ // Mock require for react-native-zeroconf
15
+ jest.mock('react-native-zeroconf', () => undefined, { virtual: true });
16
+
17
+ // Mock fetch
18
+ global.fetch = jest.fn();
19
+
20
+ describe('Server', () => {
21
+ let server: Server;
22
+
23
+ beforeEach(() => {
24
+ // Clear all mocks before each test
25
+ jest.clearAllMocks();
26
+ (global.fetch as jest.Mock).mockReset();
27
+ });
28
+
29
+ describe('Constructor and URL Management', () => {
30
+ it('should initialize with default values', () => {
31
+ server = new Server();
32
+ expect(server.getBaseUrlArr()).toEqual(new Set([]));
33
+ });
34
+
35
+ it('should initialize with custom URL', () => {
36
+ server = new Server('localhost:8080');
37
+ expect(server.getBaseUrlArr()).toEqual(new Set(['http://localhost:8080']));
38
+ });
39
+
40
+ it('should handle URLs with and without http prefix', () => {
41
+ server = new Server();
42
+ server.updateUrl('localhost:8080');
43
+ expect(server.getBaseUrlArr()).toEqual(new Set(['http://localhost:8080']));
44
+
45
+ server.updateUrl('http://localhost:8080');
46
+ expect(server.getBaseUrlArr()).toEqual(new Set(['http://localhost:8080']));
47
+ });
48
+ });
49
+
50
+ describe('ZeroConf Handling', () => {
51
+ it('should handle case when zeroconf is not available', () => {
52
+ server = new Server();
53
+ const mockListener = jest.fn();
54
+ server.addUrlsListener(mockListener);
55
+
56
+ // Since Zeroconf is not available, the listener should not be called
57
+ expect(mockListener).not.toHaveBeenCalled();
58
+ });
59
+
60
+ // Test with mock Zeroconf implementation
61
+ it('should handle case when zeroconf is available', () => {
62
+ // Temporarily mock require to return a mock Zeroconf implementation
63
+ const mockZeroconfInstance = {
64
+ on: jest.fn(),
65
+ scan: jest.fn()
66
+ };
67
+
68
+ jest.doMock('react-native-zeroconf', () => ({
69
+ __esModule: true,
70
+ default: jest.fn(() => mockZeroconfInstance)
71
+ }), { virtual: true });
72
+
73
+ server = new Server();
74
+ const mockListener = jest.fn();
75
+ server.addUrlsListener(mockListener);
76
+
77
+ // Verify that Zeroconf methods were not called since module is mocked as undefined
78
+ expect(mockListener).not.toHaveBeenCalled();
79
+ });
80
+ });
81
+
82
+ describe('Data Sending', () => {
83
+ beforeEach(() => {
84
+ server = new Server('localhost:8080');
85
+ (global.fetch as jest.Mock).mockImplementation(() =>
86
+ Promise.resolve({ ok: true })
87
+ );
88
+ });
89
+
90
+ it('should send log data', async () => {
91
+ const testData = { message: 'test log' };
92
+ await server.log(testData);
93
+
94
+ expect(global.fetch).toHaveBeenCalledWith(
95
+ 'http://localhost:8080/log',
96
+ expect.objectContaining({
97
+ method: 'POST',
98
+ headers: {
99
+ 'Content-Type': 'application/json;charset=utf-8'
100
+ },
101
+ body: expect.any(String)
102
+ })
103
+ );
104
+ });
105
+
106
+ it('should send network data', async () => {
107
+ const testData = { url: 'test.com' };
108
+ await server.network(testData);
109
+
110
+ expect(global.fetch).toHaveBeenCalledWith(
111
+ 'http://localhost:8080/network',
112
+ expect.objectContaining({
113
+ method: 'POST',
114
+ headers: {
115
+ 'Content-Type': 'application/json;charset=utf-8'
116
+ },
117
+ body: expect.any(String)
118
+ })
119
+ );
120
+ });
121
+
122
+ it('should handle timeout', async () => {
123
+ server.updateTimeout(100);
124
+ (sleep as jest.Mock).mockImplementation(() => Promise.reject(new Error('Timeout')));
125
+
126
+ const testData = { message: 'test' };
127
+ await server.log(testData);
128
+
129
+ expect(global.fetch).toHaveBeenCalled();
130
+ expect(sleep).toHaveBeenCalledWith(100, true);
131
+ });
132
+ });
133
+
134
+ describe('Base Data Management', () => {
135
+ it('should update base data', async () => {
136
+ server = new Server('localhost:8080');
137
+ const baseData = { userId: '123' };
138
+ server.updateBaseData(baseData);
139
+
140
+ await server.log({ message: 'test' });
141
+
142
+ expect(global.fetch).toHaveBeenCalledWith(
143
+ expect.any(String),
144
+ expect.objectContaining({
145
+ body: expect.stringContaining('"userId":"123"')
146
+ })
147
+ );
148
+ });
149
+ });
150
150
  });
@@ -1,113 +1,114 @@
1
- import { createClassWithErrorHandling, hasPort } from '../utils';
2
-
3
- describe('createClassWithErrorHandling', () => {
4
- class TestClass {
5
- normalMethod(): string {
6
- return 'normal';
7
- }
8
-
9
- errorMethod(): void {
10
- throw new Error('Test error');
11
- }
12
-
13
- async asyncMethod(): Promise<string> {
14
- return 'async';
15
- }
16
-
17
- async asyncErrorMethod(): Promise<void> {
18
- throw new Error('Async test error');
19
- }
20
- }
21
-
22
- let consoleErrorSpy: jest.SpyInstance;
23
-
24
- beforeEach(() => {
25
- consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
26
- });
27
-
28
- afterEach(() => {
29
- consoleErrorSpy.mockRestore();
30
- });
31
-
32
- test('should not interfere with normal methods', () => {
33
- const EnhancedClass = createClassWithErrorHandling(TestClass);
34
- const instance = new EnhancedClass();
35
- expect(instance.normalMethod()).toBe('normal');
36
- });
37
-
38
- test('should catch and log errors from methods', () => {
39
- const EnhancedClass = createClassWithErrorHandling(TestClass);
40
- const instance = new EnhancedClass();
41
- expect(() => instance.errorMethod()).toThrow('Test error');
42
- expect(consoleErrorSpy).toHaveBeenCalledWith('Error in errorMethod:', expect.any(Error));
43
- });
44
-
45
- test('should not interfere with async methods that resolve', async () => {
46
- const EnhancedClass = createClassWithErrorHandling(TestClass);
47
- const instance = new EnhancedClass();
48
- await expect(instance.asyncMethod()).resolves.toBe('async');
49
- });
50
-
51
- test('should catch and log errors from async methods that reject', async () => {
52
- const EnhancedClass = createClassWithErrorHandling(TestClass);
53
- const instance = new EnhancedClass();
54
- await expect(instance.asyncErrorMethod()).rejects.toThrow('Async test error');
55
- expect(consoleErrorSpy).toHaveBeenCalledWith('Error in asyncErrorMethod:', expect.any(Error));
56
- });
57
-
58
- test('should handle methods added after instantiation', () => {
59
- const EnhancedClass = createClassWithErrorHandling(TestClass);
60
- const instance = new EnhancedClass();
61
- (instance as any).dynamicMethod = function(): void {
62
- throw new Error('Dynamic method error');
63
- };
64
- expect(() => (instance as any).dynamicMethod()).toThrow('Dynamic method error');
65
- expect(consoleErrorSpy).toHaveBeenCalledWith('Error in dynamicMethod:', expect.any(Error));
66
- });
67
- });
68
-
69
-
70
- describe('hasPort function', () => {
71
- test('should return true for URLs with explicit ports', () => {
72
- expect(hasPort('http://example.com:8080')).toBe(true);
73
- expect(hasPort('ftp://example.com:210')).toBe(true);
74
- });
75
-
76
- test('should return false for URLs without explicit ports', () => {
77
- expect(hasPort('http://example.com')).toBe(false);
78
- expect(hasPort('https://example.com')).toBe(false);
79
- expect(hasPort('ftp://example.com')).toBe(false);
80
- });
81
-
82
- test('should return false for invalid URLs', () => {
83
- expect(hasPort('not a url')).toBe(false);
84
- expect(hasPort('http:/example.com')).toBe(false);
85
- expect(hasPort('example.com:8080')).toBe(false);
86
- });
87
-
88
- test('should return false for empty input', () => {
89
- expect(hasPort('')).toBe(false);
90
- });
91
-
92
- test('should return false for non-string input', () => {
93
- expect(hasPort(null as any)).toBe(false);
94
- expect(hasPort(undefined as any)).toBe(false);
95
- expect(hasPort(123 as any)).toBe(false);
96
- expect(hasPort({} as any)).toBe(false);
97
- });
98
-
99
- test('should handle URLs with default ports correctly', () => {
100
- expect(hasPort('http://example.com:80')).toBe(false);
101
- expect(hasPort('https://example.com:443')).toBe(false);
102
- });
103
-
104
- test('should handle URLs with IPv6 addresses', () => {
105
- expect(hasPort('http://[2001:db8::1]:8080')).toBe(true);
106
- expect(hasPort('https://[2001:db8::1]')).toBe(false);
107
- });
108
-
109
- test('should handle URLs with userinfo', () => {
110
- expect(hasPort('http://user:pass@example.com:8080')).toBe(true);
111
- expect(hasPort('http://user:pass@example.com')).toBe(false);
112
- });
1
+ import logger from '../logger';
2
+ import { createClassWithErrorHandling, hasPort } from '../utils';
3
+
4
+ describe('createClassWithErrorHandling', () => {
5
+ class TestClass {
6
+ normalMethod(): string {
7
+ return 'normal';
8
+ }
9
+
10
+ errorMethod(): void {
11
+ throw new Error('Test error');
12
+ }
13
+
14
+ async asyncMethod(): Promise<string> {
15
+ return 'async';
16
+ }
17
+
18
+ async asyncErrorMethod(): Promise<void> {
19
+ throw new Error('Async test error');
20
+ }
21
+ }
22
+
23
+ let consoleErrorSpy: jest.SpyInstance;
24
+
25
+ beforeEach(() => {
26
+ consoleErrorSpy = jest.spyOn(logger, 'error').mockImplementation(() => {});
27
+ });
28
+
29
+ afterEach(() => {
30
+ consoleErrorSpy.mockRestore();
31
+ });
32
+
33
+ test('should not interfere with normal methods', () => {
34
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
35
+ const instance = new EnhancedClass();
36
+ expect(instance.normalMethod()).toBe('normal');
37
+ });
38
+
39
+ test('should catch and log errors from methods', () => {
40
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
41
+ const instance = new EnhancedClass();
42
+ expect(() => instance.errorMethod()).toThrow('Test error');
43
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error in errorMethod:', expect.any(Error));
44
+ });
45
+
46
+ test('should not interfere with async methods that resolve', async () => {
47
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
48
+ const instance = new EnhancedClass();
49
+ await expect(instance.asyncMethod()).resolves.toBe('async');
50
+ });
51
+
52
+ test('should catch and log errors from async methods that reject', async () => {
53
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
54
+ const instance = new EnhancedClass();
55
+ await expect(instance.asyncErrorMethod()).rejects.toThrow('Async test error');
56
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error in asyncErrorMethod:', expect.any(Error));
57
+ });
58
+
59
+ test('should handle methods added after instantiation', () => {
60
+ const EnhancedClass = createClassWithErrorHandling(TestClass);
61
+ const instance = new EnhancedClass();
62
+ (instance as any).dynamicMethod = function(): void {
63
+ throw new Error('Dynamic method error');
64
+ };
65
+ expect(() => (instance as any).dynamicMethod()).toThrow('Dynamic method error');
66
+ expect(consoleErrorSpy).toHaveBeenCalledWith('Error in dynamicMethod:', expect.any(Error));
67
+ });
68
+ });
69
+
70
+
71
+ describe('hasPort function', () => {
72
+ test('should return true for URLs with explicit ports', () => {
73
+ expect(hasPort('http://example.com:8080')).toBe(true);
74
+ expect(hasPort('ftp://example.com:210')).toBe(true);
75
+ });
76
+
77
+ test('should return false for URLs without explicit ports', () => {
78
+ expect(hasPort('http://example.com')).toBe(false);
79
+ expect(hasPort('https://example.com')).toBe(false);
80
+ expect(hasPort('ftp://example.com')).toBe(false);
81
+ });
82
+
83
+ test('should return false for invalid URLs', () => {
84
+ expect(hasPort('not a url')).toBe(false);
85
+ expect(hasPort('http:/example.com')).toBe(false);
86
+ expect(hasPort('example.com:8080')).toBe(false);
87
+ });
88
+
89
+ test('should return false for empty input', () => {
90
+ expect(hasPort('')).toBe(false);
91
+ });
92
+
93
+ test('should return false for non-string input', () => {
94
+ expect(hasPort(null as any)).toBe(false);
95
+ expect(hasPort(undefined as any)).toBe(false);
96
+ expect(hasPort(123 as any)).toBe(false);
97
+ expect(hasPort({} as any)).toBe(false);
98
+ });
99
+
100
+ test('should handle URLs with default ports correctly', () => {
101
+ expect(hasPort('http://example.com:80')).toBe(false);
102
+ expect(hasPort('https://example.com:443')).toBe(false);
103
+ });
104
+
105
+ test('should handle URLs with IPv6 addresses', () => {
106
+ expect(hasPort('http://[2001:db8::1]:8080')).toBe(true);
107
+ expect(hasPort('https://[2001:db8::1]')).toBe(false);
108
+ });
109
+
110
+ test('should handle URLs with userinfo', () => {
111
+ expect(hasPort('http://user:pass@example.com:8080')).toBe(true);
112
+ expect(hasPort('http://user:pass@example.com')).toBe(false);
113
+ });
113
114
  });
package/src/common.ts CHANGED
@@ -1,70 +1,57 @@
1
- import logger from "./logger";
2
-
3
- export const URLS_KEY = 'log-listener-plugin-urls$$key'
4
- export const DEFAULT_TIMEOUT = 3000
5
- export const LOG_KEY = '[@wutiange/log-listener-plugin 日志]'
6
- export enum Level {
7
- LOG = 'log',
8
- WARN = 'warn',
9
- ERROR = 'error',
10
- }
11
-
12
- export enum Tag {
13
- LOG_PLUGIN_INTERNAL_ERROR = 'log-plugin-internal-error',
14
- DEFAULT = 'default',
15
- }
16
-
17
- const getDefaultDeviceINfo = () => {
18
- try {
19
- const {Platform} = require('react-native')
20
- return {
21
- SystemName: Platform.OS,
22
- Version: Platform.Version,
23
- ...Platform.constants
24
- }
25
- } catch (error) {
26
- logger.warn(LOG_KEY, '这个插件只能在 react-native 中使用')
27
- return {}
28
- }
29
- }
30
-
31
- export const getBaseData = (): Record<string, string> => {
32
-
33
- try {
34
- const DeviceInfo = require("react-native-device-info")?.default;
35
- return {
36
- Brand: DeviceInfo.getBrand(),
37
- Model: DeviceInfo.getModel(),
38
- AppVersion: DeviceInfo.getVersion(),
39
- Carrier: DeviceInfo.getCarrierSync(),
40
- Manufacturer: DeviceInfo.getManufacturerSync(),
41
- SystemName: DeviceInfo.getSystemName(),
42
- ...getDefaultDeviceINfo()
43
- };
44
- } catch (error) {
45
- return getDefaultDeviceINfo()
46
- }
47
- }
48
-
49
- export const getDefaultStorage = (): Storage => {
50
- try {
51
- const AsyncStorage = require("@react-native-async-storage/async-storage")?.default;
52
- return AsyncStorage;
53
- } catch (error) {
54
- return null;
55
- }
56
- }
57
-
58
-
59
- export const getErrMsg = (error: any) => {
60
- return {
61
- message: [
62
- `${
63
- error?.message ?? error
64
- }--->这是@wutiange/log-listener-plugin内部错误,请提issue反馈,issue地址:https://github.com/wutiange/log-listener-plugin/issues`,
65
- ],
66
- tag: Tag.LOG_PLUGIN_INTERNAL_ERROR,
67
- level: Level.ERROR,
68
- createTime: Date.now(),
69
- }
70
- }
1
+ import logger from "./logger";
2
+
3
+ export const URLS_KEY = 'log-listener-plugin-urls$$SetKey'
4
+ export const DEFAULT_TIMEOUT = 3000
5
+ export const LOG_KEY = '[@wutiange/log-listener-plugin 日志]'
6
+ export enum Level {
7
+ LOG = 'log',
8
+ WARN = 'warn',
9
+ ERROR = 'error',
10
+ }
11
+
12
+ export enum Tag {
13
+ LOG_PLUGIN_INTERNAL_ERROR = 'log-plugin-internal-error',
14
+ DEFAULT = 'default',
15
+ }
16
+
17
+ const getDefaultDeviceINfo = () => {
18
+ try {
19
+ const {Platform} = require('react-native')
20
+ return {
21
+ SystemName: Platform.OS,
22
+ Version: Platform.Version,
23
+ ...Platform.constants
24
+ }
25
+ } catch (error) {
26
+ logger.warn(LOG_KEY, '这个插件只能在 react-native 中使用')
27
+ return {}
28
+ }
29
+ }
30
+
31
+ export const getBaseData = (): Record<string, string> => {
32
+
33
+ try {
34
+ const DeviceInfo = require("react-native-device-info")?.default;
35
+ return {
36
+ Brand: DeviceInfo.getBrand(),
37
+ Model: DeviceInfo.getModel(),
38
+ AppVersion: DeviceInfo.getVersion(),
39
+ Carrier: DeviceInfo.getCarrierSync(),
40
+ Manufacturer: DeviceInfo.getManufacturerSync(),
41
+ SystemName: DeviceInfo.getSystemName(),
42
+ ...getDefaultDeviceINfo()
43
+ };
44
+ } catch (error) {
45
+ return getDefaultDeviceINfo()
46
+ }
47
+ }
48
+
49
+ export const getDefaultStorage = (): Storage => {
50
+ try {
51
+ const AsyncStorage = require("@react-native-async-storage/async-storage")?.default;
52
+ return AsyncStorage;
53
+ } catch (error) {
54
+ return null;
55
+ }
56
+ }
57
+