@postalsys/email-content 0.0.4 → 0.1.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.
Files changed (96) hide show
  1. package/README.md +207 -17
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/analyze.d.ts +55 -15
  4. package/dist/analyze.d.ts.map +1 -1
  5. package/dist/analyze.js +264 -61
  6. package/dist/analyze.js.map +1 -1
  7. package/dist/canonical/html.d.ts +21 -2
  8. package/dist/canonical/html.d.ts.map +1 -1
  9. package/dist/canonical/html.js +213 -14
  10. package/dist/canonical/html.js.map +1 -1
  11. package/dist/classify/confidence.d.ts +12 -0
  12. package/dist/classify/confidence.d.ts.map +1 -1
  13. package/dist/classify/confidence.js +54 -4
  14. package/dist/classify/confidence.js.map +1 -1
  15. package/dist/classify/reconcile.d.ts +25 -17
  16. package/dist/classify/reconcile.d.ts.map +1 -1
  17. package/dist/classify/reconcile.js +52 -20
  18. package/dist/classify/reconcile.js.map +1 -1
  19. package/dist/cli/annotate.d.ts.map +1 -1
  20. package/dist/cli/annotate.js +6 -3
  21. package/dist/cli/annotate.js.map +1 -1
  22. package/dist/cli/args.d.ts +14 -0
  23. package/dist/cli/args.d.ts.map +1 -1
  24. package/dist/cli/args.js +48 -1
  25. package/dist/cli/args.js.map +1 -1
  26. package/dist/cli/benchmark.d.ts +39 -0
  27. package/dist/cli/benchmark.d.ts.map +1 -1
  28. package/dist/cli/benchmark.js +179 -66
  29. package/dist/cli/benchmark.js.map +1 -1
  30. package/dist/cli/corpus.d.ts.map +1 -1
  31. package/dist/cli/corpus.js +13 -8
  32. package/dist/cli/corpus.js.map +1 -1
  33. package/dist/cli/disagreements.d.ts.map +1 -1
  34. package/dist/cli/disagreements.js +7 -4
  35. package/dist/cli/disagreements.js.map +1 -1
  36. package/dist/cli/evaluate.d.ts.map +1 -1
  37. package/dist/cli/evaluate.js +34 -10
  38. package/dist/cli/evaluate.js.map +1 -1
  39. package/dist/cli/extract.d.ts.map +1 -1
  40. package/dist/cli/extract.js +8 -3
  41. package/dist/cli/extract.js.map +1 -1
  42. package/dist/cli/main.js +8 -0
  43. package/dist/cli/main.js.map +1 -1
  44. package/dist/corpus/scanner.d.ts +9 -1
  45. package/dist/corpus/scanner.d.ts.map +1 -1
  46. package/dist/corpus/scanner.js +52 -13
  47. package/dist/corpus/scanner.js.map +1 -1
  48. package/dist/corpus/store.d.ts +33 -2
  49. package/dist/corpus/store.d.ts.map +1 -1
  50. package/dist/corpus/store.js +64 -4
  51. package/dist/corpus/store.js.map +1 -1
  52. package/dist/detect/patterns.d.ts +29 -0
  53. package/dist/detect/patterns.d.ts.map +1 -1
  54. package/dist/detect/patterns.js +80 -6
  55. package/dist/detect/patterns.js.map +1 -1
  56. package/dist/detect/reply-header.d.ts +14 -0
  57. package/dist/detect/reply-header.d.ts.map +1 -1
  58. package/dist/detect/reply-header.js +80 -37
  59. package/dist/detect/reply-header.js.map +1 -1
  60. package/dist/eval/oracle.d.ts +80 -0
  61. package/dist/eval/oracle.d.ts.map +1 -0
  62. package/dist/eval/oracle.js +250 -0
  63. package/dist/eval/oracle.js.map +1 -0
  64. package/dist/index.d.ts +6 -3
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +94 -56
  67. package/dist/index.js.map +1 -1
  68. package/dist/mime/model.d.ts +28 -3
  69. package/dist/mime/model.d.ts.map +1 -1
  70. package/dist/mime/model.js +41 -1
  71. package/dist/mime/model.js.map +1 -1
  72. package/dist/mime/parse.d.ts.map +1 -1
  73. package/dist/mime/parse.js +19 -2
  74. package/dist/mime/parse.js.map +1 -1
  75. package/dist/mime/select.d.ts +71 -0
  76. package/dist/mime/select.d.ts.map +1 -0
  77. package/dist/mime/select.js +198 -0
  78. package/dist/mime/select.js.map +1 -0
  79. package/dist/segment/html-blocks.d.ts +1 -1
  80. package/dist/segment/html-blocks.d.ts.map +1 -1
  81. package/dist/segment/html-blocks.js +77 -8
  82. package/dist/segment/html-blocks.js.map +1 -1
  83. package/dist/segment/text-blocks.d.ts.map +1 -1
  84. package/dist/segment/text-blocks.js +18 -1
  85. package/dist/segment/text-blocks.js.map +1 -1
  86. package/dist/segment/types.d.ts +14 -0
  87. package/dist/segment/types.d.ts.map +1 -1
  88. package/dist/types.d.ts +132 -11
  89. package/dist/types.d.ts.map +1 -1
  90. package/dist/types.js +37 -3
  91. package/dist/types.js.map +1 -1
  92. package/dist/util/worker-pool.d.ts +21 -0
  93. package/dist/util/worker-pool.d.ts.map +1 -1
  94. package/dist/util/worker-pool.js +61 -13
  95. package/dist/util/worker-pool.js.map +1 -1
  96. package/package.json +6 -5
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Independent safety oracles for the structural benchmark.
3
+ *
4
+ * The benchmark exists to detect the failure this project is built to prevent: a message that had
5
+ * content going in and has none coming out. It cannot do that by asking the extractor, and the
6
+ * previous version did exactly that:
7
+ *
8
+ * const hadContent = visibleChars + hiddenChars > 0;
9
+ *
10
+ * That reads "did the input have content" off the output. When extraction dropped everything the
11
+ * flag went false, the catastrophic counter did not increment, and the benchmark reported zero
12
+ * losses while a reproducible total loss case existed.
13
+ *
14
+ * So the code here shares the *definition* of a body with the extractor, and shares none of its
15
+ * *implementation*. It re-parses the message, walks the flat part list itself, and never calls the
16
+ * selection logic it is meant to check. Re-parsing costs a second MIME pass per message, which is
17
+ * the right trade for a release gate.
18
+ */
19
+ import { type MimePart, type ParsedMessage } from '../mime/model';
20
+ /** Part ids that sit inside an embedded `message/rfc822`, which is content and not the outer body. */
21
+ export declare function embeddedPartIds(message: ParsedMessage): Set<string>;
22
+ /** A decoded body-bearing leaf, by the written MIME rules rather than by the selection heuristic. */
23
+ export declare function eligibleBodyParts(message: ParsedMessage): MimePart[];
24
+ export interface InputInventory {
25
+ /** Characters of plausibly visible body text across every eligible part. */
26
+ visibleChars: number;
27
+ /** Eligible non attachment body leaves, whether or not they hold visible text. */
28
+ eligibleParts: number;
29
+ /** True when at least one eligible part holds visible text. */
30
+ hasVisibleText: boolean;
31
+ }
32
+ /**
33
+ * Count plausible visible body text in a parsed message, before extraction runs.
34
+ *
35
+ * Deliberately over-inclusive: it counts every eligible part, including both members of a
36
+ * `multipart/alternative`, because its only question is whether the message had anything visible to
37
+ * show. It is not, and must not be used as, a demand that every part appear in the output.
38
+ *
39
+ * Script, style, comment and markup text is excluded, so an image-only newsletter or a body that is
40
+ * nothing but a tracking pixel does not count as visible text that extraction then lost.
41
+ */
42
+ export declare function inventoryVisibleInput(message: ParsedMessage): InputInventory;
43
+ /**
44
+ * A piece of the message that the output has to represent somehow.
45
+ *
46
+ * Per-part coverage would be wrong. A normal `multipart/alternative` carries both a plain and an
47
+ * HTML rendering, and HTML-primary output deliberately contains only HTML-derived segments;
48
+ * demanding both part ids would report most valid mail as lossy. So the unit is a *group*, and any
49
+ * one supported member satisfies it.
50
+ */
51
+ export interface CoverageGroup {
52
+ /** Stable identifier: the container part for an alternative, the leaf itself otherwise. */
53
+ id: string;
54
+ /** True when the group is one alternative rendering set rather than independent content. */
55
+ alternative: boolean;
56
+ /** Part ids, any one of which represents this group. */
57
+ members: string[];
58
+ }
59
+ /**
60
+ * Required coverage groups for a parsed message.
61
+ *
62
+ * Written from the decision table rather than by calling `planBody()`. Sharing the implementation
63
+ * would make the oracle agree with the selection code by construction, which is exactly the
64
+ * property a gate must not have. The two are reviewed against the same table and are expected to
65
+ * agree; when they do not, one of them is wrong and the run says so.
66
+ */
67
+ export declare function requiredCoverageGroups(message: ParsedMessage): CoverageGroup[];
68
+ export interface CoverageReport {
69
+ required: number;
70
+ covered: number;
71
+ /** Group ids with no member anywhere in the output. Each one is content that vanished. */
72
+ missing: string[];
73
+ /** Alternative members deliberately not emitted. Informational, never a failure. */
74
+ alternativesNotEmitted: string[];
75
+ /** Groups present only in `hiddenSegments`. */
76
+ hiddenOnly: string[];
77
+ }
78
+ /** Compare the required groups against the MIME parts the result actually names. */
79
+ export declare function coverageOf(groups: readonly CoverageGroup[], visibleParts: ReadonlySet<string>, hiddenParts: ReadonlySet<string>): CoverageReport;
80
+ //# sourceMappingURL=oracle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oracle.d.ts","sourceRoot":"","sources":["../../src/eval/oracle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAElE,sGAAsG;AACtG,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,CAiBnE;AAED,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,QAAQ,EAAE,CASpE;AAED,MAAM,WAAW,cAAc;IAC3B,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,kFAAkF;IAClF,aAAa,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,cAAc,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,cAAc,CAO5E;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC1B,2FAA2F;IAC3F,EAAE,EAAE,MAAM,CAAC;IACX,4FAA4F;IAC5F,WAAW,EAAE,OAAO,CAAC;IACrB,wDAAwD;IACxD,OAAO,EAAE,MAAM,EAAE,CAAC;CACrB;AAyGD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,EAAE,CAwD9E;AAED,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oFAAoF;IACpF,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,+CAA+C;IAC/C,UAAU,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,EAAE,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,cAAc,CAsBhJ"}
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ /**
3
+ * Independent safety oracles for the structural benchmark.
4
+ *
5
+ * The benchmark exists to detect the failure this project is built to prevent: a message that had
6
+ * content going in and has none coming out. It cannot do that by asking the extractor, and the
7
+ * previous version did exactly that:
8
+ *
9
+ * const hadContent = visibleChars + hiddenChars > 0;
10
+ *
11
+ * That reads "did the input have content" off the output. When extraction dropped everything the
12
+ * flag went false, the catastrophic counter did not increment, and the benchmark reported zero
13
+ * losses while a reproducible total loss case existed.
14
+ *
15
+ * So the code here shares the *definition* of a body with the extractor, and shares none of its
16
+ * *implementation*. It re-parses the message, walks the flat part list itself, and never calls the
17
+ * selection logic it is meant to check. Re-parsing costs a second MIME pass per message, which is
18
+ * the right trade for a release gate.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.embeddedPartIds = embeddedPartIds;
22
+ exports.eligibleBodyParts = eligibleBodyParts;
23
+ exports.inventoryVisibleInput = inventoryVisibleInput;
24
+ exports.requiredCoverageGroups = requiredCoverageGroups;
25
+ exports.coverageOf = coverageOf;
26
+ const text_1 = require("../canonical/text");
27
+ const html_1 = require("../canonical/html");
28
+ const normalize_1 = require("../match/normalize");
29
+ const shingle_1 = require("../match/shingle");
30
+ /** Part ids that sit inside an embedded `message/rfc822`, which is content and not the outer body. */
31
+ function embeddedPartIds(message) {
32
+ const containers = message.parts.filter(part => part.rfc822 || part.embeddedRoot);
33
+ const inside = new Set();
34
+ if (!containers.length) {
35
+ return inside;
36
+ }
37
+ for (const part of message.parts) {
38
+ let cursor = part;
39
+ while (cursor?.parentId) {
40
+ if (containers.some(container => container.partId === cursor?.parentId)) {
41
+ inside.add(part.partId);
42
+ break;
43
+ }
44
+ cursor = message.partsById.get(cursor.parentId);
45
+ }
46
+ }
47
+ return inside;
48
+ }
49
+ /** A decoded body-bearing leaf, by the written MIME rules rather than by the selection heuristic. */
50
+ function eligibleBodyParts(message) {
51
+ const embedded = embeddedPartIds(message);
52
+ return message.parts.filter(part => (part.contentType === 'text/plain' || part.contentType === 'text/html') &&
53
+ part.disposition !== 'attachment' &&
54
+ Boolean(part.decoded) &&
55
+ !embedded.has(part.partId));
56
+ }
57
+ /**
58
+ * Count plausible visible body text in a parsed message, before extraction runs.
59
+ *
60
+ * Deliberately over-inclusive: it counts every eligible part, including both members of a
61
+ * `multipart/alternative`, because its only question is whether the message had anything visible to
62
+ * show. It is not, and must not be used as, a demand that every part appear in the output.
63
+ *
64
+ * Script, style, comment and markup text is excluded, so an image-only newsletter or a body that is
65
+ * nothing but a tracking pixel does not count as visible text that extraction then lost.
66
+ */
67
+ function inventoryVisibleInput(message) {
68
+ let visibleChars = 0;
69
+ const parts = eligibleBodyParts(message);
70
+ for (const part of parts) {
71
+ visibleChars += visibleTextOf(part).length;
72
+ }
73
+ return { visibleChars, eligibleParts: parts.length, hasVisibleText: visibleChars > 0 };
74
+ }
75
+ /**
76
+ * Text a reader would actually have seen in one part.
77
+ *
78
+ * Quote prefixes are stripped rather than counted. A plain part whose entire body is `>` on three
79
+ * lines contains no text at all, and counting the markers made the gate report a total content loss
80
+ * on a message that had nothing to lose. Script, style, comment and markup text is excluded the
81
+ * same way, so an image-only body does not look like text that extraction dropped.
82
+ */
83
+ function visibleTextOf(part) {
84
+ const raw = part.decoded?.text ?? '';
85
+ if (!raw) {
86
+ return '';
87
+ }
88
+ if (part.contentType === 'text/html') {
89
+ return (0, html_1.stripTagsToText)(raw).trim();
90
+ }
91
+ return (0, text_1.canonicaliseText)(raw)
92
+ .lines.filter(line => !line.blank)
93
+ .map(line => line.content)
94
+ .join('\n')
95
+ .trim();
96
+ }
97
+ /**
98
+ * Supported body leaf, by the same written rules the plan uses, deliberately reimplemented here.
99
+ *
100
+ * A part with no visible text is not required coverage. An image-only newsletter and a body that is
101
+ * nothing but a tracking pixel both have a body part and nothing for the output to carry, and
102
+ * demanding a segment for them would report "content lost" on messages where none existed.
103
+ */
104
+ function isSupportedLeaf(part) {
105
+ return ((part.contentType === 'text/plain' || part.contentType === 'text/html') &&
106
+ part.disposition !== 'attachment' &&
107
+ Boolean(part.decoded) &&
108
+ visibleTextOf(part) !== '');
109
+ }
110
+ function supportedLeavesUnder(message, part, into, depth = 0) {
111
+ if (depth > 32 || part.disposition === 'attachment' || part.rfc822 || part.embeddedRoot) {
112
+ return;
113
+ }
114
+ if (isSupportedLeaf(part)) {
115
+ into.push(part.partId);
116
+ return;
117
+ }
118
+ for (const childId of part.childIds) {
119
+ const child = message.partsById.get(childId);
120
+ if (child) {
121
+ supportedLeavesUnder(message, child, into, depth + 1);
122
+ }
123
+ }
124
+ }
125
+ function bareContentId(value) {
126
+ return (value ?? '').trim().replace(/^</, '').replace(/>$/, '').toLowerCase();
127
+ }
128
+ /**
129
+ * Fold a `mixed` container's misencoded alternatives into single equivalence groups.
130
+ *
131
+ * Some clients use `multipart/mixed` where they mean `multipart/alternative`, `mixed(H,P)` most
132
+ * often. The extractor merges such a pair into one section when their content matches, so only one
133
+ * of the two part ids reaches the output, and a per-part rule would report the other as lost
134
+ * content when nothing was lost.
135
+ *
136
+ * Decided by content rather than structure, exactly as the selection code decides it, and
137
+ * implemented separately here on purpose. An oracle that called the selection code would agree with
138
+ * it by construction and could never catch it being wrong. These two must be reviewed together
139
+ * against `docs/adr-001-document-global-classification.md`; when they disagree, one of them is
140
+ * wrong and the run says so.
141
+ */
142
+ function mergeMisencodedAlternatives(message, groups, from) {
143
+ for (let i = from; i + 1 < groups.length; i++) {
144
+ const left = groups[i];
145
+ const right = groups[i + 1];
146
+ if (left.alternative || right.alternative || left.members.length !== 1 || right.members.length !== 1) {
147
+ continue;
148
+ }
149
+ const a = message.partsById.get(left.members[0]);
150
+ const b = message.partsById.get(right.members[0]);
151
+ if (!a || !b) {
152
+ continue;
153
+ }
154
+ const plain = a.contentType === 'text/plain' ? a : b.contentType === 'text/plain' ? b : null;
155
+ const markup = a.contentType === 'text/html' ? a : b.contentType === 'text/html' ? b : null;
156
+ if (!plain || !markup) {
157
+ continue;
158
+ }
159
+ const left_ = (0, shingle_1.buildShingleIndex)((0, normalize_1.normaliseForMatch)(visibleTextOf(plain)));
160
+ const right_ = (0, shingle_1.buildShingleIndex)((0, normalize_1.normaliseForMatch)(visibleTextOf(markup)));
161
+ if (!(0, shingle_1.isMatchable)(left_) || !(0, shingle_1.isMatchable)(right_)) {
162
+ continue;
163
+ }
164
+ if ((0, shingle_1.containment)(left_, right_).containment < shingle_1.CONTAINMENT_THRESHOLD && (0, shingle_1.containment)(right_, left_).containment < shingle_1.CONTAINMENT_THRESHOLD) {
165
+ continue;
166
+ }
167
+ groups.splice(i, 2, { id: left.id, alternative: true, members: [...left.members, ...right.members] });
168
+ i--;
169
+ }
170
+ }
171
+ /**
172
+ * Required coverage groups for a parsed message.
173
+ *
174
+ * Written from the decision table rather than by calling `planBody()`. Sharing the implementation
175
+ * would make the oracle agree with the selection code by construction, which is exactly the
176
+ * property a gate must not have. The two are reviewed against the same table and are expected to
177
+ * agree; when they do not, one of them is wrong and the run says so.
178
+ */
179
+ function requiredCoverageGroups(message) {
180
+ const groups = [];
181
+ const walk = (part, depth) => {
182
+ if (depth > 32 || part.disposition === 'attachment') {
183
+ return;
184
+ }
185
+ // Embedded messages are content for the caller to render, not the container's body.
186
+ if (part.rfc822 || part.embeddedRoot) {
187
+ return;
188
+ }
189
+ if (part.multipart === 'alternative') {
190
+ const members = [];
191
+ supportedLeavesUnder(message, part, members);
192
+ if (members.length) {
193
+ groups.push({ id: part.partId, alternative: true, members });
194
+ }
195
+ return;
196
+ }
197
+ const children = part.childIds.map(id => message.partsById.get(id)).filter(Boolean);
198
+ if (part.multipart === 'related') {
199
+ // Only the root carries body. Everything else is an inline resource.
200
+ const start = bareContentId(part.contentTypeParams.start);
201
+ const root = (start ? children.find(child => bareContentId(child.headers.find(entry => entry.key === 'content-id')?.value) === start) : undefined) ??
202
+ children[0];
203
+ if (root) {
204
+ walk(root, depth + 1);
205
+ }
206
+ return;
207
+ }
208
+ if (part.multipart) {
209
+ // mixed and everything unrecognised: ordered independent content, each body-bearing
210
+ // child is its own required group.
211
+ const before = groups.length;
212
+ for (const child of children) {
213
+ walk(child, depth + 1);
214
+ }
215
+ mergeMisencodedAlternatives(message, groups, before);
216
+ return;
217
+ }
218
+ if (isSupportedLeaf(part)) {
219
+ groups.push({ id: part.partId, alternative: false, members: [part.partId] });
220
+ }
221
+ };
222
+ const root = message.partsById.get(message.rootId) ?? message.parts[0];
223
+ if (root) {
224
+ walk(root, 0);
225
+ }
226
+ return groups;
227
+ }
228
+ /** Compare the required groups against the MIME parts the result actually names. */
229
+ function coverageOf(groups, visibleParts, hiddenParts) {
230
+ const missing = [];
231
+ const alternativesNotEmitted = [];
232
+ const hiddenOnly = [];
233
+ let covered = 0;
234
+ for (const group of groups) {
235
+ const present = group.members.filter(member => visibleParts.has(member) || hiddenParts.has(member));
236
+ if (!present.length) {
237
+ missing.push(group.id);
238
+ continue;
239
+ }
240
+ covered++;
241
+ if (group.alternative) {
242
+ alternativesNotEmitted.push(...group.members.filter(member => !present.includes(member)));
243
+ }
244
+ if (present.every(member => !visibleParts.has(member))) {
245
+ hiddenOnly.push(group.id);
246
+ }
247
+ }
248
+ return { required: groups.length, covered, missing, alternativesNotEmitted, hiddenOnly };
249
+ }
250
+ //# sourceMappingURL=oracle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oracle.js","sourceRoot":"","sources":["../../src/eval/oracle.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -12,13 +12,16 @@ export * from './types';
12
12
  export { parseMessage } from './mime/parse';
