WIP: bootstrap and partial real Solana watcher implementation

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

View File

@@ -0,0 +1,922 @@
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABILITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
interface Array<T> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S | undefined;
findLast(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): number;
/**
* Returns a copy of an array with its elements reversed.
*/
toReversed(): T[];
/**
* Returns a copy of an array with its elements sorted.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending, UTF-16 code unit order.
* ```ts
* [11, 2, 22, 1].toSorted((a, b) => a - b) // [1, 2, 11, 22]
* ```
*/
toSorted(compareFn?: (a: T, b: T) => number): T[];
/**
* Copies an array and removes elements and, if necessary, inserts new elements in their place. Returns the copied array.
* @param start The zero-based location in the array from which to start removing elements.
* @param deleteCount The number of elements to remove.
* @param items Elements to insert into the copied array in place of the deleted elements.
* @returns The copied array.
*/
toSpliced(start: number, deleteCount: number, ...items: T[]): T[];
/**
* Copies an array and removes elements while returning the remaining elements.
* @param start The zero-based location in the array from which to start removing elements.
* @param deleteCount The number of elements to remove.
* @returns A copy of the original array with the remaining elements.
*/
toSpliced(start: number, deleteCount?: number): T[];
/**
* Copies an array, then overwrites the value at the provided index with the
* given value. If the index is negative, then it replaces from the end
* of the array.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to write into the copied array.
* @returns The copied array with the updated value.
*/
with(index: number, value: T): T[];
}
interface ReadonlyArray<T> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends T>(
predicate: (value: T, index: number, array: readonly T[]) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (value: T, index: number, array: readonly T[]) => unknown,
thisArg?: any,
): T | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (value: T, index: number, array: readonly T[]) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copied array with all of its elements reversed.
*/
toReversed(): T[];
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending, UTF-16 code unit order.
* ```ts
* [11, 2, 22, 1].toSorted((a, b) => a - b) // [1, 2, 11, 22]
* ```
*/
toSorted(compareFn?: (a: T, b: T) => number): T[];
/**
* Copies an array and removes elements while, if necessary, inserting new elements in their place, returning the remaining elements.
* @param start The zero-based location in the array from which to start removing elements.
* @param deleteCount The number of elements to remove.
* @param items Elements to insert into the copied array in place of the deleted elements.
* @returns A copy of the original array with the remaining elements.
*/
toSpliced(start: number, deleteCount: number, ...items: T[]): T[];
/**
* Copies an array and removes elements while returning the remaining elements.
* @param start The zero-based location in the array from which to start removing elements.
* @param deleteCount The number of elements to remove.
* @returns A copy of the original array with the remaining elements.
*/
toSpliced(start: number, deleteCount?: number): T[];
/**
* Copies an array, then overwrites the value at the provided index with the
* given value. If the index is negative, then it replaces from the end
* of the array
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: T): T[];
}
interface Int8Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends number>(
predicate: (
value: number,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (value: number, index: number, array: this) => unknown,
thisArg?: any,
): number | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (value: number, index: number, array: this) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): Int8Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = Int8Array.from([11, 2, 22, 1]);
* myNums.toSorted((a, b) => a - b) // Int8Array(4) [1, 2, 11, 22]
* ```
*/
toSorted(compareFn?: (a: number, b: number) => number): Int8Array<ArrayBuffer>;
/**
* Copies the array and inserts the given number at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: number): Int8Array<ArrayBuffer>;
}
interface Uint8Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends number>(
predicate: (
value: number,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (value: number, index: number, array: this) => unknown,
thisArg?: any,
): number | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (value: number, index: number, array: this) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): Uint8Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = Uint8Array.from([11, 2, 22, 1]);
* myNums.toSorted((a, b) => a - b) // Uint8Array(4) [1, 2, 11, 22]
* ```
*/
toSorted(compareFn?: (a: number, b: number) => number): Uint8Array<ArrayBuffer>;
/**
* Copies the array and inserts the given number at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: number): Uint8Array<ArrayBuffer>;
}
interface Uint8ClampedArray<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends number>(
predicate: (
value: number,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): Uint8ClampedArray<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = Uint8ClampedArray.from([11, 2, 22, 1]);
* myNums.toSorted((a, b) => a - b) // Uint8ClampedArray(4) [1, 2, 11, 22]
* ```
*/
toSorted(compareFn?: (a: number, b: number) => number): Uint8ClampedArray<ArrayBuffer>;
/**
* Copies the array and inserts the given number at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: number): Uint8ClampedArray<ArrayBuffer>;
}
interface Int16Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends number>(
predicate: (
value: number,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (value: number, index: number, array: this) => unknown,
thisArg?: any,
): number | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (value: number, index: number, array: this) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): Int16Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = Int16Array.from([11, 2, -22, 1]);
* myNums.toSorted((a, b) => a - b) // Int16Array(4) [-22, 1, 2, 11]
* ```
*/
toSorted(compareFn?: (a: number, b: number) => number): Int16Array<ArrayBuffer>;
/**
* Copies the array and inserts the given number at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: number): Int16Array<ArrayBuffer>;
}
interface Uint16Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends number>(
predicate: (
value: number,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): Uint16Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = Uint16Array.from([11, 2, 22, 1]);
* myNums.toSorted((a, b) => a - b) // Uint16Array(4) [1, 2, 11, 22]
* ```
*/
toSorted(compareFn?: (a: number, b: number) => number): Uint16Array<ArrayBuffer>;
/**
* Copies the array and inserts the given number at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: number): Uint16Array<ArrayBuffer>;
}
interface Int32Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends number>(
predicate: (
value: number,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (value: number, index: number, array: this) => unknown,
thisArg?: any,
): number | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (value: number, index: number, array: this) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): Int32Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = Int32Array.from([11, 2, -22, 1]);
* myNums.toSorted((a, b) => a - b) // Int32Array(4) [-22, 1, 2, 11]
* ```
*/
toSorted(compareFn?: (a: number, b: number) => number): Int32Array<ArrayBuffer>;
/**
* Copies the array and inserts the given number at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: number): Int32Array<ArrayBuffer>;
}
interface Uint32Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends number>(
predicate: (
value: number,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): Uint32Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = Uint32Array.from([11, 2, 22, 1]);
* myNums.toSorted((a, b) => a - b) // Uint32Array(4) [1, 2, 11, 22]
* ```
*/
toSorted(compareFn?: (a: number, b: number) => number): Uint32Array<ArrayBuffer>;
/**
* Copies the array and inserts the given number at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: number): Uint32Array<ArrayBuffer>;
}
interface Float32Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends number>(
predicate: (
value: number,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): Float32Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = Float32Array.from([11.25, 2, -22.5, 1]);
* myNums.toSorted((a, b) => a - b) // Float32Array(4) [-22.5, 1, 2, 11.5]
* ```
*/
toSorted(compareFn?: (a: number, b: number) => number): Float32Array<ArrayBuffer>;
/**
* Copies the array and inserts the given number at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: number): Float32Array<ArrayBuffer>;
}
interface Float64Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends number>(
predicate: (
value: number,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (
value: number,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): Float64Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = Float64Array.from([11.25, 2, -22.5, 1]);
* myNums.toSorted((a, b) => a - b) // Float64Array(4) [-22.5, 1, 2, 11.5]
* ```
*/
toSorted(compareFn?: (a: number, b: number) => number): Float64Array<ArrayBuffer>;
/**
* Copies the array and inserts the given number at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: number): Float64Array<ArrayBuffer>;
}
interface BigInt64Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends bigint>(
predicate: (
value: bigint,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (
value: bigint,
index: number,
array: this,
) => unknown,
thisArg?: any,
): bigint | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (
value: bigint,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): BigInt64Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = BigInt64Array.from([11n, 2n, -22n, 1n]);
* myNums.toSorted((a, b) => Number(a - b)) // BigInt64Array(4) [-22n, 1n, 2n, 11n]
* ```
*/
toSorted(compareFn?: (a: bigint, b: bigint) => number): BigInt64Array<ArrayBuffer>;
/**
* Copies the array and inserts the given bigint at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: bigint): BigInt64Array<ArrayBuffer>;
}
interface BigUint64Array<TArrayBuffer extends ArrayBufferLike> {
/**
* Returns the value of the last element in the array where predicate is true, and undefined
* otherwise.
* @param predicate findLast calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found, findLast
* immediately returns that element value. Otherwise, findLast returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLast<S extends bigint>(
predicate: (
value: bigint,
index: number,
array: this,
) => value is S,
thisArg?: any,
): S | undefined;
findLast(
predicate: (
value: bigint,
index: number,
array: this,
) => unknown,
thisArg?: any,
): bigint | undefined;
/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param predicate findLastIndex calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
findLastIndex(
predicate: (
value: bigint,
index: number,
array: this,
) => unknown,
thisArg?: any,
): number;
/**
* Copies the array and returns the copy with the elements in reverse order.
*/
toReversed(): BigUint64Array<ArrayBuffer>;
/**
* Copies and sorts the array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending order.
* ```ts
* const myNums = BigUint64Array.from([11n, 2n, 22n, 1n]);
* myNums.toSorted((a, b) => Number(a - b)) // BigUint64Array(4) [1n, 2n, 11n, 22n]
* ```
*/
toSorted(compareFn?: (a: bigint, b: bigint) => number): BigUint64Array<ArrayBuffer>;
/**
* Copies the array and inserts the given bigint at the provided index.
* @param index The index of the value to overwrite. If the index is
* negative, then it replaces from the end of the array.
* @param value The value to insert into the copied array.
* @returns A copy of the original array with the inserted value.
*/
with(index: number, value: bigint): BigUint64Array<ArrayBuffer>;
}

View File

