UNPKG

nntp-fast

Version:

A lightweight nntp client for node made with attention to speed and ease of use. Works with promises and streams.

273 lines (272 loc) 8.77 kB
/// <reference types="node" /> import * as net from "net"; import * as tls from "tls"; import { PassThrough, Readable } from "stream"; import * as StreamSearch from "streamsearch"; import DotUnstuffingStreamSearch from "./DotUnstuffingStreamSearch"; import { EventEmitter } from "events"; declare enum Delimiter { CRLF = 0, MLDB = 1 } interface ResponseHandler { handleResponse: (code: number, message: string, data?: Buffer) => void; decideMldb?: (code: number) => boolean; MldbStream?: PassThrough; } export interface BasicResponse { /** Response code. See [RFC 3977 section 3.2](https://tools.ietf.org/html/rfc3977#section-3.2). */ code: number; /** Response message */ message: string; } export interface DataResponse extends BasicResponse { /** Content of multi line data block. */ data?: Buffer; } export interface StatResponse { /** Response code. See [RFC 3977 section 3.2](https://tools.ietf.org/html/rfc3977#section-3.2). */ code: number; /** Number of selected article. */ articleNumber: number; /** Message id of selected article. */ articleId: string; } /** NNTP post headers */ export declare type Headers = Record<string, string>; export interface NntpConnectionConstructorOptions { /** Whether dot unstuffing should be performed. (Default: true) */ dotUnstuffing?: boolean; } export interface SteamResponse { response: Promise<BasicResponse>; stream: Readable; } /** * Emitted when socket is closed. * @asMemberOf NntpConnection * @event */ export declare function end(): void; /** * Emitted when an socket or protocoll error occurs. * @asMemberOf NntpConnection * @event */ export declare function error(error: Error): void; /** * Emitted when socket timeouts. * @asMemberOf NntpConnection * @event */ export declare function timeout(): void; /** * @noInheritDoc */ export declare class NntpConnection extends EventEmitter { /** @private */ _connected: boolean; /** @private */ _connectedResponse: BasicResponse; /** @private */ _socket: net.Socket; /** @private */ _responseQueue: ResponseHandler[]; /** @private */ _buffer: Buffer[]; /** @private */ _delimiterSearchType: Delimiter; /** @private */ _streamsearchCRLF: StreamSearch; /** @private */ _streamsearchMLDB: DotUnstuffingStreamSearch; /** * * @param options.dotUnstuffing Whether dot unstuffing should be performed. */ constructor(options?: NntpConnectionConstructorOptions); /** * Connect to nntp server * @param options See [TCP options](https://nodejs.org/api/net.html#net_socket_connect_options_connectlistener) or [TLS options](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback). * @param secure Whether to use a secure connection */ connect(options: tls.ConnectionOptions | net.NetConnectOpts, secure?: boolean): Promise<BasicResponse>; /** * Connect to nntp server * @param host * @param port * @param secure Wheter to use a secure connection */ connect(host: string, port: number, secure?: boolean): Promise<BasicResponse>; /** * @private * @param data */ _onData(data: Buffer): void; /** * @private * @param isMatch * @param data * @param start * @param end */ _onInfoCRLF(isMatch: boolean, data: Buffer, start: number, end: number): void; /** * @private * @param isMatch * @param data * @param start * @param end */ _onInfoMLDB(isMatch: boolean, data: Buffer, start: number, end: number): void; /** * @private * @param response */ _getCode(response: string): BasicResponse; /** * @private * @param headString */ _parseHeader(headString: string): Headers; /** * @private * @param response */ _handleResponse(response: string): boolean; /** * Sends command to server. * @param command command to execute * @param decideMldb optional function that decides from response code whether a * multi line data block is to be expected */ runCommand(command: string, decideMldb?: (code: number) => boolean): Promise<DataResponse>; /** * Sends command to server. Creates a stream for the multi line data block. * @param command command to execute * @param decideMldb optional function that decides from response code whether a * multi line data block is to be expected */ runCommandStream(command: string, decideMldb?: (code: number) => boolean): SteamResponse; /** * The CAPABILITIES command allows a client to determine the * capabilities of the server at any given time. * * See [RFC 3977 Section 3.3](https://tools.ietf.org/html/rfc3977#section-3.3) * @param keyword */ capabilities(keyword?: string): Promise<DataResponse>; /** * The MODE READER command instructs a mode-switching server to switch * modes, as described in [RFC 3977 Section 3.4.2](https://tools.ietf.org/html/rfc3977#section-3.4.2). */ modeReader(): Promise<BasicResponse>; /** * The client uses the QUIT command to terminate the session. */ quit(): Promise<BasicResponse>; /** * The GROUP command selects a newsgroup as the currently selected * newsgroup and returns summary information about it. * @param group */ group(group: string): Promise<{ code: number; number: number; low: number; high: number; group: string; }>; /** * The LISTGROUP command selects a newsgroup in the same manner as the * GROUP command but also provides a list of article * numbers in the newsgroup. If no group is specified, the currently * selected newsgroup is used. * * @param group * @param range */ listgroup(group?: string, range?: string): Promise<{ code: number; message: string; articles: number[]; }>; /** * The current article number will be set to the previous article in * that newsgroup */ last(): Promise<StatResponse>; /** * The current article number will be set to the next article in * that newsgroup */ next(): Promise<StatResponse>; /** * The ARTICLE command selects an article according to the arguments and * presents the entire article (that is, the headers, and the body) to * the client. * * @param messageid */ article(messageid?: string | number): Promise<{ code: number; headers: Headers; body: Buffer; }>; /** * The HEAD command selects an article according to the arguments and * presents the headers to the client. * * @param messageid */ head(messageid?: string | number): Promise<{ code: number; headers: Headers; }>; /** * The BODY command selects an article according to the arguments and * presents the body to the client. * * @param messageid */ body(messageid?: string | number): Promise<{ code: number; body: Buffer; }>; /** * The BODY command selects an article according to the arguments and * presents the body to the client. Body is given as stream. * @param messageid */ bodyStream(messageid?: string | number): SteamResponse; /** * The STAT command selects an article according to the arguments. * This command allows the client to determine whether an article exists * and what its message-id is, without having to process an arbitrary * amount of text. * * @param messageid */ stat(messageid?: string | number): Promise<StatResponse>; /** * This command exists to help clients find out the current Coordinated * Universal Time from the server's perspective. */ date(): Promise<{ code: number; date: Date; }>; /** * This command provides a short summary of the commands that are * understood by this implementation of the server. */ help(): Promise<BasicResponse>; /** * This command returns a list of newsgroups created on the server since * the specified date and time. * @param date */ newsgroups(date: Date): Promise<DataResponse>; newsgroups(date: string, time: string, gmt?: boolean): Promise<DataResponse>; } export {};