Skip to content

Instantly share code, notes, and snippets.

@ForbesLindesay
Created February 25, 2021 18:07
Show Gist options
  • Save ForbesLindesay/eb4a397fd4186d75b048482d04164048 to your computer and use it in GitHub Desktop.
Save ForbesLindesay/eb4a397fd4186d75b048482d04164048 to your computer and use it in GitHub Desktop.
pg-typed doesn't have docs yet, here's the types with some comments to get you started.
import type { SQLQuery, Queryable } from '@databases/pg';
/**
* A query for multiple records that has not yet been sent to the database
*/
export interface SelectQuery<TRecord> {
all(): Promise<TRecord[]>;
orderByAsc(key: keyof TRecord): OrderedSelectQuery<TRecord>;
orderByDesc(key: keyof TRecord): OrderedSelectQuery<TRecord>;
select<TKeys extends (keyof TRecord)[]>(...fields: TKeys): SelectQuery<Pick<TRecord, TKeys[number]>>;
}
/**
* If you stort a query, you can use `.first()` or `.limit(count)` to request
* a limited set of results, instead of all records that match the query.
*/
export interface OrderedSelectQuery<TRecord> extends SelectQuery<TRecord> {
first(): Promise<TRecord | null>;
limit(count: number): Promise<TRecord[]>;
}
/**
* FieldQueries let you apply conditions other than equality
* to fields in a where clause.
*/
export interface FieldQuery<T> {}
export type WhereCondition<TRecord> = Partial<{
[key in keyof TRecord]: TRecord[key] | FieldQuery<TRecord[key]>;
}>;
export function anyOf<T>(values: T[]): FieldQuery<T>;
export function not<T>(value: T | FieldQuery<T>): FieldQuery<T>;
export function inQueryResults(query: SQLQuery): FieldQuery<any>;
export function lessThan<T>(value: T): FieldQuery<T>;
export function greaterThan<T>(value: T): FieldQuery<T>;
export interface Table<TRecord, TInsertParameters> {
/**
* Insert and return some records, throwing an error if any record already exists
*/
insert<TRecordsToInsert extends readonly TInsertParameters[]>(...rows: TRecordsToInsert): Promise<{
[key in keyof TRecordsToInsert]: TRecord;
}>;
/**
* Insert and return some records, updating them if any already exist with the `conflictKeys` AND
* the database has a unique index enforced on those keys
*/
insertOrUpdate<TRecordsToInsert extends readonly TInsertParameters[]>(conflictKeys: (keyof TRecord)[], ...rows: TRecordsToInsert): Promise<{
[key in keyof TRecordsToInsert]: TRecord;
}>;
/**
* Insert and return some records, ignoring any that cause conflicts. Only the successfully inserted
* records are returned.
*/
insertOrIgnore<TRecordsToInsert extends readonly TInsertParameters[]>(...rows: TRecordsToInsert): Promise<TRecord[]>;
/**
* Update all records matching a condition, returning the updated records. N.B. does not error
* even if no records match the query.
*/
update(whereValues: WhereCondition<TRecord>, updateValues: Partial<TRecord>): Promise<TRecord[]>;
/**
* Delete all records matching a condition. N.B. does not error
* even if no records match the query.
*/
delete(whereValues: WhereCondition<TRecord>): Promise<void>;
/**
* Begin building a query on the given table. The actual query on the database is executed when
* you call `.all()`, `.first()` or `.limit(n)`
*/
find(whereValues?: WhereCondition<TRecord>): SelectQuery<TRecord>;
/**
* Load a record matching a query. If no record matches the query, `null` is returned.
* If multiple records match the query, an error is thrown.
*/
findOne(whereValues: WhereCondition<TRecord>): Promise<TRecord | null>;
/**
* Run some completely arbitrary SQL and cast the type to be an array of records
* for this table, N.B. no type checking is performmed.
*/
untypedQuery(query: SQLQuery): Promise<TRecord[]>;
/**
* @deprecated use .find instead of .select
*/
select(whereValues?: WhereCondition<TRecord>): SelectQuery<TRecord>;
/**
* @deprecated use .findOne instead of .selectOne
*/
selectOne(whereValues: WhereCondition<TRecord>): Promise<TRecord | null>;
}
export default function tables<TTables>(options?: PgTypedOptions): {
[TTableName in keyof TTables]: (connectionOrTransaction: Queryable) => Table<TTables[TTableName]>;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment