WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const util_1 = require("../util");
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'prefer-promise-reject-errors',
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'Require using Error objects as Promise rejection reasons',
|
||||
extendsBaseRule: true,
|
||||
recommended: 'recommended',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
messages: {
|
||||
rejectAnError: 'Expected the Promise rejection reason to be an Error.',
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allow: {
|
||||
...util_1.typeOrValueSpecifiersSchema,
|
||||
description: 'Type specifiers that can be used as Promise rejection reasons.',
|
||||
},
|
||||
allowEmptyReject: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow calls to `Promise.reject()` with no arguments.',
|
||||
},
|
||||
allowThrowingAny: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to always allow throwing values typed as `any`.',
|
||||
},
|
||||
allowThrowingUnknown: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to always allow throwing values typed as `unknown`.',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [
|
||||
{
|
||||
allow: [],
|
||||
allowEmptyReject: false,
|
||||
allowThrowingAny: false,
|
||||
allowThrowingUnknown: false,
|
||||
},
|
||||
],
|
||||
create(context, [options]) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
function checkRejectCall(callExpression) {
|
||||
const argument = callExpression.arguments.at(0);
|
||||
if (argument) {
|
||||
const type = services.getTypeAtLocation(argument);
|
||||
if ((0, util_1.typeMatchesSomeSpecifier)(type, options.allow, services.program)) {
|
||||
return;
|
||||
}
|
||||
if (options.allowThrowingAny && (0, util_1.isTypeAnyType)(type)) {
|
||||
return;
|
||||
}
|
||||
if (options.allowThrowingUnknown && (0, util_1.isTypeUnknownType)(type)) {
|
||||
return;
|
||||
}
|
||||
if ((0, util_1.isErrorLike)(services.program, type) ||
|
||||
(0, util_1.isReadonlyErrorLike)(services.program, type)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (options.allowEmptyReject) {
|
||||
return;
|
||||
}
|
||||
context.report({
|
||||
node: callExpression,
|
||||
messageId: 'rejectAnError',
|
||||
});
|
||||
}
|
||||
function typeAtLocationIsLikePromise(node) {
|
||||
const type = services.getTypeAtLocation(node);
|
||||
return ((0, util_1.isPromiseConstructorLike)(services.program, type) ||
|
||||
(0, util_1.isPromiseLike)(services.program, type));
|
||||
}
|
||||
return {
|
||||
CallExpression(node) {
|
||||
const callee = (0, util_1.skipChainExpression)(node.callee);
|
||||
if (callee.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
|
||||
return;
|
||||
}
|
||||
if (!(0, util_1.isStaticMemberAccessOfValue)(callee, context, 'reject') ||
|
||||
!typeAtLocationIsLikePromise(callee.object)) {
|
||||
return;
|
||||
}
|
||||
checkRejectCall(node);
|
||||
},
|
||||
NewExpression(node) {
|
||||
const callee = (0, util_1.skipChainExpression)(node.callee);
|
||||
if (!(0, util_1.isPromiseConstructorLike)(services.program, services.getTypeAtLocation(callee))) {
|
||||
return;
|
||||
}
|
||||
const executor = node.arguments.at(0);
|
||||
if (!executor || !(0, util_1.isFunction)(executor)) {
|
||||
return;
|
||||
}
|
||||
const rejectParamNode = executor.params.at(1);
|
||||
if (!rejectParamNode || !(0, util_1.isIdentifier)(rejectParamNode)) {
|
||||
return;
|
||||
}
|
||||
// reject param is always present in variables declared by executor
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const rejectVariable = context.sourceCode
|
||||
.getDeclaredVariables(executor)
|
||||
.find(variable => variable.identifiers.includes(rejectParamNode));
|
||||
rejectVariable.references.forEach(ref => {
|
||||
if (ref.identifier.parent.type !== utils_1.AST_NODE_TYPES.CallExpression ||
|
||||
ref.identifier !== ref.identifier.parent.callee) {
|
||||
return;
|
||||
}
|
||||
checkRejectCall(ref.identifier.parent);
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
export { __rewriteRelativeImportExtension as _ } from "tslib";
|
||||
@@ -0,0 +1,241 @@
|
||||
'use strict'
|
||||
const test = require('tape')
|
||||
const pino = require('../browser')
|
||||
|
||||
test('set the level by string', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.level = 'error'
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('set the level by string. init with silent', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
level: 'silent',
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.level = 'error'
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('set the level by string. init with silent and transmit', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
level: 'silent',
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
},
|
||||
transmit: {
|
||||
send () {}
|
||||
}
|
||||
})
|
||||
|
||||
instance.level = 'error'
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('set the level via constructor', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 50,
|
||||
msg: 'this is an error'
|
||||
},
|
||||
{
|
||||
level: 60,
|
||||
msg: 'this is fatal'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
level: 'error',
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.info('hello world')
|
||||
instance.error('this is an error')
|
||||
instance.fatal('this is fatal')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('set custom level and use it', ({ end, same, is }) => {
|
||||
const expected = [
|
||||
{
|
||||
level: 31,
|
||||
msg: 'this is a custom level'
|
||||
}
|
||||
]
|
||||
const instance = pino({
|
||||
customLevels: {
|
||||
success: 31
|
||||
},
|
||||
browser: {
|
||||
write (actual) {
|
||||
checkLogObjects(is, same, actual, expected.shift())
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.success('this is a custom level')
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('the wrong level throws', ({ end, throws }) => {
|
||||
const instance = pino()
|
||||
throws(() => {
|
||||
instance.level = 'kaboom'
|
||||
})
|
||||
end()
|
||||
})
|
||||
|
||||
test('the wrong level by number throws', ({ end, throws }) => {
|
||||
const instance = pino()
|
||||
throws(() => {
|
||||
instance.levelVal = 55
|
||||
})
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposes level string mappings', ({ end, is }) => {
|
||||
is(pino.levels.values.error, 50)
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposes level number mappings', ({ end, is }) => {
|
||||
is(pino.levels.labels[50], 'error')
|
||||
end()
|
||||
})
|
||||
|
||||
test('returns level integer', ({ end, is }) => {
|
||||
const instance = pino({ level: 'error' })
|
||||
is(instance.levelVal, 50)
|
||||
end()
|
||||
})
|
||||
|
||||
test('silent level via constructor', ({ end, fail }) => {
|
||||
const instance = pino({
|
||||
level: 'silent',
|
||||
browser: {
|
||||
write () {
|
||||
fail('no data should be logged')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Object.keys(pino.levels.values).forEach((level) => {
|
||||
instance[level]('hello world')
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('silent level by string', ({ end, fail }) => {
|
||||
const instance = pino({
|
||||
browser: {
|
||||
write () {
|
||||
fail('no data should be logged')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
instance.level = 'silent'
|
||||
|
||||
Object.keys(pino.levels.values).forEach((level) => {
|
||||
instance[level]('hello world')
|
||||
})
|
||||
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposed levels', ({ end, same }) => {
|
||||
same(Object.keys(pino.levels.values), [
|
||||
'fatal',
|
||||
'error',
|
||||
'warn',
|
||||
'info',
|
||||
'debug',
|
||||
'trace'
|
||||
])
|
||||
end()
|
||||
})
|
||||
|
||||
test('exposed labels', ({ end, same }) => {
|
||||
same(Object.keys(pino.levels.labels), [
|
||||
'10',
|
||||
'20',
|
||||
'30',
|
||||
'40',
|
||||
'50',
|
||||
'60'
|
||||
])
|
||||
end()
|
||||
})
|
||||
|
||||
function checkLogObjects (is, same, actual, expected) {
|
||||
is(actual.time <= Date.now(), true, 'time is greater than Date.now()')
|
||||
|
||||
const actualCopy = Object.assign({}, actual)
|
||||
const expectedCopy = Object.assign({}, expected)
|
||||
delete actualCopy.time
|
||||
delete expectedCopy.time
|
||||
|
||||
same(actualCopy, expectedCopy)
|
||||
}
|
||||
@@ -0,0 +1,521 @@
|
||||
# noble-hashes
|
||||
|
||||
Audited & minimal JS implementation of hash functions, MACs and KDFs.
|
||||
|
||||
- 🔒 [**Audited**](#security) by an independent security firm
|
||||
- 🔻 Tree-shakeable: unused code is excluded from your builds
|
||||
- 🏎 Fast: hand-optimized for caveats of JS engines
|
||||
- 🔍 Reliable: chained / sliding window / DoS tests and fuzzing ensure correctness
|
||||
- 🔁 No unrolled loops: makes it easier to verify and reduces source code size up to 5x
|
||||
- 🦘 Includes SHA, RIPEMD, BLAKE, HMAC, HKDF, PBKDF, Scrypt, Argon2 & KangarooTwelve
|
||||
- 🪶 48KB for everything, 4.8KB (2.36KB gzipped) for single-hash build
|
||||
|
||||
Take a glance at [GitHub Discussions](https://github.com/paulmillr/noble-hashes/discussions) for questions and support.
|
||||
The library's initial development was funded by [Ethereum Foundation](https://ethereum.org/).
|
||||
|
||||
### This library belongs to _noble_ cryptography
|
||||
|
||||
> **noble cryptography** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
||||
|
||||
- Zero or minimal dependencies
|
||||
- Highly readable TypeScript / JS code
|
||||
- PGP-signed releases and transparent NPM builds
|
||||
- All libraries:
|
||||
[ciphers](https://github.com/paulmillr/noble-ciphers),
|
||||
[curves](https://github.com/paulmillr/noble-curves),
|
||||
[hashes](https://github.com/paulmillr/noble-hashes),
|
||||
[post-quantum](https://github.com/paulmillr/noble-post-quantum),
|
||||
4kb [secp256k1](https://github.com/paulmillr/noble-secp256k1) /
|
||||
[ed25519](https://github.com/paulmillr/noble-ed25519)
|
||||
- [Check out homepage](https://paulmillr.com/noble/)
|
||||
for reading resources, documentation and apps built with noble
|
||||
|
||||
## Usage
|
||||
|
||||
> `npm install @noble/hashes`
|
||||
|
||||
> `deno add jsr:@noble/hashes`
|
||||
|
||||
> `deno doc jsr:@noble/hashes` # command-line documentation
|
||||
|
||||
We support all major platforms and runtimes.
|
||||
For React Native, you may need a [polyfill for getRandomValues](https://github.com/LinusU/react-native-get-random-values).
|
||||
A standalone file [noble-hashes.js](https://github.com/paulmillr/noble-hashes/releases) is also available.
|
||||
|
||||
```js
|
||||
// import * from '@noble/hashes'; // Error: use sub-imports, to ensure small app size
|
||||
import { sha256 } from '@noble/hashes/sha2.js'; // ESM & Common.js
|
||||
sha256(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // returns Uint8Array
|
||||
|
||||
// Available modules
|
||||
import { sha256, sha384, sha512, sha224, sha512_224, sha512_256 } from '@noble/hashes/sha2.js';
|
||||
import { sha3_256, sha3_512, keccak_256, keccak_512, shake128, shake256 } from '@noble/hashes/sha3.js';
|
||||
import { cshake256, turboshake256, kmac256, tuplehash256, k12, m14, keccakprg } from '@noble/hashes/sha3-addons.js';
|
||||
import { blake3 } from '@noble/hashes/blake3.js';
|
||||
import { blake2b, blake2s } from '@noble/hashes/blake2.js';
|
||||
import { blake256, blake512 } from '@noble/hashes/blake1.js';
|
||||
import { sha1, md5, ripemd160 } from '@noble/hashes/legacy.js';
|
||||
import { hmac } from '@noble/hashes/hmac.js';
|
||||
import { hkdf } from '@noble/hashes/hkdf.js';
|
||||
import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js';
|
||||
import { scrypt, scryptAsync } from '@noble/hashes/scrypt.js';
|
||||
import { argon2d, argon2i, argon2id } from '@noble/hashes/argon2.js';
|
||||
import * as utils from '@noble/hashes/utils'; // bytesToHex, bytesToUtf8, concatBytes...
|
||||
```
|
||||
|
||||
- [sha2: sha256, sha384, sha512](#sha2-sha256-sha384-sha512-and-others)
|
||||
- [sha3: FIPS, SHAKE, Keccak](#sha3-fips-shake-keccak)
|
||||
- [sha3-addons: cSHAKE, KMAC, K12, M14, TurboSHAKE](#sha3-addons-cshake-kmac-k12-m14-turboshake)
|
||||
- [blake, blake2, blake3](#blake-blake2-blake3) | [legacy: sha1, md5, ripemd160](#legacy-sha1-md5-ripemd160)
|
||||
- MACs: [hmac](#hmac) | [sha3-addons kmac](#sha3-addons-cshake-kmac-k12-m14-turboshake) | [blake3 key mode](#blake2b-blake2s-blake3)
|
||||
- KDFs: [hkdf](#hkdf) | [pbkdf2](#pbkdf2) | [scrypt](#scrypt) | [argon2](#argon2)
|
||||
- [utils](#utils)
|
||||
- [Security](#security) | [Speed](#speed) | [Contributing & testing](#contributing--testing) | [License](#license)
|
||||
|
||||
### Implementations
|
||||
|
||||
Hash functions:
|
||||
|
||||
- `sha256()`: receive & return `Uint8Array`
|
||||
- `sha256.create().update(a).update(b).digest()`: support partial updates
|
||||
- `blake3.create({ context: 'e', dkLen: 32 })`: sometimes have options
|
||||
- support little-endian architecture; also experimentally big-endian
|
||||
- can hash up to 4GB per chunk, with any amount of chunks
|
||||
|
||||
#### sha2: sha256, sha384, sha512 and others
|
||||
|
||||
```typescript
|
||||
import { sha224, sha256, sha384, sha512, sha512_224, sha512_256 } from '@noble/hashes/sha2.js';
|
||||
const res = sha256(Uint8Array.from([0xbc])); // basic
|
||||
for (let hash of [sha256, sha384, sha512, sha224, sha512_224, sha512_256]) {
|
||||
const arr = Uint8Array.from([0x10, 0x20, 0x30]);
|
||||
const a = hash(arr);
|
||||
const b = hash.create().update(arr).digest();
|
||||
}
|
||||
```
|
||||
|
||||
See [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
||||
[the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf).
|
||||
|
||||
#### sha3: FIPS, SHAKE, Keccak
|
||||
|
||||
```typescript
|
||||
import {
|
||||
keccak_224, keccak_256, keccak_384, keccak_512,
|
||||
sha3_224, sha3_256, sha3_384, sha3_512,
|
||||
shake128, shake256,
|
||||
} from '@noble/hashes/sha3.js';
|
||||
for (let hash of [
|
||||
sha3_224, sha3_256, sha3_384, sha3_512,
|
||||
keccak_224, keccak_256, keccak_384, keccak_512,
|
||||
]) {
|
||||
const arr = Uint8Array.from([0x10, 0x20, 0x30]);
|
||||
const a = hash(arr);
|
||||
const b = hash.create().update(arr).digest();
|
||||
}
|
||||
const shka = shake128(Uint8Array.from([0x10]), { dkLen: 512 });
|
||||
const shkb = shake256(Uint8Array.from([0x30]), { dkLen: 512 });
|
||||
```
|
||||
|
||||
See [FIPS-202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf),
|
||||
[Website](https://keccak.team/keccak.html).
|
||||
|
||||
Check out [the differences between SHA-3 and Keccak](https://crypto.stackexchange.com/questions/15727/what-are-the-key-differences-between-the-draft-sha-3-standard-and-the-keccak-sub)
|
||||
|
||||
#### sha3-addons: cSHAKE, KMAC, K12, M14, TurboSHAKE
|
||||
|
||||
```typescript
|
||||
import {
|
||||
cshake128, cshake256,
|
||||
k12,
|
||||
keccakprg,
|
||||
kmac128, kmac256,
|
||||
m14,
|
||||
parallelhash256,
|
||||
tuplehash256,
|
||||
turboshake128, turboshake256
|
||||
} from '@noble/hashes/sha3-addons.js';
|
||||
const data = Uint8Array.from([0x10, 0x20, 0x30]);
|
||||
const ec1 = cshake128(data, { personalization: 'def' });
|
||||
const ec2 = cshake256(data, { personalization: 'def' });
|
||||
const et1 = turboshake128(data);
|
||||
const et2 = turboshake256(data, { D: 0x05 });
|
||||
// tuplehash(['ab', 'c']) !== tuplehash(['a', 'bc']) !== tuplehash([data])
|
||||
const et3 = tuplehash256([utf8ToBytes('ab'), utf8ToBytes('c')]);
|
||||
// Not parallel in JS (similar to blake3 / k12), added for compat
|
||||
const ep1 = parallelhash256(data, { blockLen: 8 });
|
||||
const kk = Uint8Array.from([0xca]);
|
||||
const ek10 = kmac128(kk, data);
|
||||
const ek11 = kmac256(kk, data);
|
||||
const ek12 = k12(data);
|
||||
const ek13 = m14(data);
|
||||
// pseudo-random generator, first argument is capacity. XKCP recommends 254 bits capacity for 128-bit security strength.
|
||||
// * with a capacity of 254 bits.
|
||||
const p = keccakprg(254);
|
||||
p.feed('test');
|
||||
const rand1b = p.fetch(1);
|
||||
```
|
||||
|
||||
- Full [NIST SP 800-185](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf):
|
||||
cSHAKE, KMAC, TupleHash, ParallelHash + XOF variants
|
||||
- [Reduced-round Keccak](https://datatracker.ietf.org/doc/draft-irtf-cfrg-kangarootwelve/):
|
||||
- 🦘 K12 aka KangarooTwelve
|
||||
- M14 aka MarsupilamiFourteen
|
||||
- TurboSHAKE
|
||||
- [KeccakPRG](https://keccak.team/files/CSF-0.1.pdf): Pseudo-random generator based on Keccak
|
||||
|
||||
#### blake, blake2, blake3
|
||||
|
||||
```typescript
|
||||
import { blake224, blake256, blake384, blake512 } from '@noble/hashes/blake1.js';
|
||||
import { blake2b, blake2s } from '@noble/hashes/blake2.js';
|
||||
import { blake3 } from '@noble/hashes/blake3.js';
|
||||
|
||||
for (let hash of [
|
||||
blake224, blake256, blake384, blake512,
|
||||
blake2b, blake2s, blake3
|
||||
]) {
|
||||
const arr = Uint8Array.from([0x10, 0x20, 0x30]);
|
||||
const a = hash(arr);
|
||||
const b = hash.create().update(arr).digest();
|
||||
}
|
||||
|
||||
// blake2 advanced usage
|
||||
const ab = Uint8Array.from([0x01]);
|
||||
blake2s(ab);
|
||||
blake2s(ab, { key: new Uint8Array(32) });
|
||||
blake2s(ab, { personalization: 'pers1234' });
|
||||
blake2s(ab, { salt: 'salt1234' });
|
||||
blake2b(ab);
|
||||
blake2b(ab, { key: new Uint8Array(64) });
|
||||
blake2b(ab, { personalization: 'pers1234pers1234' });
|
||||
blake2b(ab, { salt: 'salt1234salt1234' });
|
||||
|
||||
// blake3 advanced usage
|
||||
blake3(ab);
|
||||
blake3(ab, { dkLen: 256 });
|
||||
blake3(ab, { key: new Uint8Array(32) });
|
||||
blake3(ab, { context: 'application-name' });
|
||||
```
|
||||
|
||||
- Blake1 is legacy hash, one of SHA3 proposals. It is rarely used anywhere. See [pdf](https://www.aumasson.jp/blake/blake.pdf).
|
||||
- Blake2 is popular fast hash. blake2b focuses on 64-bit platforms while blake2s is for 8-bit to 32-bit ones. See [RFC 7693](https://datatracker.ietf.org/doc/html/rfc7693), [Website](https://www.blake2.net)
|
||||
- Blake3 is faster, reduced-round blake2. See [Website & specs](https://blake3.io)
|
||||
|
||||
#### legacy: sha1, md5, ripemd160
|
||||
|
||||
SHA1 (RFC 3174), MD5 (RFC 1321) and RIPEMD160 (RFC 2286) legacy, weak hash functions.
|
||||
Don't use them in a new protocol. What "weak" means:
|
||||
|
||||
- Collisions can be made with 2^18 effort in MD5, 2^60 in SHA1, 2^80 in RIPEMD160.
|
||||
- No practical pre-image attacks (only theoretical, 2^123.4)
|
||||
- HMAC seems kinda ok: https://datatracker.ietf.org/doc/html/rfc6151
|
||||
|
||||
```typescript
|
||||
import { md5, ripemd160, sha1 } from '@noble/hashes/legacy.js';
|
||||
for (let hash of [md5, ripemd160, sha1]) {
|
||||
const arr = Uint8Array.from([0x10, 0x20, 0x30]);
|
||||
const a = hash(arr);
|
||||
const b = hash.create().update(arr).digest();
|
||||
}
|
||||
```
|
||||
|
||||
#### hmac
|
||||
|
||||
```typescript
|
||||
import { hmac } from '@noble/hashes/hmac.js';
|
||||
import { sha256 } from '@noble/hashes/sha2.js';
|
||||
const key = new Uint8Array(32).fill(1);
|
||||
const msg = new Uint8Array(32).fill(2);
|
||||
const mac1 = hmac(sha256, key, msg);
|
||||
const mac2 = hmac.create(sha256, key).update(msg).digest();
|
||||
```
|
||||
|
||||
Matches [RFC 2104](https://datatracker.ietf.org/doc/html/rfc2104).
|
||||
|
||||
#### hkdf
|
||||
|
||||
```typescript
|
||||
import { hkdf } from '@noble/hashes/hkdf.js';
|
||||
import { randomBytes } from '@noble/hashes/utils.js';
|
||||
import { sha256 } from '@noble/hashes/sha2.js';
|
||||
const inputKey = randomBytes(32);
|
||||
const salt = randomBytes(32);
|
||||
const info = 'application-key';
|
||||
const hk1 = hkdf(sha256, inputKey, salt, info, 32);
|
||||
|
||||
// == same as
|
||||
import { extract, expand } from '@noble/hashes/hkdf.js';
|
||||
import { sha256 } from '@noble/hashes/sha2.js';
|
||||
const prk = extract(sha256, inputKey, salt);
|
||||
const hk2 = expand(sha256, prk, info, 32);
|
||||
```
|
||||
|
||||
Matches [RFC 5869](https://datatracker.ietf.org/doc/html/rfc5869).
|
||||
|
||||
#### pbkdf2
|
||||
|
||||
```typescript
|
||||
import { pbkdf2, pbkdf2Async } from '@noble/hashes/pbkdf2.js';
|
||||
import { sha256 } from '@noble/hashes/sha2.js';
|
||||
const pbkey1 = pbkdf2(sha256, 'password', 'salt', { c: 32, dkLen: 32 });
|
||||
const pbkey2 = await pbkdf2Async(sha256, 'password', 'salt', { c: 32, dkLen: 32 });
|
||||
const pbkey3 = await pbkdf2Async(sha256, Uint8Array.from([1, 2, 3]), Uint8Array.from([4, 5, 6]), {
|
||||
c: 32,
|
||||
dkLen: 32,
|
||||
});
|
||||
```
|
||||
|
||||
Matches [RFC 2898](https://datatracker.ietf.org/doc/html/rfc2898).
|
||||
|
||||
#### scrypt
|
||||
|
||||
```typescript
|
||||
import { scrypt, scryptAsync } from '@noble/hashes/scrypt.js';
|
||||
const scr1 = scrypt('password', 'salt', { N: 2 ** 16, r: 8, p: 1, dkLen: 32 });
|
||||
const scr2 = await scryptAsync('password', 'salt', { N: 2 ** 16, r: 8, p: 1, dkLen: 32 });
|
||||
const scr3 = await scryptAsync(Uint8Array.from([1, 2, 3]), Uint8Array.from([4, 5, 6]), {
|
||||
N: 2 ** 17,
|
||||
r: 8,
|
||||
p: 1,
|
||||
dkLen: 32,
|
||||
onProgress(percentage) {
|
||||
console.log('progress', percentage);
|
||||
},
|
||||
maxmem: 2 ** 32 + 128 * 8 * 1, // N * r * p * 128 + (128*r*p)
|
||||
});
|
||||
```
|
||||
|
||||
Conforms to [RFC 7914](https://datatracker.ietf.org/doc/html/rfc7914),
|
||||
[Website](https://www.tarsnap.com/scrypt.html)
|
||||
|
||||
- `N, r, p` are work factors. To understand them, see [the blog post](https://blog.filippo.io/the-scrypt-parameters/).
|
||||
`r: 8, p: 1` are common. JS doesn't support parallelization, making increasing p meaningless.
|
||||
- `dkLen` is the length of output bytes e.g. `32` or `64`
|
||||
- `onProgress` can be used with async version of the function to report progress to a user.
|
||||
- `maxmem` prevents DoS and is limited to `1GB + 1KB` (`2**30 + 2**10`), but can be adjusted using formula: `N * r * p * 128 + (128 * r * p)`
|
||||
|
||||
Time it takes to derive Scrypt key under different values of N (2\*\*N) on Apple M4 (mobile phones can be 1x-4x slower):
|
||||
|
||||
| N pow | Time | RAM |
|
||||
| ----- | ---- | ----- |
|
||||
| 16 | 0.1s | 64MB |
|
||||
| 17 | 0.2s | 128MB |
|
||||
| 18 | 0.4s | 256MB |
|
||||
| 19 | 0.8s | 512MB |
|
||||
| 20 | 1.5s | 1GB |
|
||||
| 21 | 3.1s | 2GB |
|
||||
| 22 | 6.2s | 4GB |
|
||||
| 23 | 13s | 8GB |
|
||||
| 24 | 27s | 16GB |
|
||||
|
||||
> [!NOTE]
|
||||
> We support N larger than `2**20` where available, however,
|
||||
> not all JS engines support >= 2GB ArrayBuffer-s.
|
||||
> When using such N, you'll need to manually adjust `maxmem`, using formula above.
|
||||
> Other JS implementations don't support large N-s.
|
||||
|
||||
#### argon2
|
||||
|
||||
```ts
|
||||
import { argon2d, argon2i, argon2id } from '@noble/hashes/argon2.js';
|
||||
const arg1 = argon2id('password', 'saltsalt', { t: 2, m: 65536, p: 1, maxmem: 2 ** 32 - 1 });
|
||||
```
|
||||
|
||||
Argon2 [RFC 9106](https://datatracker.ietf.org/doc/html/rfc9106) implementation.
|
||||
|
||||
> [!WARNING]
|
||||
> Argon2 can't be fast in JS, because there is no fast Uint64Array.
|
||||
> It is suggested to use [Scrypt](#scrypt) instead.
|
||||
> Being 5x slower than native code means brute-forcing attackers have bigger advantage.
|
||||
|
||||
#### utils
|
||||
|
||||
```typescript
|
||||
import { bytesToHex as toHex, randomBytes } from '@noble/hashes/utils';
|
||||
console.log(toHex(randomBytes(32)));
|
||||
```
|
||||
|
||||
- `bytesToHex` will convert `Uint8Array` to a hex string
|
||||
- `randomBytes(bytes)` will produce cryptographically secure random `Uint8Array` of length `bytes`
|
||||
|
||||
## Security
|
||||
|
||||
The library has been independently audited:
|
||||
|
||||
- at version 1.0.0, in Jan 2022, by [Cure53](https://cure53.de)
|
||||
- PDFs: [website](https://cure53.de/pentest-report_hashing-libs.pdf), [in-repo](./audit/2022-01-05-cure53-audit-nbl2.pdf)
|
||||
- [Changes since audit](https://github.com/paulmillr/noble-hashes/compare/1.0.0..main).
|
||||
- Scope: everything, besides `blake3`, `sha3-addons`, `sha1` and `argon2`, which have not been audited
|
||||
- The audit has been funded by [Ethereum Foundation](https://ethereum.org/en/) with help of [Nomic Labs](https://nomiclabs.io)
|
||||
|
||||
It is tested against property-based, cross-library and Wycheproof vectors,
|
||||
and is being fuzzed in [the separate repo](https://github.com/paulmillr/fuzzing).
|
||||
|
||||
If you see anything unusual: investigate and report.
|
||||
|
||||
### Constant-timeness
|
||||
|
||||
We're targetting algorithmic constant time. _JIT-compiler_ and _Garbage Collector_ make "constant time"
|
||||
extremely hard to achieve [timing attack](https://en.wikipedia.org/wiki/Timing_attack) resistance
|
||||
in a scripting language. Which means _any other JS library can't have
|
||||
constant-timeness_. Even statically typed Rust, a language without GC,
|
||||
[makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security)
|
||||
for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones.
|
||||
Use low-level libraries & languages.
|
||||
|
||||
### Memory dumping
|
||||
|
||||
The library shares state buffers between hash
|
||||
function calls. The buffers are zeroed-out after each call. However, if an attacker
|
||||
can read application memory, you are doomed in any case:
|
||||
|
||||
- At some point, input will be a string and strings are immutable in JS:
|
||||
there is no way to overwrite them with zeros. For example: deriving
|
||||
key from `scrypt(password, salt)` where password and salt are strings
|
||||
- Input from a file will stay in file buffers
|
||||
- Input / output will be re-used multiple times in application which means it could stay in memory
|
||||
- `await anything()` will always write all internal variables (including numbers)
|
||||
to memory. With async functions / Promises there are no guarantees when the code
|
||||
chunk would be executed. Which means attacker can have plenty of time to read data from memory
|
||||
- There is no way to guarantee anything about zeroing sensitive data without
|
||||
complex tests-suite which will dump process memory and verify that there is
|
||||
no sensitive data left. For JS it means testing all browsers (incl. mobile),
|
||||
which is complex. And of course it will be useless without using the same
|
||||
test-suite in the actual application that consumes the library
|
||||
|
||||
### Supply chain security
|
||||
|
||||
- **Commits** are signed with PGP keys, to prevent forgery. Make sure to verify commit signatures
|
||||
- **Releases** are transparent and built on GitHub CI. Make sure to verify [provenance](https://docs.npmjs.com/generating-provenance-statements) logs
|
||||
- Use GitHub CLI to verify single-file builds:
|
||||
`gh attestation verify --owner paulmillr noble-hashes.js`
|
||||
- **Rare releasing** is followed to ensure less re-audit need for end-users
|
||||
- **Dependencies** are minimized and locked-down: any dependency could get hacked and users will be downloading malware with every install.
|
||||
- We make sure to use as few dependencies as possible
|
||||
- Automatic dep updates are prevented by locking-down version ranges; diffs are checked with `npm-diff`
|
||||
- **Dev Dependencies** are disabled for end-users; they are only used to develop / build the source code
|
||||
|
||||
For this package, there are 0 dependencies; and a few dev dependencies:
|
||||
|
||||
- micro-bmark, micro-should and jsbt are used for benchmarking / testing / build tooling and developed by the same author
|
||||
- prettier, fast-check and typescript are used for code quality / test generation / ts compilation. It's hard to audit their source code thoroughly and fully because of their size
|
||||
|
||||
### Randomness
|
||||
|
||||
We're deferring to built-in
|
||||
[crypto.getRandomValues](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues)
|
||||
which is considered cryptographically secure (CSPRNG).
|
||||
|
||||
In the past, browsers had bugs that made it weak: it may happen again.
|
||||
Implementing a userspace CSPRNG to get resilient to the weakness
|
||||
is even worse: there is no reliable userspace source of quality entropy.
|
||||
|
||||
### Quantum computers
|
||||
|
||||
Cryptographically relevant quantum computer, if built, will allow to
|
||||
utilize Grover's algorithm to break hashes in 2^n/2 operations, instead of 2^n.
|
||||
|
||||
This means SHA256 should be replaced with SHA512, SHA3-256 with SHA3-512, SHAKE128 with SHAKE256 etc.
|
||||
|
||||
Australian ASD prohibits SHA256 and similar hashes [after 2030](https://www.cyber.gov.au/resources-business-and-government/essential-cyber-security/ism/cyber-security-guidelines/guidelines-cryptography).
|
||||
|
||||
## Speed
|
||||
|
||||
```sh
|
||||
npm run bench:install && npm run bench
|
||||
```
|
||||
|
||||
Benchmarks measured on Apple M4.
|
||||
|
||||
```
|
||||
# 32B
|
||||
sha256 x 1,968,503 ops/sec @ 508ns/op
|
||||
sha512 x 740,740 ops/sec @ 1μs/op
|
||||
sha3_256 x 287,686 ops/sec @ 3μs/op
|
||||
sha3_512 x 288,267 ops/sec @ 3μs/op
|
||||
k12 x 476,190 ops/sec @ 2μs/op
|
||||
m14 x 423,190 ops/sec @ 2μs/op
|
||||
blake2b x 464,252 ops/sec @ 2μs/op
|
||||
blake2s x 766,871 ops/sec @ 1μs/op
|
||||
blake3 x 879,507 ops/sec @ 1μs/op
|
||||
|
||||
# 1MB
|
||||
sha256 x 331 ops/sec @ 3ms/op
|
||||
sha512 x 129 ops/sec @ 7ms/op
|
||||
sha3_256 x 38 ops/sec @ 25ms/op
|
||||
sha3_512 x 20 ops/sec @ 47ms/op
|
||||
k12 x 88 ops/sec @ 11ms/op
|
||||
m14 x 62 ops/sec @ 15ms/op
|
||||
blake2b x 69 ops/sec @ 14ms/op
|
||||
blake2s x 57 ops/sec @ 17ms/op
|
||||
blake3 x 72 ops/sec @ 13ms/op
|
||||
|
||||
# MAC
|
||||
hmac(sha256) x 599,880 ops/sec @ 1μs/op
|
||||
hmac(sha512) x 197,122 ops/sec @ 5μs/op
|
||||
kmac256 x 87,981 ops/sec @ 11μs/op
|
||||
blake3(key) x 796,812 ops/sec @ 1μs/op
|
||||
|
||||
# KDF
|
||||
hkdf(sha256) x 259,942 ops/sec @ 3μs/op
|
||||
blake3(context) x 424,808 ops/sec @ 2μs/op
|
||||
pbkdf2(sha256, c: 2 ** 18) x 5 ops/sec @ 197ms/op
|
||||
pbkdf2(sha512, c: 2 ** 18) x 1 ops/sec @ 630ms/op
|
||||
scrypt(n: 2 ** 18, r: 8, p: 1) x 2 ops/sec @ 400ms/op
|
||||
argon2id(t: 1, m: 256MB) 2881ms
|
||||
```
|
||||
|
||||
Compare to native node.js implementation that uses C bindings instead of pure-js code:
|
||||
|
||||
```
|
||||
# native (node) 32B
|
||||
sha256 x 2,267,573 ops/sec
|
||||
sha512 x 983,284 ops/sec
|
||||
sha3_256 x 1,522,070 ops/sec
|
||||
blake2b x 1,512,859 ops/sec
|
||||
blake2s x 1,821,493 ops/sec
|
||||
hmac(sha256) x 1,085,776 ops/sec
|
||||
hkdf(sha256) x 312,109 ops/sec
|
||||
# native (node) KDF
|
||||
pbkdf2(sha256, c: 2 ** 18) x 5 ops/sec @ 197ms/op
|
||||
pbkdf2(sha512, c: 2 ** 18) x 1 ops/sec @ 630ms/op
|
||||
scrypt(n: 2 ** 18, r: 8, p: 1) x 2 ops/sec @ 378ms/op
|
||||
```
|
||||
|
||||
It is possible to [make this library 4x+ faster](./benchmark/README.md) by
|
||||
_doing code generation of full loop unrolls_. We've decided against it. Reasons:
|
||||
|
||||
- the library must be auditable, with minimum amount of code, and zero dependencies
|
||||
- most method invocations with the lib are going to be something like hashing 32b to 64kb of data
|
||||
- hashing big inputs is 10x faster with low-level languages, which means you should probably pick 'em instead
|
||||
|
||||
The current performance is good enough when compared to other projects; SHA256 takes only 900 nanoseconds to run.
|
||||
|
||||
## Contributing & testing
|
||||
|
||||
`test/misc` directory contains implementations of loop unrolling and md5.
|
||||
|
||||
- `npm install && npm run build && npm test` will build the code and run tests.
|
||||
- `npm run lint` / `npm run format` will run linter / fix linter issues.
|
||||
- `npm run bench` will run benchmarks, which may need their deps first (`npm run bench:install`)
|
||||
- `npm run build:release` will build single file
|
||||
- There is **additional** 20-min DoS test `npm run test:dos` and 2-hour "big" multicore test `npm run test:big`.
|
||||
See [our approach to testing](./test/README.md)
|
||||
|
||||
Additional resources:
|
||||
|
||||
- NTT hashes are outside of scope of the library. You can view some of them in different repos:
|
||||
- [Pedersen in micro-zk-proofs](https://github.com/paulmillr/micro-zk-proofs/blob/1ed5ce1253583b2e540eef7f3477fb52bf5344ff/src/pedersen.ts)
|
||||
- [Poseidon in noble-curves](https://github.com/paulmillr/noble-curves/blob/3d124dd3ecec8b6634cc0b2ba1c183aded5304f9/src/abstract/poseidon.ts)
|
||||
- Check out [guidelines](https://github.com/paulmillr/guidelines) for coding practices
|
||||
- See [paulmillr.com/noble](https://paulmillr.com/noble/) for useful resources, articles, documentation and demos
|
||||
related to the library.
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 Paul Miller [(https://paulmillr.com)](https://paulmillr.com)
|
||||
|
||||
See LICENSE file.
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,427 @@
|
||||
# fast-copy
|
||||
|
||||
<img src="https://img.shields.io/badge/build-passing-brightgreen.svg"/>
|
||||
<img src="https://img.shields.io/badge/coverage-100%25-brightgreen.svg"/>
|
||||
<img src="https://img.shields.io/badge/license-MIT-blue.svg"/>
|
||||
|
||||
A [blazing fast](#benchmarks) deep object copier
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [fast-copy](#fast-copy)
|
||||
- [Table of contents](#table-of-contents)
|
||||
- [Usage](#usage)
|
||||
- [API](#api)
|
||||
- [`copy`](#copy)
|
||||
- [`copyStrict`](#copystrict)
|
||||
- [`createCopier`](#createcopier)
|
||||
- [`createCache`](#createcache)
|
||||
- [`methods`](#methods)
|
||||
- [Copier state](#copier-state)
|
||||
- [`cache`](#cache)
|
||||
- [`copier`](#copier)
|
||||
- [`Constructor` / `prototype`](#constructor--prototype)
|
||||
- [`strict`](#strict)
|
||||
- [Types supported](#types-supported)
|
||||
- [Aspects of default copiers](#aspects-of-default-copiers)
|
||||
- [Error references are copied directly, instead of creating a new `*Error` object](#error-references-are-copied-directly-instead-of-creating-a-new-error-object)
|
||||
- [The constructor of the original object is used, instead of using known globals](#the-constructor-of-the-original-object-is-used-instead-of-using-known-globals)
|
||||
- [Benchmarks](#benchmarks)
|
||||
- [Simple objects](#simple-objects)
|
||||
- [Complex objects](#complex-objects)
|
||||
- [Big data](#big-data)
|
||||
- [Circular objects](#circular-objects)
|
||||
- [Special objects](#special-objects)
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import { copy } from 'fast-copy';
|
||||
import { deepEqual } from 'fast-equals';
|
||||
|
||||
const object = {
|
||||
array: [123, { deep: 'value' }],
|
||||
map: new Map([
|
||||
['foo', {}],
|
||||
[{ bar: 'baz' }, 'quz'],
|
||||
]),
|
||||
};
|
||||
|
||||
const copiedObject = copy(object);
|
||||
|
||||
console.log(copiedObject === object); // false
|
||||
console.log(deepEqual(copiedObject, object)); // true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `copy`
|
||||
|
||||
Deeply copy the object passed.
|
||||
|
||||
```js
|
||||
import { copy } from 'fast-copy';
|
||||
|
||||
const copied = copy({ foo: 'bar' });
|
||||
```
|
||||
|
||||
### `copyStrict`
|
||||
|
||||
Deeply copy the object passed, but with additional strictness when replicating the original object:
|
||||
|
||||
- Properties retain their original property descriptor
|
||||
- Non-enumerable keys are copied
|
||||
- Non-standard properties (e.g., keys on arrays / maps / sets) are copied
|
||||
|
||||
```js
|
||||
import { copyStrict } from 'fast-copy';
|
||||
|
||||
const object = { foo: 'bar' };
|
||||
object.nonEnumerable = Object.defineProperty(object, 'bar', {
|
||||
enumerable: false,
|
||||
value: 'baz',
|
||||
});
|
||||
|
||||
const copied = copy(object);
|
||||
```
|
||||
|
||||
**NOTE**: This method is significantly slower than [`copy`](#copy), so it is recommended to only use this when you have
|
||||
specific use-cases that require it.
|
||||
|
||||
### `createCopier`
|
||||
|
||||
Create a custom copier based on the type-specific method overrides passed, as well as configuration options for how
|
||||
copies should be performed. This is useful if you want to squeeze out maximum performance, or perform something other
|
||||
than a standard deep copy.
|
||||
|
||||
```js
|
||||
import { createCopier } from 'fast-copy';
|
||||
import { LRUCache } from 'lru-cache';
|
||||
|
||||
const copyShallowStrict = createCopier({
|
||||
createCache: () => new LRUCache(),
|
||||
methods: {
|
||||
array: (array) => [...array],
|
||||
map: (map) => new Map(map.entries()),
|
||||
object: (object) => ({ ...object }),
|
||||
set: (set) => new Set(set.values()),
|
||||
},
|
||||
strict: true,
|
||||
});
|
||||
```
|
||||
|
||||
#### `createCache`
|
||||
|
||||
Method that creates the internal [`cache`](#cache) in the [Copier state](#copier-state). Defaults to creating a new
|
||||
`WeakMap` instance.
|
||||
|
||||
#### `methods`
|
||||
|
||||
Methods used for copying specific object types. A list of the methods and which object types they handle:
|
||||
|
||||
- `array` => `Array`
|
||||
- `arrayBuffer`=> `ArrayBuffer`, `Float32Array`, `Float64Array`, `Int8Array`, `Int16Array`, `Int32Array`, `Uint8Array`,
|
||||
`Uint8ClampedArray`, `Uint16Array`, `Uint32Array`, `BigInt64Array`, `BigUint64Array`
|
||||
- `blob` => `Blob`
|
||||
- `dataView` => `DataView`
|
||||
- `date` => `Date`
|
||||
- `error` => `Error`, `AggregateError`, `EvalError`, `RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`,
|
||||
`URIError`
|
||||
- `map` => `Map`
|
||||
- `object` => `Object`, or any custom constructor
|
||||
- `regExp` => `RegExp`
|
||||
- `set` => `Set`
|
||||
|
||||
Each method has the following contract:
|
||||
|
||||
```js
|
||||
type InternalCopier<Value> = (value: Value, state: State) => Value;
|
||||
|
||||
interface State {
|
||||
Constructor: any;
|
||||
cache: WeakMap;
|
||||
copier: InternalCopier<any>;
|
||||
prototype: any;
|
||||
}
|
||||
```
|
||||
|
||||
##### Copier state
|
||||
|
||||
###### `cache`
|
||||
|
||||
If you want to maintain circular reference handling, then you'll need the methods to handle cache population for future
|
||||
lookups:
|
||||
|
||||
```js
|
||||
function shallowlyCloneArray<Value extends any[]>(
|
||||
value: Value,
|
||||
state: State
|
||||
): Value {
|
||||
const clone = [...value];
|
||||
|
||||
state.cache.set(value, clone);
|
||||
|
||||
return clone;
|
||||
}
|
||||
```
|
||||
|
||||
###### `copier`
|
||||
|
||||
`copier` is provided for recursive calls with deeply-nested objects.
|
||||
|
||||
```js
|
||||
function deeplyCloneArray<Value extends any[]>(
|
||||
value: Value,
|
||||
state: State
|
||||
): Value {
|
||||
const clone = [];
|
||||
|
||||
state.cache.set(value, clone);
|
||||
|
||||
value.forEach((item) => state.copier(item, state));
|
||||
|
||||
return clone;
|
||||
}
|
||||
```
|
||||
|
||||
Note above I am using `forEach` instead of a simple `map`. This is because it is highly recommended to store the clone
|
||||
in [`cache`](#cache) eagerly when deeply copying, so that nested circular references are handled correctly.
|
||||
|
||||
###### `Constructor` / `prototype`
|
||||
|
||||
Both `Constructor` and `prototype` properties are only populated with complex objects that are not standard objects or
|
||||
arrays. This is mainly useful for custom subclasses of these globals, or maintaining custom prototypes of objects.
|
||||
|
||||
```js
|
||||
function deeplyCloneSubclassArray<Value extends CustomArray>(
|
||||
value: Value,
|
||||
state: State
|
||||
): Value {
|
||||
const clone = new state.Constructor();
|
||||
|
||||
state.cache.set(value, clone);
|
||||
|
||||
value.forEach((item) => clone.push(item));
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
function deeplyCloneCustomObject<Value extends CustomObject>(
|
||||
value: Value,
|
||||
state: State
|
||||
): Value {
|
||||
const clone = Object.create(state.prototype);
|
||||
|
||||
state.cache.set(value, clone);
|
||||
|
||||
Object.entries(value).forEach(([k, v]) => (clone[k] = v));
|
||||
|
||||
return clone;
|
||||
}
|
||||
```
|
||||
|
||||
#### `strict`
|
||||
|
||||
Enforces strict copying of properties, which includes properties that are not standard for that object. An example would
|
||||
be a named key on an array.
|
||||
|
||||
**NOTE**: This creates a copier that is significantly slower than "loose" mode, so it is recommended to only use this
|
||||
when you have specific use-cases that require it.
|
||||
|
||||
## Types supported
|
||||
|
||||
The following object types are deeply cloned when they are either properties on the object passed, or the object itself:
|
||||
|
||||
- `Array`
|
||||
- `ArrayBuffer`
|
||||
- `Boolean` primitive wrappers (e.g., `new Boolean(true)`)
|
||||
- `Blob`
|
||||
- `Buffer`
|
||||
- `DataView`
|
||||
- `Date`
|
||||
- `Float32Array`
|
||||
- `Float64Array`
|
||||
- `Int8Array`
|
||||
- `Int16Array`
|
||||
- `Int32Array`
|
||||
- `Map`
|
||||
- `Number` primitive wrappers (e.g., `new Number(123)`)
|
||||
- `Object`
|
||||
- `RegExp`
|
||||
- `Set`
|
||||
- `String` primitive wrappers (e.g., `new String('foo')`)
|
||||
- `Uint8Array`
|
||||
- `Uint8ClampedArray`
|
||||
- `Uint16Array`
|
||||
- `Uint32Array`
|
||||
- `React` components
|
||||
- Custom constructors
|
||||
|
||||
The following object types are copied directly, as they are either primitives, cannot be cloned, or the common use-case
|
||||
implementation does not expect cloning:
|
||||
|
||||
- `AsyncFunction`
|
||||
- `AsyncGenerator`
|
||||
- `Boolean` primitives
|
||||
- `Error`
|
||||
- `Function`
|
||||
- `Generator`
|
||||
- `GeneratorFunction`
|
||||
- `Number` primitives
|
||||
- `Null`
|
||||
- `Promise`
|
||||
- `String` primitives
|
||||
- `Symbol`
|
||||
- `Undefined`
|
||||
- `WeakMap`
|
||||
- `WeakSet`
|
||||
|
||||
Circular objects are supported out of the box. By default, a cache based on `WeakSet` is used, but if `WeakSet` is not
|
||||
available then a fallback is used. The benchmarks quoted below are based on use of `WeakSet`.
|
||||
|
||||
## Aspects of default copiers
|
||||
|
||||
Inherently, what is considered a valid copy is subjective because of different requirements and use-cases. For this
|
||||
library, some decisions were explicitly made for the default copiers of specific object types, and those decisions are
|
||||
detailed below. If your use-cases require different handling, you can always create your own custom copier with
|
||||
[`createCopier`](#createcopier).
|
||||
|
||||
### Error references are copied directly, instead of creating a new `*Error` object
|
||||
|
||||
While it would be relatively trivial to copy over the message and stack to a new object of the same `Error` subclass, it
|
||||
is a common practice to "override" the message or stack, and copies would not retain this mutation. As such, the
|
||||
original reference is copied.
|
||||
|
||||
### The constructor of the original object is used, instead of using known globals
|
||||
|
||||
Starting in ES2015, native globals can be subclassed like any custom class. When copying, we explicitly reuse the
|
||||
constructor of the original object. However, the expectation is that these subclasses would have the same constructur
|
||||
signature as their native base class. This is a common community practice, but there is the possibility of inaccuracy if
|
||||
the contract differs.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
#### Simple objects
|
||||
|
||||
_Small number of properties, all values are primitives_
|
||||
|
||||
```bash
|
||||
┌────────────────────┬────────────────┐
|
||||
│ Name │ Ops / sec │
|
||||
├────────────────────┼────────────────┤
|
||||
│ fast-copy │ 4516637.948706 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ lodash.cloneDeep │ 2726908.524823 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ clone │ 2292947.082887 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ ramda │ 1919887.358374 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ fast-clone │ 1445623.172658 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ deepclone │ 1172068.638112 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ fast-copy (strict) │ 1029920.368064 │
|
||||
└────────────────────┴────────────────┘
|
||||
Fastest was "fast-copy".
|
||||
```
|
||||
|
||||
#### Complex objects
|
||||
|
||||
_Large number of properties, values are a combination of primitives and complex objects_
|
||||
|
||||
```bash
|
||||
┌────────────────────┬───────────────┐
|
||||
│ Name │ Ops / sec │
|
||||
├────────────────────┼───────────────┤
|
||||
│ fast-copy │ 202418.444691 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ deepclone │ 139120.811183 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ clone │ 122191.364796 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ ramda │ 106986.690081 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ fast-clone │ 102390.033243 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ fast-copy (strict) │ 72306.017635 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ lodash.cloneDeep │ 68706.681189 │
|
||||
└────────────────────┴───────────────┘
|
||||
Fastest was "fast-copy".
|
||||
```
|
||||
|
||||
#### Big data
|
||||
|
||||
_Very large number of properties with high amount of nesting, mainly objects and arrays_
|
||||
|
||||
```bash
|
||||
┌────────────────────┬────────────┐
|
||||
│ Name │ Ops / sec │
|
||||
├────────────────────┼────────────┤
|
||||
│ fast-copy │ 564.726583 │
|
||||
├────────────────────┼────────────┤
|
||||
│ fast-clone │ 265.243854 │
|
||||
├────────────────────┼────────────┤
|
||||
│ lodash.cloneDeep │ 160.972258 │
|
||||
├────────────────────┼────────────┤
|
||||
│ deepclone │ 158.201556 │
|
||||
├────────────────────┼────────────┤
|
||||
│ fast-copy (strict) │ 135.031983 │
|
||||
├────────────────────┼────────────┤
|
||||
│ clone │ 122.876256 │
|
||||
├────────────────────┼────────────┤
|
||||
│ ramda │ 35.226104 │
|
||||
└────────────────────┴────────────┘
|
||||
Fastest was "fast-copy".
|
||||
```
|
||||
|
||||
#### Circular objects
|
||||
|
||||
_Simple object with a deeply nested reference to itself_
|
||||
|
||||
```bash
|
||||
┌────────────────────┬────────────────┐
|
||||
│ Name │ Ops / sec │
|
||||
├────────────────────┼────────────────┤
|
||||
│ fast-copy │ 2265437.452915 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ deepclone │ 1078459.808203 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ lodash.cloneDeep │ 989211.772997 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ fast-copy (strict) │ 865453.141899 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ clone │ 748230.731936 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ ramda │ 564490.882674 │
|
||||
├────────────────────┼────────────────┤
|
||||
│ fast-clone │ 0 │
|
||||
└────────────────────┴────────────────┘
|
||||
Fastest was "fast-copy".
|
||||
```
|
||||
|
||||
#### Special objects
|
||||
|
||||
_Custom constructors, React components, etc_
|
||||
|
||||
```bash
|
||||
┌────────────────────┬───────────────┐
|
||||
│ Name │ Ops / sec │
|
||||
├────────────────────┼───────────────┤
|
||||
│ fast-copy │ 134318.379975 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ lodash.cloneDeep │ 62990.463065 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ clone │ 59386.329843 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ fast-clone │ 53886.995853 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ ramda │ 27974.450157 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ deepclone │ 23498.796755 │
|
||||
├────────────────────┼───────────────┤
|
||||
│ fast-copy (strict) │ 18955.802659 │
|
||||
└────────────────────┴───────────────┘
|
||||
Fastest was "fast-copy".
|
||||
```
|
||||
@@ -0,0 +1,99 @@
|
||||
'use strict'
|
||||
|
||||
const test = require('node:test')
|
||||
const assert = require('node:assert')
|
||||
const os = require('node:os')
|
||||
const { join } = require('node:path')
|
||||
const { readFile } = require('node:fs').promises
|
||||
|
||||
const { watchFileCreated, file } = require('../helper')
|
||||
const pino = require('../../pino')
|
||||
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
|
||||
test('pino.transport with destination overridden by bundler', async (t) => {
|
||||
globalThis.__bundlerPathsOverrides = {
|
||||
foobar: join(__dirname, '..', 'fixtures', 'to-file-transport.js')
|
||||
}
|
||||
|
||||
const destination = file()
|
||||
const transport = pino.transport({
|
||||
target: 'foobar',
|
||||
options: { destination }
|
||||
})
|
||||
t.after(transport.end.bind(transport))
|
||||
const instance = pino(transport)
|
||||
instance.info('hello')
|
||||
await watchFileCreated(destination)
|
||||
const result = JSON.parse(await readFile(destination))
|
||||
delete result.time
|
||||
assert.deepEqual(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'hello'
|
||||
})
|
||||
|
||||
globalThis.__bundlerPathsOverrides = undefined
|
||||
})
|
||||
|
||||
test('pino.transport with worker destination overridden by bundler', async (t) => {
|
||||
globalThis.__bundlerPathsOverrides = {
|
||||
'pino-worker': join(__dirname, '..', '..', 'lib/worker.js')
|
||||
}
|
||||
|
||||
const destination = file()
|
||||
const transport = pino.transport({
|
||||
targets: [
|
||||
{
|
||||
target: join(__dirname, '..', 'fixtures', 'to-file-transport.js'),
|
||||
options: { destination }
|
||||
}
|
||||
]
|
||||
})
|
||||
t.after(transport.end.bind(transport))
|
||||
const instance = pino(transport)
|
||||
instance.info('hello')
|
||||
await watchFileCreated(destination)
|
||||
const result = JSON.parse(await readFile(destination))
|
||||
delete result.time
|
||||
assert.deepEqual(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'hello'
|
||||
})
|
||||
|
||||
globalThis.__bundlerPathsOverrides = undefined
|
||||
})
|
||||
|
||||
test('pino.transport with worker destination overridden by bundler and mjs transport', async (t) => {
|
||||
globalThis.__bundlerPathsOverrides = {
|
||||
'pino-worker': join(__dirname, '..', '..', 'lib/worker.js')
|
||||
}
|
||||
|
||||
const destination = file()
|
||||
const transport = pino.transport({
|
||||
targets: [
|
||||
{
|
||||
target: join(__dirname, '..', 'fixtures', 'ts', 'to-file-transport.es2017.cjs'),
|
||||
options: { destination }
|
||||
}
|
||||
]
|
||||
})
|
||||
t.after(transport.end.bind(transport))
|
||||
const instance = pino(transport)
|
||||
instance.info('hello')
|
||||
await watchFileCreated(destination)
|
||||
const result = JSON.parse(await readFile(destination))
|
||||
delete result.time
|
||||
assert.deepEqual(result, {
|
||||
pid,
|
||||
hostname,
|
||||
level: 30,
|
||||
msg: 'hello'
|
||||
})
|
||||
|
||||
globalThis.__bundlerPathsOverrides = undefined
|
||||
})
|
||||
@@ -0,0 +1,11 @@
|
||||
export type Options = [
|
||||
{
|
||||
allow?: string[];
|
||||
allowAsImport?: boolean;
|
||||
}
|
||||
];
|
||||
export type MessageIds = 'noRequireImports';
|
||||
declare const _default: import("@typescript-eslint/utils/ts-eslint").RuleModule<"noRequireImports", Options, import("../../rules").ESLintPluginDocs, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
||||
name: string;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,7 @@
|
||||
import * as core from "../core/index.js";
|
||||
import * as schemas from "./schemas.js";
|
||||
export declare function string<T = unknown>(params?: string | core.$ZodStringParams): schemas.ZodMiniString<T>;
|
||||
export declare function number<T = unknown>(params?: string | core.$ZodNumberParams): schemas.ZodMiniNumber<T>;
|
||||
export declare function boolean<T = unknown>(params?: string | core.$ZodBooleanParams): schemas.ZodMiniBoolean<T>;
|
||||
export declare function bigint<T = unknown>(params?: string | core.$ZodBigIntParams): schemas.ZodMiniBigInt<T>;
|
||||
export declare function date<T = unknown>(params?: string | core.$ZodDateParams): schemas.ZodMiniDate<T>;
|
||||
@@ -0,0 +1,16 @@
|
||||
import type { TSESLint } from '@typescript-eslint/utils';
|
||||
type Types = Record<string, boolean | string | {
|
||||
fixWith?: string;
|
||||
message: string;
|
||||
suggest?: readonly string[];
|
||||
} | null>;
|
||||
export type Options = [
|
||||
{
|
||||
types?: Types;
|
||||
}
|
||||
];
|
||||
export type MessageIds = 'bannedTypeMessage' | 'bannedTypeReplacement';
|
||||
declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
|
||||
name: string;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,34 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.DefinitionBase = void 0;
|
||||
const ID_1 = require("../ID");
|
||||
const generator = (0, ID_1.createIdGenerator)();
|
||||
class DefinitionBase {
|
||||
/**
|
||||
* A unique ID for this instance - primarily used to help debugging and testing
|
||||
*/
|
||||
$id = generator();
|
||||
type;
|
||||
/**
|
||||
* The `Identifier` node of this definition
|
||||
* @public
|
||||
*/
|
||||
name;
|
||||
/**
|
||||
* The enclosing node of the name.
|
||||
* @public
|
||||
*/
|
||||
node;
|
||||
/**
|
||||
* the enclosing statement node of the identifier.
|
||||
* @public
|
||||
*/
|
||||
parent;
|
||||
constructor(type, name, node, parent) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.node = node;
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
exports.DefinitionBase = DefinitionBase;
|
||||
@@ -0,0 +1,391 @@
|
||||
// Code generated by Herebyfile.mjs generate:enums from internal/ast/kind_generated.go. DO NOT EDIT.
|
||||
export var SyntaxKind;
|
||||
(function (SyntaxKind) {
|
||||
SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown";
|
||||
SyntaxKind[SyntaxKind["EndOfFile"] = 1] = "EndOfFile";
|
||||
SyntaxKind[SyntaxKind["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
|
||||
SyntaxKind[SyntaxKind["MultiLineCommentTrivia"] = 3] = "MultiLineCommentTrivia";
|
||||
SyntaxKind[SyntaxKind["NewLineTrivia"] = 4] = "NewLineTrivia";
|
||||
SyntaxKind[SyntaxKind["WhitespaceTrivia"] = 5] = "WhitespaceTrivia";
|
||||
SyntaxKind[SyntaxKind["ConflictMarkerTrivia"] = 6] = "ConflictMarkerTrivia";
|
||||
SyntaxKind[SyntaxKind["NonTextFileMarkerTrivia"] = 7] = "NonTextFileMarkerTrivia";
|
||||
SyntaxKind[SyntaxKind["NumericLiteral"] = 8] = "NumericLiteral";
|
||||
SyntaxKind[SyntaxKind["BigIntLiteral"] = 9] = "BigIntLiteral";
|
||||
SyntaxKind[SyntaxKind["StringLiteral"] = 10] = "StringLiteral";
|
||||
SyntaxKind[SyntaxKind["JsxText"] = 11] = "JsxText";
|
||||
SyntaxKind[SyntaxKind["JsxTextAllWhiteSpaces"] = 12] = "JsxTextAllWhiteSpaces";
|
||||
SyntaxKind[SyntaxKind["RegularExpressionLiteral"] = 13] = "RegularExpressionLiteral";
|
||||
SyntaxKind[SyntaxKind["NoSubstitutionTemplateLiteral"] = 14] = "NoSubstitutionTemplateLiteral";
|
||||
SyntaxKind[SyntaxKind["TemplateHead"] = 15] = "TemplateHead";
|
||||
SyntaxKind[SyntaxKind["TemplateMiddle"] = 16] = "TemplateMiddle";
|
||||
SyntaxKind[SyntaxKind["TemplateTail"] = 17] = "TemplateTail";
|
||||
SyntaxKind[SyntaxKind["OpenBraceToken"] = 18] = "OpenBraceToken";
|
||||
SyntaxKind[SyntaxKind["CloseBraceToken"] = 19] = "CloseBraceToken";
|
||||
SyntaxKind[SyntaxKind["OpenParenToken"] = 20] = "OpenParenToken";
|
||||
SyntaxKind[SyntaxKind["CloseParenToken"] = 21] = "CloseParenToken";
|
||||
SyntaxKind[SyntaxKind["OpenBracketToken"] = 22] = "OpenBracketToken";
|
||||
SyntaxKind[SyntaxKind["CloseBracketToken"] = 23] = "CloseBracketToken";
|
||||
SyntaxKind[SyntaxKind["DotToken"] = 24] = "DotToken";
|
||||
SyntaxKind[SyntaxKind["DotDotDotToken"] = 25] = "DotDotDotToken";
|
||||
SyntaxKind[SyntaxKind["SemicolonToken"] = 26] = "SemicolonToken";
|
||||
SyntaxKind[SyntaxKind["CommaToken"] = 27] = "CommaToken";
|
||||
SyntaxKind[SyntaxKind["QuestionDotToken"] = 28] = "QuestionDotToken";
|
||||
SyntaxKind[SyntaxKind["LessThanToken"] = 29] = "LessThanToken";
|
||||
SyntaxKind[SyntaxKind["LessThanSlashToken"] = 30] = "LessThanSlashToken";
|
||||
SyntaxKind[SyntaxKind["GreaterThanToken"] = 31] = "GreaterThanToken";
|
||||
SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 32] = "LessThanEqualsToken";
|
||||
SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 33] = "GreaterThanEqualsToken";
|
||||
SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 34] = "EqualsEqualsToken";
|
||||
SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 35] = "ExclamationEqualsToken";
|
||||
SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 36] = "EqualsEqualsEqualsToken";
|
||||
SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 37] = "ExclamationEqualsEqualsToken";
|
||||
SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 38] = "EqualsGreaterThanToken";
|
||||
SyntaxKind[SyntaxKind["PlusToken"] = 39] = "PlusToken";
|
||||
SyntaxKind[SyntaxKind["MinusToken"] = 40] = "MinusToken";
|
||||
SyntaxKind[SyntaxKind["AsteriskToken"] = 41] = "AsteriskToken";
|
||||
SyntaxKind[SyntaxKind["AsteriskAsteriskToken"] = 42] = "AsteriskAsteriskToken";
|
||||
SyntaxKind[SyntaxKind["SlashToken"] = 43] = "SlashToken";
|
||||
SyntaxKind[SyntaxKind["PercentToken"] = 44] = "PercentToken";
|
||||
SyntaxKind[SyntaxKind["PlusPlusToken"] = 45] = "PlusPlusToken";
|
||||
SyntaxKind[SyntaxKind["MinusMinusToken"] = 46] = "MinusMinusToken";
|
||||
SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 47] = "LessThanLessThanToken";
|
||||
SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 48] = "GreaterThanGreaterThanToken";
|
||||
SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 49] = "GreaterThanGreaterThanGreaterThanToken";
|
||||
SyntaxKind[SyntaxKind["AmpersandToken"] = 50] = "AmpersandToken";
|
||||
SyntaxKind[SyntaxKind["BarToken"] = 51] = "BarToken";
|
||||
SyntaxKind[SyntaxKind["CaretToken"] = 52] = "CaretToken";
|
||||
SyntaxKind[SyntaxKind["ExclamationToken"] = 53] = "ExclamationToken";
|
||||
SyntaxKind[SyntaxKind["TildeToken"] = 54] = "TildeToken";
|
||||
SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 55] = "AmpersandAmpersandToken";
|
||||
SyntaxKind[SyntaxKind["BarBarToken"] = 56] = "BarBarToken";
|
||||
SyntaxKind[SyntaxKind["QuestionToken"] = 57] = "QuestionToken";
|
||||
SyntaxKind[SyntaxKind["ColonToken"] = 58] = "ColonToken";
|
||||
SyntaxKind[SyntaxKind["AtToken"] = 59] = "AtToken";
|
||||
SyntaxKind[SyntaxKind["QuestionQuestionToken"] = 60] = "QuestionQuestionToken";
|
||||
SyntaxKind[SyntaxKind["BacktickToken"] = 61] = "BacktickToken";
|
||||
SyntaxKind[SyntaxKind["HashToken"] = 62] = "HashToken";
|
||||
SyntaxKind[SyntaxKind["EqualsToken"] = 63] = "EqualsToken";
|
||||
SyntaxKind[SyntaxKind["PlusEqualsToken"] = 64] = "PlusEqualsToken";
|
||||
SyntaxKind[SyntaxKind["MinusEqualsToken"] = 65] = "MinusEqualsToken";
|
||||
SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 66] = "AsteriskEqualsToken";
|
||||
SyntaxKind[SyntaxKind["AsteriskAsteriskEqualsToken"] = 67] = "AsteriskAsteriskEqualsToken";
|
||||
SyntaxKind[SyntaxKind["SlashEqualsToken"] = 68] = "SlashEqualsToken";
|
||||
SyntaxKind[SyntaxKind["PercentEqualsToken"] = 69] = "PercentEqualsToken";
|
||||
SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 70] = "LessThanLessThanEqualsToken";
|
||||
SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 71] = "GreaterThanGreaterThanEqualsToken";
|
||||
SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 72] = "GreaterThanGreaterThanGreaterThanEqualsToken";
|
||||
SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 73] = "AmpersandEqualsToken";
|
||||
SyntaxKind[SyntaxKind["BarEqualsToken"] = 74] = "BarEqualsToken";
|
||||
SyntaxKind[SyntaxKind["BarBarEqualsToken"] = 75] = "BarBarEqualsToken";
|
||||
SyntaxKind[SyntaxKind["AmpersandAmpersandEqualsToken"] = 76] = "AmpersandAmpersandEqualsToken";
|
||||
SyntaxKind[SyntaxKind["QuestionQuestionEqualsToken"] = 77] = "QuestionQuestionEqualsToken";
|
||||
SyntaxKind[SyntaxKind["CaretEqualsToken"] = 78] = "CaretEqualsToken";
|
||||
SyntaxKind[SyntaxKind["Identifier"] = 79] = "Identifier";
|
||||
SyntaxKind[SyntaxKind["PrivateIdentifier"] = 80] = "PrivateIdentifier";
|
||||
SyntaxKind[SyntaxKind["JSDocCommentTextToken"] = 81] = "JSDocCommentTextToken";
|
||||
SyntaxKind[SyntaxKind["BreakKeyword"] = 82] = "BreakKeyword";
|
||||
SyntaxKind[SyntaxKind["CaseKeyword"] = 83] = "CaseKeyword";
|
||||
SyntaxKind[SyntaxKind["CatchKeyword"] = 84] = "CatchKeyword";
|
||||
SyntaxKind[SyntaxKind["ClassKeyword"] = 85] = "ClassKeyword";
|
||||
SyntaxKind[SyntaxKind["ConstKeyword"] = 86] = "ConstKeyword";
|
||||
SyntaxKind[SyntaxKind["ContinueKeyword"] = 87] = "ContinueKeyword";
|
||||
SyntaxKind[SyntaxKind["DebuggerKeyword"] = 88] = "DebuggerKeyword";
|
||||
SyntaxKind[SyntaxKind["DefaultKeyword"] = 89] = "DefaultKeyword";
|
||||
SyntaxKind[SyntaxKind["DeleteKeyword"] = 90] = "DeleteKeyword";
|
||||
SyntaxKind[SyntaxKind["DoKeyword"] = 91] = "DoKeyword";
|
||||
SyntaxKind[SyntaxKind["ElseKeyword"] = 92] = "ElseKeyword";
|
||||
SyntaxKind[SyntaxKind["EnumKeyword"] = 93] = "EnumKeyword";
|
||||
SyntaxKind[SyntaxKind["ExportKeyword"] = 94] = "ExportKeyword";
|
||||
SyntaxKind[SyntaxKind["ExtendsKeyword"] = 95] = "ExtendsKeyword";
|
||||
SyntaxKind[SyntaxKind["FalseKeyword"] = 96] = "FalseKeyword";
|
||||
SyntaxKind[SyntaxKind["FinallyKeyword"] = 97] = "FinallyKeyword";
|
||||
SyntaxKind[SyntaxKind["ForKeyword"] = 98] = "ForKeyword";
|
||||
SyntaxKind[SyntaxKind["FunctionKeyword"] = 99] = "FunctionKeyword";
|
||||
SyntaxKind[SyntaxKind["IfKeyword"] = 100] = "IfKeyword";
|
||||
SyntaxKind[SyntaxKind["ImportKeyword"] = 101] = "ImportKeyword";
|
||||
SyntaxKind[SyntaxKind["InKeyword"] = 102] = "InKeyword";
|
||||
SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 103] = "InstanceOfKeyword";
|
||||
SyntaxKind[SyntaxKind["NewKeyword"] = 104] = "NewKeyword";
|
||||
SyntaxKind[SyntaxKind["NullKeyword"] = 105] = "NullKeyword";
|
||||
SyntaxKind[SyntaxKind["ReturnKeyword"] = 106] = "ReturnKeyword";
|
||||
SyntaxKind[SyntaxKind["SuperKeyword"] = 107] = "SuperKeyword";
|
||||
SyntaxKind[SyntaxKind["SwitchKeyword"] = 108] = "SwitchKeyword";
|
||||
SyntaxKind[SyntaxKind["ThisKeyword"] = 109] = "ThisKeyword";
|
||||
SyntaxKind[SyntaxKind["ThrowKeyword"] = 110] = "ThrowKeyword";
|
||||
SyntaxKind[SyntaxKind["TrueKeyword"] = 111] = "TrueKeyword";
|
||||
SyntaxKind[SyntaxKind["TryKeyword"] = 112] = "TryKeyword";
|
||||
SyntaxKind[SyntaxKind["TypeOfKeyword"] = 113] = "TypeOfKeyword";
|
||||
SyntaxKind[SyntaxKind["VarKeyword"] = 114] = "VarKeyword";
|
||||
SyntaxKind[SyntaxKind["VoidKeyword"] = 115] = "VoidKeyword";
|
||||
SyntaxKind[SyntaxKind["WhileKeyword"] = 116] = "WhileKeyword";
|
||||
SyntaxKind[SyntaxKind["WithKeyword"] = 117] = "WithKeyword";
|
||||
SyntaxKind[SyntaxKind["ImplementsKeyword"] = 118] = "ImplementsKeyword";
|
||||
SyntaxKind[SyntaxKind["InterfaceKeyword"] = 119] = "InterfaceKeyword";
|
||||
SyntaxKind[SyntaxKind["LetKeyword"] = 120] = "LetKeyword";
|
||||
SyntaxKind[SyntaxKind["PackageKeyword"] = 121] = "PackageKeyword";
|
||||
SyntaxKind[SyntaxKind["PrivateKeyword"] = 122] = "PrivateKeyword";
|
||||
SyntaxKind[SyntaxKind["ProtectedKeyword"] = 123] = "ProtectedKeyword";
|
||||
SyntaxKind[SyntaxKind["PublicKeyword"] = 124] = "PublicKeyword";
|
||||
SyntaxKind[SyntaxKind["StaticKeyword"] = 125] = "StaticKeyword";
|
||||
SyntaxKind[SyntaxKind["YieldKeyword"] = 126] = "YieldKeyword";
|
||||
SyntaxKind[SyntaxKind["AbstractKeyword"] = 127] = "AbstractKeyword";
|
||||
SyntaxKind[SyntaxKind["AccessorKeyword"] = 128] = "AccessorKeyword";
|
||||
SyntaxKind[SyntaxKind["AsKeyword"] = 129] = "AsKeyword";
|
||||
SyntaxKind[SyntaxKind["AssertsKeyword"] = 130] = "AssertsKeyword";
|
||||
SyntaxKind[SyntaxKind["AssertKeyword"] = 131] = "AssertKeyword";
|
||||
SyntaxKind[SyntaxKind["AnyKeyword"] = 132] = "AnyKeyword";
|
||||
SyntaxKind[SyntaxKind["AsyncKeyword"] = 133] = "AsyncKeyword";
|
||||
SyntaxKind[SyntaxKind["AwaitKeyword"] = 134] = "AwaitKeyword";
|
||||
SyntaxKind[SyntaxKind["BooleanKeyword"] = 135] = "BooleanKeyword";
|
||||
SyntaxKind[SyntaxKind["ConstructorKeyword"] = 136] = "ConstructorKeyword";
|
||||
SyntaxKind[SyntaxKind["DeclareKeyword"] = 137] = "DeclareKeyword";
|
||||
SyntaxKind[SyntaxKind["GetKeyword"] = 138] = "GetKeyword";
|
||||
SyntaxKind[SyntaxKind["ImmediateKeyword"] = 139] = "ImmediateKeyword";
|
||||
SyntaxKind[SyntaxKind["InferKeyword"] = 140] = "InferKeyword";
|
||||
SyntaxKind[SyntaxKind["IntrinsicKeyword"] = 141] = "IntrinsicKeyword";
|
||||
SyntaxKind[SyntaxKind["IsKeyword"] = 142] = "IsKeyword";
|
||||
SyntaxKind[SyntaxKind["KeyOfKeyword"] = 143] = "KeyOfKeyword";
|
||||
SyntaxKind[SyntaxKind["ModuleKeyword"] = 144] = "ModuleKeyword";
|
||||
SyntaxKind[SyntaxKind["NamespaceKeyword"] = 145] = "NamespaceKeyword";
|
||||
SyntaxKind[SyntaxKind["NeverKeyword"] = 146] = "NeverKeyword";
|
||||
SyntaxKind[SyntaxKind["OutKeyword"] = 147] = "OutKeyword";
|
||||
SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 148] = "ReadonlyKeyword";
|
||||
SyntaxKind[SyntaxKind["RequireKeyword"] = 149] = "RequireKeyword";
|
||||
SyntaxKind[SyntaxKind["NumberKeyword"] = 150] = "NumberKeyword";
|
||||
SyntaxKind[SyntaxKind["ObjectKeyword"] = 151] = "ObjectKeyword";
|
||||
SyntaxKind[SyntaxKind["SatisfiesKeyword"] = 152] = "SatisfiesKeyword";
|
||||
SyntaxKind[SyntaxKind["SetKeyword"] = 153] = "SetKeyword";
|
||||
SyntaxKind[SyntaxKind["StringKeyword"] = 154] = "StringKeyword";
|
||||
SyntaxKind[SyntaxKind["SymbolKeyword"] = 155] = "SymbolKeyword";
|
||||
SyntaxKind[SyntaxKind["TypeKeyword"] = 156] = "TypeKeyword";
|
||||
SyntaxKind[SyntaxKind["UndefinedKeyword"] = 157] = "UndefinedKeyword";
|
||||
SyntaxKind[SyntaxKind["UniqueKeyword"] = 158] = "UniqueKeyword";
|
||||
SyntaxKind[SyntaxKind["UnknownKeyword"] = 159] = "UnknownKeyword";
|
||||
SyntaxKind[SyntaxKind["UsingKeyword"] = 160] = "UsingKeyword";
|
||||
SyntaxKind[SyntaxKind["FromKeyword"] = 161] = "FromKeyword";
|
||||
SyntaxKind[SyntaxKind["GlobalKeyword"] = 162] = "GlobalKeyword";
|
||||
SyntaxKind[SyntaxKind["BigIntKeyword"] = 163] = "BigIntKeyword";
|
||||
SyntaxKind[SyntaxKind["OverrideKeyword"] = 164] = "OverrideKeyword";
|
||||
SyntaxKind[SyntaxKind["OfKeyword"] = 165] = "OfKeyword";
|
||||
SyntaxKind[SyntaxKind["DeferKeyword"] = 166] = "DeferKeyword";
|
||||
SyntaxKind[SyntaxKind["QualifiedName"] = 167] = "QualifiedName";
|
||||
SyntaxKind[SyntaxKind["ComputedPropertyName"] = 168] = "ComputedPropertyName";
|
||||
SyntaxKind[SyntaxKind["TypeParameter"] = 169] = "TypeParameter";
|
||||
SyntaxKind[SyntaxKind["Parameter"] = 170] = "Parameter";
|
||||
SyntaxKind[SyntaxKind["Decorator"] = 171] = "Decorator";
|
||||
SyntaxKind[SyntaxKind["PropertySignature"] = 172] = "PropertySignature";
|
||||
SyntaxKind[SyntaxKind["PropertyDeclaration"] = 173] = "PropertyDeclaration";
|
||||
SyntaxKind[SyntaxKind["MethodSignature"] = 174] = "MethodSignature";
|
||||
SyntaxKind[SyntaxKind["MethodDeclaration"] = 175] = "MethodDeclaration";
|
||||
SyntaxKind[SyntaxKind["ClassStaticBlockDeclaration"] = 176] = "ClassStaticBlockDeclaration";
|
||||
SyntaxKind[SyntaxKind["Constructor"] = 177] = "Constructor";
|
||||
SyntaxKind[SyntaxKind["GetAccessor"] = 178] = "GetAccessor";
|
||||
SyntaxKind[SyntaxKind["SetAccessor"] = 179] = "SetAccessor";
|
||||
SyntaxKind[SyntaxKind["CallSignature"] = 180] = "CallSignature";
|
||||
SyntaxKind[SyntaxKind["ConstructSignature"] = 181] = "ConstructSignature";
|
||||
SyntaxKind[SyntaxKind["IndexSignature"] = 182] = "IndexSignature";
|
||||
SyntaxKind[SyntaxKind["TypePredicate"] = 183] = "TypePredicate";
|
||||
SyntaxKind[SyntaxKind["TypeReference"] = 184] = "TypeReference";
|
||||
SyntaxKind[SyntaxKind["FunctionType"] = 185] = "FunctionType";
|
||||
SyntaxKind[SyntaxKind["ConstructorType"] = 186] = "ConstructorType";
|
||||
SyntaxKind[SyntaxKind["TypeQuery"] = 187] = "TypeQuery";
|
||||
SyntaxKind[SyntaxKind["TypeLiteral"] = 188] = "TypeLiteral";
|
||||
SyntaxKind[SyntaxKind["ArrayType"] = 189] = "ArrayType";
|
||||
SyntaxKind[SyntaxKind["TupleType"] = 190] = "TupleType";
|
||||
SyntaxKind[SyntaxKind["OptionalType"] = 191] = "OptionalType";
|
||||
SyntaxKind[SyntaxKind["RestType"] = 192] = "RestType";
|
||||
SyntaxKind[SyntaxKind["UnionType"] = 193] = "UnionType";
|
||||
SyntaxKind[SyntaxKind["IntersectionType"] = 194] = "IntersectionType";
|
||||
SyntaxKind[SyntaxKind["ConditionalType"] = 195] = "ConditionalType";
|
||||
SyntaxKind[SyntaxKind["InferType"] = 196] = "InferType";
|
||||
SyntaxKind[SyntaxKind["ParenthesizedType"] = 197] = "ParenthesizedType";
|
||||
SyntaxKind[SyntaxKind["ThisType"] = 198] = "ThisType";
|
||||
SyntaxKind[SyntaxKind["TypeOperator"] = 199] = "TypeOperator";
|
||||
SyntaxKind[SyntaxKind["IndexedAccessType"] = 200] = "IndexedAccessType";
|
||||
SyntaxKind[SyntaxKind["MappedType"] = 201] = "MappedType";
|
||||
SyntaxKind[SyntaxKind["LiteralType"] = 202] = "LiteralType";
|
||||
SyntaxKind[SyntaxKind["NamedTupleMember"] = 203] = "NamedTupleMember";
|
||||
SyntaxKind[SyntaxKind["TemplateLiteralType"] = 204] = "TemplateLiteralType";
|
||||
SyntaxKind[SyntaxKind["TemplateLiteralTypeSpan"] = 205] = "TemplateLiteralTypeSpan";
|
||||
SyntaxKind[SyntaxKind["ImportType"] = 206] = "ImportType";
|
||||
SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 207] = "ObjectBindingPattern";
|
||||
SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 208] = "ArrayBindingPattern";
|
||||
SyntaxKind[SyntaxKind["BindingElement"] = 209] = "BindingElement";
|
||||
SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 210] = "ArrayLiteralExpression";
|
||||
SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 211] = "ObjectLiteralExpression";
|
||||
SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 212] = "PropertyAccessExpression";
|
||||
SyntaxKind[SyntaxKind["ElementAccessExpression"] = 213] = "ElementAccessExpression";
|
||||
SyntaxKind[SyntaxKind["CallExpression"] = 214] = "CallExpression";
|
||||
SyntaxKind[SyntaxKind["NewExpression"] = 215] = "NewExpression";
|
||||
SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 216] = "TaggedTemplateExpression";
|
||||
SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 217] = "TypeAssertionExpression";
|
||||
SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 218] = "ParenthesizedExpression";
|
||||
SyntaxKind[SyntaxKind["FunctionExpression"] = 219] = "FunctionExpression";
|
||||
SyntaxKind[SyntaxKind["ArrowFunction"] = 220] = "ArrowFunction";
|
||||
SyntaxKind[SyntaxKind["DeleteExpression"] = 221] = "DeleteExpression";
|
||||
SyntaxKind[SyntaxKind["TypeOfExpression"] = 222] = "TypeOfExpression";
|
||||
SyntaxKind[SyntaxKind["VoidExpression"] = 223] = "VoidExpression";
|
||||
SyntaxKind[SyntaxKind["AwaitExpression"] = 224] = "AwaitExpression";
|
||||
SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 225] = "PrefixUnaryExpression";
|
||||
SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 226] = "PostfixUnaryExpression";
|
||||
SyntaxKind[SyntaxKind["BinaryExpression"] = 227] = "BinaryExpression";
|
||||
SyntaxKind[SyntaxKind["ConditionalExpression"] = 228] = "ConditionalExpression";
|
||||
SyntaxKind[SyntaxKind["TemplateExpression"] = 229] = "TemplateExpression";
|
||||
SyntaxKind[SyntaxKind["YieldExpression"] = 230] = "YieldExpression";
|
||||
SyntaxKind[SyntaxKind["SpreadElement"] = 231] = "SpreadElement";
|
||||
SyntaxKind[SyntaxKind["ClassExpression"] = 232] = "ClassExpression";
|
||||
SyntaxKind[SyntaxKind["OmittedExpression"] = 233] = "OmittedExpression";
|
||||
SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 234] = "ExpressionWithTypeArguments";
|
||||
SyntaxKind[SyntaxKind["AsExpression"] = 235] = "AsExpression";
|
||||
SyntaxKind[SyntaxKind["NonNullExpression"] = 236] = "NonNullExpression";
|
||||
SyntaxKind[SyntaxKind["MetaProperty"] = 237] = "MetaProperty";
|
||||
SyntaxKind[SyntaxKind["SyntheticExpression"] = 238] = "SyntheticExpression";
|
||||
SyntaxKind[SyntaxKind["SatisfiesExpression"] = 239] = "SatisfiesExpression";
|
||||
SyntaxKind[SyntaxKind["TemplateSpan"] = 240] = "TemplateSpan";
|
||||
SyntaxKind[SyntaxKind["SemicolonClassElement"] = 241] = "SemicolonClassElement";
|
||||
SyntaxKind[SyntaxKind["Block"] = 242] = "Block";
|
||||
SyntaxKind[SyntaxKind["EmptyStatement"] = 243] = "EmptyStatement";
|
||||
SyntaxKind[SyntaxKind["VariableStatement"] = 244] = "VariableStatement";
|
||||
SyntaxKind[SyntaxKind["ExpressionStatement"] = 245] = "ExpressionStatement";
|
||||
SyntaxKind[SyntaxKind["IfStatement"] = 246] = "IfStatement";
|
||||
SyntaxKind[SyntaxKind["DoStatement"] = 247] = "DoStatement";
|
||||
SyntaxKind[SyntaxKind["WhileStatement"] = 248] = "WhileStatement";
|
||||
SyntaxKind[SyntaxKind["ForStatement"] = 249] = "ForStatement";
|
||||
SyntaxKind[SyntaxKind["ForInStatement"] = 250] = "ForInStatement";
|
||||
SyntaxKind[SyntaxKind["ForOfStatement"] = 251] = "ForOfStatement";
|
||||
SyntaxKind[SyntaxKind["ContinueStatement"] = 252] = "ContinueStatement";
|
||||
SyntaxKind[SyntaxKind["BreakStatement"] = 253] = "BreakStatement";
|
||||
SyntaxKind[SyntaxKind["ReturnStatement"] = 254] = "ReturnStatement";
|
||||
SyntaxKind[SyntaxKind["WithStatement"] = 255] = "WithStatement";
|
||||
SyntaxKind[SyntaxKind["SwitchStatement"] = 256] = "SwitchStatement";
|
||||
SyntaxKind[SyntaxKind["LabeledStatement"] = 257] = "LabeledStatement";
|
||||
SyntaxKind[SyntaxKind["ThrowStatement"] = 258] = "ThrowStatement";
|
||||
SyntaxKind[SyntaxKind["TryStatement"] = 259] = "TryStatement";
|
||||
SyntaxKind[SyntaxKind["DebuggerStatement"] = 260] = "DebuggerStatement";
|
||||
SyntaxKind[SyntaxKind["VariableDeclaration"] = 261] = "VariableDeclaration";
|
||||
SyntaxKind[SyntaxKind["VariableDeclarationList"] = 262] = "VariableDeclarationList";
|
||||
SyntaxKind[SyntaxKind["FunctionDeclaration"] = 263] = "FunctionDeclaration";
|
||||
SyntaxKind[SyntaxKind["ClassDeclaration"] = 264] = "ClassDeclaration";
|
||||
SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 265] = "InterfaceDeclaration";
|
||||
SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 266] = "TypeAliasDeclaration";
|
||||
SyntaxKind[SyntaxKind["EnumDeclaration"] = 267] = "EnumDeclaration";
|
||||
SyntaxKind[SyntaxKind["ModuleDeclaration"] = 268] = "ModuleDeclaration";
|
||||
SyntaxKind[SyntaxKind["ModuleBlock"] = 269] = "ModuleBlock";
|
||||
SyntaxKind[SyntaxKind["CaseBlock"] = 270] = "CaseBlock";
|
||||
SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 271] = "NamespaceExportDeclaration";
|
||||
SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 272] = "ImportEqualsDeclaration";
|
||||
SyntaxKind[SyntaxKind["ImportDeclaration"] = 273] = "ImportDeclaration";
|
||||
SyntaxKind[SyntaxKind["ImportClause"] = 274] = "ImportClause";
|
||||
SyntaxKind[SyntaxKind["NamespaceImport"] = 275] = "NamespaceImport";
|
||||
SyntaxKind[SyntaxKind["NamedImports"] = 276] = "NamedImports";
|
||||
SyntaxKind[SyntaxKind["ImportSpecifier"] = 277] = "ImportSpecifier";
|
||||
SyntaxKind[SyntaxKind["ExportAssignment"] = 278] = "ExportAssignment";
|
||||
SyntaxKind[SyntaxKind["ExportDeclaration"] = 279] = "ExportDeclaration";
|
||||
SyntaxKind[SyntaxKind["NamedExports"] = 280] = "NamedExports";
|
||||
SyntaxKind[SyntaxKind["NamespaceExport"] = 281] = "NamespaceExport";
|
||||
SyntaxKind[SyntaxKind["ExportSpecifier"] = 282] = "ExportSpecifier";
|
||||
SyntaxKind[SyntaxKind["MissingDeclaration"] = 283] = "MissingDeclaration";
|
||||
SyntaxKind[SyntaxKind["ExternalModuleReference"] = 284] = "ExternalModuleReference";
|
||||
SyntaxKind[SyntaxKind["JsxElement"] = 285] = "JsxElement";
|
||||
SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 286] = "JsxSelfClosingElement";
|
||||
SyntaxKind[SyntaxKind["JsxOpeningElement"] = 287] = "JsxOpeningElement";
|
||||
SyntaxKind[SyntaxKind["JsxClosingElement"] = 288] = "JsxClosingElement";
|
||||
SyntaxKind[SyntaxKind["JsxFragment"] = 289] = "JsxFragment";
|
||||
SyntaxKind[SyntaxKind["JsxOpeningFragment"] = 290] = "JsxOpeningFragment";
|
||||
SyntaxKind[SyntaxKind["JsxClosingFragment"] = 291] = "JsxClosingFragment";
|
||||
SyntaxKind[SyntaxKind["JsxAttribute"] = 292] = "JsxAttribute";
|
||||
SyntaxKind[SyntaxKind["JsxAttributes"] = 293] = "JsxAttributes";
|
||||
SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 294] = "JsxSpreadAttribute";
|
||||
SyntaxKind[SyntaxKind["JsxExpression"] = 295] = "JsxExpression";
|
||||
SyntaxKind[SyntaxKind["JsxNamespacedName"] = 296] = "JsxNamespacedName";
|
||||
SyntaxKind[SyntaxKind["CaseClause"] = 297] = "CaseClause";
|
||||
SyntaxKind[SyntaxKind["DefaultClause"] = 298] = "DefaultClause";
|
||||
SyntaxKind[SyntaxKind["HeritageClause"] = 299] = "HeritageClause";
|
||||
SyntaxKind[SyntaxKind["CatchClause"] = 300] = "CatchClause";
|
||||
SyntaxKind[SyntaxKind["ImportAttributes"] = 301] = "ImportAttributes";
|
||||
SyntaxKind[SyntaxKind["ImportAttribute"] = 302] = "ImportAttribute";
|
||||
SyntaxKind[SyntaxKind["PropertyAssignment"] = 303] = "PropertyAssignment";
|
||||
SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 304] = "ShorthandPropertyAssignment";
|
||||
SyntaxKind[SyntaxKind["SpreadAssignment"] = 305] = "SpreadAssignment";
|
||||
SyntaxKind[SyntaxKind["EnumMember"] = 306] = "EnumMember";
|
||||
SyntaxKind[SyntaxKind["SourceFile"] = 307] = "SourceFile";
|
||||
SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 308] = "JSDocTypeExpression";
|
||||
SyntaxKind[SyntaxKind["JSDocNameReference"] = 309] = "JSDocNameReference";
|
||||
SyntaxKind[SyntaxKind["JSDocAllType"] = 310] = "JSDocAllType";
|
||||
SyntaxKind[SyntaxKind["JSDocNullableType"] = 311] = "JSDocNullableType";
|
||||
SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 312] = "JSDocNonNullableType";
|
||||
SyntaxKind[SyntaxKind["JSDocOptionalType"] = 313] = "JSDocOptionalType";
|
||||
SyntaxKind[SyntaxKind["JSDocVariadicType"] = 314] = "JSDocVariadicType";
|
||||
SyntaxKind[SyntaxKind["JSDoc"] = 315] = "JSDoc";
|
||||
SyntaxKind[SyntaxKind["JSDocText"] = 316] = "JSDocText";
|
||||
SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 317] = "JSDocTypeLiteral";
|
||||
SyntaxKind[SyntaxKind["JSDocSignature"] = 318] = "JSDocSignature";
|
||||
SyntaxKind[SyntaxKind["JSDocLink"] = 319] = "JSDocLink";
|
||||
SyntaxKind[SyntaxKind["JSDocLinkCode"] = 320] = "JSDocLinkCode";
|
||||
SyntaxKind[SyntaxKind["JSDocLinkPlain"] = 321] = "JSDocLinkPlain";
|
||||
SyntaxKind[SyntaxKind["JSDocUnknownTag"] = 322] = "JSDocUnknownTag";
|
||||
SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 323] = "JSDocAugmentsTag";
|
||||
SyntaxKind[SyntaxKind["JSDocImplementsTag"] = 324] = "JSDocImplementsTag";
|
||||
SyntaxKind[SyntaxKind["JSDocDeprecatedTag"] = 325] = "JSDocDeprecatedTag";
|
||||
SyntaxKind[SyntaxKind["JSDocPublicTag"] = 326] = "JSDocPublicTag";
|
||||
SyntaxKind[SyntaxKind["JSDocPrivateTag"] = 327] = "JSDocPrivateTag";
|
||||
SyntaxKind[SyntaxKind["JSDocProtectedTag"] = 328] = "JSDocProtectedTag";
|
||||
SyntaxKind[SyntaxKind["JSDocReadonlyTag"] = 329] = "JSDocReadonlyTag";
|
||||
SyntaxKind[SyntaxKind["JSDocOverrideTag"] = 330] = "JSDocOverrideTag";
|
||||
SyntaxKind[SyntaxKind["JSDocCallbackTag"] = 331] = "JSDocCallbackTag";
|
||||
SyntaxKind[SyntaxKind["JSDocOverloadTag"] = 332] = "JSDocOverloadTag";
|
||||
SyntaxKind[SyntaxKind["JSDocParameterTag"] = 333] = "JSDocParameterTag";
|
||||
SyntaxKind[SyntaxKind["JSDocReturnTag"] = 334] = "JSDocReturnTag";
|
||||
SyntaxKind[SyntaxKind["JSDocThisTag"] = 335] = "JSDocThisTag";
|
||||
SyntaxKind[SyntaxKind["JSDocTypeTag"] = 336] = "JSDocTypeTag";
|
||||
SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 337] = "JSDocTemplateTag";
|
||||
SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 338] = "JSDocTypedefTag";
|
||||
SyntaxKind[SyntaxKind["JSDocSeeTag"] = 339] = "JSDocSeeTag";
|
||||
SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 340] = "JSDocPropertyTag";
|
||||
SyntaxKind[SyntaxKind["JSDocThrowsTag"] = 341] = "JSDocThrowsTag";
|
||||
SyntaxKind[SyntaxKind["JSDocSatisfiesTag"] = 342] = "JSDocSatisfiesTag";
|
||||
SyntaxKind[SyntaxKind["JSDocImportTag"] = 343] = "JSDocImportTag";
|
||||
SyntaxKind[SyntaxKind["SyntaxList"] = 344] = "SyntaxList";
|
||||
SyntaxKind[SyntaxKind["JSTypeAliasDeclaration"] = 345] = "JSTypeAliasDeclaration";
|
||||
SyntaxKind[SyntaxKind["JSImportDeclaration"] = 346] = "JSImportDeclaration";
|
||||
SyntaxKind[SyntaxKind["NotEmittedStatement"] = 347] = "NotEmittedStatement";
|
||||
SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 348] = "PartiallyEmittedExpression";
|
||||
SyntaxKind[SyntaxKind["SyntheticReferenceExpression"] = 349] = "SyntheticReferenceExpression";
|
||||
SyntaxKind[SyntaxKind["NotEmittedTypeElement"] = 350] = "NotEmittedTypeElement";
|
||||
SyntaxKind[SyntaxKind["Count"] = 351] = "Count";
|
||||
SyntaxKind[SyntaxKind["FirstAssignment"] = 63] = "FirstAssignment";
|
||||
SyntaxKind[SyntaxKind["LastAssignment"] = 78] = "LastAssignment";
|
||||
SyntaxKind[SyntaxKind["FirstCompoundAssignment"] = 64] = "FirstCompoundAssignment";
|
||||
SyntaxKind[SyntaxKind["LastCompoundAssignment"] = 78] = "LastCompoundAssignment";
|
||||
SyntaxKind[SyntaxKind["FirstReservedWord"] = 82] = "FirstReservedWord";
|
||||
SyntaxKind[SyntaxKind["LastReservedWord"] = 117] = "LastReservedWord";
|
||||
SyntaxKind[SyntaxKind["FirstKeyword"] = 82] = "FirstKeyword";
|
||||
SyntaxKind[SyntaxKind["LastKeyword"] = 166] = "LastKeyword";
|
||||
SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 118] = "FirstFutureReservedWord";
|
||||
SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 126] = "LastFutureReservedWord";
|
||||
SyntaxKind[SyntaxKind["FirstTypeNode"] = 183] = "FirstTypeNode";
|
||||
SyntaxKind[SyntaxKind["LastTypeNode"] = 206] = "LastTypeNode";
|
||||
SyntaxKind[SyntaxKind["FirstPunctuation"] = 18] = "FirstPunctuation";
|
||||
SyntaxKind[SyntaxKind["LastPunctuation"] = 78] = "LastPunctuation";
|
||||
SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken";
|
||||
SyntaxKind[SyntaxKind["LastToken"] = 166] = "LastToken";
|
||||
SyntaxKind[SyntaxKind["FirstLiteralToken"] = 8] = "FirstLiteralToken";
|
||||
SyntaxKind[SyntaxKind["LastLiteralToken"] = 14] = "LastLiteralToken";
|
||||
SyntaxKind[SyntaxKind["FirstTemplateToken"] = 14] = "FirstTemplateToken";
|
||||
SyntaxKind[SyntaxKind["LastTemplateToken"] = 17] = "LastTemplateToken";
|
||||
SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 29] = "FirstBinaryOperator";
|
||||
SyntaxKind[SyntaxKind["LastBinaryOperator"] = 78] = "LastBinaryOperator";
|
||||
SyntaxKind[SyntaxKind["FirstStatement"] = 244] = "FirstStatement";
|
||||
SyntaxKind[SyntaxKind["LastStatement"] = 260] = "LastStatement";
|
||||
SyntaxKind[SyntaxKind["FirstNode"] = 167] = "FirstNode";
|
||||
SyntaxKind[SyntaxKind["FirstJSDocNode"] = 308] = "FirstJSDocNode";
|
||||
SyntaxKind[SyntaxKind["LastJSDocNode"] = 343] = "LastJSDocNode";
|
||||
SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 322] = "FirstJSDocTagNode";
|
||||
SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 343] = "LastJSDocTagNode";
|
||||
SyntaxKind[SyntaxKind["FirstContextualKeyword"] = 127] = "FirstContextualKeyword";
|
||||
SyntaxKind[SyntaxKind["LastContextualKeyword"] = 166] = "LastContextualKeyword";
|
||||
SyntaxKind[SyntaxKind["LastUnaryOperator"] = 54] = "LastUnaryOperator";
|
||||
SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken";
|
||||
SyntaxKind[SyntaxKind["LastTriviaToken"] = 6] = "LastTriviaToken";
|
||||
})(SyntaxKind || (SyntaxKind = {}));
|
||||
//# sourceMappingURL=syntaxKind.enum.js.map
|
||||
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
function _class_private_method_get(receiver, privateSet, fn) {
|
||||
if (!privateSet.has(receiver)) throw new TypeError("attempted to get private field on non-instance");
|
||||
|
||||
return fn;
|
||||
}
|
||||
exports._ = _class_private_method_get;
|
||||
@@ -0,0 +1,90 @@
|
||||
// @ts-ignore TS6133
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v3";
|
||||
import { ZodError } from "../ZodError.js";
|
||||
import { util } from "../helpers/util.js";
|
||||
|
||||
const testTuple = z.tuple([z.string(), z.object({ name: z.literal("Rudy") }), z.array(z.literal("blue"))]);
|
||||
const testData = ["asdf", { name: "Rudy" }, ["blue"]];
|
||||
const badData = [123, { name: "Rudy2" }, ["blue", "red"]];
|
||||
|
||||
test("tuple inference", () => {
|
||||
const args1 = z.tuple([z.string()]);
|
||||
const returns1 = z.number();
|
||||
const func1 = z.function(args1, returns1);
|
||||
type func1 = z.TypeOf<typeof func1>;
|
||||
util.assertEqual<func1, (k: string) => number>(true);
|
||||
});
|
||||
|
||||
test("successful validation", () => {
|
||||
const val = testTuple.parse(testData);
|
||||
expect(val).toEqual(["asdf", { name: "Rudy" }, ["blue"]]);
|
||||
});
|
||||
|
||||
test("successful async validation", async () => {
|
||||
const val = await testTuple.parseAsync(testData);
|
||||
return expect(val).toEqual(testData);
|
||||
});
|
||||
|
||||
test("failed validation", () => {
|
||||
const checker = () => {
|
||||
testTuple.parse([123, { name: "Rudy2" }, ["blue", "red"]] as any);
|
||||
};
|
||||
try {
|
||||
checker();
|
||||
} catch (err) {
|
||||
if (err instanceof ZodError) {
|
||||
expect(err.issues.length).toEqual(3);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("failed async validation", async () => {
|
||||
const res = await testTuple.safeParse(badData);
|
||||
expect(res.success).toEqual(false);
|
||||
if (!res.success) {
|
||||
expect(res.error.issues.length).toEqual(3);
|
||||
}
|
||||
// try {
|
||||
// checker();
|
||||
// } catch (err) {
|
||||
// if (err instanceof ZodError) {
|
||||
// expect(err.issues.length).toEqual(3);
|
||||
// }
|
||||
// }
|
||||
});
|
||||
|
||||
test("tuple with transformers", () => {
|
||||
const stringToNumber = z.string().transform((val) => val.length);
|
||||
const val = z.tuple([stringToNumber]);
|
||||
|
||||
type t1 = z.input<typeof val>;
|
||||
util.assertEqual<t1, [string]>(true);
|
||||
type t2 = z.output<typeof val>;
|
||||
util.assertEqual<t2, [number]>(true);
|
||||
expect(val.parse(["1234"])).toEqual([4]);
|
||||
});
|
||||
|
||||
test("tuple with rest schema", () => {
|
||||
const myTuple = z.tuple([z.string(), z.number()]).rest(z.boolean());
|
||||
expect(myTuple.parse(["asdf", 1234, true, false, true])).toEqual(["asdf", 1234, true, false, true]);
|
||||
|
||||
expect(myTuple.parse(["asdf", 1234])).toEqual(["asdf", 1234]);
|
||||
|
||||
expect(() => myTuple.parse(["asdf", 1234, "asdf"])).toThrow();
|
||||
type t1 = z.output<typeof myTuple>;
|
||||
|
||||
util.assertEqual<t1, [string, number, ...boolean[]]>(true);
|
||||
});
|
||||
|
||||
test("parse should fail given sparse array as tuple", () => {
|
||||
expect(() => testTuple.parse(new Array(3))).toThrow();
|
||||
});
|
||||
|
||||
// test('tuple with optional elements', () => {
|
||||
// const result = z
|
||||
// .tuple([z.string(), z.number().optional()])
|
||||
// .safeParse(['asdf']);
|
||||
// expect(result).toEqual(['asdf']);
|
||||
// });
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
var classPrivateFieldGet2 = require("./classPrivateFieldGet2.js");
|
||||
function _classExtractFieldDescriptor(e, t) {
|
||||
return classPrivateFieldGet2(t, e);
|
||||
}
|
||||
module.exports = _classExtractFieldDescriptor, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
@@ -0,0 +1,166 @@
|
||||
'use strict'
|
||||
|
||||
const test = require('node:test')
|
||||
const assert = require('node:assert')
|
||||
const os = require('node:os')
|
||||
const { join } = require('node:path')
|
||||
const { readFile } = require('node:fs').promises
|
||||
const writeStream = require('flush-write-stream')
|
||||
|
||||
const { watchFileCreated, file } = require('../helper')
|
||||
const pino = require('../../')
|
||||
|
||||
const { pid } = process
|
||||
const hostname = os.hostname()
|
||||
|
||||
function serializeError (error) {
|
||||
return {
|
||||
type: error.name,
|
||||
message: error.message,
|
||||
stack: error.stack
|
||||
}
|
||||
}
|
||||
|
||||
function parseLogs (buffer) {
|
||||
return JSON.parse(`[${buffer.toString().replace(/}{/g, '},{')}]`)
|
||||
}
|
||||
|
||||
test('transport uses pino config', async (t) => {
|
||||
const destination = file()
|
||||
const transport = pino.transport({
|
||||
pipeline: [{
|
||||
target: join(__dirname, '..', 'fixtures', 'transport-uses-pino-config.js')
|
||||
}, {
|
||||
target: 'pino/file',
|
||||
options: { destination }
|
||||
}]
|
||||
})
|
||||
t.after(transport.end.bind(transport))
|
||||
const instance = pino({
|
||||
messageKey: 'customMessageKey',
|
||||
errorKey: 'customErrorKey',
|
||||
customLevels: { custom: 35 }
|
||||
}, transport)
|
||||
|
||||
const error = new Error('bar')
|
||||
instance.custom('foo')
|
||||
instance.error(error)
|
||||
await watchFileCreated(destination)
|
||||
const result = parseLogs(await readFile(destination))
|
||||
|
||||
assert.deepEqual(result, [{
|
||||
severityText: 'custom',
|
||||
body: 'foo',
|
||||
attributes: {
|
||||
pid,
|
||||
hostname
|
||||
}
|
||||
}, {
|
||||
severityText: 'error',
|
||||
body: 'bar',
|
||||
attributes: {
|
||||
pid,
|
||||
hostname
|
||||
},
|
||||
error: serializeError(error)
|
||||
}])
|
||||
})
|
||||
|
||||
test('transport uses pino config without customizations', async (t) => {
|
||||
const destination = file()
|
||||
const transport = pino.transport({
|
||||
pipeline: [{
|
||||
target: join(__dirname, '..', 'fixtures', 'transport-uses-pino-config.js')
|
||||
}, {
|
||||
target: 'pino/file',
|
||||
options: { destination }
|
||||
}]
|
||||
})
|
||||
t.after(transport.end.bind(transport))
|
||||
const instance = pino(transport)
|
||||
|
||||
const error = new Error('qux')
|
||||
instance.info('baz')
|
||||
instance.error(error)
|
||||
await watchFileCreated(destination)
|
||||
const result = parseLogs(await readFile(destination))
|
||||
|
||||
assert.deepEqual(result, [{
|
||||
severityText: 'info',
|
||||
body: 'baz',
|
||||
attributes: {
|
||||
pid,
|
||||
hostname
|
||||
}
|
||||
}, {
|
||||
severityText: 'error',
|
||||
body: 'qux',
|
||||
attributes: {
|
||||
pid,
|
||||
hostname
|
||||
},
|
||||
error: serializeError(error)
|
||||
}])
|
||||
})
|
||||
|
||||
test('transport uses pino config with multistream', async (t) => {
|
||||
const destination = file()
|
||||
const messages = []
|
||||
const stream = writeStream(function (data, enc, cb) {
|
||||
const message = JSON.parse(data)
|
||||
delete message.time
|
||||
messages.push(message)
|
||||
cb()
|
||||
})
|
||||
const transport = pino.transport({
|
||||
pipeline: [{
|
||||
target: join(__dirname, '..', 'fixtures', 'transport-uses-pino-config.js')
|
||||
}, {
|
||||
target: 'pino/file',
|
||||
options: { destination }
|
||||
}]
|
||||
})
|
||||
t.after(transport.end.bind(transport))
|
||||
const instance = pino({
|
||||
messageKey: 'customMessageKey',
|
||||
errorKey: 'customErrorKey',
|
||||
customLevels: { custom: 35 }
|
||||
}, pino.multistream([transport, { stream }]))
|
||||
|
||||
const error = new Error('buzz')
|
||||
const serializedError = serializeError(error)
|
||||
instance.custom('fizz')
|
||||
instance.error(error)
|
||||
await watchFileCreated(destination)
|
||||
const result = parseLogs(await readFile(destination))
|
||||
|
||||
assert.deepEqual(result, [{
|
||||
severityText: 'custom',
|
||||
body: 'fizz',
|
||||
attributes: {
|
||||
pid,
|
||||
hostname
|
||||
}
|
||||
}, {
|
||||
severityText: 'error',
|
||||
body: 'buzz',
|
||||
attributes: {
|
||||
pid,
|
||||
hostname
|
||||
},
|
||||
error: serializedError
|
||||
}])
|
||||
|
||||
assert.deepEqual(messages, [{
|
||||
level: 35,
|
||||
pid,
|
||||
hostname,
|
||||
customMessageKey: 'fizz'
|
||||
}, {
|
||||
level: 50,
|
||||
pid,
|
||||
hostname,
|
||||
customErrorKey: serializedError,
|
||||
customMessageKey: 'buzz'
|
||||
}])
|
||||
})
|
||||
@@ -0,0 +1,2 @@
|
||||
import type { TSESTree } from '@typescript-eslint/utils';
|
||||
export declare function isUndefinedIdentifier(i: TSESTree.Node): boolean;
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "@types/connect",
|
||||
"version": "3.4.38",
|
||||
"description": "TypeScript definitions for connect",
|
||||
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/connect",
|
||||
"license": "MIT",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Maxime LUCE",
|
||||
"githubUsername": "SomaticIT",
|
||||
"url": "https://github.com/SomaticIT"
|
||||
},
|
||||
{
|
||||
"name": "Evan Hahn",
|
||||
"githubUsername": "EvanHahn",
|
||||
"url": "https://github.com/EvanHahn"
|
||||
}
|
||||
],
|
||||
"main": "",
|
||||
"types": "index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||
"directory": "types/connect"
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
},
|
||||
"typesPublisherContentHash": "8990242237504bdec53088b79e314b94bec69286df9de56db31f22de403b4092",
|
||||
"typeScriptVersion": "4.5"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"wss.js","sourceRoot":"","sources":["../../../src/schemes/wss.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,MAAM,CAAC;AAEtB,MAAM,OAAO,GAAoB;IAChC,MAAM,EAAG,KAAK;IACd,UAAU,EAAG,EAAE,CAAC,UAAU;IAC1B,KAAK,EAAG,EAAE,CAAC,KAAK;IAChB,SAAS,EAAG,EAAE,CAAC,SAAS;CACxB,CAAA;AAED,eAAe,OAAO,CAAC"}
|
||||
@@ -0,0 +1 @@
|
||||
export { _ as default } from "../esm/_ts_add_disposable_resource.js";
|
||||
@@ -0,0 +1,36 @@
|
||||
import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
|
||||
/**
|
||||
* Generates report loc suitable for reporting on how a class member is
|
||||
* declared, rather than how it's implemented.
|
||||
*
|
||||
* ```ts
|
||||
* class A {
|
||||
* abstract method(): void;
|
||||
* ~~~~~~~~~~~~~~~
|
||||
*
|
||||
* concreteMethod(): void {
|
||||
* ~~~~~~~~~~~~~~
|
||||
* // code
|
||||
* }
|
||||
*
|
||||
* abstract private property?: string;
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* @decorator override concreteProperty = 'value';
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export declare function getMemberHeadLoc(sourceCode: Readonly<TSESLint.SourceCode>, node: TSESTree.AccessorProperty | TSESTree.MethodDefinition | TSESTree.PropertyDefinition | TSESTree.TSAbstractAccessorProperty | TSESTree.TSAbstractMethodDefinition | TSESTree.TSAbstractPropertyDefinition): TSESTree.SourceLocation;
|
||||
/**
|
||||
* Generates report loc suitable for reporting on how a parameter property is
|
||||
* declared.
|
||||
*
|
||||
* ```ts
|
||||
* class A {
|
||||
* constructor(private property: string = 'value') {
|
||||
* ~~~~~~~~~~~~~~~~
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export declare function getParameterPropertyHeadLoc(sourceCode: Readonly<TSESLint.SourceCode>, node: TSESTree.TSParameterProperty, nodeName: string): TSESTree.SourceLocation;
|
||||
@@ -0,0 +1,42 @@
|
||||
import * as scopeManager from '@typescript-eslint/scope-manager';
|
||||
export declare namespace Scope {
|
||||
type ScopeManager = scopeManager.ScopeManager;
|
||||
type Reference = scopeManager.Reference;
|
||||
type Variable = scopeManager.ScopeVariable;
|
||||
type Scope = scopeManager.Scope;
|
||||
const ScopeType: typeof scopeManager.ScopeType;
|
||||
type DefinitionType = scopeManager.Definition;
|
||||
type Definition = scopeManager.Definition;
|
||||
const DefinitionType: typeof scopeManager.DefinitionType;
|
||||
namespace Definitions {
|
||||
type CatchClauseDefinition = scopeManager.CatchClauseDefinition;
|
||||
type ClassNameDefinition = scopeManager.ClassNameDefinition;
|
||||
type FunctionNameDefinition = scopeManager.FunctionNameDefinition;
|
||||
type ImplicitGlobalVariableDefinition = scopeManager.ImplicitGlobalVariableDefinition;
|
||||
type ImportBindingDefinition = scopeManager.ImportBindingDefinition;
|
||||
type ParameterDefinition = scopeManager.ParameterDefinition;
|
||||
type TSEnumMemberDefinition = scopeManager.TSEnumMemberDefinition;
|
||||
type TSEnumNameDefinition = scopeManager.TSEnumNameDefinition;
|
||||
type TSModuleNameDefinition = scopeManager.TSModuleNameDefinition;
|
||||
type TypeDefinition = scopeManager.TypeDefinition;
|
||||
type VariableDefinition = scopeManager.VariableDefinition;
|
||||
}
|
||||
namespace Scopes {
|
||||
type BlockScope = scopeManager.BlockScope;
|
||||
type CatchScope = scopeManager.CatchScope;
|
||||
type ClassScope = scopeManager.ClassScope;
|
||||
type ConditionalTypeScope = scopeManager.ConditionalTypeScope;
|
||||
type ForScope = scopeManager.ForScope;
|
||||
type FunctionExpressionNameScope = scopeManager.FunctionExpressionNameScope;
|
||||
type FunctionScope = scopeManager.FunctionScope;
|
||||
type FunctionTypeScope = scopeManager.FunctionTypeScope;
|
||||
type GlobalScope = scopeManager.GlobalScope;
|
||||
type MappedTypeScope = scopeManager.MappedTypeScope;
|
||||
type ModuleScope = scopeManager.ModuleScope;
|
||||
type SwitchScope = scopeManager.SwitchScope;
|
||||
type TSEnumScope = scopeManager.TSEnumScope;
|
||||
type TSModuleScope = scopeManager.TSModuleScope;
|
||||
type TypeScope = scopeManager.TypeScope;
|
||||
type WithScope = scopeManager.WithScope;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
'use strict'
|
||||
|
||||
function noOpPrepareStackTrace (_, stack) {
|
||||
return stack
|
||||
}
|
||||
|
||||
module.exports = function getCallers () {
|
||||
const originalPrepare = Error.prepareStackTrace
|
||||
Error.prepareStackTrace = noOpPrepareStackTrace
|
||||
const stack = new Error().stack
|
||||
Error.prepareStackTrace = originalPrepare
|
||||
|
||||
if (!Array.isArray(stack)) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const entries = stack.slice(2)
|
||||
|
||||
const fileNames = []
|
||||
|
||||
for (const entry of entries) {
|
||||
if (!entry) {
|
||||
continue
|
||||
}
|
||||
|
||||
fileNames.push(entry.getFileName())
|
||||
}
|
||||
|
||||
return fileNames
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
import * as ts from 'typescript';
|
||||
/**
|
||||
* Gets all of the type flags in a type, iterating through unions automatically.
|
||||
*/
|
||||
export declare function getTypeFlags(type: ts.Type): ts.TypeFlags;
|
||||
/**
|
||||
* @param flagsToCheck The composition of one or more `ts.TypeFlags`.
|
||||
* @param isReceiver Whether the type is a receiving type (e.g. the type of a
|
||||
* called function's parameter).
|
||||
* @remarks
|
||||
* Note that if the type is a union, this function will decompose it into the
|
||||
* parts and get the flags of every union constituent. If this is not desired,
|
||||
* use the `isTypeFlag` function from tsutils.
|
||||
*/
|
||||
export declare function isTypeFlagSet(type: ts.Type, flagsToCheck: ts.TypeFlags,
|
||||
/** @deprecated This params is not used and will be removed in the future.*/
|
||||
isReceiver?: boolean): boolean;
|
||||
@@ -0,0 +1,9 @@
|
||||
export interface Disposable {
|
||||
/**
|
||||
* Dispose this object.
|
||||
*/
|
||||
dispose(): void;
|
||||
}
|
||||
export declare namespace Disposable {
|
||||
function create(func: () => void): Disposable;
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
import { checkSync } from "recheck";
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("basic datetime parsing", () => {
|
||||
const datetime = z.string().datetime();
|
||||
datetime.parse("1970-01-01T00:00:00.000Z");
|
||||
datetime.parse("2022-10-13T09:52:31.816Z");
|
||||
datetime.parse("2022-10-13T09:52:31.8162314Z");
|
||||
datetime.parse("1970-01-01T00:00:00Z");
|
||||
datetime.parse("2022-10-13T09:52:31Z");
|
||||
expect(() => datetime.parse("")).toThrow();
|
||||
expect(() => datetime.parse("foo")).toThrow();
|
||||
expect(() => datetime.parse("2020-10-14")).toThrow();
|
||||
expect(() => datetime.parse("T18:45:12.123")).toThrow();
|
||||
expect(() => datetime.parse("2020-10-14T17:42:29+00:00")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with precision -1", () => {
|
||||
const datetimeNoMs = z.string().datetime({ precision: -1, offset: true, local: true });
|
||||
datetimeNoMs.parse("1970-01-01T00:00Z");
|
||||
datetimeNoMs.parse("2022-10-13T09:52Z");
|
||||
datetimeNoMs.parse("2022-10-13T09:52+02:00");
|
||||
|
||||
datetimeNoMs.parse("2022-10-13T09:52");
|
||||
expect(() => datetimeNoMs.parse("tuna")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("2022-10-13T09:52+02")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.000Z")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.Z")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("2022-10-13T09:52:31.816Z")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with precision 0", () => {
|
||||
const datetimeNoMs = z.string().datetime({ precision: 0 });
|
||||
datetimeNoMs.parse("1970-01-01T00:00:00Z");
|
||||
datetimeNoMs.parse("2022-10-13T09:52:31Z");
|
||||
expect(() => datetimeNoMs.parse("tuna")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.000Z")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.Z")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("2022-10-13T09:52:31.816Z")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with precision 3", () => {
|
||||
const datetime3Ms = z.string().datetime({ precision: 3 });
|
||||
datetime3Ms.parse("1970-01-01T00:00:00.000Z");
|
||||
datetime3Ms.parse("2022-10-13T09:52:31.123Z");
|
||||
expect(() => datetime3Ms.parse("tuna")).toThrow();
|
||||
expect(() => datetime3Ms.parse("1970-01-01T00:00:00.1Z")).toThrow();
|
||||
expect(() => datetime3Ms.parse("1970-01-01T00:00:00.12Z")).toThrow();
|
||||
expect(() => datetime3Ms.parse("2022-10-13T09:52:31Z")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with offset", () => {
|
||||
const datetimeOffset = z.string().datetime({ offset: true });
|
||||
datetimeOffset.parse("1970-01-01T00:00:00.000Z");
|
||||
datetimeOffset.parse("2022-10-13T09:52:31.816234134Z");
|
||||
datetimeOffset.parse("1970-01-01T00:00:00Z");
|
||||
datetimeOffset.parse("2022-10-13T09:52:31.4Z");
|
||||
datetimeOffset.parse("2020-10-14T17:42:29+00:00");
|
||||
datetimeOffset.parse("2020-10-14T17:42:29+03:15");
|
||||
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+0315")).toThrow();
|
||||
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+03")).toThrow();
|
||||
expect(() => datetimeOffset.parse("tuna")).toThrow();
|
||||
expect(() => datetimeOffset.parse("2022-10-13T09:52:31.Z")).toThrow();
|
||||
|
||||
// Invalid offset tests
|
||||
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+24:00")).toThrow(); // out of range hours
|
||||
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+00:60")).toThrow(); // out of range minutes
|
||||
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+1:30")).toThrow(); // single digit hours
|
||||
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+00:")).toThrow(); // incomplete offset
|
||||
});
|
||||
|
||||
test("datetime parsing with offset and precision 0", () => {
|
||||
const datetimeOffsetNoMs = z.string().datetime({ offset: true, precision: 0 });
|
||||
datetimeOffsetNoMs.parse("1970-01-01T00:00:00Z");
|
||||
datetimeOffsetNoMs.parse("2022-10-13T09:52:31Z");
|
||||
datetimeOffsetNoMs.parse("2020-10-14T17:42:29+00:00");
|
||||
expect(() => datetimeOffsetNoMs.parse("2020-10-14T17:42:29+0000")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("2020-10-14T17:42:29+00")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("tuna")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("1970-01-01T00:00:00.000Z")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("1970-01-01T00:00:00.Z")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("2022-10-13T09:52:31.816Z")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("2020-10-14T17:42:29.124+00:00")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with offset and precision 4", () => {
|
||||
const datetimeOffset4Ms = z.string().datetime({ offset: true, precision: 4 });
|
||||
datetimeOffset4Ms.parse("1970-01-01T00:00:00.1234Z");
|
||||
datetimeOffset4Ms.parse("2020-10-14T17:42:29.1234+00:00");
|
||||
expect(() => datetimeOffset4Ms.parse("2020-10-14T17:42:29.1234+0000")).toThrow();
|
||||
expect(() => datetimeOffset4Ms.parse("2020-10-14T17:42:29.1234+00")).toThrow();
|
||||
expect(() => datetimeOffset4Ms.parse("tuna")).toThrow();
|
||||
expect(() => datetimeOffset4Ms.parse("1970-01-01T00:00:00.123Z")).toThrow();
|
||||
expect(() => datetimeOffset4Ms.parse("2020-10-14T17:42:29.124+00:00")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime offset normalization", () => {
|
||||
const a = z.iso.datetime({ offset: true });
|
||||
|
||||
expect(a.safeParse("2020-10-14T17:42:29+02")).toMatchObject({ success: false });
|
||||
expect(a.safeParse("2020-10-14T17:42:29+0200")).toMatchObject({ success: false });
|
||||
a.safeParse("2020-10-14T17:42:29+02:00");
|
||||
});
|
||||
|
||||
test("datetime parsing with local option", () => {
|
||||
const a = z.string().datetime({ local: true });
|
||||
|
||||
expect(a.safeParse("1970-01-01T00:00")).toMatchObject({ success: true });
|
||||
expect(a.safeParse("1970-01-01T00:00:00")).toMatchObject({ success: true });
|
||||
expect(a.safeParse("2022-10-13T09:52:31.816")).toMatchObject({ success: true });
|
||||
expect(a.safeParse("1970-01-01T00:00:00.000")).toMatchObject({ success: true });
|
||||
expect(a.safeParse("1970-01-01T00")).toMatchObject({ success: false });
|
||||
|
||||
// Should reject timezone indicators and invalid formats
|
||||
|
||||
expect(() => a.parse("2022-10-13T09:52:31+00:00")).toThrow();
|
||||
expect(() => a.parse("2022-10-13 09:52:31")).toThrow();
|
||||
expect(() => a.parse("2022-10-13T24:52:31")).toThrow();
|
||||
expect(() => a.parse("2022-10-13T24:52")).toThrow();
|
||||
expect(() => a.parse("2022-10-13T24:52Z")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with local and offset", () => {
|
||||
const a = z.string().datetime({ local: true, offset: true });
|
||||
|
||||
// expect(a.parse("2022-10-13T12:52")).toEqual("2022-10-13T12:52:00");
|
||||
a.parse("2022-10-13T12:52:00");
|
||||
a.parse("2022-10-13T12:52:00Z");
|
||||
a.parse("2022-10-13T12:52Z");
|
||||
a.parse("2022-10-13T12:52");
|
||||
a.parse("2022-10-13T12:52+02:00");
|
||||
expect(() => a.parse("2022-10-13T12:52:00+02")).toThrow();
|
||||
// expect(() => a.parse("2022-10-13T12:52Z")).toThrow();
|
||||
// expect(() => a.parse("2022-10-13T12:52+02:00")).toThrow();
|
||||
});
|
||||
|
||||
test("date parsing", () => {
|
||||
const date = z.string().date();
|
||||
date.parse("1970-01-01");
|
||||
date.parse("2022-01-31");
|
||||
date.parse("2022-03-31");
|
||||
date.parse("2022-04-30");
|
||||
date.parse("2022-05-31");
|
||||
date.parse("2022-06-30");
|
||||
date.parse("2022-07-31");
|
||||
date.parse("2022-08-31");
|
||||
date.parse("2022-09-30");
|
||||
date.parse("2022-10-31");
|
||||
date.parse("2022-11-30");
|
||||
date.parse("2022-12-31");
|
||||
|
||||
date.parse("2000-02-29");
|
||||
date.parse("2400-02-29");
|
||||
expect(() => date.parse("2022-02-29")).toThrow();
|
||||
expect(() => date.parse("2100-02-29")).toThrow();
|
||||
expect(() => date.parse("2200-02-29")).toThrow();
|
||||
expect(() => date.parse("2300-02-29")).toThrow();
|
||||
expect(() => date.parse("2500-02-29")).toThrow();
|
||||
|
||||
expect(() => date.parse("")).toThrow();
|
||||
expect(() => date.parse("foo")).toThrow();
|
||||
expect(() => date.parse("200-01-01")).toThrow();
|
||||
expect(() => date.parse("20000-01-01")).toThrow();
|
||||
expect(() => date.parse("2000-0-01")).toThrow();
|
||||
expect(() => date.parse("2000-011-01")).toThrow();
|
||||
expect(() => date.parse("2000-01-0")).toThrow();
|
||||
expect(() => date.parse("2000-01-011")).toThrow();
|
||||
expect(() => date.parse("2000/01/01")).toThrow();
|
||||
expect(() => date.parse("01-01-2022")).toThrow();
|
||||
expect(() => date.parse("01/01/2022")).toThrow();
|
||||
expect(() => date.parse("2000-01-01 00:00:00Z")).toThrow();
|
||||
expect(() => date.parse("2020-10-14T17:42:29+00:00")).toThrow();
|
||||
expect(() => date.parse("2020-10-14T17:42:29Z")).toThrow();
|
||||
expect(() => date.parse("2020-10-14T17:42:29")).toThrow();
|
||||
expect(() => date.parse("2020-10-14T17:42:29.123Z")).toThrow();
|
||||
|
||||
expect(() => date.parse("2000-00-12")).toThrow();
|
||||
expect(() => date.parse("2000-12-00")).toThrow();
|
||||
expect(() => date.parse("2000-01-32")).toThrow();
|
||||
expect(() => date.parse("2000-13-01")).toThrow();
|
||||
expect(() => date.parse("2000-21-01")).toThrow();
|
||||
|
||||
expect(() => date.parse("2000-02-30")).toThrow();
|
||||
expect(() => date.parse("2000-02-31")).toThrow();
|
||||
expect(() => date.parse("2000-04-31")).toThrow();
|
||||
expect(() => date.parse("2000-06-31")).toThrow();
|
||||
expect(() => date.parse("2000-09-31")).toThrow();
|
||||
expect(() => date.parse("2000-11-31")).toThrow();
|
||||
});
|
||||
|
||||
test("time parsing", () => {
|
||||
const time = z.string().time();
|
||||
time.parse("00:00:00");
|
||||
time.parse("23:00:00");
|
||||
time.parse("00:59:00");
|
||||
time.parse("00:00:59");
|
||||
time.parse("23:59:59");
|
||||
time.parse("09:52:31");
|
||||
time.parse("23:59:59.9999999");
|
||||
time.parse("00:00");
|
||||
expect(() => time.parse("")).toThrow();
|
||||
expect(() => time.parse("foo")).toThrow();
|
||||
expect(() => time.parse("00:00:00Z")).toThrow();
|
||||
expect(() => time.parse("0:00:00")).toThrow();
|
||||
expect(() => time.parse("00:0:00")).toThrow();
|
||||
expect(() => time.parse("00:00:0")).toThrow();
|
||||
expect(() => time.parse("00:00:00.000+00:00")).toThrow();
|
||||
expect(() => time.parse("24:00:00")).toThrow();
|
||||
expect(() => time.parse("00:60:00")).toThrow();
|
||||
expect(() => time.parse("00:00:60")).toThrow();
|
||||
expect(() => time.parse("24:60:60")).toThrow();
|
||||
|
||||
const time2 = z.string().time({ precision: 2 });
|
||||
time2.parse("00:00:00.00");
|
||||
time2.parse("09:52:31.12");
|
||||
time2.parse("23:59:59.99");
|
||||
expect(() => time2.parse("")).toThrow();
|
||||
expect(() => time2.parse("foo")).toThrow();
|
||||
expect(() => time2.parse("00:00:00")).toThrow();
|
||||
expect(() => time2.parse("00:00:00.00Z")).toThrow();
|
||||
expect(() => time2.parse("00:00:00.0")).toThrow();
|
||||
expect(() => time2.parse("00:00:00.000")).toThrow();
|
||||
expect(() => time2.parse("00:00:00.00+00:00")).toThrow();
|
||||
|
||||
const time3 = z.string().time({ precision: z.TimePrecision.Minute });
|
||||
time3.parse("00:00");
|
||||
expect(() => time3.parse("00:00:00")).toThrow();
|
||||
});
|
||||
|
||||
test("duration", () => {
|
||||
const duration = z.string().duration();
|
||||
|
||||
const validDurations = [
|
||||
"P3Y6M4DT12H30M5S",
|
||||
"P2Y9M3DT12H31M8.001S",
|
||||
// "+P3Y6M4DT12H30M5S",
|
||||
// "-PT0.001S",
|
||||
// "+PT0.001S",
|
||||
"PT0,001S",
|
||||
"PT12H30M5S",
|
||||
// "-P2M1D",
|
||||
// "P-2M-1D",
|
||||
// "-P5DT10H",
|
||||
// "P-5DT-10H",
|
||||
"P1Y",
|
||||
"P2MT30M",
|
||||
"PT6H",
|
||||
"P5W",
|
||||
// "P0.5Y",
|
||||
// "P0,5Y",
|
||||
// "P42YT7.004M",
|
||||
];
|
||||
|
||||
const invalidDurations = [
|
||||
"foo bar",
|
||||
"",
|
||||
" ",
|
||||
"P",
|
||||
"PT",
|
||||
"P1Y2MT",
|
||||
"T1H",
|
||||
"P0.5Y1D",
|
||||
"P0,5Y6M",
|
||||
"P1YT",
|
||||
"P-2M-1D",
|
||||
"P-5DT-10H",
|
||||
"P1W2D",
|
||||
"-P1D",
|
||||
];
|
||||
|
||||
for (const val of validDurations) {
|
||||
const result = duration.safeParse(val);
|
||||
if (!result.success) {
|
||||
throw Error(`Valid duration could not be parsed: ${val}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const val of invalidDurations) {
|
||||
const result = duration.safeParse(val);
|
||||
|
||||
if (result.success) {
|
||||
throw Error(`Invalid duration was successful parsed: ${val}`);
|
||||
}
|
||||
|
||||
expect(result.error.issues[0].message).toEqual("Invalid ISO duration");
|
||||
}
|
||||
});
|
||||
|
||||
test("redos checker", () => {
|
||||
const a = z.iso.datetime();
|
||||
const b = z.string().datetime({ offset: true });
|
||||
const c = z.string().datetime({ local: true });
|
||||
const d = z.string().datetime({ local: true, offset: true, precision: 3 });
|
||||
const e = z.string().date();
|
||||
const f = z.string().time();
|
||||
const g = z.string().duration();
|
||||
for (const schema of [a, b, c, d, e, f, g]) {
|
||||
const result = checkSync(schema._zod.pattern.source, "");
|
||||
if (result.status !== "safe") throw Error("ReDoS issue");
|
||||
}
|
||||
}, 10000);
|
||||
@@ -0,0 +1,20 @@
|
||||
(c) 2007-2009 Steven Levithan <stevenlevithan.com>
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,151 @@
|
||||
export { ObjectSchema } from "@eslint/object-schema";
|
||||
export type PropertyDefinition = $eslintobjectschema.PropertyDefinition;
|
||||
export type ObjectDefinition = $eslintobjectschema.ObjectDefinition;
|
||||
export type ConfigObject = $typests.ConfigObject;
|
||||
export type FileMatcher = $typests.FileMatcher;
|
||||
export type FilesMatcher = $typests.FilesMatcher;
|
||||
export type ExtraConfigType = $typests.ExtraConfigType;
|
||||
export type MinimatchOptions = $minimatch.MinimatchOptions;
|
||||
export type ObjectSchemaInstance = ObjectSchema;
|
||||
/**
|
||||
* Represents an array of config objects and provides method for working with
|
||||
* those config objects.
|
||||
*/
|
||||
export class ConfigArray extends Array<any> {
|
||||
/**
|
||||
* Creates a new instance of ConfigArray.
|
||||
* @param {Iterable|Function|Object} configs An iterable yielding config
|
||||
* objects, or a config function, or a config object.
|
||||
* @param {Object} options The options for the ConfigArray.
|
||||
* @param {string} [options.basePath="/"] The absolute path of the config file directory.
|
||||
* Defaults to `"/"`.
|
||||
* @param {boolean} [options.normalized=false] Flag indicating if the
|
||||
* configs have already been normalized.
|
||||
* @param {ObjectDefinition} [options.schema] The additional schema
|
||||
* definitions to use for the ConfigArray schema.
|
||||
* @param {ReadonlyArray<ExtraConfigType>} [options.extraConfigTypes] List of config types supported.
|
||||
* @throws {TypeError} When the `basePath` is not a non-empty string,
|
||||
*/
|
||||
constructor(configs: Iterable<any> | Function | any, { basePath, normalized, schema: customSchema, extraConfigTypes, }?: {
|
||||
basePath?: string;
|
||||
normalized?: boolean;
|
||||
schema?: ObjectDefinition;
|
||||
extraConfigTypes?: ReadonlyArray<ExtraConfigType>;
|
||||
});
|
||||
/**
|
||||
* The path of the config file that this array was loaded from.
|
||||
* This is used to calculate filename matches.
|
||||
* @property basePath
|
||||
* @type {string}
|
||||
*/
|
||||
basePath: string;
|
||||
/**
|
||||
* The supported config types.
|
||||
* @type {ReadonlyArray<ExtraConfigType>}
|
||||
*/
|
||||
extraConfigTypes: ReadonlyArray<ExtraConfigType>;
|
||||
/**
|
||||
* Returns the `files` globs from every config object in the array.
|
||||
* This can be used to determine which files will be matched by a
|
||||
* config array or to use as a glob pattern when no patterns are provided
|
||||
* for a command line interface.
|
||||
* @returns {Array<FilesMatcher>} An array of matchers.
|
||||
*/
|
||||
get files(): Array<FilesMatcher>;
|
||||
/**
|
||||
* Returns ignore matchers that should always be ignored regardless of
|
||||
* the matching `files` fields in any configs. This is necessary to mimic
|
||||
* the behavior of things like .gitignore and .eslintignore, allowing a
|
||||
* globbing operation to be faster.
|
||||
* @returns {Array<{ basePath?: string, name?: string, ignores: FileMatcher[] }>} An array of config objects representing global ignores.
|
||||
*/
|
||||
get ignores(): Array<{
|
||||
basePath?: string;
|
||||
name?: string;
|
||||
ignores: FileMatcher[];
|
||||
}>;
|
||||
/**
|
||||
* Indicates if the config array has been normalized.
|
||||
* @returns {boolean} True if the config array is normalized, false if not.
|
||||
*/
|
||||
isNormalized(): boolean;
|
||||
/**
|
||||
* Normalizes a config array by flattening embedded arrays and executing
|
||||
* config functions.
|
||||
* @param {Object} [context] The context object for config functions.
|
||||
* @returns {Promise<ConfigArray>} The current ConfigArray instance.
|
||||
*/
|
||||
normalize(context?: any): Promise<ConfigArray>;
|
||||
/**
|
||||
* Normalizes a config array by flattening embedded arrays and executing
|
||||
* config functions.
|
||||
* @param {Object} [context] The context object for config functions.
|
||||
* @returns {ConfigArray} The current ConfigArray instance.
|
||||
*/
|
||||
normalizeSync(context?: any): ConfigArray;
|
||||
/**
|
||||
* Returns the config object for a given file path and a status that can be used to determine why a file has no config.
|
||||
* @param {string} filePath The path of a file to get a config for.
|
||||
* @returns {{ config?: Object, status: "ignored"|"external"|"unconfigured"|"matched" }}
|
||||
* An object with an optional property `config` and property `status`.
|
||||
* `config` is the config object for the specified file as returned by {@linkcode ConfigArray.getConfig},
|
||||
* `status` a is one of the constants returned by {@linkcode ConfigArray.getConfigStatus}.
|
||||
*/
|
||||
getConfigWithStatus(filePath: string): {
|
||||
config?: any;
|
||||
status: "ignored" | "external" | "unconfigured" | "matched";
|
||||
};
|
||||
/**
|
||||
* Returns the config object for a given file path.
|
||||
* @param {string} filePath The path of a file to get a config for.
|
||||
* @returns {Object|undefined} The config object for this file or `undefined`.
|
||||
*/
|
||||
getConfig(filePath: string): any | undefined;
|
||||
/**
|
||||
* Determines whether a file has a config or why it doesn't.
|
||||
* @param {string} filePath The path of the file to check.
|
||||
* @returns {"ignored"|"external"|"unconfigured"|"matched"} One of the following values:
|
||||
* * `"ignored"`: the file is ignored
|
||||
* * `"external"`: the file is outside the base path
|
||||
* * `"unconfigured"`: the file is not matched by any config
|
||||
* * `"matched"`: the file has a matching config
|
||||
*/
|
||||
getConfigStatus(filePath: string): "ignored" | "external" | "unconfigured" | "matched";
|
||||
/**
|
||||
* Determines if the given filepath is ignored based on the configs.
|
||||
* @param {string} filePath The path of a file to check.
|
||||
* @returns {boolean} True if the path is ignored, false if not.
|
||||
* @deprecated Use `isFileIgnored` instead.
|
||||
*/
|
||||
isIgnored(filePath: string): boolean;
|
||||
/**
|
||||
* Determines if the given filepath is ignored based on the configs.
|
||||
* @param {string} filePath The path of a file to check.
|
||||
* @returns {boolean} True if the path is ignored, false if not.
|
||||
*/
|
||||
isFileIgnored(filePath: string): boolean;
|
||||
/**
|
||||
* Determines if the given directory is ignored based on the configs.
|
||||
* This checks only default `ignores` that don't have `files` in the
|
||||
* same config. A pattern such as `/foo` be considered to ignore the directory
|
||||
* while a pattern such as `/foo/**` is not considered to ignore the
|
||||
* directory because it is matching files.
|
||||
* @param {string} directoryPath The path of a directory to check.
|
||||
* @returns {boolean} True if the directory is ignored, false if not. Will
|
||||
* return true for any directory that is not inside of `basePath`.
|
||||
* @throws {Error} When the `ConfigArray` is not normalized.
|
||||
*/
|
||||
isDirectoryIgnored(directoryPath: string): boolean;
|
||||
#private;
|
||||
}
|
||||
export namespace ConfigArraySymbol {
|
||||
let isNormalized: symbol;
|
||||
let configCache: symbol;
|
||||
let schema: symbol;
|
||||
let finalizeConfig: symbol;
|
||||
let preprocessConfig: symbol;
|
||||
}
|
||||
import type * as $eslintobjectschema from "@eslint/object-schema";
|
||||
import type * as $typests from "./types.ts";
|
||||
import type * as $minimatch from "minimatch";
|
||||
import { ObjectSchema } from '@eslint/object-schema';
|
||||
@@ -0,0 +1,77 @@
|
||||
import { g as normalizeWindowsPath, j as join } from './shared/pathe.M-eThtNZ.mjs';
|
||||
|
||||
const pathSeparators = /* @__PURE__ */ new Set(["/", "\\", void 0]);
|
||||
const normalizedAliasSymbol = Symbol.for("pathe:normalizedAlias");
|
||||
const SLASH_RE = /[/\\]/;
|
||||
function normalizeAliases(_aliases) {
|
||||
if (_aliases[normalizedAliasSymbol]) {
|
||||
return _aliases;
|
||||
}
|
||||
const aliases = Object.fromEntries(
|
||||
Object.entries(_aliases).sort(([a], [b]) => _compareAliases(a, b))
|
||||
);
|
||||
for (const key in aliases) {
|
||||
for (const alias in aliases) {
|
||||
if (alias === key || key.startsWith(alias)) {
|
||||
continue;
|
||||
}
|
||||
if (aliases[key]?.startsWith(alias) && pathSeparators.has(aliases[key][alias.length])) {
|
||||
aliases[key] = aliases[alias] + aliases[key].slice(alias.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
Object.defineProperty(aliases, normalizedAliasSymbol, {
|
||||
value: true,
|
||||
enumerable: false
|
||||
});
|
||||
return aliases;
|
||||
}
|
||||
function resolveAlias(path, aliases) {
|
||||
const _path = normalizeWindowsPath(path);
|
||||
aliases = normalizeAliases(aliases);
|
||||
for (const [alias, to] of Object.entries(aliases)) {
|
||||
if (!_path.startsWith(alias)) {
|
||||
continue;
|
||||
}
|
||||
const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias;
|
||||
if (hasTrailingSlash(_path[_alias.length])) {
|
||||
return join(to, _path.slice(alias.length));
|
||||
}
|
||||
}
|
||||
return _path;
|
||||
}
|
||||
function reverseResolveAlias(path, aliases) {
|
||||
const _path = normalizeWindowsPath(path);
|
||||
aliases = normalizeAliases(aliases);
|
||||
const matches = [];
|
||||
for (const [to, alias] of Object.entries(aliases)) {
|
||||
if (!_path.startsWith(alias)) {
|
||||
continue;
|
||||
}
|
||||
const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias;
|
||||
if (hasTrailingSlash(_path[_alias.length])) {
|
||||
matches.push(join(to, _path.slice(alias.length)));
|
||||
}
|
||||
}
|
||||
return matches.sort((a, b) => b.length - a.length);
|
||||
}
|
||||
function filename(path) {
|
||||
const base = path.split(SLASH_RE).pop();
|
||||
if (!base) {
|
||||
return void 0;
|
||||
}
|
||||
const separatorIndex = base.lastIndexOf(".");
|
||||
if (separatorIndex <= 0) {
|
||||
return base;
|
||||
}
|
||||
return base.slice(0, separatorIndex);
|
||||
}
|
||||
function _compareAliases(a, b) {
|
||||
return b.split("/").length - a.split("/").length;
|
||||
}
|
||||
function hasTrailingSlash(path = "/") {
|
||||
const lastChar = path[path.length - 1];
|
||||
return lastChar === "/" || lastChar === "\\";
|
||||
}
|
||||
|
||||
export { filename, normalizeAliases, resolveAlias, reverseResolveAlias };
|
||||
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
||||
exports.default = _default;
|
||||
@@ -0,0 +1,103 @@
|
||||
'use strict';
|
||||
module.exports = function generate_if(it, $keyword, $ruleType) {
|
||||
var out = ' ';
|
||||
var $lvl = it.level;
|
||||
var $dataLvl = it.dataLevel;
|
||||
var $schema = it.schema[$keyword];
|
||||
var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
|
||||
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
|
||||
var $breakOnError = !it.opts.allErrors;
|
||||
var $data = 'data' + ($dataLvl || '');
|
||||
var $valid = 'valid' + $lvl;
|
||||
var $errs = 'errs__' + $lvl;
|
||||
var $it = it.util.copy(it);
|
||||
$it.level++;
|
||||
var $nextValid = 'valid' + $it.level;
|
||||
var $thenSch = it.schema['then'],
|
||||
$elseSch = it.schema['else'],
|
||||
$thenPresent = $thenSch !== undefined && (it.opts.strictKeywords ? (typeof $thenSch == 'object' && Object.keys($thenSch).length > 0) || $thenSch === false : it.util.schemaHasRules($thenSch, it.RULES.all)),
|
||||
$elsePresent = $elseSch !== undefined && (it.opts.strictKeywords ? (typeof $elseSch == 'object' && Object.keys($elseSch).length > 0) || $elseSch === false : it.util.schemaHasRules($elseSch, it.RULES.all)),
|
||||
$currentBaseId = $it.baseId;
|
||||
if ($thenPresent || $elsePresent) {
|
||||
var $ifClause;
|
||||
$it.createErrors = false;
|
||||
$it.schema = $schema;
|
||||
$it.schemaPath = $schemaPath;
|
||||
$it.errSchemaPath = $errSchemaPath;
|
||||
out += ' var ' + ($errs) + ' = errors; var ' + ($valid) + ' = true; ';
|
||||
var $wasComposite = it.compositeRule;
|
||||
it.compositeRule = $it.compositeRule = true;
|
||||
out += ' ' + (it.validate($it)) + ' ';
|
||||
$it.baseId = $currentBaseId;
|
||||
$it.createErrors = true;
|
||||
out += ' errors = ' + ($errs) + '; if (vErrors !== null) { if (' + ($errs) + ') vErrors.length = ' + ($errs) + '; else vErrors = null; } ';
|
||||
it.compositeRule = $it.compositeRule = $wasComposite;
|
||||
if ($thenPresent) {
|
||||
out += ' if (' + ($nextValid) + ') { ';
|
||||
$it.schema = it.schema['then'];
|
||||
$it.schemaPath = it.schemaPath + '.then';
|
||||
$it.errSchemaPath = it.errSchemaPath + '/then';
|
||||
out += ' ' + (it.validate($it)) + ' ';
|
||||
$it.baseId = $currentBaseId;
|
||||
out += ' ' + ($valid) + ' = ' + ($nextValid) + '; ';
|
||||
if ($thenPresent && $elsePresent) {
|
||||
$ifClause = 'ifClause' + $lvl;
|
||||
out += ' var ' + ($ifClause) + ' = \'then\'; ';
|
||||
} else {
|
||||
$ifClause = '\'then\'';
|
||||
}
|
||||
out += ' } ';
|
||||
if ($elsePresent) {
|
||||
out += ' else { ';
|
||||
}
|
||||
} else {
|
||||
out += ' if (!' + ($nextValid) + ') { ';
|
||||
}
|
||||
if ($elsePresent) {
|
||||
$it.schema = it.schema['else'];
|
||||
$it.schemaPath = it.schemaPath + '.else';
|
||||
$it.errSchemaPath = it.errSchemaPath + '/else';
|
||||
out += ' ' + (it.validate($it)) + ' ';
|
||||
$it.baseId = $currentBaseId;
|
||||
out += ' ' + ($valid) + ' = ' + ($nextValid) + '; ';
|
||||
if ($thenPresent && $elsePresent) {
|
||||
$ifClause = 'ifClause' + $lvl;
|
||||
out += ' var ' + ($ifClause) + ' = \'else\'; ';
|
||||
} else {
|
||||
$ifClause = '\'else\'';
|
||||
}
|
||||
out += ' } ';
|
||||
}
|
||||
out += ' if (!' + ($valid) + ') { var err = '; /* istanbul ignore else */
|
||||
if (it.createErrors !== false) {
|
||||
out += ' { keyword: \'' + ('if') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { failingKeyword: ' + ($ifClause) + ' } ';
|
||||
if (it.opts.messages !== false) {
|
||||
out += ' , message: \'should match "\' + ' + ($ifClause) + ' + \'" schema\' ';
|
||||
}
|
||||
if (it.opts.verbose) {
|
||||
out += ' , schema: validate.schema' + ($schemaPath) + ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
|
||||
}
|
||||
out += ' } ';
|
||||
} else {
|
||||
out += ' {} ';
|
||||
}
|
||||
out += '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
|
||||
if (!it.compositeRule && $breakOnError) {
|
||||
/* istanbul ignore if */
|
||||
if (it.async) {
|
||||
out += ' throw new ValidationError(vErrors); ';
|
||||
} else {
|
||||
out += ' validate.errors = vErrors; return false; ';
|
||||
}
|
||||
}
|
||||
out += ' } ';
|
||||
if ($breakOnError) {
|
||||
out += ' else { ';
|
||||
}
|
||||
} else {
|
||||
if ($breakOnError) {
|
||||
out += ' if (true) { ';
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
'use strict'
|
||||
|
||||
/* eslint no-prototype-builtins: 0 */
|
||||
|
||||
const test = require('node:test')
|
||||
const assert = require('node:assert')
|
||||
|
||||
const { sink, once } = require('./helper')
|
||||
const pino = require('../')
|
||||
|
||||
test('pino exposes standard time functions', async () => {
|
||||
assert.ok(pino.stdTimeFunctions)
|
||||
assert.ok(pino.stdTimeFunctions.epochTime)
|
||||
assert.ok(pino.stdTimeFunctions.unixTime)
|
||||
assert.ok(pino.stdTimeFunctions.nullTime)
|
||||
assert.ok(pino.stdTimeFunctions.isoTime)
|
||||
assert.ok(pino.stdTimeFunctions.isoTimeNano)
|
||||
})
|
||||
|
||||
test('pino accepts external time functions', async () => {
|
||||
const opts = {
|
||||
timestamp: () => ',"time":"none"'
|
||||
}
|
||||
const stream = sink()
|
||||
const instance = pino(opts, stream)
|
||||
instance.info('foobar')
|
||||
const result = await once(stream, 'data')
|
||||
assert.equal(result.hasOwnProperty('time'), true)
|
||||
assert.equal(result.time, 'none')
|
||||
})
|
||||
|
||||
test('pino accepts external time functions with custom label', async () => {
|
||||
const opts = {
|
||||
timestamp: () => ',"custom-time-label":"none"'
|
||||
}
|
||||
const stream = sink()
|
||||
const instance = pino(opts, stream)
|
||||
instance.info('foobar')
|
||||
const result = await once(stream, 'data')
|
||||
assert.equal(result.hasOwnProperty('custom-time-label'), true)
|
||||
assert.equal(result['custom-time-label'], 'none')
|
||||
})
|
||||
|
||||
test('inserts timestamp by default', async ({ ok, equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino(stream)
|
||||
instance.info('foobar')
|
||||
const result = await once(stream, 'data')
|
||||
assert.equal(result.hasOwnProperty('time'), true)
|
||||
assert.ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
|
||||
assert.equal(result.msg, 'foobar')
|
||||
})
|
||||
|
||||
test('omits timestamp when timestamp option is false', async () => {
|
||||
const stream = sink()
|
||||
const instance = pino({ timestamp: false }, stream)
|
||||
instance.info('foobar')
|
||||
const result = await once(stream, 'data')
|
||||
assert.equal(result.hasOwnProperty('time'), false)
|
||||
assert.equal(result.msg, 'foobar')
|
||||
})
|
||||
|
||||
test('inserts timestamp when timestamp option is true', async ({ ok, equal }) => {
|
||||
const stream = sink()
|
||||
const instance = pino({ timestamp: true }, stream)
|
||||
instance.info('foobar')
|
||||
const result = await once(stream, 'data')
|
||||
assert.equal(result.hasOwnProperty('time'), true)
|
||||
assert.ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
|
||||
assert.equal(result.msg, 'foobar')
|
||||
})
|
||||
|
||||
test('child inserts timestamp by default', async ({ ok, equal }) => {
|
||||
const stream = sink()
|
||||
const logger = pino(stream)
|
||||
const instance = logger.child({ component: 'child' })
|
||||
instance.info('foobar')
|
||||
const result = await once(stream, 'data')
|
||||
assert.equal(result.hasOwnProperty('time'), true)
|
||||
assert.ok(new Date(result.time) <= new Date(), 'time is greater than timestamp')
|
||||
assert.equal(result.msg, 'foobar')
|
||||
})
|
||||
|
||||
test('child omits timestamp with option', async () => {
|
||||
const stream = sink()
|
||||
const logger = pino({ timestamp: false }, stream)
|
||||
const instance = logger.child({ component: 'child' })
|
||||
instance.info('foobar')
|
||||
const result = await once(stream, 'data')
|
||||
assert.equal(result.hasOwnProperty('time'), false)
|
||||
assert.equal(result.msg, 'foobar')
|
||||
})
|
||||
|
||||
test('pino.stdTimeFunctions.unixTime returns seconds based timestamps', async () => {
|
||||
const opts = {
|
||||
timestamp: pino.stdTimeFunctions.unixTime
|
||||
}
|
||||
const stream = sink()
|
||||
const instance = pino(opts, stream)
|
||||
const now = Date.now
|
||||
Date.now = () => 1531069919686
|
||||
instance.info('foobar')
|
||||
const result = await once(stream, 'data')
|
||||
assert.equal(result.hasOwnProperty('time'), true)
|
||||
assert.equal(result.time, 1531069920)
|
||||
Date.now = now
|
||||
})
|
||||
|
||||
test('pino.stdTimeFunctions.isoTime returns ISO 8601 timestamps', async () => {
|
||||
const opts = {
|
||||
timestamp: pino.stdTimeFunctions.isoTime
|
||||
}
|
||||
const stream = sink()
|
||||
const instance = pino(opts, stream)
|
||||
const ms = 1531069919686
|
||||
const now = Date.now
|
||||
Date.now = () => ms
|
||||
const iso = new Date(ms).toISOString()
|
||||
instance.info('foobar')
|
||||
const result = await once(stream, 'data')
|
||||
assert.equal(result.hasOwnProperty('time'), true)
|
||||
assert.equal(result.time, iso)
|
||||
Date.now = now
|
||||
})
|
||||
Reference in New Issue
Block a user