UNPKG

@lucidcms/core

Version:

The core of the Lucid CMS. It's responsible for spinning up the API and serving the CMS.

1 lines 18.5 kB
{"version":3,"file":"static-repository.mjs","names":["queryBuilder"],"sources":["../../../../src/libs/repositories/parents/static-repository.ts"],"sourcesContent":["import { sql } from \"kysely\";\nimport type { QueryParams } from \"../../../types/query-params.js\";\nimport queryBuilder, {\n\ttype QueryBuilderWhere,\n} from \"../../db/query-builder/index.js\";\nimport type { Insert, LucidDB, Select, Update } from \"../../db/types.js\";\nimport type { QueryProps } from \"../types.js\";\nimport BaseRepository from \"./base-repository.js\";\n\n/**\n * The static repository class that all repositories should extend. This class provides basic CRUD operations for a single table.\n *\n * For tables that need more complex queries with joins or subqueries. Its expect you override the methods in this class while keeping the same paramaters if posible.\n *\n * @todo Any queryBuilder helper functions likley need to make use of the columnFormats config so they can correctly parse the data if needed. For ex if the where array includes an op on a boolean column, the value needs to be correctly formatted.\n * @todo Add callback support for the validation / tweak required. Sometimes instead of returning an error on required failing we want to handle it differently\n * @todo Improve validation error messages. Allow error overides for differnt types, required, validation etc.\n * @todo look into using $if for conditional query builder options\n * @todo try and get the retuning and select props correctly typed instead of typing it ourselved with the Select helper. Likley allows us to get rid of the 'as Promise<Pick<Select<T>, K> | undefined>' and lets Kysely handle the return type\n * @todo Support for DB Adapters overiding queries. Probs best as a method that repos can opt into?\n *\n */\nabstract class StaticRepository<\n\tTable extends keyof LucidDB,\n\tT extends LucidDB[Table] = LucidDB[Table],\n> extends BaseRepository<Table, T> {\n\t// ----------------------------------------\n\t// Queries\n\tasync count<V extends boolean = false>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\twhere?: QueryBuilderWhere<Table>;\n\t\t\t}\n\t\t>,\n\t) {\n\t\tlet query = this.db\n\t\t\t.selectFrom(this.tableName)\n\t\t\t.select(sql`count(*)`.as(\"count\"));\n\n\t\tif (props.where !== undefined && props.where.length > 0) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = queryBuilder.select(query, props.where);\n\t\t}\n\n\t\tconst exec = await this.executeQuery(\n\t\t\t() =>\n\t\t\t\tquery.executeTakeFirst() as Promise<\n\t\t\t\t\t{ count: string | number } | undefined\n\t\t\t\t>,\n\t\t\t{\n\t\t\t\tmethod: \"count\",\n\t\t\t},\n\t\t);\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"count\",\n\t\t});\n\t}\n\n\t// ----------------------------------------\n\t// selects\n\tasync selectSingle<K extends keyof Select<T>, V extends boolean = false>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\tselect: K[];\n\t\t\t\twhere: QueryBuilderWhere<Table>;\n\t\t\t}\n\t\t>,\n\t) {\n\t\t// @ts-expect-error\n\t\tlet query = this.db.selectFrom(this.tableName).select(props.select);\n\n\t\t// @ts-expect-error\n\t\tquery = queryBuilder.select(query, props.where);\n\n\t\tconst exec = await this.executeQuery(\n\t\t\t() => query.executeTakeFirst() as Promise<Pick<Select<T>, K> | undefined>,\n\t\t\t{\n\t\t\t\tmethod: \"selectSingle\",\n\t\t\t},\n\t\t);\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"single\",\n\t\t\tselect: props.select as string[],\n\t\t});\n\t}\n\tasync selectMultiple<K extends keyof Select<T>, V extends boolean = false>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\tselect: K[];\n\t\t\t\twhere?: QueryBuilderWhere<Table>;\n\t\t\t\torderBy?: { column: K; direction: \"asc\" | \"desc\" }[];\n\t\t\t\tlimit?: number;\n\t\t\t\toffset?: number;\n\t\t\t}\n\t\t>,\n\t) {\n\t\t// @ts-expect-error\n\t\tlet query = this.db.selectFrom(this.tableName).select(props.select);\n\n\t\tif (props.where) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = queryBuilder.select(query, props.where);\n\t\t}\n\n\t\tif (props.orderBy) {\n\t\t\tfor (const order of props.orderBy) {\n\t\t\t\tquery = query.orderBy(order.column as string, order.direction);\n\t\t\t}\n\t\t}\n\n\t\tif (props.limit) {\n\t\t\tquery = query.limit(props.limit);\n\t\t}\n\n\t\tif (props.offset) {\n\t\t\tquery = query.offset(props.offset);\n\t\t}\n\n\t\tconst exec = await this.executeQuery(\n\t\t\t() => query.execute() as Promise<Pick<Select<T>, K>[]>,\n\t\t\t{\n\t\t\t\tmethod: \"selectMultiple\",\n\t\t\t},\n\t\t);\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"multiple\",\n\t\t\tselect: props.select as string[],\n\t\t});\n\t}\n\tasync selectMultipleFiltered<\n\t\tK extends keyof Select<T>,\n\t\tV extends boolean = false,\n\t>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\tselect: K[];\n\t\t\t\twhere?: QueryBuilderWhere<Table>;\n\t\t\t\tqueryParams: Partial<QueryParams>;\n\t\t\t}\n\t\t>,\n\t) {\n\t\tconst exec = await this.executeQuery(\n\t\t\tasync () => {\n\t\t\t\tlet mainQuery = this.db\n\t\t\t\t\t.selectFrom(this.tableName)\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\t.select(props.select);\n\n\t\t\t\tlet countQuery = this.db\n\t\t\t\t\t.selectFrom(this.tableName)\n\t\t\t\t\t.select(sql`count(*)`.as(\"count\"));\n\n\t\t\t\tif (props.where) {\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tmainQuery = queryBuilder.select(mainQuery, props.where);\n\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\tcountQuery = queryBuilder.select(countQuery, props.where);\n\t\t\t\t}\n\n\t\t\t\tconst { main, count } = queryBuilder.main(\n\t\t\t\t\t{\n\t\t\t\t\t\tmain: mainQuery,\n\t\t\t\t\t\tcount: countQuery,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tqueryParams: props.queryParams,\n\t\t\t\t\t\tdatabase: this.dbAdapter.config,\n\t\t\t\t\t\t// @ts-expect-error\n\t\t\t\t\t\tmeta: this.queryConfig,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tconst [mainResult, countResult] = await Promise.all([\n\t\t\t\t\tmain.execute() as Promise<Pick<Select<T>, K>[]>,\n\t\t\t\t\tcount?.executeTakeFirst() as Promise<{ count: string } | undefined>,\n\t\t\t\t]);\n\n\t\t\t\treturn [mainResult, countResult] as const;\n\t\t\t},\n\t\t\t{\n\t\t\t\tmethod: \"selectMultipleFiltered\",\n\t\t\t},\n\t\t);\n\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"multiple-count\",\n\t\t\tselect: props.select as string[],\n\t\t});\n\t}\n\n\t// ----------------------------------------\n\t// deletes\n\tasync deleteSingle<K extends keyof Select<T>, V extends boolean = false>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\treturning?: K[];\n\t\t\t\treturnAll?: true;\n\t\t\t\twhere: QueryBuilderWhere<Table>;\n\t\t\t}\n\t\t>,\n\t) {\n\t\tlet query = this.db.deleteFrom(this.tableName);\n\n\t\tif (\n\t\t\tprops.returnAll !== true &&\n\t\t\tprops.returning &&\n\t\t\tprops.returning.length > 0\n\t\t) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = query.returning(props.returning);\n\t\t}\n\n\t\tif (props.returnAll) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = query.returningAll();\n\t\t}\n\n\t\t// @ts-expect-error\n\t\tquery = queryBuilder.delete(query, props.where);\n\n\t\tconst exec = await this.executeQuery(\n\t\t\t() => query.executeTakeFirst() as Promise<Pick<Select<T>, K> | undefined>,\n\t\t\t{\n\t\t\t\tmethod: \"deleteSingle\",\n\t\t\t},\n\t\t);\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"single\",\n\t\t\tselect: props.returning as string[],\n\t\t\tselectAll: props.returnAll,\n\t\t});\n\t}\n\tasync deleteMultiple<K extends keyof Select<T>, V extends boolean = false>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\treturning?: K[];\n\t\t\t\treturnAll?: true;\n\t\t\t\twhere: QueryBuilderWhere<Table>;\n\t\t\t}\n\t\t>,\n\t) {\n\t\tlet query = this.db.deleteFrom(this.tableName);\n\n\t\tif (\n\t\t\tprops.returnAll !== true &&\n\t\t\tprops.returning &&\n\t\t\tprops.returning.length > 0\n\t\t) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = query.returning(props.returning);\n\t\t}\n\n\t\tif (props.returnAll) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = query.returningAll();\n\t\t}\n\n\t\t// @ts-expect-error\n\t\tquery = queryBuilder.delete(query, props.where);\n\n\t\tconst exec = await this.executeQuery(\n\t\t\t() => query.execute() as Promise<Pick<Select<T>, K>[]>,\n\t\t\t{\n\t\t\t\tmethod: \"deleteMultiple\",\n\t\t\t},\n\t\t);\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"multiple\",\n\t\t\tselect: props.returning as string[],\n\t\t\tselectAll: props.returnAll,\n\t\t});\n\t}\n\n\t// ----------------------------------------\n\t// creates\n\tasync createSingle<K extends keyof Select<T>, V extends boolean = false>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\tdata: Partial<Insert<T>>;\n\t\t\t\treturning?: K[];\n\t\t\t\treturnAll?: true;\n\t\t\t}\n\t\t>,\n\t) {\n\t\tconst formattedData = this.formatData(props.data, {\n\t\t\ttype: \"insert\",\n\t\t});\n\t\tlet query =\n\t\t\tObject.keys(formattedData).length > 0\n\t\t\t\t? this.db.insertInto(this.tableName).values(formattedData)\n\t\t\t\t: this.db.insertInto(this.tableName).defaultValues();\n\n\t\tif (\n\t\t\tprops.returnAll !== true &&\n\t\t\tprops.returning &&\n\t\t\tprops.returning.length > 0\n\t\t) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = query.returning(props.returning);\n\t\t}\n\n\t\tif (props.returnAll) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = query.returningAll();\n\t\t}\n\n\t\tconst exec = await this.executeQuery(\n\t\t\t() => query.executeTakeFirst() as Promise<Pick<Select<T>, K> | undefined>,\n\t\t\t{\n\t\t\t\tmethod: \"createSingle\",\n\t\t\t},\n\t\t);\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"single\",\n\t\t\tselect: props.returning as string[],\n\t\t\tselectAll: props.returnAll,\n\t\t});\n\t}\n\tasync createMultiple<K extends keyof Select<T>, V extends boolean = false>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\tdata: Partial<Insert<T>>[];\n\t\t\t\treturning?: K[];\n\t\t\t\treturnAll?: true;\n\t\t\t}\n\t\t>,\n\t) {\n\t\tlet query = this.db.insertInto(this.tableName).values(\n\t\t\tprops.data.map((d) =>\n\t\t\t\tthis.formatData(d, {\n\t\t\t\t\ttype: \"insert\",\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\n\t\tif (\n\t\t\tprops.returnAll !== true &&\n\t\t\tprops.returning &&\n\t\t\tprops.returning.length > 0\n\t\t) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = query.returning(props.returning);\n\t\t}\n\n\t\tif (props.returnAll) {\n\t\t\t// @ts-expect-error\n\t\t\tquery = query.returningAll();\n\t\t}\n\n\t\tconst exec = await this.executeQuery(\n\t\t\t() => query.execute() as Promise<Pick<Select<T>, K>[]>,\n\t\t\t{\n\t\t\t\tmethod: \"createMultiple\",\n\t\t\t},\n\t\t);\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"multiple\",\n\t\t\tselect: props.returning as string[],\n\t\t\tselectAll: props.returnAll,\n\t\t});\n\t}\n\n\t// ----------------------------------------\n\t// updates\n\tasync updateSingle<K extends keyof Select<T>, V extends boolean = false>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\tdata: Partial<Update<T>>;\n\t\t\t\twhere: QueryBuilderWhere<Table>;\n\t\t\t\treturning?: K[];\n\t\t\t\treturnAll?: true;\n\t\t\t}\n\t\t>,\n\t) {\n\t\tlet query = this.db\n\t\t\t.updateTable(this.tableName)\n\t\t\t.set(\n\t\t\t\tthis.formatData(props.data, {\n\t\t\t\t\ttype: \"update\",\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.$if(\n\t\t\t\tprops.returnAll !== true &&\n\t\t\t\t\tprops.returning !== undefined &&\n\t\t\t\t\tprops.returning.length > 0,\n\t\t\t\t// @ts-expect-error\n\t\t\t\t(qb) => qb.returning(props.returning),\n\t\t\t)\n\t\t\t.$if(props.returnAll ?? false, (qb) => qb.returningAll());\n\n\t\t// @ts-expect-error\n\t\tquery = queryBuilder.update(query, props.where);\n\n\t\tconst exec = await this.executeQuery(\n\t\t\t() => query.executeTakeFirst() as Promise<Pick<Select<T>, K> | undefined>,\n\t\t\t{\n\t\t\t\tmethod: \"updateSingle\",\n\t\t\t},\n\t\t);\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"single\",\n\t\t\tselect: props.returning as string[],\n\t\t\tselectAll: props.returnAll,\n\t\t});\n\t}\n\tasync updateMultiple<K extends keyof Select<T>, V extends boolean = false>(\n\t\tprops: QueryProps<\n\t\t\tV,\n\t\t\t{\n\t\t\t\tdata: Partial<Update<T>>;\n\t\t\t\twhere: QueryBuilderWhere<Table>;\n\t\t\t\treturning?: K[];\n\t\t\t\treturnAll?: true;\n\t\t\t}\n\t\t>,\n\t) {\n\t\tlet query = this.db\n\t\t\t.updateTable(this.tableName)\n\t\t\t.set(\n\t\t\t\tthis.formatData(props.data, {\n\t\t\t\t\ttype: \"update\",\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.$if(\n\t\t\t\tprops.returnAll !== true &&\n\t\t\t\t\tprops.returning !== undefined &&\n\t\t\t\t\tprops.returning.length > 0,\n\t\t\t\t// @ts-expect-error\n\t\t\t\t(qb) => qb.returning(props.returning),\n\t\t\t)\n\t\t\t.$if(props.returnAll ?? false, (qb) => qb.returningAll());\n\n\t\t// @ts-expect-error\n\t\tquery = queryBuilder.update(query, props.where);\n\n\t\tconst exec = await this.executeQuery(\n\t\t\t() => query.execute() as Promise<Pick<Select<T>, K>[] | undefined>,\n\t\t\t{\n\t\t\t\tmethod: \"updateMultiple\",\n\t\t\t},\n\t\t);\n\t\tif (exec.response.error) return exec.response;\n\n\t\treturn this.validateResponse(exec, {\n\t\t\t...props.validation,\n\t\t\tmode: \"single\",\n\t\t\tselect: props.returning as string[],\n\t\t\tselectAll: props.returnAll,\n\t\t});\n\t}\n}\n\nexport default StaticRepository;\n"],"mappings":"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"}