plugin-sensitive-filter-xr 0.0.1 → 0.0.2
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 +6 -1
- package/dist/lib/sensitiveFilter.d.ts.map +1 -1
- package/dist/lib/sensitiveFilter.js +45 -18
- package/dist/lib/types.d.ts +22 -6
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +20 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,13 +39,18 @@ type GeneralPackConfig = {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
type SensitiveFilterConfig = {
|
|
42
|
-
rules
|
|
42
|
+
rules: Array<Partial<SensitiveRule> | null>; // 必填,且至少 1 条业务规则
|
|
43
43
|
generalPack?: GeneralPackConfig;
|
|
44
44
|
caseSensitive?: boolean; // default false
|
|
45
45
|
normalize?: boolean; // default true
|
|
46
46
|
};
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
业务规则字段约束:
|
|
50
|
+
- 必填:`pattern`、`type`、`action`
|
|
51
|
+
- 条件必填:当 `action='rewrite'` 时,`replacementText` 必填
|
|
52
|
+
- 可选:`id`(留空自动生成)、`scope`(默认 `both`)、`severity`(默认 `medium`)
|
|
53
|
+
|
|
49
54
|
## 通用规则包(General Pack)
|
|
50
55
|
|
|
51
56
|
- `enabled=false`:不启用通用规则
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sensitiveFilter.d.ts","sourceRoot":"","sources":["../../src/lib/sensitiveFilter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAEvD,OAAO,EACL,eAAe,EAEf,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACf,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAGL,qBAAqB,EAKtB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"sensitiveFilter.d.ts","sourceRoot":"","sources":["../../src/lib/sensitiveFilter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAEvD,OAAO,EACL,eAAe,EAEf,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACf,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAGL,qBAAqB,EAKtB,MAAM,YAAY,CAAA;AA6QnB,qBAEa,yBAA0B,YAAW,wBAAwB,CAAC,qBAAqB,CAAC;IAC/F,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAgKlC;IAED,gBAAgB,CACd,OAAO,EAAE,qBAAqB,EAC9B,QAAQ,EAAE,uBAAuB,GAChC,cAAc,CAAC,eAAe,CAAC;CA4GnC;AAED,YAAY,EAAE,qBAAqB,EAAE,CAAA"}
|
|
@@ -166,9 +166,9 @@ function rewriteModelRequestInput(request, rewrittenText) {
|
|
|
166
166
|
}
|
|
167
167
|
function normalizeRuleDrafts(input) {
|
|
168
168
|
const rules = [];
|
|
169
|
-
for (const draft of input) {
|
|
169
|
+
for (const [index, draft] of input.entries()) {
|
|
170
170
|
if (!isRecord(draft)) {
|
|
171
|
-
|
|
171
|
+
throw new Error(`Invalid rule at index ${index}: rule must be an object`);
|
|
172
172
|
}
|
|
173
173
|
const id = toNonEmptyString(draft['id']);
|
|
174
174
|
const pattern = toNonEmptyString(draft['pattern']);
|
|
@@ -177,31 +177,38 @@ function normalizeRuleDrafts(input) {
|
|
|
177
177
|
const severity = toNonEmptyString(draft['severity']);
|
|
178
178
|
const action = toNonEmptyString(draft['action']);
|
|
179
179
|
const replacementText = toNonEmptyString(draft['replacementText']) ?? undefined;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
continue;
|
|
180
|
+
if (!pattern) {
|
|
181
|
+
throw new Error(`Invalid rule at index ${index}: pattern is required`);
|
|
183
182
|
}
|
|
184
|
-
if (!
|
|
185
|
-
|
|
183
|
+
if (!type) {
|
|
184
|
+
throw new Error(`Invalid rule at index ${index}: type is required`);
|
|
185
|
+
}
|
|
186
|
+
if (!action) {
|
|
187
|
+
throw new Error(`Invalid rule at index ${index}: action is required`);
|
|
188
|
+
}
|
|
189
|
+
if (action === 'rewrite' && !replacementText) {
|
|
190
|
+
throw new Error(`Invalid rule at index ${index}: replacementText is required when action is rewrite`);
|
|
186
191
|
}
|
|
187
192
|
if (!['keyword', 'regex'].includes(type)) {
|
|
188
|
-
|
|
193
|
+
throw new Error(`Invalid rule at index ${index}: unsupported type '${type}'`);
|
|
189
194
|
}
|
|
190
|
-
|
|
191
|
-
|
|
195
|
+
const normalizedScope = scope ?? 'both';
|
|
196
|
+
if (!['input', 'output', 'both'].includes(normalizedScope)) {
|
|
197
|
+
throw new Error(`Invalid rule at index ${index}: unsupported scope '${normalizedScope}'`);
|
|
192
198
|
}
|
|
193
|
-
|
|
194
|
-
|
|
199
|
+
const normalizedSeverity = severity ?? 'medium';
|
|
200
|
+
if (!['high', 'medium'].includes(normalizedSeverity)) {
|
|
201
|
+
throw new Error(`Invalid rule at index ${index}: unsupported severity '${normalizedSeverity}'`);
|
|
195
202
|
}
|
|
196
203
|
if (!['block', 'rewrite'].includes(action)) {
|
|
197
|
-
|
|
204
|
+
throw new Error(`Invalid rule at index ${index}: unsupported action '${action}'`);
|
|
198
205
|
}
|
|
199
206
|
rules.push({
|
|
200
|
-
id
|
|
207
|
+
id: id ?? `rule-${index + 1}`,
|
|
201
208
|
pattern,
|
|
202
209
|
type,
|
|
203
|
-
scope,
|
|
204
|
-
severity,
|
|
210
|
+
scope: normalizedScope,
|
|
211
|
+
severity: normalizedSeverity,
|
|
205
212
|
action,
|
|
206
213
|
replacementText,
|
|
207
214
|
});
|
|
@@ -243,6 +250,10 @@ let SensitiveFilterMiddleware = class SensitiveFilterMiddleware {
|
|
|
243
250
|
id: {
|
|
244
251
|
type: 'string',
|
|
245
252
|
title: { en_US: 'Rule ID', zh_Hans: '规则标识' },
|
|
253
|
+
description: {
|
|
254
|
+
en_US: 'Optional. Auto-generated when empty.',
|
|
255
|
+
zh_Hans: '可选。留空时系统自动生成。',
|
|
256
|
+
},
|
|
246
257
|
},
|
|
247
258
|
pattern: {
|
|
248
259
|
type: 'string',
|
|
@@ -295,10 +306,26 @@ let SensitiveFilterMiddleware = class SensitiveFilterMiddleware {
|
|
|
295
306
|
},
|
|
296
307
|
replacementText: {
|
|
297
308
|
type: 'string',
|
|
298
|
-
title: { en_US: 'Replacement Text', zh_Hans: '
|
|
309
|
+
title: { en_US: 'Replacement Text', zh_Hans: '替换文本(rewrite 必填)' },
|
|
299
310
|
},
|
|
300
311
|
},
|
|
312
|
+
required: ['pattern', 'type', 'action'],
|
|
313
|
+
allOf: [
|
|
314
|
+
{
|
|
315
|
+
if: {
|
|
316
|
+
properties: {
|
|
317
|
+
action: {
|
|
318
|
+
const: 'rewrite',
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
then: {
|
|
323
|
+
required: ['replacementText'],
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
],
|
|
301
327
|
},
|
|
328
|
+
minItems: 1,
|
|
302
329
|
},
|
|
303
330
|
generalPack: {
|
|
304
331
|
type: 'object',
|
|
@@ -356,7 +383,7 @@ let SensitiveFilterMiddleware = class SensitiveFilterMiddleware {
|
|
|
356
383
|
const config = parsed.data;
|
|
357
384
|
const caseSensitive = config.caseSensitive ?? false;
|
|
358
385
|
const normalize = config.normalize ?? true;
|
|
359
|
-
const customRules = normalizeRuleDrafts(config.rules
|
|
386
|
+
const customRules = normalizeRuleDrafts(config.rules);
|
|
360
387
|
const generalRules = resolveGeneralPackRules(config.generalPack);
|
|
361
388
|
const allRules = [...customRules, ...generalRules];
|
|
362
389
|
const compiledRules = allRules.map((rule, index) => {
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type GeneralPackConfig = {
|
|
|
13
13
|
profile?: 'strict' | 'balanced';
|
|
14
14
|
};
|
|
15
15
|
export type SensitiveFilterConfig = {
|
|
16
|
-
rules
|
|
16
|
+
rules: Array<Partial<SensitiveRule> | null>;
|
|
17
17
|
generalPack?: GeneralPackConfig;
|
|
18
18
|
caseSensitive?: boolean;
|
|
19
19
|
normalize?: boolean;
|
|
@@ -26,13 +26,13 @@ export type CompiledSensitiveRule = SensitiveRule & {
|
|
|
26
26
|
};
|
|
27
27
|
export declare const SensitiveFilterIcon = "<svg width=\"800px\" height=\"800px\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12 2l7 3v6c0 5.2-3.3 9.9-7 11-3.7-1.1-7-5.8-7-11V5l7-3zm0 2.1L7 6v5c0 3.9 2.3 7.8 5 8.9 2.7-1.1 5-5 5-8.9V6l-5-1.9zM8.8 12.6l1.4-1.4 1.8 1.8 3.8-3.8 1.4 1.4-5.2 5.2-3.2-3.2z\"/></svg>";
|
|
28
28
|
export declare const sensitiveFilterConfigSchema: z.ZodObject<{
|
|
29
|
-
rules: z.
|
|
29
|
+
rules: z.ZodArray<z.ZodNullable<z.ZodEffects<z.ZodObject<{
|
|
30
30
|
id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
31
|
-
pattern: z.
|
|
32
|
-
type: z.
|
|
31
|
+
pattern: z.ZodString;
|
|
32
|
+
type: z.ZodEnum<["keyword", "regex"]>;
|
|
33
33
|
scope: z.ZodNullable<z.ZodOptional<z.ZodEnum<["input", "output", "both"]>>>;
|
|
34
34
|
severity: z.ZodNullable<z.ZodOptional<z.ZodEnum<["high", "medium"]>>>;
|
|
35
|
-
action: z.
|
|
35
|
+
action: z.ZodEnum<["block", "rewrite"]>;
|
|
36
36
|
replacementText: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
37
37
|
}, "strip", z.ZodTypeAny, {
|
|
38
38
|
id?: string;
|
|
@@ -50,7 +50,23 @@ export declare const sensitiveFilterConfigSchema: z.ZodObject<{
|
|
|
50
50
|
severity?: "high" | "medium";
|
|
51
51
|
action?: "block" | "rewrite";
|
|
52
52
|
replacementText?: string;
|
|
53
|
-
}
|
|
53
|
+
}>, {
|
|
54
|
+
id?: string;
|
|
55
|
+
pattern?: string;
|
|
56
|
+
type?: "keyword" | "regex";
|
|
57
|
+
scope?: "input" | "output" | "both";
|
|
58
|
+
severity?: "high" | "medium";
|
|
59
|
+
action?: "block" | "rewrite";
|
|
60
|
+
replacementText?: string;
|
|
61
|
+
}, {
|
|
62
|
+
id?: string;
|
|
63
|
+
pattern?: string;
|
|
64
|
+
type?: "keyword" | "regex";
|
|
65
|
+
scope?: "input" | "output" | "both";
|
|
66
|
+
severity?: "high" | "medium";
|
|
67
|
+
action?: "block" | "rewrite";
|
|
68
|
+
replacementText?: string;
|
|
69
|
+
}>>, "many">;
|
|
54
70
|
generalPack: z.ZodOptional<z.ZodObject<{
|
|
55
71
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
56
72
|
profile: z.ZodOptional<z.ZodDefault<z.ZodEnum<["strict", "balanced"]>>>;
|
package/dist/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAE1B,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;IACzB,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAA;IAC3B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAA;AAE1B,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;IACzB,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAA;IAClC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAA;IAC3B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,CAAA;IAC3C,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,eAAO,MAAM,mBAAmB,wSAA8R,CAAA;AAoD9T,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKtC,CAAA;AAYF,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,aAAa,EAAE,CA6CnF"}
|
package/dist/lib/types.js
CHANGED
|
@@ -18,12 +18,28 @@ const OPEN_SOURCE_LEXICON = {
|
|
|
18
18
|
const sensitiveRuleDraftSchema = z
|
|
19
19
|
.object({
|
|
20
20
|
id: z.string().optional().nullable(),
|
|
21
|
-
pattern: z.string()
|
|
22
|
-
type: z.enum(['keyword', 'regex'])
|
|
21
|
+
pattern: z.string(),
|
|
22
|
+
type: z.enum(['keyword', 'regex']),
|
|
23
23
|
scope: z.enum(['input', 'output', 'both']).optional().nullable(),
|
|
24
24
|
severity: z.enum(['high', 'medium']).optional().nullable(),
|
|
25
|
-
action: z.enum(['block', 'rewrite'])
|
|
25
|
+
action: z.enum(['block', 'rewrite']),
|
|
26
26
|
replacementText: z.string().optional().nullable(),
|
|
27
|
+
})
|
|
28
|
+
.superRefine((value, ctx) => {
|
|
29
|
+
if (!value.pattern?.trim()) {
|
|
30
|
+
ctx.addIssue({
|
|
31
|
+
code: z.ZodIssueCode.custom,
|
|
32
|
+
path: ['pattern'],
|
|
33
|
+
message: 'pattern is required',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (value.action === 'rewrite' && !value.replacementText?.trim()) {
|
|
37
|
+
ctx.addIssue({
|
|
38
|
+
code: z.ZodIssueCode.custom,
|
|
39
|
+
path: ['replacementText'],
|
|
40
|
+
message: 'replacementText is required when action is rewrite',
|
|
41
|
+
});
|
|
42
|
+
}
|
|
27
43
|
})
|
|
28
44
|
.nullable();
|
|
29
45
|
const generalPackSchema = z.object({
|
|
@@ -31,7 +47,7 @@ const generalPackSchema = z.object({
|
|
|
31
47
|
profile: z.enum(['strict', 'balanced']).default('balanced').optional(),
|
|
32
48
|
});
|
|
33
49
|
export const sensitiveFilterConfigSchema = z.object({
|
|
34
|
-
rules: z.array(sensitiveRuleDraftSchema).
|
|
50
|
+
rules: z.array(sensitiveRuleDraftSchema).min(1, 'at least one business rule is required'),
|
|
35
51
|
generalPack: generalPackSchema.optional(),
|
|
36
52
|
caseSensitive: z.boolean().optional().default(false),
|
|
37
53
|
normalize: z.boolean().optional().default(true),
|