Created
September 8, 2024 03:37
-
-
Save MendyLanda/c865d891947be1be08f3291767f49e97 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// P.S. the real moeny is at the buttom of the file | |
import { getTableColumns, type Table } from "drizzle-orm"; | |
/** | |
* Creates a column selector for a given Drizzle ORM table. | |
* | |
* This function allows for flexible selection and omission of columns from a table. | |
* | |
* @param table - The Drizzle ORM table to create a column selector for. | |
* @returns A column selector object that can be used to select and omit columns from the table, access the result with `.columns` | |
* | |
* @example | |
* // Assuming we have a 'users' table with columns: id, name, email, age | |
* const userSelector = columnSelector(usersTable); | |
* | |
* // Select specific columns | |
* const nameAndEmail = userSelector.select('name', 'email').columns; | |
* // Result: { name: Column, email: Column } | |
* | |
* // Omit specific columns | |
* const withoutAge = userSelector.omit('age').columns; | |
* // Result: { id: Column, name: Column, email: Column } | |
* | |
* // Chain operations | |
* const onlyName = userSelector.select('name', 'email').omit('email').columns; | |
* // Result: { name: Column } | |
*/ | |
export function columnSelector<T extends Table>(table: T) { | |
type AllColumns = T["_"]["columns"]; | |
type ColumnSelector<C extends AllColumns> = { | |
select: <K extends keyof C>(...columns: K[]) => ColumnSelector<Pick<C, K>>; | |
omit: <K extends keyof C>(...columns: K[]) => ColumnSelector<Omit<C, K>>; | |
columns: C; | |
}; | |
const createColumnSelector = <C extends AllColumns>( | |
currentColumns: C, | |
): ColumnSelector<C> => ({ | |
select: <K extends keyof C>(...columns: K[]) => | |
createColumnSelector( | |
Object.fromEntries( | |
Object.entries(currentColumns).filter(([key]) => | |
columns.includes(key as K), | |
), | |
) as Pick<C, K>, | |
), | |
omit: <K extends keyof C>(...columns: K[]) => | |
createColumnSelector( | |
Object.fromEntries( | |
Object.entries(currentColumns).filter( | |
([key]) => !columns.includes(key as K), | |
), | |
) as Omit<C, K>, | |
), | |
columns: currentColumns, | |
}); | |
return createColumnSelector(getTableColumns(table)); | |
} | |
/** | |
* You can use the columnSelector to create your own custom column selectors | |
* and use them in your queries. This allows you to define reusable selectors | |
* tailored to your specific needs. | |
* | |
* For example, you might want to create a selector that always omits the | |
* 'timeDeleted' column: | |
*/ | |
function myCustomSelector<T extends Table>(table: T) { | |
return columnSelector(table).omit("timeDeleted").columns; | |
} | |
const columns = myCustomSelector(myTable); | |
// @ts-expect-error Profit! | |
columns.timeDeleted; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment