Skip to content

Commit 223b86f

Browse files
WIP
1 parent ad07053 commit 223b86f

File tree

1 file changed

+52
-34
lines changed

1 file changed

+52
-34
lines changed

packages/server/src/api/rest/index.ts

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,14 @@ class RequestHandler extends APIHandlerBase {
716716
body = SuperJSON.deserialize({ json: body, meta: body.meta.serialization });
717717
}
718718

719+
let method: 'create' | 'update' | 'upsert' = mode;
720+
let matchFields = [];
721+
722+
if (body.meta?.operation === 'upsert' && body.meta?.matchFields.length) {
723+
method = 'upsert';
724+
matchFields = body.meta.matchFields;
725+
}
726+
719727
const parsed = this.createUpdatePayloadSchema.parse(body);
720728
const attributes: any = parsed.data.attributes;
721729

@@ -740,7 +748,7 @@ class RequestHandler extends APIHandlerBase {
740748
}
741749
}
742750

743-
return { attributes, relationships: parsed.data.relationships };
751+
return { attributes, relationships: parsed.data.relationships, method, matchFields };
744752
}
745753

746754
private async processCreate(
@@ -756,53 +764,63 @@ class RequestHandler extends APIHandlerBase {
756764
return this.makeUnsupportedModelError(type);
757765
}
758766

759-
const { error, attributes, relationships } = this.processRequestBody(type, requestBody, zodSchemas, 'create');
767+
const { error, attributes, relationships, method, matchFields } = this.processRequestBody(
768+
type,
769+
requestBody,
770+
zodSchemas,
771+
'create'
772+
);
760773

761774
if (error) {
762775
return error;
763776
}
764777

765-
const createPayload: any = { data: { ...attributes } };
778+
let entity: any;
779+
if (method === 'upsert') {
780+
entity = await prisma[type].upsert(createPayload);
781+
} else {
782+
const createPayload: any = { data: { ...attributes } };
766783

767-
// turn relationship payload into Prisma connect objects
768-
if (relationships) {
769-
for (const [key, data] of Object.entries<any>(relationships)) {
770-
if (!data?.data) {
771-
return this.makeError('invalidRelationData');
772-
}
784+
// turn relationship payload into Prisma connect objects
785+
if (relationships) {
786+
for (const [key, data] of Object.entries<any>(relationships)) {
787+
if (!data?.data) {
788+
return this.makeError('invalidRelationData');
789+
}
773790

774-
const relationInfo = typeInfo.relationships[key];
775-
if (!relationInfo) {
776-
return this.makeUnsupportedRelationshipError(type, key, 400);
777-
}
791+
const relationInfo = typeInfo.relationships[key];
792+
if (!relationInfo) {
793+
return this.makeUnsupportedRelationshipError(type, key, 400);
794+
}
778795

779-
if (relationInfo.isCollection) {
780-
createPayload.data[key] = {
781-
connect: enumerate(data.data).map((item: any) =>
782-
this.makeIdConnect(relationInfo.idFields, item.id)
783-
),
784-
};
785-
} else {
786-
if (typeof data.data !== 'object') {
787-
return this.makeError('invalidRelationData');
796+
if (relationInfo.isCollection) {
797+
createPayload.data[key] = {
798+
connect: enumerate(data.data).map((item: any) =>
799+
this.makeIdConnect(relationInfo.idFields, item.id)
800+
),
801+
};
802+
} else {
803+
if (typeof data.data !== 'object') {
804+
return this.makeError('invalidRelationData');
805+
}
806+
createPayload.data[key] = {
807+
connect: this.makeIdConnect(relationInfo.idFields, data.data.id),
808+
};
788809
}
789-
createPayload.data[key] = {
790-
connect: this.makeIdConnect(relationInfo.idFields, data.data.id),
810+
811+
// make sure ID fields are included for result serialization
812+
createPayload.include = {
813+
...createPayload.include,
814+
[key]: { select: { [this.makePrismaIdKey(relationInfo.idFields)]: true } },
791815
};
792816
}
793-
794-
// make sure ID fields are included for result serialization
795-
createPayload.include = {
796-
...createPayload.include,
797-
[key]: { select: { [this.makePrismaIdKey(relationInfo.idFields)]: true } },
798-
};
799817
}
800-
}
801818

802-
// include IDs of relation fields so that they can be serialized.
803-
this.includeRelationshipIds(type, createPayload, 'include');
819+
// include IDs of relation fields so that they can be serialized.
820+
this.includeRelationshipIds(type, createPayload, 'include');
804821

805-
const entity = await prisma[type].create(createPayload);
822+
entity = await prisma[type].create(createPayload);
823+
}
806824
return {
807825
status: 201,
808826
body: await this.serializeItems(type, entity),

0 commit comments

Comments
 (0)