@zone-eu/mailsplit 5.4.9 → 5.4.11

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/lib/types.d.ts ADDED
@@ -0,0 +1,285 @@
1
+ import type { PassThrough, Transform } from 'node:stream';
2
+ import type Headers = require('./headers');
3
+
4
+ /** Value that is either present as `T` or explicitly unavailable as `false`. */
5
+ export type Maybe<T> = T | false;
6
+
7
+ /** Single item in an IMAP-style MIME part number. */
8
+ export type PartNumberItem = number | 'TEXT';
9
+
10
+ /** IMAP-style path to a MIME part, for example `[1, 2, 'TEXT']`. */
11
+ export type PartNumber = PartNumberItem[];
12
+
13
+ /** Options passed through to libmime instances created by this package. */
14
+ export interface LibmimeOptions {
15
+ /** Optional iconv-compatible implementation used by libmime for charset conversion. */
16
+ Iconv?: unknown;
17
+ }
18
+
19
+ /** Configuration for `MessageSplitter` and MIME node parsing. */
20
+ export interface SplitterOptions extends LibmimeOptions {
21
+ /** Treat `message/rfc822` parts as leaf nodes instead of parsing embedded messages. */
22
+ ignoreEmbedded?: boolean;
23
+
24
+ /** Parse embedded messages as inline unless their disposition is `attachment`. */
25
+ defaultInlineEmbedded?: boolean;
26
+
27
+ /** Maximum header block size, in bytes, allowed for a single MIME node. */
28
+ maxHeadSize?: number;
29
+
30
+ /** Maximum number of MIME child nodes accepted before parsing fails. */
31
+ maxChildNodes?: number;
32
+ }
33
+
34
+ /** Configuration for `ChunkedPassthrough`. */
35
+ export interface ChunkedPassthroughOptions {
36
+ /** Buffered byte threshold for non-final chunks. Defaults to 64 KiB. */
37
+ chunkSize?: number;
38
+ }
39
+
40
+ /** Configuration for `FlowedDecoder`. */
41
+ export interface FlowedDecoderOptions extends LibmimeOptions {
42
+ /** Whether format=flowed uses RFC 3676 `DelSp=yes` space deletion semantics. */
43
+ delSp?: boolean;
44
+
45
+ /** Source Content-Transfer-Encoding hint used during format=flowed handling. */
46
+ encoding?: string | false;
47
+ }
48
+
49
+ /** Parsed raw header line with a normalized lookup key. */
50
+ export interface HeaderLine {
51
+ /** Lower-case header key used for comparisons and lookups. */
52
+ key: string;
53
+
54
+ /** Full header line, including the original field name, value, and any folded continuations. */
55
+ line: string;
56
+ }
57
+
58
+ /** Decoded structured header value returned by libmime. */
59
+ export interface DecodedHeader {
60
+ /** Header key returned by libmime for the decoded value. */
61
+ key: string;
62
+
63
+ /** Unicode decoded header value. */
64
+ value: string;
65
+ }
66
+
67
+ /** MIME node emitted by `MessageSplitter` and accepted by `MessageJoiner`. */
68
+ export interface MimeNode {
69
+ /** Discriminator identifying this chunk as a MIME node. */
70
+ type: 'node';
71
+
72
+ /** Whether this node is the root message node. */
73
+ root: boolean;
74
+
75
+ /** Parent MIME node, or `false` for the root node. */
76
+ parentNode: MimeNode | false;
77
+
78
+ /** Boundary used by this multipart node, or `false` when not multipart. */
79
+ _boundary: Buffer | false;
80
+
81
+ /** Boundary inherited from the parent multipart node, or `false` when absent. */
82
+ _parentBoundary: Buffer | false;
83
+
84
+ /** Length, in bytes, of the raw header block collected for this node. */
85
+ _headerlen: number;
86
+
87
+ /** Multipart subtype such as `mixed` or `alternative`, or `false` for leaf nodes. */
88
+ multipart: string | false;
89
+
90
+ /** Content-Transfer-Encoding value, normalized to lower case, or `false` when absent. */
91
+ encoding: string | false;
92
+
93
+ /** Parsed and mutable header collection, available after headers are parsed. */
94
+ headers: Headers | false;
95
+
96
+ /** MIME content type such as `text/plain`, or `false` when unavailable. */
97
+ contentType: string | false;
98
+
99
+ /** Charset parameter from Content-Type, or `false` when absent. */
100
+ charset: string | false;
101
+
102
+ /** Content-Disposition value such as `inline` or `attachment`, or `false` when absent. */
103
+ disposition: string | false;
104
+
105
+ /** Decoded filename from Content-Disposition or Content-Type parameters, or `false` when absent. */
106
+ filename: string | false;
107
+
108
+ /** Whether this node is `text/*` with `format=flowed`. */
109
+ flowed: boolean;
110
+
111
+ /** Whether flowed text uses `delsp=yes`. */
112
+ delSp: boolean;
113
+
114
+ /** Splitter configuration used when parsing this node. */
115
+ config: SplitterOptions;
116
+
117
+ /** Resolved IMAP-style part number for this node, or `false` before resolution. */
118
+ partNr: PartNumber | false;
119
+
120
+ /** Number of child part numbers allocated by this node. */
121
+ childPartNumbers: number;
122
+
123
+ /** Whether this node's content type is `message/rfc822`. */
124
+ rfc822: boolean;
125
+
126
+ /** Whether an embedded `message/rfc822` node was parsed as a nested message. */
127
+ messageNode?: boolean;
128
+
129
+ /**
130
+ * Builds the next child part number for this node.
131
+ *
132
+ * @param provided Optional explicit part number item to append.
133
+ * @returns Resolved MIME part number.
134
+ */
135
+ getPartNr(provided?: PartNumberItem): PartNumber;
136
+
137
+ /**
138
+ * Appends one raw header line to this node while parsing.
139
+ *
140
+ * @param line Raw header line bytes; falsy values are ignored.
141
+ * @returns Nothing.
142
+ */
143
+ addHeaderChunk(line?: Buffer | false): void;
144
+
145
+ /**
146
+ * Parses collected header bytes and populates MIME metadata fields.
147
+ *
148
+ * @returns Nothing.
149
+ */
150
+ parseHeaders(): void;
151
+
152
+ /**
153
+ * Builds this node's header block.
154
+ *
155
+ * @returns Header bytes ending with an empty header/body separator line.
156
+ */
157
+ getHeaders(): Buffer;
158
+
159
+ /**
160
+ * Sets or updates the Content-Type header value.
161
+ *
162
+ * @param contentType MIME content type to set; falsy keeps the current type.
163
+ * @returns Nothing.
164
+ */
165
+ setContentType(contentType?: string | false): void;
166
+
167
+ /**
168
+ * Sets, updates, or removes the Content-Type charset parameter.
169
+ *
170
+ * @param charset Charset to set; falsy removes it when possible.
171
+ * @returns Nothing.
172
+ */
173
+ setCharset(charset?: string | false): void;
174
+
175
+ /**
176
+ * Sets, updates, or removes the filename parameter.
177
+ *
178
+ * @param filename Filename to set; falsy removes it when possible.
179
+ * @returns Nothing.
180
+ */
181
+ setFilename(filename?: string | false): void;
182
+
183
+ /**
184
+ * Creates a decoder stream for this node's transfer encoding.
185
+ *
186
+ * @returns Transform stream that outputs decoded content bytes.
187
+ */
188
+ getDecoder(): Transform | PassThrough;
189
+
190
+ /**
191
+ * Creates an encoder stream and updates the Content-Transfer-Encoding header when needed.
192
+ *
193
+ * @param encoding Target transfer encoding; defaults to the node's current encoding.
194
+ * @returns Transform stream that outputs encoded content bytes.
195
+ */
196
+ getEncoder(encoding?: string | false): Transform | PassThrough;
197
+ }
198
+
199
+ /** Data or body bytes emitted by `MessageSplitter`. */
200
+ export interface MessageChunk {
201
+ /** MIME node that owns or precedes this chunk. */
202
+ node: MimeNode;
203
+
204
+ /** Chunk kind: multipart structure bytes (`data`) or leaf content bytes (`body`). */
205
+ type: 'data' | 'body';
206
+
207
+ /** Raw chunk bytes. */
208
+ value: Buffer;
209
+ }
210
+
211
+ /** Sentinel input used internally to finish a pending rewriter or streamer node. */
212
+ export interface EmptyChunk {
213
+ /** Discriminator for an empty control chunk. */
214
+ type: 'none';
215
+ }
216
+
217
+ /** Object emitted by `MessageSplitter`: either a MIME node or a data/body byte chunk. */
218
+ export type SplitterChunk = MimeNode | MessageChunk;
219
+
220
+ /** Object accepted by rewriter and streamer transforms. */
221
+ export type RewriterInput = SplitterChunk | EmptyChunk;
222
+
223
+ /**
224
+ * Predicate used to select MIME nodes.
225
+ *
226
+ * @param node MIME node being inspected.
227
+ * @returns `true` to process the node, otherwise `false`.
228
+ */
229
+ export type FilterFunc = (node: MimeNode) => boolean;
230
+
231
+ /** Error object that may include a Node-style string error code. */
232
+ export type ErrorWithCode = Error & { code?: string };
233
+
234
+ /**
235
+ * Callback that resumes processing after a selected node stream has ended.
236
+ *
237
+ * @returns Nothing.
238
+ */
239
+ export type ContinueCallback = () => void;
240
+
241
+ /** Content transform stream used for decoded or encoded node bodies. */
242
+ export type ContentStream = Transform | PassThrough;
243
+
244
+ /** Decoder stream with an internal readable-state guard used by rewriter/streamer. */
245
+ export type DecoderStream = ContentStream & { $reading?: boolean };
246
+
247
+ /** Internal grouping state used while splitter coalesces adjacent chunks. */
248
+ export interface SplitterGroup {
249
+ /** MIME node associated with the group, when one exists. */
250
+ node?: MimeNode;
251
+
252
+ /** Group kind currently being accumulated. */
253
+ type: 'none' | 'node' | 'data' | 'body';
254
+
255
+ /** Buffered raw bytes for `data` or `body` groups. */
256
+ value?: Buffer;
257
+ }
258
+
259
+ /** Payload emitted with `NodeRewriter`'s `node` event. */
260
+ export interface RewriterNode {
261
+ /** Selected MIME node whose body can be rewritten. */
262
+ node: MimeNode;
263
+
264
+ /** Stream that yields decoded original body bytes. */
265
+ decoder: Transform;
266
+
267
+ /** Stream that accepts replacement decoded bytes and emits properly encoded body bytes. */
268
+ encoder: Transform;
269
+ }
270
+
271
+ /** Payload emitted with `NodeStreamer`'s `node` event. */
272
+ export interface StreamerNode {
273
+ /** Selected MIME node whose body is being streamed. */
274
+ node: MimeNode;
275
+
276
+ /** Stream that yields decoded original body bytes. */
277
+ decoder: Transform;
278
+
279
+ /**
280
+ * Signals that the consumer has finished reading the selected node.
281
+ *
282
+ * @returns Nothing.
283
+ */
284
+ done: () => void;
285
+ }
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "@zone-eu/mailsplit",
3
- "version": "5.4.9",
3
+ "version": "5.4.11",
4
4
  "description": "Split email messages into an object stream",
