ponder-client
Version:
Type-safe, lightweight Ponder client
107 lines (106 loc) • 5.22 kB
TypeScript
import type { Hex } from 'viem';
type Scalar = 'string' | 'int' | 'float' | 'boolean' | 'hex' | 'bigint';
type BaseColumn<TType extends Scalar = Scalar, TReferences extends `${string}.id` | undefined | unknown = unknown, TOptional extends boolean | unknown = unknown, TList extends boolean | unknown = unknown> = {
_type: 'b';
type: TType;
references: TReferences;
optional: TOptional;
list: TList;
};
type ReferenceColumn<TType extends Scalar = Scalar, TReferences extends `${string}.id` = `${string}.id`, TOptional extends boolean = boolean> = BaseColumn<TType, TReferences, TOptional, false>;
type NonReferenceColumn<TType extends Scalar = Scalar, TOptional extends boolean = boolean, TList extends boolean = boolean> = BaseColumn<TType, undefined, TOptional, TList>;
type EnumColumn<TType extends string | unknown = unknown, TOptional extends boolean | unknown = unknown, TList extends boolean | unknown = unknown> = {
_type: 'e';
type: TType;
optional: TOptional;
list: TList;
};
type ManyColumn<T extends `${string}.${string}` | unknown = unknown> = T extends `${infer TTableName extends string}.${infer TColumnName extends string}` ? {
_type: 'm';
referenceTable: TTableName;
referenceColumn: TColumnName;
} : {
_type: 'm';
};
type OneColumn<T extends string | unknown = unknown> = T extends string ? {
_type: 'o';
referenceColumn: T;
} : {
_type: 'o';
};
type Columns = Record<string, NonReferenceColumn | ReferenceColumn | EnumColumn | ManyColumn | OneColumn>;
/**
* Recover raw typescript types from the intermediate representation
*/
type RecoverScalarType<TScalar extends Scalar> = TScalar extends 'string' ? string : TScalar extends 'int' ? number : TScalar extends 'float' ? number : TScalar extends 'boolean' ? boolean : TScalar extends 'hex' ? Hex : TScalar extends 'bigint' ? bigint : never;
type RecoverColumnType<TColumn extends NonReferenceColumn | ReferenceColumn | EnumColumn | ManyColumn | OneColumn> = TColumn extends {
type: infer _type extends Scalar;
list: infer _list extends boolean;
} ? _list extends false ? RecoverScalarType<_type> : RecoverScalarType<_type>[] : never;
type RecoverPageInfoType<TKey extends string | number | symbol> = TKey extends 'hasNextPage' ? boolean : TKey extends 'hasPreviousPage' ? boolean : TKey extends 'startCursor' ? string : TKey extends 'endCursor' ? string : never;
type ManyFilterWhere<TColumns extends Columns> = {
[column in keyof TColumns]?: RecoverColumnType<TColumns[column]>;
};
interface ManyFilter<TColumns extends Columns> {
limit?: number;
orderBy?: keyof TColumns;
orderDirection?: 'asc' | 'desc';
before?: string;
after?: string;
where?: ManyFilterWhere<TColumns>;
}
type SingleFilter<TColumns extends Columns> = {
id: string;
};
type Selection<TColumns extends Columns> = {
[column in keyof TColumns]?: boolean;
};
interface Pagination {
hasNextPage?: boolean;
hasPreviousPage?: boolean;
startCursor?: boolean;
endCursor?: boolean;
}
type QueryPart<TTableName extends string, TColumns extends Columns, TSelection extends Selection<TColumns> = Selection<TColumns>, TPagination extends Pagination = Pagination> = {
type: 'many';
table: TTableName;
filter: ManyFilter<TColumns>;
columns: TSelection;
pagination: TPagination;
} | {
type: 'one';
table: TTableName;
filter: SingleFilter<TColumns>;
columns: TSelection;
pagination: TPagination;
};
type Query<TTableName extends string = string, TColumns extends Columns = Columns, TSelection extends Record<string, Selection<TColumns>> = Record<string, Selection<TColumns>>> = Record<string, QueryPart<TTableName, TColumns, TSelection[string]>>;
type Data<Q extends Query<any, any, any>> = Q extends Query<infer TTableName, infer TColumns> ? {
[QueryName in keyof Q]: Q[QueryName]['type'] extends 'many' ? {
items: {
[column in keyof Q[QueryName]['columns']]: RecoverColumnType<TColumns[column]>;
}[];
pageInfo: {
[key in keyof Q[QueryName]['pagination']]: RecoverPageInfoType<key>;
};
} : {
[column in keyof Q[QueryName]['columns']]: RecoverColumnType<TColumns[column]>;
};
} : never;
declare function many<TTableName extends string, TColumns extends Columns, TSelection extends Selection<TColumns> = Selection<TColumns>, TPagination extends Pagination = Pagination>(table: TTableName): (filter: ManyFilter<TColumns>, columns: TSelection, pagination: TPagination) => {
type: "many";
table: TTableName;
filter: ManyFilter<TColumns>;
columns: TSelection;
pagination: TPagination;
};
declare function one<TTableName extends string, TColumns extends Columns, TSelection extends Selection<TColumns> = Selection<TColumns>>(table: TTableName): (filter: SingleFilter<TColumns>, columns: TSelection) => {
type: "one";
table: TTableName;
filter: SingleFilter<TColumns>;
columns: TSelection;
pagination: {};
};
declare function query<TTableName extends string, TColumns extends Columns = Columns>(endpoint: string, q: Query<TTableName, TColumns>): Promise<any>;
export { one, many, query };
export type { Data, Query, QueryPart };