@wutiange/log-listener-plugin 1.2.3 → 1.3.0-alpha.0

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 (83) hide show
  1. package/dist/console.js +14 -15
  2. package/dist/console.js.map +1 -1
  3. package/dist/fetch.js +28 -28
  4. package/dist/fetch.js.map +1 -1
  5. package/dist/index.d.ts +2 -23
  6. package/dist/index.js +2 -117
  7. package/dist/index.js.map +1 -1
  8. package/dist/packages/network-logger/Logger.d.ts +28 -0
  9. package/dist/packages/network-logger/Logger.js +192 -0
  10. package/dist/packages/network-logger/Logger.js.map +1 -0
  11. package/dist/packages/network-logger/NetworkRequestInfo.d.ts +36 -0
  12. package/dist/packages/network-logger/NetworkRequestInfo.js +129 -0
  13. package/dist/packages/network-logger/NetworkRequestInfo.js.map +1 -0
  14. package/dist/packages/network-logger/constant.d.ts +2 -0
  15. package/dist/packages/network-logger/constant.js +6 -0
  16. package/dist/packages/network-logger/constant.js.map +1 -0
  17. package/dist/packages/network-logger/types.d.ts +14 -0
  18. package/dist/packages/network-logger/types.js +3 -0
  19. package/dist/packages/network-logger/types.js.map +1 -0
  20. package/dist/packages/network-logger/utils/debounce.d.ts +2 -0
  21. package/dist/packages/network-logger/utils/debounce.js +20 -0
  22. package/dist/packages/network-logger/utils/debounce.js.map +1 -0
  23. package/dist/packages/network-logger/utils/extractHost.d.ts +2 -0
  24. package/dist/packages/network-logger/utils/extractHost.js +9 -0
  25. package/dist/packages/network-logger/utils/extractHost.js.map +1 -0
  26. package/dist/packages/network-logger/utils/fromEntries.d.ts +2 -0
  27. package/dist/packages/network-logger/utils/fromEntries.js +8 -0
  28. package/dist/packages/network-logger/utils/fromEntries.js.map +1 -0
  29. package/dist/packages/network-logger/utils/logger.d.ts +1 -0
  30. package/dist/packages/network-logger/utils/logger.js +6 -0
  31. package/dist/packages/network-logger/utils/logger.js.map +1 -0
  32. package/dist/src/CompatibilityManager.d.ts +27 -0
  33. package/dist/src/CompatibilityManager.js +74 -0
  34. package/dist/src/CompatibilityManager.js.map +1 -0
  35. package/dist/src/__tests__/console.test.d.ts +1 -0
  36. package/dist/{__tests__ → src/__tests__}/console.test.js +2 -2
  37. package/dist/src/__tests__/console.test.js.map +1 -0
  38. package/dist/src/common.js.map +1 -0
  39. package/dist/src/console.d.ts +1 -0
  40. package/dist/src/console.js +20 -0
  41. package/dist/src/console.js.map +1 -0
  42. package/dist/src/fetch.d.ts +1 -0
  43. package/dist/src/fetch.js +48 -0
  44. package/dist/src/fetch.js.map +1 -0
  45. package/dist/src/index.d.ts +2 -0
  46. package/dist/src/index.js +8 -0
  47. package/dist/src/index.js.map +1 -0
  48. package/dist/src/logPlugin.d.ts +32 -0
  49. package/dist/src/logPlugin.js +187 -0
  50. package/dist/src/logPlugin.js.map +1 -0
  51. package/dist/{server.d.ts → src/server.d.ts} +1 -1
  52. package/dist/{server.js → src/server.js} +14 -8
  53. package/dist/src/server.js.map +1 -0
  54. package/dist/src/utils.d.ts +3 -0
  55. package/dist/src/utils.js +38 -0
  56. package/dist/src/utils.js.map +1 -0
  57. package/package.json +13 -5
  58. package/packages/network-logger/Logger.ts +274 -0
  59. package/packages/network-logger/NetworkRequestInfo.ts +133 -0
  60. package/packages/network-logger/constant.ts +3 -0
  61. package/packages/network-logger/types.ts +36 -0
  62. package/packages/network-logger/utils/debounce.ts +21 -0
  63. package/packages/network-logger/utils/extractHost.ts +7 -0
  64. package/packages/network-logger/utils/fromEntries.ts +7 -0
  65. package/packages/network-logger/utils/logger.ts +2 -0
  66. package/src/CompatibilityManager.ts +64 -0
  67. package/src/__tests__/console.test.ts +2 -2
  68. package/src/common.ts +2 -3
  69. package/src/logPlugin.ts +229 -0
  70. package/src/server.ts +28 -23
  71. package/src/utils.ts +38 -0
  72. package/dist/__tests__/console.test.d.ts +0 -1
  73. package/dist/__tests__/console.test.js.map +0 -1
  74. package/dist/common.js.map +0 -1
  75. package/dist/server.js.map +0 -1
  76. package/dist/utils.d.ts +0 -1
  77. package/dist/utils.js +0 -14
  78. package/dist/utils.js.map +0 -1
  79. package/src/console.ts +0 -19
  80. package/src/fetch.ts +0 -35
  81. package/src/index.ts +0 -131
  82. /package/dist/{common.d.ts → src/common.d.ts} +0 -0
  83. /package/dist/{common.js → src/common.js} +0 -0
