Skip to content

Commit

Permalink
馃 Merge PR #56462 feat(node): v16.11 by @panva
Browse files Browse the repository at this point in the history
* feat(node): v16.11

* `util` module fixes.

node 16.x
- Add `debug` alias.
- Add `getSystemErrorName`.
- Add `stripVTControlCharacters`.

node 14.x
- Add `debug` alias. Fix `debuglog` types.
- Add `getSystemErrorName`.

* add stream utilities to FileHandle

Co-authored-by: Dmitry Semigradsky <semigradskyd@gmail.com>
  • Loading branch information
panva and Semigradsky committed Oct 14, 2021
1 parent 19ba34f commit bacc304
Show file tree
Hide file tree
Showing 11 changed files with 184 additions and 14 deletions.
2 changes: 1 addition & 1 deletion types/node/crypto.d.ts
Expand Up @@ -1175,7 +1175,7 @@ declare module 'crypto' {
* generateKeySync
* } = await import('crypto');
*
* const key = generateKeySync('hmac', 64);
* const key = generateKeySync('hmac', { length: 64 });
* console.log(key.export().toString('hex')); // e89..........41e
* ```
* @since v15.0.0
Expand Down
6 changes: 6 additions & 0 deletions types/node/diagnostics_channel.d.ts
Expand Up @@ -37,6 +37,7 @@ declare module 'diagnostics_channel' {
* // There are subscribers, prepare and publish message
* }
* ```
* @since v15.1.0, v14.17.0
* @param name The channel name
* @return If there are active subscribers
*/
Expand All @@ -51,6 +52,7 @@ declare module 'diagnostics_channel' {
*
* const channel = diagnostics_channel.channel('my-channel');
* ```
* @since v15.1.0, v14.17.0
* @param name The channel name
* @return The named channel object
*/
Expand All @@ -63,6 +65,7 @@ declare module 'diagnostics_channel' {
* lookups at publish time, enabling very fast publish speeds and allowing
* for heavy use while incurring very minimal cost. Channels are created with {@link channel}, constructing a channel directly
* with `new Channel(name)` is not supported.
* @since v15.1.0, v14.17.0
*/
class Channel {
readonly name: string;
Expand All @@ -82,6 +85,7 @@ declare module 'diagnostics_channel' {
* // There are subscribers, prepare and publish message
* }
* ```
* @since v15.1.0, v14.17.0
*/
readonly hasSubscribers: boolean;
private constructor(name: string);
Expand All @@ -99,6 +103,7 @@ declare module 'diagnostics_channel' {
* // Received data
* });
* ```
* @since v15.1.0, v14.17.0
* @param onMessage The handler to receive channel messages
*/
subscribe(onMessage: ChannelListener): void;
Expand All @@ -118,6 +123,7 @@ declare module 'diagnostics_channel' {
*
* channel.unsubscribe(onMessage);
* ```
* @since v15.1.0, v14.17.0
* @param onMessage The previous subscribed handler to remove
*/
unsubscribe(onMessage: ChannelListener): void;
Expand Down
12 changes: 5 additions & 7 deletions types/node/fs.d.ts
Expand Up @@ -306,7 +306,7 @@ declare module 'fs' {
/**
* The path to the file the stream is reading from as specified in the first
* argument to `fs.createReadStream()`. If `path` is passed as a string, then`readStream.path` will be a string. If `path` is passed as a `Buffer`, then`readStream.path` will be a
* `Buffer`.
* `Buffer`. If `fd` is specified, then`readStream.path` will be `undefined`.
* @since v0.1.93
*/
path: string | Buffer;
Expand Down Expand Up @@ -2763,7 +2763,7 @@ declare module 'fs' {
* the numeric values in these objects are specified as `BigInt`s.
*
* To be notified when the file was modified, not just accessed, it is necessary
* to compare `curr.mtime` and `prev.mtime`.
* to compare `curr.mtimeMs` and `prev.mtimeMs`.
*
* When an `fs.watchFile` operation results in an `ENOENT` error, it
* will invoke the listener once, with all the fields zeroed (or, for dates, the
Expand Down Expand Up @@ -3362,7 +3362,7 @@ declare module 'fs' {
end?: number | undefined;
}
/**
* Unlike the 16 kb default `highWaterMark` for a readable stream, the stream
* Unlike the 16 kb default `highWaterMark` for a `stream.Readable`, the stream
* returned by this method has a default `highWaterMark` of 64 kb.
*
* `options` can include `start` and `end` values to read a range of bytes from
Expand All @@ -3382,7 +3382,7 @@ declare module 'fs' {
* closing naturally.
*
* By default, the stream will emit a `'close'` event after it has been
* destroyed, like most `Readable` streams. Set the `emitClose` option to`false` to change this behavior.
* destroyed. Set the `emitClose` option to `false` to change this behavior.
*
* By providing the `fs` option, it is possible to override the corresponding `fs`implementations for `open`, `read`, and `close`. When providing the `fs` option,
* an override for `read` is required. If no `fd` is provided, an override for`open` is also required. If `autoClose` is `true`, an override for `close` is
Expand Down Expand Up @@ -3424,7 +3424,6 @@ declare module 'fs' {
*
* If `options` is a string, then it specifies the encoding.
* @since v0.1.31
* @return See `Readable Stream`.
*/
export function createReadStream(path: PathLike, options?: BufferEncoding | ReadStreamOptions): ReadStream;
/**
Expand All @@ -3440,7 +3439,7 @@ declare module 'fs' {
* file descriptor leak.
*
* By default, the stream will emit a `'close'` event after it has been
* destroyed, like most `Writable` streams. Set the `emitClose` option to`false` to change this behavior.
* destroyed. Set the `emitClose` option to `false` to change this behavior.
*
* By providing the `fs` option it is possible to override the corresponding `fs`implementations for `open`, `write`, `writev` and `close`. Overriding `write()`without `writev()` can reduce
* performance as some optimizations (`_writev()`)
Expand All @@ -3453,7 +3452,6 @@ declare module 'fs' {
*
* If `options` is a string, then it specifies the encoding.
* @since v0.1.31
* @return See `Writable Stream`.
*/
export function createWriteStream(path: PathLike, options?: BufferEncoding | StreamOptions): WriteStream;
/**
Expand Down
87 changes: 87 additions & 0 deletions types/node/fs/promises.d.ts
Expand Up @@ -31,6 +31,8 @@ declare module 'fs/promises' {
WatchOptions,
WatchEventType,
CopyOptions,
ReadStream,
WriteStream,
} from 'node:fs';
interface FileChangeInfo<T extends string | Buffer> {
eventType: WatchEventType;
Expand Down Expand Up @@ -59,6 +61,20 @@ declare module 'fs/promises' {
length?: number | null;
position?: number | null;
}
interface CreateReadStreamOptions {
encoding?: BufferEncoding | null | undefined;
autoClose?: boolean | undefined;
emitClose?: boolean | undefined;
start?: number | undefined;
end?: number | undefined;
highWaterMark?: number | undefined;
}
interface CreateWriteStreamOptions {
encoding?: BufferEncoding | null | undefined;
autoClose?: boolean | undefined;
emitClose?: boolean | undefined;
start?: number | undefined;
}
// TODO: Add `EventEmitter` close
interface FileHandle {
/**
Expand Down Expand Up @@ -90,6 +106,77 @@ declare module 'fs/promises' {
* @return Fulfills with `undefined` upon success.
*/
chmod(mode: Mode): Promise<void>;
/**
* Unlike the 16 kb default `highWaterMark` for a `stream.Readable`, the stream
* returned by this method has a default `highWaterMark` of 64 kb.
*
* `options` can include `start` and `end` values to read a range of bytes from
* the file instead of the entire file. Both `start` and `end` are inclusive and
* start counting at 0, allowed values are in the
* \[0, [`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER)\] range. If `start` is
* omitted or `undefined`, `filehandle.createReadStream()` reads sequentially from
* the current file position. The `encoding` can be any one of those accepted by `Buffer`.
*
* If the `FileHandle` points to a character device that only supports blocking
* reads (such as keyboard or sound card), read operations do not finish until data
* is available. This can prevent the process from exiting and the stream from
* closing naturally.
*
* By default, the stream will emit a `'close'` event after it has been
* destroyed. Set the `emitClose` option to `false` to change this behavior.
*
* ```js
* import { open } from 'fs/promises';
*
* const fd = await open('/dev/input/event0');
* // Create a stream from some character device.
* const stream = fd.createReadStream();
* setTimeout(() => {
* stream.close(); // This may not close the stream.
* // Artificially marking end-of-stream, as if the underlying resource had
* // indicated end-of-file by itself, allows the stream to close.
* // This does not cancel pending read operations, and if there is such an
* // operation, the process may still not be able to exit successfully
* // until it finishes.
* stream.push(null);
* stream.read(0);
* }, 100);
* ```
*
* If `autoClose` is false, then the file descriptor won't be closed, even if
* there's an error. It is the application's responsibility to close it and make
* sure there's no file descriptor leak. If `autoClose` is set to true (default
* behavior), on `'error'` or `'end'` the file descriptor will be closed
* automatically.
*
* An example to read the last 10 bytes of a file which is 100 bytes long:
*
* ```js
* import { open } from 'fs/promises';
*
* const fd = await open('sample.txt');
* fd.createReadStream({ start: 90, end: 99 });
* ```
* @since v16.11.0
*/
createReadStream(options?: CreateReadStreamOptions): ReadStream;
/**
* `options` may also include a `start` option to allow writing data at some
* position past the beginning of the file, allowed values are in the
* \[0, [`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER)\] range. Modifying a file rather than replacing
* it may require the `flags` `open` option to be set to `r+` rather than the
* default `r`. The `encoding` can be any one of those accepted by `Buffer`.
*
* If `autoClose` is set to true (default behavior) on `'error'` or `'finish'`the file descriptor will be closed automatically. If `autoClose` is false,
* then the file descriptor won't be closed, even if there's an error.
* It is the application's responsibility to close it and make sure there's no
* file descriptor leak.
*
* By default, the stream will emit a `'close'` event after it has been
* destroyed. Set the `emitClose` option to `false` to change this behavior.
* @since v16.11.0
*/
createWriteStream(options?: CreateWriteStreamOptions): WriteStream;
/**
* Forces all currently queued I/O operations associated with the file to the
* operating system's synchronized I/O completion state. Refer to the POSIX [`fdatasync(2)`](http://man7.org/linux/man-pages/man2/fdatasync.2.html) documentation for details.
Expand Down
4 changes: 2 additions & 2 deletions types/node/http.d.ts
Expand Up @@ -187,9 +187,9 @@ declare module 'http' {
* The maximum number of requests socket can handle
* before closing keep alive connection.
*
* A value of `null` will disable the limit.
* A value of `0` will disable the limit.
*
* When limit is reach it will set `Connection` header value to `closed`,
* When the limit is reached it will set the `Connection` header value to `close`,
* but will not actually close the connection, subsequent requests sent
* after the limit is reached will get `503 Service Unavailable` as a response.
* @since v16.10.0
Expand Down
2 changes: 1 addition & 1 deletion types/node/index.d.ts
@@ -1,4 +1,4 @@
// Type definitions for non-npm package Node.js 16.10
// Type definitions for non-npm package Node.js 16.11
// Project: https://nodejs.org/
// Definitions by: Microsoft TypeScript <https://github.com/Microsoft>
// DefinitelyTyped <https://github.com/DefinitelyTyped>
Expand Down
18 changes: 18 additions & 0 deletions types/node/test/fs.ts
Expand Up @@ -663,3 +663,21 @@ const anyStats: fs.Stats | fs.BigIntStats = fs.statSync('.', { bigint: Math.rand
cpAsync('src', 'dest'); // $ExpectType Promise<void>
cpAsync('src', 'dest', opts); // $ExpectType Promise<void>
}

{
fs.promises.open('/dev/input/event0', 'r').then((fd) => {
// Create a stream from some character device.
const stream = fd.createReadStream(); // $ExpectType ReadStream
stream.close();
stream.push(null);
stream.read(0);
});
}

{
fs.promises.open('/tmp/tmp.txt', 'w').then((fd) => {
// Create a stream from some character device.
const stream = fd.createWriteStream(); // $ExpectType WriteStream
stream.close();
});
}
12 changes: 11 additions & 1 deletion types/node/test/util.ts
@@ -1,6 +1,6 @@
import * as util from 'node:util';
import assert = require('node:assert');
import { readFile } from 'node:fs';
import { access, readFile } from 'node:fs';

// Old and new util.inspect APIs
util.inspect(["This is nice"], false, 5);
Expand Down Expand Up @@ -182,8 +182,18 @@ const errorMap: Map<number, [string, string]> = util.getSystemErrorMap();
const logger: util.DebugLogger = util.debuglog('section');
logger.enabled; // $ExpectType boolean
util.debuglog('section', (fn: util.DebugLoggerFunction) => { });
util.debug('section', (fn: util.DebugLoggerFunction) => { });
}

{
const foo: string = util.toUSVString('foo');
}

access('file/that/does/not/exist', (err) => {
const name = util.getSystemErrorName(err!.errno!);
console.error(name);
});

{
util.stripVTControlCharacters('\u001B[4mvalue\u001B[0m'); // $ExpectType string
}
31 changes: 31 additions & 0 deletions types/node/util.d.ts
Expand Up @@ -113,6 +113,20 @@ declare module 'util' {
* @since v10.0.0
*/
export function formatWithOptions(inspectOptions: InspectOptions, format?: any, ...param: any[]): string;
/**
* Returns the string name for a numeric error code that comes from a Node.js API.
* The mapping between error codes and error names is platform-dependent.
* See `Common System Errors` for the names of common errors.
*
* ```js
* fs.access('file/that/does/not/exist', (err) => {
* const name = util.getSystemErrorName(err.errno);
* console.error(name); // ENOENT
* });
* ```
* @since v9.7.0
*/
export function getSystemErrorName(err: number): string;
/**
* Returns a Map of all system error codes available from the Node.js API.
* The mapping between error codes and error names is platform-dependent.
Expand Down Expand Up @@ -314,6 +328,9 @@ declare module 'util' {
* Allows changing inspect settings from the repl.
*/
let replDefaults: InspectOptions;
/**
* That can be used to declare custom inspect functions.
*/
const custom: unique symbol;
}
/**
Expand Down Expand Up @@ -520,6 +537,7 @@ declare module 'util' {
* @return The logging function
*/
export function debuglog(section: string, callback?: (fn: DebugLoggerFunction) => void): DebugLogger;
export const debug: typeof debuglog;
/**
* Returns `true` if the given `object` is a `Boolean`. Otherwise, returns `false`.
*
Expand Down Expand Up @@ -789,6 +807,16 @@ declare module 'util' {
* @since v9.0.0
*/
export function isDeepStrictEqual(val1: unknown, val2: unknown): boolean;
/**
* Returns `str` with any ANSI escape codes removed.
*
* ```js
* console.log(util.stripVTControlCharacters('\u001B[4mvalue\u001B[0m'));
* // Prints "value"
* ```
* @since v16.11.0
*/
export function stripVTControlCharacters(str: string): string;
/**
* Takes an `async` function (or a function that returns a `Promise`) and returns a
* function following the error-first callback style, i.e. taking
Expand Down Expand Up @@ -961,6 +989,9 @@ declare module 'util' {
): (arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5) => Promise<void>;
export function promisify(fn: Function): Function;
export namespace promisify {
/**
* That can be used to declare custom promisified variants of functions.
*/
const custom: unique symbol;
}
/**
Expand Down
16 changes: 15 additions & 1 deletion types/node/v14/test/util.ts
@@ -1,6 +1,6 @@
import * as util from 'util';
import assert = require('assert');
import { readFile } from 'fs';
import { access, readFile } from 'fs';

{
// Old and new util.inspect APIs
Expand Down Expand Up @@ -323,3 +323,17 @@ function testUtilTypes(
object; // $ExpectType WeakSet<any>
}
}

{
const logger: util.DebugLogger = util.debuglog('section');
logger.enabled; // $ExpectType boolean
util.debuglog('section', (fn: util.DebugLoggerFunction) => { });
util.debug('section', (fn: util.DebugLoggerFunction) => { });
}

{
access('file/that/does/not/exist', (err) => {
const name = util.getSystemErrorName(err!.errno!);
console.error(name);
});
}

0 comments on commit bacc304

Please sign in to comment.