whistle.interceptors 0.0.4 → 0.0.5

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/public/index.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="./vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Vite + Svelte + TS</title>
8
- <script type="module" crossorigin src="./assets/index-ZlpNVKm2.js"></script>
9
- <link rel="stylesheet" crossorigin href="./assets/index-BWNZu5u4.css">
8
+ <script type="module" crossorigin src="./assets/index-B6ysER9Q.js"></script>
9
+ <link rel="stylesheet" crossorigin href="./assets/index-B49r7c_G.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="app"></div>
package/src/server.ts CHANGED
@@ -36,22 +36,52 @@ function handleAndMode({conditions, payload, res, req, options, extra}: {
36
36
  origin: string
37
37
  }
38
38
  }) {
39
- const isMatch = conditions.every((condition) => {
40
- const { key, value, enabled } = condition
41
- return enabled && payload[key] && payload[key] === value
42
- })
39
+ let allMatch = true;
40
+ let firstMatchingCondition: any = null;
41
+ let firstMatchingIndex = -1;
42
+
43
+ // 检查所有条件是否都匹配
44
+ for (let i = 0; i < conditions.length; i++) {
45
+ const condition = conditions[i];
46
+ if (!condition.enabled) continue;
47
+
48
+ // 检查所有key-value对是否都匹配
49
+ const isMatch = condition.pairs.every(pair =>
50
+ pair.key && pair.value && payload[pair.key] === pair.value
51
+ );
52
+
53
+ if (!isMatch) {
54
+ allMatch = false;
55
+ break;
56
+ }
57
+
58
+ if (firstMatchingCondition === null) {
59
+ firstMatchingCondition = condition;
60
+ firstMatchingIndex = i;
61
+ }
62
+ }
43
63
 
44
- if (!isMatch) {
64
+ if (!allMatch) {
45
65
  return true
46
66
  }
47
67
 
48
- res.setHeader('whistle-plugin', 'whistle.interceptors');
49
- res.setHeader('Content-Type', 'application/json; charset=UTF-8');
50
- res.setHeader('Access-Control-Allow-Origin', extra.origin);
51
- res.setHeader('Access-Control-Allow-Credentials', 'true');
52
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With')
53
- res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE,HEAD')
54
- res.end(conditions[0].response)
68
+ if (firstMatchingCondition?.proxyMode === PROXY_MODE.NETWORK) {
69
+ req.getSession(session => {
70
+ // 以condition为维度保存结果
71
+ const conditionId = `${firstMatchingCondition.ruleId}_${firstMatchingIndex}`;
72
+ // @ts-ignore
73
+ options.localStorage.setProperty(`${LOCAL_PREFIX}_${conditionId}`, session.res.body)
74
+ })
75
+ return true
76
+ } else {
77
+ res.setHeader('whistle-plugin', 'whistle.interceptors');
78
+ res.setHeader('Content-Type', 'application/json; charset=UTF-8');
79
+ res.setHeader('Access-Control-Allow-Origin', extra.origin);
80
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
81
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With')
82
+ res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE,HEAD')
83
+ res.end(firstMatchingCondition?.response || conditions[0].response)
84
+ }
55
85
 
56
86
  }
57
87
 
@@ -65,20 +95,36 @@ function handleOrMode({conditions, payload, res, req, options, extra}: {
65
95
  origin: string
66
96
  }
67
97
  }) {
68
- const matchingCondition = conditions.find(
69
- ({ key, value, enabled }) => enabled && payload[key] === value
70
- );
71
- console.log('matchCondition', matchingCondition)
98
+ let matchingCondition: any = null;
99
+ let matchingIndex = -1;
100
+
101
+ // 查找匹配的条件及其索引
102
+ for (let i = 0; i < conditions.length; i++) {
103
+ const condition = conditions[i];
104
+ if (!condition.enabled) continue;
105
+
106
+ // 检查所有key-value对是否都匹配
107
+ const isMatch = condition.pairs.every(pair =>
108
+ pair.key && pair.value && payload[pair.key] === pair.value
109
+ );
110
+
111
+ if (isMatch) {
112
+ matchingCondition = condition;
113
+ matchingIndex = i;
114
+ break;
115
+ }
116
+ }
117
+
72
118
  if (!matchingCondition) {
73
119
  return true
74
120
  }
75
121
 
76
122
  if (matchingCondition.proxyMode === PROXY_MODE.NETWORK) {
77
123
  req.getSession(session => {
124
+ // 以condition为维度保存结果
125
+ const conditionId = `${matchingCondition.ruleId}_${matchingIndex}`;
78
126
  // @ts-ignore
79
- console.log('返回内容', session.res.body)
80
- // @ts-ignore
81
- options.localStorage.setProperty(`${LOCAL_PREFIX}_${matchingCondition.ruleId}_${matchingCondition.key}_${matchingCondition.value}`, session.res.body)
127
+ options.localStorage.setProperty(`${LOCAL_PREFIX}_${conditionId}`, session.res.body)
82
128
  })
83
129
  return true
84
130
  } else {
@@ -131,22 +177,24 @@ export default (server: Whistle.PluginServer, options: Whistle.PluginOptions) =>
131
177
  const id = req.originalReq.ruleValue
132
178
  const rules: Rule[] = JSON.parse(options.storage.getProperty(LOCAL_PREFIX)) || []
133
179
  const targetRule = rules.filter((rule: Rule) => rule.id === id)[0]
134
- const { matchType, method, conditions } = targetRule.config
135
180
 
136
- if (req.method !== method) {
181
+ if (!targetRule) {
137
182
  req.passThrough();
138
183
  return
139
184
  }
140
-
185
+
186
+
187
+ const { conditions } = targetRule.config
188
+
141
189
  let payLoad: Record<string, string>
142
- if (method === 'POST') {
190
+ if (req.method === 'POST' || req.method === 'PUT' || req.method === 'PATCH') {
143
191
  payLoad = await getBody(req)
144
- }
145
-
146
- if (method === 'GET') {
192
+ } else {
147
193
  // @ts-ignore
148
194
  payLoad = parseQuery(options.parseUrl(req.fullUrl).query)
149
195
  }
196
+
197
+ const matchType = 'or'
150
198
 
151
199
  handleMatchMode({
152
200
  matchType,
@@ -161,15 +209,4 @@ export default (server: Whistle.PluginServer, options: Whistle.PluginOptions) =>
161
209
  }
162
210
  });
163
211
 
164
- // handle websocket request
165
- server.on('upgrade', (req: Whistle.PluginServerRequest, socket: Whistle.PluginServerSocket) => {
166
- // do something
167
- req.passThrough();
168
- });
169
-
170
- // handle tunnel request
171
- server.on('connect', (req: Whistle.PluginServerRequest, socket: Whistle.PluginServerSocket) => {
172
- // do something
173
- req.passThrough();
174
- });
175
212
  };
package/src/types/rule.ts CHANGED
@@ -1,13 +1,15 @@
1
+ export interface KeyValuePair {
2
+ key: string;
3
+ value: string;
4
+ }
5
+
1
6
  export interface Rule {
2
7
  id: string;
3
8
  name: string;
4
9
  config: {
5
- method: 'GET' | 'POST' | 'PUT' | 'DELETE';
6
- matchType: 'and' | 'or';
7
10
  conditions: {
8
11
  ruleId: string;
9
- key: string;
10
- value: string;
12
+ pairs: KeyValuePair[];
11
13
  response: string;
12
14
  enabled?: boolean;
13
15
  remark?: string;