@@ -0,0 +1,133 @@
1
+ // @ts-ignore
2
+ import BlobFileReader from 'react-native/Libraries/Blob/FileReader';
3
+ import type {Headers, NetworkRequestInfoRow, RequestMethod} from './types';
4
+ import fromEntries from './utils/fromEntries';
5
+
6
+ export default class NetworkRequestInfo {
7
+ id = '';
8
+ type = '';
9
+ url = '';
10
+ method: RequestMethod;
11
+ status: number = -1;
12
+ dataSent = '';
13
+ responseContentType = '';
14
+ responseSize = 0;
15
+ requestHeaders: Headers = {};
16
+ responseHeaders: Headers = {};
17
+ response = '';
18
+ responseURL = '';
19
+ responseType = '';
20
+ timeout = 0;
21
+ closeReason = '';
22
+ messages = '';
23
+ serverClose: any = undefined;
24
+ serverError: any = undefined;
25
+ startTime: number = 0;
26
+ endTime: number = 0;
27
+ gqlOperation?: string;
28
+ updatedAt: number = 0;
29
+
30
+ constructor(id: string, type: string, method: RequestMethod, url: string) {
31
+ this.id = id;
32
+ this.type = type;
33
+ this.method = method;
34
+ this.url = url;
35
+ this.updatedAt = Date.now();
36
+ }
37
+
38
+ get duration() {
39
+ return this.endTime - this.startTime;
40
+ }
41
+
42
+ get curlRequest() {
43
+ let headersPart =
44
+ this.requestHeaders &&
45
+ Object.entries(this.requestHeaders)
46
+ .map(([key, value]) => `'${key}: ${this.escapeQuotes(value)}'`)
47
+ .join(' -H ');
48
+ headersPart = headersPart ? `-H ${headersPart}` : '';
49
+
50
+ const body = this.dataSent && this.escapeQuotes(this.dataSent);
51
+
52
+ const methodPart =
53
+ this.method !== 'GET' ? `-X${this.method.toUpperCase()}` : '';
54
+ const bodyPart = body ? `-d '${body}'` : '';
55
+
56
+ const parts = ['curl', methodPart, headersPart, bodyPart, `'${this.url}'`];
57
+
58
+ return parts.filter(Boolean).join(' ');
59
+ }
60
+
61
+ update(values: Partial<NetworkRequestInfo>) {
62
+ Object.assign(this, values);
63
+ if (values.dataSent) {
64
+ const data = this.parseData(values.dataSent);
65
+ this.gqlOperation = data?.operationName;
66
+ }
67
+ this.updatedAt = Date.now();
68
+ }
69
+
70
+ private escapeQuotes(value: string) {
71
+ return value.replace?.(/'/g, "\\'");
72
+ }
73
+
74
+ private parseData(data: any) {
75
+ try {
76
+ if (data?._parts?.length) {
77
+ return fromEntries(data?._parts);
78
+ }
79
+ return JSON.parse(data);
80
+ } catch (e) {
81
+ return {data};
82
+ }
83
+ }
84
+
85
+ private stringifyFormat(data: any) {
86
+ return JSON.stringify(this.parseData(data), null, 2);
87
+ }
88
+
89
+ public toRow(): NetworkRequestInfoRow {
90
+ return {
91
+ url: this.url,
92
+ gqlOperation: this.gqlOperation,
93
+ id: this.id,
94
+ method: this.method,
95
+ status: this.status,
96
+ duration: this.duration,
97
+ startTime: this.startTime,
98
+ };
99
+ }
100
+
101
+ getRequestBody(replaceEscaped = false) {
102
+ const body = this.stringifyFormat(this.dataSent);
103
+
104
+ if (replaceEscaped) {
105
+ return body.replace(/\\n/g, '\n').replace(/\\"/g, '"');
106
+ }
107
+
108
+ return body;
109
+ }
110
+
111
+ private async parseResponseBlob() {
112
+ const blobReader = new BlobFileReader();
113
+ blobReader.readAsText(this.response);
114
+
115
+ return await new Promise<string>((resolve, reject) => {
116
+ const handleError = () => reject(blobReader.error);
117
+
118
+ blobReader.addEventListener('load', () => {
119
+ resolve(blobReader.result);
120
+ });
121
+ blobReader.addEventListener('error', handleError);
122
+ blobReader.addEventListener('abort', handleError);
123
+ });
124
+ }
125
+
126
+ async getResponseBody() {
127
+ const body = await (this.responseType !== 'blob'
128
+ ? this.response
129
+ : this.parseResponseBlob());
130
+
131
+ return this.stringifyFormat(body);
132
+ }
133
+ }
@@ -0,0 +1,3 @@
1
+ // StartNetworkLoggingOptions
2
+ export const LOGGER_MAX_REQUESTS: number = 500;
3
+ export const LOGGER_REFRESH_RATE: number = 50;
@@ -0,0 +1,36 @@
1
+ import NetworkRequestInfo from './NetworkRequestInfo';
2
+
3
+ export type Headers = {[header: string]: string};
4
+ export type RequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
5
+ export type StartNetworkLoggingOptions = {
6
+ /**
7
+ * Max number of requests to keep before overwriting
8
+ * @default 500
9
+ */
10
+ maxRequests?: number;
11
+ /** List of hosts to ignore, e.g. `services.test.com` */
12
+ ignoredHosts?: string[];
13
+ /** List of urls to ignore, e.g. `https://services.test.com/test` */
14
+ ignoredUrls?: string[];
15
+ /**
16
+ * List of url patterns to ignore, e.g. `/^GET https://test.com\/pages\/.*$/`
17
+ *
18
+ * Url to match with is in the format: `${method} ${url}`, e.g. `GET https://test.com/pages/123`
19
+ */
20
+ ignoredPatterns?: RegExp[];
21
+ /**
22
+ * Force the network logger to start even if another program is using the network interceptor
23
+ * e.g. a dev/debuging program
24
+ */
25
+ forceEnable?: boolean;
26
+ /**
27
+ * Refresh rate of the logger in milliseconds
28
+ * @default 50
29
+ */
30
+ refreshRate?: number;
31
+ };
32
+
33
+ export type NetworkRequestInfoRow = Pick<
34
+ NetworkRequestInfo,
35
+ 'url' | 'gqlOperation' | 'id' | 'method' | 'status' | 'duration' | 'startTime'
36
+ >;
@@ -0,0 +1,21 @@
1
+ // https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore#_debounce
2
+ function debounce(func: Function, wait: number, immediate: boolean = false) {
3
+ let timeout: ReturnType<typeof setTimeout> | undefined;
4
+ return function () {
5
+ const args = arguments;
6
+ clearTimeout(timeout);
7
+ // @ts-ignore
8
+ if (immediate && !timeout) {
9
+ func.apply(this, args);
10
+ }
11
+ timeout = setTimeout(function () {
12
+ timeout = undefined;
13
+ // @ts-ignore
14
+ if (!immediate) {
15
+ func.apply(this, args);
16
+ }
17
+ }, wait);
18
+ };
19
+ }
20
+
21
+ export default debounce;
@@ -0,0 +1,7 @@
1
+ const extractHost = (url: string) => {
2
+ const host = url.split('//')[1]?.split(':')[0]?.split('/')[0] || undefined;
3
+
4
+ return host;
5
+ };
6
+
7
+ export default extractHost;
@@ -0,0 +1,7 @@
1
+ const fromEntries = (arr: any[]) =>
2
+ arr.reduce((acc, [k, v]) => {
3
+ acc[k] = v;
4
+ return acc;
5
+ }, {});
6
+
7
+ export default fromEntries;
@@ -0,0 +1,2 @@
1
+ export const warn = (message: string) =>
2
+ console.warn(`react-native-network-logger: ${message}`);
@@ -0,0 +1,64 @@
1
+ import NetworkRequestInfo from "../packages/network-logger/NetworkRequestInfo";
2
+
3
+ class CompatibilityManager {
4
+ private static requestInfoObj: Record<string, NetworkRequestInfo> = {}
5
+ static async interceptionToNetwork(data: NetworkRequestInfo[]) {
6
+ const tempWillSendArr: NetworkRequestInfo[] = []
7
+ if (Object.keys(CompatibilityManager.requestInfoObj).length === 0) {
8
+ CompatibilityManager.requestInfoObj = data.reduce((e, c) => {
9
+ if (c.endTime) {
10
+ return e
11
+ }
12
+ return {...e, [c.id]: c}
13
+ }, {})
14
+ tempWillSendArr.concat(data)
15
+ } else {
16
+ data.forEach(e => {
17
+ const tempObj = CompatibilityManager.requestInfoObj
18
+ if (!(e.id in tempObj)) {
19
+ tempWillSendArr.push(e)
20
+ if (!e.endTime) {
21
+ CompatibilityManager.requestInfoObj[e.id] = e
22
+ }
23
+ return
24
+ }
25
+ if (e.id in tempObj && e.endTime) {
26
+ tempWillSendArr.push(e)
27
+ delete CompatibilityManager.requestInfoObj[e.id]
28
+ return
29
+ }
30
+ })
31
+ }
32
+
33
+ // 将要发送的数据转换成兼容的数据
34
+ return CompatibilityManager.asyncSwapSendArr(tempWillSendArr)
35
+ }
36
+
37
+ private static async asyncSwapSendArr(data: NetworkRequestInfo[]) {
38
+ const asyncTempArr = await Promise.all(data.map(async (e) => {
39
+ if (e.endTime) {
40
+ return {
41
+ headers: e.responseHeaders,
42
+ body: await e.getResponseBody(),
43
+ requestId: e.id,
44
+ statusCode: e.status,
45
+ endTime: e.endTime,
46
+ };
47
+ } else {
48
+ return {
49
+ url: e.url,
50
+ id: e.id,
51
+ method: e.method,
52
+ headers: e.requestHeaders,
53
+ body: e.getRequestBody(),
54
+ createTime: e.startTime,
55
+ };
56
+ }
57
+ }));
58
+
59
+ return asyncTempArr;
60
+ }
61
+ }
62
+
63
+
64
+ export default CompatibilityManager
@@ -1,5 +1,5 @@
1
- import '../console'
2
- import logger from '../index'
1
+ import '../../console'
2
+ import logger from '../../index'
3
3
  describe("重写日志", () => {
4
4
  it("log 没有提前设置 url", () => {
5
5
  console.log("log 是否正常打印")
package/src/common.ts CHANGED
@@ -1,5 +1,4 @@
1
- export const [log, warn, error] = [console.log, console.warn, console.error]
2
-
1
+ export const [log, warn, error] = [console.log, console.warn, console.error];
3
2
 
4
3
  // @ts-ignore
5
- export const tempFetch = global.fetch as typeof fetch
4
+ export const tempFetch = global.fetch as typeof fetch;
@@ -0,0 +1,229 @@
1
+ import Server from './server';
2
+ import Logger from '../packages/network-logger/Logger';
3
+ import NetworkRequestInfo from '../packages/network-logger/NetworkRequestInfo';
4
+ import { extractDomain } from './utils';
5
+ import CompatibilityManager from './CompatibilityManager';
6
+
7
+ class LogPlugin {
8
+ private server: Server | null = null;
9
+ private baseData: Record<string, any> = {};
10
+ private timeout: number | null = null;
11
+ private networkLogger = new Logger();
12
+ private host = '';
13
+ private isAuto = false
14
+
15
+ auto() {
16
+ if (this.host) {
17
+ this.startRecordNetwork();
18
+ this.startRecordLog();
19
+ }
20
+ this.isAuto = true
21
+ }
22
+
23
+ unAuto() {
24
+ this.stopRecordLog()
25
+ this.networkLogger.disableXHRInterception()
26
+ this.isAuto = false
27
+ }
28
+
29
+ startRecordLog() {
30
+ const common = require('./common')
31
+ console.log = (...data: any[]) => {
32
+ this.log(...data);
33
+ common.log(...data);
34
+ };
35
+
36
+ console.warn = (...data: any[]) => {
37
+ this.warn(...data);
38
+ common.warn(...data);
39
+ };
40
+
41
+ console.error = (...data: any[]) => {
42
+ this.error(...data);
43
+ common.error(...data);
44
+ };
45
+ }
46
+
47
+ stopRecordLog() {
48
+ const common = require('./common')
49
+ console.log = common.log
50
+ console.warn = common.warn
51
+ console.error = common.error
52
+ }
53
+
54
+ startRecordNetwork() {
55
+ this.networkLogger.setCallback(async (data: NetworkRequestInfo[]) => {
56
+ const sendData = await CompatibilityManager.interceptionToNetwork(data);
57
+ sendData.forEach(e => {
58
+ this.server?.network({
59
+ ...this.baseData,
60
+ ...e
61
+ });
62
+ })
63
+ });
64
+
65
+ this.networkLogger.enableXHRInterception({
66
+ ignoredHosts: [extractDomain(this.host)],
67
+ });
68
+ }
69
+
70
+ setBaseUrl(url: string) {
71
+ if (!url?.trim()) {
72
+ this.networkLogger.disableXHRInterception()
73
+ this.stopRecordLog()
74
+ return
75
+ }
76
+ this.host = url.includes("http") ? url : `http://${url}`;
77
+ if (this.server) {
78
+ this.server.updateUrl(url);
79
+ } else {
80
+ this.server = new Server(url);
81
+ }
82
+ if (this.isAuto) {
83
+ this.startRecordNetwork();
84
+ this.startRecordLog()
85
+ }
86
+ }
87
+
88
+ /**
89
+ * @deprecated 不需要手动上报,日志插件会自动收集日志
90
+ */
91
+ setTimeout(timeout: number) {
92
+ if (typeof timeout === 'number') {
93
+ this.timeout = timeout;
94
+ this.server?.updateTimeout(this.timeout);
95
+ }
96
+ }
97
+
98
+ /**
99
+ * @deprecated 不需要手动上报,日志插件会自动收集日志
100
+ */
101
+ getTimeout() {
102
+ if (typeof this.timeout === 'number') {
103
+ return this.timeout;
104
+ }
105
+ return null;
106
+ }
107
+
108
+ setBaseData(data: Record<string, any> = {}) {
109
+ this.baseData = data;
110
+ }
111
+
112
+ private _log(level: string, tag: string, ...data: any[]) {
113
+ const sendData = {
114
+ ...this.baseData,
115
+ message: data,
116
+ tag,
117
+ level: level ?? 'log',
118
+ createTime: Date.now(),
119
+ };
120
+ this.server?.log(sendData);
121
+ }
122
+
123
+ tag(tag: string, ...data: any[]) {
124
+ this._log('log', tag, ...data);
125
+ }
126
+
127
+ log(...data: any[]) {
128
+ this._log('log', 'default', ...data);
129
+ }
130
+
131
+ warn(...data: any[]) {
132
+ this._log('warn', 'default', ...data);
133
+ }
134
+
135
+ error(...data: any[]) {
136
+ this._log('error', 'default', ...data);
137
+ }
138
+
139
+ /**
140
+ * @deprecated 不需要手动上报,日志插件会自动收集日志
141
+ */
142
+ async uniqueReq(
143
+ uniqueId: string | undefined,
144
+ input: RequestInfo | URL,
145
+ init?: RequestInit
146
+ ) {
147
+ let url: string | null = null;
148
+ let method = init?.method ?? 'get';
149
+ let headers = init?.headers;
150
+ let body = init?.body;
151
+ if (input instanceof Request) {
152
+ url = input.url;
153
+ method = input.method ?? 'get';
154
+ headers = (input.headers as Record<string, any>).map;
155
+ body = input.body;
156
+ } else if (input instanceof URL) {
157
+ url = input.href;
158
+ } else {
159
+ url = input;
160
+ }
161
+ return this.server?.network({
162
+ ...this.baseData,
163
+ url,
164
+ id: uniqueId,
165
+ method,
166
+ headers,
167
+ body,
168
+ createTime: Date.now(),
169
+ });
170
+ }
171
+
172
+ private async _res(uniqueId?: string, id?: number, response?: Response) {
173
+ const body = await response?.text();
174
+ return this.server?.network({
175
+ ...this.baseData,
176
+ headers: (response?.headers as Record<string, any>).map,
177
+ body,
178
+ requestId: uniqueId ?? Number(id),
179
+ statusCode: response?.status,
180
+ endTime: Date.now(),
181
+ });
182
+ }
183
+
184
+ /**
185
+ * @deprecated 不需要手动上报,日志插件会自动收集日志
186
+ */
187
+ async resTimeout(uniqueId: string) {
188
+ return this.server?.network({
189
+ ...this.baseData,
190
+ isTimeout: true,
191
+ requestId: uniqueId,
192
+ });
193
+ }
194
+
195
+ /**
196
+ * @deprecated 不需要手动上报,日志插件会自动收集日志
197
+ */
198
+ async resResponseError(uniqueId: string) {
199
+ return this.server?.network({
200
+ ...this.baseData,
201
+ isResponseError: true,
202
+ requestId: uniqueId,
203
+ });
204
+ }
205
+
206
+ /**
207
+ * @deprecated 不需要手动上报,日志插件会自动收集日志
208
+ */
209
+ async uniqueRes(uniqueId: string, response?: Response) {
210
+ return this._res(uniqueId, undefined, response);
211
+ }
212
+
213
+ /**
214
+ * @deprecated 不需要手动上报,日志插件会自动收集日志
215
+ */
216
+ async req(input: RequestInfo | URL, init?: RequestInit) {
217
+ return this.uniqueReq(undefined, input, init);
218
+ }
219
+
220
+ /**
221
+ * @deprecated 不需要手动上报,日志插件会自动收集日志
222
+ */
223
+ async res(id: number, response?: Response) {
224
+ return this._res(undefined, id, response);
225
+ }
226
+ }
227
+ const logPlugin = new LogPlugin();
228
+ export { LogPlugin };
229
+ export default logPlugin;
package/src/server.ts CHANGED
@@ -1,61 +1,66 @@
1
- import { sleep } from "./utils";
2
-
1
+ import {hasPort, sleep} from './utils';
2
+ const DEFAULT_PORT = 27751
3
3
  class Server {
4
4
  private baseUrl = '';
5
- private port = 27751
6
5
  private timeout: number;
7
6
 
8
-
9
7
  constructor(url: string, timeout: number = 3000) {
10
- this.updateUrl(url)
11
- this.timeout = timeout
8
+ this.updateUrl(url);
9
+ this.timeout = timeout;
12
10
  }
13
11
 
14
12
  updateTimeout(timeout = 3000) {
15
- this.timeout = timeout
13
+ this.timeout = timeout;
14
+ }
15
+
16
+ private getPort() {
17
+ if (hasPort(this.baseUrl)) {
18
+ return ''
19
+ }
20
+ return DEFAULT_PORT;
16
21
  }
17
22
 
18
23
  private async send(path: string, data: Record<string, any>) {
19
24
  try {
20
25
  if (!this.baseUrl) {
21
- return null
26
+ return null;
22
27
  }
23
- const common = await import('./common.js')
28
+ const common = require('./common');
24
29
  const result = await Promise.race([
25
- common.tempFetch(`${this.baseUrl}:${this.port}/${path}`, {
30
+ common.tempFetch(`${this.baseUrl}:${this.getPort()}/${path}`, {
26
31
  method: 'POST',
27
32
  headers: {
28
- 'Content-Type': 'application/json;charset=utf-8'
33
+ 'Content-Type': 'application/json;charset=utf-8',
29
34
  },
30
35
  body: JSON.stringify(data, (_, val) => {
31
36
  if (val instanceof Error) {
32
- return val.toString()
37
+ return val.toString();
33
38
  }
34
- return val
35
- })
39
+ return val;
40
+ }),
36
41
  }),
37
- sleep(this.timeout, true)
38
- ])
42
+ sleep(this.timeout, true),
43
+ ]);
39
44
  if (result instanceof Response) {
40
- return result.text()
45
+ return result.text();
41
46
  }
42
- return null
47
+ return null;
43
48
  } catch (error) {
44
- return null
49
+ return null;
45
50
  }
46
51
  }
47
52
 
48
53
  updateUrl(url: string) {
49
- this.baseUrl = url
54
+ this.baseUrl = url;
50
55
  }
51
56
 
52
57
  async log(data: Record<string, any>) {
53
- return this.send("log", data)
58
+ return this.send('log', data);
54
59
  }
55
60
 
56
61
  async network(data: Record<string, any>) {
57
- return this.send("network", data)
62
+ return this.send('network', data);
58
63
  }
59
64
  }
60
65
 
61
- export default Server
66
+ export default Server;
package/src/utils.ts CHANGED
@@ -7,3 +7,41 @@ export function sleep(ms: number, isReject: boolean = false) {
7
7
  }) : resolve, ms)
8
8
  })
