From 2835e1d7092e6e1218eb9fe2175ef486f38deea6 Mon Sep 17 00:00:00 2001 From: Elliot DeNolf Date: Fri, 16 Aug 2024 18:51:39 -0400 Subject: [PATCH] feat: abstract postgres base adapter (#7732) Abstracts Postgres base adapter in order to allow future postgres-based adapters. --- packages/db-postgres/src/index.ts | 28 ++-- packages/db-postgres/src/types.ts | 156 ++---------------- packages/drizzle/package.json | 10 ++ packages/drizzle/src/exports/postgres.ts | 13 ++ .../src/postgres}/countDistinct.ts | 10 +- .../convertPathToJSONTraversal.ts | 0 .../createJSONQuery/formatJSONPathSegment.ts | 0 .../src/postgres}/createJSONQuery/index.ts | 0 .../src/postgres}/createMigration.ts | 4 +- .../src/postgres}/defaultSnapshot.ts | 0 .../src/postgres}/deleteWhere.ts | 3 +- .../src/postgres}/dropDatabase.ts | 0 .../src => drizzle/src/postgres}/execute.ts | 0 .../src/postgres}/getMigrationTemplate.ts | 0 .../src => drizzle/src/postgres}/init.ts | 7 +- .../src => drizzle/src/postgres}/insert.ts | 3 +- .../src/postgres}/requireDrizzleKit.ts | 5 +- .../src/postgres}/schema/build.ts | 21 ++- .../src/postgres}/schema/createIndex.ts | 0 .../src/postgres}/schema/idToUUID.ts | 0 .../src/postgres}/schema/parentIDColumnMap.ts | 0 .../src/postgres}/schema/setColumnID.ts | 8 +- .../src/postgres}/schema/traverseFields.ts | 19 ++- .../src/postgres}/schema/withDefault.ts | 0 packages/drizzle/src/postgres/types.ts | 154 +++++++++++++++++ pnpm-lock.yaml | 121 ++++++++++---- 26 files changed, 338 insertions(+), 224 deletions(-) create mode 100644 packages/drizzle/src/exports/postgres.ts rename packages/{db-postgres/src => drizzle/src/postgres}/countDistinct.ts (75%) rename packages/{db-postgres/src => drizzle/src/postgres}/createJSONQuery/convertPathToJSONTraversal.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/createJSONQuery/formatJSONPathSegment.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/createJSONQuery/index.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/createMigration.ts (97%) rename packages/{db-postgres/src => drizzle/src/postgres}/defaultSnapshot.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/deleteWhere.ts (78%) rename packages/{db-postgres/src => drizzle/src/postgres}/dropDatabase.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/execute.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/getMigrationTemplate.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/init.ts (93%) rename packages/{db-postgres/src => drizzle/src/postgres}/insert.ts (89%) rename packages/{db-postgres/src => drizzle/src/postgres}/requireDrizzleKit.ts (71%) rename packages/{db-postgres/src => drizzle/src/postgres}/schema/build.ts (97%) rename packages/{db-postgres/src => drizzle/src/postgres}/schema/createIndex.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/schema/idToUUID.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/schema/parentIDColumnMap.ts (100%) rename packages/{db-postgres/src => drizzle/src/postgres}/schema/setColumnID.ts (83%) rename packages/{db-postgres/src => drizzle/src/postgres}/schema/traverseFields.ts (98%) rename packages/{db-postgres/src => drizzle/src/postgres}/schema/withDefault.ts (100%) create mode 100644 packages/drizzle/src/postgres/types.ts diff --git a/packages/db-postgres/src/index.ts b/packages/db-postgres/src/index.ts index 755365a5ad..5777c3661c 100644 --- a/packages/db-postgres/src/index.ts +++ b/packages/db-postgres/src/index.ts @@ -32,26 +32,26 @@ import { updateOne, updateVersion, } from '@payloadcms/drizzle' +import { + convertPathToJSONTraversal, + countDistinct, + createJSONQuery, + createMigration, + defaultDrizzleSnapshot, + deleteWhere, + dropDatabase, + execute, + getMigrationTemplate, + init, + insert, + requireDrizzleKit, +} from '@payloadcms/drizzle/postgres' import { pgEnum, pgSchema, pgTable } from 'drizzle-orm/pg-core' import { createDatabaseAdapter } from 'payload' import type { Args, PostgresAdapter } from './types.js' import { connect } from './connect.js' -import { countDistinct } from './countDistinct.js' -import { convertPathToJSONTraversal } from './createJSONQuery/convertPathToJSONTraversal.js' -import { createJSONQuery } from './createJSONQuery/index.js' -import { createMigration } from './createMigration.js' -import { defaultDrizzleSnapshot } from './defaultSnapshot.js' -import { deleteWhere } from './deleteWhere.js' -import { dropDatabase } from './dropDatabase.js' -import { execute } from './execute.js' -import { getMigrationTemplate } from './getMigrationTemplate.js' -import { init } from './init.js' -import { insert } from './insert.js' -import { requireDrizzleKit } from './requireDrizzleKit.js' - -export type { MigrateDownArgs, MigrateUpArgs } from './types.js' export { sql } from 'drizzle-orm' diff --git a/packages/db-postgres/src/types.ts b/packages/db-postgres/src/types.ts index fbc757efa3..b044bf9dcd 100644 --- a/packages/db-postgres/src/types.ts +++ b/packages/db-postgres/src/types.ts @@ -1,31 +1,14 @@ -import type { Operators } from '@payloadcms/drizzle' import type { - BuildQueryJoinAliases, - DrizzleAdapter, - TransactionPg, -} from '@payloadcms/drizzle/types' -import type { DrizzleSnapshotJSON } from 'drizzle-kit/api' -import type { - ColumnBaseConfig, - ColumnDataType, - DrizzleConfig, - Relation, - Relations, - SQL, -} from 'drizzle-orm' -import type { NodePgDatabase } from 'drizzle-orm/node-postgres' -import type { - PgColumn, - PgEnum, - PgInsertOnConflictDoUpdateConfig, - PgSchema, - PgTableWithColumns, - PgTransactionConfig, - pgEnum, -} from 'drizzle-orm/pg-core' -import type { PgTableFn } from 'drizzle-orm/pg-core/table' -import type { Payload, PayloadRequest } from 'payload' -import type { Pool, PoolConfig, QueryResult } from 'pg' + BasePostgresAdapter, + GenericEnum, + MigrateDownArgs, + MigrateUpArgs, + PostgresDB, +} from '@payloadcms/drizzle/postgres' +import type { DrizzleAdapter } from '@payloadcms/drizzle/types' +import type { DrizzleConfig } from 'drizzle-orm' +import type { PgSchema, PgTableFn, PgTransactionConfig } from 'drizzle-orm/pg-core' +import type { Pool, PoolConfig } from 'pg' export type Args = { idType?: 'serial' | 'uuid' @@ -49,125 +32,10 @@ export type Args = { versionsSuffix?: string } -export type GenericColumn = PgColumn< - ColumnBaseConfig, - Record -> - -export type GenericColumns = { - [x: string]: GenericColumn -} - -export type GenericTable = PgTableWithColumns<{ - columns: GenericColumns - dialect: string - name: string - schema: string -}> - -export type GenericEnum = PgEnum<[string, ...string[]]> - -export type GenericRelation = Relations>> - -export type PostgresDB = NodePgDatabase> - -export type CountDistinct = (args: { - db: PostgresDB | TransactionPg - joins: BuildQueryJoinAliases - tableName: string - where: SQL -}) => Promise - -export type DeleteWhere = (args: { - db: PostgresDB | TransactionPg - tableName: string - where: SQL -}) => Promise - -export type DropDatabase = (args: { adapter: PostgresAdapter }) => Promise - -export type Execute = (args: { - db?: PostgresDB | TransactionPg - drizzle?: PostgresDB - raw?: string - sql?: SQL -}) => Promise>> - -export type Insert = (args: { - db: PostgresDB | TransactionPg - onConflictDoUpdate?: PgInsertOnConflictDoUpdateConfig - tableName: string - values: Record | Record[] -}) => Promise[]> - -type PostgresDrizzleAdapter = Omit< - DrizzleAdapter, - | 'countDistinct' - | 'deleteWhere' - | 'drizzle' - | 'dropDatabase' - | 'execute' - | 'insert' - | 'operators' - | 'relations' -> - -type Schema = - | { - enum: typeof pgEnum - table: PgTableFn - } - | PgSchema - export type PostgresAdapter = { - countDistinct: CountDistinct - defaultDrizzleSnapshot: DrizzleSnapshotJSON - deleteWhere: DeleteWhere - drizzle: PostgresDB - dropDatabase: DropDatabase - enums: Record - execute: Execute - /** - * An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name - * Used for returning properly formed errors from unique fields - */ - fieldConstraints: Record> - idType: Args['idType'] - initializing: Promise - insert: Insert - localesSuffix?: string - logger: DrizzleConfig['logger'] - operators: Operators - pgSchema?: Schema pool: Pool - poolOptions: Args['pool'] - prodMigrations?: { - down: (args: MigrateDownArgs) => Promise - name: string - up: (args: MigrateUpArgs) => Promise - }[] - push: boolean - rejectInitializing: () => void - relations: Record - relationshipsSuffix?: string - resolveInitializing: () => void - schemaName?: Args['schemaName'] - sessions: { - [id: string]: { - db: PostgresDB | TransactionPg - reject: () => Promise - resolve: () => Promise - } - } - tableNameMap: Map - tables: Record - versionsSuffix?: string -} & PostgresDrizzleAdapter - -export type IDType = 'integer' | 'numeric' | 'uuid' | 'varchar' - -export type MigrateUpArgs = { payload: Payload; req?: Partial } -export type MigrateDownArgs = { payload: Payload; req?: Partial } + poolOptions: PoolConfig +} & BasePostgresAdapter declare module 'payload' { export interface DatabaseAdapter diff --git a/packages/drizzle/package.json b/packages/drizzle/package.json index 9d65ebc1b8..ec24ddd488 100644 --- a/packages/drizzle/package.json +++ b/packages/drizzle/package.json @@ -17,6 +17,11 @@ "types": "./src/index.ts", "default": "./src/index.ts" }, + "./postgres": { + "import": "./src/exports/postgres.ts", + "types": "./src/exports/postgres.ts", + "default": "./src/exports/postgres.ts" + }, "./types": { "import": "./src/types.ts", "types": "./src/types.ts", @@ -61,6 +66,11 @@ "types": "./dist/index.d.ts", "default": "./dist/index.js" }, + "./postgres": { + "import": "./dist/exports/postgres.js", + "types": "./dist/exports/postgres.d.ts", + "default": "./dist/exports/postgres.js" + }, "./types": { "import": "./dist/types.js", "types": "./dist/types.d.ts", diff --git a/packages/drizzle/src/exports/postgres.ts b/packages/drizzle/src/exports/postgres.ts new file mode 100644 index 0000000000..1ede681c15 --- /dev/null +++ b/packages/drizzle/src/exports/postgres.ts @@ -0,0 +1,13 @@ +export { countDistinct } from '../postgres/countDistinct.js' +export { convertPathToJSONTraversal } from '../postgres/createJSONQuery/convertPathToJSONTraversal.js' +export { createJSONQuery } from '../postgres/createJSONQuery/index.js' +export { createMigration } from '../postgres/createMigration.js' +export { defaultDrizzleSnapshot } from '../postgres/defaultSnapshot.js' +export { deleteWhere } from '../postgres/deleteWhere.js' +export { dropDatabase } from '../postgres/dropDatabase.js' +export { execute } from '../postgres/execute.js' +export { getMigrationTemplate } from '../postgres/getMigrationTemplate.js' +export { init } from '../postgres/init.js' +export { insert } from '../postgres/insert.js' +export { requireDrizzleKit } from '../postgres/requireDrizzleKit.js' +export * from '../postgres/types.js' diff --git a/packages/db-postgres/src/countDistinct.ts b/packages/drizzle/src/postgres/countDistinct.ts similarity index 75% rename from packages/db-postgres/src/countDistinct.ts rename to packages/drizzle/src/postgres/countDistinct.ts index 4a12a6a6fc..1669eaf2ef 100644 --- a/packages/db-postgres/src/countDistinct.ts +++ b/packages/drizzle/src/postgres/countDistinct.ts @@ -1,12 +1,12 @@ -import type { ChainedMethods, TransactionPg } from '@payloadcms/drizzle/types' - -import { chainMethods } from '@payloadcms/drizzle' import { sql } from 'drizzle-orm' -import type { CountDistinct, PostgresAdapter } from './types.js' +import type { ChainedMethods, TransactionPg } from '../types.js' +import type { BasePostgresAdapter, CountDistinct } from './types.js' + +import { chainMethods } from '../find/chainMethods.js' export const countDistinct: CountDistinct = async function countDistinct( - this: PostgresAdapter, + this: BasePostgresAdapter, { db, joins, tableName, where }, ) { const chainedMethods: ChainedMethods = [] diff --git a/packages/db-postgres/src/createJSONQuery/convertPathToJSONTraversal.ts b/packages/drizzle/src/postgres/createJSONQuery/convertPathToJSONTraversal.ts similarity index 100% rename from packages/db-postgres/src/createJSONQuery/convertPathToJSONTraversal.ts rename to packages/drizzle/src/postgres/createJSONQuery/convertPathToJSONTraversal.ts diff --git a/packages/db-postgres/src/createJSONQuery/formatJSONPathSegment.ts b/packages/drizzle/src/postgres/createJSONQuery/formatJSONPathSegment.ts similarity index 100% rename from packages/db-postgres/src/createJSONQuery/formatJSONPathSegment.ts rename to packages/drizzle/src/postgres/createJSONQuery/formatJSONPathSegment.ts diff --git a/packages/db-postgres/src/createJSONQuery/index.ts b/packages/drizzle/src/postgres/createJSONQuery/index.ts similarity index 100% rename from packages/db-postgres/src/createJSONQuery/index.ts rename to packages/drizzle/src/postgres/createJSONQuery/index.ts diff --git a/packages/db-postgres/src/createMigration.ts b/packages/drizzle/src/postgres/createMigration.ts similarity index 97% rename from packages/db-postgres/src/createMigration.ts rename to packages/drizzle/src/postgres/createMigration.ts index 52b0bf68c6..299b44721c 100644 --- a/packages/db-postgres/src/createMigration.ts +++ b/packages/drizzle/src/postgres/createMigration.ts @@ -8,7 +8,7 @@ import { getPredefinedMigration, writeMigrationIndex } from 'payload' import prompts from 'prompts' import { fileURLToPath } from 'url' -import type { PostgresAdapter } from './types.js' +import type { BasePostgresAdapter } from './types.js' import { defaultDrizzleSnapshot } from './defaultSnapshot.js' import { getMigrationTemplate } from './getMigrationTemplate.js' @@ -16,7 +16,7 @@ import { getMigrationTemplate } from './getMigrationTemplate.js' const require = createRequire(import.meta.url) export const createMigration: CreateMigration = async function createMigration( - this: PostgresAdapter, + this: BasePostgresAdapter, { file, forceAcceptWarning, migrationName, payload }, ) { const filename = fileURLToPath(import.meta.url) diff --git a/packages/db-postgres/src/defaultSnapshot.ts b/packages/drizzle/src/postgres/defaultSnapshot.ts similarity index 100% rename from packages/db-postgres/src/defaultSnapshot.ts rename to packages/drizzle/src/postgres/defaultSnapshot.ts diff --git a/packages/db-postgres/src/deleteWhere.ts b/packages/drizzle/src/postgres/deleteWhere.ts similarity index 78% rename from packages/db-postgres/src/deleteWhere.ts rename to packages/drizzle/src/postgres/deleteWhere.ts index c7fd178374..39f2a214af 100644 --- a/packages/db-postgres/src/deleteWhere.ts +++ b/packages/drizzle/src/postgres/deleteWhere.ts @@ -1,5 +1,4 @@ -import type { TransactionPg } from '@payloadcms/drizzle/types' - +import type { TransactionPg } from '../types.js' import type { DeleteWhere } from './types.js' export const deleteWhere: DeleteWhere = async function deleteWhere({ db, tableName, where }) { diff --git a/packages/db-postgres/src/dropDatabase.ts b/packages/drizzle/src/postgres/dropDatabase.ts similarity index 100% rename from packages/db-postgres/src/dropDatabase.ts rename to packages/drizzle/src/postgres/dropDatabase.ts diff --git a/packages/db-postgres/src/execute.ts b/packages/drizzle/src/postgres/execute.ts similarity index 100% rename from packages/db-postgres/src/execute.ts rename to packages/drizzle/src/postgres/execute.ts diff --git a/packages/db-postgres/src/getMigrationTemplate.ts b/packages/drizzle/src/postgres/getMigrationTemplate.ts similarity index 100% rename from packages/db-postgres/src/getMigrationTemplate.ts rename to packages/drizzle/src/postgres/getMigrationTemplate.ts diff --git a/packages/db-postgres/src/init.ts b/packages/drizzle/src/postgres/init.ts similarity index 93% rename from packages/db-postgres/src/init.ts rename to packages/drizzle/src/postgres/init.ts index 724e376c91..57c5617499 100644 --- a/packages/db-postgres/src/init.ts +++ b/packages/drizzle/src/postgres/init.ts @@ -1,16 +1,15 @@ import type { Init, SanitizedCollectionConfig } from 'payload' -import { createTableName } from '@payloadcms/drizzle' import { uniqueIndex } from 'drizzle-orm/pg-core' import { buildVersionCollectionFields, buildVersionGlobalFields } from 'payload' import toSnakeCase from 'to-snake-case' -import type { BaseExtraConfig } from './schema/build.js' -import type { PostgresAdapter } from './types.js' +import type { BaseExtraConfig, BasePostgresAdapter } from './types.js' +import { createTableName } from '../createTableName.js' import { buildTable } from './schema/build.js' -export const init: Init = function init(this: PostgresAdapter) { +export const init: Init = function init(this: BasePostgresAdapter) { if (this.payload.config.localization) { this.enums.enum__locales = this.pgSchema.enum( '_locales', diff --git a/packages/db-postgres/src/insert.ts b/packages/drizzle/src/postgres/insert.ts similarity index 89% rename from packages/db-postgres/src/insert.ts rename to packages/drizzle/src/postgres/insert.ts index 9f6fd0a06a..fad831d495 100644 --- a/packages/db-postgres/src/insert.ts +++ b/packages/drizzle/src/postgres/insert.ts @@ -1,5 +1,4 @@ -import type { TransactionPg } from '@payloadcms/drizzle/types' - +import type { TransactionPg } from '../types.js' import type { Insert } from './types.js' export const insert: Insert = async function insert({ diff --git a/packages/db-postgres/src/requireDrizzleKit.ts b/packages/drizzle/src/postgres/requireDrizzleKit.ts similarity index 71% rename from packages/db-postgres/src/requireDrizzleKit.ts rename to packages/drizzle/src/postgres/requireDrizzleKit.ts index 505eeaa4b1..c2868e6c34 100644 --- a/packages/db-postgres/src/requireDrizzleKit.ts +++ b/packages/drizzle/src/postgres/requireDrizzleKit.ts @@ -1,5 +1,6 @@ -import type { RequireDrizzleKit } from '@payloadcms/drizzle/types' - import { createRequire } from 'module' + +import type { RequireDrizzleKit } from '../types.js' + const require = createRequire(import.meta.url) export const requireDrizzleKit: RequireDrizzleKit = () => require('drizzle-kit/api') diff --git a/packages/db-postgres/src/schema/build.ts b/packages/drizzle/src/postgres/schema/build.ts similarity index 97% rename from packages/db-postgres/src/schema/build.ts rename to packages/drizzle/src/postgres/schema/build.ts index 52abfd72f8..b10bae1edf 100644 --- a/packages/db-postgres/src/schema/build.ts +++ b/packages/drizzle/src/postgres/schema/build.ts @@ -4,11 +4,9 @@ import type { IndexBuilder, PgColumnBuilder, PgTableWithColumns, - UniqueConstraintBuilder, } from 'drizzle-orm/pg-core' import type { Field } from 'payload' -import { createTableName } from '@payloadcms/drizzle' import { relations } from 'drizzle-orm' import { foreignKey, @@ -22,21 +20,22 @@ import { } from 'drizzle-orm/pg-core' import toSnakeCase from 'to-snake-case' -import type { GenericColumns, GenericTable, IDType, PostgresAdapter } from '../types.js' +import type { + BaseExtraConfig, + BasePostgresAdapter, + GenericColumns, + GenericTable, + IDType, + RelationMap, +} from '../types.js' +import { createTableName } from '../../createTableName.js' import { parentIDColumnMap } from './parentIDColumnMap.js' import { setColumnID } from './setColumnID.js' import { traverseFields } from './traverseFields.js' -export type BaseExtraConfig = Record< - string, - (cols: GenericColumns) => ForeignKeyBuilder | IndexBuilder | UniqueConstraintBuilder -> - -export type RelationMap = Map - type Args = { - adapter: PostgresAdapter + adapter: BasePostgresAdapter baseColumns?: Record /** * After table is created, run these functions to add extra config to the table diff --git a/packages/db-postgres/src/schema/createIndex.ts b/packages/drizzle/src/postgres/schema/createIndex.ts similarity index 100% rename from packages/db-postgres/src/schema/createIndex.ts rename to packages/drizzle/src/postgres/schema/createIndex.ts diff --git a/packages/db-postgres/src/schema/idToUUID.ts b/packages/drizzle/src/postgres/schema/idToUUID.ts similarity index 100% rename from packages/db-postgres/src/schema/idToUUID.ts rename to packages/drizzle/src/postgres/schema/idToUUID.ts diff --git a/packages/db-postgres/src/schema/parentIDColumnMap.ts b/packages/drizzle/src/postgres/schema/parentIDColumnMap.ts similarity index 100% rename from packages/db-postgres/src/schema/parentIDColumnMap.ts rename to packages/drizzle/src/postgres/schema/parentIDColumnMap.ts diff --git a/packages/db-postgres/src/schema/setColumnID.ts b/packages/drizzle/src/postgres/schema/setColumnID.ts similarity index 83% rename from packages/db-postgres/src/schema/setColumnID.ts rename to packages/drizzle/src/postgres/schema/setColumnID.ts index 0d4de2d786..c913c1e9b5 100644 --- a/packages/db-postgres/src/schema/setColumnID.ts +++ b/packages/drizzle/src/postgres/schema/setColumnID.ts @@ -4,9 +4,13 @@ import { numeric, serial, uuid, varchar } from 'drizzle-orm/pg-core' import { type Field, flattenTopLevelFields } from 'payload' import { fieldAffectsData } from 'payload/shared' -import type { IDType, PostgresAdapter } from '../types.js' +import type { BasePostgresAdapter, IDType } from '../types.js' -type Args = { adapter: PostgresAdapter; columns: Record; fields: Field[] } +type Args = { + adapter: BasePostgresAdapter + columns: Record + fields: Field[] +} export const setColumnID = ({ adapter, columns, fields }: Args): IDType => { const idField = flattenTopLevelFields(fields).find( (field) => fieldAffectsData(field) && field.name === 'id', diff --git a/packages/db-postgres/src/schema/traverseFields.ts b/packages/drizzle/src/postgres/schema/traverseFields.ts similarity index 98% rename from packages/db-postgres/src/schema/traverseFields.ts rename to packages/drizzle/src/postgres/schema/traverseFields.ts index 5eb46bcdae..9efa42c546 100644 --- a/packages/db-postgres/src/schema/traverseFields.ts +++ b/packages/drizzle/src/postgres/schema/traverseFields.ts @@ -2,11 +2,6 @@ import type { Relation } from 'drizzle-orm' import type { IndexBuilder, PgColumnBuilder } from 'drizzle-orm/pg-core' import type { Field, TabAsField } from 'payload' -import { - createTableName, - hasLocalesTable, - validateExistingBlockIsIdentical, -} from '@payloadcms/drizzle' import { relations } from 'drizzle-orm' import { PgNumericBuilder, @@ -26,9 +21,17 @@ import { InvalidConfiguration } from 'payload' import { fieldAffectsData, optionIsObject } from 'payload/shared' import toSnakeCase from 'to-snake-case' -import type { GenericColumns, IDType, PostgresAdapter } from '../types.js' -import type { BaseExtraConfig, RelationMap } from './build.js' +import type { + BaseExtraConfig, + BasePostgresAdapter, + GenericColumns, + IDType, + RelationMap, +} from '../types.js' +import { createTableName } from '../../createTableName.js' +import { hasLocalesTable } from '../../utilities/hasLocalesTable.js' +import { validateExistingBlockIsIdentical } from '../../utilities/validateExistingBlockIsIdentical.js' import { buildTable } from './build.js' import { createIndex } from './createIndex.js' import { idToUUID } from './idToUUID.js' @@ -36,7 +39,7 @@ import { parentIDColumnMap } from './parentIDColumnMap.js' import { withDefault } from './withDefault.js' type Args = { - adapter: PostgresAdapter + adapter: BasePostgresAdapter columnPrefix?: string columns: Record disableNotNull: boolean diff --git a/packages/db-postgres/src/schema/withDefault.ts b/packages/drizzle/src/postgres/schema/withDefault.ts similarity index 100% rename from packages/db-postgres/src/schema/withDefault.ts rename to packages/drizzle/src/postgres/schema/withDefault.ts diff --git a/packages/drizzle/src/postgres/types.ts b/packages/drizzle/src/postgres/types.ts new file mode 100644 index 0000000000..419d21e275 --- /dev/null +++ b/packages/drizzle/src/postgres/types.ts @@ -0,0 +1,154 @@ +import type { DrizzleSnapshotJSON } from 'drizzle-kit/api' +import type { + ColumnBaseConfig, + ColumnDataType, + DrizzleConfig, + Relation, + Relations, + SQL, +} from 'drizzle-orm' +import type { NodePgDatabase } from 'drizzle-orm/node-postgres' +import type { + ForeignKeyBuilder, + IndexBuilder, + PgColumn, + PgEnum, + PgInsertOnConflictDoUpdateConfig, + PgSchema, + PgTableWithColumns, + UniqueConstraintBuilder, + pgEnum, +} from 'drizzle-orm/pg-core' +import type { PgTableFn } from 'drizzle-orm/pg-core/table' +import type { Payload, PayloadRequest } from 'payload' +import type { QueryResult } from 'pg' + +import type { Operators } from '../index.js' +import type { BuildQueryJoinAliases, DrizzleAdapter, TransactionPg } from '../types.js' + +export type BaseExtraConfig = Record< + string, + (cols: GenericColumns) => ForeignKeyBuilder | IndexBuilder | UniqueConstraintBuilder +> + +export type RelationMap = Map + +export type GenericColumn = PgColumn< + ColumnBaseConfig, + Record +> + +export type GenericColumns = { + [x: string]: GenericColumn +} + +export type GenericTable = PgTableWithColumns<{ + columns: GenericColumns + dialect: string + name: string + schema: string +}> + +export type GenericEnum = PgEnum<[string, ...string[]]> + +export type GenericRelation = Relations>> + +export type PostgresDB = NodePgDatabase> + +export type CountDistinct = (args: { + db: PostgresDB | TransactionPg + joins: BuildQueryJoinAliases + tableName: string + where: SQL +}) => Promise + +export type DeleteWhere = (args: { + db: PostgresDB | TransactionPg + tableName: string + where: SQL +}) => Promise + +export type DropDatabase = (args: { adapter: BasePostgresAdapter }) => Promise + +export type Execute = (args: { + db?: PostgresDB | TransactionPg + drizzle?: PostgresDB + raw?: string + sql?: SQL +}) => Promise>> + +export type Insert = (args: { + db: PostgresDB | TransactionPg + onConflictDoUpdate?: PgInsertOnConflictDoUpdateConfig + tableName: string + values: Record | Record[] +}) => Promise[]> + +type Schema = + | { + enum: typeof pgEnum + table: PgTableFn + } + | PgSchema + +export type BasePostgresAdapter = { + countDistinct: CountDistinct + defaultDrizzleSnapshot: DrizzleSnapshotJSON + deleteWhere: DeleteWhere + drizzle: PostgresDB + dropDatabase: DropDatabase + enums: Record + execute: Execute + /** + * An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name + * Used for returning properly formed errors from unique fields + */ + fieldConstraints: Record> + idType: 'serial' | 'uuid' + initializing: Promise + insert: Insert + localesSuffix?: string + logger: DrizzleConfig['logger'] + operators: Operators + pgSchema?: Schema + // pool: Pool + // poolOptions: Args['pool'] + prodMigrations?: { + down: (args: MigrateDownArgs) => Promise + name: string + up: (args: MigrateUpArgs) => Promise + }[] + push: boolean + rejectInitializing: () => void + relations: Record + relationshipsSuffix?: string + resolveInitializing: () => void + schemaName?: string + sessions: { + [id: string]: { + db: PostgresDB | TransactionPg + reject: () => Promise + resolve: () => Promise + } + } + tableNameMap: Map + tables: Record + versionsSuffix?: string +} & PostgresDrizzleAdapter + +export type PostgresDrizzleAdapter = Omit< + DrizzleAdapter, + | 'countDistinct' + | 'deleteWhere' + | 'drizzle' + | 'dropDatabase' + | 'execute' + | 'insert' + | 'operators' + | 'relations' +> + +export type IDType = 'integer' | 'numeric' | 'uuid' | 'varchar' + +export type MigrateUpArgs = { payload: Payload; req?: Partial } +export type MigrateDownArgs = { payload: Payload; req?: Partial } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e438ec0d4..b61ce3ed54 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,10 +26,10 @@ importers: version: 29.7.0 '@libsql/client': specifier: 0.6.2 - version: 0.6.2 + version: 0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4) '@next/bundle-analyzer': specifier: 15.0.0-canary.104 - version: 15.0.0-canary.104 + version: 15.0.0-canary.104(bufferutil@4.0.8) '@payloadcms/db-postgres': specifier: workspace:* version: link:packages/db-postgres @@ -107,7 +107,7 @@ importers: version: 0.23.2-df9e596 drizzle-orm: specifier: 0.32.1 - version: 0.32.1(@libsql/client@0.6.2)(@types/pg@8.10.2)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0) + version: 0.32.1(@libsql/client@0.6.2(bufferutil@4.0.8))(@neondatabase/serverless@0.9.4)(@types/pg@8.11.6)(@vercel/postgres@0.9.0)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0) escape-html: specifier: ^1.0.3 version: 1.0.3 @@ -131,7 +131,7 @@ importers: version: 29.7.0(@types/node@20.12.5)(babel-plugin-macros@3.1.0) jest-environment-jsdom: specifier: 29.7.0 - version: 29.7.0 + version: 29.7.0(bufferutil@4.0.8) lint-staged: specifier: 15.2.7 version: 15.2.7 @@ -310,7 +310,7 @@ importers: version: 0.23.2-df9e596 drizzle-orm: specifier: 0.32.1 - version: 0.32.1(@libsql/client@0.6.2)(@types/pg@8.10.2)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0) + version: 0.32.1(@libsql/client@0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(@neondatabase/serverless@0.9.4)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0) pg: specifier: 8.11.3 version: 8.11.3 @@ -347,7 +347,7 @@ importers: dependencies: '@libsql/client': specifier: ^0.6.2 - version: 0.6.2 + version: 0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4) '@payloadcms/drizzle': specifier: workspace:* version: link:../drizzle @@ -359,7 +359,7 @@ importers: version: 0.23.2-df9e596 drizzle-orm: specifier: 0.32.1 - version: 0.32.1(@libsql/client@0.6.2)(@types/pg@8.10.2)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0) + version: 0.32.1(@libsql/client@0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(@neondatabase/serverless@0.9.4)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0) prompts: specifier: 2.4.2 version: 2.4.2 @@ -390,7 +390,7 @@ importers: version: 2.11.2 drizzle-orm: specifier: 0.32.1 - version: 0.32.1(@libsql/client@0.6.2)(@types/pg@8.10.2)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0) + version: 0.32.1(@libsql/client@0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(@neondatabase/serverless@0.9.4)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0) prompts: specifier: 2.4.2 version: 2.4.2 @@ -403,7 +403,7 @@ importers: devDependencies: '@libsql/client': specifier: ^0.6.2 - version: 0.6.2 + version: 0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4) '@payloadcms/eslint-config': specifier: workspace:* version: link:../eslint-config @@ -689,7 +689,7 @@ importers: version: 10.0.0 ws: specifier: ^8.16.0 - version: 8.18.0 + version: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4) devDependencies: '@next/eslint-plugin-next': specifier: ^14.1.0 @@ -3652,6 +3652,9 @@ packages: '@neon-rs/load@0.0.4': resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} + '@neondatabase/serverless@0.9.4': + resolution: {integrity: sha512-D0AXgJh6xkf+XTlsO7iwE2Q1w8981E1cLCPAALMU2YKtkF/1SF6BiAzYARZFYo175ON+b1RNIy9TdSFHm5nteg==} + '@next/bundle-analyzer@15.0.0-canary.104': resolution: {integrity: sha512-p/KzdaP6UCqTXm6cAZC6Ae+hJ4LkcdcoJ9qAeQ5UHQikCk4BB05Tt0WROf/agrj0lzX8bdMLluR24FixXffiLQ==} @@ -4349,6 +4352,9 @@ packages: '@types/pg@8.10.2': resolution: {integrity: sha512-MKFs9P6nJ+LAeHLU3V0cODEOgyThJ3OAnmOlsZsxux6sfQs3HRXR5bBn7xG5DjckEFhTAxsXi7k7cd0pCMxpJw==} + '@types/pg@8.11.6': + resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} + '@types/pluralize@0.0.33': resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} @@ -4523,6 +4529,10 @@ packages: resolution: {integrity: sha512-l0t2KhbOO/I8ZNOl9zypYf1NE0837aO4/CPQNGR/RAxtj8FpdYKjhyUADUXj2gERLQmnhun+teaVs/G7vZJ/TQ==} engines: {node: '>=16.14'} + '@vercel/postgres@0.9.0': + resolution: {integrity: sha512-WiI2g3+ce2g1u1gP41MoDj2DsMuQQ+us7vHobysRixKECGaLHpfTI7DuVZmHU087ozRAGr3GocSyqmWLLo+fig==} + engines: {node: '>=14.6'} + '@vue/compiler-core@3.4.37': resolution: {integrity: sha512-ZDDT/KiLKuCRXyzWecNzC5vTcubGz4LECAtfGPENpo0nrmqJHwuWtRLxk/Sb9RAKtR9iFflFycbkjkY+W/PZUQ==} @@ -4907,6 +4917,10 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + bundle-name@3.0.0: resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} engines: {node: '>=12'} @@ -9233,6 +9247,10 @@ packages: '@types/react': optional: true + utf-8-validate@6.0.4: + resolution: {integrity: sha512-xu9GQDeFp+eZ6LnCywXN/zBancWvOpUMzgjLPSjy4BRHSmTelvn2E0DG0o1sTiw5hkCKBHo8rwSKncfRfv2EEQ==} + engines: {node: '>=6.14.2'} + utf8-byte-length@1.0.5: resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} @@ -12052,10 +12070,10 @@ snapshots: lexical: 0.17.0 yjs: 13.6.18 - '@libsql/client@0.6.2': + '@libsql/client@0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4)': dependencies: '@libsql/core': 0.6.2 - '@libsql/hrana-client': 0.6.2 + '@libsql/hrana-client': 0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4) js-base64: 3.7.7 libsql: 0.3.19 transitivePeerDependencies: @@ -12072,10 +12090,10 @@ snapshots: '@libsql/darwin-x64@0.3.19': optional: true - '@libsql/hrana-client@0.6.2': + '@libsql/hrana-client@0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4)': dependencies: '@libsql/isomorphic-fetch': 0.2.5 - '@libsql/isomorphic-ws': 0.1.5 + '@libsql/isomorphic-ws': 0.1.5(bufferutil@4.0.8)(utf-8-validate@6.0.4) js-base64: 3.7.7 node-fetch: 3.3.2 transitivePeerDependencies: @@ -12084,10 +12102,10 @@ snapshots: '@libsql/isomorphic-fetch@0.2.5': {} - '@libsql/isomorphic-ws@0.1.5': + '@libsql/isomorphic-ws@0.1.5(bufferutil@4.0.8)(utf-8-validate@6.0.4)': dependencies: '@types/ws': 8.5.12 - ws: 8.18.0 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -12144,9 +12162,14 @@ snapshots: '@neon-rs/load@0.0.4': {} - '@next/bundle-analyzer@15.0.0-canary.104': + '@neondatabase/serverless@0.9.4': dependencies: - webpack-bundle-analyzer: 4.10.1 + '@types/pg': 8.11.6 + optional: true + + '@next/bundle-analyzer@15.0.0-canary.104(bufferutil@4.0.8)': + dependencies: + webpack-bundle-analyzer: 4.10.1(bufferutil@4.0.8) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -12986,6 +13009,13 @@ snapshots: pg-protocol: 1.6.1 pg-types: 4.0.2 + '@types/pg@8.11.6': + dependencies: + '@types/node': 20.12.5 + pg-protocol: 1.6.1 + pg-types: 4.0.2 + optional: true + '@types/pluralize@0.0.33': {} '@types/prettier@2.7.3': {} @@ -13216,6 +13246,14 @@ snapshots: is-buffer: 2.0.5 undici: 5.28.4 + '@vercel/postgres@0.9.0': + dependencies: + '@neondatabase/serverless': 0.9.4 + bufferutil: 4.0.8 + utf-8-validate: 6.0.4 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4) + optional: true + '@vue/compiler-core@3.4.37': dependencies: '@babel/parser': 7.25.3 @@ -13713,6 +13751,11 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + bufferutil@4.0.8: + dependencies: + node-gyp-build: 4.8.1 + optional: true + bundle-name@3.0.0: dependencies: run-applescript: 5.0.0 @@ -14258,11 +14301,23 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.32.1(@libsql/client@0.6.2)(@types/pg@8.10.2)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0): + drizzle-orm@0.32.1(@libsql/client@0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4))(@neondatabase/serverless@0.9.4)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0): optionalDependencies: - '@libsql/client': 0.6.2 + '@libsql/client': 0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4) + '@neondatabase/serverless': 0.9.4 '@types/pg': 8.10.2 '@types/react': types-react@19.0.0-rc.0 + '@vercel/postgres': 0.9.0 + pg: 8.11.3 + react: 19.0.0-rc-06d0b89e-20240801 + + drizzle-orm@0.32.1(@libsql/client@0.6.2(bufferutil@4.0.8))(@neondatabase/serverless@0.9.4)(@types/pg@8.11.6)(@vercel/postgres@0.9.0)(pg@8.11.3)(react@19.0.0-rc-06d0b89e-20240801)(types-react@19.0.0-rc.0): + optionalDependencies: + '@libsql/client': 0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4) + '@neondatabase/serverless': 0.9.4 + '@types/pg': 8.11.6 + '@types/react': types-react@19.0.0-rc.0 + '@vercel/postgres': 0.9.0 pg: 8.11.3 react: 19.0.0-rc-06d0b89e-20240801 @@ -15943,7 +15998,7 @@ snapshots: jest-util: 29.7.0 pretty-format: 29.7.0 - jest-environment-jsdom@29.7.0: + jest-environment-jsdom@29.7.0(bufferutil@4.0.8): dependencies: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 @@ -15952,7 +16007,7 @@ snapshots: '@types/node': 20.12.5 jest-mock: 29.7.0 jest-util: 29.7.0 - jsdom: 20.0.3 + jsdom: 20.0.3(bufferutil@4.0.8) transitivePeerDependencies: - bufferutil - supports-color @@ -16199,7 +16254,7 @@ snapshots: jsdoc-type-pratt-parser@4.1.0: {} - jsdom@20.0.3: + jsdom@20.0.3(bufferutil@4.0.8): dependencies: abab: 2.0.6 acorn: 8.12.1 @@ -16225,7 +16280,7 @@ snapshots: whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 whatwg-url: 11.0.0 - ws: 8.18.0 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4) xml-name-validator: 4.0.0 transitivePeerDependencies: - bufferutil @@ -18540,6 +18595,11 @@ snapshots: optionalDependencies: '@types/react': types-react@19.0.0-rc.0 + utf-8-validate@6.0.4: + dependencies: + node-gyp-build: 4.8.1 + optional: true + utf8-byte-length@1.0.5: {} util-deprecate@1.0.2: {} @@ -18590,7 +18650,7 @@ snapshots: webidl-conversions@7.0.0: {} - webpack-bundle-analyzer@4.10.1: + webpack-bundle-analyzer@4.10.1(bufferutil@4.0.8): dependencies: '@discoveryjs/json-ext': 0.5.7 acorn: 8.12.1 @@ -18604,7 +18664,7 @@ snapshots: opener: 1.5.2 picocolors: 1.0.1 sirv: 2.0.4 - ws: 7.5.10 + ws: 7.5.10(bufferutil@4.0.8) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -18698,9 +18758,14 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 - ws@7.5.10: {} + ws@7.5.10(bufferutil@4.0.8): + optionalDependencies: + bufferutil: 4.0.8 - ws@8.18.0: {} + ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 6.0.4 xml-name-validator@4.0.0: {}