Skip to content

Commit ca296f1

Browse files
authored
Merge pull request #29 from klerick/add-few-operand
fix(json-api-sdk): add few operand to filter target
2 parents eafd9b6 + 515c03f commit ca296f1

File tree

4 files changed

+114
-107
lines changed

4 files changed

+114
-107
lines changed

libs/json-api-nestjs/src/lib/factory/ajv/schema/transform-query-schema.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@
139139
"description": "Operand type",
140140
"additionalProperties": false,
141141
"minProperties": 1,
142-
"maxProperties": 1,
143142
"properties": {
144143
"eq": {
145144
"type": "string"

libs/json-api-nestjs/src/lib/mixin/pipes/query-transform-schema/query-transform-schema.pipe.spec.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ describe('QueryTransformSchema', () => {
184184
});
185185

186186
describe('Check filter', () => {
187-
it('Error if operand for field more one', async () => {
187+
it('Should be correct if operand for field more one', async () => {
188188
const resultInput: QueryParams<Users> = {
189189
...resultInputMock,
190190
filter: {
@@ -197,16 +197,16 @@ describe('QueryTransformSchema', () => {
197197
relation: null,
198198
},
199199
} as any;
200-
expect.assertions(3);
200+
expect.assertions(0);
201201
try {
202202
await pipe.transform(resultInput);
203203
} catch (e) {
204204
expect(e).toBeInstanceOf(BadRequestException);
205-
const countError = e.response.message.filter(
206-
(item) => item.source.parameter.split('/')[1] === 'filter'
207-
).length;
208-
expect(e.response.message.length).toBe(countError);
209-
expect(e.response.message.length).toBeGreaterThan(0);
205+
// const countError = e.response.message.filter(
206+
// (item) => item.source.parameter.split('/')[1] === 'filter'
207+
// ).length;
208+
// expect(e.response.message.length).toBe(countError);
209+
// expect(e.response.message.length).toBeGreaterThan(0);
210210
}
211211
});
212212

libs/json-api-nestjs/src/lib/mixin/service/typeorm/utils/utils-methode.ts

Lines changed: 102 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -62,105 +62,112 @@ export class UtilsMethode {
6262
let i = 0;
6363

6464
for (field in filter) {
65-
const operand = Object.keys(filter[field]).pop();
66-
const value =
67-
operand === FilterOperand.like
68-
? `%${filter[field][operand]}%`
69-
: filter[field][operand];
70-
71-
if (relations.has(field)) {
72-
const relation = metadata.relations.find(
73-
(item) => item.propertyName === field
74-
);
75-
const {
76-
inverseSidePropertyPath,
77-
inverseEntityMetadata: { target, name },
78-
} = relation;
79-
const resourceRelationName = snakeToCamel(name);
80-
const primaryColumn = metadata.primaryColumns[0].databaseName;
81-
switch (relation.relationType) {
82-
case 'many-to-many': {
83-
const { inverseJoinColumns, joinColumns } =
84-
relation.isManyToManyOwner ? relation : relation.inverseRelation;
85-
const relationProps = relation.isManyToManyOwner
86-
? relation
87-
: relation.inverseRelation;
88-
const { joinTableName } = relationProps;
89-
const { databaseName: queryJoinPropsName } =
90-
relation.isManyToManyOwner
91-
? inverseJoinColumns[0]
92-
: joinColumns[0];
93-
const { databaseName: selectJoinPropsName } =
94-
relation.isManyToManyOwner
95-
? joinColumns[0]
96-
: inverseJoinColumns[0];
97-
const onQuery = `${joinTableName}.${queryJoinPropsName} = ${resourceRelationName}.${primaryColumn}`;
98-
const selectQuery = `${joinTableName}.${selectJoinPropsName}`;
99-
100-
const query = builder
101-
.subQuery()
102-
.select(selectQuery)
103-
.from(joinTableName, joinTableName)
104-
.leftJoin(resourceRelationName, resourceRelationName, onQuery)
105-
.where(`${selectQuery} = ${builder.alias}.${primaryColumn}`)
106-
.getQuery();
107-
resultExpression.push({
108-
expression: OperandMapForNullRelation[operand].replace(
109-
'EXPRESSION',
110-
query
111-
),
112-
params: null,
113-
});
114-
break;
65+
const operands = Object.keys(filter[field]);
66+
for (const operand of operands) {
67+
const value =
68+
operand === FilterOperand.like
69+
? `%${filter[field][operand]}%`
70+
: filter[field][operand];
71+
72+
if (relations.has(field)) {
73+
const relation = metadata.relations.find(
74+
(item) => item.propertyName === field
75+
);
76+
const {
77+
inverseSidePropertyPath,
78+
inverseEntityMetadata: { target, name },
79+
} = relation;
80+
const resourceRelationName = snakeToCamel(name);
81+
const primaryColumn = metadata.primaryColumns[0].databaseName;
82+
switch (relation.relationType) {
83+
case 'many-to-many': {
84+
const { inverseJoinColumns, joinColumns } =
85+
relation.isManyToManyOwner
86+
? relation
87+
: relation.inverseRelation;
88+
const relationProps = relation.isManyToManyOwner
89+
? relation
90+
: relation.inverseRelation;
91+
const { joinTableName } = relationProps;
92+
const { databaseName: queryJoinPropsName } =
93+
relation.isManyToManyOwner
94+
? inverseJoinColumns[0]
95+
: joinColumns[0];
96+
const { databaseName: selectJoinPropsName } =
97+
relation.isManyToManyOwner
98+
? joinColumns[0]
99+
: inverseJoinColumns[0];
100+
const onQuery = `${joinTableName}.${queryJoinPropsName} = ${resourceRelationName}.${primaryColumn}`;
101+
const selectQuery = `${joinTableName}.${selectJoinPropsName}`;
102+
103+
const query = builder
104+
.subQuery()
105+
.select(selectQuery)
106+
.from(joinTableName, joinTableName)
107+
.leftJoin(resourceRelationName, resourceRelationName, onQuery)
108+
.where(`${selectQuery} = ${builder.alias}.${primaryColumn}`)
109+
.getQuery();
110+
resultExpression.push({
111+
expression: OperandMapForNullRelation[operand].replace(
112+
'EXPRESSION',
113+
query
114+
),
115+
params: null,
116+
});
117+
break;
118+
}
119+
case 'one-to-many': {
120+
const query = builder
121+
.subQuery()
122+
.select(`${resourceRelationName}.${inverseSidePropertyPath}`)
123+
.from(target, resourceRelationName)
124+
.where(
125+
`${resourceRelationName}.${inverseSidePropertyPath} = ${builder.alias}.id`
126+
)
127+
.getQuery();
128+
resultExpression.push({
129+
expression: OperandMapForNullRelation[operand].replace(
130+
'EXPRESSION',
131+
query
132+
),
133+
params: null,
134+
});
135+
break;
136+
}
137+
default: {
138+
resultExpression.push({
139+
expression: `${preparedResourceName}.${field.toString()} ${OperandMapForNull[
140+
operand
141+
].replace(
142+
'EXPRESSION',
143+
UtilsMethode.getParamName(
144+
`${preparedResourceName}.${field}`,
145+
i
146+
)
147+
)}`,
148+
params: null,
149+
});
150+
}
115151
}
116-
case 'one-to-many': {
117-
const query = builder
118-
.subQuery()
119-
.select(`${resourceRelationName}.${inverseSidePropertyPath}`)
120-
.from(target, resourceRelationName)
121-
.where(
122-
`${resourceRelationName}.${inverseSidePropertyPath} = ${builder.alias}.id`
123-
)
124-
.getQuery();
125-
resultExpression.push({
126-
expression: OperandMapForNullRelation[operand].replace(
127-
'EXPRESSION',
128-
query
152+
} else {
153+
resultExpression.push({
154+
expression: `${preparedResourceName}.${field.toString()} ${OperandsMap[
155+
operand
156+
].replace(
157+
'EXPRESSION',
158+
UtilsMethode.getParamName(`${preparedResourceName}.${field}`, i)
159+
)}`,
160+
params: {
161+
name: UtilsMethode.getParamName(
162+
`${preparedResourceName}.${field}`,
163+
i
129164
),
130-
params: null,
131-
});
132-
break;
133-
}
134-
default: {
135-
resultExpression.push({
136-
expression: `${preparedResourceName}.${field.toString()} ${OperandMapForNull[
137-
operand
138-
].replace(
139-
'EXPRESSION',
140-
UtilsMethode.getParamName(`${preparedResourceName}.${field}`, i)
141-
)}`,
142-
params: null,
143-
});
144-
}
165+
val: value,
166+
},
167+
});
145168
}
146-
} else {
147-
resultExpression.push({
148-
expression: `${preparedResourceName}.${field.toString()} ${OperandsMap[
149-
operand
150-
].replace(
151-
'EXPRESSION',
152-
UtilsMethode.getParamName(`${preparedResourceName}.${field}`, i)
153-
)}`,
154-
params: {
155-
name: UtilsMethode.getParamName(
156-
`${preparedResourceName}.${field}`,
157-
i
158-
),
159-
val: value,
160-
},
161-
});
169+
i++;
162170
}
163-
i++;
164171
}
165172

166173
return resultExpression;

libs/json-api-nestjs/src/lib/types/query.types.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ export type Operands = {
4747
[P in FilterOperand]: Record<
4848
P,
4949
P extends MapFilterOperandTypeString ? string : string[]
50-
> &
51-
Partial<Record<Exclude<FilterOperand, P>, never>> extends infer O
52-
? { [Q in keyof O]: O[Q] }
53-
: never;
50+
>;
51+
// &
52+
// Partial<Record<Exclude<FilterOperand, P>, never>> extends infer O
53+
// ? { [Q in keyof O]: O[Q] }
54+
// : never;
5455
}[FilterOperand];
5556

5657
export type OperandsRelation = {

0 commit comments

Comments
 (0)