Skip to content

Commit e59761d

Browse files
author
Mateus Garcia
committed
feat: uuid support for relationships
1 parent c88e1fd commit e59761d

File tree

4 files changed

+71
-19
lines changed

4 files changed

+71
-19
lines changed

libs/json-api-nestjs/src/lib/config/bindings.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const Bindings: BindingsConfig = {
5050
{
5151
property: PARAMS_RESOURCE_ID,
5252
decorator: Param,
53-
mixins: [idPipeMixin],
53+
mixins: [],
5454
},
5555
{
5656
decorator: Query,
@@ -72,7 +72,7 @@ const Bindings: BindingsConfig = {
7272
{
7373
property: PARAMS_RESOURCE_ID,
7474
decorator: Param,
75-
mixins: [idPipeMixin],
75+
mixins: [],
7676
},
7777
],
7878
},
@@ -97,7 +97,7 @@ const Bindings: BindingsConfig = {
9797
{
9898
property: PARAMS_RESOURCE_ID,
9999
decorator: Param,
100-
mixins: [idPipeMixin],
100+
mixins: [],
101101
},
102102
{
103103
decorator: Body,
@@ -114,7 +114,7 @@ const Bindings: BindingsConfig = {
114114
{
115115
property: PARAMS_RESOURCE_ID,
116116
decorator: Param,
117-
mixins: [idPipeMixin],
117+
mixins: [],
118118
},
119119
{
120120
property: PARAMS_RELATION_NAME,
@@ -132,7 +132,7 @@ const Bindings: BindingsConfig = {
132132
{
133133
property: PARAMS_RESOURCE_ID,
134134
decorator: Param,
135-
mixins: [idPipeMixin],
135+
mixins: [],
136136
},
137137
{
138138
property: PARAMS_RELATION_NAME,
@@ -154,7 +154,7 @@ const Bindings: BindingsConfig = {
154154
{
155155
property: PARAMS_RESOURCE_ID,
156156
decorator: Param,
157-
mixins: [idPipeMixin],
157+
mixins: [],
158158
},
159159
{
160160
property: PARAMS_RELATION_NAME,
@@ -176,7 +176,7 @@ const Bindings: BindingsConfig = {
176176
{
177177
property: PARAMS_RESOURCE_ID,
178178
decorator: Param,
179-
mixins: [idPipeMixin],
179+
mixins: [],
180180
},
181181
{
182182
property: PARAMS_RELATION_NAME,

libs/json-api-nestjs/src/lib/factory/ajv/ajv.factory.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ export function AjvCallFactory(
2626

2727
for (const entity of options.entities) {
2828
const arrayProps: { [key: string]: boolean } = {};
29+
const uuidProps: { [key: string]: boolean } = {};
2930
const relationArrayProps: { [key: string]: { [key: string]: boolean } } =
3031
{};
32+
const relationUuids: { [key: string]: { [key: string]: boolean } } = {};
3133
const repository = dataSource.getRepository(entity);
3234
const relations = repository.metadata.relations.map((i) => {
3335
return i.propertyName;
@@ -36,6 +38,7 @@ export function AjvCallFactory(
3638
.filter((i) => !relations.includes(i.propertyName))
3739
.map((i) => {
3840
arrayProps[i.propertyName] = i.isArray;
41+
uuidProps[i.propertyName] = i.generationStrategy === 'uuid';
3942
return i.propertyName;
4043
});
4144
const relationType = repository.metadata.relations.reduce((acum, i) => {
@@ -63,6 +66,15 @@ export function AjvCallFactory(
6366
relationArrayProps[item.propertyName] =
6467
relationArrayProps[item.propertyName] || {};
6568
relationArrayProps[item.propertyName][i.propertyName] = i.isArray;
69+
70+
relationUuids[item.propertyName] =
71+
relationUuids[item.propertyName] || {};
72+
73+
if (i.isPrimary) {
74+
relationUuids[item.propertyName][i.propertyName] =
75+
i.generationStrategy === 'uuid';
76+
}
77+
6678
return i.propertyName;
6779
});
6880
const fakeObject = columns.reduce<Record<string, string>>(
@@ -110,6 +122,7 @@ export function AjvCallFactory(
110122
arrayProps,
111123
relationArrayProps,
112124
relationType,
125+
relationUuids,
113126
}
114127
),
115128
`inputBodyPostSchema-${schemaName}`
@@ -122,8 +135,10 @@ export function AjvCallFactory(
122135
`inputBodyPatchSchema-${schemaName}`,
123136
{
124137
arrayProps,
138+
uuidProps,
125139
relationArrayProps,
126140
relationType,
141+
relationUuids,
127142
}
128143
),
129144
`inputBodyPatchSchema-${schemaName}`

libs/json-api-nestjs/src/lib/factory/ajv/utils/input-body-patch-schema.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ export function inputBodyPatchSchema(
88
schemaName: string,
99
arrayPropsConfig: {
1010
arrayProps: { [key: string]: boolean };
11+
uuidProps: { [key: string]: boolean };
1112
relationArrayProps: { [key: string]: { [key: string]: boolean } };
1213
relationType: {
1314
[key: string]: Function | string;
1415
};
16+
relationUuids: { [key: string]: { [key: string]: boolean } };
1517
}
1618
): ReturnType<typeof inputBodyPostSchema> {
1719
const json = inputBodyPostSchema(
@@ -21,13 +23,18 @@ export function inputBodyPatchSchema(
2123
schemaName,
2224
arrayPropsConfig
2325
);
24-
const patternObject: Record<string, string> = {};
25-
if (
26-
Reflect.getMetadata('design:type', entity['prototype'], 'id') === Number
27-
) {
28-
patternObject.pattern = '^\\d+$';
29-
patternObject.description = 'Use string should be as number string';
26+
const patternObject: Record<string, string | number> = {};
27+
patternObject.pattern = '^\\d+$';
28+
patternObject.description = 'Use string should be as number string';
29+
30+
if (arrayPropsConfig.uuidProps.id) {
31+
patternObject.pattern =
32+
'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$';
33+
patternObject.maxLength = 36;
34+
patternObject.minLength = 36;
35+
patternObject.description = 'Use string should be as uuid string';
3036
}
37+
3138
json.properties.data.properties = {
3239
...{
3340
id: {

libs/json-api-nestjs/src/lib/factory/ajv/utils/input-body-post-schema.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export function inputBodyPostSchema(
1313
relationType: {
1414
[key: string]: Function | string;
1515
};
16+
relationUuids: { [key: string]: { [key: string]: boolean } };
1617
}
1718
): typeof inputBodySchemaJson {
1819
const json: typeof inputBodySchemaJson = JSON.parse(
@@ -23,7 +24,7 @@ export function inputBodyPostSchema(
2324
camelToKebab(getEntityName(entity))
2425
);
2526

26-
const relDataType = {
27+
const relDataType: Record<string, any> = {
2728
type: 'object',
2829
properties: {
2930
data: {
@@ -103,13 +104,41 @@ export function inputBodyPostSchema(
103104
...attributes,
104105
};
105106

107+
const uuidRelations = arrayPropsConfig.relationUuids || {};
106108
const relationships = Object.keys(relationsField).reduce((acum, item) => {
109+
const currentRelDataType = {
110+
[item]: {
111+
...relDataType,
112+
properties: {
113+
...relDataType.properties,
114+
data: {
115+
...relDataType.properties.data,
116+
properties: {
117+
...relDataType.properties.data.properties,
118+
id: {
119+
...relDataType.properties.data.properties.id,
120+
pattern: uuidRelations[item]?.id
121+
? '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
122+
: '^\\d+$',
123+
...(uuidRelations[item]?.id
124+
? {
125+
minLength: 36,
126+
maxLength: 36,
127+
}
128+
: {}),
129+
},
130+
},
131+
},
132+
},
133+
},
134+
};
135+
107136
const resultSchema = {
108-
...relDataType.properties.data,
137+
...currentRelDataType[item].properties.data,
109138
properties: {
110-
...relDataType.properties.data.properties,
139+
...currentRelDataType[item].properties.data.properties,
111140
type: {
112-
...relDataType.properties.data.properties.type,
141+
...currentRelDataType[item].properties.data.properties.type,
113142
...(arrayPropsConfig.relationType[item]
114143
? {
115144
enum: [
@@ -124,9 +153,9 @@ export function inputBodyPostSchema(
124153
};
125154

126155
acum[item] = {
127-
...relDataType,
156+
...currentRelDataType[item],
128157
properties: {
129-
...relDataType.properties,
158+
...currentRelDataType[item].properties,
130159
data:
131160
Reflect.getMetadata('design:type', entity['prototype'], item) ===
132161
Array
@@ -138,6 +167,7 @@ export function inputBodyPostSchema(
138167
: resultSchema,
139168
},
140169
};
170+
141171
return acum;
142172
}, {});
143173

0 commit comments

Comments
 (0)