9
9
  }
10
+
11
+ export function extractDomain(url: string) {
12
+ // 如果 url 是空的或不是字符串,直接返回
13
+ if (!url || typeof url !== 'string') {
14
+ return url;
15
+ }
16
+
17
+ // 使用正则表达式匹配 URL
18
+ const match = url.match(/^(https?:\/\/)?([^/:]+)/i);
19
+
20
+ // 如果没有匹配到,返回原始输入
21
+ if (!match) {
22
+ return url;
23
+ }
24
+
25
+ // 返回匹配到的域名部分
26
+ return match[2];
27
+ }
28
+
29
+
30
+ export function hasPort(url: string) {
31
+ // 如果 url 是空的或不是字符串,返回 false
32
+ if (!url || typeof url !== 'string') {
33
+ return false;
34
+ }
35
+
36
+ try {
37
+ // 使用 URL 构造函数解析 URL
38
+ const parsedUrl = new URL(url);
39
+
40
+ // 检查 port 属性是否为空
41
+ // 注意:如果使用默认端口(如 HTTP 的 80 或 HTTPS 的 443),port 会是空字符串
42
+ return parsedUrl.port !== '';
43
+ } catch (error) {
44
+ // 如果 URL 无效,捕获错误并返回 false
45
+ return false;
46
+ }
47
+ }
@@ -1 +0,0 @@
1
- import '../console';
@@ -1 +0,0 @@
1
- {"version":3,"file":"console.test.js","sourceRoot":"","sources":["../../src/__tests__/console.test.ts"],"names":[],"mappings":";;;;;AAAA,sBAAmB;AACnB,qDAA6B;AAC7B,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;IACpB,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACzB,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,eAAe,EAAE,GAAG,EAAE;QACvB,eAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAA;QAC3C,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACzB,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACd,eAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAA;QAC3C,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;QAC3B,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACf,eAAM,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAA;QAC3C,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;QAC7B,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":";;;;AAAa,KAAqB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAA9D,WAAG,UAAE,YAAI,UAAE,aAAK,SAA8C;AAI/D,QAAA,SAAS,GAAG,MAAM,CAAC,KAAqB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,mCAAgC;AAEhC,MAAM,MAAM;IAMV,YAAY,GAAW,EAAE,UAAkB,IAAI;QALvC,YAAO,GAAG,EAAE,CAAC;QACb,SAAI,GAAG,KAAK,CAAA;QAKlB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACnB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,aAAa,CAAC,OAAO,GAAG,IAAI;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAEa,IAAI,CAAC,IAAY,EAAE,IAAyB;;YACxD,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,IAAI,CAAA;gBACb,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;gBAC1C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;oBAChC,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE;wBACvD,MAAM,EAAE,MAAM;wBACd,OAAO,EAAE;4BACP,cAAc,EAAE,gCAAgC;yBACjD;wBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;4BACpC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;gCACzB,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAA;4BACvB,CAAC;4BACD,OAAO,GAAG,CAAA;wBACZ,CAAC,CAAC;qBACH,CAAC;oBACF,IAAA,aAAK,EAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC;iBAC1B,CAAC,CAAA;gBACF,IAAI,MAAM,YAAY,QAAQ,EAAE,CAAC;oBAC/B,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;gBACtB,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;KAAA;IAED,SAAS,CAAC,GAAW;QACnB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAA;IACpB,CAAC;IAEK,GAAG,CAAC,IAAyB;;YACjC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC/B,CAAC;KAAA;IAEK,OAAO,CAAC,IAAyB;;YACrC,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QACnC,CAAC;KAAA;CACF;AAED,kBAAe,MAAM,CAAA"}
package/dist/utils.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare function sleep(ms: number, isReject?: boolean): Promise<unknown>;