Compare commits
13 Commits
richtext-s
...
fix/mongod
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43cdb45620 | ||
|
|
6364afb1dd | ||
|
|
56a4692662 | ||
|
|
ef6b8e4235 | ||
|
|
5f5290341a | ||
|
|
62403584ad | ||
|
|
19fcfc27af | ||
|
|
dcf14f5f71 | ||
|
|
3a784a06cc | ||
|
|
6eeae9d53b | ||
|
|
6044f810bd | ||
|
|
e68ca9363f | ||
|
|
9963b8d945 |
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -12,8 +12,8 @@
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Change to the [templates](../templates/) directory (does not affect core functionality)
|
||||
- [ ] Change to the [examples](../examples/) directory (does not affect core functionality)
|
||||
- [ ] Change to the [templates](https://github.com/payloadcms/payload/tree/main/templates) directory (does not affect core functionality)
|
||||
- [ ] Change to the [examples](https://github.com/payloadcms/payload/tree/main/examples) directory (does not affect core functionality)
|
||||
- [ ] This change requires a documentation update
|
||||
|
||||
## Checklist:
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
## [2.2.1](https://github.com/payloadcms/payload/compare/v2.2.0...v2.2.1) (2023-11-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* make outputSchema optional on richtext config ([#4230](https://github.com/payloadcms/payload/issues/4230)) ([3a784a0](https://github.com/payloadcms/payload/commit/3a784a06cc6c42c96b8d6cf023d942e6661be7b5))
|
||||
|
||||
## [2.2.0](https://github.com/payloadcms/payload/compare/v2.1.1...v2.2.0) (2023-11-20)
|
||||
|
||||
|
||||
|
||||
@@ -172,20 +172,34 @@ export default buildConfig({
|
||||
collections: [Subscriptions],
|
||||
admin: {
|
||||
bundler: viteBundler(),
|
||||
vite: (config) => {
|
||||
return {
|
||||
...config,
|
||||
resolve: {
|
||||
...config.resolve,
|
||||
// highlight-start
|
||||
alias: {
|
||||
...config.resolve.alias,
|
||||
// remember, vite aliases are exact-match only
|
||||
'./hooks/createStripeSubscription': mockModulePath,
|
||||
},
|
||||
// highlight-end
|
||||
},
|
||||
vite: (incomingViteConfig) => {
|
||||
const existingAliases = incomingViteConfig?.resolve?.alias || {};
|
||||
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
|
||||
|
||||
// Pass the existing Vite aliases
|
||||
if (Array.isArray(existingAliases)) {
|
||||
aliasArray = existingAliases;
|
||||
} else {
|
||||
aliasArray = Object.values(existingAliases);
|
||||
}
|
||||
|
||||
|
||||
// highlight-start
|
||||
// Add your own aliases using the find and replacement keys
|
||||
// remember, vite aliases are exact-match only
|
||||
aliasArray.push({
|
||||
find: '../server-only-module',
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
|
||||
});
|
||||
// highlight-end
|
||||
|
||||
return {
|
||||
...incomingViteConfig,
|
||||
resolve: {
|
||||
...(incomingViteConfig?.resolve || {}),
|
||||
alias: aliasArray,
|
||||
}
|
||||
};
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -60,17 +60,33 @@ export const buildConfig({
|
||||
collections: [],
|
||||
admin: {
|
||||
bundler: viteBundler(),
|
||||
vite: (incomingViteConfig) => ({
|
||||
...incomingViteConfig,
|
||||
resolve: {
|
||||
...(incomingViteConfig?.resolve || {}),
|
||||
alias: {
|
||||
...(incomingViteConfig?.resolve?.alias || {}),
|
||||
'../server-only-module': path.resolve(__dirname, './path/to/browser-safe-module.js'),
|
||||
'../../server-only-module': path.resolve(__dirname, './path/to/browser-safe-module.js'),
|
||||
}
|
||||
vite: (incomingViteConfig) => {
|
||||
const existingAliases = incomingViteConfig?.resolve?.alias || {};
|
||||
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
|
||||
|
||||
// Pass the existing Vite aliases
|
||||
if (Array.isArray(existingAliases)) {
|
||||
aliasArray = existingAliases;
|
||||
} else {
|
||||
aliasArray = Object.values(existingAliases);
|
||||
}
|
||||
})
|
||||
|
||||
// Add your own aliases using the find and replacement keys
|
||||
aliasArray.push({
|
||||
find: '../server-only-module',
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
|
||||
find: '../../server-only-module',
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
|
||||
});
|
||||
|
||||
return {
|
||||
...incomingViteConfig,
|
||||
resolve: {
|
||||
...(incomingViteConfig?.resolve || {}),
|
||||
alias: aliasArray,
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
})
|
||||
```
|
||||
@@ -90,7 +106,8 @@ That plugin should create an alias to support Vite as follows:
|
||||
```ts
|
||||
{
|
||||
// aliases go here
|
||||
'payload-plugin-cool': path.resolve(__dirname, './my-admin-plugin.js')
|
||||
find: 'payload-plugin-cool',
|
||||
replacement: path.resolve(__dirname, './my-admin-plugin.js')
|
||||
}
|
||||
|
||||
```
|
||||
@@ -108,22 +125,36 @@ export const buildConfig({
|
||||
collections: [],
|
||||
admin: {
|
||||
bundler: viteBundler(),
|
||||
vite: (incomingViteConfig) => ({
|
||||
...incomingViteConfig,
|
||||
resolve: {
|
||||
...(incomingViteConfig?.resolve || {}),
|
||||
alias: {
|
||||
...(incomingViteConfig?.resolve?.alias || {}),
|
||||
// custom aliases go here
|
||||
'../server-only-module': path.resolve(__dirname, './path/to/browser-safe-module.js'),
|
||||
}
|
||||
vite: (incomingViteConfig) => {
|
||||
const existingAliases = incomingViteConfig?.resolve?.alias || {};
|
||||
let aliasArray: { find: string | RegExp; replacement: string; }[] = [];
|
||||
|
||||
// Pass the existing Vite aliases
|
||||
if (Array.isArray(existingAliases)) {
|
||||
aliasArray = existingAliases;
|
||||
} else {
|
||||
aliasArray = Object.values(existingAliases);
|
||||
}
|
||||
})
|
||||
|
||||
// Add your own aliases using the find and replacement keys
|
||||
aliasArray.push({
|
||||
find: '../server-only-module',
|
||||
replacement: path.resolve(__dirname, './path/to/browser-safe-module.js')
|
||||
});
|
||||
|
||||
return {
|
||||
...incomingViteConfig,
|
||||
resolve: {
|
||||
...(incomingViteConfig?.resolve || {}),
|
||||
alias: aliasArray,
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Learn more about [aliasing server-only modules](http://localhost:3000/docs/admin/excluding-server-code#aliasing-server-only-modules).
|
||||
Learn more about [aliasing server-only modules](https://payloadcms.com/docs/admin/excluding-server-code#aliasing-server-only-modules).
|
||||
|
||||
Even though there is a new property for Vite configs specifically, we have implemented some "compatibility" between Webpack and Vite out-of-the-box.
|
||||
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
import type { RollbackTransaction } from 'payload/database'
|
||||
|
||||
export const rollbackTransaction: RollbackTransaction = async function rollbackTransaction(
|
||||
id = '',
|
||||
) {
|
||||
export const rollbackTransaction: RollbackTransaction = function rollbackTransaction(id = '') {
|
||||
// if multiple operations are using the same transaction, the first will flow through and delete the session.
|
||||
// subsequent calls should be ignored.
|
||||
if (!this.sessions[id]) {
|
||||
return
|
||||
}
|
||||
|
||||
// when session exists but is not inTransaction something unexpected is happening to the session
|
||||
// when session exists but inTransaction is false, it is no longer used and can be deleted
|
||||
if (!this.sessions[id].inTransaction()) {
|
||||
this.payload.logger.warn('rollbackTransaction called when no transaction exists')
|
||||
delete this.sessions[id]
|
||||
return
|
||||
}
|
||||
|
||||
// the first call for rollback should be aborted and deleted causing any other operations with the same transaction to fail
|
||||
await this.sessions[id].abortTransaction()
|
||||
await this.sessions[id].endSession()
|
||||
try {
|
||||
// null coalesce needed when rollback is called multiple times with the same id synchronously
|
||||
this.sessions?.[id].abortTransaction().then(() => {
|
||||
// not supported by DocumentDB
|
||||
this.sessions?.[id].endSession()
|
||||
})
|
||||
} catch (e) {
|
||||
// no action needed
|
||||
}
|
||||
delete this.sessions[id]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload",
|
||||
"version": "2.2.0",
|
||||
"version": "2.2.1",
|
||||
"description": "Node, React and MongoDB Headless CMS and Application Framework",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -31,7 +31,7 @@ export type RichTextAdapter<
|
||||
siblingDoc: Record<string, unknown>
|
||||
}) => Promise<void> | null
|
||||
|
||||
outputSchema: ({
|
||||
outputSchema?: ({
|
||||
field,
|
||||
isRequired,
|
||||
}: {
|
||||
|
||||
@@ -97,7 +97,7 @@ export default joi.object({
|
||||
CellComponent: component.required(),
|
||||
FieldComponent: component.required(),
|
||||
afterReadPromise: joi.func().optional(),
|
||||
outputSchema: joi.func().required(),
|
||||
outputSchema: joi.func().optional(),
|
||||
populationPromise: joi.func().optional(),
|
||||
validate: joi.func().required(),
|
||||
})
|
||||
|
||||
@@ -151,7 +151,7 @@ export type BeginTransaction = (
|
||||
options?: Record<string, unknown>,
|
||||
) => Promise<null | number | string>
|
||||
|
||||
export type RollbackTransaction = (id: number | string) => Promise<void>
|
||||
export type RollbackTransaction = (id: number | string) => Promise<void> | void
|
||||
|
||||
export type CommitTransaction = (id: number | string) => Promise<void>
|
||||
|
||||
|
||||
@@ -434,7 +434,7 @@ export const richText = baseField.keys({
|
||||
CellComponent: componentSchema.required(),
|
||||
FieldComponent: componentSchema.required(),
|
||||
afterReadPromise: joi.func().optional(),
|
||||
outputSchema: joi.func().required(),
|
||||
outputSchema: joi.func().optional(),
|
||||
populationPromise: joi.func().optional(),
|
||||
validate: joi.func().required(),
|
||||
})
|
||||
|
||||
@@ -413,6 +413,11 @@ describe('Field Validations', () => {
|
||||
const result = number(val, numberOptions)
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
it('should validate 0', () => {
|
||||
const val = 0
|
||||
const result = number(val, { ...numberOptions, required: true })
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
it('should validate 2', () => {
|
||||
const val = 1.5
|
||||
const result = number(val, numberOptions)
|
||||
|
||||
@@ -205,8 +205,11 @@ export const number: Validate<unknown, unknown, NumberField> = (
|
||||
if (typeof lengthValidationResult === 'string') return lengthValidationResult
|
||||
}
|
||||
|
||||
if (!value && required) return t('validation:required')
|
||||
if (!value && !required) return true
|
||||
if (!value && !isNumber(value)) {
|
||||
// if no value is present, validate based on required
|
||||
if (required) return t('validation:required')
|
||||
if (!required) return true
|
||||
}
|
||||
|
||||
const numbersToValidate: number[] = Array.isArray(value) ? value : [value]
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
"copied": "Skopiowano",
|
||||
"copy": "Skopiuj",
|
||||
"create": "Stwórz",
|
||||
"createNew": "Stwórzy nowy",
|
||||
"createNew": "Stwórz nowy",
|
||||
"createNewLabel": "Stwórz nowy {{label}}",
|
||||
"created": "Utworzono",
|
||||
"createdAt": "Data utworzenia",
|
||||
|
||||
@@ -132,10 +132,20 @@ function fieldsToJSONSchema(
|
||||
}
|
||||
|
||||
case 'richText': {
|
||||
fieldSchema = field.editor.outputSchema({
|
||||
field,
|
||||
isRequired,
|
||||
})
|
||||
if (field.editor.outputSchema) {
|
||||
fieldSchema = field.editor.outputSchema({
|
||||
field,
|
||||
isRequired,
|
||||
})
|
||||
} else {
|
||||
// Maintain backwards compatibility with existing rich text editors
|
||||
fieldSchema = {
|
||||
items: {
|
||||
type: 'object',
|
||||
},
|
||||
type: withNullableJSONSchemaType('array', isRequired),
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
"build:swc": "swc ./src -d ./dist --config-file .swcrc",
|
||||
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
||||
"clean": "rimraf {dist,*.tsbuildinfo}",
|
||||
"prepublishOnly": "yarn clean && yarn build",
|
||||
"prepublishOnly": "pnpm clean && pnpm build",
|
||||
"test": "echo \"No tests available.\""
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@aws-sdk/client-s3": "^3.142.0",
|
||||
"@aws-sdk/lib-storage": "^3.267.0",
|
||||
"@azure/storage-blob": "^12.11.0",
|
||||
"@azure/abort-controller": "^1.0.0",
|
||||
"@azure/storage-blob": "^12.11.0",
|
||||
"@google-cloud/storage": "^6.4.1",
|
||||
"payload": "^1.7.2 || ^2.0.0"
|
||||
},
|
||||
@@ -49,6 +49,7 @@
|
||||
"@azure/storage-blob": "^12.11.0",
|
||||
"@google-cloud/storage": "^6.4.1",
|
||||
"@types/express": "^4.17.9",
|
||||
"@types/find-node-modules": "^2.1.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^8.2.0",
|
||||
"nodemon": "^2.0.6",
|
||||
@@ -58,6 +59,7 @@
|
||||
"webpack": "^5.78.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"find-node-modules": "^2.1.3",
|
||||
"range-parser": "^1.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,37 @@
|
||||
import type { Configuration as WebpackConfig } from 'webpack'
|
||||
|
||||
import findNodeModules from 'find-node-modules'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
const packageName = '@payloadcms/plugin-cloud-storage'
|
||||
|
||||
const nodeModulesPaths = findNodeModules({ cwd: __dirname, relative: false })
|
||||
|
||||
export const extendWebpackConfig = (existingWebpackConfig: WebpackConfig): WebpackConfig => {
|
||||
let nodeModulesPath = nodeModulesPaths.find((p) => {
|
||||
const guess = path.resolve(p, `${packageName}/dist`)
|
||||
|
||||
if (fs.existsSync(guess)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
if (!nodeModulesPath) {
|
||||
nodeModulesPath = process.cwd()
|
||||
}
|
||||
|
||||
const newConfig: WebpackConfig = {
|
||||
...existingWebpackConfig,
|
||||
resolve: {
|
||||
...(existingWebpackConfig.resolve || {}),
|
||||
alias: {
|
||||
...(existingWebpackConfig.resolve?.alias ? existingWebpackConfig.resolve.alias : {}),
|
||||
'@payloadcms/plugin-cloud-storage/s3': path.resolve(__dirname, './mock.js'),
|
||||
'@payloadcms/plugin-cloud-storage/s3$': path.resolve(
|
||||
nodeModulesPath,
|
||||
`./${packageName}/dist/adapters/s3/mock.js`,
|
||||
),
|
||||
},
|
||||
fallback: {
|
||||
...(existingWebpackConfig.resolve?.fallback ? existingWebpackConfig.resolve.fallback : {}),
|
||||
|
||||
@@ -29,7 +29,7 @@ export const extendWebpackConfig =
|
||||
},
|
||||
}
|
||||
|
||||
return Object.entries(options.collections).reduce(
|
||||
const modifiedConfig = Object.entries(options.collections).reduce(
|
||||
(resultingWebpackConfig, [slug, collectionOptions]) => {
|
||||
const matchedCollection = config.collections?.find((coll) => coll.slug === slug)
|
||||
|
||||
@@ -47,4 +47,6 @@ export const extendWebpackConfig =
|
||||
},
|
||||
newConfig,
|
||||
)
|
||||
|
||||
return modifiedConfig
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-nested-docs",
|
||||
"version": "1.0.8",
|
||||
"version": "1.0.9",
|
||||
"description": "The official Nested Docs plugin for Payload",
|
||||
"repository": "https://github.com/payloadcms/payload",
|
||||
"license": "MIT",
|
||||
|
||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@@ -1091,6 +1091,9 @@ importers:
|
||||
'@azure/abort-controller':
|
||||
specifier: ^1.0.0
|
||||
version: 1.1.0
|
||||
find-node-modules:
|
||||
specifier: ^2.1.3
|
||||
version: 2.1.3
|
||||
range-parser:
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.1
|
||||
@@ -1110,6 +1113,9 @@ importers:
|
||||
'@types/express':
|
||||
specifier: ^4.17.9
|
||||
version: 4.17.17
|
||||
'@types/find-node-modules':
|
||||
specifier: ^2.1.2
|
||||
version: 2.1.2
|
||||
cross-env:
|
||||
specifier: ^7.0.3
|
||||
version: 7.0.3
|
||||
@@ -5864,6 +5870,10 @@ packages:
|
||||
resolution: {integrity: sha512-rnh1kFUbwp5xEu54GhGDnzxm5/iJC3irypLO9+YECIal+XXKU5ki4I1h0Sm43KNpvKzFfyYFeGOm7o6tGI9Bgw==}
|
||||
dev: true
|
||||
|
||||
/@types/find-node-modules@2.1.2:
|
||||
resolution: {integrity: sha512-5hRcqDclY6MTkHXJBc5q79z5luG+IJRlGR01wluMVMM9lYogYc2sfclXTVU5Edp0Ja4viIOCDI1lXhFRlsNTKA==}
|
||||
dev: true
|
||||
|
||||
/@types/fs-extra@11.0.2:
|
||||
resolution: {integrity: sha512-c0hrgAOVYr21EX8J0jBMXGLMgJqVf/v6yxi0dLaJboW9aQPh16Id+z6w2Tx1hm+piJOLv8xPfVKZCLfjPw/IMQ==}
|
||||
dependencies:
|
||||
|
||||
@@ -27,7 +27,6 @@ export const getPackageDetails = async (pkg?: string): Promise<PackageDetails[]>
|
||||
} else {
|
||||
packageDirs = fse.readdirSync(packagesDir).filter((d) => d !== 'eslint-config-payload')
|
||||
}
|
||||
console.log(packageDirs)
|
||||
|
||||
const packageDetails = await Promise.all(
|
||||
packageDirs.map(async (dirName) => {
|
||||
|
||||
@@ -11,7 +11,7 @@ To spin up the project locally, follow these steps:
|
||||
1. First clone the repo
|
||||
1. Then `cd YOUR_PROJECT_REPO && cp .env.example .env`
|
||||
1. Next `yarn && yarn dev` (or `docker-compose up`, see [Docker](#docker))
|
||||
1. Now `open http://localhost:8000/admin` to access the admin panel
|
||||
1. Now `open http://localhost:3000/admin` to access the admin panel
|
||||
1. Create your first admin user using the form on the page
|
||||
|
||||
That's it! Changes made in `./src` will be reflected in your app.
|
||||
|
||||
@@ -321,19 +321,19 @@ export default buildConfigWithDefaults({
|
||||
slug: 'payload-api-test-twos',
|
||||
},
|
||||
{
|
||||
slug: 'content-type',
|
||||
access: {
|
||||
read: () => true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'contentType',
|
||||
type: 'text',
|
||||
hooks: {
|
||||
afterRead: [({ req }) => req.headers?.['content-type']],
|
||||
},
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
slug: 'content-type',
|
||||
},
|
||||
],
|
||||
graphQL: {
|
||||
|
||||
@@ -6,7 +6,7 @@ import payload from '../../packages/payload/src'
|
||||
import { mapAsync } from '../../packages/payload/src/utilities/mapAsync'
|
||||
import { initPayloadTest } from '../helpers/configHelpers'
|
||||
import { idToString } from '../helpers/idToString'
|
||||
import configPromise, { errorOnHookSlug, pointSlug, slug } from './config'
|
||||
import configPromise, { errorOnHookSlug, pointSlug, relationSlug, slug } from './config'
|
||||
|
||||
const title = 'title'
|
||||
|
||||
@@ -779,6 +779,86 @@ describe('collections-graphql', () => {
|
||||
expect(totalDocs).toStrictEqual(1)
|
||||
expect(docs[0].relationToCustomID.id).toStrictEqual(1)
|
||||
})
|
||||
|
||||
it('should query a document with a deleted relationship', async () => {
|
||||
const relation = await payload.create({
|
||||
collection: relationSlug,
|
||||
data: {
|
||||
name: 'test',
|
||||
},
|
||||
})
|
||||
|
||||
await payload.create({
|
||||
collection: slug,
|
||||
data: {
|
||||
relationField: relation.id,
|
||||
title: 'has deleted relation',
|
||||
},
|
||||
})
|
||||
|
||||
await payload.delete({
|
||||
id: relation.id,
|
||||
collection: relationSlug,
|
||||
})
|
||||
|
||||
const query = `query {
|
||||
Posts(where: { title: { equals: "has deleted relation" }}) {
|
||||
docs {
|
||||
id
|
||||
title
|
||||
relationField {
|
||||
id
|
||||
}
|
||||
}
|
||||
totalDocs
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await client.request(query)
|
||||
const { docs } = response.Posts
|
||||
|
||||
expect(docs[0].relationField).toBeFalsy()
|
||||
})
|
||||
|
||||
it('should query a document with a deleted relationship hasMany', async () => {
|
||||
const relation = await payload.create({
|
||||
collection: relationSlug,
|
||||
data: {
|
||||
name: 'test',
|
||||
},
|
||||
})
|
||||
|
||||
await payload.create({
|
||||
collection: slug,
|
||||
data: {
|
||||
relationHasManyField: [relation.id],
|
||||
title: 'has deleted relation hasMany',
|
||||
},
|
||||
})
|
||||
|
||||
await payload.delete({
|
||||
id: relation.id,
|
||||
collection: relationSlug,
|
||||
})
|
||||
|
||||
const query = `query {
|
||||
Posts(where: { title: { equals: "has deleted relation hasMany" }}) {
|
||||
docs {
|
||||
id
|
||||
title
|
||||
relationHasManyField {
|
||||
id
|
||||
}
|
||||
}
|
||||
totalDocs
|
||||
}
|
||||
}`
|
||||
|
||||
const response = await client.request(query)
|
||||
const { docs } = response.Posts
|
||||
|
||||
expect(docs[0].relationHasManyField).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -161,18 +161,30 @@ describe('database', () => {
|
||||
},
|
||||
req,
|
||||
})
|
||||
|
||||
try {
|
||||
await payload.create({
|
||||
const promises = [
|
||||
payload.create({
|
||||
collection,
|
||||
data: {
|
||||
throwAfterChange: true,
|
||||
title,
|
||||
},
|
||||
req,
|
||||
})
|
||||
} catch (error: unknown) {
|
||||
// catch error and carry on
|
||||
}),
|
||||
// multiple documents should be able to fail without error
|
||||
payload.create({
|
||||
collection,
|
||||
data: {
|
||||
throwAfterChange: true,
|
||||
title,
|
||||
},
|
||||
req,
|
||||
}),
|
||||
]
|
||||
|
||||
try {
|
||||
await Promise.all(promises)
|
||||
} catch (e) {
|
||||
// catch errors and carry on
|
||||
}
|
||||
|
||||
expect(req.transactionID).toBeFalsy()
|
||||
|
||||
Reference in New Issue
Block a user