send-stream
Version:
Streaming file serving library with Range and conditional-GET support from file system or any streaming sources.
149 lines (148 loc) • 4.3 kB
TypeScript
import type { Readable } from 'node:stream';
import type { Dir, Stats, Dirent } from 'node:fs';
import type { StorageOptions } from './types';
/**
* File data with generic file descriptor used by file
* @template FileDescriptor - file descriptor type
*/
export interface GenericFileData<FileDescriptor> {
/**
* Path parts used from root
*/
pathParts: readonly string[];
/**
* Resolved path with path parts joined with root
*/
resolvedPath: string;
/**
* File stats
*/
stats: Stats;
/**
* File descriptor
*/
fd: FileDescriptor;
}
/**
* File data used by file storage
*/
export type FileData = GenericFileData<number>;
/**
* "fs" module like type with generic file descriptor used by this library
* @template FileDescriptor - file descriptor type
*/
export interface GenericFSModule<FileDescriptor> {
constants: {
O_RDONLY: number;
};
open: (path: string, flags: number, callback: (err: NodeJS.ErrnoException | null, fd: FileDescriptor) => void) => void;
fstat: (fd: FileDescriptor, callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void) => void;
close: (fd: FileDescriptor, callback: (err: NodeJS.ErrnoException | null) => void) => void;
createReadStream: (path: string, options: {
fd?: FileDescriptor;
start?: number;
end?: number;
autoClose: boolean;
}) => Readable;
opendir?: (path: string, callback: (err: NodeJS.ErrnoException | null, dir: Dir) => void) => void;
readdir: (path: string, options: {
withFileTypes: true;
}, callback: (err: NodeJS.ErrnoException | null, files: Dirent[]) => void) => void;
}
/**
* "fs" module like type used by this library
*/
export type FSModule = GenericFSModule<number>;
/**
* Content encoding path
*/
export interface ContentEncodingPath {
/**
* Content encoding name (will be used in content-encoding header if the file is found)
*/
name: string;
/**
* Path location (will replace $* groups from matched regexp)
*/
path: string;
}
/**
* Content encoding mapping
*/
export interface ContentEncodingMapping {
/**
* Regexp used to match file path
*/
matcher: RegExp | string;
/**
* Encodings to search once file path is matched
*/
encodings: readonly ContentEncodingPath[];
}
/**
* Content encoding preference
*/
export interface ContentEncodingPreference {
/**
* Order of preference
*/
readonly order: number;
/**
* Path to match
*/
readonly path: string;
}
/**
* Content encoding mapping
*/
export interface RegexpContentEncodingMapping {
/**
* Regexp used to match file path
*/
matcher: RegExp;
/**
* Encodings to search once file path is matched
*/
encodingPreferences: ReadonlyMap<string, ContentEncodingPreference>;
/**
* Identity encoding preference
*/
identityEncodingPreference: ContentEncodingPreference;
}
/**
* FileSystemStorage options with generic file descriptor
* @template FileDescriptor - file descriptor type
*/
export interface GenericFileSystemStorageOptions<FileDescriptor> extends StorageOptions {
/**
* Content encoding mapping, e.g. [{ matcher: /^(.+\\.json)$/, encodings: [{ name: 'gzip', path: '$1.gz' }] }]
*/
contentEncodingMappings?: readonly ContentEncodingMapping[];
/**
* Ignore pattern, defaults to /^\../ (files/folders beginning with a dot)
*/
ignorePattern?: RegExp | string | false;
/**
* "fs" module to use
*/
fsModule: GenericFSModule<FileDescriptor>;
/**
* Determine what should happen on directory requests (trailing slash)
* - `false` to return an error
* - `'list-files'` to list the files of directories
* - `'serve-index'` to serve the index.html file of directories
*
* Defaults to false
*/
onDirectory?: 'serve-index' | 'list-files' | false;
}
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
/**
* FileSystemStorage options
*/
export type FileSystemStorageOptions = Optional<GenericFileSystemStorageOptions<number>, 'fsModule'>;
/**
* URL encoded path or path parts
*/
export type FilePath = string | readonly string[];
export {};