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

Sign up to get free protection for your applications and to get access to all the features.
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>;