Skip to content

Commit ca52a50

Browse files
feat: consolidates create and duplicate operations (#9866)
1 parent 5bfc92d commit ca52a50

File tree

12 files changed

+201
-408
lines changed

12 files changed

+201
-408
lines changed

docs/local-api/overview.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ const post = await payload.create({
131131
// Alternatively, you can directly pass a File,
132132
// if file is provided, filePath will be omitted
133133
file: uploadedFile,
134+
135+
// If you want to create a document that is a duplicate of another document
136+
duplicateFromID: 'document-id-to-duplicate',
134137
})
135138
```
136139

packages/graphql/src/resolvers/collections/create.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,13 @@ export function createResolver<TSlug extends CollectionSlug>(
3030
context.req.locale = args.locale
3131
}
3232

33-
const options = {
33+
const result = await createOperation({
3434
collection,
3535
data: args.data,
3636
depth: 0,
3737
draft: args.draft,
3838
req: isolateObjectProperty(context.req, 'transactionID'),
39-
}
40-
41-
const result = await createOperation(options)
39+
})
4240

4341
return result
4442
}

packages/graphql/src/resolvers/collections/duplicate.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { Context } from '../types.js'
77
export type Resolver<TData> = (
88
_: unknown,
99
args: {
10+
data: TData
1011
draft: boolean
1112
fallbackLocale?: string
1213
id: string
@@ -28,15 +29,14 @@ export function duplicateResolver<TSlug extends CollectionSlug>(
2829
req.fallbackLocale = args.fallbackLocale || fallbackLocale
2930
context.req = req
3031

31-
const options = {
32+
const result = await duplicateOperation({
3233
id: args.id,
3334
collection,
35+
data: args.data,
3436
depth: 0,
3537
draft: args.draft,
3638
req: isolateObjectProperty(req, 'transactionID'),
37-
}
38-
39-
const result = await duplicateOperation(options)
39+
})
4040

4141
return result
4242
}

packages/graphql/src/schema/initCollections.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,9 @@ export function initCollections({ config, graphqlResult }: InitCollectionsGraphQ
280280
type: collection.graphQL.type,
281281
args: {
282282
id: { type: new GraphQLNonNull(idType) },
283+
...(createMutationInputType
284+
? { data: { type: collection.graphQL.mutationInputType } }
285+
: {}),
283286
},
284287
resolve: duplicateResolver(collection),
285288
}

packages/next/src/routes/rest/collections/duplicate.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const duplicate: CollectionRouteHandlerWithID = async ({
2727
const doc = await duplicateOperation({
2828
id,
2929
collection,
30+
data: req.data,
3031
depth: isNumber(depth) ? Number(depth) : undefined,
3132
draft,
3233
populate: sanitizePopulateParam(req.query.populate),

packages/payload/src/collections/operations/create.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type {
1313
BeforeOperationHook,
1414
BeforeValidateHook,
1515
Collection,
16+
DataFromCollectionSlug,
1617
RequiredDataFromCollectionSlug,
1718
SelectFromCollectionSlug,
1819
} from '../config/types.js'
@@ -21,6 +22,7 @@ import { ensureUsernameOrEmail } from '../../auth/ensureUsernameOrEmail.js'
2122
import executeAccess from '../../auth/executeAccess.js'
2223
import { sendVerificationEmail } from '../../auth/sendVerificationEmail.js'
2324
import { registerLocalStrategy } from '../../auth/strategies/local/register.js'
25+
import { getDuplicateDocumentData } from '../../duplicateDocument/index.js'
2426
import { afterChange } from '../../fields/hooks/afterChange/index.js'
2527
import { afterRead } from '../../fields/hooks/afterRead/index.js'
2628
import { beforeChange } from '../../fields/hooks/beforeChange/index.js'
@@ -43,6 +45,7 @@ export type Arguments<TSlug extends CollectionSlug> = {
4345
disableTransaction?: boolean
4446
disableVerificationEmail?: boolean
4547
draft?: boolean
48+
duplicateFromID?: DataFromCollectionSlug<TSlug>['id']
4649
overrideAccess?: boolean
4750
overwriteExistingFiles?: boolean
4851
populate?: PopulateType
@@ -97,6 +100,7 @@ export const createOperation = async <
97100
depth,
98101
disableVerificationEmail,
99102
draft = false,
103+
duplicateFromID,
100104
overrideAccess,
101105
overwriteExistingFiles = false,
102106
populate,
@@ -115,6 +119,23 @@ export const createOperation = async <
115119

116120
const shouldSaveDraft = Boolean(draft && collectionConfig.versions.drafts)
117121

122+
let duplicatedFromDocWithLocales: JsonObject = {}
123+
let duplicatedFromDoc: JsonObject = {}
124+
125+
if (duplicateFromID) {
126+
const duplicateResult = await getDuplicateDocumentData({
127+
id: duplicateFromID,
128+
collectionConfig,
129+
draftArg: shouldSaveDraft,
130+
overrideAccess,
131+
req,
132+
shouldSaveDraft,
133+
})
134+
135+
duplicatedFromDoc = duplicateResult.duplicatedFromDoc
136+
duplicatedFromDocWithLocales = duplicateResult.duplicatedFromDocWithLocales
137+
}
138+
118139
// /////////////////////////////////////
119140
// Access
120141
// /////////////////////////////////////
@@ -131,7 +152,9 @@ export const createOperation = async <
131152
collection,
132153
config,
133154
data,
155+
isDuplicating: Boolean(duplicateFromID),
134156
operation: 'create',
157+
originalDoc: duplicatedFromDoc,
135158
overwriteExistingFiles,
136159
req,
137160
throwOnMissingFile:
@@ -148,7 +171,7 @@ export const createOperation = async <
148171
collection: collectionConfig,
149172
context: req.context,
150173
data,
151-
doc: {},
174+
doc: duplicatedFromDoc,
152175
global: null,
153176
operation: 'create',
154177
overrideAccess,
@@ -169,6 +192,7 @@ export const createOperation = async <
169192
context: req.context,
170193
data,
171194
operation: 'create',
195+
originalDoc: duplicatedFromDoc,
172196
req,
173197
})) || data
174198
},
@@ -188,6 +212,7 @@ export const createOperation = async <
188212
context: req.context,
189213
data,
190214
operation: 'create',
215+
originalDoc: duplicatedFromDoc,
191216
req,
192217
})) || data
193218
}, Promise.resolve())
@@ -200,8 +225,8 @@ export const createOperation = async <
200225
collection: collectionConfig,
201226
context: req.context,
202227
data,
203-
doc: {},
204-
docWithLocales: {},
228+
doc: duplicatedFromDoc,
229+
docWithLocales: duplicatedFromDocWithLocales,
205230
global: null,
206231
operation: 'create',
207232
req,

0 commit comments

Comments
 (0)