chore: ci changes to add compatibility for mongodb alternates (#13898)

- Adds documentdb and cosmosdb to CI test matrix
- Adds missing generateDatabaseAdapter configs
- Adjust generateDatabaseAdapter firestore config to make it pure to the
compatibilityOptions we provide as an export

Creating as draft because I expect a few tests to fail based on previous
comments.

---------

Co-authored-by: Sasha <64744993+r1tsuu@users.noreply.github.com>
This commit is contained in:
Dan Ribbens
2025-10-06 16:48:02 -04:00
committed by GitHub
parent e4f8478e36
commit 9ceee8ea3c
9 changed files with 48 additions and 24 deletions

View File

@@ -152,6 +152,8 @@ jobs:
matrix:
database:
- mongodb
- documentdb
- cosmosdb
- firestore
- postgres
- postgres-custom-schema

View File

@@ -204,6 +204,11 @@ export function getLocalizedPaths({
case 'json':
case 'richText': {
const upcomingSegments = pathSegments.slice(i + 1).join('.')
pathSegments.forEach((path) => {
if (!/^\w+(?:\.\w+)*$/.test(path)) {
lastIncompletePath.invalid = true
}
})
lastIncompletePath.complete = true
lastIncompletePath.path = upcomingSegments
? `${currentPath}.${upcomingSegments}`

View File

@@ -22,7 +22,9 @@ describe('Custom GraphQL', () => {
await payload.destroy()
})
if (!['sqlite', 'sqlite-uuid'].includes(process.env.PAYLOAD_DATABASE || '')) {
if (
!['cosmosdb', 'firestore', 'sqlite', 'sqlite-uuid'].includes(process.env.PAYLOAD_DATABASE || '')
) {
describe('Isolated Transaction ID', () => {
it('should isolate transaction IDs between queries in the same request', async () => {
const query = `query {
@@ -58,7 +60,7 @@ describe('Custom GraphQL', () => {
})
})
} else {
it('should not run isolated transaction ID tests for sqlite', () => {
it('should not run isolated transaction ID tests for sqlite/firestore/cosmosdb', () => {
expect(true).toBe(true)
})
}

View File

@@ -1748,7 +1748,9 @@ describe('database', () => {
describe('transactions', () => {
describe('local api', () => {
// sqlite cannot handle concurrent write transactions
if (!['sqlite', 'sqlite-uuid'].includes(process.env.PAYLOAD_DATABASE)) {
if (
!['cosmosdb', 'firestore', 'sqlite', 'sqlite-uuid'].includes(process.env.PAYLOAD_DATABASE)
) {
it('should commit multiple operations in isolation', async () => {
const req = {
payload,

View File

@@ -5,11 +5,7 @@ import { fileURLToPath } from 'node:url'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
export const allDatabaseAdapters = {
mongodb: `
import { mongooseAdapter } from '@payloadcms/db-mongodb'
export const databaseAdapter = mongooseAdapter({
const mongooseAdapterArgs = `
ensureIndexes: true,
// required for connect to detect that we are using a memory server
mongoMemoryServer: global._mongoMemoryServer,
@@ -20,23 +16,38 @@ export const allDatabaseAdapters = {
collation: {
strength: 1,
},
`
export const allDatabaseAdapters = {
mongodb: `
import { mongooseAdapter } from '@payloadcms/db-mongodb'
export const databaseAdapter = mongooseAdapter({
${mongooseAdapterArgs}
})`,
cosmosdb: `
import { mongooseAdapter, compatibilityOptions } from '@payloadcms/db-mongodb'
export const databaseAdapter = mongooseAdapter({
...compatibilityOptions.cosmosdb,
${mongooseAdapterArgs}
})`,
documentdb: `
import { mongooseAdapter, compatibilityOptions } from '@payloadcms/db-mongodb'
export const databaseAdapter = mongooseAdapter({
...compatibilityOptions.documentdb,
${mongooseAdapterArgs}
})`,
firestore: `
import { mongooseAdapter, compatibilityOptions } from '@payloadcms/db-mongodb'
export const databaseAdapter = mongooseAdapter({
...compatibilityOptions.firestore,
url:
process.env.DATABASE_URI ||
process.env.MONGODB_MEMORY_SERVER_URI ||
'mongodb://127.0.0.1/payloadtests',
collation: {
strength: 1,
},
${mongooseAdapterArgs}
// The following options prevent some tests from failing.
// More work needed to get tests succeeding without these options.
ensureIndexes: true,
transactionOptions: {},
disableIndexHints: false,
useAlternativeDropDatabase: false,
})`,

View File

@@ -1,8 +1,7 @@
import type { Payload } from 'payload'
export const mongooseList = ['cosmosdb', 'documentdb', 'firestore', 'mongodb']
export function isMongoose(_payload?: Payload) {
return (
_payload?.db?.name === 'mongoose' ||
['firestore', 'mongodb'].includes(process.env.PAYLOAD_DATABASE)
)
return _payload?.db?.name === 'mongoose' || mongooseList.includes(process.env.PAYLOAD_DATABASE)
}

View File

@@ -2,6 +2,7 @@ import { D1DatabaseAPI } from '@miniflare/d1'
import { createSQLiteDB } from '@miniflare/shared'
import dotenv from 'dotenv'
import { MongoMemoryReplSet } from 'mongodb-memory-server'
dotenv.config()
declare global {
@@ -31,7 +32,7 @@ export default async () => {
}
if (
(!process.env.PAYLOAD_DATABASE ||
['firestore', 'mongodb'].includes(process.env.PAYLOAD_DATABASE)) &&
['cosmosdb', 'documentdb', 'firestore', 'mongodb'].includes(process.env.PAYLOAD_DATABASE)) &&
!global._mongoMemoryServer
) {
console.log('Starting memory db...')

View File

@@ -14,6 +14,7 @@ import type {
} from './payload-types.js'
import { devUser } from '../credentials.js'
import { isMongoose, mongooseList } from '../helpers/isMongoose.js'
// eslint-disable-next-line payload/no-relative-monorepo-imports
import { copyDataFromLocaleHandler } from '../../packages/ui/src/utilities/copyDataFromLocale.js'
@@ -398,7 +399,7 @@ describe('Localization', () => {
expect(docs[2].id).toBe(doc_3.id)
})
if (['mongodb'].includes(process.env.PAYLOAD_DATABASE)) {
if (mongooseList.includes(process.env.PAYLOAD_DATABASE)) {
describe('Localized sorting', () => {
let localizedAccentPostOne: LocalizedPost
let localizedAccentPostTwo: LocalizedPost
@@ -1249,7 +1250,7 @@ describe('Localization', () => {
})
// eslint-disable-next-line jest/no-conditional-in-test
if (['firestore', 'mongodb'].includes(process.env.PAYLOAD_DATABASE!)) {
if (isMongoose(payload)) {
expect(docWithoutFallback.items).toStrictEqual(null)
} else {
// TODO: build out compatability with SQL databases

View File

@@ -17,6 +17,7 @@ import type {
} from './payload-types.js'
import { initPayloadInt } from '../helpers/initPayloadInt.js'
import { mongooseList } from '../helpers/isMongoose.js'
import {
chainedRelSlug,
customIdNumberSlug,
@@ -38,7 +39,7 @@ const dirname = path.dirname(filename)
type EasierChained = { id: string; relation: EasierChained }
const mongoIt = ['firestore', 'mongodb'].includes(process.env.PAYLOAD_DATABASE || '') ? it : it.skip
const mongoIt = mongooseList.includes(process.env.PAYLOAD_DATABASE || '') ? it : it.skip
describe('Relationships', () => {
beforeAll(async () => {