From 121b0053cd18f68331e6a8e4267a933bb91b0c0f Mon Sep 17 00:00:00 2001 From: Christopher Gdynia Date: Tue, 31 Mar 2026 13:03:53 +0200 Subject: [PATCH 1/5] feat: add uuidv7 support for pgsql --- packages/db-d1-sqlite/src/index.ts | 2 +- packages/db-postgres/src/types.ts | 2 +- packages/db-sqlite/src/index.ts | 2 +- packages/db-vercel-postgres/src/types.ts | 2 +- packages/drizzle/package.json | 2 +- .../src/postgres/columnToCodeConverter.ts | 5 + .../src/postgres/schema/buildDrizzleTable.ts | 5 + .../src/postgres/schema/setColumnID.ts | 11 + packages/drizzle/src/postgres/types.ts | 2 +- .../src/queries/getTableColumnFromPath.ts | 12 +- .../drizzle/src/queries/sanitizeQueryValue.ts | 3 +- packages/drizzle/src/schema/build.ts | 6 +- packages/drizzle/src/schema/traverseFields.ts | 3 +- .../src/sqlite/columnToCodeConverter.ts | 5 + .../src/sqlite/schema/buildDrizzleTable.ts | 6 +- .../drizzle/src/sqlite/schema/setColumnID.ts | 11 + packages/drizzle/src/sqlite/types.ts | 2 +- packages/drizzle/src/types.ts | 4 +- .../src/utilities/getCollectionIdType.ts | 1 + packages/drizzle/src/utilities/isUUIDType.ts | 1 + payload-types.ts | 305 +++--------------- pnpm-lock.yaml | 22 +- test/database/int.spec.ts | 160 ++++++++- test/generateDatabaseAdapter.ts | 18 ++ test/relationships/int.spec.ts | 3 +- test/uuid-v7/config.ts | 43 +++ test/uuid-v7/int.spec.ts | 142 ++++++++ 27 files changed, 486 insertions(+), 294 deletions(-) create mode 100644 packages/drizzle/src/utilities/isUUIDType.ts create mode 100644 test/uuid-v7/config.ts create mode 100644 test/uuid-v7/int.spec.ts diff --git a/packages/db-d1-sqlite/src/index.ts b/packages/db-d1-sqlite/src/index.ts index 85d8d6d3cee..954dfa6611f 100644 --- a/packages/db-d1-sqlite/src/index.ts +++ b/packages/db-d1-sqlite/src/index.ts @@ -64,7 +64,7 @@ const filename = fileURLToPath(import.meta.url) export function sqliteD1Adapter(args: Args): DatabaseAdapterObj { const sqliteIDType = args.idType || 'number' - const payloadIDType = sqliteIDType === 'uuid' ? 'text' : 'number' + const payloadIDType = sqliteIDType === 'uuid' || sqliteIDType === 'uuidv7' ? 'text' : 'number' const allowIDOnCreate = args.allowIDOnCreate ?? false function adapter({ payload }: { payload: Payload }) { diff --git a/packages/db-postgres/src/types.ts b/packages/db-postgres/src/types.ts index 1fe48b832bd..f60c64de797 100644 --- a/packages/db-postgres/src/types.ts +++ b/packages/db-postgres/src/types.ts @@ -53,7 +53,7 @@ export type Args = { extensions?: string[] /** Generated schema from payload generate:db-schema file path */ generateSchemaOutputFile?: string - idType?: 'serial' | 'uuid' + idType?: 'serial' | 'uuid' | 'uuidv7' localesSuffix?: string logger?: DrizzleConfig['logger'] migrationDir?: string diff --git a/packages/db-sqlite/src/index.ts b/packages/db-sqlite/src/index.ts index 32a7054b164..8a35987a0b1 100644 --- a/packages/db-sqlite/src/index.ts +++ b/packages/db-sqlite/src/index.ts @@ -66,7 +66,7 @@ const filename = fileURLToPath(import.meta.url) export function sqliteAdapter(args: Args): DatabaseAdapterObj { const sqliteIDType = args.idType || 'number' - const payloadIDType = sqliteIDType === 'uuid' ? 'text' : 'number' + const payloadIDType = sqliteIDType === 'uuid' || sqliteIDType === 'uuidv7' ? 'text' : 'number' const allowIDOnCreate = args.allowIDOnCreate ?? false function adapter({ payload }: { payload: Payload }) { diff --git a/packages/db-vercel-postgres/src/types.ts b/packages/db-vercel-postgres/src/types.ts index f0d889f305c..5940582dbe2 100644 --- a/packages/db-vercel-postgres/src/types.ts +++ b/packages/db-vercel-postgres/src/types.ts @@ -53,7 +53,7 @@ export type Args = { forceUseVercelPostgres?: boolean /** Generated schema from payload generate:db-schema file path */ generateSchemaOutputFile?: string - idType?: 'serial' | 'uuid' + idType?: 'serial' | 'uuid' | 'uuidv7' localesSuffix?: string logger?: DrizzleConfig['logger'] migrationDir?: string diff --git a/packages/drizzle/package.json b/packages/drizzle/package.json index 0c71b081979..c7614c9c1ca 100644 --- a/packages/drizzle/package.json +++ b/packages/drizzle/package.json @@ -62,7 +62,7 @@ "drizzle-orm": "0.44.7", "prompts": "2.4.2", "to-snake-case": "1.0.0", - "uuid": "9.0.0" + "uuid": "^11.1.0" }, "devDependencies": { "@libsql/client": "0.14.0", diff --git a/packages/drizzle/src/postgres/columnToCodeConverter.ts b/packages/drizzle/src/postgres/columnToCodeConverter.ts index 430af808f47..508245d266e 100644 --- a/packages/drizzle/src/postgres/columnToCodeConverter.ts +++ b/packages/drizzle/src/postgres/columnToCodeConverter.ts @@ -68,6 +68,11 @@ export const columnToCodeConverter: ColumnToCodeConverter = ({ code = `${code}.defaultRandom()` } + if (column.type === 'uuid' && column.defaultV7) { + addImport('uuid', 'v7 as uuidv7') + code = `${code}.$defaultFn(() => uuidv7())` + } + if (column.notNull) { code = `${code}.notNull()` } diff --git a/packages/drizzle/src/postgres/schema/buildDrizzleTable.ts b/packages/drizzle/src/postgres/schema/buildDrizzleTable.ts index f1bb015a266..833bcb68774 100644 --- a/packages/drizzle/src/postgres/schema/buildDrizzleTable.ts +++ b/packages/drizzle/src/postgres/schema/buildDrizzleTable.ts @@ -18,6 +18,7 @@ import { varchar, vector, } from 'drizzle-orm/pg-core' +import { v7 as uuidv7 } from 'uuid' import type { RawColumn, RawTable } from '../../types.js' import type { BasePostgresAdapter } from '../types.js' @@ -109,6 +110,10 @@ export const buildDrizzleTable = ({ builder = builder.defaultRandom() } + if (column.defaultV7) { + builder = builder.$defaultFn(() => uuidv7()) + } + columns[key] = builder break } diff --git a/packages/drizzle/src/postgres/schema/setColumnID.ts b/packages/drizzle/src/postgres/schema/setColumnID.ts index c2515637d3d..6c8418e665d 100644 --- a/packages/drizzle/src/postgres/schema/setColumnID.ts +++ b/packages/drizzle/src/postgres/schema/setColumnID.ts @@ -34,6 +34,17 @@ export const setColumnID: SetColumnID = ({ adapter, columns, fields }) => { return 'uuid' } + if (adapter.idType === 'uuidv7') { + columns.id = { + name: 'id', + type: 'uuid', + defaultV7: true, + primaryKey: true, + } + + return 'uuid' + } + columns.id = { name: 'id', type: 'serial', diff --git a/packages/drizzle/src/postgres/types.ts b/packages/drizzle/src/postgres/types.ts index 60ed3a0749f..0d5b3c0215b 100644 --- a/packages/drizzle/src/postgres/types.ts +++ b/packages/drizzle/src/postgres/types.ts @@ -147,7 +147,7 @@ export type BasePostgresAdapter = { * Used for returning properly formed errors from unique fields */ fieldConstraints: Record> - idType: 'serial' | 'uuid' + idType: 'serial' | 'uuid' | 'uuidv7' initializing: Promise insert: Insert localesSuffix?: string diff --git a/packages/drizzle/src/queries/getTableColumnFromPath.ts b/packages/drizzle/src/queries/getTableColumnFromPath.ts index f7ac5b26b96..6f6309fa5d4 100644 --- a/packages/drizzle/src/queries/getTableColumnFromPath.ts +++ b/packages/drizzle/src/queries/getTableColumnFromPath.ts @@ -19,6 +19,7 @@ import type { DrizzleAdapter, GenericColumn } from '../types.js' import type { BuildQueryJoinAliases } from './buildQuery.js' import { isPolymorphicRelationship } from '../utilities/isPolymorphicRelationship.js' +import { isUUIDType } from '../utilities/isUUIDType.js' import { jsonBuildObject } from '../utilities/json.js' import { DistinctSymbol } from '../utilities/rawConstraint.js' import { resolveBlockTableName } from '../utilities/validateExistingBlockIsIdentical.js' @@ -111,7 +112,7 @@ export const getTableColumnFromPath = ({ constraints, field: { name: 'id', - type: adapter.idType === 'uuid' ? 'text' : 'number', + type: isUUIDType(adapter.idType) ? 'text' : 'number', } as NumberField | TextField, table: adapter.tables[newTableName], } @@ -414,7 +415,7 @@ export const getTableColumnFromPath = ({ constraints, field: { name: 'id', - type: adapter.idType === 'uuid' ? 'text' : 'number', + type: isUUIDType(adapter.idType) ? 'text' : 'number', } as NumberField | TextField, table: aliasRelationshipTable, } @@ -531,7 +532,7 @@ export const getTableColumnFromPath = ({ constraints, field: { name: 'id', - type: adapter.idType === 'uuid' ? 'text' : 'number', + type: isUUIDType(adapter.idType) ? 'text' : 'number', } as NumberField | TextField, table: newAliasTable, } @@ -706,8 +707,9 @@ export const getTableColumnFromPath = ({ const columns: TableColumn['columns'] = field.relationTo .map((relationTo) => { - let idType: 'number' | 'text' | 'uuid' = - adapter.idType === 'uuid' ? 'uuid' : 'number' + let idType: 'number' | 'text' | 'uuid' = isUUIDType(adapter.idType) + ? 'uuid' + : 'number' const { customIDType } = adapter.payload.collections[relationTo] diff --git a/packages/drizzle/src/queries/sanitizeQueryValue.ts b/packages/drizzle/src/queries/sanitizeQueryValue.ts index 05ba2278021..57ba65905a4 100644 --- a/packages/drizzle/src/queries/sanitizeQueryValue.ts +++ b/packages/drizzle/src/queries/sanitizeQueryValue.ts @@ -8,6 +8,7 @@ import type { DrizzleAdapter } from '../types.js' import { getCollectionIdType } from '../utilities/getCollectionIdType.js' import { isPolymorphicRelationship } from '../utilities/isPolymorphicRelationship.js' +import { isUUIDType } from '../utilities/isUUIDType.js' import { isRawConstraint } from '../utilities/rawConstraint.js' type SanitizeQueryValueArgs = { @@ -59,7 +60,7 @@ export const sanitizeQueryValue = ({ ) { const allPossibleIDTypes: (number | string)[] = [] formattedValue.forEach((val) => { - if (adapter.idType !== 'uuid' && typeof val === 'string') { + if (!isUUIDType(adapter.idType) && typeof val === 'string') { allPossibleIDTypes.push(val, parseInt(val)) } else if (typeof val === 'string') { allPossibleIDTypes.push(val) diff --git a/packages/drizzle/src/schema/build.ts b/packages/drizzle/src/schema/build.ts index 64dcbb2b1f7..4d6d3ffbe95 100644 --- a/packages/drizzle/src/schema/build.ts +++ b/packages/drizzle/src/schema/build.ts @@ -18,6 +18,7 @@ import type { import { createTableName } from '../createTableName.js' import { buildForeignKeyName } from '../utilities/buildForeignKeyName.js' import { buildIndexName } from '../utilities/buildIndexName.js' +import { isUUIDType } from '../utilities/isUUIDType.js' import { traverseFields } from './traverseFields.js' type Args = { @@ -619,8 +620,9 @@ export const buildTable = ({ config: relationshipConfig, throwValidationError: true, }) - let colType: 'integer' | 'numeric' | 'uuid' | 'varchar' = - adapter.idType === 'uuid' ? 'uuid' : 'integer' + let colType: 'integer' | 'numeric' | 'uuid' | 'varchar' = isUUIDType(adapter.idType) + ? 'uuid' + : 'integer' const relatedCollectionCustomIDType = adapter.payload.collections[relationshipConfig.slug]?.customIDType diff --git a/packages/drizzle/src/schema/traverseFields.ts b/packages/drizzle/src/schema/traverseFields.ts index 8834f2c14c5..507abda5571 100644 --- a/packages/drizzle/src/schema/traverseFields.ts +++ b/packages/drizzle/src/schema/traverseFields.ts @@ -24,6 +24,7 @@ import { createTableName } from '../createTableName.js' import { buildIndexName } from '../utilities/buildIndexName.js' import { getArrayRelationName } from '../utilities/getArrayRelationName.js' import { hasLocalesTable } from '../utilities/hasLocalesTable.js' +import { isUUIDType } from '../utilities/isUUIDType.js' import { InternalBlockTableNameIndex, setInternalBlockIndex, @@ -945,7 +946,7 @@ export const traverseFields = ({ const tableName = adapter.tableNameMap.get(toSnakeCase(field.relationTo)) // get the id type of the related collection - let colType: IDType = adapter.idType === 'uuid' ? 'uuid' : 'integer' + let colType: IDType = isUUIDType(adapter.idType) ? 'uuid' : 'integer' const relatedCollectionCustomID = relationshipConfig.fields.find( (field) => fieldAffectsData(field) && field.name === 'id', ) diff --git a/packages/drizzle/src/sqlite/columnToCodeConverter.ts b/packages/drizzle/src/sqlite/columnToCodeConverter.ts index 0f3b53320f7..61b9b838c4b 100644 --- a/packages/drizzle/src/sqlite/columnToCodeConverter.ts +++ b/packages/drizzle/src/sqlite/columnToCodeConverter.ts @@ -69,6 +69,11 @@ export const columnToCodeConverter: ColumnToCodeConverter = ({ defaultStatement = `$defaultFn(() => randomUUID())` } + if (column.defaultV7) { + addImport('uuid', 'v7 as uuidv7') + defaultStatement = `$defaultFn(() => uuidv7())` + } + break } diff --git a/packages/drizzle/src/sqlite/schema/buildDrizzleTable.ts b/packages/drizzle/src/sqlite/schema/buildDrizzleTable.ts index fccd831b318..ae0d5c5f40a 100644 --- a/packages/drizzle/src/sqlite/schema/buildDrizzleTable.ts +++ b/packages/drizzle/src/sqlite/schema/buildDrizzleTable.ts @@ -10,7 +10,7 @@ import { text, uniqueIndex, } from 'drizzle-orm/sqlite-core' -import { v4 as uuidv4 } from 'uuid' +import { v4 as uuidv4, v7 as uuidv7 } from 'uuid' import type { BuildDrizzleTable, RawColumn } from '../../types.js' @@ -72,6 +72,10 @@ export const buildDrizzleTable: BuildDrizzleTable = ({ adapter, locales, rawTabl builder = builder.$defaultFn(() => uuidv4()) } + if (column.defaultV7) { + builder = builder.$defaultFn(() => uuidv7()) + } + columns[key] = builder break } diff --git a/packages/drizzle/src/sqlite/schema/setColumnID.ts b/packages/drizzle/src/sqlite/schema/setColumnID.ts index a28db5ca433..3fbcaba398d 100644 --- a/packages/drizzle/src/sqlite/schema/setColumnID.ts +++ b/packages/drizzle/src/sqlite/schema/setColumnID.ts @@ -34,6 +34,17 @@ export const setColumnID: SetColumnID = ({ adapter, columns, fields }) => { return 'uuid' } + if (adapter.idType === 'uuidv7') { + columns.id = { + name: 'id', + type: 'uuid', + defaultV7: true, + primaryKey: true, + } + + return 'uuid' + } + columns.id = { name: 'id', type: 'integer', diff --git a/packages/drizzle/src/sqlite/types.ts b/packages/drizzle/src/sqlite/types.ts index df182a02d9d..bfccd436217 100644 --- a/packages/drizzle/src/sqlite/types.ts +++ b/packages/drizzle/src/sqlite/types.ts @@ -60,7 +60,7 @@ export type BaseSQLiteArgs = { blocksAsJSON?: boolean /** Generated schema from payload generate:db-schema file path */ generateSchemaOutputFile?: string - idType?: 'number' | 'uuid' + idType?: 'number' | 'uuid' | 'uuidv7' localesSuffix?: string logger?: DrizzleConfig['logger'] migrationDir?: string diff --git a/packages/drizzle/src/types.ts b/packages/drizzle/src/types.ts index e3b4f3513f0..51e2374cd5e 100644 --- a/packages/drizzle/src/types.ts +++ b/packages/drizzle/src/types.ts @@ -248,6 +248,8 @@ export type TimestampRawColumn = { */ export type UUIDRawColumn = { defaultRandom?: boolean + /** App-side UUID v7 default (Postgres & SQLite); mutually exclusive with defaultRandom in practice */ + defaultV7?: boolean type: 'uuid' } & BaseRawColumn @@ -404,7 +406,7 @@ export interface DrizzleAdapter extends BaseDatabaseAdapter { fieldConstraints: Record> foreignKeys: Set - idType: 'serial' | 'uuid' + idType: 'serial' | 'uuid' | 'uuidv7' indexes: Set initializing: Promise insert: Insert diff --git a/packages/drizzle/src/utilities/getCollectionIdType.ts b/packages/drizzle/src/utilities/getCollectionIdType.ts index 13db4390e43..cbf8b9e6322 100644 --- a/packages/drizzle/src/utilities/getCollectionIdType.ts +++ b/packages/drizzle/src/utilities/getCollectionIdType.ts @@ -7,6 +7,7 @@ const typeMap: Record = { serial: 'number', text: 'text', uuid: 'text', + uuidv7: 'text', } export const getCollectionIdType = ({ diff --git a/packages/drizzle/src/utilities/isUUIDType.ts b/packages/drizzle/src/utilities/isUUIDType.ts new file mode 100644 index 00000000000..8b0fa11df11 --- /dev/null +++ b/packages/drizzle/src/utilities/isUUIDType.ts @@ -0,0 +1 @@ +export const isUUIDType = (idType: string): boolean => idType === 'uuid' || idType === 'uuidv7' diff --git a/payload-types.ts b/payload-types.ts index af3d9cabe53..ea29d3c412c 100644 --- a/payload-types.ts +++ b/payload-types.ts @@ -67,10 +67,9 @@ export interface Config { }; blocks: {}; collections: { - relation: Relation; - 'posts-versioned': PostsVersioned; - 'posts-batches': PostsBatch; posts: Post; + categories: Category; + articles: Article; 'payload-kv': PayloadKv; users: User; 'payload-locked-documents': PayloadLockedDocument; @@ -79,10 +78,9 @@ export interface Config { }; collectionsJoins: {}; collectionsSelect: { - relation: RelationSelect | RelationSelect; - 'posts-versioned': PostsVersionedSelect | PostsVersionedSelect; - 'posts-batches': PostsBatchesSelect | PostsBatchesSelect; posts: PostsSelect | PostsSelect; + categories: CategoriesSelect | CategoriesSelect; + articles: ArticlesSelect | ArticlesSelect; 'payload-kv': PayloadKvSelect | PayloadKvSelect; users: UsersSelect | UsersSelect; 'payload-locked-documents': PayloadLockedDocumentsSelect | PayloadLockedDocumentsSelect; @@ -90,18 +88,12 @@ export interface Config { 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; }; db: { - defaultIDType: number; + defaultIDType: string; }; - fallbackLocale: ('false' | 'none' | 'null') | false | null | ('en' | 'fr') | ('en' | 'fr')[]; - globals: { - 'global-versioned': GlobalVersioned; - global: Global; - }; - globalsSelect: { - 'global-versioned': GlobalVersionedSelect | GlobalVersionedSelect; - global: GlobalSelect | GlobalSelect; - }; - locale: 'en' | 'fr'; + fallbackLocale: null; + globals: {}; + globalsSelect: {}; + locale: null; widgets: { collections: CollectionsWidget; }; @@ -131,93 +123,32 @@ export interface UserAuthOperations { } /** * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "relation". - */ -export interface Relation { - id: number; - name?: string | null; - updatedAt: string; - createdAt: string; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "posts-versioned". + * via the `definition` "posts". */ -export interface PostsVersioned { - id: number; +export interface Post { + id: string; title?: string | null; - content?: - | { - text?: string | null; - relation?: (number | null) | Relation; - manyRelations?: (number | Relation)[] | null; - id?: string | null; - blockName?: string | null; - blockType: 'textBlock'; - }[] - | null; updatedAt: string; createdAt: string; - _status?: ('draft' | 'published') | null; } /** * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "posts-batches". + * via the `definition` "categories". */ -export interface PostsBatch { - id: number; - title?: string | null; - content?: - | { - text?: string | null; - id?: string | null; - blockName?: string | null; - blockType: 'textBlock'; - }[] - | null; +export interface Category { + id: string; + name?: string | null; updatedAt: string; createdAt: string; } /** * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "posts". + * via the `definition` "articles". */ -export interface Post { - id: number; +export interface Article { + id: string; title?: string | null; - content?: - | ( - | { - text?: string | null; - select?: ('option1' | 'option2') | null; - relation?: (number | null) | Relation; - manyRelations?: (number | Relation)[] | null; - id?: string | null; - blockName?: string | null; - blockType: 'textBlock'; - } - | { - text?: string | null; - id?: string | null; - blockName?: string | null; - blockType: 'block_second'; - } - | { - text?: string | null; - id?: string | null; - blockName?: string | null; - blockType: 'block_third'; - } - )[] - | null; - localizedContent?: - | { - text?: string | null; - id?: string | null; - blockName?: string | null; - blockType: 'textBlockLocalized'; - }[] - | null; + category?: (string | null) | Category; updatedAt: string; createdAt: string; } @@ -226,7 +157,7 @@ export interface Post { * via the `definition` "payload-kv". */ export interface PayloadKv { - id: number; + id: string; key: string; data: | { @@ -243,7 +174,7 @@ export interface PayloadKv { * via the `definition` "users". */ export interface User { - id: number; + id: string; updatedAt: string; createdAt: string; email: string; @@ -268,32 +199,28 @@ export interface User { * via the `definition` "payload-locked-documents". */ export interface PayloadLockedDocument { - id: number; + id: string; document?: | ({ - relationTo: 'relation'; - value: number | Relation; + relationTo: 'posts'; + value: string | Post; } | null) | ({ - relationTo: 'posts-versioned'; - value: number | PostsVersioned; + relationTo: 'categories'; + value: string | Category; } | null) | ({ - relationTo: 'posts-batches'; - value: number | PostsBatch; - } | null) - | ({ - relationTo: 'posts'; - value: number | Post; + relationTo: 'articles'; + value: string | Article; } | null) | ({ relationTo: 'users'; - value: number | User; + value: string | User; } | null); globalSlug?: string | null; user: { relationTo: 'users'; - value: number | User; + value: string | User; }; updatedAt: string; createdAt: string; @@ -303,10 +230,10 @@ export interface PayloadLockedDocument { * via the `definition` "payload-preferences". */ export interface PayloadPreference { - id: number; + id: string; user: { relationTo: 'users'; - value: number | User; + value: string | User; }; key?: string | null; value?: @@ -326,7 +253,7 @@ export interface PayloadPreference { * via the `definition` "payload-migrations". */ export interface PayloadMigration { - id: number; + id: string; name?: string | null; batch?: number | null; updatedAt: string; @@ -334,101 +261,29 @@ export interface PayloadMigration { } /** * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "relation_select". - */ -export interface RelationSelect { - name?: T; - updatedAt?: T; - createdAt?: T; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "posts-versioned_select". + * via the `definition` "posts_select". */ -export interface PostsVersionedSelect { +export interface PostsSelect { title?: T; - content?: - | T - | { - textBlock?: - | T - | { - text?: T; - relation?: T; - manyRelations?: T; - id?: T; - blockName?: T; - }; - }; updatedAt?: T; createdAt?: T; - _status?: T; } /** * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "posts-batches_select". + * via the `definition` "categories_select". */ -export interface PostsBatchesSelect { - title?: T; - content?: - | T - | { - textBlock?: - | T - | { - text?: T; - id?: T; - blockName?: T; - }; - }; +export interface CategoriesSelect { + name?: T; updatedAt?: T; createdAt?: T; } /** * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "posts_select". + * via the `definition` "articles_select". */ -export interface PostsSelect { +export interface ArticlesSelect { title?: T; - content?: - | T - | { - textBlock?: - | T - | { - text?: T; - select?: T; - relation?: T; - manyRelations?: T; - id?: T; - blockName?: T; - }; - block_second?: - | T - | { - text?: T; - id?: T; - blockName?: T; - }; - block_third?: - | T - | { - text?: T; - id?: T; - blockName?: T; - }; - }; - localizedContent?: - | T - | { - textBlockLocalized?: - | T - | { - text?: T; - id?: T; - blockName?: T; - }; - }; + category?: T; updatedAt?: T; createdAt?: T; } @@ -494,82 +349,6 @@ export interface PayloadMigrationsSelect { updatedAt?: T; createdAt?: T; } -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "global-versioned". - */ -export interface GlobalVersioned { - id: number; - content?: - | { - text?: string | null; - id?: string | null; - blockName?: string | null; - blockType: 'textBlock'; - }[] - | null; - _status?: ('draft' | 'published') | null; - updatedAt?: string | null; - createdAt?: string | null; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "global". - */ -export interface Global { - id: number; - content?: - | { - text?: string | null; - id?: string | null; - blockName?: string | null; - blockType: 'textBlock'; - }[] - | null; - updatedAt?: string | null; - createdAt?: string | null; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "global-versioned_select". - */ -export interface GlobalVersionedSelect { - content?: - | T - | { - textBlock?: - | T - | { - text?: T; - id?: T; - blockName?: T; - }; - }; - _status?: T; - updatedAt?: T; - createdAt?: T; - globalType?: T; -} -/** - * This interface was referenced by `Config`'s JSON-Schema - * via the `definition` "global_select". - */ -export interface GlobalSelect { - content?: - | T - | { - textBlock?: - | T - | { - text?: T; - id?: T; - blockName?: T; - }; - }; - updatedAt?: T; - createdAt?: T; - globalType?: T; -} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "collections_widget". diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f02a6a5d468..c48b5a40a57 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -534,8 +534,8 @@ importers: specifier: 1.0.0 version: 1.0.0 uuid: - specifier: 9.0.0 - version: 9.0.0 + specifier: ^11.1.0 + version: 11.1.0 devDependencies: '@libsql/client': specifier: 0.14.0 @@ -2208,7 +2208,7 @@ importers: version: 16.4.7 geist: specifier: ^1.3.0 - version: 1.7.0(next@16.2.1(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0)) + version: 1.7.0(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0)) graphql: specifier: 16.8.1 version: 16.8.1 @@ -2217,10 +2217,10 @@ importers: version: 0.563.0(react@19.2.4) next: specifier: 16.2.1 - version: 16.2.1(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) + version: 16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) next-sitemap: specifier: ^4.2.3 - version: 4.2.3(next@16.2.1(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0)) + version: 4.2.3(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0)) payload: specifier: workspace:* version: link:../../packages/payload @@ -2281,7 +2281,7 @@ importers: version: 9.39.2(jiti@2.6.1) eslint-config-next: specifier: 16.2.1 - version: 16.2.1(eslint-plugin-import-x@4.6.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3) + version: 16.2.1(@typescript-eslint/parser@8.57.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3))(eslint-plugin-import-x@4.6.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3) jsdom: specifier: 28.0.0 version: 28.0.0(@noble/hashes@1.8.0) @@ -14275,6 +14275,10 @@ packages: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true @@ -26156,13 +26160,13 @@ snapshots: transitivePeerDependencies: - supports-color - next-sitemap@4.2.3(next@16.2.1(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0)): + next-sitemap@4.2.3(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0)): dependencies: '@corex/deepmerge': 4.0.43 '@next/env': 13.5.11 fast-glob: 3.3.3 minimist: 1.2.8 - next: 16.2.1(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) + next: 16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) next-themes@0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: @@ -28718,6 +28722,8 @@ snapshots: uuid@10.0.0: {} + uuid@11.1.0: {} + uuid@8.3.2: {} uuid@9.0.0: {} diff --git a/test/database/int.spec.ts b/test/database/int.spec.ts index fddba2904d7..719440dafb2 100644 --- a/test/database/int.spec.ts +++ b/test/database/int.spec.ts @@ -29,7 +29,7 @@ import { } from 'payload' import { assert } from 'ts-essentials' import { fileURLToPath } from 'url' -import { afterAll, beforeAll, beforeEach, expect } from 'vitest' +import { afterAll, afterEach, beforeAll, beforeEach, expect } from 'vitest' import type { NextRESTClient } from '../__helpers/shared/NextRESTClient.js' import type { Global2, Post } from './payload-types.js' @@ -41,10 +41,13 @@ import { removeFiles } from '../__helpers/shared/removeFiles.js' import { devUser } from '../credentials.js' import { seed } from './seed.js' import { + customIDsSlug, defaultValuesSlug, errorOnUnnamedFieldsSlug, fieldsPersistanceSlug, postsSlug, + relationASlug, + relationBSlug, } from './shared.js' const filename = fileURLToPath(import.meta.url) @@ -231,6 +234,155 @@ describe('database', () => { const resFind = await payload.findByID({ id: res.id, collection: 'posts', depth: 0 }) expect(resFind.categoriesCustomID[0]).toBe(9999) }) + + const describeUuidV7Adapter = + process.env.PAYLOAD_DATABASE === 'postgres-uuidv7' || + process.env.PAYLOAD_DATABASE === 'sqlite-uuidv7' + ? describe + : describe.skip + + describeUuidV7Adapter('uuidv7', () => { + const createdRows: { collection: string; id: number | string }[] = [] + + const track = (collection: string, id: number | string) => { + createdRows.push({ collection, id }) + } + + afterEach(async () => { + for (const { collection, id } of [...createdRows].reverse()) { + try { + await payload.delete({ + collection: collection as + | typeof customIDsSlug + | typeof postsSlug + | typeof relationASlug + | typeof relationBSlug, + id, + }) + } catch { + // ignore: concurrent cleanup or FK already removed + } + } + + createdRows.length = 0 + }) + + it('should generate valid UUID with version 7', async () => { + const doc = await payload.create({ + collection: postsSlug, + data: { title: 'uuidv7 test' }, + }) + + track(postsSlug, doc.id) + + expect(doc.id).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i, + ) + + expect(String(doc.id).charAt(14)).toBe('7') + }) + + it('should generate chronologically ordered IDs', async () => { + const doc1 = await payload.create({ + collection: postsSlug, + data: { title: 'uuidv7 first' }, + }) + const doc2 = await payload.create({ + collection: postsSlug, + data: { title: 'uuidv7 second' }, + }) + + track(postsSlug, doc1.id) + track(postsSlug, doc2.id) + + expect(doc2.id > doc1.id).toBe(true) + }) + + it('should findByID with uuidv7', async () => { + const created = await payload.create({ + collection: postsSlug, + data: { title: 'uuidv7 findable' }, + }) + + track(postsSlug, created.id) + + const found = await payload.findByID({ + collection: postsSlug, + id: created.id, + }) + + expect(found.id).toBe(created.id) + expect(found.title).toBe('uuidv7 findable') + }) + + it('should query with where clause on uuidv7 id', async () => { + const created = await payload.create({ + collection: postsSlug, + data: { title: 'uuidv7 queryable' }, + }) + + track(postsSlug, created.id) + + const result = await payload.find({ + collection: postsSlug, + where: { id: { equals: created.id } }, + }) + + expect(result.docs).toHaveLength(1) + expect(result.docs[0]!.id).toBe(created.id) + }) + + it('should handle relationships with uuidv7 IDs', async () => { + const relA = await payload.create({ + collection: relationASlug, + data: { title: 'uuidv7 rel A' }, + }) + const relB = await payload.create({ + collection: relationBSlug, + data: { + title: 'uuidv7 rel B', + relationship: relA.id, + }, + }) + + track(relationBSlug, relB.id) + track(relationASlug, relA.id) + + const found = await payload.findByID({ + collection: relationBSlug, + id: relB.id, + depth: 1, + }) + + expect(found.relationship).toBeDefined() + }) + + it('should work with versions and uuidv7 adapter', async () => { + const doc = await payload.create({ + collection: customIDsSlug, + data: { title: 'v7 versioned' }, + }) + + track(customIDsSlug, doc.id) + + await payload.update({ + collection: customIDsSlug, + id: doc.id, + data: { title: 'v7 versioned updated' }, + }) + + const versions = await payload.findVersions({ + collection: customIDsSlug, + where: { parent: { equals: doc.id } }, + }) + + expect(versions.totalDocs).toBeGreaterThanOrEqual(1) + }) + + it('defaultIDType should be text for uuidv7', () => { + expect(payload.db.defaultIDType).toBe('text') + }) + }) }) describe('timestamps', () => { @@ -751,7 +903,7 @@ describe('database', () => { let id: any = null if (payload.db.name === 'mongoose') { id = new mongoose.Types.ObjectId().toHexString() - } else if (payload.db.idType === 'uuid') { + } else if (payload.db.idType === 'uuid' || payload.db.idType === 'uuidv7') { id = randomUUID() } else { id = 9999 @@ -766,7 +918,7 @@ describe('database', () => { let id: any = null if (payload.db.name === 'mongoose') { id = new mongoose.Types.ObjectId().toHexString() - } else if (payload.db.idType === 'uuid') { + } else if (payload.db.idType === 'uuid' || payload.db.idType === 'uuidv7') { id = randomUUID() } else { id = 99999 @@ -788,7 +940,7 @@ describe('database', () => { let id: any = null if (payload.db.name === 'mongoose') { id = new mongoose.Types.ObjectId().toHexString() - } else if (payload.db.idType === 'uuid') { + } else if (payload.db.idType === 'uuid' || payload.db.idType === 'uuidv7') { id = randomUUID() } else { id = 999999 diff --git a/test/generateDatabaseAdapter.ts b/test/generateDatabaseAdapter.ts index 18d55767612..90659aa41e0 100644 --- a/test/generateDatabaseAdapter.ts +++ b/test/generateDatabaseAdapter.ts @@ -86,6 +86,15 @@ export const allDatabaseAdapters = { connectionString: process.env.POSTGRES_URL || process.env.DATABASE_URL || '${defaultPostgresUrl}', }, })`, + 'postgres-uuidv7': ` + import { postgresAdapter } from '@payloadcms/db-postgres' + + export const databaseAdapter = postgresAdapter({ + idType: 'uuidv7', + pool: { + connectionString: process.env.POSTGRES_URL || process.env.DATABASE_URL || '${defaultPostgresUrl}', + }, + })`, 'postgres-read-replica': ` import { postgresAdapter } from '@payloadcms/db-postgres' @@ -146,6 +155,15 @@ export const databaseAdapter = contentAPIAdapter({ url: process.env.SQLITE_URL || process.env.DATABASE_URL || 'file:./payload.db', } })`, + 'sqlite-uuidv7': ` + import { sqliteAdapter } from '@payloadcms/db-sqlite' + + export const databaseAdapter = sqliteAdapter({ + idType: 'uuidv7', + client: { + url: process.env.SQLITE_URL || process.env.DATABASE_URL || 'file:./payload.db', + } + })`, supabase: ` import { postgresAdapter } from '@payloadcms/db-postgres' diff --git a/test/relationships/int.spec.ts b/test/relationships/int.spec.ts index 146cb671b52..930f5456cb8 100644 --- a/test/relationships/int.spec.ts +++ b/test/relationships/int.spec.ts @@ -1812,7 +1812,8 @@ describe('Relationships', () => { polymorphic: { equals: { relationTo: 'movies', - value: payload.db.idType === 'uuid' ? randomUUID() : 99, + value: + payload.db.idType === 'uuid' || payload.db.idType === 'uuidv7' ? randomUUID() : 99, }, }, }, diff --git a/test/uuid-v7/config.ts b/test/uuid-v7/config.ts new file mode 100644 index 00000000000..face6bbf2cf --- /dev/null +++ b/test/uuid-v7/config.ts @@ -0,0 +1,43 @@ +import type { PostgresAdapter } from '@payloadcms/db-postgres' +import type { DatabaseAdapterObj } from 'payload' + +import path from 'path' +import { buildConfig } from 'payload' +import { fileURLToPath } from 'url' + +const dirname = path.dirname(fileURLToPath(import.meta.url)) + +const { databaseAdapter } = (await import(path.resolve(dirname, '../databaseAdapter.js'))) as { + databaseAdapter: DatabaseAdapterObj +} + +export default await buildConfig({ + db: databaseAdapter, + secret: 'uuid-v7-test-secret', + admin: { + importMap: { + baseDir: path.resolve(dirname), + }, + }, + collections: [ + { + slug: 'posts', + fields: [{ name: 'title', type: 'text' }], + }, + { + slug: 'categories', + fields: [{ name: 'name', type: 'text' }], + }, + { + slug: 'articles', + fields: [ + { name: 'title', type: 'text' }, + { + name: 'category', + type: 'relationship', + relationTo: 'categories', + }, + ], + }, + ], +}) diff --git a/test/uuid-v7/int.spec.ts b/test/uuid-v7/int.spec.ts new file mode 100644 index 00000000000..c427747bb58 --- /dev/null +++ b/test/uuid-v7/int.spec.ts @@ -0,0 +1,142 @@ +import type { Payload } from 'payload' + +import path from 'path' +import { fileURLToPath } from 'url' +import { validate as uuidValidate } from 'uuid' +import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest' + +import { initPayloadInt } from '../__helpers/shared/initPayloadInt.js' + +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) + +process.env.PAYLOAD_CONFIG_PATH = path.join(dirname, 'config.ts') + +type UuidV7Collection = 'articles' | 'categories' | 'posts' + +const describeUuidV7 = process.env.PAYLOAD_DATABASE === 'postgres-uuidv7' ? describe : describe.skip + +describeUuidV7('UUID v7 idType (postgres)', () => { + let payload: Payload + + /** Created in order; deleted in reverse (articles → categories → posts). */ + const createdStack: { collection: UuidV7Collection; id: string }[] = [] + + const track = (collection: UuidV7Collection, id: string) => { + createdStack.push({ collection, id }) + } + + beforeAll(async () => { + ;({ payload } = await initPayloadInt(dirname)) + }) + + afterEach(async () => { + if (!payload) { + return + } + + for (const { collection, id } of [...createdStack].reverse()) { + try { + await payload.delete({ collection, id }) + } catch { + // ignore: already deleted or FK race + } + } + + createdStack.length = 0 + }) + + afterAll(async () => { + if (payload) { + await payload.destroy() + } + }) + + it('should expose uuidv7 adapter idType', () => { + expect(payload.db.idType).toBe('uuidv7') + }) + + it('should create a document with a valid UUID v7 default id', async () => { + const doc = await payload.create({ + collection: 'posts', + data: { title: 'uuid v7 post' }, + }) + + track('posts', String(doc.id)) + + expect(typeof doc.id).toBe('string') + expect(uuidValidate(doc.id)).toBe(true) + expect(doc.id).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i) + expect(doc.id.charAt(14)).toBe('7') + }) + + it('should order ids lexicographically for consecutive creates', async () => { + const first = await payload.create({ + collection: 'posts', + data: { title: 'first' }, + }) + const second = await payload.create({ + collection: 'posts', + data: { title: 'second' }, + }) + + track('posts', String(first.id)) + track('posts', String(second.id)) + + expect(second.id > first.id).toBe(true) + }) + + it('should findByID with generated id', async () => { + const created = await payload.create({ + collection: 'posts', + data: { title: 'find me' }, + }) + + track('posts', String(created.id)) + + const found = await payload.findByID({ + collection: 'posts', + id: created.id, + }) + + expect(found.id).toBe(created.id) + expect(found.title).toBe('find me') + }) + + it('should resolve relationship to category', async () => { + const category = await payload.create({ + collection: 'categories', + data: { name: 'Cat A' }, + }) + const article = await payload.create({ + collection: 'articles', + data: { + title: 'Article 1', + category: category.id, + }, + depth: 1, + }) + + track('articles', String(article.id)) + track('categories', String(category.id)) + + expect(article.category).toMatchObject({ id: category.id }) + }) + + it('should query by id equals', async () => { + const created = await payload.create({ + collection: 'posts', + data: { title: 'query by id' }, + }) + + track('posts', String(created.id)) + + const res = await payload.find({ + collection: 'posts', + where: { id: { equals: created.id } }, + }) + + expect(res.docs).toHaveLength(1) + expect(res.docs[0].id).toBe(created.id) + }) +}) From f5d447553c06ac72a333306b9b55215d1745fc4d Mon Sep 17 00:00:00 2001 From: Christopher Gdynia Date: Wed, 1 Apr 2026 17:13:11 +0200 Subject: [PATCH 2/5] chore: update ci tests --- .github/workflows/int.config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/int.config.ts b/.github/workflows/int.config.ts index c1da1a41f50..7c490fa1b4c 100644 --- a/.github/workflows/int.config.ts +++ b/.github/workflows/int.config.ts @@ -10,10 +10,12 @@ createIntConfig({ 'postgres', 'postgres-custom-schema', 'postgres-uuid', + 'postgres-uuidv7', 'postgres-read-replica', 'supabase', 'sqlite', 'sqlite-uuid', + 'sqlite-uuidv7', ], shards: 3, }) From 8798a5eb10aba497a54df51322bb2606a9f2aed8 Mon Sep 17 00:00:00 2001 From: Christopher Gdynia Date: Wed, 1 Apr 2026 19:13:09 +0200 Subject: [PATCH 3/5] fix: pnpm lock file after rebase --- pnpm-lock.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c48b5a40a57..f2aea132dc1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1876,7 +1876,7 @@ importers: version: 16.8.1 next: specifier: 16.2.1 - version: 16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) + version: 16.2.1(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) payload: specifier: workspace:* version: link:../../packages/payload @@ -1913,7 +1913,7 @@ importers: version: 9.39.2(jiti@2.6.1) eslint-config-next: specifier: 16.2.1 - version: 16.2.1(@typescript-eslint/parser@8.57.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3))(eslint-plugin-import-x@4.6.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3) + version: 16.2.1(eslint-plugin-import-x@4.6.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.7.3) jsdom: specifier: 28.0.0 version: 28.0.0(@noble/hashes@1.8.0) @@ -24562,6 +24562,10 @@ snapshots: - encoding - supports-color + geist@1.7.0(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0)): + dependencies: + next: 16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) + geist@1.7.0(next@16.2.1(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0)): dependencies: next: 16.2.1(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0) From 5a49b73eb4c7db8bc480ea35168d8aa20134467b Mon Sep 17 00:00:00 2001 From: Christopher Gdynia Date: Wed, 1 Apr 2026 22:19:04 +0200 Subject: [PATCH 4/5] fix: commit generated test files --- test/_community/payload-types.ts | 13 ++ test/database/payload-types.ts | 201 +++++++++++++++++-------------- 2 files changed, 124 insertions(+), 90 deletions(-) diff --git a/test/_community/payload-types.ts b/test/_community/payload-types.ts index 944c99099f4..d4b81957515 100644 --- a/test/_community/payload-types.ts +++ b/test/_community/payload-types.ts @@ -96,6 +96,9 @@ export interface Config { menu: MenuSelect | MenuSelect; }; locale: null; + widgets: { + collections: CollectionsWidget; + }; user: User; jobs: { tasks: unknown; @@ -435,6 +438,16 @@ export interface MenuSelect { createdAt?: T; globalType?: T; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "collections_widget". + */ +export interface CollectionsWidget { + data?: { + [k: string]: unknown; + }; + width: 'full'; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "auth". diff --git a/test/database/payload-types.ts b/test/database/payload-types.ts index ff6941aff96..8d5991b0546 100644 --- a/test/database/payload-types.ts +++ b/test/database/payload-types.ts @@ -138,7 +138,7 @@ export interface Config { 'payload-migrations': PayloadMigrationsSelect | PayloadMigrationsSelect; }; db: { - defaultIDType: number; + defaultIDType: string; }; fallbackLocale: ('false' | 'none' | 'null') | false | null | ('en' | 'es' | 'uk') | ('en' | 'es' | 'uk')[]; globals: { @@ -188,7 +188,7 @@ export interface UserAuthOperations { * via the `definition` "noTimeStamps". */ export interface NoTimeStamp { - id: number; + id: string; title?: string | null; } /** @@ -196,12 +196,12 @@ export interface NoTimeStamp { * via the `definition` "categories". */ export interface Category { - id: number; + id: string; title?: string | null; - simple?: (number | null) | Simple; + simple?: (string | null) | Simple; hideout?: { camera1?: { - time1Image?: (number | null) | Post; + time1Image?: (string | null) | Post; }; }; updatedAt: string; @@ -213,7 +213,7 @@ export interface Category { * via the `definition` "simple". */ export interface Simple { - id: number; + id: string; text?: string | null; number?: number | null; updatedAt: string; @@ -224,9 +224,9 @@ export interface Simple { * via the `definition` "posts". */ export interface Post { - id: number; + id: string; title: string; - category?: (number | null) | Category; + category?: (string | null) | Category; categoryID?: | { [k: string]: unknown; @@ -238,16 +238,16 @@ export interface Post { | null; categoryTitle?: string | null; categorySimpleText?: string | null; - categories?: (number | Category)[] | null; + categories?: (string | Category)[] | null; categoriesCustomID?: (number | CategoriesCustomId)[] | null; categoryPoly?: { relationTo: 'categories'; - value: number | Category; + value: string | Category; } | null; categoryPolyMany?: | { relationTo: 'categories'; - value: number | Category; + value: string | Category; }[] | null; categoryCustomID?: (number | null) | CategoriesCustomId; @@ -255,11 +255,11 @@ export interface Post { | ( | { relationTo: 'categories'; - value: number | Category; + value: string | Category; } | { relationTo: 'simple'; - value: number | Simple; + value: string | Simple; } )[] | null; @@ -267,11 +267,11 @@ export interface Post { | ( | { relationTo: 'categories'; - value: number | Category; + value: string | Category; } | { relationTo: 'simple'; - value: number | Simple; + value: string | Simple; } )[] | null; @@ -301,11 +301,11 @@ export interface Post { | ( | { relationTo: 'categories'; - value: number | Category; + value: string | Category; } | { relationTo: 'simple'; - value: number | Simple; + value: string | Simple; } )[] | null; @@ -367,7 +367,7 @@ export interface CategoriesCustomId { * via the `definition` "simple-localized". */ export interface SimpleLocalized { - id: number; + id: string; text?: string | null; number?: number | null; updatedAt: string; @@ -378,7 +378,7 @@ export interface SimpleLocalized { * via the `definition` "error-on-unnamed-fields". */ export interface ErrorOnUnnamedField { - id: number; + id: string; groupWithinUnnamedTab: { text: string; }; @@ -390,7 +390,7 @@ export interface ErrorOnUnnamedField { * via the `definition` "default-values". */ export interface DefaultValue { - id: number; + id: string; title?: string | null; defaultValue?: string | null; array?: @@ -417,7 +417,7 @@ export interface DefaultValue { * via the `definition` "relation-a". */ export interface RelationA { - id: number; + id: string; title?: string | null; richText?: { root: { @@ -442,9 +442,9 @@ export interface RelationA { * via the `definition` "relation-b". */ export interface RelationB { - id: number; + id: string; title?: string | null; - relationship?: (number | null) | RelationA; + relationship?: (string | null) | RelationA; richText?: { root: { type: string; @@ -468,14 +468,14 @@ export interface RelationB { * via the `definition` "pg-migrations". */ export interface PgMigration { - id: number; - relation1?: (number | null) | RelationA; + id: string; + relation1?: (string | null) | RelationA; myArray?: | { - relation2?: (number | null) | RelationB; + relation2?: (string | null) | RelationB; mySubArray?: | { - relation3?: (number | null) | RelationB; + relation3?: (string | null) | RelationB; id?: string | null; }[] | null; @@ -483,12 +483,12 @@ export interface PgMigration { }[] | null; myGroup?: { - relation4?: (number | null) | RelationB; + relation4?: (string | null) | RelationB; }; myBlocks?: | { - relation5?: (number | null) | RelationA; - relation6?: (number | null) | RelationB; + relation5?: (string | null) | RelationA; + relation6?: (string | null) | RelationB; id?: string | null; blockName?: string | null; blockType: 'myBlock'; @@ -502,10 +502,10 @@ export interface PgMigration { * via the `definition` "custom-schema". */ export interface CustomSchema { - id: number; + id: string; text?: string | null; localizedText?: string | null; - relationship?: (number | RelationA)[] | null; + relationship?: (string | RelationA)[] | null; select?: ('a' | 'b' | 'c')[] | null; radio?: ('a' | 'b' | 'c') | null; array?: @@ -533,7 +533,7 @@ export interface CustomSchema { * via the `definition` "places". */ export interface Place { - id: number; + id: string; country?: string | null; city?: string | null; updatedAt: string; @@ -544,7 +544,7 @@ export interface Place { * via the `definition` "virtual-relations". */ export interface VirtualRelation { - id: number; + id: string; postTitle?: string | null; postsTitles?: string[] | null; postCategoriesTitles?: string[] | null; @@ -570,8 +570,8 @@ export interface VirtualRelation { | boolean | null; postLocalized?: string | null; - post?: (number | null) | Post; - posts?: (number | Post)[] | null; + post?: (string | null) | Post; + posts?: (string | Post)[] | null; customID?: (string | null) | CustomId; customIDValue?: string | null; updatedAt: string; @@ -594,7 +594,7 @@ export interface CustomId { * via the `definition` "fields-persistance". */ export interface FieldsPersistance { - id: number; + id: string; text?: string | null; textHooked?: string | null; array?: @@ -605,6 +605,15 @@ export interface FieldsPersistance { textWithinRow?: string | null; textWithinCollapsible?: string | null; textWithinTabs?: string | null; + blockWithVirtual?: + | { + text?: string | null; + virtualField?: string | null; + id?: string | null; + blockName?: string | null; + blockType: 'blockWithVirtual'; + }[] + | null; updatedAt: string; createdAt: string; } @@ -613,7 +622,7 @@ export interface FieldsPersistance { * via the `definition` "fake-custom-ids". */ export interface FakeCustomId { - id: number; + id: string; title?: string | null; group?: { id?: string | null; @@ -629,11 +638,11 @@ export interface FakeCustomId { * via the `definition` "relationships-migration". */ export interface RelationshipsMigration { - id: number; - relationship?: (number | null) | DefaultValue; + id: string; + relationship?: (string | null) | DefaultValue; relationship_2?: { relationTo: 'default-values'; - value: number | DefaultValue; + value: string | DefaultValue; } | null; updatedAt: string; createdAt: string; @@ -643,7 +652,7 @@ export interface RelationshipsMigration { * via the `definition` "compound-indexes". */ export interface CompoundIndex { - id: number; + id: string; one?: string | null; two?: string | null; three?: string | null; @@ -658,7 +667,7 @@ export interface CompoundIndex { * via the `definition` "aliases". */ export interface Alias { - id: number; + id: string; thisIsALongFieldNameThatCanCauseAPostgresErrorEvenThoughWeSetAShorterDBName?: | { nestedArray?: @@ -678,7 +687,7 @@ export interface Alias { * via the `definition` "blocks-docs". */ export interface BlocksDoc { - id: number; + id: string; testBlocksLocalized?: | { text?: string | null; @@ -703,7 +712,7 @@ export interface BlocksDoc { * via the `definition` "unique-fields". */ export interface UniqueField { - id: number; + id: string; slugField?: string | null; updatedAt: string; createdAt: string; @@ -713,7 +722,7 @@ export interface UniqueField { * via the `definition` "select-has-many". */ export interface SelectHasMany { - id: number; + id: string; roles?: ('user' | 'admin' | 'editor')[] | null; food?: ('apple' | 'bananabread' | 'banana')[] | null; updatedAt: string; @@ -724,7 +733,7 @@ export interface SelectHasMany { * via the `definition` "virtual-linked-tenants". */ export interface VirtualLinkedTenant { - id: number; + id: string; slug: string; updatedAt: string; createdAt: string; @@ -734,9 +743,9 @@ export interface VirtualLinkedTenant { * via the `definition` "virtual-linked-roles". */ export interface VirtualLinkedRole { - id: number; - project: number | VirtualLinkedProject; - tenant: number | VirtualLinkedTenant; + id: string; + project: string | VirtualLinkedProject; + tenant: string | VirtualLinkedTenant; tenantSlug?: string | null; updatedAt: string; createdAt: string; @@ -746,9 +755,9 @@ export interface VirtualLinkedRole { * via the `definition` "virtual-linked-projects". */ export interface VirtualLinkedProject { - id: number; + id: string; roles?: { - docs?: (number | VirtualLinkedRole)[]; + docs?: (string | VirtualLinkedRole)[]; hasNextPage?: boolean; totalDocs?: number; }; @@ -760,7 +769,7 @@ export interface VirtualLinkedProject { * via the `definition` "payload-kv". */ export interface PayloadKv { - id: number; + id: string; key: string; data: | { @@ -777,7 +786,7 @@ export interface PayloadKv { * via the `definition` "users". */ export interface User { - id: number; + id: string; updatedAt: string; createdAt: string; email: string; @@ -802,23 +811,23 @@ export interface User { * via the `definition` "payload-locked-documents". */ export interface PayloadLockedDocument { - id: number; + id: string; document?: | ({ relationTo: 'noTimeStamps'; - value: number | NoTimeStamp; + value: string | NoTimeStamp; } | null) | ({ relationTo: 'categories'; - value: number | Category; + value: string | Category; } | null) | ({ relationTo: 'simple'; - value: number | Simple; + value: string | Simple; } | null) | ({ relationTo: 'simple-localized'; - value: number | SimpleLocalized; + value: string | SimpleLocalized; } | null) | ({ relationTo: 'categories-custom-id'; @@ -826,43 +835,43 @@ export interface PayloadLockedDocument { } | null) | ({ relationTo: 'posts'; - value: number | Post; + value: string | Post; } | null) | ({ relationTo: 'error-on-unnamed-fields'; - value: number | ErrorOnUnnamedField; + value: string | ErrorOnUnnamedField; } | null) | ({ relationTo: 'default-values'; - value: number | DefaultValue; + value: string | DefaultValue; } | null) | ({ relationTo: 'relation-a'; - value: number | RelationA; + value: string | RelationA; } | null) | ({ relationTo: 'relation-b'; - value: number | RelationB; + value: string | RelationB; } | null) | ({ relationTo: 'pg-migrations'; - value: number | PgMigration; + value: string | PgMigration; } | null) | ({ relationTo: 'custom-schema'; - value: number | CustomSchema; + value: string | CustomSchema; } | null) | ({ relationTo: 'places'; - value: number | Place; + value: string | Place; } | null) | ({ relationTo: 'virtual-relations'; - value: number | VirtualRelation; + value: string | VirtualRelation; } | null) | ({ relationTo: 'fields-persistance'; - value: number | FieldsPersistance; + value: string | FieldsPersistance; } | null) | ({ relationTo: 'custom-ids'; @@ -870,52 +879,52 @@ export interface PayloadLockedDocument { } | null) | ({ relationTo: 'fake-custom-ids'; - value: number | FakeCustomId; + value: string | FakeCustomId; } | null) | ({ relationTo: 'relationships-migration'; - value: number | RelationshipsMigration; + value: string | RelationshipsMigration; } | null) | ({ relationTo: 'compound-indexes'; - value: number | CompoundIndex; + value: string | CompoundIndex; } | null) | ({ relationTo: 'aliases'; - value: number | Alias; + value: string | Alias; } | null) | ({ relationTo: 'blocks-docs'; - value: number | BlocksDoc; + value: string | BlocksDoc; } | null) | ({ relationTo: 'unique-fields'; - value: number | UniqueField; + value: string | UniqueField; } | null) | ({ relationTo: 'select-has-many'; - value: number | SelectHasMany; + value: string | SelectHasMany; } | null) | ({ relationTo: 'virtual-linked-tenants'; - value: number | VirtualLinkedTenant; + value: string | VirtualLinkedTenant; } | null) | ({ relationTo: 'virtual-linked-roles'; - value: number | VirtualLinkedRole; + value: string | VirtualLinkedRole; } | null) | ({ relationTo: 'virtual-linked-projects'; - value: number | VirtualLinkedProject; + value: string | VirtualLinkedProject; } | null) | ({ relationTo: 'users'; - value: number | User; + value: string | User; } | null); globalSlug?: string | null; user: { relationTo: 'users'; - value: number | User; + value: string | User; }; updatedAt: string; createdAt: string; @@ -925,10 +934,10 @@ export interface PayloadLockedDocument { * via the `definition` "payload-preferences". */ export interface PayloadPreference { - id: number; + id: string; user: { relationTo: 'users'; - value: number | User; + value: string | User; }; key?: string | null; value?: @@ -948,7 +957,7 @@ export interface PayloadPreference { * via the `definition` "payload-migrations". */ export interface PayloadMigration { - id: number; + id: string; name?: string | null; batch?: number | null; updatedAt: string; @@ -1291,6 +1300,18 @@ export interface FieldsPersistanceSelect { textWithinRow?: T; textWithinCollapsible?: T; textWithinTabs?: T; + blockWithVirtual?: + | T + | { + blockWithVirtual?: + | T + | { + text?: T; + virtualField?: T; + id?: T; + blockName?: T; + }; + }; updatedAt?: T; createdAt?: T; } @@ -1514,7 +1535,7 @@ export interface PayloadMigrationsSelect { * via the `definition` "header". */ export interface Header { - id: number; + id: string; itemsLvl1?: | { label?: string | null; @@ -1547,7 +1568,7 @@ export interface Header { * via the `definition` "global". */ export interface Global { - id: number; + id: string; text?: string | null; updatedAt?: string | null; createdAt?: string | null; @@ -1557,7 +1578,7 @@ export interface Global { * via the `definition` "global-2". */ export interface Global2 { - id: number; + id: string; text?: string | null; updatedAt?: string | null; createdAt?: string | null; @@ -1567,7 +1588,7 @@ export interface Global2 { * via the `definition` "global-3". */ export interface Global3 { - id: number; + id: string; text?: string | null; updatedAt?: string | null; createdAt?: string | null; @@ -1577,9 +1598,9 @@ export interface Global3 { * via the `definition` "virtual-relation-global". */ export interface VirtualRelationGlobal { - id: number; + id: string; postTitle?: string | null; - post?: (number | null) | Post; + post?: (string | null) | Post; updatedAt?: string | null; createdAt?: string | null; } From c0c5101e73e6e231f5de2ca327ec18daad2e6386 Mon Sep 17 00:00:00 2001 From: Christopher Gdynia Date: Mon, 6 Apr 2026 14:01:15 +0200 Subject: [PATCH 5/5] chore: try fix tests --- .github/actions/start-database/action.yml | 2 +- CONTRIBUTING.md | 2 + packages/db-d1-sqlite/package.json | 3 +- packages/db-mongodb/package.json | 3 +- packages/db-postgres/package.json | 2 +- packages/db-sqlite/package.json | 3 +- packages/db-vercel-postgres/package.json | 2 +- packages/drizzle/package.json | 2 +- packages/next/package.json | 3 +- packages/payload/package.json | 3 +- packages/plugin-stripe/package.json | 3 +- packages/richtext-lexical/package.json | 3 +- packages/ui/package.json | 3 +- pnpm-lock.yaml | 87 +++++++---------------- test/custom-graphql/int.spec.ts | 6 +- test/database/int.spec.ts | 4 +- test/package.json | 2 +- 17 files changed, 48 insertions(+), 85 deletions(-) diff --git a/.github/actions/start-database/action.yml b/.github/actions/start-database/action.yml index e5e2ca3b6cd..8e8f5a8cdce 100644 --- a/.github/actions/start-database/action.yml +++ b/.github/actions/start-database/action.yml @@ -3,7 +3,7 @@ description: Starts the required database for tests inputs: database: - description: 'Database type: mongodb, mongodb-atlas, cosmosdb, documentdb, firestore, postgres, postgres-custom-schema, postgres-uuid, postgres-read-replica, postgres-read-replicas, vercel-postgres-read-replica, sqlite, sqlite-uuid, supabase, d1' + description: 'Database type: mongodb, mongodb-atlas, cosmosdb, documentdb, firestore, postgres, postgres-custom-schema, postgres-uuid, postgres-uuidv7, postgres-read-replica, postgres-read-replicas, vercel-postgres-read-replica, sqlite, sqlite-uuid, sqlite-uuidv7, supabase, d1' required: true outputs: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6f9cc45a35e..3743ac887ca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -134,9 +134,11 @@ Set `PAYLOAD_DATABASE` in your `.env` file to choose the database adapter: - `postgres` - PostgreSQL with pgvector and PostGIS - `postgres-custom-schema` - PostgreSQL with custom schema - `postgres-uuid` - PostgreSQL with UUID primary keys +- `postgres-uuidv7` - PostgreSQL with UUID V7 primary keys - `postgres-read-replica` - PostgreSQL with read replica - `sqlite` - SQLite - `sqlite-uuid` - SQLite with UUID primary keys +- `sqlite-uuidv7` - SQLite with UUID V7 primary keys - `supabase` - Supabase (PostgreSQL) - `d1` - D1 (SQLite) diff --git a/packages/db-d1-sqlite/package.json b/packages/db-d1-sqlite/package.json index 7b680446408..06ad9223bc5 100644 --- a/packages/db-d1-sqlite/package.json +++ b/packages/db-d1-sqlite/package.json @@ -77,13 +77,12 @@ "drizzle-orm": "0.44.7", "prompts": "2.4.2", "to-snake-case": "1.0.0", - "uuid": "9.0.0" + "uuid": "11.1.0" }, "devDependencies": { "@payloadcms/eslint-config": "workspace:*", "@types/pg": "8.10.2", "@types/to-snake-case": "1.0.0", - "@types/uuid": "10.0.0", "payload": "workspace:*" }, "peerDependencies": { diff --git a/packages/db-mongodb/package.json b/packages/db-mongodb/package.json index b92f5f6120e..93b5d0559a7 100644 --- a/packages/db-mongodb/package.json +++ b/packages/db-mongodb/package.json @@ -55,13 +55,12 @@ "mongoose": "8.15.1", "mongoose-paginate-v2": "1.8.5", "prompts": "2.4.2", - "uuid": "10.0.0" + "uuid": "11.1.0" }, "devDependencies": { "@payloadcms/eslint-config": "workspace:*", "@types/mongoose-aggregate-paginate-v2": "1.0.12", "@types/prompts": "^2.4.5", - "@types/uuid": "10.0.0", "mongodb": "6.16.0", "mongodb-memory-server": "10.1.4", "payload": "workspace:*" diff --git a/packages/db-postgres/package.json b/packages/db-postgres/package.json index 1ad878be16a..3ec0a4be14d 100644 --- a/packages/db-postgres/package.json +++ b/packages/db-postgres/package.json @@ -82,7 +82,7 @@ "pg": "8.16.3", "prompts": "2.4.2", "to-snake-case": "1.0.0", - "uuid": "10.0.0" + "uuid": "11.1.0" }, "devDependencies": { "@hyrious/esbuild-plugin-commonjs": "0.2.6", diff --git a/packages/db-sqlite/package.json b/packages/db-sqlite/package.json index 0ed8d547b8d..1672c4e379e 100644 --- a/packages/db-sqlite/package.json +++ b/packages/db-sqlite/package.json @@ -79,13 +79,12 @@ "drizzle-orm": "0.44.7", "prompts": "2.4.2", "to-snake-case": "1.0.0", - "uuid": "9.0.0" + "uuid": "11.1.0" }, "devDependencies": { "@payloadcms/eslint-config": "workspace:*", "@types/pg": "8.10.2", "@types/to-snake-case": "1.0.0", - "@types/uuid": "10.0.0", "payload": "workspace:*" }, "peerDependencies": { diff --git a/packages/db-vercel-postgres/package.json b/packages/db-vercel-postgres/package.json index 708e0ecdbf8..13f4aec8823 100644 --- a/packages/db-vercel-postgres/package.json +++ b/packages/db-vercel-postgres/package.json @@ -82,7 +82,7 @@ "pg": "8.16.3", "prompts": "2.4.2", "to-snake-case": "1.0.0", - "uuid": "10.0.0" + "uuid": "11.1.0" }, "devDependencies": { "@hyrious/esbuild-plugin-commonjs": "0.2.6", diff --git a/packages/drizzle/package.json b/packages/drizzle/package.json index c7614c9c1ca..769216a2230 100644 --- a/packages/drizzle/package.json +++ b/packages/drizzle/package.json @@ -62,7 +62,7 @@ "drizzle-orm": "0.44.7", "prompts": "2.4.2", "to-snake-case": "1.0.0", - "uuid": "^11.1.0" + "uuid": "11.1.0" }, "devDependencies": { "@libsql/client": "0.14.0", diff --git a/packages/next/package.json b/packages/next/package.json index 075f9d5168c..04140eb5569 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -123,7 +123,7 @@ "path-to-regexp": "6.3.0", "qs-esm": "8.0.1", "sass": "1.77.4", - "uuid": "10.0.0" + "uuid": "11.1.0" }, "devDependencies": { "@babel/cli": "7.27.2", @@ -136,7 +136,6 @@ "@types/busboy": "1.5.4", "@types/react": "19.2.9", "@types/react-dom": "19.2.3", - "@types/uuid": "10.0.0", "babel-plugin-react-compiler": "19.1.0-rc.3", "esbuild": "0.27.1", "esbuild-sass-plugin": "3.3.1", diff --git a/packages/payload/package.json b/packages/payload/package.json index 5bf1f19c7c2..7f4b16e1b9b 100644 --- a/packages/payload/package.json +++ b/packages/payload/package.json @@ -128,7 +128,7 @@ "ts-essentials": "10.0.3", "tsx": "4.21.0", "undici": "7.24.4", - "uuid": "10.0.0", + "uuid": "11.1.0", "ws": "^8.16.0" }, "devDependencies": { @@ -140,7 +140,6 @@ "@types/nodemailer": "7.0.2", "@types/pluralize": "0.0.33", "@types/range-parser": "1.2.7", - "@types/uuid": "10.0.0", "@types/ws": "^8.5.10", "copyfiles": "2.4.1", "cross-env": "7.0.3", diff --git a/packages/plugin-stripe/package.json b/packages/plugin-stripe/package.json index 949c3fd43e4..7873e5e1ed6 100644 --- a/packages/plugin-stripe/package.json +++ b/packages/plugin-stripe/package.json @@ -66,7 +66,7 @@ "@payloadcms/ui": "workspace:*", "lodash.get": "^4.4.2", "stripe": "^10.2.0", - "uuid": "10.0.0" + "uuid": "11.1.0" }, "devDependencies": { "@payloadcms/eslint-config": "workspace:*", @@ -74,7 +74,6 @@ "@types/lodash.get": "^4.4.7", "@types/react": "19.2.9", "@types/react-dom": "19.2.3", - "@types/uuid": "10.0.0", "payload": "workspace:*" }, "peerDependencies": { diff --git a/packages/richtext-lexical/package.json b/packages/richtext-lexical/package.json index 7409f91e39c..33abacbac01 100644 --- a/packages/richtext-lexical/package.json +++ b/packages/richtext-lexical/package.json @@ -380,7 +380,6 @@ "@lexical/utils": "0.41.0", "@payloadcms/translations": "workspace:*", "@payloadcms/ui": "workspace:*", - "@types/uuid": "10.0.0", "acorn": "8.16.0", "bson-objectid": "2.0.4", "csstype": "3.1.3", @@ -394,7 +393,7 @@ "qs-esm": "8.0.1", "react-error-boundary": "4.1.2", "ts-essentials": "10.0.3", - "uuid": "10.0.0" + "uuid": "11.1.0" }, "devDependencies": { "@babel/cli": "7.27.2", diff --git a/packages/ui/package.json b/packages/ui/package.json index 2fe7bc3ed2a..f23279ef1a3 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -159,7 +159,7 @@ "sonner": "^1.7.2", "ts-essentials": "10.0.3", "use-context-selector": "2.0.0", - "uuid": "10.0.0" + "uuid": "11.1.0" }, "devDependencies": { "@babel/cli": "7.27.2", @@ -171,7 +171,6 @@ "@payloadcms/eslint-config": "workspace:*", "@types/react": "19.2.9", "@types/react-dom": "19.2.3", - "@types/uuid": "10.0.0", "babel-plugin-react-compiler": "19.1.0-rc.3", "esbuild": "0.27.1", "esbuild-sass-plugin": "3.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f2aea132dc1..5152e7a72ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -322,8 +322,8 @@ importers: specifier: 1.0.0 version: 1.0.0 uuid: - specifier: 9.0.0 - version: 9.0.0 + specifier: 11.1.0 + version: 11.1.0 devDependencies: '@payloadcms/eslint-config': specifier: workspace:* @@ -334,9 +334,6 @@ importers: '@types/to-snake-case': specifier: 1.0.0 version: 1.0.0 - '@types/uuid': - specifier: 10.0.0 - version: 10.0.0 payload: specifier: workspace:* version: link:../payload @@ -353,8 +350,8 @@ importers: specifier: 2.4.2 version: 2.4.2 uuid: - specifier: 10.0.0 - version: 10.0.0 + specifier: 11.1.0 + version: 11.1.0 devDependencies: '@payloadcms/eslint-config': specifier: workspace:* @@ -365,9 +362,6 @@ importers: '@types/prompts': specifier: ^2.4.5 version: 2.4.9 - '@types/uuid': - specifier: 10.0.0 - version: 10.0.0 mongodb: specifier: 6.16.0 version: 6.16.0(@aws-sdk/credential-providers@3.1014.0)(socks@2.8.7) @@ -405,8 +399,8 @@ importers: specifier: 1.0.0 version: 1.0.0 uuid: - specifier: 10.0.0 - version: 10.0.0 + specifier: 11.1.0 + version: 11.1.0 devDependencies: '@hyrious/esbuild-plugin-commonjs': specifier: 0.2.6 @@ -448,8 +442,8 @@ importers: specifier: 1.0.0 version: 1.0.0 uuid: - specifier: 9.0.0 - version: 9.0.0 + specifier: 11.1.0 + version: 11.1.0 devDependencies: '@payloadcms/eslint-config': specifier: workspace:* @@ -460,9 +454,6 @@ importers: '@types/to-snake-case': specifier: 1.0.0 version: 1.0.0 - '@types/uuid': - specifier: 10.0.0 - version: 10.0.0 payload: specifier: workspace:* version: link:../payload @@ -494,8 +485,8 @@ importers: specifier: 1.0.0 version: 1.0.0 uuid: - specifier: 10.0.0 - version: 10.0.0 + specifier: 11.1.0 + version: 11.1.0 devDependencies: '@hyrious/esbuild-plugin-commonjs': specifier: 0.2.6 @@ -534,7 +525,7 @@ importers: specifier: 1.0.0 version: 1.0.0 uuid: - specifier: ^11.1.0 + specifier: 11.1.0 version: 11.1.0 devDependencies: '@libsql/client': @@ -819,8 +810,8 @@ importers: specifier: 1.77.4 version: 1.77.4 uuid: - specifier: 10.0.0 - version: 10.0.0 + specifier: 11.1.0 + version: 11.1.0 devDependencies: '@babel/cli': specifier: 7.27.2 @@ -852,9 +843,6 @@ importers: '@types/react-dom': specifier: 19.2.3 version: 19.2.3(@types/react@19.2.9) - '@types/uuid': - specifier: 10.0.0 - version: 10.0.0 babel-plugin-react-compiler: specifier: 19.1.0-rc.3 version: 19.1.0-rc.3 @@ -964,8 +952,8 @@ importers: specifier: 7.24.4 version: 7.24.4 uuid: - specifier: 10.0.0 - version: 10.0.0 + specifier: 11.1.0 + version: 11.1.0 ws: specifier: ^8.16.0 version: 8.20.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -994,9 +982,6 @@ importers: '@types/range-parser': specifier: 1.2.7 version: 1.2.7 - '@types/uuid': - specifier: 10.0.0 - version: 10.0.0 '@types/ws': specifier: ^8.5.10 version: 8.18.1 @@ -1359,8 +1344,8 @@ importers: specifier: ^10.2.0 version: 10.17.0 uuid: - specifier: 10.0.0 - version: 10.0.0 + specifier: 11.1.0 + version: 11.1.0 devDependencies: '@payloadcms/eslint-config': specifier: workspace:* @@ -1377,9 +1362,6 @@ importers: '@types/react-dom': specifier: 19.2.3 version: 19.2.3(@types/react@19.2.9) - '@types/uuid': - specifier: 10.0.0 - version: 10.0.0 payload: specifier: workspace:* version: link:../payload @@ -1434,9 +1416,6 @@ importers: '@payloadcms/ui': specifier: workspace:* version: link:../ui - '@types/uuid': - specifier: 10.0.0 - version: 10.0.0 acorn: specifier: 8.16.0 version: 8.16.0 @@ -1483,8 +1462,8 @@ importers: specifier: 10.0.3 version: 10.0.3(typescript@5.7.3) uuid: - specifier: 10.0.0 - version: 10.0.0 + specifier: 11.1.0 + version: 11.1.0 devDependencies: '@babel/cli': specifier: 7.27.2 @@ -1805,8 +1784,8 @@ importers: specifier: 2.0.0 version: 2.0.0(react@19.2.4)(scheduler@0.25.0) uuid: - specifier: 10.0.0 - version: 10.0.0 + specifier: 11.1.0 + version: 11.1.0 devDependencies: '@babel/cli': specifier: 7.27.2 @@ -1835,9 +1814,6 @@ importers: '@types/react-dom': specifier: 19.2.3 version: 19.2.3(@types/react@19.2.9) - '@types/uuid': - specifier: 10.0.0 - version: 10.0.0 babel-plugin-react-compiler: specifier: 19.1.0-rc.3 version: 19.1.0-rc.3 @@ -2581,8 +2557,8 @@ importers: specifier: 5.7.3 version: 5.7.3 uuid: - specifier: 10.0.0 - version: 10.0.0 + specifier: 11.1.0 + version: 11.1.0 vitest: specifier: 4.0.15 version: 4.0.15(@opentelemetry/api@1.9.0)(@types/node@22.19.9)(@vitest/ui@4.0.15)(happy-dom@20.8.9(bufferutil@4.1.0)(utf-8-validate@6.0.6))(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.30.2)(sass-embedded@1.98.0)(sass@1.77.4)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) @@ -8073,9 +8049,6 @@ packages: '@types/use-sync-external-store@0.0.6': resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} - '@types/uuid@10.0.0': - resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} - '@types/webidl-conversions@7.0.3': resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==} @@ -14283,10 +14256,6 @@ packages: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - uuid@9.0.0: - resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} - hasBin: true - uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -20217,7 +20186,7 @@ snapshots: dependencies: '@sentry/bundler-plugin-core': 2.22.7 unplugin: 1.0.1 - uuid: 9.0.0 + uuid: 9.0.1 webpack: 5.105.4(@swc/core@1.15.3)(esbuild@0.25.12) transitivePeerDependencies: - encoding @@ -20227,7 +20196,7 @@ snapshots: dependencies: '@sentry/bundler-plugin-core': 3.6.1 unplugin: 1.0.1 - uuid: 9.0.0 + uuid: 9.0.1 webpack: 5.105.4(@swc/core@1.15.3)(esbuild@0.25.12) transitivePeerDependencies: - encoding @@ -21397,8 +21366,6 @@ snapshots: '@types/use-sync-external-store@0.0.6': {} - '@types/uuid@10.0.0': {} - '@types/webidl-conversions@7.0.3': {} '@types/whatwg-mimetype@3.0.2': {} @@ -28268,7 +28235,7 @@ snapshots: https-proxy-agent: 5.0.1 node-fetch: 2.7.0 stream-events: 1.0.5 - uuid: 9.0.0 + uuid: 9.0.1 transitivePeerDependencies: - encoding - supports-color @@ -28730,8 +28697,6 @@ snapshots: uuid@8.3.2: {} - uuid@9.0.0: {} - uuid@9.0.1: {} validate-npm-package-license@3.0.4: diff --git a/test/custom-graphql/int.spec.ts b/test/custom-graphql/int.spec.ts index 2a7bc045e14..109436ba8e1 100644 --- a/test/custom-graphql/int.spec.ts +++ b/test/custom-graphql/int.spec.ts @@ -24,7 +24,9 @@ describe('Custom GraphQL', () => { }) if ( - !['cosmosdb', 'firestore', 'sqlite', 'sqlite-uuid'].includes(process.env.PAYLOAD_DATABASE || '') + !['cosmosdb', 'firestore', 'sqlite', 'sqlite-uuid', 'sqlite-uuidv7'].includes( + process.env.PAYLOAD_DATABASE || '', + ) ) { describe('Isolated Transaction ID', () => { it('should isolate transaction IDs between queries in the same request', async () => { @@ -61,7 +63,7 @@ describe('Custom GraphQL', () => { }) }) } else { - it('should not run isolated transaction ID tests for sqlite/firestore/cosmosdb', () => { + it('should not run isolated transaction ID tests for sqlite (incl. uuid variants)/firestore/cosmosdb', () => { expect(true).toBe(true) }) } diff --git a/test/database/int.spec.ts b/test/database/int.spec.ts index 719440dafb2..3f087627399 100644 --- a/test/database/int.spec.ts +++ b/test/database/int.spec.ts @@ -2173,7 +2173,9 @@ describe('database', () => { describe('local api', () => { // sqlite cannot handle concurrent write transactions if ( - !['cosmosdb', 'firestore', 'sqlite', 'sqlite-uuid'].includes(process.env.PAYLOAD_DATABASE) + !['cosmosdb', 'firestore', 'sqlite', 'sqlite-uuid', 'sqlite-uuidv7'].includes( + process.env.PAYLOAD_DATABASE || '', + ) ) { it('should commit multiple operations in isolation', async () => { const req = { diff --git a/test/package.json b/test/package.json index 4734cd5be60..775cb53f07f 100644 --- a/test/package.json +++ b/test/package.json @@ -113,7 +113,7 @@ "tempy": "^1.0.1", "ts-essentials": "10.0.3", "typescript": "5.7.3", - "uuid": "10.0.0", + "uuid": "11.1.0", "vitest": "4.0.15", "wrangler": "~4.61.1", "zod": "^3.25.5"