WIP: bootstrap and partial real Solana watcher implementation

This commit is contained in:
2026-08-16 09:17:45 +00:00
commit dc23412c3f
7232 changed files with 1687637 additions and 0 deletions

View File

@@ -0,0 +1,228 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@typescript-eslint/utils");
const tsutils = __importStar(require("ts-api-utils"));
const util_1 = require("../util");
const getForStatementHeadLoc_1 = require("../util/getForStatementHeadLoc");
const isPromiseAggregatorMethod_1 = require("../util/isPromiseAggregatorMethod");
exports.default = (0, util_1.createRule)({
name: 'await-thenable',
meta: {
type: 'problem',
docs: {
description: 'Disallow awaiting a value that is not a Thenable',
recommended: 'recommended',
requiresTypeChecking: true,
},
hasSuggestions: true,
messages: {
await: 'Unexpected `await` of a non-Promise (non-"Thenable") value.',
awaitUsingOfNonAsyncDisposable: 'Unexpected `await using` of a value that is not async disposable.',
convertToOrdinaryFor: 'Convert to an ordinary `for...of` loop.',
forAwaitOfNonAsyncIterable: 'Unexpected `for await...of` of a value that is not async iterable.',
invalidPromiseAggregatorInput: 'Unexpected iterable of non-Promise (non-"Thenable") values passed to promise aggregator.',
removeAwait: 'Remove unnecessary `await`.',
},
schema: [],
},
defaultOptions: [],
create(context) {
const services = (0, util_1.getParserServices)(context);
const checker = services.program.getTypeChecker();
return {
AwaitExpression(node) {
const awaitArgumentEsNode = node.argument;
const awaitArgumentType = services.getTypeAtLocation(awaitArgumentEsNode);
const awaitArgumentTsNode = services.esTreeNodeToTSNodeMap.get(awaitArgumentEsNode);
const certainty = (0, util_1.needsToBeAwaited)(checker, awaitArgumentTsNode, awaitArgumentType);
if (certainty === util_1.Awaitable.Never) {
context.report({
node,
messageId: 'await',
suggest: [
{
messageId: 'removeAwait',
fix(fixer) {
const awaitKeyword = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await expression'));
return fixer.remove(awaitKeyword);
},
},
],
});
}
},
CallExpression(node) {
if (!(0, isPromiseAggregatorMethod_1.isPromiseAggregatorMethod)(context, services, node)) {
return;
}
const argument = node.arguments.at(0);
if (argument == null) {
return;
}
if (argument.type === utils_1.TSESTree.AST_NODE_TYPES.ArrayExpression) {
for (const element of argument.elements) {
if (element == null) {
continue;
}
const type = (0, util_1.getConstrainedTypeAtLocation)(services, element);
const tsNode = services.esTreeNodeToTSNodeMap.get(element);
if (isAlwaysNonAwaitableType(type, tsNode, checker)) {
context.report({
node: element,
messageId: 'invalidPromiseAggregatorInput',
});
}
}
return;
}
const type = (0, util_1.getConstrainedTypeAtLocation)(services, argument);
if (isInvalidPromiseAggregatorInput(checker, services.esTreeNodeToTSNodeMap.get(argument), type)) {
context.report({
node: argument,
messageId: 'invalidPromiseAggregatorInput',
});
}
},
'ForOfStatement[await=true]'(node) {
const type = services.getTypeAtLocation(node.right);
if ((0, util_1.isTypeAnyType)(type)) {
return;
}
const hasAsyncIteratorSymbol = tsutils
.unionConstituents(type)
.some(typePart => tsutils.getWellKnownSymbolPropertyOfType(typePart, 'asyncIterator', checker) != null);
if (!hasAsyncIteratorSymbol) {
context.report({
loc: (0, getForStatementHeadLoc_1.getForStatementHeadLoc)(context.sourceCode, node),
messageId: 'forAwaitOfNonAsyncIterable',
suggest: [
// Note that this suggestion causes broken code for sync iterables
// of promises, since the loop variable is not awaited.
{
messageId: 'convertToOrdinaryFor',
fix(fixer) {
const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'for await loop'));
return fixer.remove(awaitToken);
},
},
],
});
}
},
'VariableDeclaration[kind="await using"]'(node) {
for (const declarator of node.declarations) {
const init = declarator.init;
if (init == null) {
continue;
}
const type = services.getTypeAtLocation(init);
if ((0, util_1.isTypeAnyType)(type)) {
continue;
}
const hasAsyncDisposeSymbol = tsutils
.unionConstituents(type)
.some(typePart => tsutils.getWellKnownSymbolPropertyOfType(typePart, 'asyncDispose', checker) != null);
if (!hasAsyncDisposeSymbol) {
context.report({
node: init,
messageId: 'awaitUsingOfNonAsyncDisposable',
// let the user figure out what to do if there's
// await using a = b, c = d, e = f;
// it's rare and not worth the complexity to handle.
...(0, util_1.getFixOrSuggest)({
fixOrSuggest: node.declarations.length === 1 ? 'suggest' : 'none',
suggestion: {
messageId: 'removeAwait',
fix(fixer) {
const awaitToken = (0, util_1.nullThrows)(context.sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await using'));
return fixer.remove(awaitToken);
},
},
}),
});
}
}
},
};
},
});
function isInvalidPromiseAggregatorInput(checker, node, type) {
// non array/tuple/iterable types already show up as a type error
if (!isIterable(type, checker)) {
return false;
}
for (const part of tsutils.unionConstituents(type)) {
const valueTypes = getValueTypesOfArrayLike(part, checker);
if (valueTypes != null) {
for (const typeArgument of valueTypes) {
if (containsNonAwaitableType(typeArgument, node, checker)) {
return true;
}
}
}
}
return false;
}
function getValueTypesOfArrayLike(type, checker) {
if (checker.isTupleType(type)) {
return checker.getTypeArguments(type);
}
if (checker.isArrayLikeType(type)) {
return [
(0, util_1.nullThrows)(type.getNumberIndexType(), 'number index type should exist on an array-like'),
];
}
// `Iterable<...>`
if (tsutils.isTypeReference(type)) {
return checker.getTypeArguments(type).slice(0, 1);
}
return null;
}
function isAlwaysNonAwaitableType(type, node, checker) {
return tsutils
.unionConstituents(type)
.every(typeArgumentPart => (0, util_1.needsToBeAwaited)(checker, node, typeArgumentPart) === util_1.Awaitable.Never);
}
function containsNonAwaitableType(type, node, checker) {
return tsutils
.unionConstituents(type)
.some(typeArgumentPart => (0, util_1.needsToBeAwaited)(checker, node, typeArgumentPart) === util_1.Awaitable.Never);
}
function isIterable(type, checker) {
return tsutils
.unionConstituents(type)
.every(part => !!tsutils.getWellKnownSymbolPropertyOfType(part, 'iterator', checker));
}

View File

