Skip to content

Commit

Permalink
fix: filter array value transformation + removed unnecessary methods
Browse files Browse the repository at this point in the history
  • Loading branch information
tada5hi committed Oct 18, 2022
1 parent 40d56c4 commit a02767a
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 65 deletions.
2 changes: 1 addition & 1 deletion README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ read the [docs](https://rapiq.tada5hi.net).
### Build 🏗

The first step is to construct a [BuildInput](https://rapiq.tada5hi.net/guide/build-api-reference.html#buildinput) object for a generic Record `<T>` and
pass it to the [buildQuery](https://rapiq.tada5hi.net/guide/build-api-reference.html#buildquery) method to convert it to a string.
pass it to the [buildQuery](https://rapiq.tada5hi.net/guide/build-api-reference.html#buildquery) method to convert it to a transportable string.

The result string can then be provided as a URL query string to a backend application.
The backend application can than process the request, by [parsing](#parse-) the query string.
Expand Down
12 changes: 0 additions & 12 deletions src/parameter/fields/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,6 @@ function buildReverseRecord(
return output;
}

export function replaceRecordKey(record: Record<string, any>, key: string, newKey: string) : Record<string, any> {
if (
hasOwnProperty(record, key)
) {
const value = record[key];
delete record[key];
record[newKey] = value;
}

return record;
}

export function parseQueryFields(
data: unknown,
options?: FieldsParseOptions,
Expand Down
9 changes: 5 additions & 4 deletions src/parameter/fields/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ export type FieldsBuildInput<T extends Record<string, any>> =
never
}
|
[
FieldWithOperator<SimpleKeys<T>>[],
(
FieldWithOperator<SimpleKeys<T>>[]
|
{
[K in keyof T]?: Flatten<T[K]> extends OnlyObject<T[K]> ?
FieldsBuildInput<Flatten<T[K]>> :
never
},
]
}
)[]
|
FieldWithOperator<NestedKeys<T>>[] |
FieldWithOperator<NestedKeys<T>>;
Expand Down
39 changes: 0 additions & 39 deletions src/parameter/fields/utils/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* view the LICENSE file that was distributed with this source code.
*/

import { hasOwnProperty } from '../../../utils';
import { DEFAULT_ID } from '../../../constants';

export function buildFieldDomainRecords(
Expand All @@ -25,41 +24,3 @@ export function buildFieldDomainRecords(

return domainFields;
}

export function mergeFieldsDomainRecords(
sourceA: Record<string, string[]>,
sourceB: Record<string, string[]>,
) {
const target: Record<string, string[]> = {};

let keys = Object.keys(sourceA);
for (let i = 0; i < keys.length; i++) {
if (hasOwnProperty(sourceB, keys[i])) {
target[keys[i]] = [...sourceA[keys[i]], ...sourceB[keys[i]]];
} else {
target[keys[i]] = [...sourceA[keys[i]]];
}
}

keys = Object.keys(sourceB).filter((key) => !keys.includes(key));
for (let i = 0; i < keys.length; i++) {
if (hasOwnProperty(sourceA, keys[i])) {
target[keys[i]] = [...sourceA[keys[i]], ...sourceB[keys[i]]];
} else {
target[keys[i]] = [...sourceB[keys[i]]];
}
}

keys = Object.keys(target);

if (
keys.length >= 2 &&
hasOwnProperty(target, DEFAULT_ID) &&
Array.isArray(target[DEFAULT_ID]) &&
target[DEFAULT_ID].length === 0
) {
delete target[DEFAULT_ID];
}

return target;
}
12 changes: 12 additions & 0 deletions src/parameter/filters/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,23 @@ export function buildQueryFilters<T>(
return true;
}

if (Array.isArray(input)) {
// todo: check array elements are string
output[key] = input.join(',');

return true;
}

if (isFilterOperatorConfig(input)) {
if (typeof input.value === 'undefined') {
input.value = null;
}

if (Array.isArray(input.value)) {
// todo: check array elements are string
input.value = input.value.join(',');
}

if (Array.isArray(input.operator)) {
// merge operators
input.operator = input.operator
Expand Down
4 changes: 2 additions & 2 deletions src/parameter/filters/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ type FilterValueInput = FilterValueInputPrimitive | null | undefined;

export type FilterValueSimple<V extends FilterValueInput = FilterValueInput> = V extends FilterValueInputPrimitive ? (V | V[]) : V;
export type FilterValueWithOperator<V extends FilterValueInput = FilterValueInput> = V extends string | number ?
`!${V}` | `!~${V}` | `~${V}` | `<${V}` | `<=${V}` | `>${V}` | `>=${V}` :
never;
`!${V}` | `!~${V}` | `~${V}` | `<${V}` | `<=${V}` | `>${V}` | `>=${V}` | null | '!null' :
V extends boolean ? null | '!null' : never;

export type FilterValue<V extends FilterValueInput = FilterValueInput> = V extends FilterValueInputPrimitive ?
(FilterValueSimple<V> | FilterValueWithOperator<V> | Array<FilterValueWithOperator<V>>) :
Expand Down
15 changes: 8 additions & 7 deletions src/parse/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import {
FieldsParseOutput,
FiltersParseOutput,
PaginationParseOutput, RelationsParseOutput,
PaginationParseOutput,
RelationsParseOutput,
SortParseOutput,
parseQueryRelations,
} from '../parameter';
import { Parameter, URLParameter } from '../constants';
import { parseQueryParameter } from './parameter';
Expand Down Expand Up @@ -43,7 +43,8 @@ export function parseQuery(
case Parameter.RELATIONS: {
const value = input[Parameter.RELATIONS] ?? input[URLParameter.RELATIONS];
if (value || options[Parameter.RELATIONS]) {
relations = parseQueryRelations(
relations = parseQueryParameter(
key,
value,
options[Parameter.RELATIONS],
);
Expand All @@ -56,7 +57,7 @@ export function parseQuery(
const value = input[Parameter.FIELDS] ?? input[URLParameter.FIELDS];
if (value || options[Parameter.FIELDS]) {
output[Parameter.FIELDS] = parseQueryParameter(
keys[i],
key,
value,
options[Parameter.FIELDS],
relations,
Expand All @@ -68,7 +69,7 @@ export function parseQuery(
const value = input[Parameter.FILTERS] ?? input[URLParameter.FILTERS];
if (value || options[Parameter.FILTERS]) {
output[Parameter.FILTERS] = parseQueryParameter(
keys[i],
key,
value,
options[Parameter.FILTERS],
relations,
Expand All @@ -80,7 +81,7 @@ export function parseQuery(
const value = input[Parameter.PAGINATION] ?? input[URLParameter.PAGINATION];
if (value || options[Parameter.PAGINATION]) {
output[Parameter.PAGINATION] = parseQueryParameter(
keys[i],
key,
value,
options[Parameter.PAGINATION],
relations,
Expand All @@ -92,7 +93,7 @@ export function parseQuery(
const value = input[Parameter.SORT] ?? input[URLParameter.SORT];
if (value || options[Parameter.SORT]) {
output[Parameter.SORT] = parseQueryParameter(
keys[i],
key,
value,
options[Parameter.SORT],
relations,
Expand Down
47 changes: 47 additions & 0 deletions test/unit/build.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ describe('src/build.ts', () => {
});
expect(record).toEqual(buildURLQueryString({ [URLParameter.FILTERS]: { 'child.id': 1 } }));

record = buildQuery<Entity>({
filter: {
'child.id': 1,
child: {
'child.id': 'abc'
},
},
});
expect(record).toEqual(buildURLQueryString({ [URLParameter.FILTERS]: {
'child.id': 1,
'child.child.id': 'abc'
} }));

record = buildQuery<Entity>({
filter: {
siblings: {
Expand Down Expand Up @@ -136,6 +149,14 @@ describe('src/build.ts', () => {
expect(record).toEqual(buildURLQueryString({ [URLParameter.FILTERS]: { id: '>=1' } }));

// with negation & in operator
record = buildQuery<Entity>({
filter: {
id: [1,2,3],
},
});
expect(record).toEqual(buildURLQueryString({ [URLParameter.FILTERS]: { id: '1,2,3' } }));

// with negation & like operator
record = buildQuery<Entity>({
filter: {
id: {
Expand Down Expand Up @@ -200,6 +221,32 @@ describe('src/build.ts', () => {
});

expect(record).toEqual(buildURLQueryString({ fields: { [DEFAULT_ID]: ['id'], child: ['id', 'name'] } }));

record = buildQuery<Entity>({
fields: [
['id'],
['name'],
{
child: ['id', 'name'],
}
]
});

expect(record).toEqual(buildURLQueryString({ fields: { [DEFAULT_ID]: ['id', 'name'], child: ['id', 'name'] } }));
record = buildQuery<Entity>({
fields: [
['id'],
{
child: ['id'],
},
{
child: ['name'],
}
]
});

expect(record).toEqual(buildURLQueryString({ fields: { [DEFAULT_ID]: ['id'], child: ['id', 'name'] } }));

});

it('should format sort record', () => {
Expand Down
24 changes: 24 additions & 0 deletions test/unit/filters.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
parseQueryFilters,
parseQueryRelations,
} from '../../src';
import {isFilterOperatorConfig} from "../../src/parameter/filters/utils";

describe('src/filter/index.ts', () => {
it('should transform request filters', () => {
Expand Down Expand Up @@ -349,4 +350,27 @@ describe('src/filter/index.ts', () => {
},
] as FiltersParseOutput);
});

it('should determine filter operator config', () => {
let data = isFilterOperatorConfig({
value: 1,
operator: '<'
});

expect(data).toBeTruthy();

data = isFilterOperatorConfig({
value: 1,
operator: {}
})

expect(data).toBeFalsy();

data = isFilterOperatorConfig({
value: {},
operator: '<'
});

expect(data).toBeFalsy();
})
});

0 comments on commit a02767a

Please sign in to comment.