Skip to content

Commit

Permalink
feat: strongly typed options for query parse functions
Browse files Browse the repository at this point in the history
  • Loading branch information
tada5hi committed Oct 19, 2022
1 parent de77de6 commit 206c653
Show file tree
Hide file tree
Showing 18 changed files with 259 additions and 135 deletions.
30 changes: 21 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"dependencies": {
"@faker-js/faker": "^7.6.0",
"locter": "^0.3.2",
"rapiq": "^0.0.6",
"rapiq": "^0.2.2",
"reflect-metadata": "^0.1.13",
"yargs": "^17.6.0"
},
Expand Down
40 changes: 21 additions & 19 deletions src/query/parameter/fields/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {
parseQueryFields,
} from 'rapiq';

import { SelectQueryBuilder } from 'typeorm';
import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';
import { buildKeyWithPrefix, getAliasForPath } from '../../utils';
import { FieldsApplyOptions, FieldsApplyOutput } from './type';

/**
Expand All @@ -12,26 +13,22 @@ import { FieldsApplyOptions, FieldsApplyOutput } from './type';
* @param data
*/
/* istanbul ignore next */
export function applyQueryFieldsParseOutput<T>(
export function applyQueryFieldsParseOutput<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T>,
data: FieldsApplyOutput,
extendSelection?: boolean,
options?: FieldsApplyOptions<T>,
) {
options = options || {};

if (data.length === 0) {
return data;
}

if (extendSelection) {
query.addSelect(data.map((field) => {
const prefix : string = (field.alias ? `${field.alias}.` : '');
return `${prefix}${field.key}`;
}));
} else {
query.select(data.map((field) => {
const prefix : string = (field.alias ? `${field.alias}.` : '');
return `${prefix}${field.key}`;
}));
}
query.select(data.map((field) => {
const alias = getAliasForPath(options.relations, field.path) ||
options.defaultAlias;
return buildKeyWithPrefix(field.key, alias);
}));

return data;
}
Expand All @@ -43,12 +40,17 @@ export function applyQueryFieldsParseOutput<T>(
* @param data
* @param options
*/
export function applyQueryFields<T>(
export function applyQueryFields<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T>,
data: unknown,
options?: FieldsApplyOptions,
options?: FieldsApplyOptions<T>,
) : FieldsApplyOutput {
return applyQueryFieldsParseOutput(query, parseQueryFields(data, options));
options = options || {};
if (options.defaultAlias) {
options.defaultPath = options.defaultAlias;
}

return applyQueryFieldsParseOutput(query, parseQueryFields(data, options), options);
}

/**
Expand All @@ -58,10 +60,10 @@ export function applyQueryFields<T>(
* @param data
* @param options
*/
export function applyFields<T>(
export function applyFields<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T>,
data: unknown,
options?: FieldsApplyOptions,
options?: FieldsApplyOptions<T>,
) : FieldsApplyOutput {
return applyQueryFields(query, data, options);
}
7 changes: 6 additions & 1 deletion src/query/parameter/fields/type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { FieldsParseOptions, FieldsParseOutput } from 'rapiq';
import { ObjectLiteral } from 'typeorm';

export type FieldsApplyOptions = FieldsParseOptions;
export type FieldsApplyOptions<
T extends ObjectLiteral = ObjectLiteral,
> = FieldsParseOptions<T> & {
defaultAlias?: string
};
export type FieldsApplyOutput = FieldsParseOutput;

export {
Expand Down
52 changes: 27 additions & 25 deletions src/query/parameter/filters/module.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import {
FiltersParseOutput,
parseQueryFilters,
} from 'rapiq';
import { FiltersParseOutput, parseQueryFilters } from 'rapiq';

import { Brackets, SelectQueryBuilder } from 'typeorm';
import { Brackets, ObjectLiteral, SelectQueryBuilder } from 'typeorm';
import { buildKeyWithPrefix, getAliasForPath } from '../../utils';
import {
FiltersApplyOptions, FiltersApplyOutput, FiltersTransformOptions, FiltersTransformOutput,
FiltersApplyOptions, FiltersApplyOutput, FiltersTransformOutput,
} from './type';

// --------------------------------------------------

export function transformParsedFilters(
data: FiltersParseOutput,
options?: FiltersTransformOptions,
options: FiltersApplyOptions,
) : FiltersTransformOutput {
options ??= {};
options = options || {};

const items : FiltersTransformOutput = [];

for (let i = 0; i < data.length; i++) {
const fullKey : string = (data[i].alias ? `${data[i].alias}.` : '') + data[i].key;
const alias = getAliasForPath(options.relations, data[i].path) ||
options.defaultAlias;

const fullKey : string = buildKeyWithPrefix(data[i].key, alias);

const filter = data[i];
filter.operator ??= {};
Expand Down Expand Up @@ -85,8 +86,8 @@ export function transformParsedFilters(
statement.push('=');
}

let bindingKey : string | undefined = typeof options.bindingKeyFn === 'function' ?
options.bindingKeyFn(fullKey) :
let bindingKey : string | undefined = typeof options.bindingKey === 'function' ?
options.bindingKey(fullKey) :
undefined;

if (typeof bindingKey === 'undefined') {
Expand Down Expand Up @@ -115,7 +116,7 @@ export function transformParsedFilters(
* @param query
* @param data
*/
export function applyFiltersTransformed<T>(
export function applyFiltersTransformed<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T>,
data: FiltersTransformOutput,
) : FiltersTransformOutput {
Expand Down Expand Up @@ -144,10 +145,10 @@ export function applyFiltersTransformed<T>(
* @param data
* @param options
*/
export function applyQueryFiltersParseOutput<T>(
export function applyQueryFiltersParseOutput<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T>,
data: FiltersParseOutput,
options?: FiltersTransformOptions,
options?: FiltersApplyOptions<T>,
) : FiltersApplyOutput {
applyFiltersTransformed(query, transformParsedFilters(data, options));

Expand All @@ -163,19 +164,20 @@ export function applyQueryFiltersParseOutput<T>(
* @param data
* @param options
*/
export function applyQueryFilters(
query: SelectQueryBuilder<any> | undefined,
export function applyQueryFilters<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T> | undefined,
data: unknown,
options?: FiltersApplyOptions,
options?: FiltersApplyOptions<T>,
) : FiltersApplyOutput {
options ??= {};

const { transform: transformOptions, ...parseOptions } = options;
options = options || {};
if (options.defaultAlias) {
options.defaultPath = options.defaultAlias;
}

return applyQueryFiltersParseOutput(
query,
parseQueryFilters(data, parseOptions),
transformOptions,
parseQueryFilters(data, options),
options,
);
}

Expand All @@ -186,10 +188,10 @@ export function applyQueryFilters(
* @param data
* @param options
*/
export function applyFilters(
query: SelectQueryBuilder<any> | undefined,
export function applyFilters<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T> | undefined,
data: unknown,
options?: FiltersApplyOptions,
options?: FiltersApplyOptions<T>,
) : FiltersApplyOutput {
return applyQueryFilters(query, data, options);
}
14 changes: 7 additions & 7 deletions src/query/parameter/filters/type.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { FiltersParseOptions, FiltersParseOutput } from 'rapiq';
import { ObjectLiteral } from 'typeorm';

export type FiltersApplyOptions = FiltersParseOptions & {
transform?: FiltersTransformOptions
};
export type FiltersApplyOptions<
T extends ObjectLiteral = ObjectLiteral,
> = FiltersParseOptions<T> & {
bindingKey?: (key: string) => string,
defaultAlias?: string
};

export type FiltersApplyOutput = FiltersParseOutput;

Expand All @@ -13,10 +17,6 @@ export {

// -----------------------------------------

export type FiltersTransformOptions = {
bindingKeyFn?: (key: string) => string,
};

export type FilterTransformOutputElement = {
statement: string,
binding: Record<string, any>
Expand Down
31 changes: 23 additions & 8 deletions src/query/parameter/relations/module.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
import { RelationsParseOutput, parseQueryRelations } from 'rapiq';
import { SelectQueryBuilder } from 'typeorm';
import { ObjectLiteral, SelectQueryBuilder } from 'typeorm';
import { buildKeyWithPrefix } from '../../utils';
import { RelationsApplyOptions, RelationsApplyOutput } from './type';

/**
* Apply parsed include/relation parameter data on the db query.
*
* @param query
* @param data
* @param options
*/
export function applyQueryRelationsParseOutput<T>(
export function applyQueryRelationsParseOutput<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T>,
data: RelationsParseOutput,
options?: RelationsApplyOptions<T>,
) : RelationsApplyOutput {
options = options || {};
for (let i = 0; i < data.length; i++) {
const parts = data[i].key.split('.');

let key : string;
if (parts.length > 1) {
key = parts.slice(-2).join('.');
} else {
key = buildKeyWithPrefix(data[i].key, options.defaultAlias);
}

data[i].key = key;

/* istanbul ignore next */
query.leftJoinAndSelect(data[i].key, data[i].value);
query.leftJoinAndSelect(key, data[i].value);
}

return data;
Expand All @@ -27,12 +42,12 @@ export function applyQueryRelationsParseOutput<T>(
* @param data
* @param options
*/
export function applyQueryRelations<T>(
export function applyQueryRelations<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T>,
data: unknown,
options?: RelationsApplyOptions,
options?: RelationsApplyOptions<T>,
) : RelationsApplyOutput {
return applyQueryRelationsParseOutput(query, parseQueryRelations(data, options));
return applyQueryRelationsParseOutput(query, parseQueryRelations(data, options), options);
}

/**
Expand All @@ -42,10 +57,10 @@ export function applyQueryRelations<T>(
* @param data
* @param options
*/
export function applyRelations<T>(
export function applyRelations<T extends ObjectLiteral = ObjectLiteral>(
query: SelectQueryBuilder<T>,
data: unknown,
options?: RelationsApplyOptions,
options?: RelationsApplyOptions<T>,
) : RelationsApplyOutput {
return applyQueryRelations(query, data, options);
}
5 changes: 4 additions & 1 deletion src/query/parameter/relations/type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { RelationsParseOptions, RelationsParseOutput } from 'rapiq';
import { ObjectLiteral } from 'typeorm';

export type RelationsApplyOptions = RelationsParseOptions;
export type RelationsApplyOptions<T extends ObjectLiteral = ObjectLiteral> = RelationsParseOptions<T> & {
defaultAlias?: string
};
export type RelationsApplyOutput = RelationsParseOutput;

export {
Expand Down
Loading

0 comments on commit 206c653

Please sign in to comment.