@@ -0,0 +1,22 @@
import type * as TSESLint from '../ts-eslint';
import type { ParserServices, ParserServicesWithTypeInformation } from '../ts-estree';
/**
* Try to retrieve type-aware parser service from context.
* This **_will_** throw if it is not available.
*/
export declare function getParserServices<MessageIds extends string, Options extends readonly unknown[]>(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): ParserServicesWithTypeInformation;
/**
* Try to retrieve type-aware parser service from context.
* This **_will_** throw if it is not available.
*/
export declare function getParserServices<MessageIds extends string, Options extends readonly unknown[]>(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, allowWithoutFullTypeInformation: false): ParserServicesWithTypeInformation;
/**
* Try to retrieve type-aware parser service from context.
* This **_will not_** throw if it is not available.
*/
export declare function getParserServices<MessageIds extends string, Options extends readonly unknown[]>(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, allowWithoutFullTypeInformation: true): ParserServices;
/**
* Try to retrieve type-aware parser service from context.
* This may or may not throw if it is not available, depending on if `allowWithoutFullTypeInformation` is `true`
*/
export declare function getParserServices<MessageIds extends string, Options extends readonly unknown[]>(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, allowWithoutFullTypeInformation: boolean): ParserServices;

View File

@@ -0,0 +1,448 @@
/** @deprecated since v6.3.0 - use constants property exposed by the relevant module instead. */
declare module 'constants' {
/** @deprecated since v6.3.0 - use `os.constants.errno.E2BIG` instead. */
const E2BIG: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EACCES` instead. */
const EACCES: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EADDRINUSE` instead. */
const EADDRINUSE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EADDRNOTAVAIL` instead. */
const EADDRNOTAVAIL: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EAFNOSUPPORT` instead. */
const EAFNOSUPPORT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EAGAIN` instead. */
const EAGAIN: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EALREADY` instead. */
const EALREADY: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EBADF` instead. */
const EBADF: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EBADMSG` instead. */
const EBADMSG: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EBUSY` instead. */
const EBUSY: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ECANCELED` instead. */
const ECANCELED: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ECHILD` instead. */
const ECHILD: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ECONNABORTED` instead. */
const ECONNABORTED: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ECONNREFUSED` instead. */
const ECONNREFUSED: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ECONNRESET` instead. */
const ECONNRESET: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EDEADLK` instead. */
const EDEADLK: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EDESTADDRREQ` instead. */
const EDESTADDRREQ: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EDOM` instead. */
const EDOM: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EEXIST` instead. */
const EEXIST: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EFAULT` instead. */
const EFAULT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EFBIG` instead. */
const EFBIG: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EHOSTUNREACH` instead. */
const EHOSTUNREACH: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EIDRM` instead. */
const EIDRM: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EILSEQ` instead. */
const EILSEQ: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EINPROGRESS` instead. */
const EINPROGRESS: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EINTR` instead. */
const EINTR: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EINVAL` instead. */
const EINVAL: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EIO` instead. */
const EIO: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EISCONN` instead. */
const EISCONN: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EISDIR` instead. */
const EISDIR: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ELOOP` instead. */
const ELOOP: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EMFILE` instead. */
const EMFILE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EMLINK` instead. */
const EMLINK: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EMSGSIZE` instead. */
const EMSGSIZE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENAMETOOLONG` instead. */
const ENAMETOOLONG: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENETDOWN` instead. */
const ENETDOWN: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENETRESET` instead. */
const ENETRESET: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENETUNREACH` instead. */
const ENETUNREACH: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENFILE` instead. */
const ENFILE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOBUFS` instead. */
const ENOBUFS: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENODATA` instead. */
const ENODATA: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENODEV` instead. */
const ENODEV: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOENT` instead. */
const ENOENT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOEXEC` instead. */
const ENOEXEC: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOLCK` instead. */
const ENOLCK: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOLINK` instead. */
const ENOLINK: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOMEM` instead. */
const ENOMEM: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOMSG` instead. */
const ENOMSG: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOPROTOOPT` instead. */
const ENOPROTOOPT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOSPC` instead. */
const ENOSPC: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOSR` instead. */
const ENOSR: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOSTR` instead. */
const ENOSTR: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOSYS` instead. */
const ENOSYS: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOTCONN` instead. */
const ENOTCONN: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOTDIR` instead. */
const ENOTDIR: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOTEMPTY` instead. */
const ENOTEMPTY: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOTSOCK` instead. */
const ENOTSOCK: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOTSUP` instead. */
const ENOTSUP: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENOTTY` instead. */
const ENOTTY: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ENXIO` instead. */
const ENXIO: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EOPNOTSUPP` instead. */
const EOPNOTSUPP: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EOVERFLOW` instead. */
const EOVERFLOW: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EPERM` instead. */
const EPERM: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EPIPE` instead. */
const EPIPE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EPROTO` instead. */
const EPROTO: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EPROTONOSUPPORT` instead. */
const EPROTONOSUPPORT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EPROTOTYPE` instead. */
const EPROTOTYPE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ERANGE` instead. */
const ERANGE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EROFS` instead. */
const EROFS: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ESPIPE` instead. */
const ESPIPE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ESRCH` instead. */
const ESRCH: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ETIME` instead. */
const ETIME: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ETIMEDOUT` instead. */
const ETIMEDOUT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.ETXTBSY` instead. */
const ETXTBSY: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EWOULDBLOCK` instead. */
const EWOULDBLOCK: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.EXDEV` instead. */
const EXDEV: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEINTR` instead. */
const WSAEINTR: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEBADF` instead. */
const WSAEBADF: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEACCES` instead. */
const WSAEACCES: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEFAULT` instead. */
const WSAEFAULT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEINVAL` instead. */
const WSAEINVAL: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEMFILE` instead. */
const WSAEMFILE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEWOULDBLOCK` instead. */
const WSAEWOULDBLOCK: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEINPROGRESS` instead. */
const WSAEINPROGRESS: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEALREADY` instead. */
const WSAEALREADY: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENOTSOCK` instead. */
const WSAENOTSOCK: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEDESTADDRREQ` instead. */
const WSAEDESTADDRREQ: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEMSGSIZE` instead. */
const WSAEMSGSIZE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEPROTOTYPE` instead. */
const WSAEPROTOTYPE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENOPROTOOPT` instead. */
const WSAENOPROTOOPT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEPROTONOSUPPORT` instead. */
const WSAEPROTONOSUPPORT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAESOCKTNOSUPPORT` instead. */
const WSAESOCKTNOSUPPORT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEOPNOTSUPP` instead. */
const WSAEOPNOTSUPP: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEPFNOSUPPORT` instead. */
const WSAEPFNOSUPPORT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEAFNOSUPPORT` instead. */
const WSAEAFNOSUPPORT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEADDRINUSE` instead. */
const WSAEADDRINUSE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEADDRNOTAVAIL` instead. */
const WSAEADDRNOTAVAIL: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENETDOWN` instead. */
const WSAENETDOWN: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENETUNREACH` instead. */
const WSAENETUNREACH: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENETRESET` instead. */
const WSAENETRESET: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAECONNABORTED` instead. */
const WSAECONNABORTED: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAECONNRESET` instead. */
const WSAECONNRESET: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENOBUFS` instead. */
const WSAENOBUFS: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEISCONN` instead. */
const WSAEISCONN: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENOTCONN` instead. */
const WSAENOTCONN: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAESHUTDOWN` instead. */
const WSAESHUTDOWN: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAETOOMANYREFS` instead. */
const WSAETOOMANYREFS: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAETIMEDOUT` instead. */
const WSAETIMEDOUT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAECONNREFUSED` instead. */
const WSAECONNREFUSED: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAELOOP` instead. */
const WSAELOOP: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENAMETOOLONG` instead. */
const WSAENAMETOOLONG: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEHOSTDOWN` instead. */
const WSAEHOSTDOWN: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEHOSTUNREACH` instead. */
const WSAEHOSTUNREACH: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENOTEMPTY` instead. */
const WSAENOTEMPTY: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEPROCLIM` instead. */
const WSAEPROCLIM: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEUSERS` instead. */
const WSAEUSERS: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEDQUOT` instead. */
const WSAEDQUOT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAESTALE` instead. */
const WSAESTALE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEREMOTE` instead. */
const WSAEREMOTE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSASYSNOTREADY` instead. */
const WSASYSNOTREADY: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAVERNOTSUPPORTED` instead. */
const WSAVERNOTSUPPORTED: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSANOTINITIALISED` instead. */
const WSANOTINITIALISED: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEDISCON` instead. */
const WSAEDISCON: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAENOMORE` instead. */
const WSAENOMORE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAECANCELLED` instead. */
const WSAECANCELLED: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEINVALIDPROCTABLE` instead. */
const WSAEINVALIDPROCTABLE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEINVALIDPROVIDER` instead. */
const WSAEINVALIDPROVIDER: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEPROVIDERFAILEDINIT` instead. */
const WSAEPROVIDERFAILEDINIT: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSASYSCALLFAILURE` instead. */
const WSASYSCALLFAILURE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSASERVICE_NOT_FOUND` instead. */
const WSASERVICE_NOT_FOUND: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSATYPE_NOT_FOUND` instead. */
const WSATYPE_NOT_FOUND: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSA_E_NO_MORE` instead. */
const WSA_E_NO_MORE: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSA_E_CANCELLED` instead. */
const WSA_E_CANCELLED: number;
/** @deprecated since v6.3.0 - use `os.constants.errno.WSAEREFUSED` instead. */
const WSAEREFUSED: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGHUP` instead. */
const SIGHUP: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGINT` instead. */
const SIGINT: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGILL` instead. */
const SIGILL: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGABRT` instead. */
const SIGABRT: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGFPE` instead. */
const SIGFPE: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGKILL` instead. */
const SIGKILL: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGSEGV` instead. */
const SIGSEGV: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGTERM` instead. */
const SIGTERM: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGBREAK` instead. */
const SIGBREAK: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGWINCH` instead. */
const SIGWINCH: number;
const SSL_OP_ALL: number;
const SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number;
const SSL_OP_CIPHER_SERVER_PREFERENCE: number;
const SSL_OP_CISCO_ANYCONNECT: number;
const SSL_OP_COOKIE_EXCHANGE: number;
const SSL_OP_CRYPTOPRO_TLSEXT_BUG: number;
const SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number;
const SSL_OP_EPHEMERAL_RSA: number;
const SSL_OP_LEGACY_SERVER_CONNECT: number;
const SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number;
const SSL_OP_MICROSOFT_SESS_ID_BUG: number;
const SSL_OP_MSIE_SSLV2_RSA_PADDING: number;
const SSL_OP_NETSCAPE_CA_DN_BUG: number;
const SSL_OP_NETSCAPE_CHALLENGE_BUG: number;
const SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number;
const SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number;
const SSL_OP_NO_COMPRESSION: number;
const SSL_OP_NO_QUERY_MTU: number;
const SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number;
const SSL_OP_NO_SSLv2: number;
const SSL_OP_NO_SSLv3: number;
const SSL_OP_NO_TICKET: number;
const SSL_OP_NO_TLSv1: number;
const SSL_OP_NO_TLSv1_1: number;
const SSL_OP_NO_TLSv1_2: number;
const SSL_OP_PKCS1_CHECK_1: number;
const SSL_OP_PKCS1_CHECK_2: number;
const SSL_OP_SINGLE_DH_USE: number;
const SSL_OP_SINGLE_ECDH_USE: number;
const SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number;
const SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number;
const SSL_OP_TLS_BLOCK_PADDING_BUG: number;
const SSL_OP_TLS_D5_BUG: number;
const SSL_OP_TLS_ROLLBACK_BUG: number;
const ENGINE_METHOD_DSA: number;
const ENGINE_METHOD_DH: number;
const ENGINE_METHOD_RAND: number;
const ENGINE_METHOD_ECDH: number;
const ENGINE_METHOD_ECDSA: number;
const ENGINE_METHOD_CIPHERS: number;
const ENGINE_METHOD_DIGESTS: number;
const ENGINE_METHOD_STORE: number;
const ENGINE_METHOD_PKEY_METHS: number;
const ENGINE_METHOD_PKEY_ASN1_METHS: number;
const ENGINE_METHOD_ALL: number;
const ENGINE_METHOD_NONE: number;
const DH_CHECK_P_NOT_SAFE_PRIME: number;
const DH_CHECK_P_NOT_PRIME: number;
const DH_UNABLE_TO_CHECK_GENERATOR: number;
const DH_NOT_SUITABLE_GENERATOR: number;
const RSA_PKCS1_PADDING: number;
const RSA_SSLV23_PADDING: number;
const RSA_NO_PADDING: number;
const RSA_PKCS1_OAEP_PADDING: number;
const RSA_X931_PADDING: number;
const RSA_PKCS1_PSS_PADDING: number;
const POINT_CONVERSION_COMPRESSED: number;
const POINT_CONVERSION_UNCOMPRESSED: number;
const POINT_CONVERSION_HYBRID: number;
const O_RDONLY: number;
const O_WRONLY: number;
const O_RDWR: number;
const S_IFMT: number;
const S_IFREG: number;
const S_IFDIR: number;
const S_IFCHR: number;
const S_IFBLK: number;
const S_IFIFO: number;
const S_IFSOCK: number;
const S_IRWXU: number;
const S_IRUSR: number;
const S_IWUSR: number;
const S_IXUSR: number;
const S_IRWXG: number;
const S_IRGRP: number;
const S_IWGRP: number;
const S_IXGRP: number;
const S_IRWXO: number;
const S_IROTH: number;
const S_IWOTH: number;
const S_IXOTH: number;
const S_IFLNK: number;
const O_CREAT: number;
const O_EXCL: number;
const O_NOCTTY: number;
const O_DIRECTORY: number;
const O_NOATIME: number;
const O_NOFOLLOW: number;
const O_SYNC: number;
const O_DSYNC: number;
const O_SYMLINK: number;
const O_DIRECT: number;
const O_NONBLOCK: number;
const O_TRUNC: number;
const O_APPEND: number;
const F_OK: number;
const R_OK: number;
const W_OK: number;
const X_OK: number;
const COPYFILE_EXCL: number;
const COPYFILE_FICLONE: number;
const COPYFILE_FICLONE_FORCE: number;
const UV_UDP_REUSEADDR: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGQUIT` instead. */
const SIGQUIT: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGTRAP` instead. */
const SIGTRAP: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGIOT` instead. */
const SIGIOT: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGBUS` instead. */
const SIGBUS: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGUSR1` instead. */
const SIGUSR1: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGUSR2` instead. */
const SIGUSR2: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGPIPE` instead. */
const SIGPIPE: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGALRM` instead. */
const SIGALRM: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGCHLD` instead. */
const SIGCHLD: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGSTKFLT` instead. */
const SIGSTKFLT: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGCONT` instead. */
const SIGCONT: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGSTOP` instead. */
const SIGSTOP: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGTSTP` instead. */
const SIGTSTP: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGTTIN` instead. */
const SIGTTIN: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGTTOU` instead. */
const SIGTTOU: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGURG` instead. */
const SIGURG: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGXCPU` instead. */
const SIGXCPU: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGXFSZ` instead. */
const SIGXFSZ: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGVTALRM` instead. */
const SIGVTALRM: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGPROF` instead. */
const SIGPROF: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGIO` instead. */
const SIGIO: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGPOLL` instead. */
const SIGPOLL: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGPWR` instead. */
const SIGPWR: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGSYS` instead. */
const SIGSYS: number;
/** @deprecated since v6.3.0 - use `os.constants.signals.SIGUNUSED` instead. */
const SIGUNUSED: number;
const defaultCoreCipherList: string;
const defaultCipherList: string;
const ENGINE_METHOD_RSA: number;
const ALPN_ENABLED: number;
}