13
13
  export type { ParsedMessage, MimePart } from './mime/model';
14
14
  export type { Block, BlockFeatures, BlockKind, Evidence } from './segment/types';
15
- export { DEFAULT_CONFIDENCE } from './classify/confidence';
15
+ export { DEFAULT_CONFIDENCE, validateConfidenceConfig, type ConfidenceConfig } from './classify/confidence';
16
+ export { validateParseOptions, DEFAULT_PARSE_OPTIONS } from './mime/model';
16
17
  export { buildHistoryDocument, matchBlocks, type HistoryDocument, type BlockMatch } from './match/history';
17
18
  export { corpusThreadResolver, folderThreadResolver, type ThreadResolver } from './corpus/thread-index';
18
- export { analyze, resolveHistory, senderTokensFrom, type MessageContent, type AnalyzeOptions, type AnalyzeResult } from './analyze';
19
+ export { analyze, resolveHistory, senderTokensFrom, type BodySection, type MessageContent, type AnalyzeOptions, type AnalyzeResult } from './analyze';
20
+ export { planBody, reportableExclusions, type BodyPlan, type ExclusionReason, type PlannedSection, type SectionRole } from './mime/select';
21
+ export { loadPatterns, PatternAssetError } from './detect/patterns';
19
22
  export interface ExtractOptions {
20
23
  parse?: ParseOptions;
21
- confidence?: ConfidenceConfig;
24
+ confidence?: Partial<ConfidenceConfig>;
22
25
  /**
23
26
  * Earlier messages in the thread, most recent first. Optional: extraction works without any
24
27
  * history, and history only ever adds evidence.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAiB,KAAK,YAAY,EAAsB,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAqB,KAAK,gBAAgB,EAAE,KAAK,MAAM,EAAgB,MAAM,SAAS,CAAC;AAE9F,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC3G,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACxG,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAEpI,MAAM,WAAW,cAAc;IAC3B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,kGAAkG;IAClG,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACrD,qCAAqC;IACrC,WAAW,CAAC,EAAE;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,MAAM,EAAE;YACJ,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,EAAE,MAAM,CAAC;YACnB,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,QAAQ,EAAE;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAC;gBAAC,QAAQ,EAAE,MAAM,CAAA;aAAE,EAAE,CAAC;YAC3D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAClC,OAAO,EAAE,MAAM,CAAC;SACnB,EAAE,CAAC;KACP,CAAC;CACL;AAkFD,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CA+C1G"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,KAAK,YAAY,EAA4C,MAAM,cAAc,CAAC;AAG3F,OAAO,EAA4B,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAqB,KAAK,gBAAgB,EAAE,KAAK,MAAM,EAAgB,MAAM,SAAS,CAAC;AAE9F,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC5G,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC3G,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACxG,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AACtJ,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,KAAK,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3I,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAWpE,MAAM,WAAW,cAAc;IAC3B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,kGAAkG;IAClG,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACrD,qCAAqC;IACrC,WAAW,CAAC,EAAE;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,MAAM,EAAE;YACJ,KAAK,EAAE,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,EAAE,MAAM,CAAC;YACnB,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,QAAQ,EAAE;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,CAAC;gBAAC,QAAQ,EAAE,MAAM,CAAA;aAAE,EAAE,CAAC;YAC3D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAClC,OAAO,EAAE,MAAM,CAAC;SACnB,EAAE,CAAC;KACP,CAAC;CACL;AA2CD,wBAAsB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CA2G1G"}
package/dist/index.js CHANGED
@@ -20,16 +20,24 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
20
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
21
  };
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.senderTokensFrom = exports.resolveHistory = exports.analyze = exports.folderThreadResolver = exports.corpusThreadResolver = exports.matchBlocks = exports.buildHistoryDocument = exports.DEFAULT_CONFIDENCE = exports.parseMessage = void 0;
23
+ exports.PatternAssetError = exports.loadPatterns = exports.reportableExclusions = exports.planBody = exports.senderTokensFrom = exports.resolveHistory = exports.analyze = exports.folderThreadResolver = exports.corpusThreadResolver = exports.matchBlocks = exports.buildHistoryDocument = exports.DEFAULT_PARSE_OPTIONS = exports.validateParseOptions = exports.validateConfidenceConfig = exports.DEFAULT_CONFIDENCE = exports.parseMessage = void 0;
24
24
  exports.extract = extract;
25
25
  const parse_1 = require("./mime/parse");
26
+ const model_1 = require("./mime/model");
27
+ const select_1 = require("./mime/select");
28
+ const patterns_1 = require("./detect/patterns");
29
+ const confidence_1 = require("./classify/confidence");
26
30
  const analyze_1 = require("./analyze");
27
31
  const types_1 = require("./types");
28
32
  __exportStar(require("./types"), exports);
29
33
  var parse_2 = require("./mime/parse");
30
34
  Object.defineProperty(exports, "parseMessage", { enumerable: true, get: function () { return parse_2.parseMessage; } });
31
- var confidence_1 = require("./classify/confidence");
32
- Object.defineProperty(exports, "DEFAULT_CONFIDENCE", { enumerable: true, get: function () { return confidence_1.DEFAULT_CONFIDENCE; } });
35
+ var confidence_2 = require("./classify/confidence");
36
+ Object.defineProperty(exports, "DEFAULT_CONFIDENCE", { enumerable: true, get: function () { return confidence_2.DEFAULT_CONFIDENCE; } });
37
+ Object.defineProperty(exports, "validateConfidenceConfig", { enumerable: true, get: function () { return confidence_2.validateConfidenceConfig; } });
38
+ var model_2 = require("./mime/model");
39
+ Object.defineProperty(exports, "validateParseOptions", { enumerable: true, get: function () { return model_2.validateParseOptions; } });
40
+ Object.defineProperty(exports, "DEFAULT_PARSE_OPTIONS", { enumerable: true, get: function () { return model_2.DEFAULT_PARSE_OPTIONS; } });
33
41
  var history_1 = require("./match/history");
34
42
  Object.defineProperty(exports, "buildHistoryDocument", { enumerable: true, get: function () { return history_1.buildHistoryDocument; } });
35
43
  Object.defineProperty(exports, "matchBlocks", { enumerable: true, get: function () { return history_1.matchBlocks; } });
@@ -40,50 +48,20 @@ var analyze_2 = require("./analyze");
40
48
  Object.defineProperty(exports, "analyze", { enumerable: true, get: function () { return analyze_2.analyze; } });
41
49
  Object.defineProperty(exports, "resolveHistory", { enumerable: true, get: function () { return analyze_2.resolveHistory; } });
42
50
  Object.defineProperty(exports, "senderTokensFrom", { enumerable: true, get: function () { return analyze_2.senderTokensFrom; } });
51
+ var select_2 = require("./mime/select");
52
+ Object.defineProperty(exports, "planBody", { enumerable: true, get: function () { return select_2.planBody; } });
53
+ Object.defineProperty(exports, "reportableExclusions", { enumerable: true, get: function () { return select_2.reportableExclusions; } });
54
+ var patterns_2 = require("./detect/patterns");
55
+ Object.defineProperty(exports, "loadPatterns", { enumerable: true, get: function () { return patterns_2.loadPatterns; } });
56
+ Object.defineProperty(exports, "PatternAssetError", { enumerable: true, get: function () { return patterns_2.PatternAssetError; } });
43
57
  /**
44
- * Choose the text and HTML parts that hold the message body.
58
+ * Classifier assets are validated when the package is required, not when a message arrives.
45
59
  *
46
- * The largest candidate of each type wins. A message can carry several text parts, for example a
47
- * gateway appended disclaimer in `multipart/mixed(alternative(P,H), P)`, and the body is the large
48
- * one. Attachments and parts inside a forwarded `message/rfc822` are excluded: an embedded message
49
- * is content to be classified, not the container's own body.
60
+ * Missing or corrupt pattern files are an installation defect. Discovering that on the thousandth
61
+ * message, as one more degraded result, is far worse than discovering it at startup: every message
62
+ * until then came back looking like new content, because nothing could be recognised as history.
50
63
  */
51
- function selectBodyParts(message) {
52
- const insideEmbedded = new Set();
53
- for (const part of message.parts) {
54
- if (!part.rfc822 && !part.embeddedRoot) {
55
- continue;
56
- }
57
- for (const other of message.parts) {
58
- let cursor = other;
59
- while (cursor?.parentId) {
60
- if (cursor.parentId === part.partId) {
61
- insideEmbedded.add(other.partId);
62
- break;
63
- }
64
- cursor = message.partsById.get(cursor.parentId);
65
- }
66
- }
67
- }
68
- let text = null;
69
- let html = null;
70
- for (const part of message.parts) {
71
- if (part.disposition === 'attachment' || !part.decoded || insideEmbedded.has(part.partId)) {
72
- continue;
73
- }
74
- if (part.contentType === 'text/plain') {
75
- if (!text || part.decoded.text.length > (text.decoded?.text.length ?? 0)) {
76
- text = part;
77
- }
78
- }
79
- else if (part.contentType === 'text/html') {
80
- if (!html || part.decoded.text.length > (html.decoded?.text.length ?? 0)) {
81
- html = part;
82
- }
83
- }
84
- }
85
- return { text, html };
86
- }
64
+ (0, patterns_1.loadPatterns)();
87
65
  /**
88
66
  * Extract the conversationally relevant content of a raw RFC 5322 message.
89
67
  *
@@ -105,7 +83,9 @@ function degraded(text, warnings) {
105
83
  confidence: 0.5,
106
84
  visibility: 'show',
107
85
  reasons: ['degraded_to_unknown'],
108
- source: { mimePart: 'TEXT', representation: 'text', blockIndex: 0, start: 0, end: text.length }
86
+ // No MIME tree was produced, so there is no part to name. Inventing one, which
87
+ // this used to do, points a reviewer at a part that does not exist.
88
+ source: { kind: 'raw-message', start: 0, end: text.length }
109
89
  }
110
90
  ]
111
91
  : [],
@@ -115,39 +95,93 @@ function degraded(text, warnings) {
115
95
  originalAvailable: true,
116
96
  primaryRepresentation: 'none',
117
97
  extractorVersion: types_1.EXTRACTOR_VERSION,
118
- historyUsed: false
98
+ historyUsed: false,
99
+ // Threading headers are exactly what a failed parse could not read. Reply status is left
100
+ // false and the uncertainty is made observable, rather than guessed at with a substring
101
+ // search over the raw bytes.
102
+ isReply: false
119
103
  };
120
104
  }
121
105
  async function extract(raw, options = {}) {
106
+ // Assets first, then options. Both are checked outside the fail-soft path, because neither is
107
+ // a property of the message and both would otherwise repeat silently on every one of them.
108
+ (0, patterns_1.loadPatterns)();
109
+ // Validated before any work, so a bad option fails on the first message rather than producing
110
+ // subtly wrong results on every message.
111
+ const parseOptions = (0, model_1.validateParseOptions)(options.parse);
112
+ const confidence = (0, confidence_1.validateConfidenceConfig)(options.confidence);
122
113
  const buffer = typeof raw === 'string' ? Buffer.from(raw) : raw;
114
+ if (buffer.length > parseOptions.maxMessageBytes) {
115
+ // A circuit breaker the caller asked for. Not an error: an oversized message is input, and
116
+ // input degrades rather than throwing. Nothing was read, so nothing is returned, and the
117
+ // caller still holds the original.
118
+ return degraded('', [
119
+ { code: 'input_limit_exceeded', detail: `maxMessageBytes (${parseOptions.maxMessageBytes}), message was ${buffer.length}` },
120
+ { code: 'extraction_degraded' },
121
+ { code: 'reply_status_unknown' }
122
+ ]);
123
+ }
123
124
  let message;
124
125
  try {
125
- message = await (0, parse_1.parseMessage)(buffer, options.parse);
126
+ message = await (0, parse_1.parseMessage)(buffer, parseOptions);
126
127
  }
127
128
  catch (err) {
128
129
  return degraded(buffer.toString('utf8'), [
129
130
  { code: 'mime_parse_error', detail: err instanceof Error ? err.message.slice(0, 200) : 'unknown' },
130
- { code: 'extraction_degraded' }
131
+ { code: 'extraction_degraded' },
132
+ { code: 'reply_status_unknown' }
131
133
  ]);
132
134
  }
133
- const parts = selectBodyParts(message);
135
+ const plan = (0, select_1.planBody)(message);
136
+ // A tree that failed to parse must not come back as nothing.
137
+ //
138
+ // `parseMessage()` never rejects: it records the failure as a warning and returns whatever it
139
+ // salvaged. When it salvaged no parts at all, the body plan is empty, and the result used to be
140
+ // zero segments plus `no_body_parts` even though the raw message plainly held text. That is the
141
+ // same defect as the malformed HTML fallback, one stage earlier, and with the same shape: total
142
+ // content loss whose only trace is a warning.
143
+ if (!plan.sections.length && message.warnings.some(warning => warning.code === 'mime_parse_error')) {
144
+ const text = buffer.toString('utf8');
145
+ if (text.trim()) {
146
+ return degraded(text, [
147
+ ...message.warnings,
148
+ { code: 'extraction_degraded', detail: 'no MIME body could be recovered' },
149
+ { code: 'reply_status_unknown' }
150
+ ]);
151
+ }
152
+ }
153
+ // Every eligible inline body part the plan leaves out is named. Silent substitution is the
154
+ // failure mode this replaced: a long inline footer used to displace a short authored reply with
155
+ // nothing in the result to say so. Unused alternative members, attachments and embedded
156
+ // messages are excluded by a written rule and are not reported, because they are not losses.
157
+ const omissions = (0, select_1.reportableExclusions)(plan).map(entry => ({
158
+ code: 'body_section_not_selected',
159
+ mimePart: entry.partId,
160
+ detail: entry.reason
161
+ }));
162
+ // The whole plan goes through, in document order. Composition happens inside analyze() so that
163
+ // a caller who already has a parsed multipart message can express exactly the same thing.
164
+ const sections = plan.sections.map(section => ({
165
+ text: section.text?.decoded?.text ?? null,
166
+ html: section.html?.decoded?.text ?? null,
167
+ ...(section.text ? { textPartId: section.text.partId } : {}),
168
+ ...(section.html ? { htmlPartId: section.html.partId } : {}),
169
+ role: section.role
170
+ }));
134
171
  const result = await (0, analyze_1.analyze)({
135
- text: parts.text?.decoded?.text ?? null,
136
- html: parts.html?.decoded?.text ?? null,
172
+ sections,
137
173
  subject: message.headers.subject,
138
174
  from: message.headers.from,
139
175
  inReplyTo: message.headers.inReplyTo,
140
- references: message.headers.references,
141
- ...(parts.text ? { textPartId: parts.text.partId } : {}),
142
- ...(parts.html ? { htmlPartId: parts.html.partId } : {})
176
+ references: message.headers.references
143
177
  }, {
144
- ...(options.confidence ? { confidence: options.confidence } : {}),
178
+ confidence,
145
179
  ...(options.history ? { history: options.history } : {}),
146
180
  ...(options.historyDocuments ? { historyDocuments: options.historyDocuments } : {}),
147
181
  ...(options.explain ? { explain: true } : {})
148
182
  });
149
183
  // MIME level warnings belong to the message, not to the body analysis.
150
- const warnings = [...message.warnings, ...result.warnings];
184
+ const warnings = [...message.warnings, ...omissions, ...result.warnings];
151
185
  return {
152
186
  segments: result.segments,
153
187
  hiddenSegments: result.hiddenSegments,
@@ -157,6 +191,10 @@ async function extract(raw, options = {}) {
157
191
  primaryRepresentation: result.primaryRepresentation,
158
192
  extractorVersion: result.extractorVersion,
159
193
  historyUsed: result.historyUsed,
194
+ isReply: result.isReply,
195
+ // `satisfies` rather than a bare return: an omitted mandatory field then fails the build
196
+ // instead of quietly disappearing from the public result, which is how `isReply` went
197
+ // missing from this entry point while the README documented it.
160
198
  ...(result.diagnostics ? { diagnostics: { ...result.diagnostics, structure: message.structure } } : {})
161
199
  };
162
200
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}