WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
export declare var ElementFlags: any;
|
||||
//# sourceMappingURL=elementFlags.d.ts.map
|
||||
@@ -0,0 +1,4 @@
|
||||
export function parse(text: string, reviver?: (this: any, key: string, value: any) => any): any;
|
||||
export function stringify(value: any, replacer?: (string | number)[] | null | undefined | ((this: any, key: string, value: any) => any), space?: string | number | undefined): string;
|
||||
export function toJSON(value: any): any;
|
||||
export function fromJSON(value: any): any;
|
||||
@@ -0,0 +1,930 @@
|
||||
import { MockInstance } from '@vitest/spy';
|
||||
import { Formatter } from 'tinyrainbow';
|
||||
import { StandardSchemaV1 } from '@standard-schema/spec';
|
||||
import { diff, printDiffOrStringify } from '@vitest/utils/diff';
|
||||
export { DiffOptions } from '@vitest/utils/diff';
|
||||
import { stringify } from '@vitest/utils/display';
|
||||
import * as chai from 'chai';
|
||||
export { chai };
|
||||
|
||||
interface AsymmetricMatcherInterface {
|
||||
asymmetricMatch: (other: unknown, customTesters?: Array<Tester>) => boolean;
|
||||
toString: () => string;
|
||||
getExpectedType?: () => string;
|
||||
toAsymmetricMatcher?: () => string;
|
||||
}
|
||||
declare abstract class AsymmetricMatcher<
|
||||
T,
|
||||
State extends MatcherState = MatcherState
|
||||
> implements AsymmetricMatcherInterface {
|
||||
protected sample: T;
|
||||
protected inverse: boolean;
|
||||
$$typeof: symbol;
|
||||
constructor(sample: T, inverse?: boolean);
|
||||
protected getMatcherContext(expect?: Chai.ExpectStatic): State;
|
||||
abstract asymmetricMatch(other: unknown, customTesters?: Array<Tester>): boolean;
|
||||
abstract toString(): string;
|
||||
getExpectedType?(): string;
|
||||
toAsymmetricMatcher?(): string;
|
||||
}
|
||||
declare class StringContaining extends AsymmetricMatcher<string> {
|
||||
constructor(sample: string, inverse?: boolean);
|
||||
asymmetricMatch(other: string): boolean;
|
||||
toString(): string;
|
||||
getExpectedType(): string;
|
||||
}
|
||||
declare class Anything extends AsymmetricMatcher<void> {
|
||||
asymmetricMatch(other: unknown): boolean;
|
||||
toString(): string;
|
||||
toAsymmetricMatcher(): string;
|
||||
}
|
||||
declare class ObjectContaining extends AsymmetricMatcher<Record<string | symbol | number, unknown>> {
|
||||
constructor(sample: Record<string, unknown>, inverse?: boolean);
|
||||
getPrototype(obj: object): any;
|
||||
hasProperty(obj: object | null, property: string | symbol): boolean;
|
||||
getProperties(obj: object): (string | symbol)[];
|
||||
asymmetricMatch(other: any, customTesters?: Array<Tester>): boolean;
|
||||
toString(): string;
|
||||
getExpectedType(): string;
|
||||
}
|
||||
declare class ArrayContaining<T = unknown> extends AsymmetricMatcher<Array<T>> {
|
||||
constructor(sample: Array<T>, inverse?: boolean);
|
||||
asymmetricMatch(other: Array<T>, customTesters?: Array<Tester>): boolean;
|
||||
toString(): string;
|
||||
getExpectedType(): string;
|
||||
}
|
||||
declare class Any extends AsymmetricMatcher<any> {
|
||||
constructor(sample: unknown);
|
||||
fnNameFor(func: Function): string;
|
||||
asymmetricMatch(other: unknown): boolean;
|
||||
toString(): string;
|
||||
getExpectedType(): string;
|
||||
toAsymmetricMatcher(): string;
|
||||
}
|
||||
declare class StringMatching extends AsymmetricMatcher<RegExp> {
|
||||
constructor(sample: string | RegExp, inverse?: boolean);
|
||||
asymmetricMatch(other: string): boolean;
|
||||
toString(): string;
|
||||
getExpectedType(): string;
|
||||
}
|
||||
declare class SchemaMatching extends AsymmetricMatcher<StandardSchemaV1<unknown, unknown>> {
|
||||
private result;
|
||||
constructor(sample: StandardSchemaV1<unknown, unknown>, inverse?: boolean);
|
||||
asymmetricMatch(other: unknown): boolean;
|
||||
toString(): string;
|
||||
getExpectedType(): string;
|
||||
toAsymmetricMatcher(): string;
|
||||
}
|
||||
declare const JestAsymmetricMatchers: ChaiPlugin;
|
||||
|
||||
declare function matcherHint(matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions): string;
|
||||
declare function printReceived(object: unknown): string;
|
||||
declare function printExpected(value: unknown): string;
|
||||
declare function getMatcherUtils(): {
|
||||
EXPECTED_COLOR: Formatter;
|
||||
RECEIVED_COLOR: Formatter;
|
||||
INVERTED_COLOR: Formatter;
|
||||
BOLD_WEIGHT: Formatter;
|
||||
DIM_COLOR: Formatter;
|
||||
diff: typeof diff;
|
||||
matcherHint: typeof matcherHint;
|
||||
printReceived: typeof printReceived;
|
||||
printExpected: typeof printExpected;
|
||||
printDiffOrStringify: typeof printDiffOrStringify;
|
||||
printWithType: typeof printWithType;
|
||||
};
|
||||
declare function printWithType<T>(name: string, value: T, print: (value: T) => string): string;
|
||||
declare function addCustomEqualityTesters(newTesters: Array<Tester>): void;
|
||||
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
|
||||
type ChaiPlugin = Chai.ChaiPlugin;
|
||||
type Tester = (this: TesterContext, a: any, b: any, customTesters: Array<Tester>) => boolean | undefined;
|
||||
interface TesterContext {
|
||||
equals: (a: unknown, b: unknown, customTesters?: Array<Tester>, strictCheck?: boolean) => boolean;
|
||||
}
|
||||
|
||||
interface MatcherHintOptions {
|
||||
comment?: string;
|
||||
expectedColor?: Formatter;
|
||||
isDirectExpectCall?: boolean;
|
||||
isNot?: boolean;
|
||||
promise?: string;
|
||||
receivedColor?: Formatter;
|
||||
secondArgument?: string;
|
||||
secondArgumentColor?: Formatter;
|
||||
}
|
||||
interface MatcherState {
|
||||
customTesters: Array<Tester>;
|
||||
assertionCalls: number;
|
||||
currentTestName?: string;
|
||||
/**
|
||||
* @deprecated exists only in types
|
||||
*/
|
||||
dontThrow?: () => void;
|
||||
/**
|
||||
* @deprecated exists only in types
|
||||
*/
|
||||
error?: Error;
|
||||
equals: (a: unknown, b: unknown, customTesters?: Array<Tester>, strictCheck?: boolean) => boolean;
|
||||
/**
|
||||
* @deprecated exists only in types
|
||||
*/
|
||||
expand?: boolean;
|
||||
expectedAssertionsNumber?: number | null;
|
||||
expectedAssertionsNumberErrorGen?: (() => Error) | null;
|
||||
isExpectingAssertions?: boolean;
|
||||
isExpectingAssertionsError?: Error | null;
|
||||
isNot: boolean;
|
||||
promise: string;
|
||||
/**
|
||||
* @deprecated exists only in types
|
||||
*/
|
||||
suppressedErrors: Array<Error>;
|
||||
testPath?: string;
|
||||
utils: ReturnType<typeof getMatcherUtils> & {
|
||||
diff: typeof diff;
|
||||
stringify: typeof stringify;
|
||||
iterableEquality: Tester;
|
||||
subsetEquality: Tester;
|
||||
};
|
||||
soft?: boolean;
|
||||
poll?: boolean;
|
||||
/**
|
||||
* The same assertion instance that chai plugins receive.
|
||||
* @experimental
|
||||
* @see {@link https://www.chaijs.com/guide/plugins/} Core Plugin Concepts
|
||||
*/
|
||||
readonly assertion: Assertion;
|
||||
}
|
||||
interface SyncExpectationResult {
|
||||
pass: boolean;
|
||||
message: () => string;
|
||||
actual?: any;
|
||||
expected?: any;
|
||||
meta?: object;
|
||||
}
|
||||
type AsyncExpectationResult = Promise<SyncExpectationResult>;
|
||||
type ExpectationResult = SyncExpectationResult | AsyncExpectationResult;
|
||||
interface RawMatcherFn<
|
||||
T extends MatcherState = MatcherState,
|
||||
E extends Array<any> = Array<any>
|
||||
> {
|
||||
(this: T, received: any, ...expected: E): ExpectationResult;
|
||||
}
|
||||
interface Matchers<T = any> {}
|
||||
type MatchersObject<T extends MatcherState = MatcherState> = Record<string, RawMatcherFn<T>> & ThisType<T> & { [K in keyof Matchers<T>]? : RawMatcherFn<T, Parameters<Matchers<T>[K]>> };
|
||||
interface ExpectStatic extends Chai.ExpectStatic, Matchers, AsymmetricMatchersContaining {
|
||||
<T>(actual: T, message?: string): Assertion<T>;
|
||||
extend: (expects: MatchersObject) => void;
|
||||
anything: () => any;
|
||||
any: (constructor: unknown) => any;
|
||||
getState: () => MatcherState;
|
||||
setState: (state: Partial<MatcherState>) => void;
|
||||
not: AsymmetricMatchersContaining;
|
||||
}
|
||||
interface CustomMatcher {
|
||||
/**
|
||||
* Checks that a value satisfies a custom matcher function.
|
||||
*
|
||||
* @param matcher - A function returning a boolean based on the custom condition
|
||||
* @param message - Optional custom error message on failure
|
||||
*
|
||||
* @example
|
||||
* expect(age).toSatisfy(val => val >= 18, 'Age must be at least 18');
|
||||
* expect(age).toEqual(expect.toSatisfy(val => val >= 18, 'Age must be at least 18'));
|
||||
*/
|
||||
toSatisfy: (matcher: (value: any) => boolean, message?: string) => any;
|
||||
/**
|
||||
* Matches if the received value is one of the values in the expected array or set.
|
||||
*
|
||||
* @example
|
||||
* expect(1).toBeOneOf([1, 2, 3])
|
||||
* expect('foo').toBeOneOf([expect.any(String)])
|
||||
* expect({ a: 1 }).toEqual({ a: expect.toBeOneOf(['1', '2', '3']) })
|
||||
*/
|
||||
toBeOneOf: <T>(sample: Array<T> | Set<T>) => any;
|
||||
}
|
||||
interface AsymmetricMatchersContaining extends CustomMatcher {
|
||||
/**
|
||||
* Matches if the received string contains the expected substring.
|
||||
*
|
||||
* @example
|
||||
* expect('I have an apple').toEqual(expect.stringContaining('apple'));
|
||||
* expect({ a: 'test string' }).toEqual({ a: expect.stringContaining('test') });
|
||||
*/
|
||||
stringContaining: (expected: string) => any;
|
||||
/**
|
||||
* Matches if the received object contains all properties of the expected object.
|
||||
*
|
||||
* @example
|
||||
* expect({ a: '1', b: 2 }).toEqual(expect.objectContaining({ a: '1' }))
|
||||
*/
|
||||
objectContaining: <T = any>(expected: DeeplyAllowMatchers<T>) => any;
|
||||
/**
|
||||
* Matches if the received array contains all elements in the expected array.
|
||||
*
|
||||
* @example
|
||||
* expect(['a', 'b', 'c']).toEqual(expect.arrayContaining(['b', 'a']));
|
||||
*/
|
||||
arrayContaining: <T = unknown>(expected: Array<DeeplyAllowMatchers<T>>) => any;
|
||||
/**
|
||||
* Matches if the received string or regex matches the expected pattern.
|
||||
*
|
||||
* @example
|
||||
* expect('hello world').toEqual(expect.stringMatching(/^hello/));
|
||||
* expect('hello world').toEqual(expect.stringMatching('hello'));
|
||||
*/
|
||||
stringMatching: (expected: string | RegExp) => any;
|
||||
/**
|
||||
* Matches if the received number is within a certain precision of the expected number.
|
||||
*
|
||||
* @example
|
||||
* expect(10.45).toEqual(expect.closeTo(10.5, 1));
|
||||
* expect(5.11).toEqual(expect.closeTo(5.12)); // with default precision
|
||||
*/
|
||||
closeTo: (expected: number, precision?: number) => any;
|
||||
/**
|
||||
* Matches if the received value validates against a Standard Schema.
|
||||
*
|
||||
* @param schema - A Standard Schema V1 compatible schema object
|
||||
*
|
||||
* @example
|
||||
* expect(user).toEqual(expect.schemaMatching(z.object({ name: z.string() })))
|
||||
* expect(['hello', 'world']).toEqual([expect.schemaMatching(z.string()), expect.schemaMatching(z.string())])
|
||||
*/
|
||||
schemaMatching: (schema: unknown) => any;
|
||||
}
|
||||
type WithAsymmetricMatcher<T> = T | AsymmetricMatcher<unknown>;
|
||||
type DeeplyAllowMatchers<T> = T extends Array<infer Element> ? WithAsymmetricMatcher<T> | DeeplyAllowMatchers<Element>[] : T extends object ? WithAsymmetricMatcher<T> | { [K in keyof T] : DeeplyAllowMatchers<T[K]> } : WithAsymmetricMatcher<T>;
|
||||
interface JestAssertion<T = any> extends jest.Matchers<void, T>, CustomMatcher {
|
||||
/**
|
||||
* Used when you want to check that two objects have the same value.
|
||||
* This matcher recursively checks the equality of all fields, rather than checking for object identity.
|
||||
*
|
||||
* @example
|
||||
* expect(user).toEqual({ name: 'Alice', age: 30 });
|
||||
*/
|
||||
toEqual: <E>(expected: E) => void;
|
||||
/**
|
||||
* Use to test that objects have the same types as well as structure.
|
||||
*
|
||||
* @example
|
||||
* expect(user).toStrictEqual({ name: 'Alice', age: 30 });
|
||||
*/
|
||||
toStrictEqual: <E>(expected: E) => void;
|
||||
/**
|
||||
* Checks that a value is what you expect. It calls `Object.is` to compare values.
|
||||
* Don't use `toBe` with floating-point numbers.
|
||||
*
|
||||
* @example
|
||||
* expect(result).toBe(42);
|
||||
* expect(status).toBe(true);
|
||||
*/
|
||||
toBe: <E>(expected: E) => void;
|
||||
/**
|
||||
* Check that a string matches a regular expression.
|
||||
*
|
||||
* @example
|
||||
* expect(message).toMatch(/hello/);
|
||||
* expect(greeting).toMatch('world');
|
||||
*/
|
||||
toMatch: (expected: string | RegExp) => void;
|
||||
/**
|
||||
* Used to check that a JavaScript object matches a subset of the properties of an object
|
||||
*
|
||||
* @example
|
||||
* expect(user).toMatchObject({
|
||||
* name: 'Alice',
|
||||
* address: { city: 'Wonderland' }
|
||||
* });
|
||||
*/
|
||||
toMatchObject: <E extends object | any[]>(expected: E) => void;
|
||||
/**
|
||||
* Used when you want to check that an item is in a list.
|
||||
* For testing the items in the list, this uses `===`, a strict equality check.
|
||||
*
|
||||
* @example
|
||||
* expect(items).toContain('apple');
|
||||
* expect(numbers).toContain(5);
|
||||
*/
|
||||
toContain: <E>(item: E) => void;
|
||||
/**
|
||||
* Used when you want to check that an item is in a list.
|
||||
* For testing the items in the list, this matcher recursively checks the
|
||||
* equality of all fields, rather than checking for object identity.
|
||||
*
|
||||
* @example
|
||||
* expect(items).toContainEqual({ name: 'apple', quantity: 1 });
|
||||
*/
|
||||
toContainEqual: <E>(item: E) => void;
|
||||
/**
|
||||
* Use when you don't care what a value is, you just want to ensure a value
|
||||
* is true in a boolean context. In JavaScript, there are six falsy values:
|
||||
* `false`, `0`, `''`, `null`, `undefined`, and `NaN`. Everything else is truthy.
|
||||
*
|
||||
* @example
|
||||
* expect(user.isActive).toBeTruthy();
|
||||
*/
|
||||
toBeTruthy: () => void;
|
||||
/**
|
||||
* When you don't care what a value is, you just want to
|
||||
* ensure a value is false in a boolean context.
|
||||
*
|
||||
* @example
|
||||
* expect(user.isActive).toBeFalsy();
|
||||
*/
|
||||
toBeFalsy: () => void;
|
||||
/**
|
||||
* For comparing floating point numbers.
|
||||
*
|
||||
* @example
|
||||
* expect(score).toBeGreaterThan(10);
|
||||
*/
|
||||
toBeGreaterThan: (num: number | bigint) => void;
|
||||
/**
|
||||
* For comparing floating point numbers.
|
||||
*
|
||||
* @example
|
||||
* expect(score).toBeGreaterThanOrEqual(10);
|
||||
*/
|
||||
toBeGreaterThanOrEqual: (num: number | bigint) => void;
|
||||
/**
|
||||
* For comparing floating point numbers.
|
||||
*
|
||||
* @example
|
||||
* expect(score).toBeLessThan(10);
|
||||
*/
|
||||
toBeLessThan: (num: number | bigint) => void;
|
||||
/**
|
||||
* For comparing floating point numbers.
|
||||
*
|
||||
* @example
|
||||
* expect(score).toBeLessThanOrEqual(10);
|
||||
*/
|
||||
toBeLessThanOrEqual: (num: number | bigint) => void;
|
||||
/**
|
||||
* Used to check that a variable is NaN.
|
||||
*
|
||||
* @example
|
||||
* expect(value).toBeNaN();
|
||||
*/
|
||||
toBeNaN: () => void;
|
||||
/**
|
||||
* Used to check that a variable is undefined.
|
||||
*
|
||||
* @example
|
||||
* expect(value).toBeUndefined();
|
||||
*/
|
||||
toBeUndefined: () => void;
|
||||
/**
|
||||
* This is the same as `.toBe(null)` but the error messages are a bit nicer.
|
||||
* So use `.toBeNull()` when you want to check that something is null.
|
||||
*
|
||||
* @example
|
||||
* expect(value).toBeNull();
|
||||
*/
|
||||
toBeNull: () => void;
|
||||
/**
|
||||
* Used to check that a variable is nullable (null or undefined).
|
||||
*
|
||||
* @example
|
||||
* expect(value).toBeNullable();
|
||||
*/
|
||||
toBeNullable: () => void;
|
||||
/**
|
||||
* Ensure that a variable is not undefined.
|
||||
*
|
||||
* @example
|
||||
* expect(value).toBeDefined();
|
||||
*/
|
||||
toBeDefined: () => void;
|
||||
/**
|
||||
* Ensure that an object is an instance of a class.
|
||||
* This matcher uses `instanceof` underneath.
|
||||
*
|
||||
* @example
|
||||
* expect(new Date()).toBeInstanceOf(Date);
|
||||
*/
|
||||
toBeInstanceOf: <E>(expected: E) => void;
|
||||
/**
|
||||
* Used to check that an object has a `.length` property
|
||||
* and it is set to a certain numeric value.
|
||||
*
|
||||
* @example
|
||||
* expect([1, 2, 3]).toHaveLength(3);
|
||||
* expect('hello').toHaveLength(5);
|
||||
*/
|
||||
toHaveLength: (length: number) => void;
|
||||
/**
|
||||
* Use to check if a property at the specified path exists on an object.
|
||||
* For checking deeply nested properties, you may use dot notation or an array containing
|
||||
* the path segments for deep references.
|
||||
*
|
||||
* Optionally, you can provide a value to check if it matches the value present at the path
|
||||
* on the target object. This matcher uses 'deep equality' (like `toEqual()`) and recursively checks
|
||||
* the equality of all fields.
|
||||
*
|
||||
* @example
|
||||
* expect(user).toHaveProperty('address.city', 'New York');
|
||||
* expect(config).toHaveProperty(['settings', 'theme'], 'dark');
|
||||
*/
|
||||
toHaveProperty: <E>(property: string | (string | number)[], value?: E) => void;
|
||||
/**
|
||||
* Using exact equality with floating point numbers is a bad idea.
|
||||
* Rounding means that intuitive things fail.
|
||||
* The default for `numDigits` is 2.
|
||||
*
|
||||
* @example
|
||||
* expect(price).toBeCloseTo(9.99, 2);
|
||||
*/
|
||||
toBeCloseTo: (number: number, numDigits?: number) => void;
|
||||
/**
|
||||
* Ensures that a mock function is called an exact number of times.
|
||||
*
|
||||
* Also under the alias `expect.toBeCalledTimes`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveBeenCalledTimes(2);
|
||||
*/
|
||||
toHaveBeenCalledTimes: (times: number) => void;
|
||||
/**
|
||||
* Ensures that a mock function is called an exact number of times.
|
||||
*
|
||||
* Alias for `expect.toHaveBeenCalledTimes`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toBeCalledTimes(2);
|
||||
* @deprecated Use `toHaveBeenCalledTimes` instead
|
||||
*/
|
||||
toBeCalledTimes: (times: number) => void;
|
||||
/**
|
||||
* Ensures that a mock function is called.
|
||||
*
|
||||
* Also under the alias `expect.toBeCalled`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveBeenCalled();
|
||||
*/
|
||||
toHaveBeenCalled: () => void;
|
||||
/**
|
||||
* Ensures that a mock function is called.
|
||||
*
|
||||
* Alias for `expect.toHaveBeenCalled`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toBeCalled();
|
||||
* @deprecated Use `toHaveBeenCalled` instead
|
||||
*/
|
||||
toBeCalled: () => void;
|
||||
/**
|
||||
* Ensure that a mock function is called with specific arguments.
|
||||
*
|
||||
* Also under the alias `expect.toBeCalledWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveBeenCalledWith('arg1', 42);
|
||||
*/
|
||||
toHaveBeenCalledWith: <E extends any[]>(...args: E) => void;
|
||||
/**
|
||||
* Ensure that a mock function is called with specific arguments.
|
||||
*
|
||||
* Alias for `expect.toHaveBeenCalledWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toBeCalledWith('arg1', 42);
|
||||
* @deprecated Use `toHaveBeenCalledWith` instead
|
||||
*/
|
||||
toBeCalledWith: <E extends any[]>(...args: E) => void;
|
||||
/**
|
||||
* Ensure that a mock function is called with specific arguments on an Nth call.
|
||||
*
|
||||
* Also under the alias `expect.nthCalledWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveBeenNthCalledWith(2, 'secondArg');
|
||||
*/
|
||||
toHaveBeenNthCalledWith: <E extends any[]>(n: number, ...args: E) => void;
|
||||
/**
|
||||
* If you have a mock function, you can use `.toHaveBeenLastCalledWith`
|
||||
* to test what arguments it was last called with.
|
||||
*
|
||||
* Also under the alias `expect.lastCalledWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveBeenLastCalledWith('lastArg');
|
||||
*/
|
||||
toHaveBeenLastCalledWith: <E extends any[]>(...args: E) => void;
|
||||
/**
|
||||
* Used to test that a function throws when it is called.
|
||||
*
|
||||
* Also under the alias `expect.toThrowError`.
|
||||
*
|
||||
* @example
|
||||
* expect(() => functionWithError()).toThrow('Error message');
|
||||
* expect(() => parseJSON('invalid')).toThrow(SyntaxError);
|
||||
* expect(() => { throw 42 }).toThrow(42);
|
||||
*/
|
||||
toThrow: (expected?: any) => void;
|
||||
/**
|
||||
* Used to test that a function throws when it is called.
|
||||
*
|
||||
* Alias for `expect.toThrow`.
|
||||
*
|
||||
* @example
|
||||
* expect(() => functionWithError()).toThrowError('Error message');
|
||||
* expect(() => parseJSON('invalid')).toThrowError(SyntaxError);
|
||||
* expect(() => { throw 42 }).toThrowError(42);
|
||||
* @deprecated Use `toThrow` instead
|
||||
*/
|
||||
toThrowError: (expected?: any) => void;
|
||||
/**
|
||||
* Use to test that the mock function successfully returned (i.e., did not throw an error) at least one time
|
||||
*
|
||||
* Alias for `expect.toHaveReturned`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toReturn();
|
||||
* @deprecated Use `toHaveReturned` instead
|
||||
*/
|
||||
toReturn: () => void;
|
||||
/**
|
||||
* Use to test that the mock function successfully returned (i.e., did not throw an error) at least one time
|
||||
*
|
||||
* Also under the alias `expect.toReturn`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveReturned();
|
||||
*/
|
||||
toHaveReturned: () => void;
|
||||
/**
|
||||
* Use to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times.
|
||||
* Any calls to the mock function that throw an error are not counted toward the number of times the function returned.
|
||||
*
|
||||
* Alias for `expect.toHaveReturnedTimes`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toReturnTimes(3);
|
||||
* @deprecated Use `toHaveReturnedTimes` instead
|
||||
*/
|
||||
toReturnTimes: (times: number) => void;
|
||||
/**
|
||||
* Use to ensure that a mock function returned successfully (i.e., did not throw an error) an exact number of times.
|
||||
* Any calls to the mock function that throw an error are not counted toward the number of times the function returned.
|
||||
*
|
||||
* Also under the alias `expect.toReturnTimes`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveReturnedTimes(3);
|
||||
*/
|
||||
toHaveReturnedTimes: (times: number) => void;
|
||||
/**
|
||||
* Use to ensure that a mock function returned a specific value.
|
||||
*
|
||||
* Alias for `expect.toHaveReturnedWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toReturnWith('returnValue');
|
||||
* @deprecated Use `toHaveReturnedWith` instead
|
||||
*/
|
||||
toReturnWith: <E>(value: E) => void;
|
||||
/**
|
||||
* Use to ensure that a mock function returned a specific value.
|
||||
*
|
||||
* Also under the alias `expect.toReturnWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveReturnedWith('returnValue');
|
||||
*/
|
||||
toHaveReturnedWith: <E>(value: E) => void;
|
||||
/**
|
||||
* Use to test the specific value that a mock function last returned.
|
||||
* If the last call to the mock function threw an error, then this matcher will fail
|
||||
* no matter what value you provided as the expected return value.
|
||||
*
|
||||
* Also under the alias `expect.lastReturnedWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveLastReturnedWith('lastValue');
|
||||
*/
|
||||
toHaveLastReturnedWith: <E>(value: E) => void;
|
||||
/**
|
||||
* Use to test the specific value that a mock function returned for the nth call.
|
||||
* If the nth call to the mock function threw an error, then this matcher will fail
|
||||
* no matter what value you provided as the expected return value.
|
||||
*
|
||||
* Also under the alias `expect.nthReturnedWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveNthReturnedWith(2, 'nthValue');
|
||||
*/
|
||||
toHaveNthReturnedWith: <E>(nthCall: number, value: E) => void;
|
||||
}
|
||||
type VitestAssertion<
|
||||
A,
|
||||
T
|
||||
> = { [K in keyof A] : A[K] extends Chai.Assertion ? Assertion<T> : A[K] extends (...args: any[]) => any ? A[K] : VitestAssertion<A[K], T> } & ((type: string, message?: string) => Assertion);
|
||||
type Promisify<O> = { [K in keyof O] : O[K] extends (...args: infer A) => infer R ? Promisify<O[K]> & ((...args: A) => Promise<R>) : O[K] };
|
||||
type PromisifyAssertion<T> = Promisify<Assertion<T>>;
|
||||
interface Assertion<T = any> extends VitestAssertion<Chai.Assertion, T>, JestAssertion<T>, ChaiMockAssertion, Matchers<T> {
|
||||
/**
|
||||
* Ensures a value is of a specific type.
|
||||
*
|
||||
* @example
|
||||
* expect(value).toBeTypeOf('string');
|
||||
* expect(number).toBeTypeOf('number');
|
||||
*/
|
||||
toBeTypeOf: (expected: "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined") => void;
|
||||
/**
|
||||
* Asserts that a mock function was called exactly once.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveBeenCalledOnce();
|
||||
*/
|
||||
toHaveBeenCalledOnce: () => void;
|
||||
/**
|
||||
* Ensure that a mock function is called with specific arguments and called
|
||||
* exactly once.
|
||||
*
|
||||
* @example
|
||||
* expect(mockFunc).toHaveBeenCalledExactlyOnceWith('arg1', 42);
|
||||
*/
|
||||
toHaveBeenCalledExactlyOnceWith: <E extends any[]>(...args: E) => void;
|
||||
/**
|
||||
* This assertion checks if a `Mock` was called before another `Mock`.
|
||||
* @param mock - A mock function created by `vi.spyOn` or `vi.fn`
|
||||
* @param failIfNoFirstInvocation - Fail if the first mock was never called
|
||||
* @example
|
||||
* const mock1 = vi.fn()
|
||||
* const mock2 = vi.fn()
|
||||
*
|
||||
* mock1()
|
||||
* mock2()
|
||||
* mock1()
|
||||
*
|
||||
* expect(mock1).toHaveBeenCalledBefore(mock2)
|
||||
*/
|
||||
toHaveBeenCalledBefore: (mock: MockInstance, failIfNoFirstInvocation?: boolean) => void;
|
||||
/**
|
||||
* This assertion checks if a `Mock` was called after another `Mock`.
|
||||
* @param mock - A mock function created by `vi.spyOn` or `vi.fn`
|
||||
* @param failIfNoFirstInvocation - Fail if the first mock was never called
|
||||
* @example
|
||||
* const mock1 = vi.fn()
|
||||
* const mock2 = vi.fn()
|
||||
*
|
||||
* mock2()
|
||||
* mock1()
|
||||
* mock2()
|
||||
*
|
||||
* expect(mock1).toHaveBeenCalledAfter(mock2)
|
||||
*/
|
||||
toHaveBeenCalledAfter: (mock: MockInstance, failIfNoFirstInvocation?: boolean) => void;
|
||||
/**
|
||||
* Checks that a promise resolves successfully at least once.
|
||||
*
|
||||
* @example
|
||||
* await expect(promise).toHaveResolved();
|
||||
*/
|
||||
toHaveResolved: () => void;
|
||||
/**
|
||||
* Checks that a promise resolves to a specific value.
|
||||
*
|
||||
* @example
|
||||
* await expect(promise).toHaveResolvedWith('success');
|
||||
*/
|
||||
toHaveResolvedWith: <E>(value: E) => void;
|
||||
/**
|
||||
* Ensures a promise resolves a specific number of times.
|
||||
*
|
||||
* @example
|
||||
* expect(mockAsyncFunc).toHaveResolvedTimes(3);
|
||||
*/
|
||||
toHaveResolvedTimes: (times: number) => void;
|
||||
/**
|
||||
* Asserts that the last resolved value of a promise matches an expected value.
|
||||
*
|
||||
* @example
|
||||
* await expect(mockAsyncFunc).toHaveLastResolvedWith('finalResult');
|
||||
*/
|
||||
toHaveLastResolvedWith: <E>(value: E) => void;
|
||||
/**
|
||||
* Ensures a specific value was returned by a promise on the nth resolution.
|
||||
*
|
||||
* @example
|
||||
* await expect(mockAsyncFunc).toHaveNthResolvedWith(2, 'secondResult');
|
||||
*/
|
||||
toHaveNthResolvedWith: <E>(nthCall: number, value: E) => void;
|
||||
/**
|
||||
* Verifies that a promise resolves.
|
||||
*
|
||||
* @example
|
||||
* await expect(someAsyncFunc).resolves.toBe(42);
|
||||
*/
|
||||
resolves: PromisifyAssertion<T>;
|
||||
/**
|
||||
* Verifies that a promise rejects.
|
||||
*
|
||||
* @example
|
||||
* await expect(someAsyncFunc).rejects.toThrow('error');
|
||||
*/
|
||||
rejects: PromisifyAssertion<T>;
|
||||
}
|
||||
/**
|
||||
* Chai-style assertions for spy/mock testing.
|
||||
* These provide sinon-chai compatible assertion names that delegate to Jest-style implementations.
|
||||
*/
|
||||
interface ChaiMockAssertion {
|
||||
/**
|
||||
* Checks that a spy was called at least once.
|
||||
* Chai-style equivalent of `toHaveBeenCalled`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.been.called
|
||||
*/
|
||||
readonly called: Assertion;
|
||||
/**
|
||||
* Checks that a spy was called a specific number of times.
|
||||
* Chai-style equivalent of `toHaveBeenCalledTimes`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.callCount(3)
|
||||
*/
|
||||
callCount: (count: number) => void;
|
||||
/**
|
||||
* Checks that a spy was called with specific arguments at least once.
|
||||
* Chai-style equivalent of `toHaveBeenCalledWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.been.calledWith('arg1', 'arg2')
|
||||
*/
|
||||
calledWith: <E extends any[]>(...args: E) => void;
|
||||
/**
|
||||
* Checks that a spy was called exactly once.
|
||||
* Chai-style equivalent of `toHaveBeenCalledOnce`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.been.calledOnce
|
||||
*/
|
||||
readonly calledOnce: Assertion;
|
||||
/**
|
||||
* Checks that a spy was called exactly once with specific arguments.
|
||||
* Chai-style equivalent of `toHaveBeenCalledExactlyOnceWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.been.calledOnceWith('arg1', 'arg2')
|
||||
*/
|
||||
calledOnceWith: <E extends any[]>(...args: E) => void;
|
||||
/**
|
||||
* Checks that the last call to a spy was made with specific arguments.
|
||||
* Chai-style equivalent of `toHaveBeenLastCalledWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.been.lastCalledWith('arg1', 'arg2')
|
||||
*/
|
||||
lastCalledWith: <E extends any[]>(...args: E) => void;
|
||||
/**
|
||||
* Checks that the nth call to a spy was made with specific arguments.
|
||||
* Chai-style equivalent of `toHaveBeenNthCalledWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.been.nthCalledWith(2, 'arg1', 'arg2')
|
||||
*/
|
||||
nthCalledWith: <E extends any[]>(n: number, ...args: E) => void;
|
||||
/**
|
||||
* Checks that a spy returned a specific value at least once.
|
||||
* Chai-style equivalent of `toHaveReturnedWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.returned('value')
|
||||
*/
|
||||
returned: <E>(value: E) => void;
|
||||
/**
|
||||
* Checks that a spy returned a specific value at least once.
|
||||
* Chai-style equivalent of `toHaveReturnedWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.returnedWith('value')
|
||||
*/
|
||||
returnedWith: <E>(value: E) => void;
|
||||
/**
|
||||
* Checks that a spy returned successfully a specific number of times.
|
||||
* Chai-style equivalent of `toHaveReturnedTimes`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.returnedTimes(3)
|
||||
*/
|
||||
returnedTimes: (count: number) => void;
|
||||
/**
|
||||
* Checks that the last return value of a spy matches the expected value.
|
||||
* Chai-style equivalent of `toHaveLastReturnedWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.lastReturnedWith('value')
|
||||
*/
|
||||
lastReturnedWith: <E>(value: E) => void;
|
||||
/**
|
||||
* Checks that the nth return value of a spy matches the expected value.
|
||||
* Chai-style equivalent of `toHaveNthReturnedWith`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.nthReturnedWith(2, 'value')
|
||||
*/
|
||||
nthReturnedWith: <E>(n: number, value: E) => void;
|
||||
/**
|
||||
* Checks that a spy was called before another spy.
|
||||
* Chai-style equivalent of `toHaveBeenCalledBefore`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy1).to.have.been.calledBefore(spy2)
|
||||
*/
|
||||
calledBefore: (mock: MockInstance, failIfNoFirstInvocation?: boolean) => void;
|
||||
/**
|
||||
* Checks that a spy was called after another spy.
|
||||
* Chai-style equivalent of `toHaveBeenCalledAfter`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy1).to.have.been.calledAfter(spy2)
|
||||
*/
|
||||
calledAfter: (mock: MockInstance, failIfNoFirstInvocation?: boolean) => void;
|
||||
/**
|
||||
* Checks that a spy was called exactly twice.
|
||||
* Chai-style equivalent of `toHaveBeenCalledTimes(2)`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.been.calledTwice
|
||||
*/
|
||||
readonly calledTwice: Assertion;
|
||||
/**
|
||||
* Checks that a spy was called exactly three times.
|
||||
* Chai-style equivalent of `toHaveBeenCalledTimes(3)`.
|
||||
*
|
||||
* @example
|
||||
* expect(spy).to.have.been.calledThrice
|
||||
*/
|
||||
readonly calledThrice: Assertion;
|
||||
}
|
||||
declare global {
|
||||
namespace jest {
|
||||
interface Matchers<
|
||||
R,
|
||||
T = {}
|
||||
> {}
|
||||
}
|
||||
}
|
||||
|
||||
declare const ChaiStyleAssertions: ChaiPlugin;
|
||||
|
||||
declare const MATCHERS_OBJECT: unique symbol;
|
||||
declare const JEST_MATCHERS_OBJECT: unique symbol;
|
||||
declare const GLOBAL_EXPECT: unique symbol;
|
||||
declare const ASYMMETRIC_MATCHERS_OBJECT: unique symbol;
|
||||
|
||||
declare const customMatchers: MatchersObject;
|
||||
|
||||
declare const JestChaiExpect: ChaiPlugin;
|
||||
|
||||
declare const JestExtend: ChaiPlugin;
|
||||
|
||||
declare function equals(a: unknown, b: unknown, customTesters?: Array<Tester>, strictCheck?: boolean): boolean;
|
||||
declare function isAsymmetric(obj: any): obj is AsymmetricMatcher<any>;
|
||||
declare function hasAsymmetric(obj: any, seen?: Set<any>): boolean;
|
||||
declare function isError(value: unknown): value is Error;
|
||||
declare function isA(typeName: string, value: unknown): boolean;
|
||||
declare function fnNameFor(func: Function): string;
|
||||
declare function hasProperty(obj: object | null, property: string): boolean;
|
||||
declare function isImmutableUnorderedKeyed(maybeKeyed: any): boolean;
|
||||
declare function isImmutableUnorderedSet(maybeSet: any): boolean;
|
||||
declare function iterableEquality(a: any, b: any, customTesters?: Array<Tester>, aStack?: Array<any>, bStack?: Array<any>): boolean | undefined;
|
||||
declare function subsetEquality(object: unknown, subset: unknown, customTesters?: Array<Tester>): boolean | undefined;
|
||||
declare function typeEquality(a: any, b: any): boolean | undefined;
|
||||
declare function arrayBufferEquality(a: unknown, b: unknown): boolean | undefined;
|
||||
declare function sparseArrayEquality(a: unknown, b: unknown, customTesters?: Array<Tester>): boolean | undefined;
|
||||
declare function generateToBeMessage(deepEqualityName: string, expected?: string, actual?: string): string;
|
||||
declare function pluralize(word: string, count: number): string;
|
||||
declare function getObjectKeys(object: object): Array<string | symbol>;
|
||||
declare function getObjectSubset(object: any, subset: any, customTesters: Array<Tester>): {
|
||||
subset: any;
|
||||
stripped: number;
|
||||
};
|
||||
/**
|
||||
* Detects if an object is a Standard Schema V1 compatible schema
|
||||
*/
|
||||
declare function isStandardSchema(obj: any): obj is StandardSchemaV1;
|
||||
|
||||
declare function getState<State extends MatcherState = MatcherState>(expect: ExpectStatic): State;
|
||||
declare function setState<State extends MatcherState = MatcherState>(state: Partial<State>, expect: ExpectStatic): void;
|
||||
|
||||
declare function createAssertionMessage(util: Chai.ChaiUtils, assertion: Chai.Assertion, hasArgs: boolean): string;
|
||||
declare function recordAsyncExpect(_test: any, promise: Promise<any>, assertion: string, error: Error, isSoft?: boolean): Promise<any>;
|
||||
/** wrap assertion function to support `expect.soft` and provide assertion name as `_name` */
|
||||
declare function wrapAssertion(utils: Chai.ChaiUtils, name: string, fn: (this: Chai.AssertionStatic & Assertion, ...args: any[]) => void | PromiseLike<void>): (this: Chai.AssertionStatic & Assertion, ...args: any[]) => void | PromiseLike<void>;
|
||||
|
||||
export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, ChaiStyleAssertions, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, SchemaMatching, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, createAssertionMessage, customMatchers, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isError, isImmutableUnorderedKeyed, isImmutableUnorderedSet, isStandardSchema, iterableEquality, pluralize, recordAsyncExpect, setState, sparseArrayEquality, subsetEquality, typeEquality, wrapAssertion };
|
||||
export type { Assertion, AsymmetricMatcherInterface, AsymmetricMatchersContaining, AsyncExpectationResult, ChaiMockAssertion, ChaiPlugin, DeeplyAllowMatchers, ExpectStatic, ExpectationResult, JestAssertion, MatcherHintOptions, MatcherState, Matchers, MatchersObject, PromisifyAssertion, RawMatcherFn, SyncExpectationResult, Tester, TesterContext };
|
||||
@@ -0,0 +1,134 @@
|
||||
# 🌈Colorette
|
||||
|
||||
> Easily set your terminal text color & styles.
|
||||
|
||||
- No dependecies
|
||||
- Automatic color support detection
|
||||
- Up to [2x faster](#benchmarks) than alternatives
|
||||
- TypeScript support
|
||||
- [`NO_COLOR`](https://no-color.org) friendly
|
||||
- Node >= `10`
|
||||
|
||||
> [**Upgrading from Colorette `1.x`?**](https://github.com/jorgebucaran/colorette/issues/70)
|
||||
|
||||
## Quickstart
|
||||
|
||||
```js
|
||||
import { blue, bold, underline } from "colorette"
|
||||
|
||||
console.log(
|
||||
blue("I'm blue"),
|
||||
bold(blue("da ba dee")),
|
||||
underline(bold(blue("da ba daa")))
|
||||
)
|
||||
```
|
||||
|
||||
Here's an example using [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals).
|
||||
|
||||
```js
|
||||
console.log(`
|
||||
There's a ${underline(blue("house"))},
|
||||
With a ${bold(blue("window"))},
|
||||
And a ${blue("corvette")}
|
||||
And everything is blue
|
||||
`)
|
||||
```
|
||||
|
||||
You can also nest styles without breaking existing color sequences.
|
||||
|
||||
```js
|
||||
console.log(bold(`I'm ${blue(`da ba ${underline("dee")} da ba`)} daa`))
|
||||
```
|
||||
|
||||
Need to override terminal color detection? You can do that too.
|
||||
|
||||
```js
|
||||
import { createColors } from "colorette"
|
||||
|
||||
const { blue } = createColors({ useColor: false })
|
||||
|
||||
console.log(blue("Blue? Nope, nah"))
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
```console
|
||||
npm install colorette
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### \<color\>()
|
||||
|
||||
> See all [supported colors](#supported-colors).
|
||||
|
||||
```js
|
||||
import { blue } from "colorette"
|
||||
|
||||
blue("I'm blue") //=> \x1b[34mI'm blue\x1b[39m
|
||||
```
|
||||
|
||||
### createColors()
|
||||
|
||||
Override terminal color detection via `createColors({ useColor })`.
|
||||
|
||||
```js
|
||||
import { createColors } from "colorette"
|
||||
|
||||
const { blue } = createColors({ useColor: false })
|
||||
```
|
||||
|
||||
### isColorSupported
|
||||
|
||||
`true` if your terminal supports color, `false` otherwise. Used internally, but exposed for convenience.
|
||||
|
||||
## Environment
|
||||
|
||||
You can override color detection from the CLI by setting the `--no-color` or `--color` flags.
|
||||
|
||||
```console
|
||||
$ ./example.js --no-color | ./consumer.js
|
||||
```
|
||||
|
||||
Or if you can't use CLI flags, by setting the `NO_COLOR=` or `FORCE_COLOR=` environment variables.
|
||||
|
||||
```console
|
||||
$ NO_COLOR= ./example.js | ./consumer.js
|
||||
```
|
||||
|
||||
## Supported colors
|
||||
|
||||
| Colors | Background Colors | Bright Colors | Bright Background Colors | Modifiers |
|
||||
| ------- | ----------------- | ------------- | ------------------------ | ----------------- |
|
||||
| black | bgBlack | blackBright | bgBlackBright | dim |
|
||||
| red | bgRed | redBright | bgRedBright | **bold** |
|
||||
| green | bgGreen | greenBright | bgGreenBright | hidden |
|
||||
| yellow | bgYellow | yellowBright | bgYellowBright | _italic_ |
|
||||
| blue | bgBlue | blueBright | bgBlueBright | <u>underline</u> |
|
||||
| magenta | bgMagenta | magentaBright | bgMagentaBright | ~~strikethrough~~ |
|
||||
| cyan | bgCyan | cyanBright | bgCyanBright | reset |
|
||||
| white | bgWhite | whiteBright | bgWhiteBright | |
|
||||
| gray | | | | |
|
||||
|
||||
## [Benchmarks](https://github.com/jorgebucaran/colorette/actions/workflows/bench.yml)
|
||||
|
||||
```console
|
||||
npm --prefix bench start
|
||||
```
|
||||
|
||||
```diff
|
||||
chalk 1,786,703 ops/sec
|
||||
kleur 1,618,960 ops/sec
|
||||
colors 646,823 ops/sec
|
||||
ansi-colors 786,149 ops/sec
|
||||
picocolors 2,871,758 ops/sec
|
||||
+ colorette 3,002,751 ops/sec
|
||||
```
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Colorette started out in 2015 by [@jorgebucaran](https://github.com/jorgebucaran) as a lightweight alternative to [Chalk](https://github.com/chalk/chalk) and was introduced originally as [Clor](https://github.com/jorgebucaran/colorette/commit/b01b5b9961ceb7df878583a3002e836fae9e37ce). Our terminal color detection logic borrows heavily from [@sindresorhus](https://github.com/sindresorhus) and [@Qix-](https://github.com/Qix-) work on Chalk. The idea of slicing strings to clear bleeding sequences was adapted from a similar technique used by [@alexeyraspopov](https://github.com/alexeyraspopov) in [picocolors](https://github.com/alexeyraspopov/picocolors). Thank you to all our contributors! <3
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE.md)
|
||||
@@ -0,0 +1,252 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
enum testEnum {
|
||||
A = 0,
|
||||
B = 1,
|
||||
}
|
||||
|
||||
test("flat inference", () => {
|
||||
const readonlyString = z.string().readonly();
|
||||
const readonlyNumber = z.number().readonly();
|
||||
const readonlyNaN = z.nan().readonly();
|
||||
const readonlyBigInt = z.bigint().readonly();
|
||||
const readonlyBoolean = z.boolean().readonly();
|
||||
const readonlyDate = z.date().readonly();
|
||||
const readonlyUndefined = z.undefined().readonly();
|
||||
const readonlyNull = z.null().readonly();
|
||||
const readonlyAny = z.any().readonly();
|
||||
const readonlyUnknown = z.unknown().readonly();
|
||||
const readonlyVoid = z.void().readonly();
|
||||
const readonlyStringArray = z.array(z.string()).readonly();
|
||||
const readonlyTuple = z.tuple([z.string(), z.number()]).readonly();
|
||||
const readonlyMap = z.map(z.string(), z.date()).readonly();
|
||||
const readonlySet = z.set(z.string()).readonly();
|
||||
const readonlyStringRecord = z.record(z.string(), z.string()).readonly();
|
||||
const readonlyNumberRecord = z.record(z.string(), z.number()).readonly();
|
||||
const readonlyObject = z.object({ a: z.string(), 1: z.number() }).readonly();
|
||||
const readonlyEnum = z.nativeEnum(testEnum).readonly();
|
||||
const readonlyPromise = z.promise(z.string()).readonly();
|
||||
|
||||
expectTypeOf<typeof readonlyString._output>().toEqualTypeOf<string>();
|
||||
expectTypeOf<typeof readonlyNumber._output>().toEqualTypeOf<number>();
|
||||
expectTypeOf<typeof readonlyNaN._output>().toEqualTypeOf<number>();
|
||||
expectTypeOf<typeof readonlyBigInt._output>().toEqualTypeOf<bigint>();
|
||||
expectTypeOf<typeof readonlyBoolean._output>().toEqualTypeOf<boolean>();
|
||||
expectTypeOf<typeof readonlyDate._output>().toEqualTypeOf<Date>();
|
||||
expectTypeOf<typeof readonlyUndefined._output>().toEqualTypeOf<undefined>();
|
||||
expectTypeOf<typeof readonlyNull._output>().toEqualTypeOf<null>();
|
||||
expectTypeOf<typeof readonlyAny._output>().toEqualTypeOf<any>();
|
||||
expectTypeOf<typeof readonlyUnknown._output>().toEqualTypeOf<Readonly<unknown>>();
|
||||
expectTypeOf<typeof readonlyVoid._output>().toEqualTypeOf<void>();
|
||||
expectTypeOf<typeof readonlyStringArray._output>().toEqualTypeOf<readonly string[]>();
|
||||
expectTypeOf<typeof readonlyTuple._output>().toEqualTypeOf<readonly [string, number]>();
|
||||
expectTypeOf<typeof readonlyMap._output>().toEqualTypeOf<ReadonlyMap<string, Date>>();
|
||||
expectTypeOf<typeof readonlySet._output>().toEqualTypeOf<ReadonlySet<string>>();
|
||||
expectTypeOf<typeof readonlyStringRecord._output>().toEqualTypeOf<Readonly<Record<string, string>>>();
|
||||
expectTypeOf<typeof readonlyNumberRecord._output>().toEqualTypeOf<Readonly<Record<string, number>>>();
|
||||
expectTypeOf<typeof readonlyObject._output>().toEqualTypeOf<{ readonly a: string; readonly 1: number }>();
|
||||
expectTypeOf<typeof readonlyEnum._output>().toEqualTypeOf<Readonly<testEnum>>();
|
||||
expectTypeOf<typeof readonlyPromise._output>().toEqualTypeOf<Promise<string>>();
|
||||
});
|
||||
|
||||
// test("deep inference", () => {
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[0]>>().toEqualTypeOf<string>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[1]>>().toEqualTypeOf<number>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[2]>>().toEqualTypeOf<number>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[3]>>().toEqualTypeOf<bigint>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[4]>>().toEqualTypeOf<boolean>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[5]>>().toEqualTypeOf<Date>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[6]>>().toEqualTypeOf<undefined>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[7]>>().toEqualTypeOf<null>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[8]>>().toEqualTypeOf<any>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[9]>
|
||||
// >().toEqualTypeOf<Readonly<unknown>>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[10]>>().toEqualTypeOf<void>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[11]>
|
||||
// >().toEqualTypeOf<(args_0: string, args_1: number, ...args_2: unknown[]) => unknown>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[12]>
|
||||
// >().toEqualTypeOf<readonly string[]>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[13]>
|
||||
// >().toEqualTypeOf<readonly [string, number]>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[14]>
|
||||
// >().toEqualTypeOf<ReadonlyMap<string, Date>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[15]>
|
||||
// >().toEqualTypeOf<ReadonlySet<Promise<string>>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[16]>
|
||||
// >().toEqualTypeOf<Readonly<Record<string, string>>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[17]>
|
||||
// >().toEqualTypeOf<Readonly<Record<string, number>>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[18]>
|
||||
// >().toEqualTypeOf<{ readonly a: string; readonly 1: number }>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[19]>
|
||||
// >().toEqualTypeOf<Readonly<testEnum>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[20]>
|
||||
// >().toEqualTypeOf<Promise<string>>();
|
||||
|
||||
// expectTypeOf<
|
||||
// z.infer<typeof crazyDeepReadonlySchema>
|
||||
// >().toEqualTypeOf<ReadonlyMap<
|
||||
// ReadonlySet<readonly [string, number]>,
|
||||
// {
|
||||
// readonly a: {
|
||||
// readonly [x: string]: readonly any[];
|
||||
// };
|
||||
// readonly b: {
|
||||
// readonly c: {
|
||||
// readonly d: {
|
||||
// readonly e: {
|
||||
// readonly f: {
|
||||
// readonly g?: {};
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// }
|
||||
// >>();
|
||||
// });
|
||||
|
||||
test("object freezing", async () => {
|
||||
expect(Object.isFrozen(z.array(z.string()).readonly().parse(["a"]))).toBe(true);
|
||||
expect(Object.isFrozen(z.tuple([z.string(), z.number()]).readonly().parse(["a", 1]))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
z
|
||||
.map(z.string(), z.date())
|
||||
.readonly()
|
||||
.parse(new Map([["a", new Date()]]))
|
||||
)
|
||||
).toBe(true);
|
||||
|
||||
expect(Object.isFrozen(z.record(z.string(), z.string()).readonly().parse({ a: "b" }))).toBe(true);
|
||||
expect(Object.isFrozen(z.record(z.string(), z.number()).readonly().parse({ a: 1 }))).toBe(true);
|
||||
expect(Object.isFrozen(z.object({ a: z.string(), 1: z.number() }).readonly().parse({ a: "b", 1: 2 }))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
await z
|
||||
.set(z.promise(z.string()))
|
||||
.readonly()
|
||||
.parseAsync(new Set([Promise.resolve("a")]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(Object.isFrozen(await z.promise(z.string()).readonly().parseAsync(Promise.resolve("a")))).toBe(true);
|
||||
});
|
||||
|
||||
test("async object freezing", async () => {
|
||||
expect(Object.isFrozen(await z.array(z.string()).readonly().parseAsync(["a"]))).toBe(true);
|
||||
expect(Object.isFrozen(await z.tuple([z.string(), z.number()]).readonly().parseAsync(["a", 1]))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
await z
|
||||
.map(z.string(), z.date())
|
||||
.readonly()
|
||||
.parseAsync(new Map([["a", new Date()]]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
await z
|
||||
.set(z.promise(z.string()))
|
||||
.readonly()
|
||||
.parseAsync(new Set([Promise.resolve("a")]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(Object.isFrozen(await z.record(z.string(), z.string()).readonly().parseAsync({ a: "b" }))).toBe(true);
|
||||
expect(Object.isFrozen(await z.record(z.string(), z.number()).readonly().parseAsync({ a: 1 }))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(await z.object({ a: z.string(), 1: z.number() }).readonly().parseAsync({ a: "b", 1: 2 }))
|
||||
).toBe(true);
|
||||
expect(Object.isFrozen(await z.promise(z.string()).readonly().parseAsync(Promise.resolve("a")))).toBe(true);
|
||||
});
|
||||
|
||||
test("readonly inference", () => {
|
||||
const readonlyStringArray = z.string().array().readonly();
|
||||
const readonlyStringTuple = z.tuple([z.string()]).readonly();
|
||||
const deepReadonly = z.object({ a: z.string() }).readonly();
|
||||
|
||||
type readonlyStringArray = z.infer<typeof readonlyStringArray>;
|
||||
type readonlyStringTuple = z.infer<typeof readonlyStringTuple>;
|
||||
type deepReadonly = z.infer<typeof deepReadonly>;
|
||||
|
||||
expectTypeOf<readonlyStringArray>().toEqualTypeOf<readonly string[]>();
|
||||
expectTypeOf<readonlyStringTuple>().toEqualTypeOf<readonly [string]>();
|
||||
expectTypeOf<deepReadonly>().toEqualTypeOf<{ readonly a: string }>();
|
||||
});
|
||||
|
||||
test("readonly parse", () => {
|
||||
const schema = z.array(z.string()).readonly();
|
||||
const readonlyArray = ["a", "b", "c"] as const;
|
||||
const mutableArray = ["a", "b", "c"];
|
||||
const result1 = schema.parse(readonlyArray);
|
||||
const result2 = schema.parse(mutableArray);
|
||||
expect(result1).toEqual(readonlyArray);
|
||||
expect(result2).toEqual(mutableArray);
|
||||
});
|
||||
|
||||
test("readonly parse with tuples", () => {
|
||||
const schema = z.tuple([z.string(), z.number()]).readonly();
|
||||
schema.parse(["a", 1]);
|
||||
});
|
||||
|
||||
test("readonly and the get method", () => {
|
||||
const readonlyString = z.string().readonly();
|
||||
const readonlyNumber1 = z.number().readonly();
|
||||
const readonlyNumber2 = z.number().readonly();
|
||||
const readonlyBigInt = z.bigint().readonly();
|
||||
const readonlyBoolean = z.boolean().readonly();
|
||||
const readonlyDate = z.date().readonly();
|
||||
const readonlyUndefined = z.undefined().readonly();
|
||||
const readonlyNull = z.null().readonly();
|
||||
const readonlyAny = z.any().readonly();
|
||||
const readonlyUnknown = z.unknown().readonly();
|
||||
const readonlyVoid = z.void().readonly();
|
||||
// const readonlyFunction = z.function(z.tuple([z.string(), z.number()]), z.unknown()).readonly();
|
||||
const readonlyStringArray = z.string().array().readonly();
|
||||
const readonlyTuple = z.tuple([z.string(), z.number()]).readonly();
|
||||
|
||||
expectTypeOf<z.infer<typeof readonlyString>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof readonlyNumber1>>().toEqualTypeOf<number>();
|
||||
expectTypeOf<z.infer<typeof readonlyNumber2>>().toEqualTypeOf<number>();
|
||||
expectTypeOf<z.infer<typeof readonlyBigInt>>().toEqualTypeOf<bigint>();
|
||||
expectTypeOf<z.infer<typeof readonlyBoolean>>().toEqualTypeOf<boolean>();
|
||||
expectTypeOf<z.infer<typeof readonlyDate>>().toEqualTypeOf<Date>();
|
||||
expectTypeOf<z.infer<typeof readonlyUndefined>>().toEqualTypeOf<undefined>();
|
||||
expectTypeOf<z.infer<typeof readonlyNull>>().toEqualTypeOf<null>();
|
||||
expectTypeOf<z.infer<typeof readonlyAny>>().toEqualTypeOf<any>();
|
||||
expectTypeOf<z.infer<typeof readonlyUnknown>>().toEqualTypeOf<Readonly<unknown>>();
|
||||
expectTypeOf<z.infer<typeof readonlyVoid>>().toEqualTypeOf<void>();
|
||||
// expectTypeOf<z.infer<typeof readonlyFunction>>().toEqualTypeOf<
|
||||
// (args_0: string, args_1: number, ...args_2: unknown[]) => unknown
|
||||
// >();
|
||||
expectTypeOf<z.infer<typeof readonlyStringArray>>().toEqualTypeOf<readonly string[]>();
|
||||
expectTypeOf<z.infer<typeof readonlyTuple>>().toEqualTypeOf<readonly [string, number]>();
|
||||
|
||||
expect(readonlyString.parse("asdf")).toEqual("asdf");
|
||||
expect(readonlyNumber1.parse(1234)).toEqual(1234);
|
||||
expect(readonlyNumber2.parse(1234)).toEqual(1234);
|
||||
const bigIntVal = BigInt(1);
|
||||
expect(readonlyBigInt.parse(bigIntVal)).toEqual(bigIntVal);
|
||||
expect(readonlyBoolean.parse(true)).toEqual(true);
|
||||
const dateVal = new Date();
|
||||
expect(readonlyDate.parse(dateVal)).toEqual(dateVal);
|
||||
expect(readonlyUndefined.parse(undefined)).toEqual(undefined);
|
||||
expect(readonlyNull.parse(null)).toEqual(null);
|
||||
expect(readonlyAny.parse("whatever")).toEqual("whatever");
|
||||
expect(readonlyUnknown.parse("whatever")).toEqual("whatever");
|
||||
expect(readonlyVoid.parse(undefined)).toEqual(undefined);
|
||||
// expect(readonlyFunction.parse(() => void 0)).toEqual(() => void 0);
|
||||
expect(readonlyStringArray.parse(["asdf"])).toEqual(["asdf"]);
|
||||
expect(readonlyTuple.parse(["asdf", 1234])).toEqual(["asdf", 1234]);
|
||||
});
|
||||
@@ -0,0 +1,465 @@
|
||||
// Generated by LiveScript 1.6.0
|
||||
(function(){
|
||||
var VERSION, ref$, id, map, compact, any, groupBy, partition, chars, isItNaN, keys, Obj, camelize, deepIs, closestString, nameToRaw, dasherize, naturalJoin, generateHelp, generateHelpForOption, parsedTypeCheck, parseType, parseLevn, camelizeKeys, parseString, main, toString$ = {}.toString, slice$ = [].slice, arrayFrom$ = Array.from || function(x){return slice$.call(x);};
|
||||
VERSION = '0.9.4';
|
||||
ref$ = require('prelude-ls'), id = ref$.id, map = ref$.map, compact = ref$.compact, any = ref$.any, groupBy = ref$.groupBy, partition = ref$.partition, chars = ref$.chars, isItNaN = ref$.isItNaN, keys = ref$.keys, Obj = ref$.Obj, camelize = ref$.camelize;
|
||||
deepIs = require('deep-is');
|
||||
ref$ = require('./util'), closestString = ref$.closestString, nameToRaw = ref$.nameToRaw, dasherize = ref$.dasherize, naturalJoin = ref$.naturalJoin;
|
||||
ref$ = require('./help'), generateHelp = ref$.generateHelp, generateHelpForOption = ref$.generateHelpForOption;
|
||||
ref$ = require('type-check'), parsedTypeCheck = ref$.parsedTypeCheck, parseType = ref$.parseType;
|
||||
parseLevn = require('levn').parsedTypeParse;
|
||||
camelizeKeys = function(obj){
|
||||
var key, value, resultObj$ = {};
|
||||
for (key in obj) {
|
||||
value = obj[key];
|
||||
resultObj$[camelize(key)] = value;
|
||||
}
|
||||
return resultObj$;
|
||||
};
|
||||
parseString = function(string){
|
||||
var assignOpt, regex, replaceRegex, result;
|
||||
assignOpt = '--?[a-zA-Z][-a-z-A-Z0-9]*=';
|
||||
regex = RegExp('(?:' + assignOpt + ')?(?:\'(?:\\\\\'|[^\'])+\'|"(?:\\\\"|[^"])+")|[^\'"\\s]+', 'g');
|
||||
replaceRegex = RegExp('^(' + assignOpt + ')?[\'"]([\\s\\S]*)[\'"]$');
|
||||
result = map(function(it){
|
||||
return it.replace(replaceRegex, '$1$2');
|
||||
}, string.match(regex) || []);
|
||||
return result;
|
||||
};
|
||||
main = function(libOptions){
|
||||
var opts, defaults, required, traverse, getOption, parse;
|
||||
opts = {};
|
||||
defaults = {};
|
||||
required = [];
|
||||
if (toString$.call(libOptions.stdout).slice(8, -1) === 'Undefined') {
|
||||
libOptions.stdout = process.stdout;
|
||||
}
|
||||
libOptions.positionalAnywhere == null && (libOptions.positionalAnywhere = true);
|
||||
libOptions.typeAliases == null && (libOptions.typeAliases = {});
|
||||
libOptions.defaults == null && (libOptions.defaults = {});
|
||||
if (libOptions.concatRepeatedArrays != null) {
|
||||
libOptions.defaults.concatRepeatedArrays = libOptions.concatRepeatedArrays;
|
||||
}
|
||||
if (libOptions.mergeRepeatedObjects != null) {
|
||||
libOptions.defaults.mergeRepeatedObjects = libOptions.mergeRepeatedObjects;
|
||||
}
|
||||
traverse = function(options){
|
||||
var i$, len$, option, name, k, ref$, v, type, that, e, parsedPossibilities, parsedType, j$, len1$, possibility, rawDependsType, dependsOpts, dependsType, cra, alias, shortNames, longNames;
|
||||
if (toString$.call(options).slice(8, -1) !== 'Array') {
|
||||
throw new Error('No options defined.');
|
||||
}
|
||||
for (i$ = 0, len$ = options.length; i$ < len$; ++i$) {
|
||||
option = options[i$];
|
||||
if (option.heading == null) {
|
||||
name = option.option;
|
||||
if (opts[name] != null) {
|
||||
throw new Error("Option '" + name + "' already defined.");
|
||||
}
|
||||
for (k in ref$ = libOptions.defaults) {
|
||||
v = ref$[k];
|
||||
option[k] == null && (option[k] = v);
|
||||
}
|
||||
if (option.type === 'Boolean') {
|
||||
option.boolean == null && (option.boolean = true);
|
||||
}
|
||||
if (option.parsedType == null) {
|
||||
if (!option.type) {
|
||||
throw new Error("No type defined for option '" + name + "'.");
|
||||
}
|
||||
try {
|
||||
type = (that = libOptions.typeAliases[option.type]) != null
|
||||
? that
|
||||
: option.type;
|
||||
option.parsedType = parseType(type);
|
||||
} catch (e$) {
|
||||
e = e$;
|
||||
throw new Error("Option '" + name + "': Error parsing type '" + option.type + "': " + e.message);
|
||||
}
|
||||
}
|
||||
if (option['default']) {
|
||||
try {
|
||||
defaults[name] = parseLevn(option.parsedType, option['default']);
|
||||
} catch (e$) {
|
||||
e = e$;
|
||||
throw new Error("Option '" + name + "': Error parsing default value '" + option['default'] + "' for type '" + option.type + "': " + e.message);
|
||||
}
|
||||
}
|
||||
if (option['enum'] && !option.parsedPossiblities) {
|
||||
parsedPossibilities = [];
|
||||
parsedType = option.parsedType;
|
||||
for (j$ = 0, len1$ = (ref$ = option['enum']).length; j$ < len1$; ++j$) {
|
||||
possibility = ref$[j$];
|
||||
try {
|
||||
parsedPossibilities.push(parseLevn(parsedType, possibility));
|
||||
} catch (e$) {
|
||||
e = e$;
|
||||
throw new Error("Option '" + name + "': Error parsing enum value '" + possibility + "' for type '" + option.type + "': " + e.message);
|
||||
}
|
||||
}
|
||||
option.parsedPossibilities = parsedPossibilities;
|
||||
}
|
||||
if (that = option.dependsOn) {
|
||||
if (that.length) {
|
||||
ref$ = [].concat(option.dependsOn), rawDependsType = ref$[0], dependsOpts = slice$.call(ref$, 1);
|
||||
dependsType = rawDependsType.toLowerCase();
|
||||
if (dependsOpts.length) {
|
||||
if (dependsType === 'and' || dependsType === 'or') {
|
||||
option.dependsOn = [dependsType].concat(arrayFrom$(dependsOpts));
|
||||
} else {
|
||||
throw new Error("Option '" + name + "': If you have more than one dependency, you must specify either 'and' or 'or'");
|
||||
}
|
||||
} else {
|
||||
if ((ref$ = dependsType.toLowerCase()) === 'and' || ref$ === 'or') {
|
||||
option.dependsOn = null;
|
||||
} else {
|
||||
option.dependsOn = ['and', rawDependsType];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
option.dependsOn = null;
|
||||
}
|
||||
}
|
||||
if (option.required) {
|
||||
required.push(name);
|
||||
}
|
||||
opts[name] = option;
|
||||
if (option.concatRepeatedArrays != null) {
|
||||
cra = option.concatRepeatedArrays;
|
||||
if ('Boolean' === toString$.call(cra).slice(8, -1)) {
|
||||
option.concatRepeatedArrays = [cra, {}];
|
||||
} else if (cra.length === 1) {
|
||||
option.concatRepeatedArrays = [cra[0], {}];
|
||||
} else if (cra.length !== 2) {
|
||||
throw new Error("Invalid setting for concatRepeatedArrays");
|
||||
}
|
||||
}
|
||||
if (option.alias || option.aliases) {
|
||||
if (name === 'NUM') {
|
||||
throw new Error("-NUM option can't have aliases.");
|
||||
}
|
||||
if (option.alias) {
|
||||
option.aliases == null && (option.aliases = [].concat(option.alias));
|
||||
}
|
||||
for (j$ = 0, len1$ = (ref$ = option.aliases).length; j$ < len1$; ++j$) {
|
||||
alias = ref$[j$];
|
||||
if (opts[alias] != null) {
|
||||
throw new Error("Option '" + alias + "' already defined.");
|
||||
}
|
||||
opts[alias] = option;
|
||||
}
|
||||
ref$ = partition(fn$, option.aliases), shortNames = ref$[0], longNames = ref$[1];
|
||||
option.shortNames == null && (option.shortNames = shortNames);
|
||||
option.longNames == null && (option.longNames = longNames);
|
||||
}
|
||||
if ((!option.aliases || option.shortNames.length === 0) && option.type === 'Boolean' && option['default'] === 'true') {
|
||||
option.negateName = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
function fn$(it){
|
||||
return it.length === 1;
|
||||
}
|
||||
};
|
||||
traverse(libOptions.options);
|
||||
getOption = function(name){
|
||||
var opt, possiblyMeant;
|
||||
opt = opts[name];
|
||||
if (opt == null) {
|
||||
possiblyMeant = closestString(keys(opts), name);
|
||||
throw new Error("Invalid option '" + nameToRaw(name) + "'" + (possiblyMeant ? " - perhaps you meant '" + nameToRaw(possiblyMeant) + "'?" : '.'));
|
||||
}
|
||||
return opt;
|
||||
};
|
||||
parse = function(input, arg$){
|
||||
var slice, obj, positional, restPositional, overrideRequired, prop, setValue, setDefaults, checkRequired, mutuallyExclusiveError, checkMutuallyExclusive, checkDependency, checkDependencies, checkProp, args, key, value, option, ref$, i$, len$, arg, that, result, short, argName, usingAssign, val, flags, len, j$, len1$, i, flag, opt, name, valPrime, negated, noedName;
|
||||
slice = (arg$ != null
|
||||
? arg$
|
||||
: {}).slice;
|
||||
obj = {};
|
||||
positional = [];
|
||||
restPositional = false;
|
||||
overrideRequired = false;
|
||||
prop = null;
|
||||
setValue = function(name, value){
|
||||
var opt, val, cra, e, currentType;
|
||||
opt = getOption(name);
|
||||
if (opt.boolean) {
|
||||
val = value;
|
||||
} else {
|
||||
try {
|
||||
cra = opt.concatRepeatedArrays;
|
||||
if (cra != null && cra[0] && cra[1].oneValuePerFlag && opt.parsedType.length === 1 && opt.parsedType[0].structure === 'array') {
|
||||
val = [parseLevn(opt.parsedType[0].of, value)];
|
||||
} else {
|
||||
val = parseLevn(opt.parsedType, value);
|
||||
}
|
||||
} catch (e$) {
|
||||
e = e$;
|
||||
throw new Error("Invalid value for option '" + name + "' - expected type " + opt.type + ", received value: " + value + ".");
|
||||
}
|
||||
if (opt['enum'] && !any(function(it){
|
||||
return deepIs(it, val);
|
||||
}, opt.parsedPossibilities)) {
|
||||
throw new Error("Option " + name + ": '" + val + "' not one of " + naturalJoin(opt['enum']) + ".");
|
||||
}
|
||||
}
|
||||
currentType = toString$.call(obj[name]).slice(8, -1);
|
||||
if (obj[name] != null) {
|
||||
if (opt.concatRepeatedArrays != null && opt.concatRepeatedArrays[0] && currentType === 'Array') {
|
||||
obj[name] = obj[name].concat(val);
|
||||
} else if (opt.mergeRepeatedObjects && currentType === 'Object') {
|
||||
import$(obj[name], val);
|
||||
} else {
|
||||
obj[name] = val;
|
||||
}
|
||||
} else {
|
||||
obj[name] = val;
|
||||
}
|
||||
if (opt.restPositional) {
|
||||
restPositional = true;
|
||||
}
|
||||
if (opt.overrideRequired) {
|
||||
overrideRequired = true;
|
||||
}
|
||||
};
|
||||
setDefaults = function(){
|
||||
var name, ref$, value;
|
||||
for (name in ref$ = defaults) {
|
||||
value = ref$[name];
|
||||
if (obj[name] == null) {
|
||||
obj[name] = value;
|
||||
}
|
||||
}
|
||||
};
|
||||
checkRequired = function(){
|
||||
var i$, ref$, len$, name;
|
||||
if (overrideRequired) {
|
||||
return;
|
||||
}
|
||||
for (i$ = 0, len$ = (ref$ = required).length; i$ < len$; ++i$) {
|
||||
name = ref$[i$];
|
||||
if (!obj[name]) {
|
||||
throw new Error("Option " + nameToRaw(name) + " is required.");
|
||||
}
|
||||
}
|
||||
};
|
||||
mutuallyExclusiveError = function(first, second){
|
||||
throw new Error("The options " + nameToRaw(first) + " and " + nameToRaw(second) + " are mutually exclusive - you cannot use them at the same time.");
|
||||
};
|
||||
checkMutuallyExclusive = function(){
|
||||
var rules, i$, len$, rule, present, j$, len1$, element, k$, len2$, opt;
|
||||
rules = libOptions.mutuallyExclusive;
|
||||
if (!rules) {
|
||||
return;
|
||||
}
|
||||
for (i$ = 0, len$ = rules.length; i$ < len$; ++i$) {
|
||||
rule = rules[i$];
|
||||
present = null;
|
||||
for (j$ = 0, len1$ = rule.length; j$ < len1$; ++j$) {
|
||||
element = rule[j$];
|
||||
if (toString$.call(element).slice(8, -1) === 'Array') {
|
||||
for (k$ = 0, len2$ = element.length; k$ < len2$; ++k$) {
|
||||
opt = element[k$];
|
||||
if (opt in obj) {
|
||||
if (present != null) {
|
||||
mutuallyExclusiveError(present, opt);
|
||||
} else {
|
||||
present = opt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (element in obj) {
|
||||
if (present != null) {
|
||||
mutuallyExclusiveError(present, element);
|
||||
} else {
|
||||
present = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
checkDependency = function(option){
|
||||
var dependsOn, type, targetOptionNames, i$, len$, targetOptionName, targetOption;
|
||||
dependsOn = option.dependsOn;
|
||||
if (!dependsOn || option.dependenciesMet) {
|
||||
return true;
|
||||
}
|
||||
type = dependsOn[0], targetOptionNames = slice$.call(dependsOn, 1);
|
||||
for (i$ = 0, len$ = targetOptionNames.length; i$ < len$; ++i$) {
|
||||
targetOptionName = targetOptionNames[i$];
|
||||
targetOption = obj[targetOptionName];
|
||||
if (targetOption && checkDependency(targetOption)) {
|
||||
if (type === 'or') {
|
||||
return true;
|
||||
}
|
||||
} else if (type === 'and') {
|
||||
throw new Error("The option '" + option.option + "' did not have its dependencies met.");
|
||||
}
|
||||
}
|
||||
if (type === 'and') {
|
||||
return true;
|
||||
} else {
|
||||
throw new Error("The option '" + option.option + "' did not meet any of its dependencies.");
|
||||
}
|
||||
};
|
||||
checkDependencies = function(){
|
||||
var name;
|
||||
for (name in obj) {
|
||||
checkDependency(opts[name]);
|
||||
}
|
||||
};
|
||||
checkProp = function(){
|
||||
if (prop) {
|
||||
throw new Error("Value for '" + prop + "' of type '" + getOption(prop).type + "' required.");
|
||||
}
|
||||
};
|
||||
switch (toString$.call(input).slice(8, -1)) {
|
||||
case 'String':
|
||||
args = parseString(input.slice(slice != null ? slice : 0));
|
||||
break;
|
||||
case 'Array':
|
||||
args = input.slice(slice != null ? slice : 2);
|
||||
break;
|
||||
case 'Object':
|
||||
obj = {};
|
||||
for (key in input) {
|
||||
value = input[key];
|
||||
if (key !== '_') {
|
||||
option = getOption(dasherize(key));
|
||||
if (parsedTypeCheck(option.parsedType, value)) {
|
||||
obj[option.option] = value;
|
||||
} else {
|
||||
throw new Error("Option '" + option.option + "': Invalid type for '" + value + "' - expected type '" + option.type + "'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
checkMutuallyExclusive();
|
||||
checkDependencies();
|
||||
setDefaults();
|
||||
checkRequired();
|
||||
return ref$ = camelizeKeys(obj), ref$._ = input._ || [], ref$;
|
||||
default:
|
||||
throw new Error("Invalid argument to 'parse': " + input + ".");
|
||||
}
|
||||
for (i$ = 0, len$ = args.length; i$ < len$; ++i$) {
|
||||
arg = args[i$];
|
||||
if (arg === '--') {
|
||||
restPositional = true;
|
||||
} else if (restPositional) {
|
||||
positional.push(arg);
|
||||
} else {
|
||||
if (that = arg.match(/^(--?)([a-zA-Z][-a-zA-Z0-9]*)(=)?(.*)?$/)) {
|
||||
result = that;
|
||||
checkProp();
|
||||
short = result[1].length === 1;
|
||||
argName = result[2];
|
||||
usingAssign = result[3] != null;
|
||||
val = result[4];
|
||||
if (usingAssign && val == null) {
|
||||
throw new Error("No value for '" + argName + "' specified.");
|
||||
}
|
||||
if (short) {
|
||||
flags = chars(argName);
|
||||
len = flags.length;
|
||||
for (j$ = 0, len1$ = flags.length; j$ < len1$; ++j$) {
|
||||
i = j$;
|
||||
flag = flags[j$];
|
||||
opt = getOption(flag);
|
||||
name = opt.option;
|
||||
if (restPositional) {
|
||||
positional.push(flag);
|
||||
} else if (i === len - 1) {
|
||||
if (usingAssign) {
|
||||
valPrime = opt.boolean ? parseLevn([{
|
||||
type: 'Boolean'
|
||||
}], val) : val;
|
||||
setValue(name, valPrime);
|
||||
} else if (opt.boolean) {
|
||||
setValue(name, true);
|
||||
} else {
|
||||
prop = name;
|
||||
}
|
||||
} else if (opt.boolean) {
|
||||
setValue(name, true);
|
||||
} else {
|
||||
throw new Error("Can't set argument '" + flag + "' when not last flag in a group of short flags.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
negated = false;
|
||||
if (that = argName.match(/^no-(.+)$/)) {
|
||||
negated = true;
|
||||
noedName = that[1];
|
||||
opt = getOption(noedName);
|
||||
} else {
|
||||
opt = getOption(argName);
|
||||
}
|
||||
name = opt.option;
|
||||
if (opt.boolean) {
|
||||
valPrime = usingAssign ? parseLevn([{
|
||||
type: 'Boolean'
|
||||
}], val) : true;
|
||||
if (negated) {
|
||||
setValue(name, !valPrime);
|
||||
} else {
|
||||
setValue(name, valPrime);
|
||||
}
|
||||
} else {
|
||||
if (negated) {
|
||||
throw new Error("Only use 'no-' prefix for Boolean options, not with '" + noedName + "'.");
|
||||
}
|
||||
if (usingAssign) {
|
||||
setValue(name, val);
|
||||
} else {
|
||||
prop = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (that = arg.match(/^-([0-9]+(?:\.[0-9]+)?)$/)) {
|
||||
opt = opts.NUM;
|
||||
if (!opt) {
|
||||
throw new Error('No -NUM option defined.');
|
||||
}
|
||||
setValue(opt.option, that[1]);
|
||||
} else {
|
||||
if (prop) {
|
||||
setValue(prop, arg);
|
||||
prop = null;
|
||||
} else {
|
||||
positional.push(arg);
|
||||
if (!libOptions.positionalAnywhere) {
|
||||
restPositional = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checkProp();
|
||||
checkMutuallyExclusive();
|
||||
checkDependencies();
|
||||
setDefaults();
|
||||
checkRequired();
|
||||
return ref$ = camelizeKeys(obj), ref$._ = positional, ref$;
|
||||
};
|
||||
return {
|
||||
parse: parse,
|
||||
parseArgv: function(it){
|
||||
return parse(it, {
|
||||
slice: 2
|
||||
});
|
||||
},
|
||||
generateHelp: generateHelp(libOptions),
|
||||
generateHelpForOption: generateHelpForOption(getOption, libOptions)
|
||||
};
|
||||
};
|
||||
main.VERSION = VERSION;
|
||||
module.exports = main;
|
||||
function import$(obj, src){
|
||||
var own = {}.hasOwnProperty;
|
||||
for (var key in src) if (own.call(src, key)) obj[key] = src[key];
|
||||
return obj;
|
||||
}
|
||||
}).call(this);
|
||||
@@ -0,0 +1,33 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.z = void 0;
|
||||
const z = __importStar(require("./v4/classic/external.cjs"));
|
||||
exports.z = z;
|
||||
__exportStar(require("./v4/classic/external.cjs"), exports);
|
||||
exports.default = z;
|
||||
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isArray = isArray;
|
||||
// https://github.com/microsoft/TypeScript/issues/17002
|
||||
function isArray(arg) {
|
||||
return Array.isArray(arg);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import Enumerator from '../enumerator';
|
||||
|
||||
/**
|
||||
`Promise.all` accepts an array of promises, and returns a new promise which
|
||||
is fulfilled with an array of fulfillment values for the passed promises, or
|
||||
rejected with the reason of the first passed promise to be rejected. It casts all
|
||||
elements of the passed iterable to promises as it runs this algorithm.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
let promise1 = resolve(1);
|
||||
let promise2 = resolve(2);
|
||||
let promise3 = resolve(3);
|
||||
let promises = [ promise1, promise2, promise3 ];
|
||||
|
||||
Promise.all(promises).then(function(array){
|
||||
// The array here would be [ 1, 2, 3 ];
|
||||
});
|
||||
```
|
||||
|
||||
If any of the `promises` given to `all` are rejected, the first promise
|
||||
that is rejected will be given as an argument to the returned promises's
|
||||
rejection handler. For example:
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
let promise1 = resolve(1);
|
||||
let promise2 = reject(new Error("2"));
|
||||
let promise3 = reject(new Error("3"));
|
||||
let promises = [ promise1, promise2, promise3 ];
|
||||
|
||||
Promise.all(promises).then(function(array){
|
||||
// Code here never runs because there are rejected promises!
|
||||
}, function(error) {
|
||||
// error.message === "2"
|
||||
});
|
||||
```
|
||||
|
||||
@method all
|
||||
@static
|
||||
@param {Array} entries array of promises
|
||||
@param {String} label optional string for labeling the promise.
|
||||
Useful for tooling.
|
||||
@return {Promise} promise that is fulfilled when all `promises` have been
|
||||
fulfilled, or rejected if any of them become rejected.
|
||||
@static
|
||||
*/
|
||||
export default function all(entries) {
|
||||
return new Enumerator(this, entries).promise;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABILITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
/// <reference lib="es5" />
|
||||
/// <reference lib="es2015.core" />
|
||||
/// <reference lib="es2015.collection" />
|
||||
/// <reference lib="es2015.iterable" />
|
||||
/// <reference lib="es2015.generator" />
|
||||
/// <reference lib="es2015.promise" />
|
||||
/// <reference lib="es2015.proxy" />
|
||||
/// <reference lib="es2015.reflect" />
|
||||
/// <reference lib="es2015.symbol" />
|
||||
/// <reference lib="es2015.symbol.wellknown" />
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Event } from './events';
|
||||
import { Disposable } from './disposable';
|
||||
/**
|
||||
* Defines a CancellationToken. This interface is not
|
||||
* intended to be implemented. A CancellationToken must
|
||||
* be created via a CancellationTokenSource.
|
||||
*/
|
||||
export interface CancellationToken {
|
||||
/**
|
||||
* Is `true` when the token has been cancelled, `false` otherwise.
|
||||
*/
|
||||
readonly isCancellationRequested: boolean;
|
||||
/**
|
||||
* An {@link Event event} which fires upon cancellation.
|
||||
*/
|
||||
readonly onCancellationRequested: Event<any>;
|
||||
}
|
||||
export declare namespace CancellationToken {
|
||||
const None: CancellationToken;
|
||||
const Cancelled: CancellationToken;
|
||||
function is(value: any): value is CancellationToken;
|
||||
}
|
||||
export interface AbstractCancellationTokenSource extends Disposable {
|
||||
token: CancellationToken;
|
||||
cancel(): void;
|
||||
}
|
||||
export declare class CancellationTokenSource implements AbstractCancellationTokenSource {
|
||||
private _token;
|
||||
get token(): CancellationToken;
|
||||
cancel(): void;
|
||||
dispose(): void;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
'use strict'
|
||||
const pino = require('../..')
|
||||
const log = pino({
|
||||
transport: {
|
||||
target: 'pino/file',
|
||||
options: { destination: 1 }
|
||||
}
|
||||
})
|
||||
log.info('hello world!')
|
||||
process.on('exit', (code) => {
|
||||
log.info('Exiting peacefully')
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"typePredicateKind.js","sourceRoot":"","sources":["../../src/enums/typePredicateKind.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,MAAM,CAAC,IAAI,iBAAsB,CAAC;AAClC,CAAC,UAAU,iBAAiB;IACxB,iBAAiB,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;IAC1D,iBAAiB,CAAC,iBAAiB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC;IACtE,iBAAiB,CAAC,iBAAiB,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC;IACxE,iBAAiB,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,GAAG,mBAAmB,CAAC;AACxF,CAAC,CAAC,CAAC,iBAAiB,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,CAAC,CAAC"}
|
||||
@@ -0,0 +1,189 @@
|
||||
import { stripVTControlCharacters } from 'node:util';
|
||||
import { slash } from '@vitest/utils/helpers';
|
||||
import { isAbsolute, relative, dirname, basename } from 'pathe';
|
||||
import c from 'tinyrainbow';
|
||||
|
||||
const F_RIGHT = "→";
|
||||
const F_DOWN = "↓";
|
||||
const F_DOWN_RIGHT = "↳";
|
||||
const F_POINTER = "❯";
|
||||
const F_DOT = "·";
|
||||
const F_CHECK = "✓";
|
||||
const F_CROSS = "×";
|
||||
const F_LONG_DASH = "⎯";
|
||||
const F_TODO = "□";
|
||||
const F_TREE_NODE_MIDDLE = "├──";
|
||||
const F_TREE_NODE_END = "└──";
|
||||
|
||||
const pointer = c.yellow(F_POINTER);
|
||||
const skipped = c.dim(c.gray(F_DOWN));
|
||||
const todo = c.dim(c.gray(F_TODO));
|
||||
const benchmarkPass = c.green(F_DOT);
|
||||
const testPass = c.green(F_CHECK);
|
||||
const taskFail = c.red(F_CROSS);
|
||||
const suiteFail = c.red(F_POINTER);
|
||||
const pending = c.gray("·");
|
||||
const separator = c.dim(" > ");
|
||||
const labelDefaultColors = [
|
||||
c.bgYellow,
|
||||
c.bgCyan,
|
||||
c.bgGreen,
|
||||
c.bgMagenta
|
||||
];
|
||||
function getCols(delta = 0) {
|
||||
let length = process.stdout?.columns;
|
||||
if (!length || Number.isNaN(length)) length = 30;
|
||||
return Math.max(length + delta, 0);
|
||||
}
|
||||
function errorBanner(message) {
|
||||
return divider(c.bold(c.bgRed(` ${message} `)), null, null, c.red);
|
||||
}
|
||||
function divider(text, left, right, color) {
|
||||
const cols = getCols();
|
||||
const c = color || ((text) => text);
|
||||
if (text) {
|
||||
const textLength = stripVTControlCharacters(text).length;
|
||||
if (left == null && right != null) left = cols - textLength - right;
|
||||
else {
|
||||
left = left ?? Math.floor((cols - textLength) / 2);
|
||||
right = cols - textLength - left;
|
||||
}
|
||||
left = Math.max(0, left);
|
||||
right = Math.max(0, right);
|
||||
return `${c(F_LONG_DASH.repeat(left))}${text}${c(F_LONG_DASH.repeat(right))}`;
|
||||
}
|
||||
return F_LONG_DASH.repeat(cols);
|
||||
}
|
||||
function formatTestPath(root, path) {
|
||||
if (isAbsolute(path)) path = relative(root, path);
|
||||
const dir = dirname(path);
|
||||
const ext = path.match(/(\.(spec|test)\.[cm]?[tj]sx?)$/)?.[0] || "";
|
||||
const base = basename(path, ext);
|
||||
return slash(c.dim(`${dir}/`) + c.bold(base)) + c.dim(ext);
|
||||
}
|
||||
function renderSnapshotSummary(rootDir, snapshots) {
|
||||
const summary = [];
|
||||
if (snapshots.added) summary.push(c.bold(c.green(`${snapshots.added} written`)));
|
||||
if (snapshots.unmatched) summary.push(c.bold(c.red(`${snapshots.unmatched} failed`)));
|
||||
if (snapshots.updated) summary.push(c.bold(c.green(`${snapshots.updated} updated `)));
|
||||
if (snapshots.filesRemoved) if (snapshots.didUpdate) summary.push(c.bold(c.green(`${snapshots.filesRemoved} files removed `)));
|
||||
else summary.push(c.bold(c.yellow(`${snapshots.filesRemoved} files obsolete `)));
|
||||
if (snapshots.filesRemovedList && snapshots.filesRemovedList.length) {
|
||||
const [head, ...tail] = snapshots.filesRemovedList;
|
||||
summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, head)}`);
|
||||
tail.forEach((key) => {
|
||||
summary.push(` ${c.gray(F_DOT)} ${formatTestPath(rootDir, key)}`);
|
||||
});
|
||||
}
|
||||
if (snapshots.unchecked) {
|
||||
if (snapshots.didUpdate) summary.push(c.bold(c.green(`${snapshots.unchecked} removed`)));
|
||||
else summary.push(c.bold(c.yellow(`${snapshots.unchecked} obsolete`)));
|
||||
snapshots.uncheckedKeysByFile.forEach((uncheckedFile) => {
|
||||
summary.push(`${c.gray(F_DOWN_RIGHT)} ${formatTestPath(rootDir, uncheckedFile.filePath)}`);
|
||||
uncheckedFile.keys.forEach((key) => summary.push(` ${c.gray(F_DOT)} ${key}`));
|
||||
});
|
||||
}
|
||||
return summary;
|
||||
}
|
||||
function countTestErrors(tasks) {
|
||||
return tasks.reduce((c, i) => c + (i.result?.errors?.length || 0), 0);
|
||||
}
|
||||
function getStateString(tasks, name = "tests", showTotal = true) {
|
||||
if (tasks.length === 0) return c.dim(`no ${name}`);
|
||||
const passed = tasks.reduce((acc, i) => {
|
||||
// Exclude expected failures from passed count
|
||||
if (i.result?.state === "pass" && i.type === "test" && i.fails) return acc;
|
||||
return i.result?.state === "pass" ? acc + 1 : acc;
|
||||
}, 0);
|
||||
const failed = tasks.reduce((acc, i) => i.result?.state === "fail" ? acc + 1 : acc, 0);
|
||||
const skipped = tasks.reduce((acc, i) => i.mode === "skip" ? acc + 1 : acc, 0);
|
||||
const todo = tasks.reduce((acc, i) => i.mode === "todo" ? acc + 1 : acc, 0);
|
||||
const expectedFail = tasks.reduce((acc, i) => {
|
||||
// Count tests that are marked as .fails and passed (which means they failed as expected)
|
||||
if (i.result?.state === "pass" && i.type === "test" && i.fails) return acc + 1;
|
||||
return acc;
|
||||
}, 0);
|
||||
return [
|
||||
failed ? c.bold(c.red(`${failed} failed`)) : null,
|
||||
passed ? c.bold(c.green(`${passed} passed`)) : null,
|
||||
expectedFail ? c.cyan(`${expectedFail} expected fail`) : null,
|
||||
skipped ? c.yellow(`${skipped} skipped`) : null,
|
||||
todo ? c.gray(`${todo} todo`) : null
|
||||
].filter(Boolean).join(c.dim(" | ")) + (showTotal ? c.gray(` (${tasks.length})`) : "");
|
||||
}
|
||||
function getStateSymbol(task) {
|
||||
if (task.mode === "todo") return todo;
|
||||
if (task.mode === "skip") return skipped;
|
||||
if (!task.result) return pending;
|
||||
if (task.result.state === "run" || task.result.state === "queued") {
|
||||
if (task.type === "suite") return pointer;
|
||||
}
|
||||
if (task.result.state === "pass") return task.meta?.benchmark ? benchmarkPass : testPass;
|
||||
if (task.result.state === "fail") return task.type === "suite" ? suiteFail : taskFail;
|
||||
return " ";
|
||||
}
|
||||
function formatTimeString(date) {
|
||||
return date.toTimeString().split(" ")[0];
|
||||
}
|
||||
function formatTime(time) {
|
||||
if (time > 1e3) return `${(time / 1e3).toFixed(2)}s`;
|
||||
return `${Math.round(time)}ms`;
|
||||
}
|
||||
function formatProjectName(project, suffix = " ") {
|
||||
if (!project?.name) return "";
|
||||
if (!c.isColorSupported) return `|${project.name}|${suffix}`;
|
||||
let background = project.color && c[`bg${capitalize(project.color)}`];
|
||||
if (!background) background = labelDefaultColors[project.name.split("").reduce((acc, v, idx) => acc + v.charCodeAt(0) + idx, 0) % labelDefaultColors.length];
|
||||
return c.black(background(` ${project.name} `)) + suffix;
|
||||
}
|
||||
function withLabel(color, label, message) {
|
||||
const bgColor = `bg${color.charAt(0).toUpperCase()}${color.slice(1)}`;
|
||||
return `${c.bold(c.black(c[bgColor](` ${label} `)))} ${message ? c[color](message) : ""}`;
|
||||
}
|
||||
function padSummaryTitle(str) {
|
||||
return c.dim(`${str.padStart(11)} `);
|
||||
}
|
||||
function truncateString(text, maxLength) {
|
||||
const plainText = stripVTControlCharacters(text);
|
||||
if (plainText.length <= maxLength) return text;
|
||||
return `${plainText.slice(0, maxLength - 1)}…`;
|
||||
}
|
||||
function capitalize(text) {
|
||||
return `${text[0].toUpperCase()}${text.slice(1)}`;
|
||||
}
|
||||
/**
|
||||
* Returns the singular or plural form of a word based on the count.
|
||||
*/
|
||||
function noun(count, singular, plural) {
|
||||
if (count === 1) return singular;
|
||||
return plural;
|
||||
}
|
||||
|
||||
var utils = /*#__PURE__*/Object.freeze({
|
||||
__proto__: null,
|
||||
benchmarkPass: benchmarkPass,
|
||||
countTestErrors: countTestErrors,
|
||||
divider: divider,
|
||||
errorBanner: errorBanner,
|
||||
formatProjectName: formatProjectName,
|
||||
formatTestPath: formatTestPath,
|
||||
formatTime: formatTime,
|
||||
formatTimeString: formatTimeString,
|
||||
getStateString: getStateString,
|
||||
getStateSymbol: getStateSymbol,
|
||||
noun: noun,
|
||||
padSummaryTitle: padSummaryTitle,
|
||||
pending: pending,
|
||||
pointer: pointer,
|
||||
renderSnapshotSummary: renderSnapshotSummary,
|
||||
separator: separator,
|
||||
skipped: skipped,
|
||||
suiteFail: suiteFail,
|
||||
taskFail: taskFail,
|
||||
testPass: testPass,
|
||||
todo: todo,
|
||||
truncateString: truncateString,
|
||||
withLabel: withLabel
|
||||
});
|
||||
|
||||
export { F_POINTER as F, taskFail as a, F_CHECK as b, F_DOWN_RIGHT as c, divider as d, errorBanner as e, formatTimeString as f, formatProjectName as g, getStateSymbol as h, getStateString as i, formatTime as j, countTestErrors as k, F_TREE_NODE_END as l, F_TREE_NODE_MIDDLE as m, noun as n, F_RIGHT as o, padSummaryTitle as p, renderSnapshotSummary as r, separator as s, truncateString as t, utils as u, withLabel as w };
|
||||
@@ -0,0 +1,8 @@
|
||||
var arrayWithoutHoles = require("./arrayWithoutHoles.js");
|
||||
var iterableToArray = require("./iterableToArray.js");
|
||||
var unsupportedIterableToArray = require("./unsupportedIterableToArray.js");
|
||||
var nonIterableSpread = require("./nonIterableSpread.js");
|
||||
function _toConsumableArray(r) {
|
||||
return arrayWithoutHoles(r) || iterableToArray(r) || unsupportedIterableToArray(r) || nonIterableSpread();
|
||||
}
|
||||
module.exports = _toConsumableArray, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "path-exists",
|
||||
"version": "4.0.0",
|
||||
"description": "Check if a path exists",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/path-exists",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava && tsd"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"keywords": [
|
||||
"path",
|
||||
"exists",
|
||||
"exist",
|
||||
"file",
|
||||
"filepath",
|
||||
"fs",
|
||||
"filesystem",
|
||||
"file-system",
|
||||
"access",
|
||||
"stat"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^1.4.1",
|
||||
"tsd": "^0.7.2",
|
||||
"xo": "^0.24.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
function FormatStackTrace(error, frames) {
|
||||
var lines = [];
|
||||
try {
|
||||
lines.push(error.toString());
|
||||
} catch (e) {
|
||||
try {
|
||||
lines.push("<error: " + e + ">");
|
||||
} catch (ee) {
|
||||
lines.push("<error>");
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < frames.length; i++) {
|
||||
var frame = frames[i];
|
||||
var line;
|
||||
try {
|
||||
line = frame.toString();
|
||||
} catch (e) {
|
||||
try {
|
||||
line = "<error: " + e + ">";
|
||||
} catch (ee) {
|
||||
// Any code that reaches this point is seriously nasty!
|
||||
line = "<error>";
|
||||
}
|
||||
}
|
||||
lines.push(" at " + line);
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
module.exports = FormatStackTrace;
|
||||
@@ -0,0 +1 @@
|
||||
export { _ as default } from "../esm/_array_without_holes.js";
|
||||
@@ -0,0 +1,87 @@
|
||||
import { FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';
|
||||
import { NumberCodecConfig } from './common';
|
||||
/**
|
||||
* Returns an encoder for 128-bit unsigned integers (`u128`).
|
||||
*
|
||||
* This encoder serializes `u128` values using sixteen bytes in little-endian format by default.
|
||||
* You may specify big-endian storage using the `endian` option.
|
||||
*
|
||||
* For more details, see {@link getU128Codec}.
|
||||
*
|
||||
* @param config - Optional settings for endianness.
|
||||
* @returns A `FixedSizeEncoder<number | bigint, 16>` for encoding `u128` values.
|
||||
*
|
||||
* @example
|
||||
* Encoding a `u128` value.
|
||||
* ```ts
|
||||
* const encoder = getU128Encoder();
|
||||
* const bytes = encoder.encode(42n); // 0x2a000000000000000000000000000000
|
||||
* ```
|
||||
*
|
||||
* @see {@link getU128Codec}
|
||||
*/
|
||||
export declare const getU128Encoder: (config?: NumberCodecConfig) => FixedSizeEncoder<bigint | number, 16>;
|
||||
/**
|
||||
* Returns a decoder for 128-bit unsigned integers (`u128`).
|
||||
*
|
||||
* This decoder deserializes `u128` values from sixteen bytes in little-endian format by default.
|
||||
* You may specify big-endian storage using the `endian` option.
|
||||
*
|
||||
* For more details, see {@link getU128Codec}.
|
||||
*
|
||||
* @param config - Optional settings for endianness.
|
||||
* @returns A `FixedSizeDecoder<bigint, 16>` for decoding `u128` values.
|
||||
*
|
||||
* @example
|
||||
* Decoding a `u128` value.
|
||||
* ```ts
|
||||
* const decoder = getU128Decoder();
|
||||
* const value = decoder.decode(new Uint8Array([0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); // 42n
|
||||
* ```
|
||||
*
|
||||
* @see {@link getU128Codec}
|
||||
*/
|
||||
export declare const getU128Decoder: (config?: NumberCodecConfig) => FixedSizeDecoder<bigint, 16>;
|
||||
/**
|
||||
* Returns a codec for encoding and decoding 128-bit unsigned integers (`u128`).
|
||||
*
|
||||
* This codec serializes `u128` values using 16 bytes.
|
||||
* Values can be provided as either `number` or `bigint`, but the decoded value is always a `bigint`.
|
||||
*
|
||||
* @param config - Optional configuration to specify endianness (little by default).
|
||||
* @returns A `FixedSizeCodec<number | bigint, bigint, 16>` for encoding and decoding `u128` values.
|
||||
*
|
||||
* @example
|
||||
* Encoding and decoding a `u128` value.
|
||||
* ```ts
|
||||
* const codec = getU128Codec();
|
||||
* const bytes = codec.encode(42); // 0x2a000000000000000000000000000000
|
||||
* const value = codec.decode(bytes); // 42n
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* Using big-endian encoding.
|
||||
* ```ts
|
||||
* const codec = getU128Codec({ endian: Endian.Big });
|
||||
* const bytes = codec.encode(42); // 0x0000000000000000000000000000002a
|
||||
* ```
|
||||
*
|
||||
* @remarks
|
||||
* This codec supports values between `0` and `2^128 - 1`.
|
||||
* Since JavaScript `number` cannot safely represent values beyond `2^53 - 1`, the decoded value is always a `bigint`.
|
||||
*
|
||||
* - If you need a smaller unsigned integer, consider using {@link getU64Codec} or {@link getU32Codec}.
|
||||
* - If you need signed integers, consider using {@link getI128Codec}.
|
||||
*
|
||||
* Separate {@link getU128Encoder} and {@link getU128Decoder} functions are available.
|
||||
*
|
||||
* ```ts
|
||||
* const bytes = getU128Encoder().encode(42);
|
||||
* const value = getU128Decoder().decode(bytes);
|
||||
* ```
|
||||
*
|
||||
* @see {@link getU128Encoder}
|
||||
* @see {@link getU128Decoder}
|
||||
*/
|
||||
export declare const getU128Codec: (config?: NumberCodecConfig) => FixedSizeCodec<bigint | number, bigint, 16>;
|
||||
//# sourceMappingURL=u128.d.ts.map
|
||||
@@ -0,0 +1,64 @@
|
||||
'use strict';
|
||||
|
||||
/* eslint no-proto: 0 */
|
||||
|
||||
var parse = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
test('proto pollution', function (t) {
|
||||
var argv = parse(['--__proto__.x', '123']);
|
||||
t.equal({}.x, undefined);
|
||||
t.equal(argv.__proto__.x, undefined);
|
||||
t.equal(argv.x, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (array)', function (t) {
|
||||
var argv = parse(['--x', '4', '--x', '5', '--x.__proto__.z', '789']);
|
||||
t.equal({}.z, undefined);
|
||||
t.deepEqual(argv.x, [4, 5]);
|
||||
t.equal(argv.x.z, undefined);
|
||||
t.equal(argv.x.__proto__.z, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (number)', function (t) {
|
||||
var argv = parse(['--x', '5', '--x.__proto__.z', '100']);
|
||||
t.equal({}.z, undefined);
|
||||
t.equal((4).z, undefined);
|
||||
t.equal(argv.x, 5);
|
||||
t.equal(argv.x.z, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (string)', function (t) {
|
||||
var argv = parse(['--x', 'abc', '--x.__proto__.z', 'def']);
|
||||
t.equal({}.z, undefined);
|
||||
t.equal('...'.z, undefined);
|
||||
t.equal(argv.x, 'abc');
|
||||
t.equal(argv.x.z, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (constructor)', function (t) {
|
||||
var argv = parse(['--constructor.prototype.y', '123']);
|
||||
t.equal({}.y, undefined);
|
||||
t.equal(argv.y, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('proto pollution (constructor function)', function (t) {
|
||||
var argv = parse(['--_.concat.constructor.prototype.y', '123']);
|
||||
function fnToBeTested() {}
|
||||
t.equal(fnToBeTested.y, undefined);
|
||||
t.equal(argv.y, undefined);
|
||||
t.end();
|
||||
});
|
||||
|
||||
// powered by snyk - https://github.com/backstage/backstage/issues/10343
|
||||
test('proto pollution (constructor function) snyk', function (t) {
|
||||
var argv = parse('--_.constructor.constructor.prototype.foo bar'.split(' '));
|
||||
t.equal(function () {}.foo, undefined);
|
||||
t.equal(argv.y, undefined);
|
||||
t.end();
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { Stringifier } from './postcss.js'
|
||||
|
||||
interface Stringify extends Stringifier {
|
||||
default: Stringify
|
||||
}
|
||||
|
||||
declare let stringify: Stringify
|
||||
|
||||
export = stringify
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Internal webcrypto alias.
|
||||
* We prefer WebCrypto aka globalThis.crypto, which exists in node.js 16+.
|
||||
* Falls back to Node.js built-in crypto for Node.js <=v14.
|
||||
* See utils.ts for details.
|
||||
* @module
|
||||
*/
|
||||
// @ts-ignore
|
||||
import * as nc from 'node:crypto';
|
||||
export const crypto: any =
|
||||
nc && typeof nc === 'object' && 'webcrypto' in nc
|
||||
? (nc.webcrypto as any)
|
||||
: nc && typeof nc === 'object' && 'randomBytes' in nc
|
||||
? nc
|
||||
: undefined;
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { TSESLint } from '@typescript-eslint/utils';
|
||||
type AccessibilityLevel = 'explicit' | 'no-public' | 'off';
|
||||
export interface Config {
|
||||
accessibility?: AccessibilityLevel;
|
||||
ignoredMethodNames?: string[];
|
||||
overrides?: {
|
||||
accessors?: AccessibilityLevel;
|
||||
constructors?: AccessibilityLevel;
|
||||
methods?: AccessibilityLevel;
|
||||
parameterProperties?: AccessibilityLevel;
|
||||
properties?: AccessibilityLevel;
|
||||
};
|
||||
}
|
||||
export type Options = [Config];
|
||||
export type MessageIds = 'addExplicitAccessibility' | 'missingAccessibility' | 'unwantedPublicAccessibility';
|
||||
declare const _default: TSESLint.RuleModule<MessageIds, Options, import("../../rules").ESLintPluginDocs, TSESLint.RuleListener> & {
|
||||
name: string;
|
||||
};
|
||||
export default _default;
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "../../cjs/_instanceof.cjs",
|
||||
"module": "../../esm/_instanceof.js"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { NodeSnapshotEnvironment } from '@vitest/snapshot/environment';
|
||||
import { g as getWorkerState } from './utils.BX5Fg8C4.js';
|
||||
import '@vitest/utils/timers';
|
||||
|
||||
class VitestNodeSnapshotEnvironment extends NodeSnapshotEnvironment {
|
||||
getHeader() {
|
||||
return `// Vitest Snapshot v${this.getVersion()}, https://vitest.dev/guide/snapshot.html`;
|
||||
}
|
||||
resolvePath(filepath) {
|
||||
return getWorkerState().rpc.resolveSnapshotPath(filepath);
|
||||
}
|
||||
}
|
||||
|
||||
export { VitestNodeSnapshotEnvironment };
|
||||
@@ -0,0 +1,4 @@
|
||||
scripts/
|
||||
test/
|
||||
|
||||
!lib/mapping_table.json
|
||||
@@ -0,0 +1,125 @@
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("record should parse objects with non-function constructor field", () => {
|
||||
const schema = z.record(z.string(), z.any());
|
||||
|
||||
expect(() => schema.parse({ constructor: "string", key: "value" })).not.toThrow();
|
||||
|
||||
const result1 = schema.parse({ constructor: "string", key: "value" });
|
||||
expect(result1).toEqual({ constructor: "string", key: "value" });
|
||||
|
||||
expect(() => schema.parse({ constructor: 123, key: "value" })).not.toThrow();
|
||||
|
||||
const result2 = schema.parse({ constructor: 123, key: "value" });
|
||||
expect(result2).toEqual({ constructor: 123, key: "value" });
|
||||
|
||||
expect(() => schema.parse({ constructor: null, key: "value" })).not.toThrow();
|
||||
|
||||
const result3 = schema.parse({ constructor: null, key: "value" });
|
||||
expect(result3).toEqual({ constructor: null, key: "value" });
|
||||
|
||||
expect(() => schema.parse({ constructor: {}, key: "value" })).not.toThrow();
|
||||
|
||||
const result4 = schema.parse({ constructor: {}, key: "value" });
|
||||
expect(result4).toEqual({ constructor: {}, key: "value" });
|
||||
|
||||
expect(() => schema.parse({ constructor: [], key: "value" })).not.toThrow();
|
||||
|
||||
const result5 = schema.parse({ constructor: [], key: "value" });
|
||||
expect(result5).toEqual({ constructor: [], key: "value" });
|
||||
|
||||
expect(() => schema.parse({ constructor: true, key: "value" })).not.toThrow();
|
||||
|
||||
const result6 = schema.parse({ constructor: true, key: "value" });
|
||||
expect(result6).toEqual({ constructor: true, key: "value" });
|
||||
});
|
||||
|
||||
test("record should still work with normal objects", () => {
|
||||
const schema = z.record(z.string(), z.string());
|
||||
|
||||
expect(() => schema.parse({ normalKey: "value" })).not.toThrow();
|
||||
|
||||
const result1 = schema.parse({ normalKey: "value" });
|
||||
expect(result1).toEqual({ normalKey: "value" });
|
||||
|
||||
expect(() => schema.parse({ key1: "value1", key2: "value2" })).not.toThrow();
|
||||
|
||||
const result2 = schema.parse({ key1: "value1", key2: "value2" });
|
||||
expect(result2).toEqual({ key1: "value1", key2: "value2" });
|
||||
});
|
||||
|
||||
test("record should validate values according to schema even with constructor field", () => {
|
||||
const stringSchema = z.record(z.string(), z.string());
|
||||
|
||||
expect(() => stringSchema.parse({ constructor: "string", key: "value" })).not.toThrow();
|
||||
|
||||
expect(() => stringSchema.parse({ constructor: 123, key: "value" })).toThrow();
|
||||
});
|
||||
|
||||
test("record should work with different key types and constructor field", () => {
|
||||
const enumSchema = z.record(z.enum(["constructor", "key"]), z.string());
|
||||
|
||||
expect(() => enumSchema.parse({ constructor: "value1", key: "value2" })).not.toThrow();
|
||||
|
||||
const result = enumSchema.parse({ constructor: "value1", key: "value2" });
|
||||
expect(result).toEqual({ constructor: "value1", key: "value2" });
|
||||
});
|
||||
|
||||
test("record should skip non-enumerable own properties", () => {
|
||||
const schema = z.record(z.string(), z.string());
|
||||
|
||||
const input = { key: "value" };
|
||||
Object.defineProperty(input, "~standard", {
|
||||
value: { validate: () => {}, vendor: "zod", version: 1 },
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: false,
|
||||
});
|
||||
|
||||
const result = schema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data).toEqual({ key: "value" });
|
||||
expect("~standard" in result.data).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
test("record fails on enumerable invalid values even when non-enumerable properties are present", () => {
|
||||
const schema = z.record(z.string(), z.string());
|
||||
|
||||
const input = { key: "value", bad: 123 };
|
||||
Object.defineProperty(input, "hidden", {
|
||||
value: "should be ignored",
|
||||
enumerable: false,
|
||||
});
|
||||
|
||||
const result = schema.safeParse(input);
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
test("record validates enumerable Symbol keys and skips non-enumerable Symbol keys", () => {
|
||||
const enumerableSym = Symbol.for("included");
|
||||
const nonEnumerableSym = Symbol.for("hidden");
|
||||
const schema = z.record(z.symbol(), z.string());
|
||||
|
||||
const input: Record<symbol, unknown> = { [enumerableSym]: "value" };
|
||||
Object.defineProperty(input, nonEnumerableSym, {
|
||||
value: 123,
|
||||
enumerable: false,
|
||||
});
|
||||
|
||||
const result = schema.safeParse(input);
|
||||
expect(result.success).toBe(true);
|
||||
if (result.success) {
|
||||
expect(result.data[enumerableSym]).toBe("value");
|
||||
expect(Object.prototype.hasOwnProperty.call(result.data, nonEnumerableSym)).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
test("z.json() accepts z.toJSONSchema() output (issue #5714)", () => {
|
||||
const schema = z.object({ name: z.string() });
|
||||
const jsonSchema = z.toJSONSchema(schema);
|
||||
|
||||
expect(z.json().safeParse(jsonSchema).success).toBe(true);
|
||||
});
|
||||
Reference in New Issue
Block a user