Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,43 @@ describe('PATCH method:', () => {

await jsonSdk.jonApiSdkService.deleteOne(newCommentsAfterSave);
});

it('Should be update empty attributes with relations', async () => {
const newAddress = new Addresses();
newAddress.city = faker.location.city();
newAddress.state = faker.location.state();
newAddress.country = faker.location.country();

const newComments = new Comments();
newComments.text = faker.string.alpha();
newComments.kind = CommentKind.Comment;

const newAddressAfterSave = await jsonSdk.jonApiSdkService.postOne(
newAddress
);

const newCommentsAfterSave = await jsonSdk.jonApiSdkService.postOne(
newComments
);

userAfterSave.addresses = newAddressAfterSave;
userAfterSave.comments = [newCommentsAfterSave];

const userWithEmptyAttr = new Users();
userWithEmptyAttr.id = userAfterSave.id;
userWithEmptyAttr.addresses = newAddressAfterSave;
userWithEmptyAttr.comments = [newCommentsAfterSave];

await jsonSdk.jonApiSdkService.patchOne(userWithEmptyAttr);
const userAfterUpdate = await jsonSdk.jonApiSdkService.getOne(
Users,
userWithEmptyAttr.id,
{ include: ['addresses', 'comments'] }
);
expect(userAfterUpdate.addresses).toEqual(newAddressAfterSave);
newCommentsAfterSave.updatedAt = userAfterUpdate.comments[0].updatedAt;
expect(userAfterUpdate.comments[0]).toEqual(newCommentsAfterSave);

await jsonSdk.jonApiSdkService.deleteOne(newCommentsAfterSave);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
QueryParamsForOneItem,
RelationBodyData,
ResourceObject,
ResourceObjectRelationships,
ReturnIfArray,
} from '../types';
import { EntityArray, getTypeForReq } from '../utils';
Expand Down Expand Up @@ -172,7 +171,7 @@ export class JsonApiSdkService {
data: {
id: entity[this.jsonApiSdkConfig.idKey].toString(),
type: getTypeForReq(entity.constructor.name),
attributes,
...(Object.keys(attributes).length > 0 ? { attributes } : {}),
...(Object.keys(relationships).length > 0 ? { relationships } : {}),
},
};
Expand Down
4 changes: 2 additions & 2 deletions libs/json-api/json-api-nestjs-sdk/src/lib/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ type MainData<E> = {
export type PostData<E> = {
data: MainData<E>;
};

export type PatchData<E> = {
data: { id: string } & MainData<E>;
data: { id: string } & Omit<MainData<E>, 'attributes'> &
Partial<Pick<MainData<E>, 'attributes'>>;
};
export type RelationData = { id: string; type: string };
export type RelationBodyData = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -573,9 +573,24 @@ describe('zod-helper', () => {
attributes,
},
};
const check3 = {
data: {
id: '1',
type: 'users',
relationships,
},
};

expect(zodInputPatchSchemaTest.parse(check)).toEqual(check);
expect(zodInputPatchSchemaTest.parse(check2)).toEqual(check2);
expect(zodInputPatchSchemaTest.parse(check3)).toEqual({
data: {
id: '1',
type: 'users',
relationships,
attributes: {},
},
});
});

it('should be not ok', () => {
Expand Down Expand Up @@ -608,7 +623,13 @@ describe('zod-helper', () => {
},
},
};
const arrayCheck = [check1, check2, check3];
const check4 = {
data: {
id: '1',
type: 'users',
},
};
const arrayCheck = [check1, check2, check3, check4];
expect.assertions(arrayCheck.length);
for (const item of arrayCheck) {
try {
Expand Down
31 changes: 27 additions & 4 deletions libs/json-api/json-api-nestjs/src/lib/helper/zod/zod-helper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Repository } from 'typeorm';
import { z, ZodObject } from 'zod';
import { z, ZodObject, ZodUnion } from 'zod';
import { QueryField } from 'json-shared-type';

import {
Expand Down Expand Up @@ -45,6 +45,7 @@ import {

import {
PatchShape,
PatchShapeDefault,
zodPatchRelationshipsSchema,
} from './zod-input-patch-schema';

Expand Down Expand Up @@ -93,7 +94,12 @@ export type PostData<E extends Entity> = z.infer<ZodInputPostSchema<E>>['data'];

export type ZodInputPatchSchema<E extends Entity> = ZodObject<
{
data: ZodObject<PatchShape<E>, 'strict'>;
data: ZodUnion<
[
ZodObject<PatchShapeDefault<E>, 'strict'>,
ZodObject<PatchShape<E>, 'strict'>
]
>;
},
'strict'
>;
Expand Down Expand Up @@ -236,7 +242,8 @@ export const zodInputPatchSchema = <E extends Entity>(
{} as FieldWithType<E>
);
const typeName = camelToKebab(getEntityName(repository.target));
const postShape: PatchShape<E> = {

const patchShapeDefault: PatchShapeDefault<E> = {
id: zodIdSchema(primaryType),
type: zodTypeSchema(typeName),
attributes: zodAttributesSchema(fieldWithType),
Expand All @@ -247,9 +254,25 @@ export const zodInputPatchSchema = <E extends Entity>(
).optional(),
};

const patchShape: PatchShape<E> = {
id: zodIdSchema(primaryType),
type: zodTypeSchema(typeName),
attributes: zodAttributesSchema(fieldWithType)
.optional()
.default({} as any),
relationships: zodPatchRelationshipsSchema(
relationArrayProps,
relationPopsName,
primaryColumnType
),
};

return z
.object({
data: z.object(postShape).strict(),
data: z.union([
z.object(patchShapeDefault).strict(),
z.object(patchShape).strict(),
]),
})
.strict();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ import { ZodAttributesSchema } from '../zod-input-post-schema/attributes';
import { ZodTypeSchema } from '../zod-input-post-schema/type';
import { ZodIdSchema } from '../zod-input-post-schema/id';

import { ZodObject, ZodOptional } from 'zod';
import { ZodDefault, ZodObject, ZodOptional } from 'zod';
import {
ZodPatchRelationshipsSchema,
zodPatchRelationshipsSchema,
} from './relationships';

export type PatchShape<E extends Entity> = {
id: ZodIdSchema;
type: ZodTypeSchema<string>;
attributes: ZodDefault<ZodOptional<ZodAttributesSchema<E>>>;
relationships: ZodPatchRelationshipsSchema<E>;
};

export type PatchShapeDefault<E extends Entity> = {
id: ZodIdSchema;
type: ZodTypeSchema<string>;
attributes: ZodAttributesSchema<E>;
Expand Down