From f8496ab69b05c5869763d73c4a996534c6a810ce Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Sat, 17 Oct 2020 01:38:31 +0200 Subject: [PATCH 1/5] Types: Add type Buffer to njs_core Created according to http://nginx.org/en/docs/njs/reference.html. Signed-off-by: Jakub Jirutka --- src/ts/njs_core.d.ts | 548 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 546 insertions(+), 2 deletions(-) diff --git a/src/ts/njs_core.d.ts b/src/ts/njs_core.d.ts index 9abcee523..c470b84e8 100644 --- a/src/ts/njs_core.d.ts +++ b/src/ts/njs_core.d.ts @@ -1,8 +1,10 @@ +type BufferEncoding = "utf8" | "hex" | "base64" | "base64url"; + interface StringConstructor { /** * Creates a byte string from an encoded string. */ - bytesFrom(bytes: string, encoding: "hex" | "base64" | "base64url"): NjsByteString; + bytesFrom(bytes: string, encoding: Exclude): NjsByteString; /** * Creates a byte string from an array that contains octets. */ @@ -35,11 +37,553 @@ type NjsByteString = string & { /** * Encodes a byte string to hex, base64, or base64url. */ - toString(encoding: "hex" | "base64" | "base64url"): string; + toString(encoding: Exclude): string; }; type NjsStringLike = string | NjsByteString; +type TypedArray = + | Uint8Array + | Uint8ClampedArray + | Uint16Array + | Uint32Array + | Int8Array + | Int16Array + | Int32Array + | Float32Array + | Float64Array; + +/** + * Raw data is stored in instances of the `Buffer` class. + */ +declare class Buffer extends Uint8Array { + /** + * Allocates a new `Buffer` of a specified `size`. + * + * @param size The count of octets to allocate. + * @param fill If specified, the allocated `Buffer` will be initialized by calling `buf.fill(fill)`. + * Otherwise, the `Buffer` will be zero-filled. + * @param encoding The character encoding used for call to `buf.fill(fill, encoding)` while + * initalizing. Defaults to`'utf8'`. + */ + static alloc(size: number, fill?: NjsStringLike | Uint8Array | number, encoding?: BufferEncoding): Buffer; + /** + * The same as `Buffer.alloc()`, with the difference that the memory allocated for the buffer + * is not initialized, the contents of the new buffer is unknown and may contain sensitive data. + * + * @param size The count of octets to allocate. + */ + static allocUnsafe(size: number): Buffer; + + /** + * Returns the byte length of the specified `value`, when encoded using `encoding`. + * + * @param value The value to test. + * @param encoding The character encoding used to evaluate `value` if `value` is a `string`. + * Defaults to `'utf8'`. + */ + static byteLength(value: NjsStringLike | Buffer | TypedArray | DataView | ArrayBuffer, encoding?: BufferEncoding): number; + + /** + * Compares `buffer1` with `buffer2` when sorting arrays of buffer instances. + * + * @return + * - `0` if `buffer2` is the same as `buffer1`, + * - `1` if `buffer2` should come _before_ `buffer1` when sorted, + * - `-1` if `buffer2` should come _after_ `buffer1` when sorted. + */ + static compare(buf1: Uint8Array, buf2: Uint8Array): -1 | 0 | 1; + + /** + * Returns a new `Buffer` which is the result of concatenating all the `Buffer` instances in + * the `list`. If there are no items in the `list` or the total length is 0, a new zero-length + * `Buffer` is returned. + * + * @param list An array of `Buffer` or `Uint8Array` objects to concatenate. + * @param totalLength Total length of the buffers when concatenated, coerced to an unsigned + * integer. If not specified, it is calculated from the `Buffer` instances in `list` by adding + * their lengths. If the combined length of the Buffers in list exceeds `totalLength`, the + * result is truncated to `totalLength`. + */ + static concat(list: Uint8Array[], totalLength?: number): Buffer; + + /** + * FIXME + * + * @param arrayBuffer The `.buffer` property of any `TypedArray` or a `new ArrayBuffer()`. + * @param byteOffset An integer specifying the index of the first byte to expose. Defaults to `0`. + * @param length An integer specifying number of bytes to expose. + * Defaults to `arrayBuffer.byteLength - byteOffset`. + */ + static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer; + /** + * Allocates a new `Buffer` using an array of bytes in the range `0 – 255`. Array entries + * outside that range will be truncated. + * + * @param data The data to create a new `Buffer`. + */ + static from(data: number[]): Buffer; + /** + * Copies the passed buffer `data` onto a new `Buffer` instance. + * + * @param data The buffer to copy. + */ + static from(data: Uint8Array): Buffer; + /** + * For objects whose `valueOf()` function returns a value not strictly equal to object, returns + * `Buffer.from(object.valueOf(), offsetOrEncoding, length)`. + * + * @param obj An object supporting `valueOf()`. + */ + // FIXME: This documentation is incomplete. + static from(obj: { valueOf(): NjsStringLike | object }, byteOffset?: number, length?: number): Buffer; + /** + * Creates a new `Buffer` with a string `str`. + * + * @param str The string to create a new `Buffer`. + * @param encoding The character encoding to be used when converting a string into bytes. + * Defaults to `'utf8'`. + */ + static from(str: NjsStringLike, encoding?: BufferEncoding): Buffer; + + /** + * Returns true if the `obj` is a `Buffer`. + * + * @param obj The object to test. + */ + static isBuffer(obj: any): obj is Buffer; + + /** + * Returns `true` if `encoding` is the name of a supported character encoding. + * + * @param encoding The string to test. + */ + static isEncoding(encoding: NjsStringLike): encoding is BufferEncoding; + + /** + * The underlying `ArrayBuffer` object based on which this `Buffer` object is created. + */ + readonly buffer: ArrayBuffer; + /** + * Specifies the `byteOffset` of the Buffer's underlying `ArrayBuffer` object. + */ + readonly byteOffset: number; + /** + * The number of bytes in this buffer. + */ + readonly length: number; + + /** + * Constructor cannot be called. + */ + private constructor(); + + /** + * The index operator can be used to get and set the octet at position index in buffer. + * The values refer to individual bytes, so the legal value range is between 0 and 255 (decimal). + */ + [index: number]: number; + + /** + * Compares this buffer (source) with the `target` and returns a number indicating whether this + * buffer comes before, after, or is the same as the `target` in sort order. Comparison is based + * on the actual sequence of bytes in each `Buffer`. + * + * @param target The target buffer for comparison. + * @param targetStart An integer specifying the offset within `target` at which to begin + * comparison. Defaults to `0`. + * @param targetEnd An integer specifying the offset within `target` at which to end comparison. + * Defaults to `target.length`. + * @param sourceStart An integer specifying the offset within this buffer at which to begin + * comparison. Defaults to `0`. + * @param sourceEnd An integer specifying the offset within this buffer at which to end comparison + * (not inclusive). Defaults to `buf.length`. + * @return + * - `0` if `target` is the same as this buffer, + * - `1` if `target` should come _before_ this buffer when sorted, + * - `-1` if `target` should come _after_ this buffer when sorted. + */ + compare(target: Uint8Array, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): -1 | 0 | 1; + + /** + * Copies data from a region of this buffer to a region in `target`, even if the `target` + * memory region overlaps with this buffer. + * + * @param target The target buffer. + * @param targetStart An integer specifying the offset within `target` at which to begin writing. + * Defaults to `0`. + * @param sourceStart An integer specifying the offset within this buffer from which to begin + * copying. Defaults to `0`. + * @param sourceEnd An integer specifying the offset within this buffer at which to stop copying + * (not inclusive). Defaults to `buf.length`. + * @return The number of bytes copied. + */ + copy(target: Uint8Array, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + + /** + * Returns `true` if both this buffer and `other` buffer have exactly the same bytes. + * + * @param other The other buffer to compare with. + */ + equals(other: Uint8Array): boolean; + + /** + * Fills this buffer with the specified `value`. If the `offset` and `end` are not specified, + * the entire buffer will be filled. The `value` is coerced to `uint32` if it is not a `string`, + * `Buffer`, or `integer`. If the resulting integer is greater than `255`, the buffer will be + * filled with `value` and `255`. + * + * @param value The value with which to fill this buffer. + * @param offset Number of bytes to skip before starting to fill this buffer. Defaults to `0`. + * @param end Where to stop filling this buffer (not inclusive). Defaults to `buf.length`. + * @param encoding The encoding for `value` if `value` is a `string`. Defaults to `'utf8'`. + */ + fill(value: NjsStringLike | Uint8Array | number, offset?: number, end?: number, encoding?: BufferEncoding): this; + + /** + * Equivalent to `buf.indexOf() !== -1`, returns `true` if the `value` was found in this buffer. + * + * @param value What to search for. If a `number`, it must be between `0` and `255`. + * @param byteOffset Where to begin search in this buffer. Defaults to `0`. + * @param encoding The encoding for `value` if `value` is a `string`. Defaults to `'utf8'`. + */ + includes(value: NjsStringLike | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): boolean; + + /** + * Returns an integer which is the index of the first occurrence of `value` in this buffer, + * or `-1` if this buffer does not contain `value`. + * + * @param value What to search for. If a `number`, it must be between `0` and `255`. + * @param byteOffset Where to begin search in this buffer. Defaults to `0`. + * @param encoding The encoding for `value` if `value` is a `string`. Defaults to `'utf8'`. + */ + indexOf(value: NjsStringLike | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number; + /** + * The same as `buf.indexOf()`, except the last occurrence of the `value` is found instead of + * the first occurrence. If the `value` is an empty `string` or empty `Buffer`, `byteOffset` + * will be returned. + * + * @param value What to search for. If a `number`, it must be between `0` and `255`. + * @param byteOffset Where to begin search in this buffer. Defaults to `0`. + * @param encoding The encoding for `value` if `value` is a `string`. Defaults to `'utf8'`. + */ + lastIndexOf(value: NjsStringLike | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number; + + /** + * Reads the `byteLength` from this buffer at the specified `offset` and interprets the result + * as a big-endian, two's complement signed value supporting up to 48 bits of accuracy. + * + * @param offset An integer specifying the number of bytes to skip before starting to read. + * Must satisfy `0 <= offset <= buf.length - byteLength`. + * @param byteLength An integer between `1` and `6` specifying the number of bytes to read. + * Must satisfy `0 < byteLength <= 6`. + */ + readIntBE(offset: number, byteLength: number): number; + /** + * @see {Buffer.prototype.readIntBE}. + */ + readInt8(offset?: number): number; + /** + * @see {Buffer.prototype.readIntBE}. + */ + readInt16BE(offset?: number): number; + /** + * @see {Buffer.prototype.readIntBE}. + */ + readInt32BE(offset?: number): number; + /** + * Reads the `byteLength` from this buffer at the specified `offset` and interprets the result + * as a little-endian, two's complement signed value supporting up to 48 bits of accuracy. + * + * @param offset An integer specifying the number of bytes to skip before starting to read. + * Must satisfy `0 <= offset <= buf.length - byteLength`. + * @param byteLength An integer between `1` and `6` specifying the number of bytes to read. + * Must satisfy `0 < byteLength <= 6`. + */ + readIntLE(offset: number, byteLength: number): number; + /** + * @see {Buffer.prototype.readIntLE}. + */ + readInt16LE(offset?: number): number; + /** + * @see {Buffer.prototype.readIntLE}. + */ + readInt32LE(offset?: number): number; + + /** + * Reads the `byteLength` from this buffer at the specified `offset` and interprets the result + * as a big-endian integer supporting up to 48 bits of accuracy. + * + * @param offset An integer specifying the number of bytes to skip before starting to read. + * Must satisfy `0 <= offset <= buf.length - byteLength`. + * @param byteLength An integer between `1` and `6` specifying the number of bytes to read. + * Must satisfy `0 < byteLength <= 6`. + */ + readUIntBE(offset: number, byteLength: number): number; + /** + * @see {Buffer.prototype.readUIntBE}. + */ + readUInt8(offset?: number): number; + /** + * @see {Buffer.prototype.readUIntBE}. + */ + readUInt16BE(offset?: number): number; + /** + * @see {Buffer.prototype.readUIntBE}. + */ + readUInt32BE(offset?: number): number; + /** + * Reads the `byteLength` from this buffer at the specified `offset` and interprets the result + * as a little-endian integer supporting up to 48 bits of accuracy. + * + * @param offset An integer specifying the number of bytes to skip before starting to read. + * Must satisfy `0 <= offset <= buf.length - byteLength`. + * @param byteLength An integer between `1` and `6` specifying the number of bytes to read. + * Must satisfy `0 < byteLength <= 6`. + */ + readUIntLE(offset: number, byteLength: number): number; + /** + * @see {Buffer.prototype.readUIntLE}. + */ + readUInt16LE(offset?: number): number; + /** + * @see {Buffer.prototype.readUIntLE}. + */ + readUInt32LE(offset?: number): number; + + /** + * Reads a 64-bit, big-endian double from this buffer at the specified `offset`. + * + * @param offset An integer specifying the number of bytes to skip before starting to read. + * Must satisfy `0 <= offset <= buf.length - 8`. Defaults to `0`. + */ + readDoubleBE(offset?: number): number; + /** + * Reads a 64-bit, little-endian double from this buffer at the specified `offset`. + * + * @param offset An integer specifying the number of bytes to skip before starting to read. + * Must satisfy `0 <= offset <= buf.length - 8`. Defaults to `0`. + */ + readDoubleLE(offset?: number): number; + + /** + * Reads a 32-bit, big-endian float from this buffer at the specified `offset`. + * + * @param offset An integer specifying the number of bytes to skip before starting to read. + * Must satisfy `0 <= offset <= buf.length - 4`. Defaults to `0`. + */ + readFloatBE(offset?: number): number; + /** + * Reads a 32-bit, little-endian float from this buffer at the specified `offset`. + * + * @param offset An integer specifying the number of bytes to skip before starting to read. + * Must satisfy `0 <= offset <= buf.length - 4`. Defaults to `0`. + */ + readFloatLE(offset?: number): number; + + /** + * Returns a new `Buffer` that references **the same memory as the original**, but offset and + * cropped by `start` and `end`. + * + * @param start Where the new `Buffer` will start. Defaults to `0`. + * @param end Where the new `Buffer` will end (not inclusive). If `end` is greater than + * `buf.length`, the same result as that of end equal to `buf.length` is returned. + * Defaults to `buf.length`. + */ + subarray(start?: number, end?: number): Buffer; + + /** + * Returns a new `Buffer` that references **the same memory as the original**, but offset and + * cropped by the `start` and end `values`. + * + * @param start Where the new `Buffer` will start. Defaults to `0`. + * @param end Where the new `Buffer` will end (not inclusive). Defaults to `buf.length`. + */ + slice(begin?: number, end?: number): Buffer; + + /** + * Interprets this buffer as an array of unsigned 16-bit numbers and swaps the byte order + * in-place. + * + * @throws {RangeError} if `buf.length` is not a multiple of 2. + */ + swap16(): Buffer; + /** + * Interprets this buffer as an array of unsigned 32-bit numbers and swaps the byte order + * in-place. + * + * @throws {RangeError} if `buf.length` is not a multiple of 4. + */ + swap32(): Buffer; + /** + * Interprets this buffer as an array of 64-bit numbers and swaps byte order in-place. + * + * @throws {RangeError} if `buf.length` is not a multiple of 8. + */ + swap32(): Buffer; + + /** + * Returns a JSON representation of this buffer. `JSON.stringify()` implicitly calls this + * function when stringifying a `Buffer` instance. + */ + toJSON(): { type: "Buffer"; data: number[] }; + + /** + * Decodes this buffer to a string according to the specified character `encoding`. + * + * @param encoding The character encoding. Defaults to `'utf8'`. + * @param start The byte offset to start decoding at. Defaults to `0`. + * @param end The byte offset to stop decoding at (not inclusive). Defaults to `buf.length`. + */ + toString(encoding?: BufferEncoding, start?: number, end?: number): string; + + /** + * Writes a string `str` to this buffer at the `offset` according to the character `encoding`. + * If this buffer did not contain enough space to fit the entire string, only part of the + * string will be written, however, partially encoded characters will not be written. + * + * @param str The string to write into this buffer. + * @param offset An integer specifying the number of bytes to skip before starting to write `str`. + * Defaults to `0`. + * @param length An integer specifying the number of bytes to write. + * Defaults to `buf.length - offset`. + * @param encoding The character encoding of `str`. Defaults to `'utf8'`. + * @return Offset plus the number of bytes written. + */ + write(str: NjsStringLike, encoding?: BufferEncoding): number; + write(str: NjsStringLike, offset: number, encoding?: BufferEncoding): number; + write(str: NjsStringLike, offset: number, length: number, encoding?: BufferEncoding): number; + + /** + * Writes `byteLength` bytes of `value` to this buffer at the specified `offset` as big-endian. + * Supports up to 48 bits of accuracy. + * + * @param value The number to be written into this buffer. + * @param offset An integer specifying the number of bytes to skip before starting to write. + * Must satisfy `0 <= offset <= buf.length - byteLength`. + * @param byteLength An integer between `1` and `6` specifying the number of bytes to read. + * Must satisfy `0 < byteLength <= 6`. + * @return Offset plus the number of bytes written. + */ + writeIntBE(value: number, offset: number, byteLength: number): number; + /** + * @see {Buffer.prototype.writeIntBE}. + */ + writeInt8(value: number, offset?: number): number; + /** + * @see {Buffer.prototype.writeIntBE}. + */ + writeInt16BE(value: number, offset?: number): number; + /** + * @see {Buffer.prototype.writeIntBE}. + */ + writeInt32BE(value: number, offset?: number): number; + /** + * Writes `byteLength` bytes of `value` to this buffer at the specified `offset` as + * little-endian. Supports up to 48 bits of accuracy. + * + * @param value The number to be written into this buffer. + * @param offset An integer specifying the number of bytes to skip before starting to write. + * Must satisfy `0 <= offset <= buf.length - byteLength`. + * @param byteLength An integer between `1` and `6` specifying the number of bytes to read. + * Must satisfy `0 < byteLength <= 6`. + * @return Offset plus the number of bytes written. + */ + writeIntLE(value: number, offset: number, byteLength: number): number; + /** + * @see {Buffer.prototype.writeIntLE}. + */ + writeInt16LE(value: number, offset?: number): number; + /** + * @see {Buffer.prototype.writeIntLE}. + */ + writeInt32LE(value: number, offset?: number): number; + + /** + * Writes `byteLength` bytes of `value` to this buffer at the specified `offset` as big-endian. + * Supports up to 48 bits of accuracy. + * + * @param value The number to be written into this buffer. + * @param offset An integer specifying the number of bytes to skip before starting to write. + * Must satisfy `0 <= offset <= buf.length - byteLength`. + * @param byteLength An integer between `1` and `6` specifying the number of bytes to read. + * Must satisfy `0 < byteLength <= 6`. + * @return Offset plus the number of bytes written. + */ + writeUIntBE(value: number, offset: number, byteLength: number): number; + /** + * @see {Buffer.prototype.writeUIntBE}. + */ + writeUInt8(value: number, offset?: number): number; + /** + * @see {Buffer.prototype.writeUIntBE}. + */ + writeUInt16BE(value: number, offset?: number): number; + /** + * @see {Buffer.prototype.writeUIntBE}. + */ + writeUInt32BE(value: number, offset?: number): number; + /** + * Writes `byteLength` bytes of `value` to this buffer at the specified `offset` as + * little-endian. Supports up to 48 bits of accuracy. + * + * @param value The number to be written into this buffer. + * @param offset An integer specifying the number of bytes to skip before starting to write. + * Must satisfy `0 <= offset <= buf.length - byteLength`. + * @param byteLength An integer between `1` and `6` specifying the number of bytes to read. + * Must satisfy `0 < byteLength <= 6`. + * @return Offset plus the number of bytes written. + */ + writeUIntLE(value: number, offset: number, byteLength: number): number; + /** + * @see {Buffer.prototype.writeUIntLE}. + */ + writeUInt16LE(value: number, offset?: number): number; + /** + * @see {Buffer.prototype.writeUIntLE}. + */ + writeUInt32LE(value: number, offset?: number): number; + + /** + * Writes the `value` to this buffer at the specified `offset` as big-endian. + * + * @param value The number to be written into this buffer. + * @param offset An integer specifying the number of bytes to skip before starting to write. + * Must satisfy `0 <= offset <= buf.length - 8`. Defaults to `0`. + * @return Offset plus the number of bytes written. + */ + writeDoubleBE(value: number, offset?: number): number; + /** + * Writes the `value` to this buffer at the specified `offset` as little-endian. + * + * @param value The number to be written into this buffer. + * @param offset An integer specifying the number of bytes to skip before starting to write. + * Must satisfy `0 <= offset <= buf.length - 8`. Defaults to `0`. + * @return Offset plus the number of bytes written. + */ + writeDoubleLE(value: number, offset?: number): number; + + /** + * Writes the `value` to this buffer at the specified `offset` as big-endian. + * + * @param value The number to be written into this buffer. + * @param offset An integer specifying the number of bytes to skip before starting to write. + * Must satisfy `0 <= offset <= buf.length - 4`. Defaults to `0`. + * @return Offset plus the number of bytes written. + */ + writeFloatBE(value: number, offset?: number): number; + /** + * Writes the `value` to this buffer at the specified `offset` as little-endian. + * + * @param value The number to be written into this buffer. + * @param offset An integer specifying the number of bytes to skip before starting to write. + * Must satisfy `0 <= offset <= buf.length - 4`. Defaults to `0`. + * @return Offset plus the number of bytes written. + */ + writeFloatLE(value: number, offset?: number): number; +} + + // Global objects interface NjsGlobal { From 9711ae92d40c1e0d4944bf65cd4f8ca1ae2500fe Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Fri, 9 Oct 2020 02:33:31 +0200 Subject: [PATCH 2/5] Types: Add types for fs module Created according to http://nginx.org/en/docs/njs/reference.html. Signed-off-by: Jakub Jirutka --- src/ts/fs.d.ts | 384 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 src/ts/fs.d.ts diff --git a/src/ts/fs.d.ts b/src/ts/fs.d.ts new file mode 100644 index 000000000..682cee490 --- /dev/null +++ b/src/ts/fs.d.ts @@ -0,0 +1,384 @@ +/// + +declare module "fs" { + + /** + * File system flag that controls opening of a file. + * + * - `'a'` - Open a file for appending. The file is created if it does not exist. + * - `'ax'` - The same as `'a'` but fails if the file already exists. + * - `'a+'` - Open a file for reading and appending. If the file does not exist, it will be created. + * - `'ax+'` - The same as `'a+'` but fails if the file already exists. + * - `'as'` - Open a file for appending in synchronous mode. If the file does not exist, it will be created. + * - `'as+'` - Open a file for reading and appending in synchronous mode. If the file does not exist, it will be created. + * - `'r'` - Open a file for reading. An exception occurs if the file does not exist. + * - `'r+'` - Open a file for reading and writing. An exception occurs if the file does not exist. + * - `'rs+'` - Open a file for reading and writing in synchronous mode. Instructs the operating system to bypass the local file system cache. + * - `'w'` - Open a file for writing. If the file does not exist, it will be created. If the file exists, it will be replaced. + * - `'wx'` - The same as `'w'` but fails if the file already exists. + * - `'w+'` - Open a file for reading and writing. If the file does not exist, it will be created. If the file exists, it will be replaced. + * - `'wx+'` - The same as `'w+'` but fails if the file already exists. + */ + export type OpenMode = "a" | "ax" | "a+" | "ax+" | "as" | "as+" | "r" | "r+" | "rs+" | "w" | "wx" | "w+" | "wx+"; + + export type FileEncoding = BufferEncoding; + + /** + * Valid types for path values in "fs". + */ + export type PathLike = string | Buffer; + + /** + * A representation of a directory entry - a file or a subdirectory. + * + * When `readdirSync()` is called with the `withFileTypes` option, the resulting array contains + * `fs.Dirent` objects. + */ + export interface Dirent { + /** + * @returns `true` if the object describes a block device. + */ + isBlockDevice(): boolean; + /** + * @returns `true` if the object describes a character device. + */ + isCharacterDevice(): boolean; + /** + * @returns `true` if the object describes a file system directory. + */ + isDirectory(): boolean; + /** + * @returns `true` if the object describes a first-in-first-out (FIFO) pipe. + */ + isFIFO(): boolean; + /** + * @returns `true` if the object describes a regular file. + */ + isFile(): boolean; + /** + * @returns `true` if the object describes a socket. + */ + isSocket(): boolean; + /** + * @returns `true` if the object describes a symbolic link. + */ + isSymbolicLink(): boolean; + + /** + * The name of the file this object refers to. + */ + name: string; + } + + type WriteFileOptions = { + mode?: number; + flag?: OpenMode; + }; + + type Constants = { + /** + * Indicates that the file is visible to the calling process, used by default if no mode + * is specified. + */ + F_OK: 0; + /** + * Indicates that the file can be read by the calling process. + */ + R_OK: 4; + /** + * Indicates that the file can be written by the calling process. + */ + W_OK: 2; + /** + * Indicates that the file can be executed by the calling process. + */ + X_OK: 1; + }; + + interface Promises { + /** + * Asynchronously tests permissions for a file or directory specified in the `path`. + * If the check fails, an error will be returned, otherwise, the method will return undefined. + * + * @example + * import fs from 'fs' + * fs.promises.access('/file/path', fs.constants.R_OK | fs.constants.W_OK) + * .then(() => console.log('has access')) + * .catch(() => console.log('no access')) + * + * @since 0.3.9 + * @param path A path to a file or directory. + * @param mode An optional integer that specifies the accessibility checks to be performed. + * Defaults to `fs.constants.F_OK`. + */ + access(path: PathLike, mode?: number): Promise; + + /** + * Asynchronously appends specified `data` to a file with provided `filename`. + * If the file does not exist, it will be created. + * + * @since 0.4.4 + * @param path A path to a file. + * @param data The data to write. + * @param options An object optionally specifying the file mode and flag. + * If `mode` is not supplied, the default of `0o666` is used. + * If `flag` is not supplied, the default of `'a'` is used. + */ + appendFile(path: PathLike, data: NjsStringLike | Buffer, options?: WriteFileOptions): Promise; + + /** + * Asynchronously creates a directory at the specified `path`. + * + * @since 0.4.2 + * @param path A path to a file. + * @param options The file mode (or an object specifying the file mode). Defaults to `0o777`. + */ + mkdir(path: PathLike, options?: { mode?: number } | number): Promise; + + /** + * Asynchronously reads the contents of a directory at the specified `path`. + * + * @since 0.4.2 + * @param path A path to a file. + * @param options A string that specifies encoding or an object optionally specifying + * the following keys: + * - `encoding` - `'utf8'` (default) or `'buffer'` (since 0.4.4) + * - `withFileTypes` - if set to `true`, the files array will contain `fs.Dirent` objects; defaults to `false`. + */ + readdir(path: PathLike, options?: { encoding?: "utf8"; withFileTypes?: false; } | "utf8"): Promise; + readdir(path: PathLike, options: { encoding: "buffer"; withFileTypes?: false; } | "buffer"): Promise; + readdir(path: PathLike, options: { encoding?: "utf8" | "buffer"; withFileTypes: true; }): Promise; + + /** + * Asynchronously returns the contents of the file with provided `filename`. + * If an encoding is specified, a `string` is returned, otherwise, a `Buffer`. + * + * @param path A path to a file. + * @param options A string that specifies encoding or an object with the following optional keys: + * - `encoding` - `'utf8'`, `'hex'`, `'base64'`, or `'base64url'` (the last three since 0.4.4). + * - `flag` - file system flag, defaults to `r`. + */ + readFile(path: PathLike): Promise; + readFile(path: PathLike, options?: { flag?: OpenMode; }): Promise; + readFile(path: PathLike, options: { encoding?: FileEncoding; flag?: OpenMode; } | FileEncoding): Promise; + + /** + * Asynchronously computes the canonical pathname by resolving `.`, `..` and symbolic links using + * `realpath(3)`. + * + * @since 0.3.9 + * @param path A path to a file. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. + */ + realpath(path: PathLike, options?: { encoding?: "utf8" } | "utf8"): Promise; + realpath(path: PathLike, options: { encoding: "buffer" } | "buffer"): Promise; + + /** + * Asynchronously changes the name or location of a file from `oldPath` to `newPath`. + * + * @since 0.3.4 + * @param oldPath A path to a file. + * @param newPath A path to a file. + */ + rename(oldPath: PathLike, newPath: PathLike): Promise; + + /** + * Asynchronously removes a directory at the specified `path`. + * + * @since 0.4.2 + * @param path A path to a file. + */ + rmdir(path: PathLike): Promise; + + /** + * Asynchronously creates the link called `path` pointing to `target` using `symlink(2)`. + * Relative targets are relative to the link’s parent directory. + * + * @since 0.3.9 + * @param target A path to an existing file. + * @param path A path to the new symlink. + */ + symlink(target: PathLike, path: PathLike): Promise; + + /** + * Asynchronously unlinks a file by `path`. + * + * @since 0.3.9 + * @param path A path to a file. + */ + unlink(path: PathLike): Promise; + + /** + * Asynchronously writes `data` to a file with provided `filename`. If the file does not + * exist, it will be created, if the file exists, it will be replaced. + * + * @since 0.4.4 + * @param path A path to a file. + * @param data The data to write. + * @param options An object optionally specifying the file mode and flag. + * If `mode` is not supplied, the default of `0o666` is used. + * If `flag` is not supplied, the default of `'w'` is used. + */ + writeFile(path: PathLike, data: NjsStringLike | Buffer, options?: WriteFileOptions): Promise; + } + + interface NjsFS { + /** + * Promissified versions of file system methods. + * + * @since 0.3.9 + */ + promises: Promises + /** + * File Access Constants + */ + constants: Constants + + /** + * Synchronously tests permissions for a file or directory specified in the `path`. + * If the check fails, an error will be returned, otherwise, the method will return undefined. + * + * @example + * try { + * fs.accessSync('/file/path', fs.constants.R_OK | fs.constants.W_OK); + * console.log('has access'); + * } catch (e) { + * console.log('no access'); + * } + * + * @since 0.3.9 + * @param path A path to a file or directory. + * @param mode An optional integer that specifies the accessibility checks to be performed. + * Defaults to `fs.constants.F_OK`. + */ + accessSync(path: PathLike, mode?: number): void; + + /** + * Synchronously appends specified `data` to a file with provided `filename`. + * If the file does not exist, it will be created. + * + * @since 0.4.4 + * @param path A path to a file. + * @param data The data to write. + * @param options An object optionally specifying the file mode and flag. + * If `mode` is not supplied, the default of `0o666` is used. + * If `flag` is not supplied, the default of `'a'` is used. + */ + appendFileSync(path: PathLike, data: NjsStringLike | Buffer, options?: WriteFileOptions): void; + + /** + * Synchronously creates a directory at the specified `path`. + * + * @since 0.4.2 + * @param path A path to a file. + * @param options The file mode (or an object specifying the file mode). Defaults to `0o777`. + */ + mkdirSync(path: PathLike, options?: { mode?: number } | number): void; + + /** + * Synchronously reads the contents of a directory at the specified `path`. + * + * @since 0.4.2 + * @param path A path to a file. + * @param options A string that specifies encoding or an object optionally specifying + * the following keys: + * - `encoding` - `'utf8'` (default) or `'buffer'` (since 0.4.4) + * - `withFileTypes` - if set to `true`, the files array will contain `fs.Dirent` objects; + * defaults to `false`. + */ + readdirSync(path: PathLike, options?: { encoding?: "utf8"; withFileTypes?: false; } | "utf8"): string[]; + readdirSync(path: PathLike, options: { encoding: "buffer"; withFileTypes?: false; } | "buffer"): Buffer[]; + readdirSync(path: PathLike, options: { encoding?: "utf8" | "buffer"; withFileTypes: true; }): Dirent[]; + + /** + * Synchronously returns the contents of the file with provided `filename`. + * If an encoding is specified, a `string` is returned, otherwise, a `Buffer`. + * + * @example + * import fs from 'fs' + * var file = fs.readFileSync('/file/path.tar.gz') + * var gzipped = file.slice(0,2).toString('hex') === '1f8b'; gzipped // => true + * + * @param path A path to a file. + * @param options A string that specifies encoding or an object with the following optional keys: + * - `encoding` - `'utf8'`, `'hex'`, `'base64'`, or `'base64url'` (the last three since 0.4.4). + * - `flag` - file system flag, defaults to `r`. + */ + readFileSync(path: PathLike): Buffer; + readFileSync(path: PathLike, options?: { flag?: OpenMode; }): Buffer; + readFileSync(path: PathLike, options: { encoding?: FileEncoding; flag?: OpenMode; } | FileEncoding): string; + + /** + * Synchronously computes the canonical pathname by resolving `.`, `..` and symbolic links using + * `realpath(3)`. + * + * @since 0.3.9 + * @param path A path to a file. + * @param options The encoding (or an object specifying the encoding), used as the encoding of the result. + */ + realpathSync(path: PathLike, options?: { encoding?: "utf8" } | "utf8"): string; + realpathSync(path: PathLike, options: { encoding: "buffer" } | "buffer"): Buffer; + + /** + * Synchronously changes the name or location of a file from `oldPath` to `newPath`. + * + * @example + * import fs from 'fs' + * var file = fs.renameSync('hello.txt', 'HelloWorld.txt') + * + * @since 0.3.4 + * @param oldPath A path to a file. + * @param newPath A path to a file. + */ + renameSync(oldPath: PathLike, newPath: PathLike): void; + + /** + * Synchronously removes a directory at the specified `path`. + * + * @since 0.4.2 + * @param path A path to a file. + */ + rmdirSync(path: PathLike): void; + + /** + * Synchronously creates the link called `path` pointing to `target` using `symlink(2)`. + * Relative targets are relative to the link’s parent directory. + * + * @since 0.3.9 + * @param target A path to an existing file. + * @param path A path to the new symlink. + */ + symlinkSync(target: PathLike, path: PathLike): void; + + /** + * Synchronously unlinks a file by `path`. + * + * @since 0.3.9 + * @param path A path to a file. + */ + unlinkSync(path: PathLike): void; + + /** + * Synchronously writes `data` to a file with provided `filename`. If the file does not exist, + * it will be created, if the file exists, it will be replaced. + * + * @example + * import fs from 'fs' + * fs.writeFileSync('hello.txt', 'Hello world') + * + * @since 0.4.4 + * @param path A path to a file. + * @param data The data to write. + * @param options An object optionally specifying the file mode and flag. + * If `mode` is not supplied, the default of `0o666` is used. + * If `flag` is not supplied, the default of `'w'` is used. + */ + writeFileSync(path: PathLike, data: NjsStringLike | Buffer, options?: WriteFileOptions): void; + } + + const fs: NjsFS; + + // It's exported like this because njs doesn't support named imports. + // TODO: Replace NjsFS with individual named exports as soon as njs supports named imports. + export default fs; +} From 230ed5f1bd1747bf1fc3801ff331a34a9ab51d09 Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Fri, 9 Oct 2020 17:05:47 +0200 Subject: [PATCH 3/5] Types: Add types for querystring module Created according to http://nginx.org/en/docs/njs/reference.html. Signed-off-by: Jakub Jirutka --- src/ts/querystring.d.ts | 101 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/ts/querystring.d.ts diff --git a/src/ts/querystring.d.ts b/src/ts/querystring.d.ts new file mode 100644 index 000000000..0368ec1c4 --- /dev/null +++ b/src/ts/querystring.d.ts @@ -0,0 +1,101 @@ +/// + +declare module "querystring" { + + export interface ParsedUrlQuery { + [key: string]: string | string[] | undefined; + } + + export interface ParsedUrlQueryInput { + [key: string]: NjsStringLike | number | boolean | NjsStringLike[] | number[] | boolean[] | null | undefined; + } + + interface ParseOptions { + /** + * Function used to decode percent-encoded characters in the query string. + * Defaults to `querystring.unescape()`. + */ + decodeURIComponent?: (str: NjsStringLike) => string; + + /** + * The maximum number of keys to parse; defaults to `1000`. + * The `0` value removes limitations for counting keys. + */ + maxKeys?: number; + } + + interface StringifyOptions { + /** + * The function to use when converting URL-unsafe characters to percent-encoding in the + * query string; defaults to `querystring.escape()`. + */ + encodeURIComponent?: (str: NjsStringLike) => string; + } + + interface QueryString { + /** + * Performs URL encoding of the given string `str`, returns an escaped query string. + * The method is used by `querystring.stringify()` and should not be used directly. + * + * @param str The query string to escape. + * @return The escaped query string. + */ + escape(str: NjsStringLike): string; + + /** + * Parses the query string URL and returns an object. + * + * By default, percent-encoded characters within the query string are assumed to use the + * UTF-8 encoding, invalid UTF-8 sequences will be replaced with the `U+FFFD` replacement + * character. + * + * @param query The query string. + * @param separator The substring for delimiting key and value pairs in the query string; defaults to `'&'`. + * @param equal The substring for delimiting keys and values in the query string, defaults to `'='`. + * @param options An object optionally specifying `decodeURIComponent` function and `maxKeys` number. + * @return An object containing the components of the query string. + */ + parse(query: NjsStringLike, separator?: NjsStringLike, equal?: NjsStringLike, options?: ParseOptions): ParsedUrlQuery; + + /** + * An alias for `querystring.parse()`. + */ + decode(query: NjsStringLike, separator?: NjsStringLike, equal?: NjsStringLike, options?: ParseOptions): ParsedUrlQuery; + + /** + * Serializes an object and returns a URL query string. + * + * By default, characters that require percent-encoding within the query string are encoded + * as UTF-8. If other encoding is required, then `encodeURIComponent` option should be + * specified. + * + * @param obj The data to convert to a query string. + * @param separator The substring for delimiting key and value pairs in the query string; defaults to `'&'`. + * @param equal The substring for delimiting keys and values in the query string; defaults to `'='`. + * @param options An object optionally specifying `encodeURIComponent` function. + * @return A query string. + */ + stringify(obj: ParsedUrlQueryInput, separator?: NjsStringLike, equal?: NjsStringLike, options?: StringifyOptions): string; + + /** + * An alias for `querystring.stringify()`. + */ + encode(obj: ParsedUrlQueryInput, separator?: NjsStringLike, equal?: NjsStringLike, options?: StringifyOptions): string; + + /** + * Performs decoding of URL percent-encoded characters of the string `str`, returns an + * unescaped query string. The method is used by `querystring.parse()` and should not be + * used directly. + * + * @param str An escaped query string. + * @return An unescaped string. + */ + unescape(str: NjsStringLike): string; + } + + const querystring: QueryString; + + // It's exported like this because njs doesn't support named imports. + // TODO: Replace NjsFS with individual named exports as soon as njs supports named imports. + export default querystring; +} From f90044bc1bf2822b1ee41392236ee61a52957120 Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Fri, 9 Oct 2020 17:28:58 +0200 Subject: [PATCH 4/5] Types: Add types for crypto module Created according to http://nginx.org/en/docs/njs/reference.html. Signed-off-by: Jakub Jirutka --- src/ts/crypto.d.ts | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/ts/crypto.d.ts diff --git a/src/ts/crypto.d.ts b/src/ts/crypto.d.ts new file mode 100644 index 000000000..5895b3e74 --- /dev/null +++ b/src/ts/crypto.d.ts @@ -0,0 +1,76 @@ +/// + +declare module "crypto" { + + export type Algorithm = "md5" | "sha1" | "sha256"; + + export type DigestEncoding = Exclude; + + export interface Hash { + /** + * Updates the hash content with the given `data` and returns self. + */ + update(data: NjsStringLike | Buffer | DataView | TypedArray): Hash; + + /** + * Calculates the digest of all of the data passed using `hash.update()`. + * + * @example + * import cr from 'crypto' + * cr.createHash('sha1').update('A').update('B').digest('base64url') // => 'BtlFlCqiamG-GMPiK_GbvKjdK10' + * + * @param encoding The encoding of the return value. If not provided, a `Buffer` object + * (or a byte string before version 0.4.4) is returned. + * @return A calculated digest. + */ + digest(): Buffer; + digest(encoding: DigestEncoding): string; + } + + export interface Hmac { + /** + * Updates the HMAC content with the given `data` and returns self. + */ + update(data: NjsStringLike | Buffer | DataView | TypedArray): Hmac; + + /** + * Calculates the HMAC digest of all of the data passed using `hmac.update()`. + * + * @example + * import cr from 'crypto' + * cr.createHmac('sha1', 'secret.key').update('AB').digest('base64url') // => 'Oglm93xn23_MkiaEq_e9u8zk374' + * + * @param encoding The encoding of the return value. If not provided, a `Buffer` object + * (or a byte string before version 0.4.4) is returned. + * @return The calculated HMAC digest. + */ + digest(): Buffer; + digest(encoding: DigestEncoding): string; + } + + interface Crypto { + /** + * Creates and returns a `Hash` object that can be used to generate hash digests using + * the given `algorithm`. + * + * @param algorithm `'md5'`, `'sha1'`, or `'sha256'` + * @returns A `Hash` object. + */ + createHash(algorithm: Algorithm): Hash; + + /** + * Creates and returns an HMAC object that uses the given `algorithm` and secret `key`. + * + * @param algorithm `'md5'`, `'sha1'`, or `'sha256'` + * @param key The secret key. + * @returns An `HMAC` object. + */ + createHmac(algorithm: Algorithm, key: NjsStringLike): Hmac; + } + + const crypto: Crypto; + + // It's exported like this because njs doesn't support named imports. + // TODO: Replace NjsFS with individual named exports as soon as njs supports named imports. + export default crypto; +} From 2b9b808e3b7c9d857e7c3c712ae2d5863e7c3baf Mon Sep 17 00:00:00 2001 From: Jakub Jirutka Date: Mon, 19 Oct 2020 21:42:01 +0200 Subject: [PATCH 5/5] Types: Tag String.bytesFrom() in as `@deprecated` https://github.com/nginx/njs/pull/342#issuecomment-712394673 --- src/ts/njs_core.d.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ts/njs_core.d.ts b/src/ts/njs_core.d.ts index c470b84e8..e830aea27 100644 --- a/src/ts/njs_core.d.ts +++ b/src/ts/njs_core.d.ts @@ -3,10 +3,14 @@ type BufferEncoding = "utf8" | "hex" | "base64" | "base64url"; interface StringConstructor { /** * Creates a byte string from an encoded string. + * + * @deprecated will be removed in the future. */ bytesFrom(bytes: string, encoding: Exclude): NjsByteString; /** * Creates a byte string from an array that contains octets. + * + * @deprecated will be removed in the future. */ bytesFrom(bytes: Array): NjsByteString; }