Reformat project into workspaces
CI/CD Pipeline / test (push) Failing after 1m51s
CI/CD Pipeline / deploy-internal (push) Has been skipped

This commit is contained in:
chris committed 2026-08-28 19:58:43 -04:00
1 parent 20bb10114b
commit c3e2cf5ed3
38 files changed
+975 -298

No files matched your search

View File
File renamed without changes.
+35
View File
@@ -0,0 +1,35 @@
{
"name": "book-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "tsx run-tests.ts",
"db:migrate": "dotenv dbmate up"
},
"keywords": [],
"author": "Chris Smith",
"license": "ISC",
"devDependencies": {
"@types/cors": "^2.8.19",
"@types/express": "^5.0.6",
"@types/morgan": "^1.9.10",
"@types/node": "^26.3.0",
"@types/pg": "^8.23.1",
"dbmate": "^2.35.0",
"tsx": "^4.23.12",
"typescript": "^7.0.2"
},
"dependencies": {
"cors": "^2.8.6",
"dotenv": "^17.4.2",
"dotenv-cli": "^11.0.0",
"express": "^5.2.1",
"morgan": "^1.11.0",
"pg": "^8.23.0"
},
"allowScripts": {
"dotenv-cli@11.0.0": true,
"esbuild@0.28.2": true
}
}
+14
View File
@@ -0,0 +1,14 @@
import { run } from 'node:test';
import { globSync } from 'node:fs';
import { spec } from 'node:test/reporters';
const files = globSync('src/**/*.test.ts');
if (files.length === 0) {
console.error('❌ No test files found in src/**/*.test.ts');
process.exit(1);
}
run({ files })
.compose(new spec())
.pipe(process.stdout);
+40
View File
@@ -0,0 +1,40 @@
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { CategoryRepository } from './category.repository';
describe('CategoryRepository - ltree SQL Generator', () => {
const repository = new CategoryRepository();
describe('generateDescendantsQuery()', () => {
it('should generate valid SQL using the ltree descenant operator (<@)', () => {
const parentPath = 'Top.Science';
const result = repository.generateDescendantsQuery(parentPath);
// veriy the generated SQL syntax as correct ltree
assert.match(result.sql, /<@/);
assert.match(result.sql, /::ltree/);
assert.deepEqual(result.values, ['Top.Science']);
});
});
describe('generateWildcardQuery()', () => {
it('should generate valid SQL utilizing an lquery matching operator (~)', () => {
const result = repository.generateWildcardQuery('Top.*.Astronomy');
assert.match(result.sql, /~/);
assert.match(result.sql, /::lquery/);
assert.equal(result.values[0], 'Top.*.Astronomy');
});
});
describe('isValidLtreePath() validation utility', () => {
it('should pass for correctly formatted dot-separated ltree structures', () => {
assert.equal(repository.isValidLtreePath('Top.Hobbies.Amateurs_Astronomy'), true);
});
it('should fail if special characters or spaces are introduced into the path', () => {
assert.equal(repository.isValidLtreePath('Top.Hobbies.Bad Path!'), false);
assert.equal(repository.isValidLtreePath('Top..InvalidDoubleDot'), false);
});
});
});
+30
View File
@@ -0,0 +1,30 @@
// structural interface to the test table
export interface CatetoryNode {
id: number;
name: string;
path: string; // ltree field
}
export class CategoryRepository {
// simulate generating a SQL query targeting child paths
generateDescendantsQuery(parentPath: string): { sql: string; values: string[] } {
return {
sql: 'SELECT id, name, path FROM categories WHERE path <@ $1::ltree',
values: [parentPath]
};
}
generateWildcardQuery(pattern: string): { sql: string, values: string[] } {
// Simulate genrating a SQL query using ltree wildcards
return {
sql: 'SELECT id, name, path FROM categories WHERE path ~ $1::lquery',
values: [pattern]
};
}
// helper utility to validate a string as an ltree value
isValidLtreePath(path: string): boolean {
const ltreeRegex = /^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$/;
return ltreeRegex.test(path);
}
}
+47 -21
View File
@@ -1,13 +1,35 @@
{ {
"name": "book-test", "name": "book-test-workspace",
"version": "1.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"api": {
"name": "book-test",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"cors": "^2.8.6",
"dotenv": "^17.4.2",
"dotenv-cli": "^11.0.0",
"express": "^5.2.1",
"morgan": "^1.11.0",
"pg": "^8.23.0"
},
"devDependencies": {
"@types/cors": "^2.8.19",
"@types/express": "^5.0.6",
"@types/morgan": "^1.9.10",
"@types/node": "^26.3.0",
"@types/pg": "^8.23.1",
"dbmate": "^2.35.0",
"tsx": "^4.23.12",
"typescript": "^7.0.2"
}
},
"node_modules/@dbmate/linux-x64": { "node_modules/@dbmate/linux-x64": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/@dbmate/linux-x64/-/linux-x64-2.35.0.tgz", "resolved": "https://registry.npmjs.org/@dbmate/linux-x64/-/linux-x64-2.35.1.tgz",
"integrity": "sha512-oF88oEwEX8pZGuU6f1Zqevqrz0rH2tiUQG7cUmCfJ/VTkWmWVzEQ8yleMwvL8iWJUHgcXotPnQy++JSQhuaB9Q==", "integrity": "sha512-gdr9Q6vMMUaNYz8fv64oNSuoHYLjpeuZjahY6J7Dy4c6wQVcfLs7t3aiBCBxlvVkjJJIr5Ig3ApwqC0V2IojQA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -109,9 +131,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "26.3.0", "version": "26.4.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.3.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz",
"integrity": "sha512-L3fgrnchriRC2ExBflb8j4uZZURHZfQsmQeyVzhjcHW4kkwVyo8/0h1B2MVzMTrYUJYu6G7EWs14hW/L9putqw==", "integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -244,6 +266,10 @@
"url": "https://opencollective.com/express" "url": "https://opencollective.com/express"
} }
}, },
"node_modules/book-test": {
"resolved": "api",
"link": true
},
"node_modules/bytes": { "node_modules/bytes": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -354,22 +380,22 @@
} }
}, },
"node_modules/dbmate": { "node_modules/dbmate": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/dbmate/-/dbmate-2.35.0.tgz", "resolved": "https://registry.npmjs.org/dbmate/-/dbmate-2.35.1.tgz",
"integrity": "sha512-BqVpyxFZyaCOOHfB1LHgh5FzgthU719lzaWKPRhXj8s3rJtCseeVw5WfzYm8haF9Dx0UhNu0RtCaEouoexW1Gg==", "integrity": "sha512-TGhNRbSnlLeLjpV/m4uHJSwZhsJZEeE+IIl98UYbb6s63j1ZsPY6XuVWL6pl3YYyfupVh7pAye6iuOAYf3Maxw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
"dbmate": "dist/cli.js" "dbmate": "dist/cli.js"
}, },
"optionalDependencies": { "optionalDependencies": {
"@dbmate/darwin-arm64": "2.35.0", "@dbmate/darwin-arm64": "2.35.1",
"@dbmate/darwin-x64": "2.35.0", "@dbmate/darwin-x64": "2.35.1",
"@dbmate/linux-arm": "2.35.0", "@dbmate/linux-arm": "2.35.1",
"@dbmate/linux-arm64": "2.35.0", "@dbmate/linux-arm64": "2.35.1",
"@dbmate/linux-ia32": "2.35.0", "@dbmate/linux-ia32": "2.35.1",
"@dbmate/linux-x64": "2.35.0", "@dbmate/linux-x64": "2.35.1",
"@dbmate/win32-x64": "2.35.0" "@dbmate/win32-x64": "2.35.1"
} }
}, },
"node_modules/debug": { "node_modules/debug": {
@@ -864,9 +890,9 @@
} }
}, },
"node_modules/morgan": { "node_modules/morgan": {
"version": "1.11.0", "version": "1.12.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.11.0.tgz", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.12.0.tgz",
"integrity": "sha512-zSkVu3t18r39pw4ixfBKvfZi3y2UOqr7d4WYwcj3m8nXpEQK4rPO6GLzs/CExoRgmX3y9EjmmcXqv6jq0SK46g==", "integrity": "sha512-OHpTRQwn2ezasILW8iKe+Yww1XsfWsZIpUOLF7RDb2g5GwO3trPaRwi7+8BDiJ7HFx2Kg2mfUdCBcVhwYlOz2g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"basic-auth": "~2.0.1", "basic-auth": "~2.0.1",
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@dbmate/linux-x64", "name": "@dbmate/linux-x64",
"version": "2.35.0", "version": "2.35.1",
"description": "The linux x64 binary for dbmate", "description": "The linux x64 binary for dbmate",
"repository": { "repository": {
"type": "git", "type": "git",
+1 -1
View File
@@ -8,7 +8,7 @@ This package contains type definitions for node (https://nodejs.org/).
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node. Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node.
### Additional Details ### Additional Details
* Last updated: Mon, 24 Aug 2026 19:40:21 GMT * Last updated: Thu, 27 Aug 2026 00:14:49 GMT
* Dependencies: [undici-types](https://npmjs.com/package/undici-types) * Dependencies: [undici-types](https://npmjs.com/package/undici-types)
# Credits # Credits
+5
View File
@@ -463,4 +463,9 @@ declare module "node:buffer" {
*/ */
type AllowSharedBuffer = Buffer<ArrayBufferLike>; type AllowSharedBuffer = Buffer<ArrayBufferLike>;
} }
/**
* @deprecated This is intended for internal use, and will be removed once `@types/node` no longer supports
* TypeScript versions earlier than 5.7.
*/
type BufferView<T extends NodeJS.ArrayBufferView> = T extends NodeJS.ArrayBufferView<infer B> ? Buffer<B> : never;
} }
-2
View File
@@ -3475,7 +3475,6 @@ declare module "node:crypto" {
* ``` * ```
* @since v24.7.0 * @since v24.7.0
* @param algorithm Variant of Argon2, one of `"argon2d"`, `"argon2i"` or `"argon2id"`. * @param algorithm Variant of Argon2, one of `"argon2d"`, `"argon2i"` or `"argon2id"`.
* @experimental
*/ */
function argon2( function argon2(
algorithm: Argon2Algorithm, algorithm: Argon2Algorithm,
@@ -3515,7 +3514,6 @@ declare module "node:crypto" {
* console.log(derivedKey.toString('hex')); // 'af91dad...9520f15' * console.log(derivedKey.toString('hex')); // 'af91dad...9520f15'
* ``` * ```
* @since v24.7.0 * @since v24.7.0
* @experimental
*/ */
function argon2Sync(algorithm: Argon2Algorithm, parameters: Argon2Parameters): NonSharedBuffer; function argon2Sync(algorithm: Argon2Algorithm, parameters: Argon2Parameters): NonSharedBuffer;
/** /**
+119 -4
View File
@@ -15,6 +15,10 @@ declare module "node:dgram" {
exclusive?: boolean | undefined; exclusive?: boolean | undefined;
fd?: number | undefined; fd?: number | undefined;
} }
interface BindSyncOptions {
port?: number | undefined;
address?: string | undefined;
}
type SocketType = "udp4" | "udp6"; type SocketType = "udp4" | "udp6";
interface SocketOptions extends Abortable { interface SocketOptions extends Abortable {
type: SocketType; type: SocketType;
@@ -117,10 +121,12 @@ declare module "node:dgram" {
* messages on a named `port` and optional `address`. If `port` is not * messages on a named `port` and optional `address`. If `port` is not
* specified or is `0`, the operating system will attempt to bind to a * specified or is `0`, the operating system will attempt to bind to a
* random port. If `address` is not specified, the operating system will * random port. If `address` is not specified, the operating system will
* attempt to listen on all addresses. Once binding is complete, a `'listening'` event is emitted and the optional `callback` function is * attempt to listen on all addresses. Once binding is complete, a
* `'listening'` event is emitted and the optional `callback` function is
* called. * called.
* *
* Specifying both a `'listening'` event listener and passing a `callback` to the `socket.bind()` method is not harmful but not very * Specifying both a `'listening'` event listener and passing a
* `callback` to the `socket.bind()` method is not harmful but not very
* useful. * useful.
* *
* A bound datagram socket keeps the Node.js process running to receive * A bound datagram socket keeps the Node.js process running to receive
@@ -157,9 +163,82 @@ declare module "node:dgram" {
* @param callback with no parameters. Called when binding is complete. * @param callback with no parameters. Called when binding is complete.
*/ */
bind(port?: number, address?: string, callback?: () => void): this; bind(port?: number, address?: string, callback?: () => void): this;
bind(port?: number, callback?: () => void): this; bind(port: number, callback: () => void): this;
bind(callback?: () => void): this; bind(callback: () => void): this;
/**
* For UDP sockets, causes the `dgram.Socket` to listen for datagram
* messages on a named `port` and optional `address` that are passed as
* properties of an `options` object passed as the first argument. If
* `port` is not specified or is `0`, the operating system will attempt
* to bind to a random port. If `address` is not specified, the operating
* system will attempt to listen on all addresses. Once binding is
* complete, a `'listening'` event is emitted and the optional `callback`
* function is called.
*
* The `options` object may contain a `fd` property. When a `fd` greater
* than `0` is set, it will wrap around an existing socket with the given
* file descriptor. In this case, the properties of `port` and `address`
* will be ignored.
*
* Specifying both a `'listening'` event listener and passing a
* `callback` to the `socket.bind()` method is not harmful but not very
* useful.
*
* The `options` object may contain an additional `exclusive` property that is
* used when using `dgram.Socket` objects with the [`cluster`](https://nodejs.org/docs/latest-v26.x/api/cluster.html) module. When
* `exclusive` is set to `false` (the default), cluster workers will use the same
* underlying socket handle allowing connection handling duties to be shared.
* When `exclusive` is `true`, however, the handle is not shared and attempted
* port sharing results in an error. Creating a `dgram.Socket` with the `reusePort`
* option set to `true` causes `exclusive` to always be `true` when `socket.bind()`
* is called.
*
* A bound datagram socket keeps the Node.js process running to receive
* datagram messages.
*
* If binding fails, an `'error'` event is generated. In rare case (e.g.
* attempting to bind with a closed socket), an `Error` may be thrown.
*
* An example socket listening on an exclusive port is shown below.
*
* ```js
* socket.bind({
* address: 'localhost',
* port: 8000,
* exclusive: true,
* });
* ```
* @since v0.11.14
* @param options Required. Supports the following properties:
*/
bind(options: BindOptions, callback?: () => void): this; bind(options: BindOptions, callback?: () => void): this;
/**
* The synchronous counterpart of `socket.bind()`. `bind(2)` is a local,
* non-blocking system call, so the bind is performed inline and the resolved
* address is returned immediately, including the operating-system-assigned
* ephemeral port when `port` is `0`:
*
* ```js
* const dgram = require('node:dgram');
*
* const socket = dgram.createSocket('udp4');
* const address = socket.bindSync({ address: '0.0.0.0', port: 0 });
* console.log(address); // e.g. { address: '0.0.0.0', family: 'IPv4', port: 53124 }
* ```
*
* A bind failure such as `EADDRINUSE` is thrown synchronously rather than emitted
* as an `'error'` event. After `bindSync()` returns, `socket.address()` is
* valid synchronously and the `'listening'` event is emitted on the next tick.
*
* `address` must be a numeric IP literal; `bindSync()` never performs DNS
* resolution (asynchronous name resolution being the only genuinely blocking part
* of binding). Incoming datagrams continue to be delivered asynchronously via the
* `'message'` event. `bindSync()` always binds the socket's own handle and
* does not participate in [`cluster`](https://nodejs.org/docs/latest-v26.x/api/cluster.html) handle sharing.
* @since v26.4.0
* @returns The bound address as returned by `socket.address()`.
*/
bindSync(options?: BindSyncOptions): AddressInfo;
/** /**
* Close the underlying socket and stop listening for data on it. If a callback is * Close the underlying socket and stop listening for data on it. If a callback is
* provided, it is added as a listener for the `'close'` event. * provided, it is added as a listener for the `'close'` event.
@@ -182,6 +261,42 @@ declare module "node:dgram" {
*/ */
connect(port: number, address?: string, callback?: () => void): void; connect(port: number, address?: string, callback?: () => void): void;
connect(port: number, callback: () => void): void; connect(port: number, callback: () => void): void;
/**
* The synchronous counterpart of `socket.connect()`. For a UDP socket
* `connect(2)` only records the default peer address and is a local, non-blocking
* system call, so the association is performed inline. Any error raised by the
* call itself (for example `EAFNOSUPPORT` for a mismatched address family) is
* thrown synchronously rather than reported via the `'error'` event. Because
* `connect(2)` does not probe reachability, errors such as `ECONNREFUSED` are
* still surfaced asynchronously on a later send or receive, exactly as for
* `socket.connect()`:
*
* ```js
* const dgram = require('node:dgram');
*
* const socket = dgram.createSocket('udp4');
* socket.connectSync(41234, '127.0.0.1');
* console.log(socket.remoteAddress()); // { address: '127.0.0.1', family: 'IPv4', port: 41234 }
* ```
*
* If the socket is still unbound it is bound synchronously first. After
* `connectSync()` returns, `socket.remoteAddress()` is valid synchronously
* and the `'connect'` event is emitted on the next tick. Trying to call
* `connectSync()` on an already connected socket throws an
* `ERR_SOCKET_DGRAM_IS_CONNECTED` exception, and calling it while an
* asynchronous [`socket.bind()`][] is still in progress throws an
* `ERR_SOCKET_ALREADY_BOUND` exception.
*
* `address` must be a numeric IP literal; `connectSync()` never performs DNS
* resolution (asynchronous name resolution being the only genuinely blocking part
* of connecting).
* @since v26.4.0
* @param address A numeric IP address to connect to. Unlike
* `socket.connect()`, no DNS resolution is performed, so a host name is not
* accepted. If omitted, `'127.0.0.1'` (for `udp4` sockets) or `'::1'` (for
* `udp6` sockets) is used.
*/
connectSync(port: number, address?: string): void;
/** /**
* A synchronous function that disassociates a connected `dgram.Socket` from * A synchronous function that disassociates a connected `dgram.Socket` from
* its remote address. Trying to call `disconnect()` on an unbound or already * its remote address. Trying to call `disconnect()` on an unbound or already
+86 -76
View File
@@ -1,5 +1,5 @@
declare module "node:fs" { declare module "node:fs" {
import { NonSharedBuffer } from "node:buffer"; import { BufferView, NonSharedBuffer } from "node:buffer";
import { Abortable, EventEmitter, InternalEventEmitter } from "node:events"; import { Abortable, EventEmitter, InternalEventEmitter } from "node:events";
import { FileHandle } from "node:fs/promises"; import { FileHandle } from "node:fs/promises";
import * as stream from "node:stream"; import * as stream from "node:stream";
@@ -3029,6 +3029,19 @@ declare module "node:fs" {
* If no `options` object is specified, it will default with the above values. * If no `options` object is specified, it will default with the above values.
*/ */
function readSync(fd: number, buffer: NodeJS.ArrayBufferView, opts?: ReadOptions): number; function readSync(fd: number, buffer: NodeJS.ArrayBufferView, opts?: ReadOptions): number;
interface ReadFileOptions extends Abortable {
encoding?: BufferEncoding | null | undefined;
flag?: OpenMode | undefined;
}
interface ReadFileOptionsWithStringEncoding extends ReadFileOptions {
encoding: BufferEncoding;
}
interface ReadFileOptionsWithBufferEncoding extends ReadFileOptions {
encoding?: null | undefined;
}
interface ReadFileOptionsWithBuffer<T extends NodeJS.ArrayBufferView> extends ReadFileOptionsWithBufferEncoding {
buffer: T | ((size: number) => T);
}
/** /**
* Asynchronously reads the entire contents of a file. * Asynchronously reads the entire contents of a file.
* *
@@ -3046,6 +3059,11 @@ declare module "node:fs" {
* *
* If no encoding is specified, then the raw buffer is returned. * If no encoding is specified, then the raw buffer is returned.
* *
* If `buffer` is provided and no encoding is specified, the returned `Buffer` is
* a view over the supplied buffer containing only the bytes read. If the
* supplied buffer is too small to contain the entire file, the callback is
* called with an error.
*
* If `options` is a string, then it specifies the encoding: * If `options` is a string, then it specifies the encoding:
* *
* ```js * ```js
@@ -3054,7 +3072,8 @@ declare module "node:fs" {
* readFile('/etc/passwd', 'utf8', callback); * readFile('/etc/passwd', 'utf8', callback);
* ``` * ```
* *
* When the path is a directory, the behavior of `fs.readFile()` and {@link readFileSync} is platform-specific. On macOS, Linux, and Windows, an * When the path is a directory, the behavior of `fs.readFile()` and
* `fs.readFileSync()` is platform-specific. On macOS, Linux, and Windows, an
* error will be returned. On FreeBSD, a representation of the directory's contents * error will be returned. On FreeBSD, a representation of the directory's contents
* will be returned. * will be returned.
* *
@@ -3092,60 +3111,56 @@ declare module "node:fs" {
* *
* Aborting an ongoing request does not abort individual operating * Aborting an ongoing request does not abort individual operating
* system requests but rather the internal buffering `fs.readFile` performs. * system requests but rather the internal buffering `fs.readFile` performs.
*
* An example using the `buffer` option with a pre-allocated buffer:
*
* ```js
* import { Buffer } from 'node:buffer';
* import { readFile } from 'node:fs';
*
* const buf = Buffer.alloc(16384);
* readFile('/path/to/file', { buffer: buf }, (err, data) => {
* if (err) throw err;
* console.log(data); // A view over `buf` containing only the bytes read
* });
* ```
*
* An example using the `buffer` option with a function returning a buffer:
*
* ```js
* import { Buffer } from 'node:buffer';
* import { readFile } from 'node:fs';
*
* readFile('/path/to/file', {
* buffer: (size) => Buffer.alloc(size),
* }, (err, data) => {
* if (err) throw err;
* console.log(data);
* });
* ```
* @since v0.1.29 * @since v0.1.29
* @param path filename or file descriptor * @param path filename or file descriptor
*/ */
function readFile<T extends NodeJS.ArrayBufferView>(
path: PathOrFileDescriptor,
options: ReadFileOptionsWithBuffer<T>,
callback: (err: NodeJS.ErrnoException | null, data: BufferView<T>) => void,
): void;
function readFile( function readFile(
path: PathOrFileDescriptor, path: PathOrFileDescriptor,
options: options: ReadFileOptionsWithBufferEncoding | null | undefined,
| ({
encoding?: null | undefined;
flag?: string | undefined;
} & Abortable)
| undefined
| null,
callback: (err: NodeJS.ErrnoException | null, data: NonSharedBuffer) => void, callback: (err: NodeJS.ErrnoException | null, data: NonSharedBuffer) => void,
): void; ): void;
/**
* Asynchronously reads the entire contents of a file.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* If a file descriptor is provided, the underlying file will _not_ be closed automatically.
* @param options Either the encoding for the result, or an object that contains the encoding and an optional flag.
* If a flag is not provided, it defaults to `'r'`.
*/
function readFile( function readFile(
path: PathOrFileDescriptor, path: PathOrFileDescriptor,
options: options: ReadFileOptionsWithStringEncoding | BufferEncoding,
| ({
encoding: BufferEncoding;
flag?: string | undefined;
} & Abortable)
| BufferEncoding,
callback: (err: NodeJS.ErrnoException | null, data: string) => void, callback: (err: NodeJS.ErrnoException | null, data: string) => void,
): void; ): void;
/**
* Asynchronously reads the entire contents of a file.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* If a file descriptor is provided, the underlying file will _not_ be closed automatically.
* @param options Either the encoding for the result, or an object that contains the encoding and an optional flag.
* If a flag is not provided, it defaults to `'r'`.
*/
function readFile( function readFile(
path: PathOrFileDescriptor, path: PathOrFileDescriptor,
options: options: ReadFileOptions | BufferEncoding | null | undefined,
| (ObjectEncodingOptions & {
flag?: string | undefined;
} & Abortable)
| BufferEncoding
| undefined
| null,
callback: (err: NodeJS.ErrnoException | null, data: string | NonSharedBuffer) => void, callback: (err: NodeJS.ErrnoException | null, data: string | NonSharedBuffer) => void,
): void; ): void;
/**
* Asynchronously reads the entire contents of a file.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* If a file descriptor is provided, the underlying file will _not_ be closed automatically.
*/
function readFile( function readFile(
path: PathOrFileDescriptor, path: PathOrFileDescriptor,
callback: (err: NodeJS.ErrnoException | null, data: NonSharedBuffer) => void, callback: (err: NodeJS.ErrnoException | null, data: NonSharedBuffer) => void,
@@ -3200,16 +3215,37 @@ declare module "node:fs" {
| null, | null,
): Promise<string | NonSharedBuffer>; ): Promise<string | NonSharedBuffer>;
} }
interface ReadFileSyncOptions {
encoding?: BufferEncoding | null | undefined;
flag?: OpenMode | undefined;
}
interface ReadFileSyncOptionsWithStringEncoding extends ReadFileSyncOptions {
encoding: BufferEncoding;
}
interface ReadFileSyncOptionsWithBufferEncoding extends ReadFileSyncOptions {
encoding?: null | undefined;
}
interface ReadFileSyncOptionsWithBuffer<T extends NodeJS.ArrayBufferView>
extends ReadFileSyncOptionsWithBufferEncoding
{
buffer: T | ((size: number) => T);
}
/** /**
* Returns the contents of the `path`. * Returns the contents of the `path`.
* *
* For detailed information, see the documentation of the asynchronous version of * For detailed information, see the documentation of the asynchronous version of
* this API: {@link readFile}. * this API: `fs.readFile()`.
* *
* If the `encoding` option is specified then this function returns a * If the `encoding` option is specified then this function returns a
* string. Otherwise it returns a buffer. * string. Otherwise it returns a buffer.
* *
* Similar to {@link readFile}, when the path is a directory, the behavior of `fs.readFileSync()` is platform-specific. * If `buffer` is provided and no encoding is specified, the returned {Buffer} is
* a view over the supplied buffer containing only the bytes read. If the
* supplied buffer is too small to contain the entire file, an error will be
* thrown.
*
* Similar to `fs.readFile()`, when the path is a directory, the behavior of
* `fs.readFileSync()` is platform-specific.
* *
* ```js * ```js
* import { readFileSync } from 'node:fs'; * import { readFileSync } from 'node:fs';
@@ -3224,45 +3260,19 @@ declare module "node:fs" {
* @since v0.1.8 * @since v0.1.8
* @param path filename or file descriptor * @param path filename or file descriptor
*/ */
function readFileSync<T extends NodeJS.ArrayBufferView>(
path: PathOrFileDescriptor,
options: ReadFileSyncOptionsWithBuffer<T>,
): BufferView<T>;
function readFileSync( function readFileSync(
path: PathOrFileDescriptor, path: PathOrFileDescriptor,
options?: { options?: ReadFileSyncOptionsWithBufferEncoding | null,
encoding?: null | undefined;
flag?: string | undefined;
} | null,
): NonSharedBuffer; ): NonSharedBuffer;
/**
* Synchronously reads the entire contents of a file.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* If a file descriptor is provided, the underlying file will _not_ be closed automatically.
* @param options Either the encoding for the result, or an object that contains the encoding and an optional flag.
* If a flag is not provided, it defaults to `'r'`.
*/
function readFileSync( function readFileSync(
path: PathOrFileDescriptor, path: PathOrFileDescriptor,
options: options: ReadFileSyncOptionsWithStringEncoding | BufferEncoding,
| {
encoding: BufferEncoding;
flag?: string | undefined;
}
| BufferEncoding,
): string; ): string;
/** function readFileSync(path: PathOrFileDescriptor, options: ReadFileSyncOptions): string | NonSharedBuffer;
* Synchronously reads the entire contents of a file.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* If a file descriptor is provided, the underlying file will _not_ be closed automatically.
* @param options Either the encoding for the result, or an object that contains the encoding and an optional flag.
* If a flag is not provided, it defaults to `'r'`.
*/
function readFileSync(
path: PathOrFileDescriptor,
options?:
| (ObjectEncodingOptions & {
flag?: string | undefined;
})
| BufferEncoding
| null,
): string | NonSharedBuffer;
type WriteFileOptions = type WriteFileOptions =
| ( | (
& ObjectEncodingOptions & ObjectEncodingOptions
+61 -65
View File
@@ -1,5 +1,5 @@
declare module "node:fs/promises" { declare module "node:fs/promises" {
import { NonSharedBuffer } from "node:buffer"; import { BufferView, NonSharedBuffer } from "node:buffer";
import { Abortable } from "node:events"; import { Abortable } from "node:events";
import { Interface as ReadlineInterface } from "node:readline"; import { Interface as ReadlineInterface } from "node:readline";
import { import {
@@ -20,6 +20,10 @@ declare module "node:fs/promises" {
OpenDirOptions, OpenDirOptions,
OpenMode, OpenMode,
PathLike, PathLike,
ReadFileOptions,
ReadFileOptionsWithBuffer,
ReadFileOptionsWithBufferEncoding,
ReadFileOptionsWithStringEncoding,
ReadOptions, ReadOptions,
ReadOptionsWithBuffer, ReadOptionsWithBuffer,
ReadPosition, ReadPosition,
@@ -36,7 +40,6 @@ declare module "node:fs/promises" {
WriteStream, WriteStream,
WriteVResult, WriteVResult,
} from "node:fs"; } from "node:fs";
import { Stream } from "node:stream";
import { ByteReadableStream, Transform, Writer } from "node:stream/iter"; import { ByteReadableStream, Transform, Writer } from "node:stream/iter";
import { ReadableStream } from "node:stream/web"; import { ReadableStream } from "node:stream/web";
interface FileChangeInfo<T extends string | Buffer> { interface FileChangeInfo<T extends string | Buffer> {
@@ -357,39 +360,61 @@ declare module "node:fs/promises" {
* *
* If `options` is a string, then it specifies the `encoding`. * If `options` is a string, then it specifies the `encoding`.
* *
* If `buffer` is provided and no encoding is specified, the returned {Buffer} is
* a view over the supplied buffer containing only the bytes read. If the
* supplied buffer is too small to contain the entire file, the operation will
* fail.
*
* The `FileHandle` has to support reading. * The `FileHandle` has to support reading.
* *
* If one or more `filehandle.read()` calls are made on a file handle and then a `filehandle.readFile()` call is made, the data will be read from the current * If one or more `filehandle.read()` calls are made on a file handle and then a
* `filehandle.readFile()` call is made, the data will be read from the current
* position till the end of the file. It doesn't always read from the beginning * position till the end of the file. It doesn't always read from the beginning
* of the file. * of the file.
*
* An example using the `buffer` option with a pre-allocated buffer:
*
* ```js
* import { Buffer } from 'node:buffer';
* import { open } from 'node:fs/promises';
*
* const file = await open('./some/file/to/read');
* try {
* const buf = Buffer.alloc(16384);
* const contents = await file.readFile({ buffer: buf });
* console.log(contents); // A view over `buf` containing only the bytes read
* } finally {
* await file.close();
* }
* ```
*
* An example using the `buffer` option with a function returning a buffer:
*
* ```js
* import { Buffer } from 'node:buffer';
* import { open } from 'node:fs/promises';
*
* const file = await open('./some/file/to/read');
* try {
* const contents = await file.readFile({
* buffer: (size) => Buffer.alloc(size),
* });
* console.log(contents);
* } finally {
* await file.close();
* }
* ```
* @since v10.0.0 * @since v10.0.0
* @return Fulfills upon a successful read with the contents of the file. If no encoding is specified (using `options.encoding`), the data is returned as a {Buffer} object. Otherwise, the * @returns Fulfills upon a successful read with the contents of the
* data will be a string. * file. If no encoding is specified (using `options.encoding`), the data is
* returned as a `Buffer` object. Otherwise, the data will be a string.
*/ */
readFile( readFile<T extends NodeJS.ArrayBufferView>(
options?: options: Omit<ReadFileOptionsWithBuffer<T>, "flag">,
| ({ encoding?: null | undefined } & Abortable) ): Promise<BufferView<T>>;
| null, readFile(options?: Omit<ReadFileOptionsWithBufferEncoding, "flag"> | null): Promise<NonSharedBuffer>;
): Promise<NonSharedBuffer>; readFile(options: Omit<ReadFileOptionsWithStringEncoding, "flag"> | BufferEncoding): Promise<string>;
/** readFile(options: Omit<ReadFileOptions, "flag"> | BufferEncoding | null): Promise<string | NonSharedBuffer>;
* Asynchronously reads the entire contents of a file. The underlying file will _not_ be closed automatically.
* The `FileHandle` must have been opened for reading.
*/
readFile(
options:
| ({ encoding: BufferEncoding } & Abortable)
| BufferEncoding,
): Promise<string>;
/**
* Asynchronously reads the entire contents of a file. The underlying file will _not_ be closed automatically.
* The `FileHandle` must have been opened for reading.
*/
readFile(
options?:
| (ObjectEncodingOptions & Abortable)
| BufferEncoding
| null,
): Promise<string | NonSharedBuffer>;
/** /**
* Convenience method to create a `readline` interface and stream over the file. * Convenience method to create a `readline` interface and stream over the file.
* See `filehandle.createReadStream()` for the options. * See `filehandle.createReadStream()` for the options.
@@ -1310,50 +1335,21 @@ declare module "node:fs/promises" {
* @param path filename or `FileHandle` * @param path filename or `FileHandle`
* @return Fulfills with the contents of the file. * @return Fulfills with the contents of the file.
*/ */
function readFile<T extends NodeJS.ArrayBufferView>(
path: PathLike | FileHandle,
options: ReadFileOptionsWithBuffer<T>,
): Promise<BufferView<T>>;
function readFile( function readFile(
path: PathLike | FileHandle, path: PathLike | FileHandle,
options?: options?: ReadFileOptionsWithBufferEncoding | null,
| ({
encoding?: null | undefined;
flag?: OpenMode | undefined;
} & Abortable)
| null,
): Promise<NonSharedBuffer>; ): Promise<NonSharedBuffer>;
/**
* Asynchronously reads the entire contents of a file.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* If a `FileHandle` is provided, the underlying file will _not_ be closed automatically.
* @param options An object that may contain an optional flag.
* If a flag is not provided, it defaults to `'r'`.
*/
function readFile( function readFile(
path: PathLike | FileHandle, path: PathLike | FileHandle,
options: options: ReadFileOptionsWithStringEncoding | BufferEncoding,
| ({
encoding: BufferEncoding;
flag?: OpenMode | undefined;
} & Abortable)
| BufferEncoding,
): Promise<string>; ): Promise<string>;
/**
* Asynchronously reads the entire contents of a file.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* If a `FileHandle` is provided, the underlying file will _not_ be closed automatically.
* @param options An object that may contain an optional flag.
* If a flag is not provided, it defaults to `'r'`.
*/
function readFile( function readFile(
path: PathLike | FileHandle, path: PathLike | FileHandle,
options?: options: ReadFileOptions | BufferEncoding | null,
| (
& ObjectEncodingOptions
& Abortable
& {
flag?: OpenMode | undefined;
}
)
| BufferEncoding
| null,
): Promise<string | NonSharedBuffer>; ): Promise<string | NonSharedBuffer>;
/** /**
* Asynchronously open a directory for iterative scanning. See the POSIX [`opendir(3)`](http://man7.org/linux/man-pages/man3/opendir.3.html) documentation for more detail. * Asynchronously open a directory for iterative scanning. See the POSIX [`opendir(3)`](http://man7.org/linux/man-pages/man3/opendir.3.html) documentation for more detail.
+1 -1
View File
@@ -299,7 +299,7 @@ declare module "node:http" {
requireHostHeader?: boolean | undefined; requireHostHeader?: boolean | undefined;
/** /**
* If set to `true`, it enables keep-alive functionality on the socket immediately after a new incoming connection is received, * If set to `true`, it enables keep-alive functionality on the socket immediately after a new incoming connection is received,
* similarly on what is done in `socket.setKeepAlive([enable][, initialDelay])`. * similarly on what is done in `socket.setKeepAlive()`.
* @default false * @default false
* @since v16.5.0 * @since v16.5.0
*/ */
+2 -2
View File
@@ -433,7 +433,7 @@ declare module "node:http2" {
* *
* When the `options.waitForTrailers` option is set, the `'wantTrailers'` event * When the `options.waitForTrailers` option is set, the `'wantTrailers'` event
* will be emitted immediately after queuing the last chunk of payload data to be * will be emitted immediately after queuing the last chunk of payload data to be
* sent. The `http2stream.sendTrailers()` method can then be used to sent trailing * sent. The `http2stream.sendTrailers()` method can then be used to send trailing
* header fields to the peer. * header fields to the peer.
* *
* When `options.waitForTrailers` is set, the `Http2Stream` will not automatically * When `options.waitForTrailers` is set, the `Http2Stream` will not automatically
@@ -548,7 +548,7 @@ declare module "node:http2" {
* *
* When the `options.waitForTrailers` option is set, the `'wantTrailers'` event * When the `options.waitForTrailers` option is set, the `'wantTrailers'` event
* will be emitted immediately after queuing the last chunk of payload data to be * will be emitted immediately after queuing the last chunk of payload data to be
* sent. The `http2stream.sendTrailers()` method can then be used to sent trailing * sent. The `http2stream.sendTrailers()` method can then be used to send trailing
* header fields to the peer. * header fields to the peer.
* *
* When `options.waitForTrailers` is set, the `Http2Stream` will not automatically * When `options.waitForTrailers` is set, the `Http2Stream` will not automatically
+1
View File
@@ -108,6 +108,7 @@
/// <reference path="util.d.ts" /> /// <reference path="util.d.ts" />
/// <reference path="util/types.d.ts" /> /// <reference path="util/types.d.ts" />
/// <reference path="v8.d.ts" /> /// <reference path="v8.d.ts" />
/// <reference path="vfs.d.ts" />
/// <reference path="vm.d.ts" /> /// <reference path="vm.d.ts" />
/// <reference path="wasi.d.ts" /> /// <reference path="wasi.d.ts" />
/// <reference path="worker_threads.d.ts" /> /// <reference path="worker_threads.d.ts" />
+2 -1
View File
@@ -43,7 +43,8 @@ declare module "node:inspector" {
*/ */
function open(port?: number, host?: string, wait?: boolean): Disposable; function open(port?: number, host?: string, wait?: boolean): Disposable;
/** /**
* Deactivate the inspector. Blocks until there are no active connections. * Deactivates the inspector. If there are active connections, they are forcibly
* terminated. Blocks until the inspector server has fully stopped.
*/ */
function close(): void; function close(): void;
/** /**
+109 -17
View File
@@ -25,6 +25,7 @@ declare module "node:net" {
keepAliveInitialDelay?: number | undefined; keepAliveInitialDelay?: number | undefined;
blockList?: BlockList | undefined; blockList?: BlockList | undefined;
typeOfService?: number | undefined; typeOfService?: number | undefined;
handle?: BoundSocket | undefined;
} }
interface OnReadOpts { interface OnReadOpts {
buffer: Uint8Array | (() => Uint8Array); buffer: Uint8Array | (() => Uint8Array);
@@ -57,6 +58,12 @@ declare module "node:net" {
} }
type SocketConnectOpts = TcpSocketConnectOpts | IpcSocketConnectOpts; type SocketConnectOpts = TcpSocketConnectOpts | IpcSocketConnectOpts;
type SocketReadyState = "opening" | "open" | "readOnly" | "writeOnly" | "closed"; type SocketReadyState = "opening" | "open" | "readOnly" | "writeOnly" | "closed";
interface SetKeepAliveOptions {
enable?: boolean | undefined;
initialDelay?: number | undefined;
interval?: number | undefined;
count?: number | undefined;
}
interface SocketEventMap extends Omit<stream.DuplexEventMap, "close"> { interface SocketEventMap extends Omit<stream.DuplexEventMap, "close"> {
"close": [hadError: boolean]; "close": [hadError: boolean];
"connect": []; "connect": [];
@@ -199,25 +206,27 @@ declare module "node:net" {
*/ */
setNoDelay(noDelay?: boolean): this; setNoDelay(noDelay?: boolean): this;
/** /**
* Enable/disable keep-alive functionality, and optionally set the initial * Configure keep-alive using an options object. See `socket.setKeepAlive()`
* delay before the first keepalive probe is sent on an idle socket. * for a description of each property.
* *
* Set `initialDelay` (in milliseconds) to set the delay between the last * ```js
* data packet received and the first keepalive probe. Setting `0` for`initialDelay` will leave the value unchanged from the default * socket.setKeepAlive({ enable: true, initialDelay: 1000, interval: 1000, count: 10 });
* (or previous) setting. * ```
* * @since v26.4.0
* Enabling the keep-alive functionality will set the following socket options: * @returns The socket itself.
*
* * `SO_KEEPALIVE=1`
* * `TCP_KEEPIDLE=initialDelay`
* * `TCP_KEEPCNT=10`
* * `TCP_KEEPINTVL=1`
* @since v0.1.92
* @param [enable=false]
* @param [initialDelay=0]
* @return The socket itself.
*/ */
setKeepAlive(enable?: boolean, initialDelay?: number): this; setKeepAlive(options: SetKeepAliveOptions): this;
/**
* Configure keep-alive using positional arguments. See
* `socket.setKeepAlive()` for a description of each argument.
* @since v0.1.92
* @param enable **Default:** `false`
* @param initialDelay **Default:** `0`
* @param interval **Default:** `1000`
* @param count **Default:** `10`
* @returns The socket itself.
*/
setKeepAlive(enable?: boolean, initialDelay?: number, interval?: number, count?: number): this;
/** /**
* Returns the current Type of Service (TOS) field for IPv4 packets or Traffic * Returns the current Type of Service (TOS) field for IPv4 packets or Traffic
* Class for IPv6 packets for this socket. * Class for IPv6 packets for this socket.
@@ -442,9 +451,92 @@ declare module "node:net" {
removeListener(eventName: string | symbol, listener: (...args: any[]) => void): this; removeListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
// #endregion // #endregion
} }
interface BoundSocketOptions {
/**
* Local address to bind. Must be a numeric IP literal; no DNS
* resolution is performed. **Default:** `'0.0.0.0'`, or `'::'` when
* `ipv6Only` is `true`.
*/
host?: string | undefined;
/**
* Local port. `0` requests an OS-assigned ephemeral port.
* **Default:** `0`.
*/
port?: number | undefined;
/**
* Sets `IPV6_V6ONLY`, disabling dual-stack support so the
* socket binds IPv6 only. Only meaningful for IPv6 binds. **Default:**
* `false`.
*/
ipv6Only?: boolean | undefined;
/**
* Sets `SO_REUSEPORT`, allowing multiple sockets to bind
* the same address and port for kernel-level load balancing. Support is
* platform-dependent. **Default:** `false`.
*/
reusePort?: boolean | undefined;
}
/**
* Allows for the synchronous creation of a pre-bound socket, that can be passed
* to `listen()` or `new net.Socket()` later on. For `listen()` this enables
* synchronous port reservation, while for `new net.Socket()`, it allows control
* over the local egress port/IP, via `bind(2)` semantics.
*
* Adoption transfers ownership of the socket; afterwards `address()` and `close()`
* throw `ERR_SOCKET_HANDLE_ADOPTED`. A handle that is never adopted must be
* closed to avoid leaking the socket.
*
* ```js
* import net from 'node:net';
*
* const bound = new net.BoundSocket();
* const { port } = bound.address();
* console.log(`Reserved port ${port} for server`);
*
* const server = net.createServer();
* server.listen(bound); // Adopt as a server, or pass to new net.Socket() instead.
* ```
* @since v26.4.0
*/
class BoundSocket {
/**
* @since v26.4.0
*/
constructor(options?: BoundSocketOptions);
/**
* Returns the bound local address. When bound with `port: 0`, `port` is the
* OS-assigned ephemeral port.
* @since v26.4.0
* @returns An object with `address`, `family`, and `port` properties,
* as `server.address()` returns.
*/
address(): AddressInfo;
/**
* Returns the file descriptor of the bound socket. Ownership remains with the
* `BoundSocket`, so the descriptor must not be closed by the caller. The
* descriptor is only available before the handle is adopted; afterwards it belongs
* to the adopting `net.Server` or `net.Socket` and `fd()` throws
* `ERR_SOCKET_HANDLE_ADOPTED`.
* @since v26.4.0
* @returns The underlying OS file descriptor, or `-1` on platforms
* that do not expose one for sockets (such as Windows).
*/
fd(): number;
/**
* Releases the bound socket. Only needed when the handle is never adopted.
* @since v26.4.0
*/
close(): void;
/**
* Closes the handle if it has not been adopted or closed; otherwise a no-op.
* @since v26.4.0
*/
[Symbol.dispose](): void;
}
interface ListenOptions extends Abortable { interface ListenOptions extends Abortable {
backlog?: number | undefined; backlog?: number | undefined;
exclusive?: boolean | undefined; exclusive?: boolean | undefined;
handle?: BoundSocket | undefined;
host?: string | undefined; host?: string | undefined;
/** /**
* @default false * @default false
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@types/node", "name": "@types/node",
"version": "26.3.0", "version": "26.4.0",
"description": "TypeScript definitions for node", "description": "TypeScript definitions for node",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node", "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node",
"license": "MIT", "license": "MIT",
@@ -150,6 +150,6 @@
"undici-types": "~8.3.0" "undici-types": "~8.3.0"
}, },
"peerDependencies": {}, "peerDependencies": {},
"typesPublisherContentHash": "125032099e1f7132c95bf327b36f694c396de965952f7cb9632ac916bbad47e9", "typesPublisherContentHash": "0793b8d36264e159c56982e4bc1d7024a8a703b13431ee414c7feacfe570e674",
"typeScriptVersion": "5.6" "typeScriptVersion": "5.6"
} }
+37 -11
View File
@@ -1,10 +1,10 @@
declare module "node:quic" { declare module "node:quic" {
import { NonSharedBuffer } from "node:buffer"; import { NonSharedBuffer } from "node:buffer";
import { KeyObject } from "node:crypto"; import { KeyObject, X509Certificate } from "node:crypto";
import { FileHandle } from "node:fs/promises"; import { FileHandle } from "node:fs/promises";
import { BlockList, SocketAddress } from "node:net"; import { BlockList, SocketAddress } from "node:net";
import { Writer } from "node:stream/iter"; import { Writer } from "node:stream/iter";
import { EphemeralKeyInfo, PeerCertificate } from "node:tls"; import { EphemeralKeyInfo } from "node:tls";
/** /**
* @since v23.8.0 * @since v23.8.0
*/ */
@@ -25,6 +25,10 @@ declare module "node:quic" {
id: bigint, id: bigint,
status: "acknowledged" | "lost" | "abandoned", status: "acknowledged" | "lost" | "abandoned",
) => void; ) => void;
/**
* @since v23.8.0
*/
type OnApplicationCallback = (this: QuicSession, applicationoptions: SessionApplicationOptions) => void;
/** /**
* @since v23.8.0 * @since v23.8.0
*/ */
@@ -235,6 +239,7 @@ declare module "node:quic" {
*/ */
enableDatagrams?: boolean | undefined; enableDatagrams?: boolean | undefined;
} }
type SessionApplicationOptions = { [K in keyof ApplicationOptions]-?: ApplicationOptions[K] & (bigint | boolean) };
/** /**
* @since v23.8.0 * @since v23.8.0
*/ */
@@ -539,6 +544,7 @@ declare module "node:quic" {
ongoaway?: QuicSession["ongoaway"] | undefined; ongoaway?: QuicSession["ongoaway"] | undefined;
onkeylog?: QuicSession["onkeylog"] | undefined; onkeylog?: QuicSession["onkeylog"] | undefined;
onqlog?: QuicSession["onqlog"] | undefined; onqlog?: QuicSession["onqlog"] | undefined;
onapplication?: QuicSession["onapplication"] | undefined;
onheaders?: QuicStream["onheaders"] | undefined; onheaders?: QuicStream["onheaders"] | undefined;
ontrailers?: QuicStream["ontrailers"] | undefined; ontrailers?: QuicStream["ontrailers"] | undefined;
oninfo?: QuicStream["oninfo"] | undefined; oninfo?: QuicStream["oninfo"] | undefined;
@@ -608,6 +614,20 @@ declare module "node:quic" {
* @since v23.8.0 * @since v23.8.0
*/ */
function listen(onsession: OnSessionCallback, options?: SessionOptions): Promise<QuicEndpoint>; function listen(onsession: OnSessionCallback, options?: SessionOptions): Promise<QuicEndpoint>;
interface ListEndpointsOptions {
/**
* If `true` (the default), only returns endpoints that are
* active (not destroyed, not closing, and not busy). If `false` returns all
* endpoints.
*/
active?: boolean | undefined;
}
/**
* Returns the list of all `QuicEndpoint` instances. By default, only active
* endpoints are returned.
* @since v26.4.0
*/
function listEndpoints(options?: ListEndpointsOptions): QuicEndpoint[];
/** /**
* The endpoint configuration options passed when constructing a new `QuicEndpoint` instance. * The endpoint configuration options passed when constructing a new `QuicEndpoint` instance.
* @since v23.8.0 * @since v23.8.0
@@ -1172,7 +1192,7 @@ declare module "node:quic" {
* be negotiated separately from the transport parameters. Read only. * be negotiated separately from the transport parameters. Read only.
* @since v26.3.0 * @since v26.3.0
*/ */
readonly applicationOptions: { [K in keyof ApplicationOptions]-?: ApplicationOptions[K] & (bigint | boolean) }; readonly applicationOptions: SessionApplicationOptions;
/** /**
* Initiate a graceful close of the session. Existing streams will be allowed * Initiate a graceful close of the session. Existing streams will be allowed
* to complete but no new streams will be opened. Once all streams have closed, * to complete but no new streams will be opened. Once all streams have closed,
@@ -1226,6 +1246,11 @@ declare module "node:quic" {
* @since v23.8.0 * @since v23.8.0
*/ */
readonly endpoint: QuicEndpoint | null; readonly endpoint: QuicEndpoint | null;
/**
* The callback to invoke when new application options, e.g. HTTP/3 settings arrived.
* @since v26.4
*/
onapplication: OnApplicationCallback | undefined;
/** /**
* An optional callback invoked when the session is destroyed with an error. * An optional callback invoked when the session is destroyed with an error.
* This includes errors caused by user callbacks that throw or reject (see * This includes errors caused by user callbacks that throw or reject (see
@@ -1412,19 +1437,20 @@ declare module "node:quic" {
encoding?: BufferEncoding, encoding?: BufferEncoding,
): Promise<bigint>; ): Promise<bigint>;
/** /**
* The local certificate as an object with properties such as `subject`, * The local certificate as a `crypto.X509Certificate` instance. Server
* `issuer`, `valid_from`, `valid_to`, `fingerprint`, etc. Returns `undefined` * sessions return the certificate configured for the negotiated SNI host.
* if the session is destroyed or no certificate is available. * Client sessions return `undefined` unless a client certificate was sent.
* Returns `undefined` if the session is destroyed.
* @since v26.2.0 * @since v26.2.0
*/ */
readonly certificate: PeerCertificate | undefined; readonly certificate: X509Certificate | undefined;
/** /**
* The peer's certificate as an object with properties such as `subject`, * The peer's certificate as a `crypto.X509Certificate` instance. Returns
* `issuer`, `valid_from`, `valid_to`, `fingerprint`, etc. Returns `undefined` * `undefined` if the peer did not present a certificate or the session is
* if the session is destroyed or the peer did not present a certificate. * destroyed.
* @since v26.2.0 * @since v26.2.0
*/ */
readonly peerCertificate: PeerCertificate | undefined; readonly peerCertificate: X509Certificate | undefined;
/** /**
* The ephemeral key information for the session, with properties such as * The ephemeral key information for the session, with properties such as
* `type`, `name`, and `size`. Only available on client sessions. Returns * `type`, `name`, and `size`. Only available on client sessions. Returns
+4 -4
View File
@@ -271,8 +271,8 @@ declare module "node:stream/iter" {
* *
* If the object implements the `toAsyncStreamable` protocol (as * If the object implements the `toAsyncStreamable` protocol (as
* `stream.Readable` does), that protocol is used. Otherwise, the function * `stream.Readable` does), that protocol is used. Otherwise, the function
* duck-types on `read()` and `on()` (EventEmitter) and wraps the stream with * duck-types on `read()`, `on()`, and `off()` (EventEmitter) and wraps the
* a batched async iterator. * stream with a batched async iterator.
* *
* The result is cached per instance -- calling `fromReadable()` twice with the * The result is cached per instance -- calling `fromReadable()` twice with the
* same stream returns the same iterable. * same stream returns the same iterable.
@@ -294,7 +294,7 @@ declare module "node:stream/iter" {
* @since v26.1.0 * @since v26.1.0
* @experimental * @experimental
* @param readable A classic Readable stream or any object * @param readable A classic Readable stream or any object
* with `read()` and `on()` methods. * with `read()`, `on()` and `off()` methods.
* @returns A stream/iter async iterable source. * @returns A stream/iter async iterable source.
*/ */
function fromReadable(readable: NodeJS.ReadableStream): ByteReadableStream; function fromReadable(readable: NodeJS.ReadableStream): ByteReadableStream;
@@ -389,7 +389,7 @@ declare module "node:stream/iter" {
* *
* Each `_write()` / `_writev()` call attempts the Writer's synchronous method * Each `_write()` / `_writev()` call attempts the Writer's synchronous method
* first (`writeSync` / `writevSync`), falling back to the async method if the * first (`writeSync` / `writevSync`), falling back to the async method if the
* sync path returns `false` or throws. Similarly, `_final()` tries `endSync()` * sync path returns `false`. Similarly, `_final()` tries `endSync()`
* before `end()`. When the sync path succeeds, the callback is deferred via * before `end()`. When the sync path succeeds, the callback is deferred via
* `queueMicrotask` to preserve the async resolution contract. * `queueMicrotask` to preserve the async resolution contract.
* *
+24
View File
@@ -746,6 +746,7 @@ declare module "node:tls" {
// #endregion // #endregion
} }
type SecureVersion = "TLSv1.3" | "TLSv1.2" | "TLSv1.1" | "TLSv1"; type SecureVersion = "TLSv1.3" | "TLSv1.2" | "TLSv1.1" | "TLSv1";
type CertificateCompressionAlgorithm = "zlib" | "brotli" | "zstd";
interface SecureContextOptions { interface SecureContextOptions {
/** /**
* If set, this will be called when a client opens a connection using the ALPN extension. * If set, this will be called when a client opens a connection using the ALPN extension.
@@ -782,6 +783,15 @@ declare module "node:tls" {
* able to validate the certificate, and the handshake will fail. * able to validate the certificate, and the handshake will fail.
*/ */
cert?: string | Buffer | Array<string | Buffer> | undefined; cert?: string | Buffer | Array<string | Buffer> | undefined;
/**
* An array of supported certificate
* compression algorithm names, in preference order. Supported values are
* `'zlib'`, `'brotli'`, and `'zstd'`. When set, enables TLS certificate
* compression ([RFC 8879](https://tools.ietf.org/html/rfc8879)) which compresses certificates during the TLS
* handshake, reducing handshake size. Only effective with TLSv1.3.
* **Default:** `[]` (disabled).
*/
certificateCompression?: readonly CertificateCompressionAlgorithm[] | undefined;
/** /**
* Colon-separated list of supported signature algorithms. The list * Colon-separated list of supported signature algorithms. The list
* can contain digest algorithms (SHA256, MD5 etc.), public key * can contain digest algorithms (SHA256, MD5 etc.), public key
@@ -1110,6 +1120,20 @@ declare module "node:tls" {
* @since v0.10.2 * @since v0.10.2
*/ */
function getCiphers(): string[]; function getCiphers(): string[];
/**
* Returns an array with the names of the RFC 8879 certificate compression
* algorithms supported by the current OpenSSL build, suitable for use in the
* `certificateCompression` option of `tls.createSecureContext()`. Possible
* values include `'zlib'`, `'brotli'`, and `'zstd'`.
*
* The array is empty when certificate compression is unavailable.
*
* ```js
* console.log(tls.getCertificateCompressionAlgorithms()); // ['zlib', 'brotli', 'zstd']
* ```
* @since v26.4.0
*/
function getCertificateCompressionAlgorithms(): CertificateCompressionAlgorithm[];
/** /**
* Sets the default CA certificates used by Node.js TLS clients. If the provided * Sets the default CA certificates used by Node.js TLS clients. If the provided
* certificates are parsed successfully, they will become the default CA * certificates are parsed successfully, they will become the default CA
+5
View File
@@ -459,4 +459,9 @@ declare module "node:buffer" {
*/ */
type AllowSharedBuffer = Buffer; type AllowSharedBuffer = Buffer;
} }
/**
* @deprecated This is intended for internal use, and will be removed once `@types/node` no longer supports
* TypeScript versions earlier than 5.7.
*/
type BufferView<T extends NodeJS.ArrayBufferView> = Buffer;
} }
+1
View File
@@ -110,6 +110,7 @@
/// <reference path="../util.d.ts" /> /// <reference path="../util.d.ts" />
/// <reference path="../util/types.d.ts" /> /// <reference path="../util/types.d.ts" />
/// <reference path="../v8.d.ts" /> /// <reference path="../v8.d.ts" />
/// <reference path="../vfs.d.ts" />
/// <reference path="../vm.d.ts" /> /// <reference path="../vm.d.ts" />
/// <reference path="../wasi.d.ts" /> /// <reference path="../wasi.d.ts" />
/// <reference path="../worker_threads.d.ts" /> /// <reference path="../worker_threads.d.ts" />
+1
View File
@@ -110,6 +110,7 @@
/// <reference path="../util.d.ts" /> /// <reference path="../util.d.ts" />
/// <reference path="../util/types.d.ts" /> /// <reference path="../util/types.d.ts" />
/// <reference path="../v8.d.ts" /> /// <reference path="../v8.d.ts" />
/// <reference path="../vfs.d.ts" />
/// <reference path="../vm.d.ts" /> /// <reference path="../vm.d.ts" />
/// <reference path="../wasi.d.ts" /> /// <reference path="../wasi.d.ts" />
/// <reference path="../worker_threads.d.ts" /> /// <reference path="../worker_threads.d.ts" />
+4 -3
View File
@@ -28,10 +28,11 @@ declare module "node:tty" {
* Allows configuration of `tty.ReadStream` so that it operates as a raw device. * Allows configuration of `tty.ReadStream` so that it operates as a raw device.
* *
* When in raw mode, input is always available character-by-character, not * When in raw mode, input is always available character-by-character, not
* including modifiers. Additionally, all special processing of characters by the * including modifiers. Additionally, all special processing of input characters
* terminal is disabled, including echoing input * by the terminal is disabled, including echoing input
* characters. Ctrl+C will no longer cause a `SIGINT` when * characters. Ctrl+C will no longer cause a `SIGINT` when
* in this mode. * in this mode. This mode does not affect terminal output processing, such as
* newline translation on Unix terminals.
* @since v0.7.7 * @since v0.7.7
* @param mode If `true`, configures the `tty.ReadStream` to operate as a raw device. If `false`, configures the `tty.ReadStream` to operate in its default mode. The `readStream.isRaw` * @param mode If `true`, configures the `tty.ReadStream` to operate as a raw device. If `false`, configures the `tty.ReadStream` to operate in its default mode. The `readStream.isRaw`
* property will be set to the resulting mode. * property will be set to the resulting mode.
+210
View File
@@ -0,0 +1,210 @@
declare module "node:vfs" {
/**
* Convenience factory equivalent to `new VirtualFileSystem(provider, options)`.
*
* ```js
* const vfs = require('node:vfs');
*
* // Default in-memory provider
* const memoryVfs = vfs.create();
*
* // Explicit provider
* const realVfs = vfs.create(new vfs.RealFSProvider('/tmp/sandbox'));
* ```
* @since v26.4.0
* @param provider The provider to use. **Default:** `new MemoryProvider()`.
*/
function create(provider?: VirtualProvider, options?: VirtualFileSystemOptions): VirtualFileSystem;
function create(options: VirtualFileSystemOptions): VirtualFileSystem;
interface VirtualFileSystemOptions {
/**
* Whether to emit the experimental warning. **Default:** `true`.
*/
emitExperimentalWarning?: boolean | undefined;
}
/**
* A `VirtualFileSystem` wraps a {@link VirtualProvider} and exposes a
* `node:fs`-like API. Each instance maintains its own file tree.
* @since v26.4.0
*/
class VirtualFileSystem {
/**
* @param provider The provider to use. **Default:** `new MemoryProvider()`.
*/
constructor(provider?: VirtualProvider, options?: VirtualFileSystemOptions);
constructor(options: VirtualFileSystemOptions);
/**
* The provider backing this VFS instance.
* @since v26.4.0
*/
readonly provider: VirtualProvider;
/**
* `true` when the underlying provider is read-only.
* @since v26.4.0
*/
readonly readonly: boolean;
}
interface VirtualFileSystem extends
// Synchronous API
Pick<
typeof import("node:fs"),
| "existsSync"
| "statSync"
| "lstatSync"
| "readFileSync"
| "writeFileSync"
| "appendFileSync"
| "readdirSync"
| "mkdirSync"
| "rmdirSync"
| "unlinkSync"
| "renameSync"
| "copyFileSync"
| "realpathSync"
| "readlinkSync"
| "symlinkSync"
| "accessSync"
| "rmSync"
| "truncateSync"
| "ftruncateSync"
| "linkSync"
| "chmodSync"
| "chownSync"
| "utimesSync"
| "lutimesSync"
| "mkdtempSync"
| "opendirSync"
| "openAsBlob"
| "openSync"
| "closeSync"
| "readSync"
| "writeSync"
| "fstatSync"
| "createReadStream"
| "createWriteStream"
| "watch"
| "watchFile"
| "unwatchFile"
>,
// Callback API
Pick<
typeof import("node:fs"),
| "readFile"
| "writeFile"
| "stat"
| "lstat"
| "readdir"
| "realpath"
| "readlink"
| "access"
| "open"
| "close"
| "read"
| "write"
| "rm"
| "fstat"
| "truncate"
| "ftruncate"
| "link"
| "mkdtemp"
| "opendir"
>
{
// Promise API
readonly promises: Pick<
typeof import("node:fs/promises"),
| "readFile"
| "writeFile"
| "appendFile"
| "stat"
| "lstat"
| "readdir"
| "mkdir"
| "rmdir"
| "unlink"
| "rename"
| "copyFile"
| "realpath"
| "readlink"
| "symlink"
| "access"
| "rm"
| "truncate"
| "link"
| "mkdtemp"
| "chmod"
| "chown"
| "lchown"
| "utimes"
| "lutimes"
| "open"
| "lchmod"
| "watch"
>;
}
/**
* The base class for all VFS providers. Subclasses implement the essential
* primitives (such as `open`, `stat`, `readdir`, `mkdir`, `rmdir`, `unlink`,
* `rename`, etc.) and inherit default implementations of the derived
* methods (such as `readFile`, `writeFile`, `exists`, `copyFile`, `access`, etc.).
* @since v26.4.0
*/
abstract class VirtualProvider {
get readonly(): boolean;
get supportsSymlinks(): boolean;
get supportsWatch(): boolean;
}
/**
* The default in-memory provider. Stores files, directories, and symbolic
* links in a `Map`-backed tree, supports symlinks (`supportsSymlinks ===
* true`), and supports watching (`supportsWatch === true`).
* @since v26.4.0
*/
class MemoryProvider extends VirtualProvider {
/**
* Locks the provider into read-only mode. Subsequent writes through any
* `VirtualFileSystem` using this provider throw `EROFS`. There is no
* way to revert the provider to writable.
*
* ```js
* const vfs = require('node:vfs');
*
* const provider = new vfs.MemoryProvider();
* const myVfs = vfs.create(provider);
* myVfs.writeFileSync('/seed.txt', 'initial');
*
* provider.setReadOnly();
*
* myVfs.writeFileSync('/x.txt', 'fail'); // throws EROFS
* ```
* @since v26.4.0
*/
setReadOnly(): void;
}
/**
* A provider that wraps a directory (i.e. one on the actual file system) and exposes its
* contents through the VFS API. All VFS paths are resolved relative to
* the root and verified to stay inside it; symbolic links resolving
* outside the root are rejected.
* @since v26.4.0
*/
class RealFSProvider extends VirtualProvider {
/**
* ```js
* const vfs = require('node:vfs');
*
* const realVfs = vfs.create(new vfs.RealFSProvider('/tmp/sandbox'));
* realVfs.writeFileSync('/file.txt', 'hello'); // writes /tmp/sandbox/file.txt
* ```
* @since v26.4.0
* @param rootPath The absolute file-system path to use as the root.
* Must be a non-empty string.
*/
constructor(rootPath: string);
/**
* The resolved absolute path used as the root.
* @since v26.4.0
*/
readonly rootPath: string;
}
}
+1 -1
View File
@@ -741,7 +741,7 @@ declare module "node:vm" {
*/ */
status: ModuleStatus; status: ModuleStatus;
/** /**
* Evaluate the module and its depenendencies. Corresponds to the [Evaluate() concrete method](https://tc39.es/ecma262/#sec-moduleevaluation) field of * Evaluate the module and its dependencies. Corresponds to the [Evaluate() concrete method](https://tc39.es/ecma262/#sec-moduleevaluation) field of
* [Cyclic Module Record](https://tc39.es/ecma262/#sec-cyclic-module-records)s in the ECMAScript specification. * [Cyclic Module Record](https://tc39.es/ecma262/#sec-cyclic-module-records)s in the ECMAScript specification.
* *
* If the module is a `vm.SourceTextModule`, `evaluate()` must be called after the module has been instantiated; * If the module is a `vm.SourceTextModule`, `evaluate()` must be called after the module has been instantiated;
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../api
+8 -8
View File
@@ -1,6 +1,6 @@
{ {
"name": "dbmate", "name": "dbmate",
"version": "2.35.0", "version": "2.35.1",
"description": "A lightweight, framework-agnostic database migration tool", "description": "A lightweight, framework-agnostic database migration tool",
"repository": { "repository": {
"type": "git", "type": "git",
@@ -30,12 +30,12 @@
"build": "tsc --build" "build": "tsc --build"
}, },
"optionalDependencies": { "optionalDependencies": {
"@dbmate/linux-ia32": "2.35.0", "@dbmate/linux-ia32": "2.35.1",
"@dbmate/linux-x64": "2.35.0", "@dbmate/linux-x64": "2.35.1",
"@dbmate/linux-arm": "2.35.0", "@dbmate/linux-arm": "2.35.1",
"@dbmate/linux-arm64": "2.35.0", "@dbmate/linux-arm64": "2.35.1",
"@dbmate/darwin-x64": "2.35.0", "@dbmate/darwin-x64": "2.35.1",
"@dbmate/darwin-arm64": "2.35.0", "@dbmate/darwin-arm64": "2.35.1",
"@dbmate/win32-x64": "2.35.0" "@dbmate/win32-x64": "2.35.1"
} }
} }
BIN
View File
Binary file not shown.
+40 -1
View File
@@ -7,7 +7,7 @@
HTTP request logger middleware for node.js HTTP request logger middleware for node.js
> Named after [Dexter](http://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion. > Named after [Dexter](https://en.wikipedia.org/wiki/Dexter_Morgan), a show you should not watch until completion.
## Installation ## Installation
@@ -21,6 +21,16 @@ $ npm install morgan
## API ## API
For ES Modules:
<!-- eslint-disable no-unused-vars -->
```js
import morgan from 'morgan'
```
For CommonJS:
<!-- eslint-disable no-unused-vars --> <!-- eslint-disable no-unused-vars -->
```js ```js
@@ -98,6 +108,30 @@ morgan('combined', {
Output stream for writing log lines, defaults to `process.stdout`. Output stream for writing log lines, defaults to `process.stdout`.
If the stream is in object mode (`stream.writableObjectMode` is `true`) and the
format function returns an object, the object is written to the stream as-is,
without a trailing newline. This allows passing structured log entries to
loggers that accept objects:
<!-- eslint-disable no-undef -->
```js
morgan(function (tokens, req, res) {
return {
method: tokens.method(req, res),
url: tokens.url(req, res),
status: Number(tokens.status(req, res))
}
}, {
stream: {
writableObjectMode: true,
write: function (entry) {
// entry is the object returned by the format function
}
}
})
```
#### Predefined Formats #### Predefined Formats
There are various pre-defined formats provided: There are various pre-defined formats provided:
@@ -134,6 +168,11 @@ for information codes.
GET /dev 200 0.224 ms - 2 GET /dev 200 0.224 ms - 2
``` ```
Coloring is disabled when the [`NO_COLOR`](https://no-color.org) environment
variable is set to any non-empty value, in which case the output above is
written without any escape sequences. The variable is read once, when `morgan`
is first required.
##### short ##### short
Shorter than default, also including response time. Shorter than default, also including response time.
+21 -4
View File
@@ -47,6 +47,8 @@ var CLF_MONTH = [
var DEFAULT_BUFFER_DURATION = 1000 var DEFAULT_BUFFER_DURATION = 1000
var NO_COLOR = Boolean(process.env.NO_COLOR)
/** /**
* Escape control characters and backslashes so a value is safe for * Escape control characters and backslashes so a value is safe for
* line-oriented logs. * line-oriented logs.
@@ -59,7 +61,7 @@ function escapeLogField (value) {
if (value == null) return undefined if (value == null) return undefined
// eslint-disable-next-line no-control-regex // eslint-disable-next-line no-control-regex
return String(value).replace(/[\u0000-\u001f\u007f\\]/g, function (ch) { return String(value).replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029\\]/g, function (ch) {
switch (ch) { switch (ch) {
case '\\': return '\\\\' case '\\': return '\\\\'
case '\b': return '\\b' case '\b': return '\\b'
@@ -153,7 +155,11 @@ function morgan (format, options) {
} }
debug('log request') debug('log request')
if (stream.writableObjectMode && typeof line === 'object') {
stream.write(line)
} else {
stream.write(line + '\n') stream.write(line + '\n')
}
}; };
if (immediate) { if (immediate) {
@@ -231,6 +237,12 @@ morgan.format('dev', function developmentFormatLine (tokens, req, res) {
return fn(tokens, req, res) return fn(tokens, req, res)
}) })
// NO_COLOR (https://no-color.org): when set and not an empty string, the dev
// format is replaced at load time with a variant free of escape sequences
if (NO_COLOR) {
morgan.format('dev', compile(':method :url :status :response-time ms - :res[content-length]'))
}
/** /**
* request url * request url
*/ */
@@ -334,9 +346,9 @@ morgan.token('remote-user', function getRemoteUserToken (req) {
// parse basic credentials // parse basic credentials
var credentials = auth(req) var credentials = auth(req)
// return username // return username (escaping is applied by the token() wrapper)
return credentials return credentials
? escapeLogField(credentials.name) ? credentials.name
: undefined : undefined
}) })
@@ -573,6 +585,11 @@ function recordStartTime () {
*/ */
function token (name, fn) { function token (name, fn) {
morgan[name] = fn // wrap the token so its string output is always escaped for line-oriented
// logs, regardless of whether the format is a string or a function
morgan[name] = function tokenValue () {
var value = fn.apply(this, arguments)
return typeof value === 'string' ? escapeLogField(value) : value
}
return this return this
} }
+6 -6
View File
@@ -1,7 +1,7 @@
{ {
"name": "morgan", "name": "morgan",
"description": "HTTP request logger middleware for node.js", "description": "HTTP request logger middleware for node.js",
"version": "1.11.0", "version": "1.12.0",
"contributors": [ "contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>", "Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)" "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
@@ -28,12 +28,12 @@
"devDependencies": { "devDependencies": {
"eslint": "6.8.0", "eslint": "6.8.0",
"eslint-config-standard": "14.1.1", "eslint-config-standard": "14.1.1",
"eslint-plugin-import": "2.20.2", "eslint-plugin-import": "2.32.0",
"eslint-plugin-markdown": "1.0.2", "eslint-plugin-markdown": "1.0.2",
"eslint-plugin-node": "11.1.0", "eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "4.2.1", "eslint-plugin-promise": "4.3.1",
"eslint-plugin-standard": "4.0.1", "eslint-plugin-standard": "4.1.0",
"mocha": "10.4.0", "mocha": "10.8.2",
"nyc": "15.1.0", "nyc": "15.1.0",
"split": "1.0.1", "split": "1.0.1",
"supertest": "4.0.2" "supertest": "4.0.2"
@@ -48,7 +48,7 @@
}, },
"scripts": { "scripts": {
"lint": "eslint --plugin markdown --ext js,md .", "lint": "eslint --plugin markdown --ext js,md .",
"test": "mocha --check-leaks --reporter spec", "test": "mocha --check-leaks --reporter spec test/morgan.js && mocha --check-leaks --reporter spec test/noColor.js",
"test-ci": "nyc --reporter=lcov --reporter=text npm test", "test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test" "test-cov": "nyc --reporter=html --reporter=text npm test"
} }
+49 -39
View File
@@ -1,10 +1,16 @@
{ {
"name": "book-test", "name": "book-test-workspace",
"version": "1.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "book-test-workspace",
"workspaces": [
"api",
"web"
]
},
"api": {
"name": "book-test", "name": "book-test",
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
@@ -28,9 +34,9 @@
} }
}, },
"node_modules/@dbmate/darwin-arm64": { "node_modules/@dbmate/darwin-arm64": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/@dbmate/darwin-arm64/-/darwin-arm64-2.35.0.tgz", "resolved": "https://registry.npmjs.org/@dbmate/darwin-arm64/-/darwin-arm64-2.35.1.tgz",
"integrity": "sha512-0a6TsWVGTy62X46PpsDYp7hgh9Sdd8Yox8TvPWUSj82Ol5F+7fHaOrDvajSx9KYu1fFOAdacXRDQ+0hd7QA1qA==", "integrity": "sha512-M63uycMI/sBHdjlf9NOn3YO2rKz4m3gLo/1kJ2QceODO724nZ4hJbsyfVHTpKpuHd6lct4+Vnhuqfz7lS9dKhg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -42,9 +48,9 @@
] ]
}, },
"node_modules/@dbmate/darwin-x64": { "node_modules/@dbmate/darwin-x64": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/@dbmate/darwin-x64/-/darwin-x64-2.35.0.tgz", "resolved": "https://registry.npmjs.org/@dbmate/darwin-x64/-/darwin-x64-2.35.1.tgz",
"integrity": "sha512-oN8Z7hh8ShNowo2JRCMK2QTaOZpyZCA7X0Pe0ZLt2cS1W+AJ3lDC7bx2/KxSvHdyo4xZQP8LxoGPZj/YT3RwhQ==", "integrity": "sha512-03QeOqT/RZZhX+v1B2+pkd6HPhSeAjz43LOm7ljylKP/D+/VKbg1QkxAcehsO20i3s7hIxH9+I/WmPyffRwMxw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -56,9 +62,9 @@
] ]
}, },
"node_modules/@dbmate/linux-arm": { "node_modules/@dbmate/linux-arm": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/@dbmate/linux-arm/-/linux-arm-2.35.0.tgz", "resolved": "https://registry.npmjs.org/@dbmate/linux-arm/-/linux-arm-2.35.1.tgz",
"integrity": "sha512-MxcaSAoXoQKowN/VxktEayLwTimiYTw0dStbYssleYhleKHsmqTzkfIvh8oR6BOWB4l9F3Og+0wuxLqlqhQ06w==", "integrity": "sha512-LOhSMHzTKcy5KbsFYsQnY36B6GLS6xH8BiBSaI84vTkwmbezggDIzGbZ4Eq+FCD9eMS7lLfmpmoOZoLrwbb3IQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -70,9 +76,9 @@
] ]
}, },
"node_modules/@dbmate/linux-arm64": { "node_modules/@dbmate/linux-arm64": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/@dbmate/linux-arm64/-/linux-arm64-2.35.0.tgz", "resolved": "https://registry.npmjs.org/@dbmate/linux-arm64/-/linux-arm64-2.35.1.tgz",
"integrity": "sha512-B6NKjr2Dqiv78lCutyaWvhXXjxJUsFUENiIoOofFa+RpUyOEAWRYbdcIvHhK3Wyi1pA8TJ4tceQa3bSUXfC/bw==", "integrity": "sha512-GqK2KVT2jbSe5vM16oHMpi0v6nvDwgeoM6M8k1XFV/RB1rfuG/33BMzTbgIsV91jLjed0PMeiQVvgWr41Se9Jg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -84,9 +90,9 @@
] ]
}, },
"node_modules/@dbmate/linux-ia32": { "node_modules/@dbmate/linux-ia32": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/@dbmate/linux-ia32/-/linux-ia32-2.35.0.tgz", "resolved": "https://registry.npmjs.org/@dbmate/linux-ia32/-/linux-ia32-2.35.1.tgz",
"integrity": "sha512-xyvckTGsP+o7k7aJubQHScFRJf7zcz1rqin0QNMYDVCpPUTVMHL/2Vhjjgls50BvwQKOVlVNCC4/nLuOX9+iQA==", "integrity": "sha512-e38FzTUdraDS2tdI34QHr8Gf68TOS8dPsVdfrl+y7La2hSn8UIMtQ43cMaExTyHo6uZ9mFKUeIxgwVgAxDrQbQ==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -98,9 +104,9 @@
] ]
}, },
"node_modules/@dbmate/linux-x64": { "node_modules/@dbmate/linux-x64": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/@dbmate/linux-x64/-/linux-x64-2.35.0.tgz", "resolved": "https://registry.npmjs.org/@dbmate/linux-x64/-/linux-x64-2.35.1.tgz",
"integrity": "sha512-oF88oEwEX8pZGuU6f1Zqevqrz0rH2tiUQG7cUmCfJ/VTkWmWVzEQ8yleMwvL8iWJUHgcXotPnQy++JSQhuaB9Q==", "integrity": "sha512-gdr9Q6vMMUaNYz8fv64oNSuoHYLjpeuZjahY6J7Dy4c6wQVcfLs7t3aiBCBxlvVkjJJIr5Ig3ApwqC0V2IojQA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -112,9 +118,9 @@
] ]
}, },
"node_modules/@dbmate/win32-x64": { "node_modules/@dbmate/win32-x64": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/@dbmate/win32-x64/-/win32-x64-2.35.0.tgz", "resolved": "https://registry.npmjs.org/@dbmate/win32-x64/-/win32-x64-2.35.1.tgz",
"integrity": "sha512-/etcU66AA/kLnyhj098SlD9dkDhurDdybjPty3yhdp41Aymoi3oEu9lcoGzj+zPDeND4dJfJG95hV0+bQ4ZiwQ==", "integrity": "sha512-1pP+/oDEeOLvrvPdirM8VIi/+8v8Qf9fDOpNo3nRslQPaoOTJKsMaVLr5b5Ba/UrOisFYJmLKslgWvvjGAY7wg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -641,9 +647,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "26.3.0", "version": "26.4.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-26.3.0.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz",
"integrity": "sha512-L3fgrnchriRC2ExBflb8j4uZZURHZfQsmQeyVzhjcHW4kkwVyo8/0h1B2MVzMTrYUJYu6G7EWs14hW/L9putqw==", "integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -1099,6 +1105,10 @@
"url": "https://opencollective.com/express" "url": "https://opencollective.com/express"
} }
}, },
"node_modules/book-test": {
"resolved": "api",
"link": true
},
"node_modules/bytes": { "node_modules/bytes": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -1209,22 +1219,22 @@
} }
}, },
"node_modules/dbmate": { "node_modules/dbmate": {
"version": "2.35.0", "version": "2.35.1",
"resolved": "https://registry.npmjs.org/dbmate/-/dbmate-2.35.0.tgz", "resolved": "https://registry.npmjs.org/dbmate/-/dbmate-2.35.1.tgz",
"integrity": "sha512-BqVpyxFZyaCOOHfB1LHgh5FzgthU719lzaWKPRhXj8s3rJtCseeVw5WfzYm8haF9Dx0UhNu0RtCaEouoexW1Gg==", "integrity": "sha512-TGhNRbSnlLeLjpV/m4uHJSwZhsJZEeE+IIl98UYbb6s63j1ZsPY6XuVWL6pl3YYyfupVh7pAye6iuOAYf3Maxw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
"dbmate": "dist/cli.js" "dbmate": "dist/cli.js"
}, },
"optionalDependencies": { "optionalDependencies": {
"@dbmate/darwin-arm64": "2.35.0", "@dbmate/darwin-arm64": "2.35.1",
"@dbmate/darwin-x64": "2.35.0", "@dbmate/darwin-x64": "2.35.1",
"@dbmate/linux-arm": "2.35.0", "@dbmate/linux-arm": "2.35.1",
"@dbmate/linux-arm64": "2.35.0", "@dbmate/linux-arm64": "2.35.1",
"@dbmate/linux-ia32": "2.35.0", "@dbmate/linux-ia32": "2.35.1",
"@dbmate/linux-x64": "2.35.0", "@dbmate/linux-x64": "2.35.1",
"@dbmate/win32-x64": "2.35.0" "@dbmate/win32-x64": "2.35.1"
} }
}, },
"node_modules/debug": { "node_modules/debug": {
@@ -1734,9 +1744,9 @@
} }
}, },
"node_modules/morgan": { "node_modules/morgan": {
"version": "1.11.0", "version": "1.12.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.11.0.tgz", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.12.0.tgz",
"integrity": "sha512-zSkVu3t18r39pw4ixfBKvfZi3y2UOqr7d4WYwcj3m8nXpEQK4rPO6GLzs/CExoRgmX3y9EjmmcXqv6jq0SK46g==", "integrity": "sha512-OHpTRQwn2ezasILW8iKe+Yww1XsfWsZIpUOLF7RDb2g5GwO3trPaRwi7+8BDiJ7HFx2Kg2mfUdCBcVhwYlOz2g==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"basic-auth": "~2.0.1", "basic-auth": "~2.0.1",
+7 -28
View File
@@ -1,35 +1,14 @@
{ {
"name": "book-test", "name": "book-test-workspace",
"version": "1.0.0", "private": true,
"description": "", "workspaces": [
"main": "index.js", "api",
"web"
],
"scripts": { "scripts": {
"test": "node --import tsx --test src/**/*.test.ts", "test:api": "npm run test --workspace=api"
"db:migrate": "dotenv dbmate up"
},
"keywords": [],
"author": "Chris Smith",
"license": "ISC",
"devDependencies": {
"@types/cors": "^2.8.19",
"@types/express": "^5.0.6",
"@types/morgan": "^1.9.10",
"@types/node": "^26.3.0",
"@types/pg": "^8.23.1",
"dbmate": "^2.35.0",
"tsx": "^4.23.12",
"typescript": "^7.0.2"
},
"dependencies": {
"cors": "^2.8.6",
"dotenv": "^17.4.2",
"dotenv-cli": "^11.0.0",
"express": "^5.2.1",
"morgan": "^1.11.0",
"pg": "^8.23.0"
}, },
"allowScripts": { "allowScripts": {
"dotenv-cli@11.0.0": true,
"esbuild@0.28.2": true "esbuild@0.28.2": true
} }
} }