View File

@@ -0,0 +1,14 @@
"use strict";
// THIS CODE WAS AUTOMATICALLY GENERATED
// DO NOT EDIT THIS CODE BY HAND
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
// npx nx generate-lib repo
Object.defineProperty(exports, "__esModule", { value: true });
exports.es7 = void 0;
const es2015_1 = require("./es2015");
const es2016_array_include_1 = require("./es2016.array.include");
const es2016_intl_1 = require("./es2016.intl");
exports.es7 = {
libs: [es2015_1.es2015, es2016_array_include_1.es2016_array_include, es2016_intl_1.es2016_intl],
variables: [],
};

View File

@@ -0,0 +1,35 @@
'use strict'
const types = require('pg-types')
function TypeOverrides(userTypes) {
this._types = userTypes || types
this.text = {}
this.binary = {}
}
TypeOverrides.prototype.getOverrides = function (format) {
switch (format) {
case 'text':
return this.text
case 'binary':
return this.binary
default:
return {}
}
}
TypeOverrides.prototype.setTypeParser = function (oid, format, parseFn) {
if (typeof format === 'function') {
parseFn = format
format = 'text'
}
this.getOverrides(format)[oid] = parseFn
}
TypeOverrides.prototype.getTypeParser = function (oid, format) {
format = format || 'text'
return this.getOverrides(format)[oid] || this._types.getTypeParser(oid, format)
}
module.exports = TypeOverrides

