🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@zone-eu/mailsplit

Package Overview
Dependencies
Maintainers
2
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zone-eu/mailsplit - npm Package Compare versions

Comparing version
5.4.10
to
5.4.11
+56
-0
index.d.ts

@@ -12,8 +12,21 @@ /// <reference types="node" />

export {
/** Splits raw message bytes into MIME node and content chunks. */
Splitter,
/** Joins MIME node and content chunks back into raw message bytes. */
Joiner,
/** Rewrites body content for MIME nodes selected by a filter function. */
Rewriter,
/** Streams decoded body content for MIME nodes selected by a filter function. */
Streamer,
/** Buffers byte input and emits larger Buffer chunks. */
ChunkedPassthrough,
/** Parses, mutates, and rebuilds message header blocks. */
Headers,
/** Represents one parsed MIME node and its header/body metadata. */
MimeNode

@@ -23,24 +36,67 @@ };

export type {
/** Value that is either present as `T` or explicitly unavailable as `false`. */
Maybe,
/** Single item in an IMAP-style MIME part number. */
PartNumberItem,
/** IMAP-style path to a MIME part. */
PartNumber,
/** Options passed through to libmime instances. */
LibmimeOptions,
/** Configuration for `Splitter` and MIME node parsing. */
SplitterOptions,
/** Configuration for `ChunkedPassthrough`. */
ChunkedPassthroughOptions,
/** Configuration for format=flowed decoding. */
FlowedDecoderOptions,
/** Parsed raw header line with a normalized lookup key. */
HeaderLine,
/** Decoded structured header value. */
DecodedHeader,
/** MIME node shape emitted by `Splitter`. */
MimeNode,
/** Data or body bytes emitted by `Splitter`. */
MessageChunk,
/** Sentinel input used internally by rewriter/streamer transforms. */
EmptyChunk,
/** Object emitted by `Splitter`. */
SplitterChunk,
/** Object accepted by rewriter and streamer transforms. */
RewriterInput,
/** Predicate used to select MIME nodes. */
FilterFunc,
/** Error object that may include a Node-style string code. */
ErrorWithCode,
/** Callback that resumes processing after a selected node stream ends. */
ContinueCallback,
/** Content transform stream used for decoded or encoded node bodies. */
ContentStream,
/** Decoder stream with an internal readable-state guard. */
DecoderStream,
/** Internal splitter grouping state. */
SplitterGroup,
/** Payload emitted with `Rewriter`'s `node` event. */
RewriterNode,
/** Payload emitted with `Streamer`'s `node` event. */
StreamerNode
} from './lib/types';
import { Transform } from 'node:stream';
import type { ChunkedPassthroughOptions } from './types';
/** Transform stream that buffers byte input and emits larger Buffer chunks. */
declare class ChunkedPassthrough extends Transform {
/**
* Creates a chunking passthrough transform that accepts Buffer input and emits Buffer chunks.
*
* @param options Optional chunk size configuration.
*/
constructor(options?: ChunkedPassthroughOptions);
/**
* Registers a listener for buffered byte chunks.
*
* @param event Event name.
* @param listener Receives each buffered Buffer chunk.
* @returns This passthrough instance.
*/
on(event: 'data', listener: (data: Buffer) => void): this;
/**
* Registers a one-time listener for the next buffered byte chunk.
*
* @param event Event name.
* @param listener Receives the next buffered Buffer chunk.
* @returns This passthrough instance.
*/
once(event: 'data', listener: (data: Buffer) => void): this;
/**
* Adds a listener for buffered byte chunks.
*
* @param event Event name.
* @param listener Receives each buffered Buffer chunk.
* @returns This passthrough instance.
*/
addListener(event: 'data', listener: (data: Buffer) => void): this;
/**
* Prepends a listener for buffered byte chunks.
*
* @param event Event name.
* @param listener Receives each buffered Buffer chunk.
* @returns This passthrough instance.
*/
prependListener(event: 'data', listener: (data: Buffer) => void): this;
/**
* Emits a buffered byte chunk.
*
* @param event Event name.
* @param data Buffer chunk to emit.
* @returns `true` when the event had listeners.
*/
emit(event: 'data', data: Buffer): boolean;

@@ -11,0 +57,0 @@ }

+3
-0

@@ -5,2 +5,5 @@ 'use strict';

