diff --git a/packages/core/src/utils/RelationQueries.ts b/packages/core/src/utils/RelationQueries.ts index a2a5e20de..36f248ef0 100644 --- a/packages/core/src/utils/RelationQueries.ts +++ b/packages/core/src/utils/RelationQueries.ts @@ -17,19 +17,19 @@ type CamelCaseIdObject = KeysToCamelCase<{ [Key in `${T}_id`]: string; }>; -class RelationQueryError extends Error {} - /** * Query class for relation tables that connect several tables by their entry ids. * - * @example * Let's say we have two tables `users` and `groups` and a relation table * `user_group_relations`. Then we can create a `RelationQueries` instance like this: * * ```ts - * const userGroupRelations = new RelationQueries(pool, 'user_group_relations', 'users', 'groups'); + * const userGroupRelations = new RelationQueries(pool, 'user_group_relations', Users, Groups); * ``` * + * `Users` and `Groups` are the schemas of the tables that satisfy the {@link TableInfo} + * interface. The generated schemas in `@logto/schemas` satisfy this interface. + * * To insert a new relation, we can use the {@link RelationQueries.insert} method: * * ```ts @@ -44,7 +44,7 @@ class RelationQueryError extends Error {} * To get all entries for a specific table, we can use the {@link RelationQueries.getEntries} method: * * ```ts - * await userGroupRelations.getEntries('users', { group_id: 'group-id-1' }); + * await userGroupRelations.getEntries(Users, { groupId: 'group-id-1' }); * ``` * * This will return all entries for the `users` table that are connected to the @@ -63,7 +63,8 @@ export default class RelationQueries< /** * @param pool The database pool. * @param relationTable The name of the relation table. - * @param relations The names of the tables that are connected by the relation table. + * @param relations The schemas of the tables that are connected by the relation table. + * @see {@link TableInfo} for more information about the schemas. */ constructor( public readonly pool: CommonQueryMethods, @@ -81,7 +82,7 @@ export default class RelationQueries< * * @example * ```ts - * const userGroupRelations = new RelationQueries(pool, 'user_group_relations', 'users', 'groups'); + * const userGroupRelations = new RelationQueries(pool, 'user_group_relations', Users, Groups); * * userGroupRelations.insert(['user-id-1', 'group-id-1']); * // Insert multiple relations at once @@ -113,6 +114,19 @@ export default class RelationQueries< `); } + /** + * Delete a relation from the relation table. + * + * @param data The ids of the entries to delete. The keys must be in camel case + * and end with `Id`. + * @returns A Promise that resolves to the query result. + * + * @example + * ```ts + * const userGroupRelations = new RelationQueries(pool, 'user_group_relations', Users, Groups); + * userGroupRelations.delete({ userId: 'user-id-1', groupId: 'group-id-1' }); + * ``` + */ async delete(data: CamelCaseIdObject) { const snakeCaseData = snakecaseKeys(data); return this.pool.query(sql` @@ -126,6 +140,21 @@ export default class RelationQueries< `); } + /** + * Get all entries for a specific schema that are connected to the given ids. + * + * @param forSchema The schema to get the entries for. + * @param where Other ids to filter the entries by. The keys must be in camel case + * and end with `Id`. + * @returns A Promise that resolves an array of entries of the given schema. + * + * @example + * ```ts + * const userGroupRelations = new RelationQueries(pool, 'user_group_relations', Users, Groups); + * + * userGroupRelations.getEntries(Users, { groupId: 'group-id-1' }); + * ``` + */ async getEntries( forSchema: S, where: CamelCaseIdObject>