@@ -0,0 +1,105 @@
import { expect, test } from "vitest";
import * as z from "zod/v4";
test("locales - uz", () => {
z.config(z.locales.uz());
const invalidType = z.number().safeParse("a");
expect(invalidType.error!.issues[0].code).toBe("invalid_type");
expect(invalidType.error!.issues[0].message).toBe("Notogri kirish: kutilgan raqam, qabul qilingan string");
const invalidType2 = z.string().safeParse(1);
expect(invalidType2.error!.issues[0].code).toBe("invalid_type");
expect(invalidType2.error!.issues[0].message).toBe("Notogri kirish: kutilgan string, qabul qilingan raqam");
const invalidValue = z.enum(["a", "b"]).safeParse(1);
expect(invalidValue.error!.issues[0].code).toBe("invalid_value");
expect(invalidValue.error!.issues[0].message).toBe('Notogri variant: quyidagilardan biri kutilgan "a"|"b"');
const tooBig = z.number().max(10).safeParse(15);
expect(tooBig.error!.issues[0].code).toBe("too_big");
expect(tooBig.error!.issues[0].message).toBe("Juda katta: kutilgan number <=10");
const tooSmall = z.number().min(10).safeParse(5);
expect(tooSmall.error!.issues[0].code).toBe("too_small");
expect(tooSmall.error!.issues[0].message).toBe("Juda kichik: kutilgan number >=10");
const invalidFormatRegex = z.string().regex(/abcd/).safeParse("invalid-string");
expect(invalidFormatRegex.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatRegex.error!.issues[0].message).toContain("shabloniga mos kelishi kerak");
const invalidFormatStartsWith = z.string().startsWith("abcd").safeParse("invalid-string");
expect(invalidFormatStartsWith.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatStartsWith.error!.issues[0].message).toContain('"abcd" bilan boshlanishi kerak');
const notMultipleOf = z.number().multipleOf(3).safeParse(10);
expect(notMultipleOf.error!.issues[0].code).toBe("not_multiple_of");
expect(notMultipleOf.error!.issues[0].message).toContain("3 ning karralisi bolishi kerak");
const unrecognizedKeys = z.object({ a: z.string(), b: z.number() }).strict().safeParse({ a: "a", b: 1, c: 2 });
expect(unrecognizedKeys.error!.issues[0].code).toBe("unrecognized_keys");
expect(unrecognizedKeys.error!.issues[0].message).toContain('Nomalum kalit: "c"');
const invalidUnion = z.union([z.string(), z.number()]).safeParse(true);
expect(invalidUnion.error!.issues[0].code).toBe("invalid_union");
expect(invalidUnion.error!.issues[0].message).toBe("Notogri kirish");
const tooBigString = z.string().max(5).safeParse("too long string");
expect(tooBigString.error!.issues[0].code).toBe("too_big");
expect(tooBigString.error!.issues[0].message).toContain("belgi");
expect(tooBigString.error!.issues[0].message).toContain("bolishi kerak");
const tooSmallArray = z.array(z.string()).min(3).safeParse(["a", "b"]);
expect(tooSmallArray.error!.issues[0].code).toBe("too_small");
expect(tooSmallArray.error!.issues[0].message).toContain("element");
expect(tooSmallArray.error!.issues[0].message).toContain("bolishi kerak");
const invalidFormatEndsWith = z.string().endsWith("xyz").safeParse("invalid-string");
expect(invalidFormatEndsWith.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatEndsWith.error!.issues[0].message).toContain('"xyz" bilan tugashi kerak');
const invalidFormatIncludes = z.string().includes("test").safeParse("invalid-string");
expect(invalidFormatIncludes.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatIncludes.error!.issues[0].message).toContain('"test" ni oz ichiga olishi kerak');
const invalidFormatEmail = z.string().email().safeParse("invalid-email");
expect(invalidFormatEmail.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatEmail.error!.issues[0].message).toContain("elektron pochta manzili");
const invalidFormatUrl = z.string().url().safeParse("invalid-url");
expect(invalidFormatUrl.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatUrl.error!.issues[0].message).toContain("URL");
const unrecognizedKeysMultiple = z
.object({ a: z.string(), b: z.number() })
.strict()
.safeParse({ a: "a", b: 1, c: 2, d: 3 });
expect(unrecognizedKeysMultiple.error!.issues[0].code).toBe("unrecognized_keys");
expect(unrecognizedKeysMultiple.error!.issues[0].message).toContain("Nomalum kalitlar");
const invalidElement = z.array(z.string()).safeParse([1, 2, 3]);
expect(invalidElement.error!.issues[0].code).toBe("invalid_type");
expect(invalidElement.error!.issues[0].message).toContain("raqam");
const tooSmallMap = z
.map(z.string(), z.string())
.min(3)
.safeParse(new Map([["a", "b"]]));
expect(tooSmallMap.error!.issues[0].code).toBe("too_small");
expect(tooSmallMap.error!.issues[0].message).toContain("yozuv");
expect(tooSmallMap.error!.issues[0].message).toContain("bolishi kerak");
const tooBigMap = z
.map(z.string(), z.string())
.max(2)
.safeParse(
new Map([
["a", "b"],
["c", "d"],
["e", "f"],
])
);
expect(tooBigMap.error!.issues[0].code).toBe("too_big");
expect(tooBigMap.error!.issues[0].message).toContain("yozuv");
expect(tooBigMap.error!.issues[0].message).toContain("bolishi kerak");
});

View File

@@ -0,0 +1,9 @@
"use strict";
var _check_private_redeclaration = require("./_check_private_redeclaration.cjs");
function _class_private_field_init(obj, privateMap, value) {
_check_private_redeclaration._(obj, privateMap);
privateMap.set(obj, value);
}
exports._ = _class_private_field_init;

View File

@@ -0,0 +1,31 @@
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) resolve(value);
else Promise.resolve(value).then(_next, _throw);
}
function _async_to_generator(fn) {
return function() {
var self = this, args = arguments;
return new Promise(function(resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
export { _async_to_generator as _ };

View File

@@ -0,0 +1,252 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createParseSettings = createParseSettings;
exports.clearTSConfigMatchCache = clearTSConfigMatchCache;
exports.clearTSServerProjectService = clearTSServerProjectService;
const project_service_1 = require("@typescript-eslint/project-service");
const debug_1 = __importDefault(require("debug"));
const node_path_1 = __importDefault(require("node:path"));
const ts = __importStar(require("typescript"));
const shared_1 = require("../create-program/shared");
const validateDefaultProjectForFilesGlob_1 = require("../create-program/validateDefaultProjectForFilesGlob");
const source_files_1 = require("../source-files");
const candidateTSConfigRootDirs_1 = require("./candidateTSConfigRootDirs");
const ExpiringCache_1 = require("./ExpiringCache");
const getProjectConfigFiles_1 = require("./getProjectConfigFiles");
const inferSingleRun_1 = require("./inferSingleRun");
const resolveProjectList_1 = require("./resolveProjectList");
const warnAboutTSVersion_1 = require("./warnAboutTSVersion");
const log = (0, debug_1.default)('typescript-eslint:typescript-estree:parseSettings:createParseSettings');
let TSCONFIG_MATCH_CACHE;
let TSSERVER_PROJECT_SERVICE = null;
// NOTE - we intentionally use "unnecessary" `?.` here because in TS<5.3 this enum doesn't exist
// This object exists so we can centralize these for tracking and so we don't proliferate these across the file
// https://github.com/microsoft/TypeScript/issues/56579
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
const JSDocParsingMode = {
ParseAll: ts.JSDocParsingMode?.ParseAll,
ParseForTypeErrors: ts.JSDocParsingMode?.ParseForTypeErrors,
ParseForTypeInfo: ts.JSDocParsingMode?.ParseForTypeInfo,
ParseNone: ts.JSDocParsingMode?.ParseNone,
};
/* eslint-enable @typescript-eslint/no-unnecessary-condition */
function createParseSettings(code, tsestreeOptions = {}) {
const codeFullText = enforceCodeString(code);
const singleRun = (0, inferSingleRun_1.inferSingleRun)(tsestreeOptions);
const tsconfigRootDir = (() => {
if (tsestreeOptions.tsconfigRootDir == null) {
const inferredTsconfigRootDir = (0, candidateTSConfigRootDirs_1.getInferredTSConfigRootDir)();
if (node_path_1.default.resolve(inferredTsconfigRootDir) !== inferredTsconfigRootDir) {
throw new Error(`inferred tsconfigRootDir should be a resolved absolute path, but received: ${JSON.stringify(inferredTsconfigRootDir)}. This is a bug in typescript-eslint! Please report it to us at https://github.com/typescript-eslint/typescript-eslint/issues/new/choose.`);
}
return inferredTsconfigRootDir;
}
if (typeof tsestreeOptions.tsconfigRootDir === 'string') {
const userProvidedTsconfigRootDir = tsestreeOptions.tsconfigRootDir;
if (!node_path_1.default.isAbsolute(userProvidedTsconfigRootDir) ||
// Ensure it's fully absolute with a drive letter if windows
(process.platform === 'win32' &&
!/^[a-zA-Z]:/.test(userProvidedTsconfigRootDir))) {
throw new Error(`parserOptions.tsconfigRootDir must be an absolute path, but received: ${JSON.stringify(userProvidedTsconfigRootDir)}. This is a bug in your configuration; please supply an absolute path.`);
}
// Deal with any funny business around trailing path separators (a/b/) or relative path segments (/a/b/../c)
// Since we already know it's absolute, we can safely use path.resolve here.
return node_path_1.default.resolve(userProvidedTsconfigRootDir);
}
throw new Error(`If provided, parserOptions.tsconfigRootDir must be a string, but received a value of type "${typeof tsestreeOptions.tsconfigRootDir}"`);
})();
const passedLoggerFn = typeof tsestreeOptions.loggerFn === 'function';
const filePath = (0, shared_1.ensureAbsolutePath)(typeof tsestreeOptions.filePath === 'string' &&
tsestreeOptions.filePath !== '<input>'
? tsestreeOptions.filePath
: getFileName(tsestreeOptions.jsx), tsconfigRootDir);
const extension = node_path_1.default.extname(filePath).toLowerCase();
const jsDocParsingMode = (() => {
switch (tsestreeOptions.jsDocParsingMode) {
case 'all':
return JSDocParsingMode.ParseAll;
case 'none':
return JSDocParsingMode.ParseNone;
case 'type-info':
return JSDocParsingMode.ParseForTypeInfo;
default:
return JSDocParsingMode.ParseAll;
}
})();
const parseSettings = {
loc: tsestreeOptions.loc === true,
range: tsestreeOptions.range === true,
allowInvalidAST: tsestreeOptions.allowInvalidAST === true,
code,
codeFullText,
comment: tsestreeOptions.comment === true,
comments: [],
debugLevel: tsestreeOptions.debugLevel === true
? new Set(['typescript-eslint'])
: Array.isArray(tsestreeOptions.debugLevel)
? new Set(tsestreeOptions.debugLevel)
: new Set(),
errorOnTypeScriptSyntacticAndSemanticIssues: false,
errorOnUnknownASTType: tsestreeOptions.errorOnUnknownASTType === true,
extraFileExtensions: Array.isArray(tsestreeOptions.extraFileExtensions) &&
tsestreeOptions.extraFileExtensions.every(ext => typeof ext === 'string')
? tsestreeOptions.extraFileExtensions
: [],
filePath,
jsDocParsingMode,
jsx: tsestreeOptions.jsx === true,
log: typeof tsestreeOptions.loggerFn === 'function'
? tsestreeOptions.loggerFn
: tsestreeOptions.loggerFn === false
? () => { } // eslint-disable-line @typescript-eslint/no-empty-function
: console.log, // eslint-disable-line no-console
preserveNodeMaps: tsestreeOptions.preserveNodeMaps !== false,
programs: Array.isArray(tsestreeOptions.programs)
? tsestreeOptions.programs
: null,
projects: new Map(),
projectService: tsestreeOptions.projectService ||
(tsestreeOptions.project &&
tsestreeOptions.projectService !== false &&
process.env.TYPESCRIPT_ESLINT_PROJECT_SERVICE === 'true')
? populateProjectService(tsestreeOptions.projectService, {
jsDocParsingMode,
tsconfigRootDir,
})
: undefined,
setExternalModuleIndicator: tsestreeOptions.sourceType === 'module' ||
(tsestreeOptions.sourceType == null && extension === ts.Extension.Mjs) ||
(tsestreeOptions.sourceType == null && extension === ts.Extension.Mts)
? (file) => {
file.externalModuleIndicator = true;
}
: undefined,
singleRun,
suppressDeprecatedPropertyWarnings: tsestreeOptions.suppressDeprecatedPropertyWarnings ??
process.env.NODE_ENV !== 'test',
tokens: tsestreeOptions.tokens === true ? [] : null,
tsconfigMatchCache: (TSCONFIG_MATCH_CACHE ??= new ExpiringCache_1.ExpiringCache(singleRun
? 'Infinity'
: (tsestreeOptions.cacheLifetime?.glob ??
ExpiringCache_1.DEFAULT_TSCONFIG_CACHE_DURATION_SECONDS))),
tsconfigRootDir,
};
// TODO: Eventually, parse settings will be validated more thoroughly.
// https://github.com/typescript-eslint/typescript-eslint/issues/6403
if (parseSettings.projectService &&
tsestreeOptions.project &&
process.env.TYPESCRIPT_ESLINT_IGNORE_PROJECT_AND_PROJECT_SERVICE_ERROR !==
'true') {
throw new Error('Enabling "project" does nothing when "projectService" is enabled. You can remove the "project" setting.');
}
// debug doesn't support multiple `enable` calls, so have to do it all at once
if (parseSettings.debugLevel.size > 0) {
const namespaces = [];
if (parseSettings.debugLevel.has('typescript-eslint')) {
namespaces.push('typescript-eslint:*');
}
if (parseSettings.debugLevel.has('eslint') ||
// make sure we don't turn off the eslint debug if it was enabled via --debug
debug_1.default.enabled('eslint:*,-eslint:code-path')) {
// https://github.com/eslint/eslint/blob/9dfc8501fb1956c90dc11e6377b4cb38a6bea65d/bin/eslint.js#L25
namespaces.push('eslint:*,-eslint:code-path');
}
debug_1.default.enable(namespaces.join(','));
}
if (Array.isArray(tsestreeOptions.programs)) {
if (!tsestreeOptions.programs.length) {
throw new Error(`You have set parserOptions.programs to an empty array. This will cause all files to not be found in existing programs. Either provide one or more existing TypeScript Program instances in the array, or remove the parserOptions.programs setting.`);
}
log('parserOptions.programs was provided, so parserOptions.project will be ignored.');
}
// Providing a program or project service overrides project resolution
if (!parseSettings.programs && !parseSettings.projectService) {
parseSettings.projects = (0, resolveProjectList_1.resolveProjectList)({
cacheLifetime: tsestreeOptions.cacheLifetime,
project: (0, getProjectConfigFiles_1.getProjectConfigFiles)(parseSettings, tsestreeOptions.project),
projectFolderIgnoreList: tsestreeOptions.projectFolderIgnoreList,
singleRun: parseSettings.singleRun,
tsconfigRootDir,
});
}
// No type-aware linting which means that cross-file (or even same-file) JSDoc is useless
// So in this specific case we default to 'none' if no value was provided
if (tsestreeOptions.jsDocParsingMode == null &&
parseSettings.projects.size === 0 &&
parseSettings.programs == null &&
parseSettings.projectService == null) {
parseSettings.jsDocParsingMode = JSDocParsingMode.ParseNone;
}
(0, warnAboutTSVersion_1.handleUnsupportedTSVersion)(parseSettings, tsestreeOptions.onUnsupportedTypeScriptVersion ?? 'warn', passedLoggerFn);
return parseSettings;
}
function clearTSConfigMatchCache() {
TSCONFIG_MATCH_CACHE?.clear();
}
function clearTSServerProjectService() {
TSSERVER_PROJECT_SERVICE = null;
}
/**
* Ensures source code is a string.
*/
function enforceCodeString(code) {
return (0, source_files_1.isSourceFile)(code)
? code.getFullText(code)
: typeof code === 'string'
? code
: String(code);
}
/**
* Compute the filename based on the parser options.
*
* Even if jsx option is set in typescript compiler, filename still has to
* contain .tsx file extension.
*/
function getFileName(jsx) {
return jsx ? 'estree.tsx' : 'estree.ts';
}
function populateProjectService(optionsRaw, settings) {
const options = typeof optionsRaw === 'object' ? optionsRaw : {};
(0, validateDefaultProjectForFilesGlob_1.validateDefaultProjectForFilesGlob)(options.allowDefaultProject);
TSSERVER_PROJECT_SERVICE ??= (0, project_service_1.createProjectService)({
options,
...settings,
});
return TSSERVER_PROJECT_SERVICE;
}

View File

@@ -0,0 +1,7 @@
import { URISchemeHandler, URIOptions } from "../uri";
import { URNComponents } from "./urn";
export interface UUIDComponents extends URNComponents {
uuid?: string;
}
declare const handler: URISchemeHandler<UUIDComponents, URIOptions, URNComponents>;
export default handler;

View File

@@ -0,0 +1,9 @@
export {};
import * as console from "node:console";
declare global {
interface Console extends console.Console {}
var console: Console;
}

View File

@@ -0,0 +1,74 @@
"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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZodRealError = exports.ZodError = void 0;
const core = __importStar(require("../core/index.cjs"));
const index_js_1 = require("../core/index.cjs");
const util = __importStar(require("../core/util.cjs"));
const initializer = (inst, issues) => {
index_js_1.$ZodError.init(inst, issues);
inst.name = "ZodError";
Object.defineProperties(inst, {
format: {
value: (mapper) => core.formatError(inst, mapper),
// enumerable: false,
},
flatten: {
value: (mapper) => core.flattenError(inst, mapper),
// enumerable: false,
},
addIssue: {
value: (issue) => {
inst.issues.push(issue);
inst.message = JSON.stringify(inst.issues, util.jsonStringifyReplacer, 2);
},
// enumerable: false,
},
addIssues: {
value: (issues) => {
inst.issues.push(...issues);
inst.message = JSON.stringify(inst.issues, util.jsonStringifyReplacer, 2);
},
// enumerable: false,
},
isEmpty: {
get() {
return inst.issues.length === 0;
},
// enumerable: false,
},
});
// Object.defineProperty(inst, "isEmpty", {
// get() {
// return inst.issues.length === 0;
// },
// });
};
exports.ZodError = core.$constructor("ZodError", initializer);
exports.ZodRealError = core.$constructor("ZodError", initializer, {
Parent: Error,
});
// /** @deprecated Use `z.core.$ZodErrorMapCtx` instead. */
// export type ErrorMapCtx = core.$ZodErrorMapCtx;

View File

@@ -0,0 +1,384 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
/**
* @typedef {{ readonly [type: string]: ReadonlyArray<string> }} VisitorKeys
*/
/**
* @type {VisitorKeys}
*/
const KEYS = {
ArrayExpression: [
"elements"
],
ArrayPattern: [
"elements"
],
ArrowFunctionExpression: [
"params",
"body"
],
AssignmentExpression: [
"left",
"right"
],
AssignmentPattern: [
"left",
"right"
],
AwaitExpression: [
"argument"
],
BinaryExpression: [
"left",
"right"
],
BlockStatement: [
"body"
],
BreakStatement: [
"label"
],
CallExpression: [
"callee",
"arguments"
],
CatchClause: [
"param",
"body"
],
ChainExpression: [
"expression"
],
ClassBody: [
"body"
],
ClassDeclaration: [
"id",
"superClass",
"body"
],
ClassExpression: [
"id",
"superClass",
"body"
],
ConditionalExpression: [
"test",
"consequent",
"alternate"
],
ContinueStatement: [
"label"
],
DebuggerStatement: [],
DoWhileStatement: [
"body",
"test"
],
EmptyStatement: [],
ExperimentalRestProperty: [
"argument"
],
ExperimentalSpreadProperty: [
"argument"
],
ExportAllDeclaration: [
"exported",
"source"
],
ExportDefaultDeclaration: [
"declaration"
],
ExportNamedDeclaration: [
"declaration",
"specifiers",
"source"
],
ExportSpecifier: [
"exported",
"local"
],
ExpressionStatement: [
"expression"
],
ForInStatement: [
"left",
"right",
"body"
],
ForOfStatement: [
"left",
"right",
"body"
],
ForStatement: [
"init",
"test",
"update",
"body"
],
FunctionDeclaration: [
"id",
"params",
"body"
],
FunctionExpression: [
"id",
"params",
"body"
],
Identifier: [],
IfStatement: [
"test",
"consequent",
"alternate"
],
ImportDeclaration: [
"specifiers",
"source"
],
ImportDefaultSpecifier: [
"local"
],
ImportExpression: [
"source"
],
ImportNamespaceSpecifier: [
"local"
],
ImportSpecifier: [
"imported",
"local"
],
JSXAttribute: [
"name",
"value"
],
JSXClosingElement: [
"name"
],
JSXClosingFragment: [],
JSXElement: [
"openingElement",
"children",
"closingElement"
],
JSXEmptyExpression: [],
JSXExpressionContainer: [
"expression"
],
JSXFragment: [
"openingFragment",
"children",
"closingFragment"
],
JSXIdentifier: [],
JSXMemberExpression: [
"object",
"property"
],
JSXNamespacedName: [
"namespace",
"name"
],
JSXOpeningElement: [
"name",
"attributes"
],
JSXOpeningFragment: [],
JSXSpreadAttribute: [
"argument"
],
JSXSpreadChild: [
"expression"
],
JSXText: [],
LabeledStatement: [
"label",
"body"
],
Literal: [],
LogicalExpression: [
"left",
"right"
],
MemberExpression: [
"object",
"property"
],
MetaProperty: [
"meta",
"property"
],
MethodDefinition: [
"key",
"value"
],
NewExpression: [
"callee",
"arguments"
],
ObjectExpression: [
"properties"
],
ObjectPattern: [
"properties"
],
PrivateIdentifier: [],
Program: [
"body"
],
Property: [
"key",
"value"
],
PropertyDefinition: [
"key",
"value"
],
RestElement: [
"argument"
],
ReturnStatement: [
"argument"
],
SequenceExpression: [
"expressions"
],
SpreadElement: [
"argument"
],
StaticBlock: [
"body"
],
Super: [],
SwitchCase: [
"test",
"consequent"
],
SwitchStatement: [
"discriminant",
"cases"
],
TaggedTemplateExpression: [
"tag",
"quasi"
],
TemplateElement: [],
TemplateLiteral: [
"quasis",
"expressions"
],
ThisExpression: [],
ThrowStatement: [
"argument"
],
TryStatement: [
"block",
"handler",
"finalizer"
],
UnaryExpression: [
"argument"
],
UpdateExpression: [
"argument"
],
VariableDeclaration: [
"declarations"
],
VariableDeclarator: [
"id",
"init"
],
WhileStatement: [
"test",
"body"
],
WithStatement: [
"object",
"body"
],
YieldExpression: [
"argument"
]
};
// Types.
const NODE_TYPES = Object.keys(KEYS);
// Freeze the keys.
for (const type of NODE_TYPES) {
Object.freeze(KEYS[type]);
}
Object.freeze(KEYS);
/**
* @author Toru Nagashima <https://github.com/mysticatea>
* See LICENSE file in root directory for full license.
*/
/**
* @typedef {import('./visitor-keys.js').VisitorKeys} VisitorKeys
*/
// List to ignore keys.
const KEY_BLACKLIST = new Set([
"parent",
"leadingComments",
"trailingComments"
]);
/**
* Check whether a given key should be used or not.
* @param {string} key The key to check.
* @returns {boolean} `true` if the key should be used.
*/
function filterKey(key) {
return !KEY_BLACKLIST.has(key) && key[0] !== "_";
}
/**
* Get visitor keys of a given node.
* @param {object} node The AST node to get keys.
* @returns {readonly string[]} Visitor keys of the node.
*/
function getKeys(node) {
return Object.keys(node).filter(filterKey);
}
// Disable valid-jsdoc rule because it reports syntax error on the type of @returns.
// eslint-disable-next-line valid-jsdoc
/**
* Make the union set with `KEYS` and given keys.
* @param {VisitorKeys} additionalKeys The additional keys.
* @returns {VisitorKeys} The union set.
*/
function unionWith(additionalKeys) {
const retv = /** @type {{
[type: string]: ReadonlyArray<string>
}} */ (Object.assign({}, KEYS));
for (const type of Object.keys(additionalKeys)) {
if (Object.prototype.hasOwnProperty.call(retv, type)) {
const keys = new Set(additionalKeys[type]);
for (const key of retv[type]) {
keys.add(key);
}
retv[type] = Object.freeze(Array.from(keys));
} else {
retv[type] = Object.freeze(Array.from(additionalKeys[type]));
}
}
return Object.freeze(retv);
}
exports.KEYS = KEYS;
exports.getKeys = getKeys;
exports.unionWith = unionWith;

View File

@@ -0,0 +1,85 @@
'use strict';
module.exports = function generate__limitLength(it, $keyword, $ruleType) {
var out = ' ';
var $lvl = it.level;
var $dataLvl = it.dataLevel;
var $schema = it.schema[$keyword];
var $schemaPath = it.schemaPath + it.util.getProperty($keyword);
var $errSchemaPath = it.errSchemaPath + '/' + $keyword;
var $breakOnError = !it.opts.allErrors;
var $errorKeyword;
var $data = 'data' + ($dataLvl || '');
var $isData = it.opts.$data && $schema && $schema.$data,
$schemaValue;
if ($isData) {
out += ' var schema' + ($lvl) + ' = ' + (it.util.getData($schema.$data, $dataLvl, it.dataPathArr)) + '; ';
$schemaValue = 'schema' + $lvl;
} else {
$schemaValue = $schema;
}
if (!($isData || typeof $schema == 'number')) {
throw new Error($keyword + ' must be number');
}
var $op = $keyword == 'maxLength' ? '>' : '<';
out += 'if ( ';
if ($isData) {
out += ' (' + ($schemaValue) + ' !== undefined && typeof ' + ($schemaValue) + ' != \'number\') || ';
}
if (it.opts.unicode === false) {
out += ' ' + ($data) + '.length ';
} else {
out += ' ucs2length(' + ($data) + ') ';
}
out += ' ' + ($op) + ' ' + ($schemaValue) + ') { ';
var $errorKeyword = $keyword;
var $$outStack = $$outStack || [];
$$outStack.push(out);
out = ''; /* istanbul ignore else */
if (it.createErrors !== false) {
out += ' { keyword: \'' + ($errorKeyword || '_limitLength') + '\' , dataPath: (dataPath || \'\') + ' + (it.errorPath) + ' , schemaPath: ' + (it.util.toQuotedString($errSchemaPath)) + ' , params: { limit: ' + ($schemaValue) + ' } ';
if (it.opts.messages !== false) {
out += ' , message: \'should NOT be ';
if ($keyword == 'maxLength') {
out += 'longer';
} else {
out += 'shorter';
}
out += ' than ';
if ($isData) {
out += '\' + ' + ($schemaValue) + ' + \'';
} else {
out += '' + ($schema);
}
out += ' characters\' ';
}
if (it.opts.verbose) {
out += ' , schema: ';
if ($isData) {
out += 'validate.schema' + ($schemaPath);
} else {
out += '' + ($schema);
}
out += ' , parentSchema: validate.schema' + (it.schemaPath) + ' , data: ' + ($data) + ' ';
}
out += ' } ';
} else {
out += ' {} ';
}
var __err = out;
out = $$outStack.pop();
if (!it.compositeRule && $breakOnError) {
/* istanbul ignore if */
if (it.async) {
out += ' throw new ValidationError([' + (__err) + ']); ';
} else {
out += ' validate.errors = [' + (__err) + ']; return false; ';
}
} else {
out += ' var err = ' + (__err) + '; if (vErrors === null) vErrors = [err]; else vErrors.push(err); errors++; ';
}
out += '} ';
if ($breakOnError) {
out += ' else { ';
}
return out;
}

View File

@@ -0,0 +1,35 @@
/**
* @fileoverview Defining the hashing function in one place.
* @author Michael Ficarra
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const murmur = require("imurmurhash");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Private
//------------------------------------------------------------------------------
/**
* hash the given string
* @param {string} str the string to hash
* @returns {string} the hash
*/
function hash(str) {
return murmur(str).result().toString(36);
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = hash;

View File

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

View File

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

View File

@@ -0,0 +1,330 @@
import type { Primitive } from "./helpers/typeAliases.js";
import { util, type ZodParsedType } from "./helpers/util.js";
import type { TypeOf, ZodType } from "./index.js";
type allKeys<T> = T extends any ? keyof T : never;
export type inferFlattenedErrors<T extends ZodType<any, any, any>, U = string> = typeToFlattenedError<TypeOf<T>, U>;
export type typeToFlattenedError<T, U = string> = {
formErrors: U[];
fieldErrors: {
[P in allKeys<T>]?: U[];
};
};
export const ZodIssueCode = util.arrayToEnum([
"invalid_type",
"invalid_literal",
"custom",
"invalid_union",
"invalid_union_discriminator",
"invalid_enum_value",
"unrecognized_keys",
"invalid_arguments",
"invalid_return_type",
"invalid_date",
"invalid_string",
"too_small",
"too_big",
"invalid_intersection_types",
"not_multiple_of",
"not_finite",
]);
export type ZodIssueCode = keyof typeof ZodIssueCode;
export type ZodIssueBase = {
path: (string | number)[];
message?: string | undefined;
};
export interface ZodInvalidTypeIssue extends ZodIssueBase {
code: typeof ZodIssueCode.invalid_type;
expected: ZodParsedType;
received: ZodParsedType;
}
export interface ZodInvalidLiteralIssue extends ZodIssueBase {
code: typeof ZodIssueCode.invalid_literal;
expected: unknown;
received: unknown;
}
export interface ZodUnrecognizedKeysIssue extends ZodIssueBase {
code: typeof ZodIssueCode.unrecognized_keys;
keys: string[];
}
export interface ZodInvalidUnionIssue extends ZodIssueBase {
code: typeof ZodIssueCode.invalid_union;
unionErrors: ZodError[];
}
export interface ZodInvalidUnionDiscriminatorIssue extends ZodIssueBase {
code: typeof ZodIssueCode.invalid_union_discriminator;
options: Primitive[];
}
export interface ZodInvalidEnumValueIssue extends ZodIssueBase {
received: string | number;
code: typeof ZodIssueCode.invalid_enum_value;
options: (string | number)[];
}
export interface ZodInvalidArgumentsIssue extends ZodIssueBase {
code: typeof ZodIssueCode.invalid_arguments;
argumentsError: ZodError;
}
export interface ZodInvalidReturnTypeIssue extends ZodIssueBase {
code: typeof ZodIssueCode.invalid_return_type;
returnTypeError: ZodError;
}
export interface ZodInvalidDateIssue extends ZodIssueBase {
code: typeof ZodIssueCode.invalid_date;
}
export type StringValidation =
| "email"
| "url"
| "emoji"
| "uuid"
| "nanoid"
| "regex"
| "cuid"
| "cuid2"
| "ulid"
| "datetime"
| "date"
| "time"
| "duration"
| "ip"
| "cidr"
| "base64"
| "jwt"
| "base64url"
| { includes: string; position?: number | undefined }
| { startsWith: string }
| { endsWith: string };
export interface ZodInvalidStringIssue extends ZodIssueBase {
code: typeof ZodIssueCode.invalid_string;
validation: StringValidation;
}
export interface ZodTooSmallIssue extends ZodIssueBase {
code: typeof ZodIssueCode.too_small;
minimum: number | bigint;
inclusive: boolean;
exact?: boolean;
type: "array" | "string" | "number" | "set" | "date" | "bigint";
}
export interface ZodTooBigIssue extends ZodIssueBase {
code: typeof ZodIssueCode.too_big;
maximum: number | bigint;
inclusive: boolean;
exact?: boolean;
type: "array" | "string" | "number" | "set" | "date" | "bigint";
}
export interface ZodInvalidIntersectionTypesIssue extends ZodIssueBase {
code: typeof ZodIssueCode.invalid_intersection_types;
}
export interface ZodNotMultipleOfIssue extends ZodIssueBase {
code: typeof ZodIssueCode.not_multiple_of;
multipleOf: number | bigint;
}
export interface ZodNotFiniteIssue extends ZodIssueBase {
code: typeof ZodIssueCode.not_finite;
}
export interface ZodCustomIssue extends ZodIssueBase {
code: typeof ZodIssueCode.custom;
params?: { [k: string]: any };
}
export type DenormalizedError = { [k: string]: DenormalizedError | string[] };
export type ZodIssueOptionalMessage =
| ZodInvalidTypeIssue
| ZodInvalidLiteralIssue
| ZodUnrecognizedKeysIssue
| ZodInvalidUnionIssue
| ZodInvalidUnionDiscriminatorIssue
| ZodInvalidEnumValueIssue
| ZodInvalidArgumentsIssue
| ZodInvalidReturnTypeIssue
| ZodInvalidDateIssue
| ZodInvalidStringIssue
| ZodTooSmallIssue
| ZodTooBigIssue
| ZodInvalidIntersectionTypesIssue
| ZodNotMultipleOfIssue
| ZodNotFiniteIssue
| ZodCustomIssue;
export type ZodIssue = ZodIssueOptionalMessage & {
fatal?: boolean | undefined;
message: string;
};
export const quotelessJson = (obj: any) => {
const json = JSON.stringify(obj, null, 2);
return json.replace(/"([^"]+)":/g, "$1:");
};
type recursiveZodFormattedError<T> = T extends [any, ...any[]]
? { [K in keyof T]?: ZodFormattedError<T[K]> }
: T extends any[]
? { [k: number]: ZodFormattedError<T[number]> }
: T extends object
? { [K in keyof T]?: ZodFormattedError<T[K]> }
: unknown;
export type ZodFormattedError<T, U = string> = {
_errors: U[];
} & recursiveZodFormattedError<NonNullable<T>>;
export type inferFormattedError<T extends ZodType<any, any, any>, U = string> = ZodFormattedError<TypeOf<T>, U>;
export class ZodError<T = any> extends Error {
issues: ZodIssue[] = [];
get errors() {
return this.issues;
}
constructor(issues: ZodIssue[]) {
super();
const actualProto = new.target.prototype;
if (Object.setPrototypeOf) {
// eslint-disable-next-line ban/ban
Object.setPrototypeOf(this, actualProto);
} else {
(this as any).__proto__ = actualProto;
}
this.name = "ZodError";
this.issues = issues;
}
format(): ZodFormattedError<T>;
format<U>(mapper: (issue: ZodIssue) => U): ZodFormattedError<T, U>;
format(_mapper?: any) {
const mapper: (issue: ZodIssue) => any =
_mapper ||
function (issue: ZodIssue) {
return issue.message;
};
const fieldErrors: ZodFormattedError<T> = { _errors: [] } as any;
const processError = (error: ZodError) => {
for (const issue of error.issues) {
if (issue.code === "invalid_union") {
issue.unionErrors.map(processError);
} else if (issue.code === "invalid_return_type") {
processError(issue.returnTypeError);
} else if (issue.code === "invalid_arguments") {
processError(issue.argumentsError);
} else if (issue.path.length === 0) {
(fieldErrors as any)._errors.push(mapper(issue));
} else {
let curr: any = fieldErrors;
let i = 0;
while (i < issue.path.length) {
const el = issue.path[i]!;
const terminal = i === issue.path.length - 1;
if (!terminal) {
curr[el] = curr[el] || { _errors: [] };
// if (typeof el === "string") {
// curr[el] = curr[el] || { _errors: [] };
// } else if (typeof el === "number") {
// const errorArray: any = [];
// errorArray._errors = [];
// curr[el] = curr[el] || errorArray;
// }
} else {
curr[el] = curr[el] || { _errors: [] };
curr[el]._errors.push(mapper(issue));
}
curr = curr[el];
i++;
}
}
}
};
processError(this);
return fieldErrors;
}
static create = (issues: ZodIssue[]) => {
const error = new ZodError(issues);
return error;
};
static assert(value: unknown): asserts value is ZodError {
if (!(value instanceof ZodError)) {
throw new Error(`Not a ZodError: ${value}`);
}
}
override toString() {
return this.message;
}
override get message() {
return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
}
get isEmpty(): boolean {
return this.issues.length === 0;
}
addIssue = (sub: ZodIssue) => {
this.issues = [...this.issues, sub];
};
addIssues = (subs: ZodIssue[] = []) => {
this.issues = [...this.issues, ...subs];
};
flatten(): typeToFlattenedError<T>;
flatten<U>(mapper?: (issue: ZodIssue) => U): typeToFlattenedError<T, U>;
flatten<U = string>(mapper: (issue: ZodIssue) => U = (issue: ZodIssue) => issue.message as any): any {
const fieldErrors: any = Object.create(null);
const formErrors: U[] = [];
for (const sub of this.issues) {
if (sub.path.length > 0) {
const firstEl = sub.path[0]!;
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
fieldErrors[firstEl].push(mapper(sub));
} else {
formErrors.push(mapper(sub));
}
}
return { formErrors, fieldErrors };
}
get formErrors() {
return this.flatten();
}
}
type stripPath<T extends object> = T extends any ? util.OmitKeys<T, "path"> : never;
export type IssueData = stripPath<ZodIssueOptionalMessage> & {
path?: (string | number)[];
fatal?: boolean | undefined;
};
export type ErrorMapCtx = {
defaultError: string;
data: any;
};
export type ZodErrorMap = (issue: ZodIssueOptionalMessage, _ctx: ErrorMapCtx) => { message: string };

View File

@@ -0,0 +1 @@
{"version":3,"file":"u8.d.ts","sourceRoot":"","sources":["../../src/u8.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIvG;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,YAAY,QAAO,gBAAgB,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,CAM7D,CAAC;AAEP;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,YAAY,QAAO,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAKpD,CAAC;AAEP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,UAAU,QAAO,cAAc,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,CACvB,CAAC"}

View File

@@ -0,0 +1,18 @@
import { Parser } from "../index.js";
export declare const parsers: {
__babel_estree: Parser;
__js_expression: Parser;
__ts_expression: Parser;
__vue_event_binding: Parser;
__vue_expression: Parser;
__vue_ts_event_binding: Parser;
__vue_ts_expression: Parser;
babel: Parser;
"babel-flow": Parser;
"babel-ts": Parser;
json: Parser;
"json-stringify": Parser;
json5: Parser;
jsonc: Parser;
};

View File

@@ -0,0 +1,335 @@
/**
* Implements [Poseidon](https://www.poseidon-hash.info) ZK-friendly hash.
*
* There are many poseidon variants with different constants.
* We don't provide them: you should construct them manually.
* Check out [micro-starknet](https://github.com/paulmillr/micro-starknet) package for a proper example.
* @module
*/
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
import { _validateObject, bitGet } from '../utils.ts';
import { FpInvertBatch, FpPow, type IField, validateField } from './modular.ts';
// Grain LFSR (Linear-Feedback Shift Register): https://eprint.iacr.org/2009/109.pdf
function grainLFSR(state: number[]): () => boolean {
let pos = 0;
if (state.length !== 80) throw new Error('grainLFRS: wrong state length, should be 80 bits');
const getBit = (): boolean => {
const r = (offset: number) => state[(pos + offset) % 80];
const bit = r(62) ^ r(51) ^ r(38) ^ r(23) ^ r(13) ^ r(0);
state[pos] = bit;
pos = ++pos % 80;
return !!bit;
};
for (let i = 0; i < 160; i++) getBit();
return () => {
// https://en.wikipedia.org/wiki/Shrinking_generator
while (true) {
const b1 = getBit();
const b2 = getBit();
if (!b1) continue;
return b2;
}
};
}
export type PoseidonBasicOpts = {
Fp: IField<bigint>;
t: number; // t = rate + capacity
roundsFull: number;
roundsPartial: number;
isSboxInverse?: boolean;
};
function assertValidPosOpts(opts: PoseidonBasicOpts) {
const { Fp, roundsFull } = opts;
validateField(Fp);
_validateObject(
opts,
{
t: 'number',
roundsFull: 'number',
roundsPartial: 'number',
},
{
isSboxInverse: 'boolean',
}
);
for (const i of ['t', 'roundsFull', 'roundsPartial'] as const) {
if (!Number.isSafeInteger(opts[i]) || opts[i] < 1) throw new Error('invalid number ' + i);
}
if (roundsFull & 1) throw new Error('roundsFull is not even' + roundsFull);
}
function poseidonGrain(opts: PoseidonBasicOpts) {
assertValidPosOpts(opts);
const { Fp } = opts;
const state = Array(80).fill(1);
let pos = 0;
const writeBits = (value: bigint, bitCount: number) => {
for (let i = bitCount - 1; i >= 0; i--) state[pos++] = Number(bitGet(value, i));
};
const _0n = BigInt(0);
const _1n = BigInt(1);
writeBits(_1n, 2); // prime field
writeBits(opts.isSboxInverse ? _1n : _0n, 4); // b2..b5
writeBits(BigInt(Fp.BITS), 12); // b6..b17
writeBits(BigInt(opts.t), 12); // b18..b29
writeBits(BigInt(opts.roundsFull), 10); // b30..b39
writeBits(BigInt(opts.roundsPartial), 10); // b40..b49
const getBit = grainLFSR(state);
return (count: number, reject: boolean): bigint[] => {
const res: bigint[] = [];
for (let i = 0; i < count; i++) {
while (true) {
let num = _0n;
for (let i = 0; i < Fp.BITS; i++) {
num <<= _1n;
if (getBit()) num |= _1n;
}
if (reject && num >= Fp.ORDER) continue; // rejection sampling
res.push(Fp.create(num));
break;
}
}
return res;
};
}
export type PoseidonGrainOpts = PoseidonBasicOpts & {
sboxPower?: number;
};
type PoseidonConstants = { mds: bigint[][]; roundConstants: bigint[][] };
// NOTE: this is not standard but used often for constant generation for poseidon
// (grain LFRS-like structure)
export function grainGenConstants(opts: PoseidonGrainOpts, skipMDS: number = 0): PoseidonConstants {
const { Fp, t, roundsFull, roundsPartial } = opts;
const rounds = roundsFull + roundsPartial;
const sample = poseidonGrain(opts);
const roundConstants: bigint[][] = [];
for (let r = 0; r < rounds; r++) roundConstants.push(sample(t, true));
if (skipMDS > 0) for (let i = 0; i < skipMDS; i++) sample(2 * t, false);
const xs = sample(t, false);
const ys = sample(t, false);
// Construct MDS Matrix M[i][j] = 1 / (xs[i] + ys[j])
const mds: bigint[][] = [];
for (let i = 0; i < t; i++) {
const row: bigint[] = [];
for (let j = 0; j < t; j++) {
const xy = Fp.add(xs[i], ys[j]);
if (Fp.is0(xy))
throw new Error(`Error generating MDS matrix: xs[${i}] + ys[${j}] resulted in zero.`);
row.push(xy);
}
mds.push(FpInvertBatch(Fp, row));
}
return { roundConstants, mds };
}
export type PoseidonOpts = PoseidonBasicOpts &
PoseidonConstants & {
sboxPower?: number;
reversePartialPowIdx?: boolean; // Hack for stark
};
export function validateOpts(opts: PoseidonOpts): Readonly<{
rounds: number;
sboxFn: (n: bigint) => bigint;
roundConstants: bigint[][];
mds: bigint[][];
Fp: IField<bigint>;
t: number;
roundsFull: number;
roundsPartial: number;
sboxPower?: number;
reversePartialPowIdx?: boolean; // Hack for stark
}> {
assertValidPosOpts(opts);
const { Fp, mds, reversePartialPowIdx: rev, roundConstants: rc } = opts;
const { roundsFull, roundsPartial, sboxPower, t } = opts;
// MDS is TxT matrix
if (!Array.isArray(mds) || mds.length !== t) throw new Error('Poseidon: invalid MDS matrix');
const _mds = mds.map((mdsRow) => {
if (!Array.isArray(mdsRow) || mdsRow.length !== t)
throw new Error('invalid MDS matrix row: ' + mdsRow);
return mdsRow.map((i) => {
if (typeof i !== 'bigint') throw new Error('invalid MDS matrix bigint: ' + i);
return Fp.create(i);
});
});
if (rev !== undefined && typeof rev !== 'boolean')
throw new Error('invalid param reversePartialPowIdx=' + rev);
if (roundsFull & 1) throw new Error('roundsFull is not even' + roundsFull);
const rounds = roundsFull + roundsPartial;
if (!Array.isArray(rc) || rc.length !== rounds)
throw new Error('Poseidon: invalid round constants');
const roundConstants = rc.map((rc) => {
if (!Array.isArray(rc) || rc.length !== t) throw new Error('invalid round constants');
return rc.map((i) => {
if (typeof i !== 'bigint' || !Fp.isValid(i)) throw new Error('invalid round constant');
return Fp.create(i);
});
});
if (!sboxPower || ![3, 5, 7, 17].includes(sboxPower)) throw new Error('invalid sboxPower');
const _sboxPower = BigInt(sboxPower);
let sboxFn = (n: bigint) => FpPow(Fp, n, _sboxPower);
// Unwrapped sbox power for common cases (195->142μs)
if (sboxPower === 3) sboxFn = (n: bigint) => Fp.mul(Fp.sqrN(n), n);
else if (sboxPower === 5) sboxFn = (n: bigint) => Fp.mul(Fp.sqrN(Fp.sqrN(n)), n);
return Object.freeze({ ...opts, rounds, sboxFn, roundConstants, mds: _mds });
}
export function splitConstants(rc: bigint[], t: number): bigint[][] {
if (typeof t !== 'number') throw new Error('poseidonSplitConstants: invalid t');
if (!Array.isArray(rc) || rc.length % t) throw new Error('poseidonSplitConstants: invalid rc');
const res = [];
let tmp = [];
for (let i = 0; i < rc.length; i++) {
tmp.push(rc[i]);
if (tmp.length === t) {
res.push(tmp);
tmp = [];
}
}
return res;
}
export type PoseidonFn = {
(values: bigint[]): bigint[];
// For verification in tests
roundConstants: bigint[][];
};
/** Poseidon NTT-friendly hash. */
export function poseidon(opts: PoseidonOpts): PoseidonFn {
const _opts = validateOpts(opts);
const { Fp, mds, roundConstants, rounds: totalRounds, roundsPartial, sboxFn, t } = _opts;
const halfRoundsFull = _opts.roundsFull / 2;
const partialIdx = _opts.reversePartialPowIdx ? t - 1 : 0;
const poseidonRound = (values: bigint[], isFull: boolean, idx: number) => {
values = values.map((i, j) => Fp.add(i, roundConstants[idx][j]));
if (isFull) values = values.map((i) => sboxFn(i));
else values[partialIdx] = sboxFn(values[partialIdx]);
// Matrix multiplication
values = mds.map((i) => i.reduce((acc, i, j) => Fp.add(acc, Fp.mulN(i, values[j])), Fp.ZERO));
return values;
};
const poseidonHash = function poseidonHash(values: bigint[]) {
if (!Array.isArray(values) || values.length !== t)
throw new Error('invalid values, expected array of bigints with length ' + t);
values = values.map((i) => {
if (typeof i !== 'bigint') throw new Error('invalid bigint=' + i);
return Fp.create(i);
});
let lastRound = 0;
// Apply r_f/2 full rounds.
for (let i = 0; i < halfRoundsFull; i++) values = poseidonRound(values, true, lastRound++);
// Apply r_p partial rounds.
for (let i = 0; i < roundsPartial; i++) values = poseidonRound(values, false, lastRound++);
// Apply r_f/2 full rounds.
for (let i = 0; i < halfRoundsFull; i++) values = poseidonRound(values, true, lastRound++);
if (lastRound !== totalRounds) throw new Error('invalid number of rounds');
return values;
};
// For verification in tests
poseidonHash.roundConstants = roundConstants;
return poseidonHash;
}
export class PoseidonSponge {
private Fp: IField<bigint>;
readonly rate: number;
readonly capacity: number;
readonly hash: PoseidonFn;
private state: bigint[]; // [...capacity, ...rate]
private pos = 0;
private isAbsorbing = true;
constructor(Fp: IField<bigint>, rate: number, capacity: number, hash: PoseidonFn) {
this.Fp = Fp;
this.hash = hash;
this.rate = rate;
this.capacity = capacity;
this.state = new Array(rate + capacity);
this.clean();
}
private process(): void {
this.state = this.hash(this.state);
}
absorb(input: bigint[]): void {
for (const i of input)
if (typeof i !== 'bigint' || !this.Fp.isValid(i)) throw new Error('invalid input: ' + i);
for (let i = 0; i < input.length; ) {
if (!this.isAbsorbing || this.pos === this.rate) {
this.process();
this.pos = 0;
this.isAbsorbing = true;
}
const chunk = Math.min(this.rate - this.pos, input.length - i);
for (let j = 0; j < chunk; j++) {
const idx = this.capacity + this.pos++;
this.state[idx] = this.Fp.add(this.state[idx], input[i++]);
}
}
}
squeeze(count: number): bigint[] {
const res: bigint[] = [];
while (res.length < count) {
if (this.isAbsorbing || this.pos === this.rate) {
this.process();
this.pos = 0;
this.isAbsorbing = false;
}
const chunk = Math.min(this.rate - this.pos, count - res.length);
for (let i = 0; i < chunk; i++) res.push(this.state[this.capacity + this.pos++]);
}
return res;
}
clean(): void {
this.state.fill(this.Fp.ZERO);
this.isAbsorbing = true;
this.pos = 0;
}
clone(): PoseidonSponge {
const c = new PoseidonSponge(this.Fp, this.rate, this.capacity, this.hash);
c.pos = this.pos;
c.state = [...this.state];
return c;
}
}
export type PoseidonSpongeOpts = Omit<PoseidonOpts, 't'> & {
rate: number;
capacity: number;
};
/**
* The method is not defined in spec, but nevertheless used often.
* Check carefully for compatibility: there are many edge cases, like absorbing an empty array.
* We cross-test against:
* - https://github.com/ProvableHQ/snarkVM/tree/staging/algorithms
* - https://github.com/arkworks-rs/crypto-primitives/tree/main
*/
export function poseidonSponge(opts: PoseidonSpongeOpts): () => PoseidonSponge {
for (const i of ['rate', 'capacity'] as const) {
if (typeof opts[i] !== 'number' || !Number.isSafeInteger(opts[i]))
throw new Error('invalid number ' + i);
}
const { rate, capacity } = opts;
const t = opts.rate + opts.capacity;
// Re-use hash instance between multiple instances
const hash = poseidon({ ...opts, t });
const { Fp } = opts;
return () => new PoseidonSponge(Fp, rate, capacity, hash);
}

View File

@@ -0,0 +1,73 @@
import { URL } from 'node:url'
import Dispatcher from './dispatcher'
import buildConnector from './connector'
type H2ClientOptions = Omit<Dispatcher.ConnectOptions, 'origin'>
/**
* A basic H2C client, mapped on top a single TCP connection. Pipelining is disabled by default.
*/
export class H2CClient extends Dispatcher {
constructor (url: string | URL, options?: H2CClient.Options)
/** Property to get and set the pipelining factor. */
pipelining: number
/** `true` after `client.close()` has been called. */
closed: boolean
/** `true` after `client.destroyed()` has been called or `client.close()` has been called and the client shutdown has completed. */
destroyed: boolean
// Override dispatcher APIs.
override connect (
options: H2ClientOptions
): Promise<Dispatcher.ConnectData>
override connect (
options: H2ClientOptions,
callback: (err: Error | null, data: Dispatcher.ConnectData) => void
): void
}
export declare namespace H2CClient {
export interface Options {
/** The maximum length of request headers in bytes. Default: Node.js' `--max-http-header-size` or `16384` (16KiB). */
maxHeaderSize?: number;
/** The amount of time, in milliseconds, the parser will wait to receive the complete HTTP headers (Node 14 and above only). Default: `300e3` milliseconds (300s). */
headersTimeout?: number;
/** The timeout for establishing a socket connection, in milliseconds. Use `0` to disable it entirely. Default: `10e3` milliseconds (10s). */
connectTimeout?: number;
/** The timeout after which a request will time out, in milliseconds. Monitors time between receiving body data. Use `0` to disable it entirely. Default: `300e3` milliseconds (300s). */
bodyTimeout?: number;
/** the timeout, in milliseconds, after which a socket without active requests will time out. Monitors time between activity on a connected socket. This value may be overridden by *keep-alive* hints from the server. Default: `4e3` milliseconds (4s). */
keepAliveTimeout?: number;
/** the maximum allowed `idleTimeout`, in milliseconds, when overridden by *keep-alive* hints from the server. Default: `600e3` milliseconds (10min). */
keepAliveMaxTimeout?: number;
/** A number of milliseconds subtracted from server *keep-alive* hints when overriding `idleTimeout` to account for timing inaccuracies caused by e.g. transport latency. Default: `1e3` milliseconds (1s). */
keepAliveTimeoutThreshold?: number;
/** An IPC endpoint, either a Unix domain socket or Windows named pipe. Default: `null`. */
socketPath?: string;
/** The amount of concurrent requests to be sent over the single TCP/TLS connection according to [RFC7230](https://tools.ietf.org/html/rfc7230#section-6.3.2). Default: `1`. */
pipelining?: number;
/** If `true`, an error is thrown when the request content-length header doesn't match the length of the request body. Default: `true`. */
strictContentLength?: boolean;
/** Maximum number of TLS cached sessions used by the built-in connector. Use `0` to disable TLS session caching. Default: `100`. */
maxCachedSessions?: number;
/** Connector options passed to `buildConnector`, or a custom connector function. Default: `null`. */
connect?: Omit<Partial<buildConnector.BuildOptions>, 'allowH2'> | buildConnector.connector;
/** The maximum number of requests to send over a single connection before it is reset. Use `0` to disable this limit. Default: `null`. */
maxRequestsPerClient?: number;
/** Local IP address the socket should connect from. */
localAddress?: string;
/** Max response body size in bytes, -1 is disabled */
maxResponseSize?: number;
/** Enables a family autodetection algorithm that loosely implements section 5 of RFC 8305. */
autoSelectFamily?: boolean;
/** The amount of time in milliseconds to wait for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option. */
autoSelectFamilyAttemptTimeout?: number;
/**
* @description Dictates the maximum number of concurrent streams for a single H2 session. It can be overridden by a SETTINGS remote frame.
* @default 100
*/
maxConcurrentStreams?: number
}
}
export default H2CClient

View File

@@ -0,0 +1,19 @@
import { _ as _path } from './shared/pathe.M-eThtNZ.mjs';
export { c as basename, d as dirname, e as extname, f as format, i as isAbsolute, j as join, m as matchesGlob, n as normalize, a as normalizeString, p as parse, b as relative, r as resolve, s as sep, t as toNamespacedPath } from './shared/pathe.M-eThtNZ.mjs';
const delimiter = /* @__PURE__ */ (() => globalThis.process?.platform === "win32" ? ";" : ":")();
const _platforms = { posix: void 0, win32: void 0 };
const mix = (del = delimiter) => {
return new Proxy(_path, {
get(_, prop) {
if (prop === "delimiter") return del;
if (prop === "posix") return posix;
if (prop === "win32") return win32;
return _platforms[prop] || _path[prop];
}
});
};
const posix = /* @__PURE__ */ mix(":");
const win32 = /* @__PURE__ */ mix(";");
export { posix as default, delimiter, posix, win32 };

View File

@@ -0,0 +1,20 @@
/*! *****************************************************************************
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.
***************************************************************************** */
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => void;

View File

@@ -0,0 +1,58 @@
export class BufferReader {
private buffer: Buffer = Buffer.allocUnsafe(0)
// TODO(bmc): support non-utf8 encoding?
private encoding: BufferEncoding = 'utf-8'
constructor(private offset: number = 0) {}
public setBuffer(offset: number, buffer: Buffer): void {
this.offset = offset
this.buffer = buffer
}
public int16(): number {
const result = this.buffer.readInt16BE(this.offset)
this.offset += 2
return result
}
public byte(): number {
const result = this.buffer[this.offset]
this.offset++
return result
}
public int32(): number {
const result = this.buffer.readInt32BE(this.offset)
this.offset += 4
return result
}
public uint32(): number {
const result = this.buffer.readUInt32BE(this.offset)
this.offset += 4
return result
}
public string(length: number): string {
const result = this.buffer.toString(this.encoding, this.offset, this.offset + length)
this.offset += length
return result
}
public cstring(): string {
const start = this.offset
let end = start
// eslint-disable-next-line no-empty
while (this.buffer[end++]) {}
this.offset = end
return this.buffer.toString(this.encoding, start, end - 1)
}
public bytes(length: number): Buffer {
const result = this.buffer.slice(this.offset, this.offset + length)
this.offset += length
return result
}
}

View File

@@ -0,0 +1,11 @@
language: node_js
sudo: false
node_js:
- 6
- 8
- 10
- 11
- 12
- 13
script:
- npm run ci

View File

@@ -0,0 +1 @@
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/structs/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EACL,MAAM,EACN,YAAY,EACZ,UAAU,EACV,mBAAmB,EACpB,MAAM,aAAa,CAAA;AAGpB;;;;;GAKG;AAEH,wBAAgB,MAAM,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,YAAY,EACnE,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAC1B,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACjD,wBAAgB,MAAM,CACpB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EAEtB,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAC1B,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACvE,wBAAgB,MAAM,CACpB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EAEtB,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAC1B,MAAM,CACP,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAC9C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CACnC,CAAA;AACD,wBAAgB,MAAM,CACpB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,YAAY,EAEtB,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAC1B,MAAM,CACP,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EACzD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAC9C,CAAA;AAQD;;GAEG;AAEH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAE7E;AAED;;;GAGG;AAEH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,GAC1C,MAAM,CAAC,CAAC,CAAC,CAaX;AAED;;;;;;GAMG;AAEH,wBAAgB,OAAO,CAAC,CAAC,EACvB,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,GACnD,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAqBjB;AAED;;;;;;;GAOG;AAEH,wBAAgB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAsBjE;AAED;;;;;GAKG;AAEH,wBAAgB,IAAI,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,MAAM,CAAC,EAC5D,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAChC,IAAI,EAAE,CAAC,EAAE,GACR,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAc5C;AAED;;;;;GAKG;AAEH,wBAAgB,OAAO,CAAC,CAAC,SAAS,YAAY,EAC5C,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GACnC,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAapE;AAED;;;;;GAKG;AAEH,wBAAgB,IAAI,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,MAAM,CAAC,EAC5D,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAChC,IAAI,EAAE,CAAC,EAAE,GACR,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAe5C;AAED;;;;GAIG;AAEH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAM7E"}

View File

@@ -0,0 +1,173 @@
/*
Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
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.
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 <COPYRIGHT HOLDER> 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.
*/
/** @import * as types from "eslint-scope" */
const READ = 0x1;
const WRITE = 0x2;
const RW = READ | WRITE;
/**
* A Reference represents a single occurrence of an identifier in code.
* @constructor Reference
* @implements {types.Reference}
*/
class Reference {
constructor(
ident,
scope,
flag,
writeExpr,
maybeImplicitGlobal,
partial,
init,
) {
/**
* Identifier syntax node.
* @member {espreeIdentifier} Reference#identifier
*/
this.identifier = ident;
/**
* Reference to the enclosing Scope.
* @member {Scope} Reference#from
*/
this.from = scope;
/**
* Whether the reference comes from a dynamic scope (such as 'eval',
* 'with', etc.), and may be trapped by dynamic scopes.
* @member {boolean} Reference#tainted
*/
this.tainted = false;
/**
* The variable this reference is resolved with.
* @member {Variable} Reference#resolved
*/
this.resolved = null;
/**
* The read-write mode of the reference. (Value is one of {@link
* Reference.READ}, {@link Reference.RW}, {@link Reference.WRITE}).
* @member {number} Reference#flag
*/
this.flag = flag;
if (this.isWrite()) {
/**
* If reference is writeable, this is the tree being written to it.
* @member {espreeNode} Reference#writeExpr
*/
this.writeExpr = writeExpr;
/**
* Whether the Reference might refer to a partial value of writeExpr.
* @member {boolean} Reference#partial
*/
this.partial = partial;
/**
* Whether the Reference is to write of initialization.
* @member {boolean} Reference#init
*/
this.init = init;
}
this.__maybeImplicitGlobal = maybeImplicitGlobal;
}
/**
* Whether the reference is static.
* @function Reference#isStatic
* @returns {boolean} static
*/
isStatic() {
return (
!this.tainted && !!this.resolved && this.resolved.scope.isStatic()
);
}
/**
* Whether the reference is writeable.
* @function Reference#isWrite
* @returns {boolean} write
*/
isWrite() {
return !!(this.flag & Reference.WRITE);
}
/**
* Whether the reference is readable.
* @function Reference#isRead
* @returns {boolean} read
*/
isRead() {
return !!(this.flag & Reference.READ);
}
/**
* Whether the reference is read-only.
* @function Reference#isReadOnly
* @returns {boolean} read only
*/
isReadOnly() {
return this.flag === Reference.READ;
}
/**
* Whether the reference is write-only.
* @function Reference#isWriteOnly
* @returns {boolean} write only
*/
isWriteOnly() {
return this.flag === Reference.WRITE;
}
/**
* Whether the reference is read-write.
* @function Reference#isReadWrite
* @returns {boolean} read write
*/
isReadWrite() {
return this.flag === Reference.RW;
}
}
/**
* @constant Reference.READ
*/
Reference.READ = READ;
/**
* @constant Reference.WRITE
*/
Reference.WRITE = WRITE;
/**
* @constant Reference.RW
*/
Reference.RW = RW;
export default Reference;
/* vim: set sw=4 ts=4 et tw=80 : */

View File

@@ -0,0 +1,952 @@
import * as BufferLayout from '@solana/buffer-layout';
import {
encodeData,
decodeData,
InstructionType,
IInstructionInputData,
} from '../instruction';
import * as Layout from '../layout';
import {PublicKey} from '../publickey';
import {SystemProgram} from './system';
import {
SYSVAR_CLOCK_PUBKEY,
SYSVAR_RENT_PUBKEY,
SYSVAR_STAKE_HISTORY_PUBKEY,
} from '../sysvar';
import {Transaction, TransactionInstruction} from '../transaction';
import {toBuffer} from '../utils/to-buffer';
/**
* Address of the stake config account which configures the rate
* of stake warmup and cooldown as well as the slashing penalty.
*/
export const STAKE_CONFIG_ID = new PublicKey(
'StakeConfig11111111111111111111111111111111',
);
/**
* Stake account authority info
*/
export class Authorized {
/** stake authority */
staker: PublicKey;
/** withdraw authority */
withdrawer: PublicKey;
/**
* Create a new Authorized object
* @param staker the stake authority
* @param withdrawer the withdraw authority
*/
constructor(staker: PublicKey, withdrawer: PublicKey) {
this.staker = staker;
this.withdrawer = withdrawer;
}
}
type AuthorizedRaw = Readonly<{
staker: Uint8Array;
withdrawer: Uint8Array;
}>;
/**
* Stake account lockup info
*/
export class Lockup {
/** Unix timestamp of lockup expiration */
unixTimestamp: number;
/** Epoch of lockup expiration */
epoch: number;
/** Lockup custodian authority */
custodian: PublicKey;
/**
* Create a new Lockup object
*/
constructor(unixTimestamp: number, epoch: number, custodian: PublicKey) {
this.unixTimestamp = unixTimestamp;
this.epoch = epoch;
this.custodian = custodian;
}
/**
* Default, inactive Lockup value
*/
static default: Lockup = new Lockup(0, 0, PublicKey.default);
}
type LockupRaw = Readonly<{
custodian: Uint8Array;
epoch: number;
unixTimestamp: number;
}>;
/**
* Create stake account transaction params
*/
export type CreateStakeAccountParams = {
/** Address of the account which will fund creation */
fromPubkey: PublicKey;
/** Address of the new stake account */
stakePubkey: PublicKey;
/** Authorities of the new stake account */
authorized: Authorized;
/** Lockup of the new stake account */
lockup?: Lockup;
/** Funding amount */
lamports: number;
};
/**
* Create stake account with seed transaction params
*/
export type CreateStakeAccountWithSeedParams = {
fromPubkey: PublicKey;
stakePubkey: PublicKey;
basePubkey: PublicKey;
seed: string;
authorized: Authorized;
lockup?: Lockup;
lamports: number;
};
/**
* Initialize stake instruction params
*/
export type InitializeStakeParams = {
stakePubkey: PublicKey;
authorized: Authorized;
lockup?: Lockup;
};
/**
* Delegate stake instruction params
*/
export type DelegateStakeParams = {
stakePubkey: PublicKey;
authorizedPubkey: PublicKey;
votePubkey: PublicKey;
};
/**
* Authorize stake instruction params
*/
export type AuthorizeStakeParams = {
stakePubkey: PublicKey;
authorizedPubkey: PublicKey;
newAuthorizedPubkey: PublicKey;
stakeAuthorizationType: StakeAuthorizationType;
custodianPubkey?: PublicKey;
};
/**
* Authorize stake instruction params using a derived key
*/
export type AuthorizeWithSeedStakeParams = {
stakePubkey: PublicKey;
authorityBase: PublicKey;
authoritySeed: string;
authorityOwner: PublicKey;
newAuthorizedPubkey: PublicKey;
stakeAuthorizationType: StakeAuthorizationType;
custodianPubkey?: PublicKey;
};
/**
* Split stake instruction params
*/
export type SplitStakeParams = {
stakePubkey: PublicKey;
authorizedPubkey: PublicKey;
splitStakePubkey: PublicKey;
lamports: number;
};
/**
* Split with seed transaction params
*/
export type SplitStakeWithSeedParams = {
stakePubkey: PublicKey;
authorizedPubkey: PublicKey;
splitStakePubkey: PublicKey;
basePubkey: PublicKey;
seed: string;
lamports: number;
};
/**
* Withdraw stake instruction params
*/
export type WithdrawStakeParams = {
stakePubkey: PublicKey;
authorizedPubkey: PublicKey;
toPubkey: PublicKey;
lamports: number;
custodianPubkey?: PublicKey;
};
/**
* Deactivate stake instruction params
*/
export type DeactivateStakeParams = {
stakePubkey: PublicKey;
authorizedPubkey: PublicKey;
};
/**
* Merge stake instruction params
*/
export type MergeStakeParams = {
stakePubkey: PublicKey;
sourceStakePubKey: PublicKey;
authorizedPubkey: PublicKey;
};
/**
* Stake Instruction class
*/
export class StakeInstruction {
/**
* @internal
*/
constructor() {}
/**
* Decode a stake instruction and retrieve the instruction type.
*/
static decodeInstructionType(
instruction: TransactionInstruction,
): StakeInstructionType {
this.checkProgramId(instruction.programId);
const instructionTypeLayout = BufferLayout.u32('instruction');
const typeIndex = instructionTypeLayout.decode(instruction.data);
let type: StakeInstructionType | undefined;
for (const [ixType, layout] of Object.entries(STAKE_INSTRUCTION_LAYOUTS)) {
if (layout.index == typeIndex) {
type = ixType as StakeInstructionType;
break;
}
}
if (!type) {
throw new Error('Instruction type incorrect; not a StakeInstruction');
}
return type;
}
/**
* Decode a initialize stake instruction and retrieve the instruction params.
*/
static decodeInitialize(
instruction: TransactionInstruction,
): InitializeStakeParams {
this.checkProgramId(instruction.programId);
this.checkKeyLength(instruction.keys, 2);
const {authorized, lockup} = decodeData(
STAKE_INSTRUCTION_LAYOUTS.Initialize,
instruction.data,
);
return {
stakePubkey: instruction.keys[0].pubkey,
authorized: new Authorized(
new PublicKey(authorized.staker),
new PublicKey(authorized.withdrawer),
),
lockup: new Lockup(
lockup.unixTimestamp,
lockup.epoch,
new PublicKey(lockup.custodian),
),
};
}
/**
* Decode a delegate stake instruction and retrieve the instruction params.
*/
static decodeDelegate(
instruction: TransactionInstruction,
): DelegateStakeParams {
this.checkProgramId(instruction.programId);
this.checkKeyLength(instruction.keys, 6);
decodeData(STAKE_INSTRUCTION_LAYOUTS.Delegate, instruction.data);
return {
stakePubkey: instruction.keys[0].pubkey,
votePubkey: instruction.keys[1].pubkey,
authorizedPubkey: instruction.keys[5].pubkey,
};
}
/**
* Decode an authorize stake instruction and retrieve the instruction params.
*/
static decodeAuthorize(
instruction: TransactionInstruction,
): AuthorizeStakeParams {
this.checkProgramId(instruction.programId);
this.checkKeyLength(instruction.keys, 3);
const {newAuthorized, stakeAuthorizationType} = decodeData(
STAKE_INSTRUCTION_LAYOUTS.Authorize,
instruction.data,
);
const o: AuthorizeStakeParams = {
stakePubkey: instruction.keys[0].pubkey,
authorizedPubkey: instruction.keys[2].pubkey,
newAuthorizedPubkey: new PublicKey(newAuthorized),
stakeAuthorizationType: {
index: stakeAuthorizationType,
},
};
if (instruction.keys.length > 3) {
o.custodianPubkey = instruction.keys[3].pubkey;
}
return o;
}
/**
* Decode an authorize-with-seed stake instruction and retrieve the instruction params.
*/
static decodeAuthorizeWithSeed(
instruction: TransactionInstruction,
): AuthorizeWithSeedStakeParams {
this.checkProgramId(instruction.programId);
this.checkKeyLength(instruction.keys, 2);
const {
newAuthorized,
stakeAuthorizationType,
authoritySeed,
authorityOwner,
} = decodeData(
STAKE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed,
instruction.data,
);
const o: AuthorizeWithSeedStakeParams = {
stakePubkey: instruction.keys[0].pubkey,
authorityBase: instruction.keys[1].pubkey,
authoritySeed: authoritySeed,
authorityOwner: new PublicKey(authorityOwner),
newAuthorizedPubkey: new PublicKey(newAuthorized),
stakeAuthorizationType: {
index: stakeAuthorizationType,
},
};
if (instruction.keys.length > 3) {
o.custodianPubkey = instruction.keys[3].pubkey;
}
return o;
}
/**
* Decode a split stake instruction and retrieve the instruction params.
*/
static decodeSplit(instruction: TransactionInstruction): SplitStakeParams {
this.checkProgramId(instruction.programId);
this.checkKeyLength(instruction.keys, 3);
const {lamports} = decodeData(
STAKE_INSTRUCTION_LAYOUTS.Split,
instruction.data,
);
return {
stakePubkey: instruction.keys[0].pubkey,
splitStakePubkey: instruction.keys[1].pubkey,
authorizedPubkey: instruction.keys[2].pubkey,
lamports,
};
}
/**
* Decode a merge stake instruction and retrieve the instruction params.
*/
static decodeMerge(instruction: TransactionInstruction): MergeStakeParams {
this.checkProgramId(instruction.programId);
this.checkKeyLength(instruction.keys, 3);
decodeData(STAKE_INSTRUCTION_LAYOUTS.Merge, instruction.data);
return {
stakePubkey: instruction.keys[0].pubkey,
sourceStakePubKey: instruction.keys[1].pubkey,
authorizedPubkey: instruction.keys[4].pubkey,
};
}
/**
* Decode a withdraw stake instruction and retrieve the instruction params.
*/
static decodeWithdraw(
instruction: TransactionInstruction,
): WithdrawStakeParams {
this.checkProgramId(instruction.programId);
this.checkKeyLength(instruction.keys, 5);
const {lamports} = decodeData(
STAKE_INSTRUCTION_LAYOUTS.Withdraw,
instruction.data,
);
const o: WithdrawStakeParams = {
stakePubkey: instruction.keys[0].pubkey,
toPubkey: instruction.keys[1].pubkey,
authorizedPubkey: instruction.keys[4].pubkey,
lamports,
};
if (instruction.keys.length > 5) {
o.custodianPubkey = instruction.keys[5].pubkey;
}
return o;
}
/**
* Decode a deactivate stake instruction and retrieve the instruction params.
*/
static decodeDeactivate(
instruction: TransactionInstruction,
): DeactivateStakeParams {
this.checkProgramId(instruction.programId);
this.checkKeyLength(instruction.keys, 3);
decodeData(STAKE_INSTRUCTION_LAYOUTS.Deactivate, instruction.data);
return {
stakePubkey: instruction.keys[0].pubkey,
authorizedPubkey: instruction.keys[2].pubkey,
};
}
/**
* @internal
*/
static checkProgramId(programId: PublicKey) {
if (!programId.equals(StakeProgram.programId)) {
throw new Error('invalid instruction; programId is not StakeProgram');
}
}
/**
* @internal
*/
static checkKeyLength(keys: Array<any>, expectedLength: number) {
if (keys.length < expectedLength) {
throw new Error(
`invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`,
);
}
}
}
/**
* An enumeration of valid StakeInstructionType's
*/
export type StakeInstructionType =
// FIXME
// It would be preferable for this type to be `keyof StakeInstructionInputData`
// but Typedoc does not transpile `keyof` expressions.
// See https://github.com/TypeStrong/typedoc/issues/1894
| 'Authorize'
| 'AuthorizeWithSeed'
| 'Deactivate'
| 'Delegate'
| 'Initialize'
| 'Merge'
| 'Split'
| 'Withdraw';
type StakeInstructionInputData = {
Authorize: IInstructionInputData &
Readonly<{
newAuthorized: Uint8Array;
stakeAuthorizationType: number;
}>;
AuthorizeWithSeed: IInstructionInputData &
Readonly<{
authorityOwner: Uint8Array;
authoritySeed: string;
instruction: number;
newAuthorized: Uint8Array;
stakeAuthorizationType: number;
}>;
Deactivate: IInstructionInputData;
Delegate: IInstructionInputData;
Initialize: IInstructionInputData &
Readonly<{
authorized: AuthorizedRaw;
lockup: LockupRaw;
}>;
Merge: IInstructionInputData;
Split: IInstructionInputData &
Readonly<{
lamports: number;
}>;
Withdraw: IInstructionInputData &
Readonly<{
lamports: number;
}>;
};
/**
* An enumeration of valid stake InstructionType's
* @internal
*/
export const STAKE_INSTRUCTION_LAYOUTS = Object.freeze<{
[Instruction in StakeInstructionType]: InstructionType<
StakeInstructionInputData[Instruction]
>;
}>({
Initialize: {
index: 0,
layout: BufferLayout.struct<StakeInstructionInputData['Initialize']>([
BufferLayout.u32('instruction'),
Layout.authorized(),
Layout.lockup(),
]),
},
Authorize: {
index: 1,
layout: BufferLayout.struct<StakeInstructionInputData['Authorize']>([
BufferLayout.u32('instruction'),
Layout.publicKey('newAuthorized'),
BufferLayout.u32('stakeAuthorizationType'),
]),
},
Delegate: {
index: 2,
layout: BufferLayout.struct<StakeInstructionInputData['Delegate']>([
BufferLayout.u32('instruction'),
]),
},
Split: {
index: 3,
layout: BufferLayout.struct<StakeInstructionInputData['Split']>([
BufferLayout.u32('instruction'),
BufferLayout.ns64('lamports'),
]),
},
Withdraw: {
index: 4,
layout: BufferLayout.struct<StakeInstructionInputData['Withdraw']>([
BufferLayout.u32('instruction'),
BufferLayout.ns64('lamports'),
]),
},
Deactivate: {
index: 5,
layout: BufferLayout.struct<StakeInstructionInputData['Deactivate']>([
BufferLayout.u32('instruction'),
]),
},
Merge: {
index: 7,
layout: BufferLayout.struct<StakeInstructionInputData['Merge']>([
BufferLayout.u32('instruction'),
]),
},
AuthorizeWithSeed: {
index: 8,
layout: BufferLayout.struct<StakeInstructionInputData['AuthorizeWithSeed']>(
[
BufferLayout.u32('instruction'),
Layout.publicKey('newAuthorized'),
BufferLayout.u32('stakeAuthorizationType'),
Layout.rustString('authoritySeed'),
Layout.publicKey('authorityOwner'),
],
),
},
});
/**
* Stake authorization type
*/
export type StakeAuthorizationType = {
/** The Stake Authorization index (from solana-stake-program) */
index: number;
};
/**
* An enumeration of valid StakeAuthorizationLayout's
*/
export const StakeAuthorizationLayout = Object.freeze({
Staker: {
index: 0,
},
Withdrawer: {
index: 1,
},
});
/**
* Factory class for transactions to interact with the Stake program
*/
export class StakeProgram {
/**
* @internal
*/
constructor() {}
/**
* Public key that identifies the Stake program
*/
static programId: PublicKey = new PublicKey(
'Stake11111111111111111111111111111111111111',
);
/**
* Max space of a Stake account
*
* This is generated from the solana-stake-program StakeState struct as
* `StakeStateV2::size_of()`:
* https://docs.rs/solana-stake-program/latest/solana_stake_program/stake_state/enum.StakeStateV2.html
*/
static space: number = 200;
/**
* Generate an Initialize instruction to add to a Stake Create transaction
*/
static initialize(params: InitializeStakeParams): TransactionInstruction {
const {stakePubkey, authorized, lockup: maybeLockup} = params;
const lockup: Lockup = maybeLockup || Lockup.default;
const type = STAKE_INSTRUCTION_LAYOUTS.Initialize;
const data = encodeData(type, {
authorized: {
staker: toBuffer(authorized.staker.toBuffer()),
withdrawer: toBuffer(authorized.withdrawer.toBuffer()),
},
lockup: {
unixTimestamp: lockup.unixTimestamp,
epoch: lockup.epoch,
custodian: toBuffer(lockup.custodian.toBuffer()),
},
});
const instructionData = {
keys: [
{pubkey: stakePubkey, isSigner: false, isWritable: true},
{pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false},
],
programId: this.programId,
data,
};
return new TransactionInstruction(instructionData);
}
/**
* Generate a Transaction that creates a new Stake account at
* an address generated with `from`, a seed, and the Stake programId
*/
static createAccountWithSeed(
params: CreateStakeAccountWithSeedParams,
): Transaction {
const transaction = new Transaction();
transaction.add(
SystemProgram.createAccountWithSeed({
fromPubkey: params.fromPubkey,
newAccountPubkey: params.stakePubkey,
basePubkey: params.basePubkey,
seed: params.seed,
lamports: params.lamports,
space: this.space,
programId: this.programId,
}),
);
const {stakePubkey, authorized, lockup} = params;
return transaction.add(this.initialize({stakePubkey, authorized, lockup}));
}
/**
* Generate a Transaction that creates a new Stake account
*/
static createAccount(params: CreateStakeAccountParams): Transaction {
const transaction = new Transaction();
transaction.add(
SystemProgram.createAccount({
fromPubkey: params.fromPubkey,
newAccountPubkey: params.stakePubkey,
lamports: params.lamports,
space: this.space,
programId: this.programId,
}),
);
const {stakePubkey, authorized, lockup} = params;
return transaction.add(this.initialize({stakePubkey, authorized, lockup}));
}
/**
* Generate a Transaction that delegates Stake tokens to a validator
* Vote PublicKey. This transaction can also be used to redelegate Stake
* to a new validator Vote PublicKey.
*/
static delegate(params: DelegateStakeParams): Transaction {
const {stakePubkey, authorizedPubkey, votePubkey} = params;
const type = STAKE_INSTRUCTION_LAYOUTS.Delegate;
const data = encodeData(type);
return new Transaction().add({
keys: [
{pubkey: stakePubkey, isSigner: false, isWritable: true},
{pubkey: votePubkey, isSigner: false, isWritable: false},
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
{
pubkey: SYSVAR_STAKE_HISTORY_PUBKEY,
isSigner: false,
isWritable: false,
},
{pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false},
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
],
programId: this.programId,
data,
});
}
/**
* Generate a Transaction that authorizes a new PublicKey as Staker
* or Withdrawer on the Stake account.
*/
static authorize(params: AuthorizeStakeParams): Transaction {
const {
stakePubkey,
authorizedPubkey,
newAuthorizedPubkey,
stakeAuthorizationType,
custodianPubkey,
} = params;
const type = STAKE_INSTRUCTION_LAYOUTS.Authorize;
const data = encodeData(type, {
newAuthorized: toBuffer(newAuthorizedPubkey.toBuffer()),
stakeAuthorizationType: stakeAuthorizationType.index,
});
const keys = [
{pubkey: stakePubkey, isSigner: false, isWritable: true},
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: true},
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
];
if (custodianPubkey) {
keys.push({
pubkey: custodianPubkey,
isSigner: true,
isWritable: false,
});
}
return new Transaction().add({
keys,
programId: this.programId,
data,
});
}
/**
* Generate a Transaction that authorizes a new PublicKey as Staker
* or Withdrawer on the Stake account.
*/
static authorizeWithSeed(params: AuthorizeWithSeedStakeParams): Transaction {
const {
stakePubkey,
authorityBase,
authoritySeed,
authorityOwner,
newAuthorizedPubkey,
stakeAuthorizationType,
custodianPubkey,
} = params;
const type = STAKE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed;
const data = encodeData(type, {
newAuthorized: toBuffer(newAuthorizedPubkey.toBuffer()),
stakeAuthorizationType: stakeAuthorizationType.index,
authoritySeed: authoritySeed,
authorityOwner: toBuffer(authorityOwner.toBuffer()),
});
const keys = [
{pubkey: stakePubkey, isSigner: false, isWritable: true},
{pubkey: authorityBase, isSigner: true, isWritable: false},
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
];
if (custodianPubkey) {
keys.push({
pubkey: custodianPubkey,
isSigner: true,
isWritable: false,
});
}
return new Transaction().add({
keys,
programId: this.programId,
data,
});
}
/**
* @internal
*/
static splitInstruction(params: SplitStakeParams): TransactionInstruction {
const {stakePubkey, authorizedPubkey, splitStakePubkey, lamports} = params;
const type = STAKE_INSTRUCTION_LAYOUTS.Split;
const data = encodeData(type, {lamports});
return new TransactionInstruction({
keys: [
{pubkey: stakePubkey, isSigner: false, isWritable: true},
{pubkey: splitStakePubkey, isSigner: false, isWritable: true},
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
],
programId: this.programId,
data,
});
}
/**
* Generate a Transaction that splits Stake tokens into another stake account
*/
static split(
params: SplitStakeParams,
// Compute the cost of allocating the new stake account in lamports
rentExemptReserve: number,
): Transaction {
const transaction = new Transaction();
transaction.add(
SystemProgram.createAccount({
fromPubkey: params.authorizedPubkey,
newAccountPubkey: params.splitStakePubkey,
lamports: rentExemptReserve,
space: this.space,
programId: this.programId,
}),
);
return transaction.add(this.splitInstruction(params));
}
/**
* Generate a Transaction that splits Stake tokens into another account
* derived from a base public key and seed
*/
static splitWithSeed(
params: SplitStakeWithSeedParams,
// If this stake account is new, compute the cost of allocating it in lamports
rentExemptReserve?: number,
): Transaction {
const {
stakePubkey,
authorizedPubkey,
splitStakePubkey,
basePubkey,
seed,
lamports,
} = params;
const transaction = new Transaction();
transaction.add(
SystemProgram.allocate({
accountPubkey: splitStakePubkey,
basePubkey,
seed,
space: this.space,
programId: this.programId,
}),
);
if (rentExemptReserve && rentExemptReserve > 0) {
transaction.add(
SystemProgram.transfer({
fromPubkey: params.authorizedPubkey,
toPubkey: splitStakePubkey,
lamports: rentExemptReserve,
}),
);
}
return transaction.add(
this.splitInstruction({
stakePubkey,
authorizedPubkey,
splitStakePubkey,
lamports,
}),
);
}
/**
* Generate a Transaction that merges Stake accounts.
*/
static merge(params: MergeStakeParams): Transaction {
const {stakePubkey, sourceStakePubKey, authorizedPubkey} = params;
const type = STAKE_INSTRUCTION_LAYOUTS.Merge;
const data = encodeData(type);
return new Transaction().add({
keys: [
{pubkey: stakePubkey, isSigner: false, isWritable: true},
{pubkey: sourceStakePubKey, isSigner: false, isWritable: true},
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
{
pubkey: SYSVAR_STAKE_HISTORY_PUBKEY,
isSigner: false,
isWritable: false,
},
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
],
programId: this.programId,
data,
});
}
/**
* Generate a Transaction that withdraws deactivated Stake tokens.
*/
static withdraw(params: WithdrawStakeParams): Transaction {
const {stakePubkey, authorizedPubkey, toPubkey, lamports, custodianPubkey} =
params;
const type = STAKE_INSTRUCTION_LAYOUTS.Withdraw;
const data = encodeData(type, {lamports});
const keys = [
{pubkey: stakePubkey, isSigner: false, isWritable: true},
{pubkey: toPubkey, isSigner: false, isWritable: true},
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
{
pubkey: SYSVAR_STAKE_HISTORY_PUBKEY,
isSigner: false,
isWritable: false,
},
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
];
if (custodianPubkey) {
keys.push({
pubkey: custodianPubkey,
isSigner: true,
isWritable: false,
});
}
return new Transaction().add({
keys,
programId: this.programId,
data,
});
}
/**
* Generate a Transaction that deactivates Stake tokens.
*/
static deactivate(params: DeactivateStakeParams): Transaction {
const {stakePubkey, authorizedPubkey} = params;
const type = STAKE_INSTRUCTION_LAYOUTS.Deactivate;
const data = encodeData(type);
return new Transaction().add({
keys: [
{pubkey: stakePubkey, isSigner: false, isWritable: true},
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
],
programId: this.programId,
data,
});
}
}