View File

@@ -0,0 +1,112 @@
# pg-cloudflare
`pg-cloudflare` makes it easier to take an existing package that relies on `tls` and `net`, and make it work in environments where only `connect()` is supported, such as Cloudflare Workers.
`pg-cloudflare` wraps `connect()`, the [TCP Socket API](https://github.com/wintercg/proposal-sockets-api) proposed within WinterCG, and implemented in [Cloudflare Workers](https://developers.cloudflare.com/workers/runtime-apis/tcp-sockets/), and exposes an interface with methods similar to what the `net` and `tls` modules in Node.js expose. (ex: `net.connect(path[, options][, callback])`). This minimizes the number of changes needed in order to make an existing package work across JavaScript runtimes.
## Installation
```
npm i --save-dev pg-cloudflare
```
The package uses conditional exports to support bundlers that don't know about
`cloudflare:sockets`, so the consumer code by default imports an empty file. To
enable the package, resolve to the `cloudflare` condition in your bundler's
config. For example:
- `webpack.config.js`
```js
export default {
...,
resolve: { conditionNames: [..., "workerd"] },
plugins: [
// ignore cloudflare:sockets imports
new webpack.IgnorePlugin({
resourceRegExp: /^cloudflare:sockets$/,
}),
],
}
```
- `vite.config.js`
> [!NOTE]
> If you are using the [Cloudflare Vite plugin](https://www.npmjs.com/package/@cloudflare/vite-plugin) then the following configuration is not necessary.
```js
export default defineConfig({
...,
resolve: {
conditions: [..., "workerd"],
},
build: {
...,
// don't try to bundle cloudflare:sockets
rollupOptions: {
external: [..., 'cloudflare:sockets'],
},
},
})
```
- `rollup.config.js`
```js
export default defineConfig({
...,
plugins: [..., nodeResolve({ exportConditions: [..., 'workerd'] })],
// don't try to bundle cloudflare:sockets
external: [..., 'cloudflare:sockets'],
})
```
- `esbuild.config.js`
```js
await esbuild.build({
...,
conditions: [..., 'workerd'],
})
```
The concrete examples can be found in `packages/pg-bundler-test`.
## How to use conditionally, in non-Node.js environments
As implemented in `pg` [here](https://github.com/brianc/node-postgres/commit/07553428e9c0eacf761a5d4541a3300ff7859578#diff-34588ad868ebcb232660aba7ee6a99d1e02f4bc93f73497d2688c3f074e60533R5-R13), a typical use case might look as follows, where in a Node.js environment the `net` module is used, while in a non-Node.js environment, where `net` is unavailable, `pg-cloudflare` is used instead, providing an equivalent interface:
```js
module.exports.getStream = function getStream(ssl = false) {
const net = require('net')
if (typeof net.Socket === 'function') {
return net.Socket()
}
const { CloudflareSocket } = require('pg-cloudflare')
return new CloudflareSocket(ssl)
}
```
## Node.js implementation of the Socket API proposal
If you're looking for a way to rely on `connect()` as the interface you use to interact with raw sockets, but need this interface to be available in a Node.js environment, [`@arrowood.dev/socket`](https://github.com/Ethan-Arrowood/socket) provides a Node.js implementation of the Socket API.
### license
The MIT License (MIT)
Copyright (c) 2023 Brian M. Carlson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,23 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABILITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
interface String {
/**
* Returns a new String consisting of the single UTF-16 code unit located at the specified index.
* @param index The zero-based index of the desired code unit. A negative index will count back from the last item.
*/
at(index: number): string | undefined;
}

View File

@@ -0,0 +1,111 @@
import type { $ZodStringFormats } from "../core/checks.js";
import type * as errors from "../core/errors.js";
import * as util from "../core/util.js";
const error: () => errors.$ZodErrorMap = () => {
const Sizable: Record<string, { unit: string; verb: string }> = {
string: { unit: "karakter", verb: "olmalı" },
file: { unit: "bayt", verb: "olmalı" },
array: { unit: "öğe", verb: "olmalı" },
set: { unit: "öğe", verb: "olmalı" },
};
function getSizing(origin: string): { unit: string; verb: string } | null {
return Sizable[origin] ?? null;
}
const FormatDictionary: {
[k in $ZodStringFormats | (string & {})]?: string;
} = {
regex: "girdi",
email: "e-posta adresi",
url: "URL",
emoji: "emoji",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "ISO tarih ve saat",
date: "ISO tarih",
time: "ISO saat",
duration: "ISO süre",
ipv4: "IPv4 adresi",
ipv6: "IPv6 adresi",
cidrv4: "IPv4 aralığı",
cidrv6: "IPv6 aralığı",
base64: "base64 ile şifrelenmiş metin",
base64url: "base64url ile şifrelenmiş metin",
json_string: "JSON dizesi",
e164: "E.164 sayısı",
jwt: "JWT",
template_literal: "Şablon dizesi",
};
const TypeDictionary: {
[k in errors.$ZodInvalidTypeExpected | (string & {})]?: string;
} = {
nan: "NaN",
};
return (issue) => {
switch (issue.code) {
case "invalid_type": {
const expected = TypeDictionary[issue.expected] ?? issue.expected;
const receivedType = util.parsedType(issue.input);
const received = TypeDictionary[receivedType] ?? receivedType;
if (/^[A-Z]/.test(issue.expected)) {
return `Geçersiz değer: beklenen instanceof ${issue.expected}, alınan ${received}`;
}
return `Geçersiz değer: beklenen ${expected}, alınan ${received}`;
}
case "invalid_value":
if (issue.values.length === 1) return `Geçersiz değer: beklenen ${util.stringifyPrimitive(issue.values[0])}`;
return `Geçersiz seçenek: aşağıdakilerden biri olmalı: ${util.joinValues(issue.values, "|")}`;
case "too_big": {
const adj = issue.inclusive ? "<=" : "<";
const sizing = getSizing(issue.origin);
if (sizing)
return `Çok büyük: beklenen ${issue.origin ?? "değer"} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "öğe"}`;
return `Çok büyük: beklenen ${issue.origin ?? "değer"} ${adj}${issue.maximum.toString()}`;
}
case "too_small": {
const adj = issue.inclusive ? ">=" : ">";
const sizing = getSizing(issue.origin);
if (sizing) return `Çok küçük: beklenen ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
return `Çok küçük: beklenen ${issue.origin} ${adj}${issue.minimum.toString()}`;
}
case "invalid_format": {
const _issue = issue as errors.$ZodStringFormatIssues;
if (_issue.format === "starts_with") return `Geçersiz metin: "${_issue.prefix}" ile başlamalı`;
if (_issue.format === "ends_with") return `Geçersiz metin: "${_issue.suffix}" ile bitmeli`;
if (_issue.format === "includes") return `Geçersiz metin: "${_issue.includes}" içermeli`;
if (_issue.format === "regex") return `Geçersiz metin: ${_issue.pattern} desenine uymalı`;
return `Geçersiz ${FormatDictionary[_issue.format] ?? issue.format}`;
}
case "not_multiple_of":
return `Geçersiz sayı: ${issue.divisor} ile tam bölünebilmeli`;
case "unrecognized_keys":
return `Tanınmayan anahtar${issue.keys.length > 1 ? "lar" : ""}: ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return `${issue.origin} içinde geçersiz anahtar`;
case "invalid_union":
return "Geçersiz değer";
case "invalid_element":
return `${issue.origin} içinde geçersiz değer`;
default:
return `Geçersiz değer`;
}
};
};
export default function (): { localeError: errors.$ZodErrorMap } {
return {
localeError: error(),
};
}

View File

@@ -0,0 +1,24 @@
'use strict'
const fs = require('fs')
const { Writable } = require('stream')
function run (opts) {
let data = ''
return new Writable({
autoDestroy: true,
write (chunk, enc, cb) {
data += chunk.toString()
cb()
},
final (cb) {
setTimeout(function () {
fs.writeFile(opts.dest, data, function (err) {
cb(err)
})
}, 100)
}
})
}
module.exports = run

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ast/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}

View File

@@ -0,0 +1,4 @@
{
"main": "../../cjs/_await_value.cjs",
"module": "../../esm/_await_value.js"
}

View File

@@ -0,0 +1,7 @@
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
export default _default;
/**
* Contains all of `recommended` along with additional recommended rules that require type information.
* @see {@link https://typescript-eslint.io/users/configs#recommended-type-checked}
*/
declare function _default(plugin: FlatConfig.Plugin, parser: FlatConfig.Parser): FlatConfig.ConfigArray;

View File

@@ -0,0 +1,3 @@
import type { ParserServicesWithTypeInformation, TSESTree } from '@typescript-eslint/utils';
import type { RuleContext } from '@typescript-eslint/utils/ts-eslint';
export declare function isPromiseAggregatorMethod(context: RuleContext<string, unknown[]>, services: ParserServicesWithTypeInformation, node: TSESTree.CallExpression): boolean;

View File

@@ -0,0 +1,14 @@
import setPrototypeOf from "./setPrototypeOf.js";
function _inherits(t, e) {
if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
t.prototype = Object.create(e && e.prototype, {
constructor: {
value: t,
writable: !0,
configurable: !0
}
}), Object.defineProperty(t, "prototype", {
writable: !1
}), e && setPrototypeOf(t, e);
}
export { _inherits as default };

View File

@@ -0,0 +1,98 @@
{{# def.definitions }}
{{# def.errors }}
{{# def.setupKeyword }}
{{# def.setupNextLevel }}
{{## def.validateItems:startFrom:
for (var {{=$idx}} = {{=startFrom}}; {{=$idx}} < {{=$data}}.length; {{=$idx}}++) {
{{
$it.errorPath = it.util.getPathExpr(it.errorPath, $idx, it.opts.jsonPointers, true);
var $passData = $data + '[' + $idx + ']';
$it.dataPathArr[$dataNxt] = $idx;
}}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
{{? $breakOnError }}
if (!{{=$nextValid}}) break;
{{?}}
}
#}}
{{
var $idx = 'i' + $lvl
, $dataNxt = $it.dataLevel = it.dataLevel + 1
, $nextData = 'data' + $dataNxt
, $currentBaseId = it.baseId;
}}
var {{=$errs}} = errors;
var {{=$valid}};
{{? Array.isArray($schema) }}
{{ /* 'items' is an array of schemas */}}
{{ var $additionalItems = it.schema.additionalItems; }}
{{? $additionalItems === false }}
{{=$valid}} = {{=$data}}.length <= {{= $schema.length }};
{{
var $currErrSchemaPath = $errSchemaPath;
$errSchemaPath = it.errSchemaPath + '/additionalItems';
}}
{{# def.checkError:'additionalItems' }}
{{ $errSchemaPath = $currErrSchemaPath; }}
{{# def.elseIfValid}}
{{?}}
{{~ $schema:$sch:$i }}
{{? {{# def.nonEmptySchema:$sch }} }}
{{=$nextValid}} = true;
if ({{=$data}}.length > {{=$i}}) {
{{
var $passData = $data + '[' + $i + ']';
$it.schema = $sch;
$it.schemaPath = $schemaPath + '[' + $i + ']';
$it.errSchemaPath = $errSchemaPath + '/' + $i;
$it.errorPath = it.util.getPathExpr(it.errorPath, $i, it.opts.jsonPointers, true);
$it.dataPathArr[$dataNxt] = $i;
}}
{{# def.generateSubschemaCode }}
{{# def.optimizeValidate }}
}
{{# def.ifResultValid }}
{{?}}
{{~}}
{{? typeof $additionalItems == 'object' && {{# def.nonEmptySchema:$additionalItems }} }}
{{
$it.schema = $additionalItems;
$it.schemaPath = it.schemaPath + '.additionalItems';
$it.errSchemaPath = it.errSchemaPath + '/additionalItems';
}}
{{=$nextValid}} = true;
if ({{=$data}}.length > {{= $schema.length }}) {
{{# def.validateItems: $schema.length }}
}
{{# def.ifResultValid }}
{{?}}
{{?? {{# def.nonEmptySchema:$schema }} }}
{{ /* 'items' is a single schema */}}
{{
$it.schema = $schema;
$it.schemaPath = $schemaPath;
$it.errSchemaPath = $errSchemaPath;
}}
{{# def.validateItems: 0 }}
{{?}}
{{? $breakOnError }}
{{= $closingBraces }}
if ({{=$errs}} == errors) {
{{?}}

View File

@@ -0,0 +1,23 @@
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,39 @@
'use strict'
module.exports = handleCustomLevelsOpts
/**
* Parse a CSV string or options object that specifies
* configuration for custom levels.
*
* @param {string|object} cLevels An object mapping level
* names to values, e.g. `{ info: 30, debug: 65 }`, or a
* CSV string in the format `level_name:level_value`, e.g.
* `info:30,debug:65`.
*
* @returns {object} An object mapping levels to labels that
* appear in logs, e.g. `{ '30': 'INFO', '65': 'DEBUG' }`.
*/
function handleCustomLevelsOpts (cLevels) {
if (!cLevels) return {}
if (typeof cLevels === 'string') {
return cLevels
.split(',')
.reduce((agg, value, idx) => {
const [levelName, levelNum = idx] = value.split(':')
agg[levelNum] = levelName.toUpperCase()
return agg
},
{ default: 'USERLVL' })
} else if (Object.prototype.toString.call(cLevels) === '[object Object]') {
return Object
.keys(cLevels)
.reduce((agg, levelName) => {
agg[cLevels[levelName]] = levelName.toUpperCase()
return agg
}, { default: 'USERLVL' })
} else {
return {}
}
}

View File

@@ -0,0 +1,83 @@
# Borsh JS
[![Project license](https://img.shields.io/badge/license-Apache2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Project license](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Discord](https://img.shields.io/discord/490367152054992913?label=discord)](https://discord.gg/Vyp7ETM)
[![Travis status](https://travis-ci.com/near/borsh.svg?branch=master)](https://travis-ci.com/near/borsh-js)
[![NPM version](https://img.shields.io/npm/v/borsh.svg?style=flat-square)](https://npmjs.com/borsh)
[![Size on NPM](https://img.shields.io/bundlephobia/minzip/borsh.svg?style=flat-square)](https://npmjs.com/borsh)
**Borsh JS** is an implementation of the [Borsh] binary serialization format for
JavaScript and TypeScript projects.
Borsh stands for _Binary Object Representation Serializer for Hashing_. It is meant to be used in security-critical projects as it prioritizes consistency,
safety, speed, and comes with a strict specification.
## Examples
### Serializing an object
```javascript
const value = new Test({ x: 255, y: 20, z: '123', q: [1, 2, 3] });
const schema = new Map([[Test, { kind: 'struct', fields: [['x', 'u8'], ['y', 'u64'], ['z', 'string'], ['q', [3]]] }]]);
const buffer = borsh.serialize(schema, value);
```
### Deserializing an object
```javascript
const newValue = borsh.deserialize(schema, Test, buffer);
```
## Type Mappings
| Borsh | TypeScript |
|-----------------------|----------------|
| `u8` integer | `number` |
| `u16` integer | `number` |
| `u32` integer | `number` |
| `u64` integer | `BN` |
| `u128` integer | `BN` |
| `u256` integer | `BN` |
| `u512` integer | `BN` |
| `f32` float | N/A |
| `f64` float | N/A |
| fixed-size byte array | `Uint8Array` |
| UTF-8 string | `string` |
| option | `null` or type |
| map | N/A |
| set | N/A |
| structs | `any` |
## Contributing
Install dependencies:
```bash
yarn install
```
Continuously build with:
```bash
yarn dev
```
Run tests:
```bash
yarn test
```
Run linter
```bash
yarn lint
```
## Publish
Prepare `dist` version by running:
```bash
yarn build
```
When publishing to npm use [np](https://github.com/sindresorhus/np).
# License
This repository is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
See [LICENSE-MIT](LICENSE-MIT.txt) and [LICENSE-APACHE](LICENSE-APACHE) for details.
[Borsh]: https://borsh.io

View File

@@ -0,0 +1,607 @@
/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex" }] */
'use strict';
const { Duplex } = require('stream');
const { randomFillSync } = require('crypto');
const {
types: { isUint8Array }
} = require('util');
const PerMessageDeflate = require('./permessage-deflate');
const { EMPTY_BUFFER, kWebSocket, NOOP } = require('./constants');
const { isBlob, isValidStatusCode } = require('./validation');
const { mask: applyMask, toBuffer } = require('./buffer-util');
const kByteLength = Symbol('kByteLength');
const maskBuffer = Buffer.alloc(4);
const RANDOM_POOL_SIZE = 8 * 1024;
let randomPool;
let randomPoolPointer = RANDOM_POOL_SIZE;
const DEFAULT = 0;
const DEFLATING = 1;
const GET_BLOB_DATA = 2;
/**
* HyBi Sender implementation.
*/
class Sender {
/**
* Creates a Sender instance.
*
* @param {Duplex} socket The connection socket
* @param {Object} [extensions] An object containing the negotiated extensions
* @param {Function} [generateMask] The function used to generate the masking
* key
*/
constructor(socket, extensions, generateMask) {
this._extensions = extensions || {};
if (generateMask) {
this._generateMask = generateMask;
this._maskBuffer = Buffer.alloc(4);
}
this._socket = socket;
this._firstFragment = true;
this._compress = false;
this._bufferedBytes = 0;
this._queue = [];
this._state = DEFAULT;
this.onerror = NOOP;
this[kWebSocket] = undefined;
}
/**
* Frames a piece of data according to the HyBi WebSocket protocol.
*
* @param {(Buffer|String)} data The data to frame
* @param {Object} options Options object
* @param {Boolean} [options.fin=false] Specifies whether or not to set the
* FIN bit
* @param {Function} [options.generateMask] The function used to generate the
* masking key
* @param {Boolean} [options.mask=false] Specifies whether or not to mask
* `data`
* @param {Buffer} [options.maskBuffer] The buffer used to store the masking
* key
* @param {Number} options.opcode The opcode
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
* modified
* @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
* RSV1 bit
* @return {(Buffer|String)[]} The framed data
* @public
*/
static frame(data, options) {
let mask;
let merge = false;
let offset = 2;
let skipMasking = false;
if (options.mask) {
mask = options.maskBuffer || maskBuffer;
if (options.generateMask) {
options.generateMask(mask);
} else {
if (randomPoolPointer === RANDOM_POOL_SIZE) {
/* istanbul ignore else */
if (randomPool === undefined) {
//
// This is lazily initialized because server-sent frames must not
// be masked so it may never be used.
//
randomPool = Buffer.alloc(RANDOM_POOL_SIZE);
}
randomFillSync(randomPool, 0, RANDOM_POOL_SIZE);
randomPoolPointer = 0;
}
mask[0] = randomPool[randomPoolPointer++];
mask[1] = randomPool[randomPoolPointer++];
mask[2] = randomPool[randomPoolPointer++];
mask[3] = randomPool[randomPoolPointer++];
}
skipMasking = (mask[0] | mask[1] | mask[2] | mask[3]) === 0;
offset = 6;
}
let dataLength;
if (typeof data === 'string') {
if (
(!options.mask || skipMasking) &&
options[kByteLength] !== undefined
) {
dataLength = options[kByteLength];
} else {
data = Buffer.from(data);
dataLength = data.length;
}
} else {
dataLength = data.length;
merge = options.mask && options.readOnly && !skipMasking;
}
let payloadLength = dataLength;
if (dataLength >= 65536) {
offset += 8;
payloadLength = 127;
} else if (dataLength > 125) {
offset += 2;
payloadLength = 126;
}
const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);
target[0] = options.fin ? options.opcode | 0x80 : options.opcode;
if (options.rsv1) target[0] |= 0x40;
target[1] = payloadLength;
if (payloadLength === 126) {
target.writeUInt16BE(dataLength, 2);
} else if (payloadLength === 127) {
target[2] = target[3] = 0;
target.writeUIntBE(dataLength, 4, 6);
}
if (!options.mask) return [target, data];
target[1] |= 0x80;
target[offset - 4] = mask[0];
target[offset - 3] = mask[1];
target[offset - 2] = mask[2];
target[offset - 1] = mask[3];
if (skipMasking) return [target, data];
if (merge) {
applyMask(data, mask, target, offset, dataLength);
return [target];
}
applyMask(data, mask, data, 0, dataLength);
return [target, data];
}
/**
* Sends a close message to the other peer.
*
* @param {Number} [code] The status code component of the body
* @param {(String|Buffer)} [data] The message component of the body
* @param {Boolean} [mask=false] Specifies whether or not to mask the message
* @param {Function} [cb] Callback
* @public
*/
close(code, data, mask, cb) {
let buf;
if (code === undefined) {
buf = EMPTY_BUFFER;
} else if (typeof code !== 'number' || !isValidStatusCode(code)) {
throw new TypeError('First argument must be a valid error code number');
} else if (data === undefined || !data.length) {
buf = Buffer.allocUnsafe(2);
buf.writeUInt16BE(code, 0);
} else {
const length = Buffer.byteLength(data);
if (length > 123) {
throw new RangeError('The message must not be greater than 123 bytes');
}
buf = Buffer.allocUnsafe(2 + length);
buf.writeUInt16BE(code, 0);
if (typeof data === 'string') {
buf.write(data, 2);
} else if (isUint8Array(data)) {
buf.set(data, 2);
} else {
throw new TypeError('Second argument must be a string or a Uint8Array');
}
}
const options = {
[kByteLength]: buf.length,
fin: true,
generateMask: this._generateMask,
mask,
maskBuffer: this._maskBuffer,
opcode: 0x08,
readOnly: false,
rsv1: false
};
if (this._state !== DEFAULT) {
this.enqueue([this.dispatch, buf, false, options, cb]);
} else {
this.sendFrame(Sender.frame(buf, options), cb);
}
}
/**
* Sends a ping message to the other peer.
*
* @param {*} data The message to send
* @param {Boolean} [mask=false] Specifies whether or not to mask `data`
* @param {Function} [cb] Callback
* @public
*/
ping(data, mask, cb) {
let byteLength;
let readOnly;
if (typeof data === 'string') {
byteLength = Buffer.byteLength(data);
readOnly = false;
} else if (isBlob(data)) {
byteLength = data.size;
readOnly = false;
} else {
data = toBuffer(data);
byteLength = data.length;
readOnly = toBuffer.readOnly;
}
if (byteLength > 125) {
throw new RangeError('The data size must not be greater than 125 bytes');
}
const options = {
[kByteLength]: byteLength,
fin: true,
generateMask: this._generateMask,
mask,
maskBuffer: this._maskBuffer,
opcode: 0x09,
readOnly,
rsv1: false
};
if (isBlob(data)) {
if (this._state !== DEFAULT) {
this.enqueue([this.getBlobData, data, false, options, cb]);
} else {
this.getBlobData(data, false, options, cb);
}
} else if (this._state !== DEFAULT) {
this.enqueue([this.dispatch, data, false, options, cb]);
} else {
this.sendFrame(Sender.frame(data, options), cb);
}
}
/**
* Sends a pong message to the other peer.
*
* @param {*} data The message to send
* @param {Boolean} [mask=false] Specifies whether or not to mask `data`
* @param {Function} [cb] Callback
* @public
*/
pong(data, mask, cb) {
let byteLength;
let readOnly;
if (typeof data === 'string') {
byteLength = Buffer.byteLength(data);
readOnly = false;
} else if (isBlob(data)) {
byteLength = data.size;
readOnly = false;
} else {
data = toBuffer(data);
byteLength = data.length;
readOnly = toBuffer.readOnly;
}
if (byteLength > 125) {
throw new RangeError('The data size must not be greater than 125 bytes');
}
const options = {
[kByteLength]: byteLength,
fin: true,
generateMask: this._generateMask,
mask,
maskBuffer: this._maskBuffer,
opcode: 0x0a,
readOnly,
rsv1: false
};
if (isBlob(data)) {
if (this._state !== DEFAULT) {
this.enqueue([this.getBlobData, data, false, options, cb]);
} else {
this.getBlobData(data, false, options, cb);
}
} else if (this._state !== DEFAULT) {
this.enqueue([this.dispatch, data, false, options, cb]);
} else {
this.sendFrame(Sender.frame(data, options), cb);
}
}
/**
* Sends a data message to the other peer.
*
* @param {*} data The message to send
* @param {Object} options Options object
* @param {Boolean} [options.binary=false] Specifies whether `data` is binary
* or text
* @param {Boolean} [options.compress=false] Specifies whether or not to
* compress `data`
* @param {Boolean} [options.fin=false] Specifies whether the fragment is the
* last one
* @param {Boolean} [options.mask=false] Specifies whether or not to mask
* `data`
* @param {Function} [cb] Callback
* @public
*/
send(data, options, cb) {
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
let opcode = options.binary ? 2 : 1;
let rsv1 = options.compress;
let byteLength;
let readOnly;
if (typeof data === 'string') {
byteLength = Buffer.byteLength(data);
readOnly = false;
} else if (isBlob(data)) {
byteLength = data.size;
readOnly = false;
} else {
data = toBuffer(data);
byteLength = data.length;
readOnly = toBuffer.readOnly;
}
if (this._firstFragment) {
this._firstFragment = false;
if (
rsv1 &&
perMessageDeflate &&
perMessageDeflate.params[
perMessageDeflate._isServer
? 'server_no_context_takeover'
: 'client_no_context_takeover'
]
) {
rsv1 = byteLength >= perMessageDeflate._threshold;
}
this._compress = rsv1;
} else {
rsv1 = false;
opcode = 0;
}
if (options.fin) this._firstFragment = true;
const opts = {
[kByteLength]: byteLength,
fin: options.fin,
generateMask: this._generateMask,
mask: options.mask,
maskBuffer: this._maskBuffer,
opcode,
readOnly,
rsv1
};
if (isBlob(data)) {
if (this._state !== DEFAULT) {
this.enqueue([this.getBlobData, data, this._compress, opts, cb]);
} else {
this.getBlobData(data, this._compress, opts, cb);
}
} else if (this._state !== DEFAULT) {
this.enqueue([this.dispatch, data, this._compress, opts, cb]);
} else {
this.dispatch(data, this._compress, opts, cb);
}
}
/**
* Gets the contents of a blob as binary data.
*
* @param {Blob} blob The blob
* @param {Boolean} [compress=false] Specifies whether or not to compress
* the data
* @param {Object} options Options object
* @param {Boolean} [options.fin=false] Specifies whether or not to set the
* FIN bit
* @param {Function} [options.generateMask] The function used to generate the
* masking key
* @param {Boolean} [options.mask=false] Specifies whether or not to mask
* `data`
* @param {Buffer} [options.maskBuffer] The buffer used to store the masking
* key
* @param {Number} options.opcode The opcode
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
* modified
* @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
* RSV1 bit
* @param {Function} [cb] Callback
* @private
*/
getBlobData(blob, compress, options, cb) {
this._bufferedBytes += options[kByteLength];
this._state = GET_BLOB_DATA;
blob
.arrayBuffer()
.then((arrayBuffer) => {
if (this._socket.destroyed) {
const err = new Error(
'The socket was closed while the blob was being read'
);
//
// `callCallbacks` is called in the next tick to ensure that errors
// that might be thrown in the callbacks behave like errors thrown
// outside the promise chain.
//
process.nextTick(callCallbacks, this, err, cb);
return;
}
this._bufferedBytes -= options[kByteLength];
const data = toBuffer(arrayBuffer);
if (!compress) {
this._state = DEFAULT;
this.sendFrame(Sender.frame(data, options), cb);
this.dequeue();
} else {
this.dispatch(data, compress, options, cb);
}
})
.catch((err) => {
//
// `onError` is called in the next tick for the same reason that
// `callCallbacks` above is.
//
process.nextTick(onError, this, err, cb);
});
}
/**
* Dispatches a message.
*
* @param {(Buffer|String)} data The message to send
* @param {Boolean} [compress=false] Specifies whether or not to compress
* `data`
* @param {Object} options Options object
* @param {Boolean} [options.fin=false] Specifies whether or not to set the
* FIN bit
* @param {Function} [options.generateMask] The function used to generate the
* masking key
* @param {Boolean} [options.mask=false] Specifies whether or not to mask
* `data`
* @param {Buffer} [options.maskBuffer] The buffer used to store the masking
* key
* @param {Number} options.opcode The opcode
* @param {Boolean} [options.readOnly=false] Specifies whether `data` can be
* modified
* @param {Boolean} [options.rsv1=false] Specifies whether or not to set the
* RSV1 bit
* @param {Function} [cb] Callback
* @private
*/
dispatch(data, compress, options, cb) {
if (!compress) {
this.sendFrame(Sender.frame(data, options), cb);
return;
}
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
this._bufferedBytes += options[kByteLength];
this._state = DEFLATING;
perMessageDeflate.compress(data, options.fin, (_, buf) => {
if (this._socket.destroyed) {
const err = new Error(
'The socket was closed while data was being compressed'
);
callCallbacks(this, err, cb);
return;
}
this._bufferedBytes -= options[kByteLength];
this._state = DEFAULT;
options.readOnly = false;
this.sendFrame(Sender.frame(buf, options), cb);
this.dequeue();
});
}
/**
* Executes queued send operations.
*
* @private
*/
dequeue() {
while (this._state === DEFAULT && this._queue.length) {
const params = this._queue.shift();
this._bufferedBytes -= params[3][kByteLength];
Reflect.apply(params[0], this, params.slice(1));
}
}
/**
* Enqueues a send operation.
*
* @param {Array} params Send operation parameters.
* @private
*/
enqueue(params) {
this._bufferedBytes += params[3][kByteLength];
this._queue.push(params);
}
/**
* Sends a frame.
*
* @param {(Buffer | String)[]} list The frame to send
* @param {Function} [cb] Callback
* @private
*/
sendFrame(list, cb) {
if (list.length === 2) {
this._socket.cork();
this._socket.write(list[0]);
this._socket.write(list[1], cb);
this._socket.uncork();
} else {
this._socket.write(list[0], cb);
}
}
}
module.exports = Sender;
/**
* Calls queued callbacks with an error.
*
* @param {Sender} sender The `Sender` instance
* @param {Error} err The error to call the callbacks with
* @param {Function} [cb] The first callback
* @private
*/
function callCallbacks(sender, err, cb) {
if (typeof cb === 'function') cb(err);
for (let i = 0; i < sender._queue.length; i++) {
const params = sender._queue[i];
const callback = params[params.length - 1];
if (typeof callback === 'function') callback(err);
}
}
/**
* Handles a `Sender` error.
*
* @param {Sender} sender The `Sender` instance
* @param {Error} err The error
* @param {Function} [cb] The first pending callback
* @private
*/
function onError(sender, err, cb) {
callCallbacks(sender, err, cb);
sender.onerror(err);
}