/**
* Transform stream that buffers byte input and emits larger Buffer chunks.
*/
class ChunkedPassthrough extends Transform {

@@ -7,0 +10,0 @@ /**

import { Transform } from 'node:stream';
import type { FlowedDecoderOptions } from './types';
/** Transform stream that decodes `text/plain; format=flowed` content. */
declare class FlowedDecoder extends Transform {
/**
* Creates a flowed text decoder that accepts encoded text bytes and emits decoded Buffer chunks.
*
* @param config Optional flowed text and charset decoding settings.
*/
constructor(config?: FlowedDecoderOptions);
/**
* Registers a listener for decoded flowed text bytes.
*
* @param event Event name.
* @param listener Receives decoded Buffer chunks.
* @returns This decoder instance.
*/
on(event: 'data', listener: (data: Buffer) => void): this;
/**
* Registers a one-time listener for the next decoded flowed text chunk.
*
* @param event Event name.
* @param listener Receives the next decoded Buffer chunk.
* @returns This decoder instance.
*/
once(event: 'data', listener: (data: Buffer) => void): this;
/**
* Adds a listener for decoded flowed text bytes.
*
* @param event Event name.
* @param listener Receives decoded Buffer chunks.
* @returns This decoder instance.
*/
addListener(event: 'data', listener: (data: Buffer) => void): this;
/**
* Prepends a listener for decoded flowed text bytes.
*
* @param event Event name.
* @param listener Receives decoded Buffer chunks.
* @returns This decoder instance.
*/
prependListener(event: 'data', listener: (data: Buffer) => void): this;
/**
* Emits a decoded flowed text chunk.
*
* @param event Event name.
* @param data Buffer chunk to emit.
* @returns `true` when the event had listeners.
*/
emit(event: 'data', data: Buffer): boolean;

@@ -11,0 +57,0 @@ }

+4
-5
'use strict';
// Helper class to rewrite nodes with specific mime type
// Helper class to decode format=flowed text nodes

@@ -13,10 +13,9 @@ const Transform = require('stream').Transform;

/**
* Really bad "stream" transform to parse format=flowed content
* Transform stream that decodes text/plain format=flowed content.
*
* @constructor
* @param {FlowedDecoderOptions} [config]
* @param {FlowedDecoderOptions} [config] Flowed text and charset decoding settings.
*/
class FlowedDecoder extends Transform {
/**
* @param {FlowedDecoderOptions} [config]
* @param {FlowedDecoderOptions} [config] Flowed text and charset decoding settings.
*/

@@ -23,0 +22,0 @@ constructor(config) {

import type { DecodedHeader, HeaderLine, LibmimeOptions } from './types';
/** Mutable parser and builder for RFC-style message header blocks. */
declare class Headers {
/** Whether header lines have been modified after construction. */
changed: boolean;
/** Original unparsed header source, or `false` when constructed from parsed lines. */
headers: string | Buffer | false;
/** Whether `headers` has been parsed into `lines`. */
parsed: boolean;
/** Parsed header lines, or `false` until parsing occurs. */
lines: HeaderLine[] | false;
/** MBOX `From ` prefix line, or `false` when absent. */
mbox: string | false;
/** HTTP request prefix line, or `false` when absent. */
http: string | false;
/**
* Creates a mutable header collection.
*
* @param headers Raw header bytes/string, already parsed header lines, or `false` for an empty collection.
* @param config Optional libmime configuration.
*/
constructor(headers?: string | Buffer | HeaderLine[] | false, config?: LibmimeOptions);
/**
* Checks whether at least one header with the requested key exists.
*
* @param key Header field name to find, case-insensitively.
* @returns `true` when the header exists.
*/
hasHeader(key: string): boolean;
/**
* Gets all raw header lines for a key.
*
* @param key Header field name to find, case-insensitively.
* @returns Full decoded header lines, including field names.
*/
get(key: string): string[];
/**
* Gets all decoded structured header values for a key.
*
* @param key Header field name to decode, case-insensitively.
* @returns Decoded header entries with key and value fields.
*/
getDecoded(key: string): DecodedHeader[];
/**
* Gets the first decoded header value for a key.
*
* @param key Header field name to find, case-insensitively.
* @returns Trimmed decoded value, or an empty string when the header is absent.
*/
getFirst(key: string): string;
/**
* Gets the mutable parsed header list.
*
* @returns Parsed header lines in message order.
*/
getList(): HeaderLine[];
/**
* Adds a folded header line.
*
* @param key Header field name to add.
* @param value Header value; `undefined` leaves the collection unchanged.
* @param index Insertion index, where omitted or less than 1 inserts at the top.
* @returns Nothing.
*/
add(key: string, value?: string | number | Buffer, index?: number): void;
/**
* Adds a preformatted header line.
*
* @param key Header field name used for normalized lookup.
* @param line Full header line to insert; falsy values leave the collection unchanged.
* @param index Insertion index, where omitted or less than 1 inserts at the top.
* @returns Nothing.
*/
addFormatted(key: string, line?: string | Buffer | false, index?: number): void;
/**
* Removes all headers matching a key.
*
* @param key Header field name to remove, case-insensitively.
* @returns Nothing.
*/
remove(key: string): void;
/**
* Replaces matching headers with a new folded header value.
*
* @param key Header field name to update.
* @param value Header value to write; `undefined` removes matching values without adding a replacement.
* @param relativeIndex Optional zero-based index among headers with the same key.
* @returns Nothing.
*/
update(key: string, value?: string | number | Buffer, relativeIndex?: number): void;
/**
* Builds a raw header block.
*
* @param lineEnd Line ending to use when rebuilding changed headers; defaults to CRLF.
* @returns Header bytes ending with an empty header/body separator line.
*/
build(lineEnd?: string | false): Buffer;

@@ -22,0 +115,0 @@ }

@@ -12,9 +12,9 @@ 'use strict';

/**
* Class Headers to parse and handle message headers. Headers instance allows to
* check existing, delete or add new headers
* Parses and builds message headers. A Headers instance allows callers to
* inspect, delete, update, and add header lines.
*/
class Headers {
/**
* @param {string | Buffer | HeaderLine[] | false} [headers]
* @param {LibmimeOptions} [config]
* @param {string | Buffer | HeaderLine[] | false} [headers] Raw header source or already parsed lines.
* @param {LibmimeOptions} [config] Optional libmime configuration.
*/

@@ -21,0 +21,0 @@ constructor(headers, config) {

import { Transform } from 'node:stream';
/** Transform stream that joins splitter objects back into raw email bytes. */
declare class MessageJoiner extends Transform {
/**
* Creates a joiner that accepts splitter objects and emits Buffer chunks.
*/
constructor();
/**
* Registers a listener for generated message bytes.
*
* @param event Event name.
* @param listener Receives each generated Buffer chunk.
* @returns This joiner instance.
*/
on(event: 'data', listener: (data: Buffer) => void): this;
/**
* Registers a one-time listener for generated message bytes.
*
* @param event Event name.
* @param listener Receives the next generated Buffer chunk.
* @returns This joiner instance.
*/
once(event: 'data', listener: (data: Buffer) => void): this;
/**
* Adds a listener for generated message bytes.
*
* @param event Event name.
* @param listener Receives each generated Buffer chunk.
* @returns This joiner instance.
*/
addListener(event: 'data', listener: (data: Buffer) => void): this;
/**
* Prepends a listener for generated message bytes.
*
* @param event Event name.
* @param listener Receives each generated Buffer chunk.
* @returns This joiner instance.
*/
prependListener(event: 'data', listener: (data: Buffer) => void): this;
/**
* Emits a generated message byte chunk.
*
* @param event Event name.
* @param data Buffer chunk to emit.
* @returns `true` when the event had listeners.
*/
emit(event: 'data', data: Buffer): boolean;

@@ -10,0 +54,0 @@ }

@@ -7,3 +7,9 @@ 'use strict';

/**
* Transform stream that joins splitter objects back into raw message bytes.
*/
class MessageJoiner extends Transform {
/**
* Creates a joiner that accepts splitter objects and emits Buffer chunks.
*/
constructor() {

@@ -10,0 +16,0 @@ let options = {

import { Transform } from 'node:stream';
import type { SplitterChunk, SplitterOptions } from './types';
/** Transform stream that splits raw email bytes into MIME node and content chunks. */
declare class MessageSplitter extends Transform {
/**
* Creates a splitter that accepts Buffer input and emits `SplitterChunk` objects.
*
* @param config Optional parser limits and embedded-message behavior.
*/
constructor(config?: SplitterOptions);
/**
* Registers a listener for parsed splitter chunks.
*
* @param event Event name.
* @param listener Receives each parsed MIME node, data chunk, or body chunk.
* @returns This splitter instance.
*/
on(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Registers a one-time listener for the next parsed splitter chunk.
*
* @param event Event name.
* @param listener Receives the next parsed MIME node, data chunk, or body chunk.
* @returns This splitter instance.
*/
once(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Adds a listener for parsed splitter chunks.
*
* @param event Event name.
* @param listener Receives each parsed MIME node, data chunk, or body chunk.
* @returns This splitter instance.
*/
addListener(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Prepends a listener for parsed splitter chunks.
*
* @param event Event name.
* @param listener Receives each parsed MIME node, data chunk, or body chunk.
* @returns This splitter instance.
*/
prependListener(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Emits a parsed splitter chunk.
*
* @param event Event name.
* @param data MIME node, data chunk, or body chunk to emit.
* @returns `true` when the event had listeners.
*/
emit(event: 'data', data: SplitterChunk): boolean;

@@ -11,0 +57,0 @@ }

@@ -19,2 +19,5 @@ 'use strict';

/**
* Transform stream that splits raw email bytes into MIME node and content chunks.
*/
class MessageSplitter extends Transform {

@@ -63,3 +66,8 @@ /**

/** @param {MessageChunk} data */
/**
* Removes a pending line break from body data that belongs to a following boundary.
*
* @param {MessageChunk} data Body chunk to adjust in place.
* @returns {void}
*/
let checkTrailingLinebreak = data => {

@@ -93,2 +101,7 @@ if (data.type === 'body' && data.node.parentNode && data.value && data.value.length) {

/**
* Iterates the current input chunk line by line and emits parsed groups.
*
* @returns {void}
*/
let iterateData = () => {

@@ -95,0 +108,0 @@ for (let len = chunk.length; i < len; i++) {

import type { ContentStream, MimeNode as MimeNodeShape, PartNumber, PartNumberItem, SplitterOptions } from './types';
import type Headers = require('./headers');
/** Parsed MIME node with mutable headers and content encoding helpers. */
declare class MimeNode implements MimeNodeShape {
/** Discriminator identifying this chunk as a MIME node. */
type: 'node';
/** Whether this node is the root message node. */
root: boolean;
/** Parent MIME node, or `false` for the root node. */
parentNode: MimeNodeShape | false;
/** Boundary used by this multipart node, or `false` when not multipart. */
_boundary: Buffer | false;
/** Boundary inherited from the parent multipart node, or `false` when absent. */
_parentBoundary: Buffer | false;
/** Length, in bytes, of the raw header block collected for this node. */
_headerlen: number;
/** Multipart subtype such as `mixed` or `alternative`, or `false` for leaf nodes. */
multipart: string | false;
/** Content-Transfer-Encoding value, normalized to lower case, or `false` when absent. */
encoding: string | false;
/** Parsed and mutable header collection, available after headers are parsed. */
headers: Headers | false;
/** MIME content type such as `text/plain`, or `false` when unavailable. */
contentType: string | false;
/** Charset parameter from Content-Type, or `false` when absent. */
charset: string | false;
/** Content-Disposition value such as `inline` or `attachment`, or `false` when absent. */
disposition: string | false;
/** Decoded filename from Content-Disposition or Content-Type parameters, or `false` when absent. */
filename: string | false;
/** Whether this node is `text/*` with `format=flowed`. */
flowed: boolean;
/** Whether flowed text uses `delsp=yes`. */
delSp: boolean;
/** Splitter configuration used when parsing this node. */
config: SplitterOptions;
/** Resolved IMAP-style part number for this node, or `false` before resolution. */
partNr: PartNumber | false;
/** Number of child part numbers allocated by this node. */
childPartNumbers: number;
/** Whether this node's content type is `message/rfc822`. */
rfc822: boolean;
/** Whether an embedded `message/rfc822` node was parsed as a nested message. */
messageNode?: boolean;
/**
* Creates a MIME node with empty header state.
*
* @param parentNode Parent node, or `false`/omitted for the root node.
* @param config Optional splitter and libmime configuration.
*/
constructor(parentNode?: MimeNodeShape | false, config?: SplitterOptions);
/**
* Builds the next child part number for this node.
*
* @param provided Optional explicit part number item to append.
* @returns Resolved MIME part number.
*/
getPartNr(provided?: PartNumberItem): PartNumber;
/**
* Appends one raw header line to this node while parsing.
*
* @param line Raw header line bytes; falsy values are ignored.
* @returns Nothing.
*/
addHeaderChunk(line?: Buffer | false): void;
/**
* Parses collected header bytes and populates MIME metadata fields.
*
* @returns Nothing.
*/
parseHeaders(): void;
/**
* Builds this node's header block.
*
* @returns Header bytes ending with an empty header/body separator line.
*/
getHeaders(): Buffer;
/**
* Sets or updates the Content-Type header value.
*
* @param contentType MIME content type to set; falsy keeps the current type.
* @returns Nothing.
*/
setContentType(contentType?: string | false): void;
/**
* Sets, updates, or removes the Content-Type charset parameter.
*
* @param charset Charset to set; falsy removes it when possible.
* @returns Nothing.
*/
setCharset(charset?: string | false): void;
/**
* Sets, updates, or removes the filename parameter.
*
* @param filename Filename to set; falsy removes it when possible.
* @returns Nothing.
*/
setFilename(filename?: string | false): void;
/**
* Creates a decoder stream for this node's transfer encoding.
*
* @returns Transform stream that outputs decoded content bytes.
*/
getDecoder(): ContentStream;
/**
* Creates an encoder stream and updates the Content-Transfer-Encoding header when needed.
*
* @param encoding Target transfer encoding; defaults to the node's current encoding.
* @returns Transform stream that outputs encoded content bytes.
*/
getEncoder(encoding?: string | false): ContentStream;

@@ -36,0 +142,0 @@ }

@@ -21,6 +21,9 @@ 'use strict';

/**
* Parsed MIME node with mutable headers and transfer-encoding helpers.
*/
class MimeNode {
/**
* @param {MimeNodeType | false} parentNode
* @param {SplitterOptions} [config]
* @param {MimeNodeType | false} parentNode Parent node, or false for the root node.
* @param {SplitterOptions} [config] Splitter and libmime configuration.
*/

@@ -27,0 +30,0 @@ constructor(parentNode, config) {

import { Transform } from 'node:stream';
import type { FilterFunc, RewriterNode, SplitterChunk } from './types';
/** Transform stream that replaces the body content of selected MIME nodes. */
declare class NodeRewriter extends Transform {
/**
* Creates a node rewriter that accepts splitter chunks and emits rewritten splitter chunks.
*
* @param filterFunc Predicate that selects MIME nodes to rewrite.
* @param rewriteAction Optional compatibility hook stored on the instance; consumers usually handle the `node` event.
*/
constructor(filterFunc: FilterFunc, rewriteAction?: Function);
/**
* Registers a listener for rewritten splitter chunks.
*
* @param event Event name.
* @param listener Receives each outgoing MIME node, data chunk, or body chunk.
* @returns This rewriter instance.
*/
on(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Registers a listener for selected nodes.
*
* @param event Event name.
* @param listener Receives decoder and encoder streams for a selected node.
* @returns This rewriter instance.
*/
on(event: 'node', listener: (data: RewriterNode) => void): this;
/**
* Registers a one-time listener for the next rewritten splitter chunk.
*
* @param event Event name.
* @param listener Receives the next outgoing MIME node, data chunk, or body chunk.
* @returns This rewriter instance.
*/
once(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Registers a one-time listener for the next selected node.
*
* @param event Event name.
* @param listener Receives decoder and encoder streams for the next selected node.
* @returns This rewriter instance.
*/
once(event: 'node', listener: (data: RewriterNode) => void): this;
/**
* Adds a listener for rewritten splitter chunks.
*
* @param event Event name.
* @param listener Receives each outgoing MIME node, data chunk, or body chunk.
* @returns This rewriter instance.
*/
addListener(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Adds a listener for selected nodes.
*
* @param event Event name.
* @param listener Receives decoder and encoder streams for a selected node.
* @returns This rewriter instance.
*/
addListener(event: 'node', listener: (data: RewriterNode) => void): this;
/**
* Prepends a listener for rewritten splitter chunks.
*
* @param event Event name.
* @param listener Receives each outgoing MIME node, data chunk, or body chunk.
* @returns This rewriter instance.
*/
prependListener(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Prepends a listener for selected nodes.
*
* @param event Event name.
* @param listener Receives decoder and encoder streams for a selected node.
* @returns This rewriter instance.
*/
prependListener(event: 'node', listener: (data: RewriterNode) => void): this;
/**
* Emits a rewritten splitter chunk.
*
* @param event Event name.
* @param data MIME node, data chunk, or body chunk to emit.
* @returns `true` when the event had listeners.
*/
emit(event: 'data', data: SplitterChunk): boolean;
/**
* Emits a selected-node payload.
*
* @param event Event name.
* @param data Selected node payload containing decoder and encoder streams.
* @returns `true` when the event had listeners.
*/
emit(event: 'node', data: RewriterNode): boolean;

@@ -16,0 +103,0 @@ }

@@ -17,12 +17,12 @@ 'use strict';

/**
* NodeRewriter Transform stream. Updates content for all nodes with specified mime type
* NodeRewriter Transform stream. Updates content for all nodes selected by the
* filter function.
*
* @constructor
* @param {FilterFunc} filterFunc Function to select nodes to rewrite
* @param {Function} [rewriteAction] Function to run with the node content
* @param {FilterFunc} filterFunc Function that receives a MIME node and returns true to rewrite it.
* @param {Function} [rewriteAction] Optional compatibility hook stored on the instance.
*/
class NodeRewriter extends Transform {
/**
* @param {FilterFunc} filterFunc
* @param {Function} [rewriteAction]
* @param {FilterFunc} filterFunc Function that receives a MIME node and returns true to rewrite it.
* @param {Function} [rewriteAction] Optional compatibility hook stored on the instance.
*/

@@ -132,2 +132,7 @@ constructor(filterFunc, rewriteAction) {

/**
* Reads encoded replacement bytes and forwards them as body chunks.
*
* @returns {void | NodeJS.Immediate}
*/
let readFromEncoder = () => {

@@ -207,5 +212,14 @@ decoder.$reading = true;

});
flowDecoder.on('error', /** @param {Error} err */ err => {
decoder.emit('error', err);
});
flowDecoder.on(
'error',
/**
* Forwards flowed decoder errors to the replacement decoder.
*
* @param {Error} err Decoder error to forward.
* @returns {void}
*/
err => {
decoder.emit('error', err);
}
);
flowDecoder.pipe(decoder);

@@ -212,0 +226,0 @@

import { Transform } from 'node:stream';
import type { FilterFunc, SplitterChunk, StreamerNode } from './types';
/** Transform stream that exposes decoded body streams for selected MIME nodes without replacing them. */
declare class NodeStreamer extends Transform {
/**
* Creates a node streamer that accepts splitter chunks and passes them through unchanged.
*
* @param filterFunc Predicate that selects MIME nodes to stream.
* @param streamAction Optional compatibility hook stored on the instance; consumers usually handle the `node` event.
*/
constructor(filterFunc: FilterFunc, streamAction?: Function);
/**
* Registers a listener for passed-through splitter chunks.
*
* @param event Event name.
* @param listener Receives each outgoing MIME node, data chunk, or body chunk.
* @returns This streamer instance.
*/
on(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Registers a listener for selected nodes.
*
* @param event Event name.
* @param listener Receives a decoder stream and completion callback for a selected node.
* @returns This streamer instance.
*/
on(event: 'node', listener: (data: StreamerNode) => void): this;
/**
* Registers a one-time listener for the next passed-through splitter chunk.
*
* @param event Event name.
* @param listener Receives the next outgoing MIME node, data chunk, or body chunk.
* @returns This streamer instance.
*/
once(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Registers a one-time listener for the next selected node.
*
* @param event Event name.
* @param listener Receives a decoder stream and completion callback for the next selected node.
* @returns This streamer instance.
*/
once(event: 'node', listener: (data: StreamerNode) => void): this;
/**
* Adds a listener for passed-through splitter chunks.
*
* @param event Event name.
* @param listener Receives each outgoing MIME node, data chunk, or body chunk.
* @returns This streamer instance.
*/
addListener(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Adds a listener for selected nodes.
*
* @param event Event name.
* @param listener Receives a decoder stream and completion callback for a selected node.
* @returns This streamer instance.
*/
addListener(event: 'node', listener: (data: StreamerNode) => void): this;
/**
* Prepends a listener for passed-through splitter chunks.
*
* @param event Event name.
* @param listener Receives each outgoing MIME node, data chunk, or body chunk.
* @returns This streamer instance.
*/
prependListener(event: 'data', listener: (data: SplitterChunk) => void): this;
/**
* Prepends a listener for selected nodes.
*
* @param event Event name.
* @param listener Receives a decoder stream and completion callback for a selected node.
* @returns This streamer instance.
*/
prependListener(event: 'node', listener: (data: StreamerNode) => void): this;
/**
* Emits a passed-through splitter chunk.
*
* @param event Event name.
* @param data MIME node, data chunk, or body chunk to emit.
* @returns `true` when the event had listeners.
*/
emit(event: 'data', data: SplitterChunk): boolean;
/**
* Emits a selected-node payload.
*
* @param event Event name.
* @param data Selected node payload containing decoder stream and completion callback.
* @returns `true` when the event had listeners.
*/
emit(event: 'node', data: StreamerNode): boolean;

@@ -16,0 +103,0 @@ }

'use strict';
// Helper class to rewrite nodes with specific mime type
// Helper class to stream selected nodes by MIME metadata

@@ -16,12 +16,12 @@ const Transform = require('stream').Transform;

/**
* NodeRewriter Transform stream. Updates content for all nodes with specified mime type
* NodeStreamer Transform stream. Exposes decoded content for nodes selected by
* the filter function while passing the original message through unchanged.
*
* @constructor
* @param {FilterFunc} filterFunc Function to select nodes to stream
* @param {Function} [streamAction] Function to run with the node content
* @param {FilterFunc} filterFunc Function that receives a MIME node and returns true to stream it.
* @param {Function} [streamAction] Optional compatibility hook stored on the instance.
*/
class NodeStreamer extends Transform {
/**
* @param {FilterFunc} filterFunc
* @param {Function} [streamAction]
* @param {FilterFunc} filterFunc Function that receives a MIME node and returns true to stream it.
* @param {Function} [streamAction] Optional compatibility hook stored on the instance.
*/

@@ -93,2 +93,7 @@ constructor(filterFunc, streamAction) {

/**
* Resumes processing with the first chunk after the streamed node.
*
* @returns {void}
*/
let doContinue = () => {

@@ -135,5 +140,14 @@ this.continue = false;

});
flowDecoder.on('error', /** @param {Error} err */ err => {
decoder.emit('error', err);
});
flowDecoder.on(
'error',
/**
* Forwards flowed decoder errors to the output decoder.
*
* @param {Error} err Decoder error to forward.
* @returns {void}
*/
err => {
decoder.emit('error', err);
}
);
flowDecoder.pipe(decoder);

@@ -145,2 +159,7 @@ }

decoder,
/**
* Marks the selected node stream as consumed so the passthrough can continue.
*
* @returns {void}
*/
done: () => {

@@ -147,0 +166,0 @@ if (typeof this.continue === 'function') {

import type { PassThrough, Transform } from 'node:stream';
import type Headers = require('./headers');
/** Value that is either present as `T` or explicitly unavailable as `false`. */
export type Maybe<T> = T | false;
/** Single item in an IMAP-style MIME part number. */
export type PartNumberItem = number | 'TEXT';
/** IMAP-style path to a MIME part, for example `[1, 2, 'TEXT']`. */
export type PartNumber = PartNumberItem[];
/** Options passed through to libmime instances created by this package. */
export interface LibmimeOptions {
/** Optional iconv-compatible implementation used by libmime for charset conversion. */
Iconv?: unknown;
}
/** Configuration for `MessageSplitter` and MIME node parsing. */
export interface SplitterOptions extends LibmimeOptions {
/** Treat `message/rfc822` parts as leaf nodes instead of parsing embedded messages. */
ignoreEmbedded?: boolean;
/** Parse embedded messages as inline unless their disposition is `attachment`. */
defaultInlineEmbedded?: boolean;
/** Maximum header block size, in bytes, allowed for a single MIME node. */
maxHeadSize?: number;
/** Maximum number of MIME child nodes accepted before parsing fails. */
maxChildNodes?: number;
}
/** Configuration for `ChunkedPassthrough`. */
export interface ChunkedPassthroughOptions {
/** Buffered byte threshold for non-final chunks. Defaults to 64 KiB. */
chunkSize?: number;
}
/** Configuration for `FlowedDecoder`. */
export interface FlowedDecoderOptions extends LibmimeOptions {
/** Whether format=flowed uses RFC 3676 `DelSp=yes` space deletion semantics. */
delSp?: boolean;
/** Source Content-Transfer-Encoding hint used during format=flowed handling. */
encoding?: string | false;
}
/** Parsed raw header line with a normalized lookup key. */
export interface HeaderLine {
/** Lower-case header key used for comparisons and lookups. */
key: string;
/** Full header line, including the original field name, value, and any folded continuations. */
line: string;
}
/** Decoded structured header value returned by libmime. */
export interface DecodedHeader {
/** Header key returned by libmime for the decoded value. */
key: string;
/** Unicode decoded header value. */
value: string;
}
/** MIME node emitted by `MessageSplitter` and accepted by `MessageJoiner`. */
export interface MimeNode {
/** Discriminator identifying this chunk as a MIME node. */
type: 'node';
/** Whether this node is the root message node. */
root: boolean;
/** Parent MIME node, or `false` for the root node. */
parentNode: MimeNode | false;
/** Boundary used by this multipart node, or `false` when not multipart. */
_boundary: Buffer | false;
/** Boundary inherited from the parent multipart node, or `false` when absent. */
_parentBoundary: Buffer | false;
/** Length, in bytes, of the raw header block collected for this node. */
_headerlen: number;
/** Multipart subtype such as `mixed` or `alternative`, or `false` for leaf nodes. */
multipart: string | false;
/** Content-Transfer-Encoding value, normalized to lower case, or `false` when absent. */
encoding: string | false;
/** Parsed and mutable header collection, available after headers are parsed. */
headers: Headers | false;
/** MIME content type such as `text/plain`, or `false` when unavailable. */
contentType: string | false;
/** Charset parameter from Content-Type, or `false` when absent. */
charset: string | false;
/** Content-Disposition value such as `inline` or `attachment`, or `false` when absent. */
disposition: string | false;
/** Decoded filename from Content-Disposition or Content-Type parameters, or `false` when absent. */
filename: string | false;
/** Whether this node is `text/*` with `format=flowed`. */
flowed: boolean;
/** Whether flowed text uses `delsp=yes`. */
delSp: boolean;
/** Splitter configuration used when parsing this node. */
config: SplitterOptions;
/** Resolved IMAP-style part number for this node, or `false` before resolution. */
partNr: PartNumber | false;
/** Number of child part numbers allocated by this node. */
childPartNumbers: number;
/** Whether this node's content type is `message/rfc822`. */
rfc822: boolean;
/** Whether an embedded `message/rfc822` node was parsed as a nested message. */
messageNode?: boolean;
/**
* Builds the next child part number for this node.
*
* @param provided Optional explicit part number item to append.
* @returns Resolved MIME part number.
*/
getPartNr(provided?: PartNumberItem): PartNumber;
/**
* Appends one raw header line to this node while parsing.
*
* @param line Raw header line bytes; falsy values are ignored.
* @returns Nothing.
*/
addHeaderChunk(line?: Buffer | false): void;
/**
* Parses collected header bytes and populates MIME metadata fields.
*
* @returns Nothing.
*/
parseHeaders(): void;
/**
* Builds this node's header block.
*
* @returns Header bytes ending with an empty header/body separator line.
*/
getHeaders(): Buffer;
/**
* Sets or updates the Content-Type header value.
*
* @param contentType MIME content type to set; falsy keeps the current type.
* @returns Nothing.
*/
setContentType(contentType?: string | false): void;
/**
* Sets, updates, or removes the Content-Type charset parameter.
*
* @param charset Charset to set; falsy removes it when possible.
* @returns Nothing.
*/
setCharset(charset?: string | false): void;
/**
* Sets, updates, or removes the filename parameter.
*
* @param filename Filename to set; falsy removes it when possible.
* @returns Nothing.
*/
setFilename(filename?: string | false): void;
/**
* Creates a decoder stream for this node's transfer encoding.
*
* @returns Transform stream that outputs decoded content bytes.
*/
getDecoder(): Transform | PassThrough;
/**
* Creates an encoder stream and updates the Content-Transfer-Encoding header when needed.
*
* @param encoding Target transfer encoding; defaults to the node's current encoding.
* @returns Transform stream that outputs encoded content bytes.
*/
getEncoder(encoding?: string | false): Transform | PassThrough;
}
/** Data or body bytes emitted by `MessageSplitter`. */
export interface MessageChunk {
/** MIME node that owns or precedes this chunk. */
node: MimeNode;
/** Chunk kind: multipart structure bytes (`data`) or leaf content bytes (`body`). */
type: 'data' | 'body';
/** Raw chunk bytes. */
value: Buffer;
}
/** Sentinel input used internally to finish a pending rewriter or streamer node. */
export interface EmptyChunk {
/** Discriminator for an empty control chunk. */
type: 'none';
}
/** Object emitted by `MessageSplitter`: either a MIME node or a data/body byte chunk. */
export type SplitterChunk = MimeNode | MessageChunk;
/** Object accepted by rewriter and streamer transforms. */
export type RewriterInput = SplitterChunk | EmptyChunk;
/**
* Predicate used to select MIME nodes.
*
* @param node MIME node being inspected.
* @returns `true` to process the node, otherwise `false`.
*/
export type FilterFunc = (node: MimeNode) => boolean;
/** Error object that may include a Node-style string error code. */
export type ErrorWithCode = Error & { code?: string };
/**
* Callback that resumes processing after a selected node stream has ended.
*
* @returns Nothing.
*/
export type ContinueCallback = () => void;
/** Content transform stream used for decoded or encoded node bodies. */
export type ContentStream = Transform | PassThrough;
/** Decoder stream with an internal readable-state guard used by rewriter/streamer. */
export type DecoderStream = ContentStream & { $reading?: boolean };
/** Internal grouping state used while splitter coalesces adjacent chunks. */
export interface SplitterGroup {
/** MIME node associated with the group, when one exists. */
node?: MimeNode;
/** Group kind currently being accumulated. */
type: 'none' | 'node' | 'data' | 'body';
/** Buffered raw bytes for `data` or `body` groups. */
value?: Buffer;
}
/** Payload emitted with `NodeRewriter`'s `node` event. */
export interface RewriterNode {
/** Selected MIME node whose body can be rewritten. */
node: MimeNode;
/** Stream that yields decoded original body bytes. */
decoder: Transform;
/** Stream that accepts replacement decoded bytes and emits properly encoded body bytes. */
encoder: Transform;
}
/** Payload emitted with `NodeStreamer`'s `node` event. */
export interface StreamerNode {
/** Selected MIME node whose body is being streamed. */
node: MimeNode;
/** Stream that yields decoded original body bytes. */
decoder: Transform;
/**
* Signals that the consumer has finished reading the selected node.
*
* @returns Nothing.
*/
done: () => void;
}
{
"name": "@zone-eu/mailsplit",
"version": "5.4.10",
"version": "5.4.11",
"description": "Split email messages into an object stream",

@@ -5,0 +5,0 @@ "main": "index.js",