diff --git a/types/tar/index.d.ts b/types/tar/index.d.ts index 4b62578290..7a81825894 100644 --- a/types/tar/index.d.ts +++ b/types/tar/index.d.ts @@ -1,13 +1,14 @@ -// Type definitions for tar v1.0.1 +// Type definitions for tar 4.0 // Project: https://github.com/npm/node-tar -// Definitions by: Maxime LUCE +// Definitions by: Maxime LUCE , Connor Peet // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TODO: When/if typings for [fstream](https://github.com/npm/fstream) are written, refactor this typing to use it for the various streams. /// - import stream = require("stream"); +import events = require("events"); +import zlib = require("zlib"); // #region Interfaces @@ -63,14 +64,11 @@ export interface PackStream extends NodeJS.ReadWriteStream { _process(): void; } -export interface ExtractStream extends ParseStream { -} - // #endregion // #region Enums -export declare var fields: { +export interface Fields { path: number; mode: number; uid: number; @@ -88,17 +86,19 @@ export declare var fields: { devmin: number; prefix: number; fill: number; -}; +} -export declare var fieldSize: number[]; -export declare var fieldOffs: number[]; -export declare var fieldEnds: number[]; +export type fields = Fields; // alias for backwards compatbility + +export const fieldSize: number[]; +export const fieldOffs: number[]; +export const fieldEnds: number[]; /** * Different values of the 'type' field * paths match the values of Stats.isX() functions, where appropriate */ -export declare var types: { +export const types: { 0: string; "\0": string; "": string; @@ -145,7 +145,7 @@ export declare var types: { /** * Values for the mode field */ -export declare var modes: { +export const modes: { suid: number; sgid: number; svtx: number; @@ -160,7 +160,7 @@ export declare var modes: { oexec: number; }; -export declare var numeric: { +export const numeric: { mode: boolean; uid: boolean; gid: boolean; @@ -176,7 +176,7 @@ export declare var numeric: { nlink: boolean; }; -export declare var knownExtended: { +export const knownExtended: { atime: boolean; charset: boolean; comment: boolean; @@ -193,8 +193,8 @@ export declare var knownExtended: { uname: boolean; }; -export declare var headerSize: number; -export declare var blockSize: number; +export const headerSize: number; +export const blockSize: number; //#endregion @@ -203,17 +203,14 @@ export declare var blockSize: number; /** * Returns a writable stream. Write tar data to it and it will emit entry events for each entry parsed from the tarball. This is used by tar.Extract. */ -export declare function Parse(): ParseStream; +export function Parse(): ParseStream; /** * Returns a through stream. Use fstream to write files into the pack stream and you will receive tar archive data from the pack stream. * This only works with directories, it does not work with individual files. * The optional properties object are used to set properties in the tar 'Global Extended Header'. */ -export declare function Pack(props?: HeaderProperties): PackStream; -/** - * Returns a through stream. Write tar data to the stream and the files in the tarball will be extracted onto the filesystem. - */ -export declare function Extract(path: string): ExtractStream; +export function Pack(props?: HeaderProperties): PackStream; + /** * Returns a through stream. Write tar data to the stream and the files in the tarball will be extracted onto the filesystem. * options can be: @@ -225,4 +222,482 @@ export declare function Extract(path: string): ExtractStream; * ``` * options also get passed to the fstream.Writer instance that tar uses internally. */ -export declare function Extract(opts: ExtractOptions): ExtractStream; +export function Extract(opts: ExtractOptions | string): ParseStream; + +export interface FileStat extends stream.Readable, Fields { + header: HeaderProperties; + startBlockSize: number; + blockRemain: number; + remain: number; + meta: boolean; + ignore: boolean; + size: number; +} + +export interface CreateOptions { + /** + * A function that will get called with (message, data) + * for any warnings encountered. + */ + onwarn?(message: string, data: Buffer): void; + + /** + * Treat warnings as crash-worthy errors. Default false. + */ + strict?: boolean; + + /** + * The current working directory for creating the archive. Defaults to process.cwd(). + */ + cwd?: string; + + /** + * Alias for cwd. + */ + C?: string; + + /** + * Set to any truthy value to create a gzipped archive, + * or an object with settings for zlib.Gzip() + */ + gzip?: boolean | zlib.ZlibOptions; + + /** + * Alias for gzip. + */ + z?: boolean | zlib.ZlibOptions; + + /** + * A function that gets called with (path, stat) for each entry being + * added. Return true to add the entry to the archive, or false to omit it. + */ + filter?(path: string, stat: FileStat): boolean; + + /** + * Omit metadata that is system-specific: ctime, atime, uid, gid, uname, + * gname, dev, ino, and nlink. Note that mtime is still included, + * because this is necessary other time-based operations. + */ + portable?: boolean; + + /** + * Allow absolute paths. By default, / is stripped from absolute paths. + */ + preservePaths?: boolean; + + /** + * Alias for presevePaths. + */ + P?: boolean; + + /** + * The mode to set on the created file archive. + */ + mode?: number; + + /** + * Do not recursively archive the contents of directories. + */ + noDirRecurse?: boolean; + + /** + * Set to true to pack the targets of symbolic links. Without this + * option, symbolic links are archived as such. + */ + follow?: boolean; + + /** + * Alias for follow. + */ + L?: boolean; + + /** + * Alias for follow. + */ + h?: boolean; + + /** + * uppress pax extended headers. Note that this means that long paths and + * linkpaths will be truncated, and large or negative numeric values + * may be interpreted incorrectly. + */ + noPax?: boolean; +} + +export interface ExtractOptions { + /** + * A function that will get called with (message, data) + * for any warnings encountered. + */ + onwarn?(message: string, data: Buffer): void; + + /** + * Treat warnings as crash-worthy errors. Default false. + */ + strict?: boolean; + + /** + * Extract files relative to the specified directory. Defaults to + * process.cwd(). If provided, this must exist and must be a directory. + */ + cwd?: string; + + /** + * Alias for cwd. + */ + C?: string; + + /** + * A function that gets called with (path, stat) for each entry being + * added. Return true to emit the entry from the archive, or false to skip it. + */ + filter?(path: string, stat: FileStat): boolean; + + /** + * Set to true to keep the existing file on disk if it's newer than + * the file in the archive. + */ + newer?: boolean; + + /** + * Alias for newer. + */ + 'keep-newer'?: boolean; + + /** + * Alias for newer. + */ + 'keep-newer-files'?: boolean; + + /** + * Do not overwrite existing files. In particular, if a file appears more + * than once in an archive, later copies will not overwrite earlier copies + */ + keep?: boolean; + + /** + * Alias for keep. + */ + k?: boolean; + + /** + * Alias for keep. + */ + 'keep-existing'?: boolean; + + /** + * Unlink files before creating them. Without this option, tar overwrites + * existing files, which preserves existing hardlinks. With this option, + * existing hardlinks will be broken, as will any symlink that would + * affect the location of an extracted file. + */ + unlink?: boolean; + + /** + * Remove the specified number of leading path elements. Pathnames with + * fewer elements will be silently skipped. Note that the pathname + * is edited after applying the filter, but before security checks. + */ + strip?: number; + + /** + * Alias for strip. + */ + 'strip-components'?: number; + + /** + * Alias for strip. + */ + stripComponents?: number; + + /** + * If true, tar will set the uid and gid of extracted entries to the uid + * and gid fields in the archive. This defaults to true when run as root, + * and false otherwise. If false, then files and directories will be set + * with the owner and group of the user running the process. This is + * similar to -p in tar(1), but ACLs and other system-specific data is + * never unpacked in this implementation, and modes + * are set by default already. + */ + preserveOwner?: boolean; + + /** + * Alias for preserveOwner. + */ + p?: boolean; + + /** + * Set to a number to force ownership of all extracted files and folders, + * and all implicitly created directories, to be owned by the specified + * user id, regardless of the uid field in the archive. Cannot be used + * along with preserveOwner. Requires also setting a gid option. + */ + uid?: number; + + /** + * Set to a number to force ownership of all extracted files and folders, + * and all implicitly created directories, to be owned by the specified + * group id, regardless of the gid field in the archive. Cannot be used + * along with preserveOwner. Requires also setting a uid option + */ + gui?: number; +} + +export interface ListOptions { + /** + * Treat warnings as crash-worthy errors. Default false. + */ + strict?: boolean; + + /** + * Extract files relative to the specified directory. Defaults to + * process.cwd(). If provided, this must exist and must be a directory. + */ + cwd?: string; + + /** + * Alias for cwd. + */ + C?: string; + + /** + * A function that gets called with (path, stat) for each entry being + * added. Return true to emit the entry from the archive, or false to skip it. + */ + filter?(path: string, entry: FileStat): boolean; + + /** + * A function that gets called with (entry) for each entry that passes the + * filter. This is important for when both file and sync are set, because + * it will be called synchronously. + */ + onentry?(entry: FileStat): void; + + /** + * The maximum buffer size for fs.read() operations. Defaults to 16 MB. + */ + maxReadSize?: number; + + /** + * By default, entry streams are resumed immediately after the call to + * onentry. Set noResume: true to suppress this behavior. Note that by + * opting into this, the stream will never complete until the entry + * data is consumed. + */ + noResume?: boolean; +} + +export interface ReplaceOptions { + /** + * Required. Write the tarball archive to the specified filename. + */ + file: string; + + /** + * Act synchronously. If this is set, then any provided file will be + * fully written after the call to tar.c. + */ + sync?: boolean; + + /** + * A function that will get called with (message, data) + * for any warnings encountered. + */ + onwarn?(message: string, data: Buffer): void; + + /** + * Treat warnings as crash-worthy errors. Default false. + */ + strict?: boolean; + + /** + * Extract files relative to the specified directory. Defaults to + * process.cwd(). If provided, this must exist and must be a directory. + */ + cwd?: string; + + /** + * Alias for cwd. + */ + C?: string; + + /** + * A path portion to prefix onto the entries in the archive. + */ + prefix?: string; + + /** + * Set to any truthy value to create a gzipped archive, + * or an object with settings for zlib.Gzip() + */ + gzip?: boolean | zlib.ZlibOptions; + + /** + * A function that gets called with (path, stat) for each entry being + * added. Return true to emit the entry from the archive, or false to skip it. + */ + filter?(path: string, stat: FileStat): boolean; + + /** + * Allow absolute paths. By default, / is stripped from absolute paths. + */ + preservePaths?: boolean; + + /** + * The maximum buffer size for fs.read() operations. Defaults to 16 MB. + */ + maxReadSize?: number; + + /** + * Do not recursively archive the contents of directories. + */ + noDirRecurse?: boolean; + + /** + * Set to true to pack the targets of symbolic links. Without this + * option, symbolic links are archived as such. + */ + follow?: boolean; + + /** + * Alias for follow. + */ + L?: boolean; + + /** + * Alias for follow. + */ + h?: boolean; + + /** + * uppress pax extended headers. Note that this means that long paths and + * linkpaths will be truncated, and large or negative numeric values + * may be interpreted incorrectly. + */ + noPax?: boolean; +} + +export interface FileOptions { + /** + * Uses the given file as the input or output of this function. + */ + file?: string; + + /** + * Alias for file. + */ + f?: string; +} + +/** + * Create a tarball archive. The fileList is an array of paths to add to the + * tarball. Adding a directory also adds its children recursively. An entry in + * fileList that starts with an @ symbol is a tar archive whose entries will + * be added. To add a file that starts with @, prepend it with `./`. + * + * Archive data may be read from the returned stream. + */ +export function create(options: CreateOptions, fileList: ReadonlyArray, callback?: (err?: Error) => void): stream.Readable; + +/** + * Create a tarball archive. The fileList is an array of paths to add to the + * tarball. Adding a directory also adds its children recursively. An entry in + * fileList that starts with an @ symbol is a tar archive whose entries will + * be added. To add a file that starts with @, prepend it with `./`. + */ +export function create(options: CreateOptions & FileOptions, fileList: ReadonlyArray): Promise; +export function create(options: CreateOptions & FileOptions & { sync: true }, fileList: ReadonlyArray): void; +export function create(options: CreateOptions & FileOptions, fileList: ReadonlyArray, callback: (err?: Error) => void): void; + +/** + * Alias for create + */ +export const c: typeof create; + +/** + * Extract a tarball archive. The fileList is an array of paths to extract + * from the tarball. If no paths are provided, then all the entries are + * extracted. If the archive is gzipped, then tar will detect this and unzip + * it. Note that all directories that are created will be forced to be + * writable, readable, and listable by their owner, to avoid cases where a + * directory prevents extraction of child entries by virtue of its mode. Most + * extraction errors will cause a warn event to be emitted. If the cwd is + * missing, or not a directory, then the extraction will fail completely. + * + * Archive data should be written to the returned stream. + */ +export function extract(options: ExtractOptions, fileList?: ReadonlyArray, callback?: (err?: Error) => void): stream.Writable; + +/** + * Extract a tarball archive. The fileList is an array of paths to extract + * from the tarball. If no paths are provided, then all the entries are + * extracted. If the archive is gzipped, then tar will detect this and unzip + * it. Note that all directories that are created will be forced to be + * writable, readable, and listable by their owner, to avoid cases where a + * directory prevents extraction of child entries by virtue of its mode. Most + * extraction errors will cause a warn event to be emitted. If the cwd is + * missing, or not a directory, then the extraction will fail completely. + */ +export function extract(options: ExtractOptions & FileOptions, fileList?: ReadonlyArray): Promise; +export function extract(options: ExtractOptions & FileOptions & { sync: true }, fileList?: ReadonlyArray): void; +export function extract(options: ExtractOptions & FileOptions, fileList: ReadonlyArray | undefined, callback: (err?: Error) => void): void; + +/** + * Alias for extract + */ +export const x: typeof extract; + +/** + * List the contents of a tarball archive. The fileList is an array of paths + * to list from the tarball. If no paths are provided, then all the entries + * are listed. If the archive is gzipped, then tar will detect this and unzip + * it. + * + * Archive data should be written to the returned stream. + */ +export function list(options?: ListOptions, fileList?: ReadonlyArray, callback?: (err?: Error) => void): stream.Writable; + +/** + * List the contents of a tarball archive. The fileList is an array of paths + * to list from the tarball. If no paths are provided, then all the entries + * are listed. If the archive is gzipped, then tar will detect this and unzip + * it. + */ +export function list(options: ListOptions & FileOptions, fileList?: ReadonlyArray): Promise; +export function list(options: ListOptions & FileOptions & { sync: true }, fileList?: ReadonlyArray): void; + +/** + * Alias for list + */ +export const t: typeof list; + +/** + * Add files to an existing archive. Because later entries override earlier + * entries, this effectively replaces any existing entries. The fileList is an + * array of paths to add to the tarball. Adding a directory also adds its + * children recursively. An entry in fileList that starts with an @ symbol is + * a tar archive whose entries will be added. To add a file that + * starts with @, prepend it with ./. + */ +export function replace(options: ReplaceOptions, fileList?: ReadonlyArray): Promise; +export function replace(options: ReplaceOptions, fileList: ReadonlyArray | undefined, callback: (err?: Error) => void): Promise; + +/** + * Alias for replace + */ +export const r: typeof replace; + +/** + * Add files to an archive if they are newer than the entry already in the + * tarball archive. The fileList is an array of paths to add to the tarball. + * Adding a directory also adds its children recursively. An entry in fileList + * that starts with an @ symbol is a tar archive whose entries will be added. + * To add a file that starts with @, prepend it with ./. + */ +export function update(options: ReplaceOptions, fileList?: ReadonlyArray): Promise; +export function update(options: ReplaceOptions, fileList: ReadonlyArray | undefined, callback: (err?: Error) => void): Promise; + +/** + * Alias for update + */ +export const u: typeof update; diff --git a/types/tar/tar-tests.ts b/types/tar/tar-tests.ts index d80e068ace..a35baec70b 100644 --- a/types/tar/tar-tests.ts +++ b/types/tar/tar-tests.ts @@ -15,14 +15,53 @@ fs.createReadStream("path/to/file.tar").pipe(tar.Extract("path/to/extract")); /** * Use with events */ -var readStream = fs.createReadStream("/path/to/file.tar"); -var extract = tar.Extract("/path/to/target"); +const readStream = fs.createReadStream("/path/to/file.tar"); +const extract = tar.Extract("/path/to/target"); readStream.pipe(extract); -extract.on("entry", (entry: any) => { +extract.on("entry", (entry: any) => undefined); +let packStream: tar.PackStream = tar.Pack(); +packStream = tar.Pack({ path: 'test' }); + +/** + * Examples from tar docs: + */ + +tar.c( + { + gzip: true, + file: 'my-tarball.tgz' + }, + ['some', 'files', 'and', 'folders'] +).then(() => undefined); + +tar.c( + { + gzip: true, + }, + ['some', 'files', 'and', 'folders'] +).pipe(fs.createWriteStream('my-tarball.tgz')); + +tar.x( + { + file: 'my-tarball.tgz', + } +).then(() => undefined); + +fs.createReadStream('my-tarball.tgz').pipe( + tar.x({ + strip: 1, + C: 'some-dir' // alias for cwd:'some-dir', also ok + }) +); + +tar.t({ + file: 'my-tarball.tgz', + onentry: (entry) => console.log(entry.path, 'was', entry.size), }); -var packStream: tar.PackStream = tar.Pack(); -packStream = tar.Pack({ path: 'test' }); +fs.createReadStream('my-tarball.tgz') + .pipe(tar.t()) + .on('entry', entry => console.log(entry.size)); diff --git a/types/tar/tslint.json b/types/tar/tslint.json new file mode 100644 index 0000000000..f93cf8562a --- /dev/null +++ b/types/tar/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "dtslint/dt.json" +}