@zhin.js/plugin-content-moderation 1.0.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.
- package/README.md +173 -0
- package/lib/bypass.d.ts +10 -0
- package/lib/bypass.d.ts.map +1 -0
- package/lib/bypass.js +27 -0
- package/lib/bypass.js.map +1 -0
- package/lib/config.d.ts +5 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +184 -0
- package/lib/config.js.map +1 -0
- package/lib/engine.d.ts +40 -0
- package/lib/engine.d.ts.map +1 -0
- package/lib/engine.js +170 -0
- package/lib/engine.js.map +1 -0
- package/lib/extract.d.ts +18 -0
- package/lib/extract.d.ts.map +1 -0
- package/lib/extract.js +121 -0
- package/lib/extract.js.map +1 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/lib/providers/builtin-lexicon.d.ts +15 -0
- package/lib/providers/builtin-lexicon.d.ts.map +1 -0
- package/lib/providers/builtin-lexicon.js +133 -0
- package/lib/providers/builtin-lexicon.js.map +1 -0
- package/lib/providers/http.d.ts +14 -0
- package/lib/providers/http.d.ts.map +1 -0
- package/lib/providers/http.js +191 -0
- package/lib/providers/http.js.map +1 -0
- package/lib/providers/local-lexicon.d.ts +28 -0
- package/lib/providers/local-lexicon.d.ts.map +1 -0
- package/lib/providers/local-lexicon.js +129 -0
- package/lib/providers/local-lexicon.js.map +1 -0
- package/lib/providers/registry.d.ts +8 -0
- package/lib/providers/registry.d.ts.map +1 -0
- package/lib/providers/registry.js +24 -0
- package/lib/providers/registry.js.map +1 -0
- package/lib/providers/types.d.ts +6 -0
- package/lib/providers/types.d.ts.map +1 -0
- package/lib/providers/types.js +2 -0
- package/lib/providers/types.js.map +1 -0
- package/lib/redact.d.ts +18 -0
- package/lib/redact.d.ts.map +1 -0
- package/lib/redact.js +102 -0
- package/lib/redact.js.map +1 -0
- package/lib/types.d.ts +105 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +26 -0
- package/lib/types.js.map +1 -0
- package/middlewares/inbound.js +97 -0
- package/middlewares/inbound.ts +112 -0
- package/middlewares/outbound.js +53 -0
- package/middlewares/outbound.ts +66 -0
- package/package.json +81 -0
- package/plugin.js +8 -0
- package/schema.json +240 -0
- package/src/bypass.ts +38 -0
- package/src/config.ts +203 -0
- package/src/engine.ts +220 -0
- package/src/extract.ts +155 -0
- package/src/index.ts +49 -0
- package/src/providers/builtin-lexicon.ts +149 -0
- package/src/providers/http.ts +225 -0
- package/src/providers/local-lexicon.ts +148 -0
- package/src/providers/registry.ts +37 -0
- package/src/providers/types.ts +6 -0
- package/src/redact.ts +141 -0
- package/src/types.ts +143 -0
package/lib/extract.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ExtractedImage, ScanContext, TextMatch } from './types.js';
|
|
2
|
+
export interface ExtractedContent {
|
|
3
|
+
readonly text: string;
|
|
4
|
+
readonly images: readonly ExtractedImage[];
|
|
5
|
+
/** Original segment list when payload was structured; undefined for plain string. */
|
|
6
|
+
readonly segments?: readonly Record<string, unknown>[];
|
|
7
|
+
}
|
|
8
|
+
export declare function extractFromTextAndSegments(content: string, segments: readonly unknown[] | undefined): ExtractedContent;
|
|
9
|
+
export declare function extractFromOutboundPayload(payload: unknown): ExtractedContent;
|
|
10
|
+
export declare function buildScanContext(input: {
|
|
11
|
+
readonly adapter?: string;
|
|
12
|
+
readonly endpoint?: string;
|
|
13
|
+
readonly conversationKind?: string;
|
|
14
|
+
readonly conversationId?: string;
|
|
15
|
+
readonly sender?: string;
|
|
16
|
+
}): ScanContext;
|
|
17
|
+
export declare function mergeMatches(...lists: Array<readonly TextMatch[] | undefined>): readonly TextMatch[];
|
|
18
|
+
//# sourceMappingURL=extract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACxD;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,GACvC,gBAAgB,CAQlB;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAiB7E;AA2ED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,WAAW,CAQd;AAED,wBAAgB,YAAY,CAC1B,GAAG,KAAK,EAAE,KAAK,CAAC,SAAS,SAAS,EAAE,GAAG,SAAS,CAAC,GAChD,SAAS,SAAS,EAAE,CAgBtB"}
|
package/lib/extract.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
export function extractFromTextAndSegments(content, segments) {
|
|
2
|
+
if (Array.isArray(segments) && segments.length > 0) {
|
|
3
|
+
return extractFromSegments(segments);
|
|
4
|
+
}
|
|
5
|
+
return Object.freeze({
|
|
6
|
+
text: content ?? '',
|
|
7
|
+
images: Object.freeze([]),
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export function extractFromOutboundPayload(payload) {
|
|
11
|
+
if (typeof payload === 'string') {
|
|
12
|
+
return Object.freeze({
|
|
13
|
+
text: payload,
|
|
14
|
+
images: Object.freeze([]),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(payload)) {
|
|
18
|
+
return extractFromSegments(payload);
|
|
19
|
+
}
|
|
20
|
+
if (payload && typeof payload === 'object' && 'type' in payload) {
|
|
21
|
+
return extractFromSegments([payload]);
|
|
22
|
+
}
|
|
23
|
+
return Object.freeze({
|
|
24
|
+
text: payload == null ? '' : String(payload),
|
|
25
|
+
images: Object.freeze([]),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function extractFromSegments(segments) {
|
|
29
|
+
const texts = [];
|
|
30
|
+
const images = [];
|
|
31
|
+
const normalized = [];
|
|
32
|
+
for (let i = 0; i < segments.length; i++) {
|
|
33
|
+
const seg = segments[i];
|
|
34
|
+
if (!seg || typeof seg !== 'object')
|
|
35
|
+
continue;
|
|
36
|
+
const record = seg;
|
|
37
|
+
normalized.push(record);
|
|
38
|
+
const type = String(record.type ?? '');
|
|
39
|
+
const data = asRecord(record.data);
|
|
40
|
+
if (type === 'text') {
|
|
41
|
+
const text = typeof data.text === 'string' ? data.text : '';
|
|
42
|
+
if (text)
|
|
43
|
+
texts.push(text);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (type === 'image') {
|
|
47
|
+
const media = asRecord(data.media);
|
|
48
|
+
const image = mediaToImage(images.length, i, media, data);
|
|
49
|
+
if (image)
|
|
50
|
+
images.push(image);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return Object.freeze({
|
|
54
|
+
text: texts.join(''),
|
|
55
|
+
images: Object.freeze(images),
|
|
56
|
+
segments: Object.freeze(normalized),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function mediaToImage(index, segmentIndex, media, data) {
|
|
60
|
+
// Canonical MediaRef
|
|
61
|
+
if (typeof media.kind === 'string' && typeof media.value === 'string') {
|
|
62
|
+
const mime = typeof media.mime_type === 'string' ? media.mime_type : undefined;
|
|
63
|
+
if (media.kind === 'url') {
|
|
64
|
+
return Object.freeze({ index, segmentIndex, url: media.value, mime });
|
|
65
|
+
}
|
|
66
|
+
if (media.kind === 'base64') {
|
|
67
|
+
return Object.freeze({ index, segmentIndex, base64: media.value, mime });
|
|
68
|
+
}
|
|
69
|
+
if (media.kind === 'path') {
|
|
70
|
+
return Object.freeze({ index, segmentIndex, path: media.value, mime });
|
|
71
|
+
}
|
|
72
|
+
// kind=file: opaque platform ref — no fetchable URL
|
|
73
|
+
return Object.freeze({ index, segmentIndex, mime });
|
|
74
|
+
}
|
|
75
|
+
// Legacy wire fields
|
|
76
|
+
if (typeof data.url === 'string' && data.url) {
|
|
77
|
+
return Object.freeze({ index, segmentIndex, url: data.url });
|
|
78
|
+
}
|
|
79
|
+
if (typeof data.base64 === 'string' && data.base64) {
|
|
80
|
+
return Object.freeze({ index, segmentIndex, base64: data.base64 });
|
|
81
|
+
}
|
|
82
|
+
if (typeof data.file === 'string' && data.file) {
|
|
83
|
+
const file = data.file;
|
|
84
|
+
if (/^https?:\/\//i.test(file)) {
|
|
85
|
+
return Object.freeze({ index, segmentIndex, url: file });
|
|
86
|
+
}
|
|
87
|
+
return Object.freeze({ index, segmentIndex, path: file });
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
export function buildScanContext(input) {
|
|
92
|
+
return Object.freeze({
|
|
93
|
+
adapter: input.adapter ?? '',
|
|
94
|
+
endpoint: input.endpoint ?? '',
|
|
95
|
+
conversationKind: input.conversationKind ?? '',
|
|
96
|
+
conversationId: input.conversationId ?? '',
|
|
97
|
+
...(input.sender != null ? { sender: input.sender } : {}),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
export function mergeMatches(...lists) {
|
|
101
|
+
const out = [];
|
|
102
|
+
for (const list of lists) {
|
|
103
|
+
if (!list)
|
|
104
|
+
continue;
|
|
105
|
+
for (const m of list) {
|
|
106
|
+
if (Number.isFinite(m.start)
|
|
107
|
+
&& Number.isFinite(m.end)
|
|
108
|
+
&& m.end > m.start
|
|
109
|
+
&& m.start >= 0) {
|
|
110
|
+
out.push({ start: Math.trunc(m.start), end: Math.trunc(m.end) });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return Object.freeze(out);
|
|
115
|
+
}
|
|
116
|
+
function asRecord(value) {
|
|
117
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
118
|
+
? value
|
|
119
|
+
: {};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { DEFAULT_ACTIONS, DEFAULT_MODERATION_CONFIG, resolveModerationConfig, } from './config.js';
|
|
2
|
+
export { shouldBypassInbound, shouldBypassOutbound, } from './bypass.js';
|
|
3
|
+
export { extractFromOutboundPayload, extractFromTextAndSegments, buildScanContext, } from './extract.js';
|
|
4
|
+
export { redactText, redactOutboundPayload, } from './redact.js';
|
|
5
|
+
export { ModerationEngine, getModerationEngine, resetModerationEngine, mergeResults, } from './engine.js';
|
|
6
|
+
export type { Severity, Action, OnErrorPolicy, Direction, ModerationConfig, ProviderResult, MergedResult, ScanInput, SourceConfig, } from './types.js';
|
|
7
|
+
export { maxSeverity, SEVERITY_RANK } from './types.js';
|
|
8
|
+
export { LocalLexiconProvider, findMatches, findGradedMatches, loadWords, loadLexiconEntries, parseWordFile, parseWordLine, } from './providers/local-lexicon.js';
|
|
9
|
+
export { BUILTIN_LEXICON, mergeLexiconEntries } from './providers/builtin-lexicon.js';
|
|
10
|
+
export type { LexiconEntry, LexiconSeverity } from './providers/builtin-lexicon.js';
|
|
11
|
+
export { HttpModerationProvider, parseHttpResult, isPublicHttpUrl } from './providers/http.js';
|
|
12
|
+
export { createProviders } from './providers/registry.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,UAAU,EACV,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,QAAQ,EACR,MAAM,EACN,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,SAAS,EACT,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACtF,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACpF,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { DEFAULT_ACTIONS, DEFAULT_MODERATION_CONFIG, resolveModerationConfig, } from './config.js';
|
|
2
|
+
export { shouldBypassInbound, shouldBypassOutbound, } from './bypass.js';
|
|
3
|
+
export { extractFromOutboundPayload, extractFromTextAndSegments, buildScanContext, } from './extract.js';
|
|
4
|
+
export { redactText, redactOutboundPayload, } from './redact.js';
|
|
5
|
+
export { ModerationEngine, getModerationEngine, resetModerationEngine, mergeResults, } from './engine.js';
|
|
6
|
+
export { maxSeverity, SEVERITY_RANK } from './types.js';
|
|
7
|
+
export { LocalLexiconProvider, findMatches, findGradedMatches, loadWords, loadLexiconEntries, parseWordFile, parseWordLine, } from './providers/local-lexicon.js';
|
|
8
|
+
export { BUILTIN_LEXICON, mergeLexiconEntries } from './providers/builtin-lexicon.js';
|
|
9
|
+
export { HttpModerationProvider, parseHttpResult, isPublicHttpUrl } from './providers/http.js';
|
|
10
|
+
export { createProviders } from './providers/registry.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,UAAU,EACV,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,GACb,MAAM,aAAa,CAAC;AAYrB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,aAAa,GACd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAEtF,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Severity } from '../types.js';
|
|
2
|
+
export type LexiconSeverity = Exclude<Severity, 'pass'>;
|
|
3
|
+
export interface LexiconEntry {
|
|
4
|
+
readonly word: string;
|
|
5
|
+
readonly severity: LexiconSeverity;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Built-in graded lexicon for IM bots (starter set).
|
|
9
|
+
* Users can extend / override via `words` / `wordFiles`; same word keeps the
|
|
10
|
+
* higher severity when merging.
|
|
11
|
+
*/
|
|
12
|
+
export declare const BUILTIN_LEXICON: readonly LexiconEntry[];
|
|
13
|
+
/** Merge entries; duplicate words keep the higher severity. */
|
|
14
|
+
export declare function mergeLexiconEntries(...lists: Array<readonly LexiconEntry[] | undefined>): readonly LexiconEntry[];
|
|
15
|
+
//# sourceMappingURL=builtin-lexicon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin-lexicon.d.ts","sourceRoot":"","sources":["../../src/providers/builtin-lexicon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAExD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;CACpC;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAqGjD,CAAC;AAMH,+DAA+D;AAC/D,wBAAgB,mBAAmB,CACjC,GAAG,KAAK,EAAE,KAAK,CAAC,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC,GACnD,SAAS,YAAY,EAAE,CAwBzB"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in graded lexicon for IM bots (starter set).
|
|
3
|
+
* Users can extend / override via `words` / `wordFiles`; same word keeps the
|
|
4
|
+
* higher severity when merging.
|
|
5
|
+
*/
|
|
6
|
+
export const BUILTIN_LEXICON = Object.freeze([
|
|
7
|
+
// —— low:轻度不当 / 骚扰语气 ——
|
|
8
|
+
entry('脑残', 'low'),
|
|
9
|
+
entry('智障', 'low'),
|
|
10
|
+
entry('废物', 'low'),
|
|
11
|
+
entry('垃圾人', 'low'),
|
|
12
|
+
entry('滚蛋', 'low'),
|
|
13
|
+
entry('去死', 'low'),
|
|
14
|
+
entry('找死', 'low'),
|
|
15
|
+
entry('闭嘴', 'low'),
|
|
16
|
+
entry('恶心', 'low'),
|
|
17
|
+
entry('变态', 'low'),
|
|
18
|
+
// —— medium:辱骂 / 粗口 ——
|
|
19
|
+
entry('傻逼', 'medium'),
|
|
20
|
+
entry('傻B', 'medium'),
|
|
21
|
+
entry('傻b', 'medium'),
|
|
22
|
+
entry('傻叉', 'medium'),
|
|
23
|
+
entry('操逼', 'medium'),
|
|
24
|
+
entry('草泥马', 'medium'),
|
|
25
|
+
entry('妈的', 'medium'),
|
|
26
|
+
entry('他妈的', 'medium'),
|
|
27
|
+
entry('你妈的', 'medium'),
|
|
28
|
+
entry('卧槽', 'medium'),
|
|
29
|
+
entry('日你', 'medium'),
|
|
30
|
+
entry('操你', 'medium'),
|
|
31
|
+
entry('操他', 'medium'),
|
|
32
|
+
entry('狗日的', 'medium'),
|
|
33
|
+
entry('混蛋', 'medium'),
|
|
34
|
+
entry('王八蛋', 'medium'),
|
|
35
|
+
entry('白痴', 'medium'),
|
|
36
|
+
entry('去死吧', 'medium'),
|
|
37
|
+
// —— high:色情 / 引流诈骗常见话术 ——
|
|
38
|
+
entry('约炮', 'high'),
|
|
39
|
+
entry('裸聊', 'high'),
|
|
40
|
+
entry('色情', 'high'),
|
|
41
|
+
entry('黄色网站', 'high'),
|
|
42
|
+
entry('看片加', 'high'),
|
|
43
|
+
entry('援交', 'high'),
|
|
44
|
+
entry('包养', 'high'),
|
|
45
|
+
entry('上门服务', 'high'),
|
|
46
|
+
entry('加微信领', 'high'),
|
|
47
|
+
entry('刷单返利', 'high'),
|
|
48
|
+
entry('刷单赚钱', 'high'),
|
|
49
|
+
entry('日赚千元', 'high'),
|
|
50
|
+
entry('稳赚不赔', 'high'),
|
|
51
|
+
entry('内幕消息', 'high'),
|
|
52
|
+
entry('代开发票', 'high'),
|
|
53
|
+
entry('办假证', 'high'),
|
|
54
|
+
entry('假钞', 'high'),
|
|
55
|
+
entry('色情服务', 'high'),
|
|
56
|
+
entry('一夜情', 'high'),
|
|
57
|
+
// —— high:中国政治敏感(常见审查词,可按业务在配置中覆盖/关闭内置)——
|
|
58
|
+
entry('台独', 'high'),
|
|
59
|
+
entry('藏独', 'high'),
|
|
60
|
+
entry('疆独', 'high'),
|
|
61
|
+
entry('港独', 'high'),
|
|
62
|
+
entry('分裂国家', 'high'),
|
|
63
|
+
entry('民族分裂', 'high'),
|
|
64
|
+
entry('法轮功', 'high'),
|
|
65
|
+
entry('法轮大法', 'high'),
|
|
66
|
+
entry('六四事件', 'high'),
|
|
67
|
+
entry('六四屠城', 'high'),
|
|
68
|
+
entry('天安门事件', 'high'),
|
|
69
|
+
entry('坦克人', 'high'),
|
|
70
|
+
entry('学潮动乱', 'high'),
|
|
71
|
+
entry('政治风波', 'high'),
|
|
72
|
+
entry('打倒共产党', 'high'),
|
|
73
|
+
entry('推翻共产党', 'high'),
|
|
74
|
+
entry('颠覆国家政权', 'high'),
|
|
75
|
+
entry('占中运动', 'high'),
|
|
76
|
+
entry('反送中', 'high'),
|
|
77
|
+
entry('香港独立', 'high'),
|
|
78
|
+
entry('台湾独立', 'high'),
|
|
79
|
+
entry('西藏独立', 'high'),
|
|
80
|
+
entry('新疆独立', 'high'),
|
|
81
|
+
entry('东突厥斯坦', 'high'),
|
|
82
|
+
entry('民运人士', 'high'),
|
|
83
|
+
entry('零八宪章', 'high'),
|
|
84
|
+
entry('煽动颠覆', 'high'),
|
|
85
|
+
entry('颜色革命', 'high'),
|
|
86
|
+
entry('大跃进饿死', 'high'),
|
|
87
|
+
entry('文革迫害', 'high'),
|
|
88
|
+
// —— critical:毒品 / 极端违法 / 煽动暴力颠覆 ——
|
|
89
|
+
entry('冰毒', 'critical'),
|
|
90
|
+
entry('海洛因', 'critical'),
|
|
91
|
+
entry('可卡因', 'critical'),
|
|
92
|
+
entry('大麻走私', 'critical'),
|
|
93
|
+
entry('售卖枪支', 'critical'),
|
|
94
|
+
entry('买卖枪支', 'critical'),
|
|
95
|
+
entry('制毒', 'critical'),
|
|
96
|
+
entry('贩毒', 'critical'),
|
|
97
|
+
entry('炸药制作', 'critical'),
|
|
98
|
+
entry('儿童色情', 'critical'),
|
|
99
|
+
entry('幼女援交', 'critical'),
|
|
100
|
+
entry('武装暴动', 'critical'),
|
|
101
|
+
entry('暴力推翻政权', 'critical'),
|
|
102
|
+
entry('刺杀国家领导人', 'critical'),
|
|
103
|
+
]);
|
|
104
|
+
function entry(word, severity) {
|
|
105
|
+
return Object.freeze({ word, severity });
|
|
106
|
+
}
|
|
107
|
+
/** Merge entries; duplicate words keep the higher severity. */
|
|
108
|
+
export function mergeLexiconEntries(...lists) {
|
|
109
|
+
const map = new Map();
|
|
110
|
+
const rank = {
|
|
111
|
+
low: 1,
|
|
112
|
+
medium: 2,
|
|
113
|
+
high: 3,
|
|
114
|
+
critical: 4,
|
|
115
|
+
};
|
|
116
|
+
for (const list of lists) {
|
|
117
|
+
if (!list)
|
|
118
|
+
continue;
|
|
119
|
+
for (const item of list) {
|
|
120
|
+
const word = item.word.trim();
|
|
121
|
+
if (!word)
|
|
122
|
+
continue;
|
|
123
|
+
const prev = map.get(word);
|
|
124
|
+
if (!prev || rank[item.severity] > rank[prev]) {
|
|
125
|
+
map.set(word, item.severity);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return Object.freeze([...map.entries()]
|
|
130
|
+
.map(([word, severity]) => Object.freeze({ word, severity }))
|
|
131
|
+
.sort((a, b) => b.word.length - a.word.length || a.word.localeCompare(b.word)));
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=builtin-lexicon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtin-lexicon.js","sourceRoot":"","sources":["../../src/providers/builtin-lexicon.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAA4B,MAAM,CAAC,MAAM,CAAC;IACpE,wBAAwB;IACxB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC;IACnB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;IAClB,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;IAElB,uBAAuB;IACvB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;IACtB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;IACtB,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;IACtB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;IACtB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;IACtB,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC;IAEtB,2BAA2B;IAC3B,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;IAEpB,0CAA0C;IAC1C,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;IAErB,oCAAoC;IACpC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC;IACvB,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC;IACxB,KAAK,CAAC,KAAK,EAAE,UAAU,CAAC;IACxB,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC;IACzB,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC;IACzB,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC;IACzB,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC;IACvB,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC;IACvB,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC;IACzB,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC;IACzB,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC;IACzB,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC;IACzB,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC;IAC3B,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC;CAC7B,CAAC,CAAC;AAEH,SAAS,KAAK,CAAC,IAAY,EAAE,QAAyB;IACpD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,mBAAmB,CACjC,GAAG,KAAiD;IAEpD,MAAM,GAAG,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC/C,MAAM,IAAI,GAAoC;QAC5C,GAAG,EAAE,CAAC;QACN,MAAM,EAAE,CAAC;QACT,IAAI,EAAE,CAAC;QACP,QAAQ,EAAE,CAAC;KACZ,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9C,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;SAC5D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CACjF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HttpSourceConfig, ProviderResult, ScanInput } from '../types.js';
|
|
2
|
+
import type { ModerationProvider } from './types.js';
|
|
3
|
+
export interface HttpProviderDeps {
|
|
4
|
+
readonly fetch?: typeof fetch;
|
|
5
|
+
}
|
|
6
|
+
export declare class HttpModerationProvider implements ModerationProvider {
|
|
7
|
+
#private;
|
|
8
|
+
readonly id: string;
|
|
9
|
+
constructor(config: HttpSourceConfig, deps?: HttpProviderDeps);
|
|
10
|
+
scan(input: ScanInput): Promise<ProviderResult>;
|
|
11
|
+
}
|
|
12
|
+
export declare function isPublicHttpUrl(url: string): boolean;
|
|
13
|
+
export declare function parseHttpResult(sourceId: string, body: unknown): ProviderResult;
|
|
14
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/providers/http.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,gBAAgB,EAChB,cAAc,EACd,SAAS,EAGV,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CAC/B;AAED,qBAAa,sBAAuB,YAAW,kBAAkB;;IAC/D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAIR,MAAM,EAAE,gBAAgB,EAAE,IAAI,GAAE,gBAAqB;IAM3D,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;CAmFtD;AAmDD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,cAAc,CAkB/E"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { isSeverity } from '../types.js';
|
|
3
|
+
export class HttpModerationProvider {
|
|
4
|
+
id;
|
|
5
|
+
#config;
|
|
6
|
+
#fetch;
|
|
7
|
+
constructor(config, deps = {}) {
|
|
8
|
+
this.id = config.id;
|
|
9
|
+
this.#config = config;
|
|
10
|
+
this.#fetch = deps.fetch ?? globalThis.fetch.bind(globalThis);
|
|
11
|
+
}
|
|
12
|
+
async scan(input) {
|
|
13
|
+
try {
|
|
14
|
+
const images = await prepareImages(input.images, this.#config.forceUpload, this.#fetch);
|
|
15
|
+
const useMultipart = images.some((img) => img.mode === 'upload');
|
|
16
|
+
const controller = new AbortController();
|
|
17
|
+
const timer = setTimeout(() => controller.abort(), this.#config.timeoutMs);
|
|
18
|
+
try {
|
|
19
|
+
const response = useMultipart
|
|
20
|
+
? await this.#postMultipart(input, images, controller.signal)
|
|
21
|
+
: await this.#postJson(input, images, controller.signal);
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(`HTTP ${response.status}`);
|
|
24
|
+
}
|
|
25
|
+
const body = await response.json();
|
|
26
|
+
return parseHttpResult(this.id, body);
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
clearTimeout(timer);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
return Object.freeze({
|
|
34
|
+
sourceId: this.id,
|
|
35
|
+
severity: this.#config.onError === 'closed' ? 'critical' : 'pass',
|
|
36
|
+
error: true,
|
|
37
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async #postJson(input, images, signal) {
|
|
42
|
+
const body = {
|
|
43
|
+
text: input.text,
|
|
44
|
+
images: images.map((img) => (img.mode === 'url'
|
|
45
|
+
? { url: img.url }
|
|
46
|
+
: { base64: img.base64, mime: img.mime })),
|
|
47
|
+
direction: input.direction,
|
|
48
|
+
context: input.context,
|
|
49
|
+
};
|
|
50
|
+
return this.#fetch(this.#config.url, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers: {
|
|
53
|
+
'content-type': 'application/json',
|
|
54
|
+
...this.#config.headers,
|
|
55
|
+
},
|
|
56
|
+
body: JSON.stringify(body),
|
|
57
|
+
signal,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async #postMultipart(input, images, signal) {
|
|
61
|
+
const form = new FormData();
|
|
62
|
+
form.set('text', input.text);
|
|
63
|
+
form.set('direction', input.direction);
|
|
64
|
+
form.set('context', JSON.stringify(input.context));
|
|
65
|
+
for (const [i, img] of images.entries()) {
|
|
66
|
+
if (img.mode === 'url') {
|
|
67
|
+
form.append('images', JSON.stringify({ index: i, url: img.url }));
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const bytes = Uint8Array.from(Buffer.from(img.base64, 'base64'));
|
|
71
|
+
const mime = img.mime || 'application/octet-stream';
|
|
72
|
+
form.append('images', new Blob([bytes], { type: mime }), `image-${i}.${extensionForMime(mime)}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return this.#fetch(this.#config.url, {
|
|
76
|
+
method: 'POST',
|
|
77
|
+
headers: { ...this.#config.headers },
|
|
78
|
+
body: form,
|
|
79
|
+
signal,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function prepareImages(images, forceUpload, fetchImpl) {
|
|
84
|
+
const out = [];
|
|
85
|
+
for (const image of images) {
|
|
86
|
+
if (!forceUpload && image.url && isPublicHttpUrl(image.url)) {
|
|
87
|
+
out.push({ mode: 'url', url: image.url });
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (image.base64) {
|
|
91
|
+
out.push({ mode: 'upload', base64: image.base64, mime: image.mime });
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (image.path) {
|
|
95
|
+
const buf = readFileSync(image.path);
|
|
96
|
+
out.push({
|
|
97
|
+
mode: 'upload',
|
|
98
|
+
base64: buf.toString('base64'),
|
|
99
|
+
mime: image.mime,
|
|
100
|
+
});
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (image.url) {
|
|
104
|
+
const downloaded = await downloadAsBase64(image.url, fetchImpl);
|
|
105
|
+
out.push({ mode: 'upload', base64: downloaded.base64, mime: downloaded.mime ?? image.mime });
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
// Opaque file refs: skip (cannot fetch without platform API)
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
async function downloadAsBase64(url, fetchImpl) {
|
|
113
|
+
const response = await fetchImpl(url);
|
|
114
|
+
if (!response.ok)
|
|
115
|
+
throw new Error(`download failed: HTTP ${response.status}`);
|
|
116
|
+
const mime = response.headers.get('content-type') ?? undefined;
|
|
117
|
+
const buf = Buffer.from(await response.arrayBuffer());
|
|
118
|
+
return { base64: buf.toString('base64'), mime };
|
|
119
|
+
}
|
|
120
|
+
export function isPublicHttpUrl(url) {
|
|
121
|
+
try {
|
|
122
|
+
const parsed = new URL(url);
|
|
123
|
+
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export function parseHttpResult(sourceId, body) {
|
|
130
|
+
if (!body || typeof body !== 'object') {
|
|
131
|
+
throw new Error('invalid moderation response');
|
|
132
|
+
}
|
|
133
|
+
const record = body;
|
|
134
|
+
if (!isSeverity(record.severity)) {
|
|
135
|
+
throw new Error('invalid severity in moderation response');
|
|
136
|
+
}
|
|
137
|
+
const severity = record.severity;
|
|
138
|
+
const matches = parseMatches(record.matches);
|
|
139
|
+
const flaggedImageIndexes = parseFlaggedImages(record.images);
|
|
140
|
+
return Object.freeze({
|
|
141
|
+
sourceId,
|
|
142
|
+
severity,
|
|
143
|
+
...(matches.length ? { matches } : {}),
|
|
144
|
+
...(flaggedImageIndexes.length ? { flaggedImageIndexes } : {}),
|
|
145
|
+
...(typeof record.reason === 'string' ? { reason: record.reason } : {}),
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function parseMatches(raw) {
|
|
149
|
+
if (!Array.isArray(raw))
|
|
150
|
+
return Object.freeze([]);
|
|
151
|
+
const out = [];
|
|
152
|
+
for (const item of raw) {
|
|
153
|
+
if (!item || typeof item !== 'object')
|
|
154
|
+
continue;
|
|
155
|
+
const start = item.start;
|
|
156
|
+
const end = item.end;
|
|
157
|
+
if (typeof start !== 'number' || typeof end !== 'number')
|
|
158
|
+
continue;
|
|
159
|
+
if (!(end > start) || start < 0)
|
|
160
|
+
continue;
|
|
161
|
+
out.push({ start: Math.trunc(start), end: Math.trunc(end) });
|
|
162
|
+
}
|
|
163
|
+
return Object.freeze(out);
|
|
164
|
+
}
|
|
165
|
+
function parseFlaggedImages(raw) {
|
|
166
|
+
if (!Array.isArray(raw))
|
|
167
|
+
return Object.freeze([]);
|
|
168
|
+
const out = [];
|
|
169
|
+
for (const item of raw) {
|
|
170
|
+
if (!item || typeof item !== 'object')
|
|
171
|
+
continue;
|
|
172
|
+
const index = item.index;
|
|
173
|
+
const flagged = item.flagged;
|
|
174
|
+
if (typeof index === 'number' && Number.isFinite(index) && flagged === true) {
|
|
175
|
+
out.push(Math.trunc(index));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return Object.freeze(out);
|
|
179
|
+
}
|
|
180
|
+
function extensionForMime(mime) {
|
|
181
|
+
if (mime.includes('png'))
|
|
182
|
+
return 'png';
|
|
183
|
+
if (mime.includes('jpeg') || mime.includes('jpg'))
|
|
184
|
+
return 'jpg';
|
|
185
|
+
if (mime.includes('gif'))
|
|
186
|
+
return 'gif';
|
|
187
|
+
if (mime.includes('webp'))
|
|
188
|
+
return 'webp';
|
|
189
|
+
return 'bin';
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/providers/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type LocalSourceConfig, type ProviderResult, type ScanInput, type TextMatch } from '../types.js';
|
|
2
|
+
import type { LexiconEntry, LexiconSeverity } from './builtin-lexicon.js';
|
|
3
|
+
import type { ModerationProvider } from './types.js';
|
|
4
|
+
export interface GradedMatch extends TextMatch {
|
|
5
|
+
readonly word: string;
|
|
6
|
+
readonly severity: LexiconSeverity;
|
|
7
|
+
}
|
|
8
|
+
export declare class LocalLexiconProvider implements ModerationProvider {
|
|
9
|
+
#private;
|
|
10
|
+
readonly id: string;
|
|
11
|
+
constructor(config: LocalSourceConfig, cwd?: string);
|
|
12
|
+
scan(input: ScanInput): Promise<ProviderResult>;
|
|
13
|
+
}
|
|
14
|
+
export declare function loadLexiconEntries(config: LocalSourceConfig, cwd: string): readonly LexiconEntry[];
|
|
15
|
+
/** @deprecated Use loadLexiconEntries; kept for tests that only need bare words. */
|
|
16
|
+
export declare function loadWords(config: LocalSourceConfig, cwd: string): string[];
|
|
17
|
+
export declare function findMatches(text: string, words: readonly string[]): readonly TextMatch[];
|
|
18
|
+
export declare function findGradedMatches(text: string, entries: readonly LexiconEntry[]): readonly GradedMatch[];
|
|
19
|
+
/**
|
|
20
|
+
* Word-file lines:
|
|
21
|
+
* - `# comment`
|
|
22
|
+
* - `word` → defaultSeverity
|
|
23
|
+
* - `severity:word` → graded(low|medium|high|critical)
|
|
24
|
+
* - `word|severity` → graded
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseWordFile(content: string, defaultSeverity: LexiconSeverity): LexiconEntry[];
|
|
27
|
+
export declare function parseWordLine(line: string, defaultSeverity: LexiconSeverity): LexiconEntry | null;
|
|
28
|
+
//# sourceMappingURL=local-lexicon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-lexicon.d.ts","sourceRoot":"","sources":["../../src/providers/local-lexicon.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AACvH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;CACpC;AAED,qBAAa,oBAAqB,YAAW,kBAAkB;;IAC7D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAIR,MAAM,EAAE,iBAAiB,EAAE,GAAG,GAAE,MAAsB;IAM5D,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;CA4BtD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAUlG;AAED,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAE1E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,SAAS,EAAE,CAGxF;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,YAAY,EAAE,GAC/B,SAAS,WAAW,EAAE,CAoBxB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,eAAe,GAC/B,YAAY,EAAE,CAShB;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,eAAe,GAC/B,YAAY,GAAG,IAAI,CAgBrB"}
|