5
5
  "main": "index.js",
6
+ "types": "index.d.ts",
6
7
  "directories": {
7
8
  "test": "test"
8
9
  },
9
10
  "scripts": {
10
11
  "test": "grunt",
11
- "update": "rm -rf node_modules package-lock.json && ncu -u && npm install"
12
+ "update": "rm -rf node_modules package-lock.json && ncu -u && npm install",
13
+ "typecheck": "tsc -p tsconfig.json"
12
14
  },
13
15
  "author": "Andris Reinman",
14
16
  "license": "(MIT OR EUPL-1.1+)",
@@ -18,18 +20,26 @@
18
20
  "libqp": "2.1.1"
19
21
  },
20
22
  "devDependencies": {
23
+ "@types/eslint": "9.6.1",
24
+ "@types/eslint-config-prettier": "6.11.3",
25
+ "@types/grunt": "0.4.32",
26
+ "@types/libmime": "5.3.0",
27
+ "@types/libqp": "1.1.3",
28
+ "@types/node": "25.7.0",
21
29
  "eslint": "8.29.0",
22
30
  "eslint-config-nodemailer": "1.2.0",
23
31
  "eslint-config-prettier": "9.1.0",
24
- "grunt": "1.6.1",
32
+ "grunt": "1.6.2",
25
33
  "grunt-cli": "1.5.0",
26
34
  "grunt-contrib-nodeunit": "5.0.0",
27
35
  "grunt-eslint": "24.0.1",
28
- "random-message": "1.1.0"
36
+ "random-message": "1.1.0",
37
+ "typescript": "6.0.3"
29
38
  },
30
39
  "files": [
31
40
  "lib",
32
- "index.js"
41
+ "index.js",
42
+ "index.d.ts"
33
43
  ],
34
44
  "repository": {
35
45
  "type": "git",