reqwise-core 1.0.0 → 1.1.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/README.md +71 -0
- package/dist/index.d.mts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +81 -31
- package/dist/index.mjs +199 -38
- package/package.json +28 -25
- package/.turbo/turbo-build.log +0 -26
- package/dist/chunk-DKID2ES7.mjs +0 -96
- package/dist/chunk-DKID2ES7.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/storage-P7DHGOZ3.mjs +0 -19
- package/dist/storage-P7DHGOZ3.mjs.map +0 -1
- package/public/banner.png +0 -0
- package/public/logo.png +0 -0
- package/src/banner.b64.txt +0 -1
- package/src/client.ts +0 -163
- package/src/filter.ts +0 -96
- package/src/i18n.ts +0 -843
- package/src/images.ts +0 -2
- package/src/index.ts +0 -24
- package/src/panel.ts +0 -446
- package/src/renderer.ts +0 -574
- package/src/storage.ts +0 -102
- package/src/styles.ts +0 -730
- package/src/types.ts +0 -59
- package/tsconfig.json +0 -15
- package/tsup.config.ts +0 -9
package/src/client.ts
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { ReqwiseEntry, ReqwiseConfig, RequestConfig } from './types'
|
|
2
|
-
import storage from './storage'
|
|
3
|
-
import filter from './filter'
|
|
4
|
-
import i18n from './i18n'
|
|
5
|
-
|
|
6
|
-
const START_TS = Symbol('reqwise_start_ts')
|
|
7
|
-
|
|
8
|
-
let cfg: ReqwiseConfig = {
|
|
9
|
-
theme: 'dark',
|
|
10
|
-
placement: 'right',
|
|
11
|
-
defaultOpen: false,
|
|
12
|
-
enabled: true,
|
|
13
|
-
maxItems: 200,
|
|
14
|
-
persistHistory: true,
|
|
15
|
-
defaultLang: 'en',
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function initClient(c?: Partial<ReqwiseConfig>) {
|
|
19
|
-
if (c) cfg = { ...(cfg || {}), ...c }
|
|
20
|
-
storage.initStorage(cfg)
|
|
21
|
-
filter.setConfig(cfg)
|
|
22
|
-
if (c && c.defaultLang) i18n.setLanguage(c.defaultLang)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function makeId(): string {
|
|
26
|
-
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 9)}`
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function buildEntry(base: Partial<ReqwiseEntry>): ReqwiseEntry {
|
|
30
|
-
return {
|
|
31
|
-
id: base.id || makeId(),
|
|
32
|
-
source: base.source || 'auto',
|
|
33
|
-
page: base.page || (typeof location !== 'undefined' ? location.href : 'unknown'),
|
|
34
|
-
timestamp: base.timestamp || new Date().toISOString(),
|
|
35
|
-
method: (base.method || 'GET') as any,
|
|
36
|
-
url: base.url || '',
|
|
37
|
-
params: base.params,
|
|
38
|
-
requestHeaders: base.requestHeaders,
|
|
39
|
-
requestBody: base.requestBody,
|
|
40
|
-
status: base.status,
|
|
41
|
-
statusText: base.statusText,
|
|
42
|
-
responseHeaders: base.responseHeaders,
|
|
43
|
-
responseBody: base.responseBody,
|
|
44
|
-
duration: base.duration,
|
|
45
|
-
error: base.error,
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function recordPartial(entry: Partial<ReqwiseEntry>) {
|
|
50
|
-
const e = buildEntry(entry)
|
|
51
|
-
storage.saveEntry(e)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Axios adapter (optional)
|
|
55
|
-
export function wrapAxios(instance: any) {
|
|
56
|
-
if (!instance || typeof instance.interceptors !== 'object') return
|
|
57
|
-
|
|
58
|
-
instance.interceptors.request.use((req: any) => {
|
|
59
|
-
try {
|
|
60
|
-
(req as any)[START_TS] = Date.now()
|
|
61
|
-
} catch (e) {}
|
|
62
|
-
return req
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
instance.interceptors.response.use(
|
|
66
|
-
(res: any) => {
|
|
67
|
-
try {
|
|
68
|
-
const req = res.config || {}
|
|
69
|
-
const start = req[START_TS] || Date.now()
|
|
70
|
-
const duration = Date.now() - start
|
|
71
|
-
const entry = buildEntry({
|
|
72
|
-
method: (req.method || 'GET').toUpperCase(),
|
|
73
|
-
url: req.url || req.baseURL || '',
|
|
74
|
-
requestHeaders: filter.maskHeaders(req.headers),
|
|
75
|
-
requestBody: filter.maskFields(req.data),
|
|
76
|
-
status: res.status,
|
|
77
|
-
statusText: res.statusText,
|
|
78
|
-
responseHeaders: filter.maskHeaders(res.headers),
|
|
79
|
-
responseBody: filter.maskFields(res.data),
|
|
80
|
-
duration,
|
|
81
|
-
})
|
|
82
|
-
if (!filter.shouldIgnore(entry.url)) storage.saveEntry(entry)
|
|
83
|
-
} catch (e) {}
|
|
84
|
-
return res
|
|
85
|
-
},
|
|
86
|
-
(err: any) => {
|
|
87
|
-
try {
|
|
88
|
-
const req = err?.config || {}
|
|
89
|
-
const start = req[START_TS] || Date.now()
|
|
90
|
-
const duration = Date.now() - start
|
|
91
|
-
const response = err?.response || {}
|
|
92
|
-
const entry = buildEntry({
|
|
93
|
-
method: (req.method || 'GET').toUpperCase(),
|
|
94
|
-
url: req.url || req.baseURL || '',
|
|
95
|
-
requestHeaders: filter.maskHeaders(req.headers),
|
|
96
|
-
requestBody: filter.maskFields(req.data),
|
|
97
|
-
status: response.status,
|
|
98
|
-
statusText: response.statusText,
|
|
99
|
-
responseHeaders: filter.maskHeaders(response.headers),
|
|
100
|
-
responseBody: filter.maskFields(response.data),
|
|
101
|
-
duration,
|
|
102
|
-
error: { message: err.message || 'Error' },
|
|
103
|
-
})
|
|
104
|
-
if (!filter.shouldIgnore(entry.url)) storage.saveEntry(entry)
|
|
105
|
-
} catch (e) {}
|
|
106
|
-
return Promise.reject(err)
|
|
107
|
-
}
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Fetch wrapper
|
|
112
|
-
export async function fetchWithRecord(input: RequestInfo, init?: RequestInit & RequestConfig) {
|
|
113
|
-
const url = typeof input === 'string' ? input : String((input as Request).url || '')
|
|
114
|
-
if (filter.shouldIgnore(url)) return fetch(input, init)
|
|
115
|
-
const start = Date.now()
|
|
116
|
-
try {
|
|
117
|
-
const res = await fetch(input, init as any)
|
|
118
|
-
const cloned = res.clone()
|
|
119
|
-
let body: any = null
|
|
120
|
-
try {
|
|
121
|
-
body = await cloned.json().catch(() => cloned.text())
|
|
122
|
-
} catch (e) {
|
|
123
|
-
body = undefined
|
|
124
|
-
}
|
|
125
|
-
const duration = Date.now() - start
|
|
126
|
-
const headers: Record<string, string> = {}
|
|
127
|
-
res.headers.forEach((v, k) => (headers[k] = v))
|
|
128
|
-
const entry = buildEntry({
|
|
129
|
-
method: (init?.method || 'GET') as any,
|
|
130
|
-
url,
|
|
131
|
-
requestHeaders: filter.maskHeaders((init && (init.headers as any)) || {}),
|
|
132
|
-
requestBody: filter.maskFields(init && (init as any).body),
|
|
133
|
-
status: res.status,
|
|
134
|
-
statusText: res.statusText,
|
|
135
|
-
responseHeaders: filter.maskHeaders(headers),
|
|
136
|
-
responseBody: filter.maskFields(body),
|
|
137
|
-
duration,
|
|
138
|
-
})
|
|
139
|
-
storage.saveEntry(entry)
|
|
140
|
-
return res
|
|
141
|
-
} catch (err: any) {
|
|
142
|
-
const duration = Date.now() - start
|
|
143
|
-
const entry = buildEntry({
|
|
144
|
-
method: (init?.method || 'GET') as any,
|
|
145
|
-
url,
|
|
146
|
-
requestHeaders: filter.maskHeaders((init && (init.headers as any)) || {}),
|
|
147
|
-
requestBody: filter.maskFields(init && (init as any).body),
|
|
148
|
-
duration,
|
|
149
|
-
error: { message: err?.message || String(err) },
|
|
150
|
-
})
|
|
151
|
-
storage.saveEntry(entry)
|
|
152
|
-
throw err
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const ReqwiseClient = {
|
|
157
|
-
init: initClient,
|
|
158
|
-
wrapAxios,
|
|
159
|
-
fetch: fetchWithRecord,
|
|
160
|
-
record: recordPartial,
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export default ReqwiseClient
|
package/src/filter.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { ReqwiseConfig } from './types'
|
|
2
|
-
|
|
3
|
-
let cfg: Partial<ReqwiseConfig> = {}
|
|
4
|
-
|
|
5
|
-
let ignorePatterns: string[] = [
|
|
6
|
-
'node_modules',
|
|
7
|
-
'.map',
|
|
8
|
-
'.css',
|
|
9
|
-
'.png',
|
|
10
|
-
'.jpg',
|
|
11
|
-
'chrome-extension:',
|
|
12
|
-
]
|
|
13
|
-
|
|
14
|
-
let maskHeaderKeys: string[] = ['authorization', 'cookie']
|
|
15
|
-
let maskFieldKeys: string[] = ['password', 'token', 'secret']
|
|
16
|
-
|
|
17
|
-
function normalizeKey(k: string) {
|
|
18
|
-
return String(k || '').toLowerCase()
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function patternToRegExp(p: string): RegExp {
|
|
22
|
-
// simple heuristic: if contains * treat as wildcard, otherwise escape and match substring
|
|
23
|
-
if (p.includes('*')) {
|
|
24
|
-
const esc = p.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\\\*/g, '.*')
|
|
25
|
-
return new RegExp(esc)
|
|
26
|
-
}
|
|
27
|
-
try {
|
|
28
|
-
return new RegExp(p)
|
|
29
|
-
} catch (e) {
|
|
30
|
-
// fallback to substring
|
|
31
|
-
return new RegExp(p.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function setConfig(c: Partial<ReqwiseConfig>) {
|
|
36
|
-
cfg = { ...cfg, ...c }
|
|
37
|
-
if (c.ignore) ignorePatterns = c.ignore.slice()
|
|
38
|
-
if (c.maskHeaders) maskHeaderKeys = c.maskHeaders.slice()
|
|
39
|
-
if (c.maskFields) maskFieldKeys = c.maskFields.slice()
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function addIgnorePattern(p: string) {
|
|
43
|
-
ignorePatterns.push(p)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function removeIgnorePattern(p: string) {
|
|
47
|
-
ignorePatterns = ignorePatterns.filter(x => x !== p)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function shouldIgnore(url: string): boolean {
|
|
51
|
-
if (!url) return true
|
|
52
|
-
for (const p of ignorePatterns) {
|
|
53
|
-
const re = patternToRegExp(p)
|
|
54
|
-
if (re.test(url)) return true
|
|
55
|
-
if (url.indexOf(p) !== -1) return true
|
|
56
|
-
}
|
|
57
|
-
return false
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function maskHeaders(headers?: Record<string, string> | null): Record<string, string> | undefined {
|
|
61
|
-
if (!headers) return undefined
|
|
62
|
-
const out: Record<string, string> = {}
|
|
63
|
-
for (const k of Object.keys(headers)) {
|
|
64
|
-
const nk = normalizeKey(k)
|
|
65
|
-
if (maskHeaderKeys.includes(nk)) out[k] = '****'
|
|
66
|
-
else out[k] = headers[k] as string
|
|
67
|
-
}
|
|
68
|
-
return out
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function maskObject(obj: any): any {
|
|
72
|
-
if (obj === null || obj === undefined) return obj
|
|
73
|
-
if (typeof obj !== 'object') return obj
|
|
74
|
-
if (Array.isArray(obj)) return obj.map(maskObject)
|
|
75
|
-
const out: any = {}
|
|
76
|
-
for (const k of Object.keys(obj)) {
|
|
77
|
-
const nk = normalizeKey(k)
|
|
78
|
-
if (maskFieldKeys.includes(nk)) out[k] = '****'
|
|
79
|
-
else out[k] = maskObject(obj[k])
|
|
80
|
-
}
|
|
81
|
-
return out
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export function maskFields(payload?: any) {
|
|
85
|
-
if (payload === undefined) return payload
|
|
86
|
-
return maskObject(payload)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export default {
|
|
90
|
-
setConfig,
|
|
91
|
-
addIgnorePattern,
|
|
92
|
-
removeIgnorePattern,
|
|
93
|
-
shouldIgnore,
|
|
94
|
-
maskHeaders,
|
|
95
|
-
maskFields,
|
|
96
|
-
}
|