Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,92 @@ import Headers = require('./lib/headers');
import MimeNode = require('./lib/mime-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
};

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';
46 changes: 46 additions & 0 deletions lib/chunked-passthrough.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,58 @@
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;
}

Expand Down
3 changes: 3 additions & 0 deletions lib/chunked-passthrough.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

const { Transform } = require('stream');

/**
* Transform stream that buffers byte input and emits larger Buffer chunks.
*/
class ChunkedPassthrough extends Transform {
/**
* @param {import('..').ChunkedPassthroughOptions} [options]
Expand Down
46 changes: 46 additions & 0 deletions lib/flowed-decoder.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,58 @@
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;
}

Expand Down
9 changes: 4 additions & 5 deletions lib/flowed-decoder.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

// Helper class to rewrite nodes with specific mime type
// Helper class to decode format=flowed text nodes

const Transform = require('stream').Transform;
const libmime = require('libmime');
Expand All @@ -10,14 +10,13 @@ const libmime = require('libmime');
const Libmime = /** @type {any} */ (libmime.Libmime);

/**
* 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.
*/
constructor(config) {
super();
Expand Down
93 changes: 93 additions & 0 deletions lib/headers.d.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,116 @@
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;
}

Expand Down
8 changes: 4 additions & 4 deletions lib/headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ const libmime = require('libmime');
const Libmime = /** @type {any} */ (libmime.Libmime);

/**
* 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.
*/
constructor(headers, config) {
config = config || {};
Expand Down
Loading