Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

52 lines
1.4 KiB
TypeScript
Raw Permalink Normal View History

import path from 'path'
import { getPayload, type SanitizedConfig } from 'payload'
import { loadEnv } from 'payload/node'
import { fileURLToPath } from 'url'
import { setTestEnvPaths } from './__helpers/shared/setTestEnvPaths.js'
chore: monorepo devcontainer support, refactor db adapter and docker start script (#16396) ## Devcontainers Adds dev container configuration, so contributors can open the repo in VS Code without setting up Node, pnpm, or Docker on their own machine. Works for both "Reopen in Container" (your local clone bind-mounted in) and "Clone Repository in Container Volume" (a fresh clone inside an isolated Docker volume, useful when running multiple parallel sessions against the same repo without them stepping on each other). `test/generateDatabaseAdapter.ts` was renamed to `test/dbAdapters.ts` and is the source of truth for anything db-adapter-related in one place: the source templates the codegen writes out, and the host/port/env-var defaults per adapter, which the new `assertDbReachable.ts` function uses to probe services. This should enable running multiple agents conflict-free ## DB Connection probe + docker:start script improvements `assertDbReachable` is now run within `pnpm dev`. If the db connection fails, you now get immediate feedback through a helpful error, instead of having to wait for Next.js to compile and then be thrown off by a cryptic db seed error: <img width="852" height="488" alt="screenshot 2026-04-26 at 15 26 12@2x" src="https://github.com/user-attachments/assets/aecfee0a-20eb-4d25-9215-256f8c8f5f8a" /> `pnpm docker:start` is now an interactive picker. You can still pass profile names as args (`pnpm docker:start postgres mongodb`) to skip the prompt: <img width="898" height="348" alt="screenshot 2026-04-26 at 15 28 04@2x" src="https://github.com/user-attachments/assets/7d4b8f3d-89a5-46b7-b3ca-887a793246b1" /> These changes encourages contributors not to start every single service we have available (uses around 4gb of ram), and only start the database service that you're using => much less memory usage. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1214135483864575
2026-04-28 15:19:58 -07:00
import { generateDatabaseAdapter } from './dbAdapters.js'
loadEnv()
const [testConfigDir] = process.argv.slice(2)
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
const writeDBAdapter = process.env.WRITE_DB_ADAPTER !== 'false'
process.env.PAYLOAD_DROP_DATABASE = process.env.PAYLOAD_DROP_DATABASE || 'true'
fix(db-mongodb): improve compatibility with Firestore database (#12763) ### What? Adds four more arguments to the `mongooseAdapter`: ```typescript useJoinAggregations?: boolean /* The big one */ useAlternativeDropDatabase?: boolean useBigIntForNumberIDs?: boolean usePipelineInSortLookup?: boolean ``` Also export a new `compatabilityOptions` object from `@payloadcms/db-mongodb` where each key is a mongo-compatible database and the value is the recommended `mongooseAdapter` settings for compatability. ### Why? When using firestore and visiting `/admin/collections/media/payload-folders`, we get: ``` MongoServerError: invalid field(s) in lookup: [let, pipeline], only lookup(from, localField, foreignField, as) is supported ``` Firestore doesn't support the full MongoDB aggregation API used by Payload which gets used when building aggregations for populating join fields. There are several other compatability issues with Firestore: - The invalid `pipeline` property is used in the `$lookup` aggregation in `buildSortParams` - Firestore only supports number IDs of type `Long`, but Mongoose converts custom ID fields of type number to `Double` - Firestore does not support the `dropDatabase` command - Firestore does not support the `createIndex` command (not addressed in this PR) ### How? ```typescript useJoinAggregations?: boolean /* The big one */ ``` When this is `false` we skip the `buildJoinAggregation()` pipeline and resolve the join fields through multiple queries. This can potentially be used with AWS DocumentDB and Azure Cosmos DB to support join fields, but I have not tested with either of these databases. ```typescript useAlternativeDropDatabase?: boolean ``` When `true`, monkey-patch (replace) the `dropDatabase` function so that it calls `collection.deleteMany({})` on every collection instead of sending a single `dropDatabase` command to the database ```typescript useBigIntForNumberIDs?: boolean ``` When `true`, use `mongoose.Schema.Types.BigInt` for custom ID fields of type `number` which converts to a firestore `Long` behind the scenes ```typescript usePipelineInSortLookup?: boolean ``` When `false`, modify the sortAggregation pipeline in `buildSortParams()` so that we don't use the `pipeline` property in the `$lookup` aggregation. Results in slightly worse performance when sorting by relationship properties. ### Limitations This PR does not add support for transactions or creating indexes in firestore. ### Fixes Fixed a bug (and added a test) where you weren't able to sort by multiple properties on a relationship field. ### Future work 1. Firestore supports simple `$lookup` aggregations but other databases might not. Could add a `useSortAggregations` property which can be used to disable aggregations in sorting. --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Sasha <64744993+r1tsuu@users.noreply.github.com>
2025-07-17 01:02:43 +05:45
if (process.env.PAYLOAD_DATABASE === 'mongodb' || process.env.PAYLOAD_DATABASE === 'firestore') {
throw new Error('Not supported')
}
if (writeDBAdapter) {
generateDatabaseAdapter(process.env.PAYLOAD_DATABASE || 'postgres')
process.env.WRITE_DB_ADAPTER = 'false'
}
const loadConfig = async (configPath: string): Promise<SanitizedConfig> => {
return await (
await import(configPath)
).default
}
if (!testConfigDir) {
throw new Error('Yo must Specify testConfigDir')
}
const testDir = path.resolve(dirname, testConfigDir)
const config = await loadConfig(path.resolve(testDir, 'config.ts'))
setTestEnvPaths(testDir)
const payload = await getPayload({ config })
// await payload.db.dropDatabase({ adapter: payload.db })
await payload.db.generateSchema({
outputFile: path.resolve(testDir, 'payload-generated-schema.ts'),
})
process.exit(0)