From 1c0e59f4981b1b2ce6b2d671f670243486719142 Mon Sep 17 00:00:00 2001 From: tada5hi Date: Sat, 22 Oct 2022 17:30:38 +0200 Subject: [PATCH] fix: cleanup types + support more filter input values --- README.MD | 3 +- docs/guide/fields-api-reference.md | 9 +- docs/guide/filters-api-reference.md | 6 +- docs/guide/parse.md | 160 +++++++----------- docs/guide/sort-api-reference.md | 8 +- src/parameter/fields/parse.ts | 6 +- src/parameter/fields/type.ts | 6 +- src/parameter/filters/parse.ts | 43 +++-- src/parameter/filters/type.ts | 14 +- src/parameter/filters/utils/operator.ts | 69 +++++--- src/parameter/filters/utils/value.ts | 11 +- src/parameter/relations/parse.ts | 20 +-- src/parameter/sort/parse.ts | 6 +- src/parameter/sort/type.ts | 10 +- src/parameter/type.ts | 10 +- .../{options-allowed.ts => allowed-option.ts} | 10 +- src/parameter/utils/parse/index.ts | 2 +- test/unit/utils.spec.ts | 34 ++-- 18 files changed, 214 insertions(+), 213 deletions(-) rename src/parameter/utils/parse/{options-allowed.ts => allowed-option.ts} (76%) diff --git a/README.MD b/README.MD index 38facbe3..165858fe 100644 --- a/README.MD +++ b/README.MD @@ -245,7 +245,8 @@ import { /** * Get many users. * - * ... + * Request example + * - url: /users?page[limit]=10&page[offset]=0&include=realm&filter[id]=1&fields=id,name * * @param req * @param res diff --git a/docs/guide/fields-api-reference.md b/docs/guide/fields-api-reference.md index 554ce70a..2a35ed0e 100644 --- a/docs/guide/fields-api-reference.md +++ b/docs/guide/fields-api-reference.md @@ -85,12 +85,11 @@ const input : FieldsBuildInput = [ ## `FieldsParseOptions` ```typescript -type FieldsParseOptions< - T extends Record = Record, -> = { +type FieldsParseOptions = Record, + > = { mapping?: Record, - allowed?: ParseOptionsAllowed, - default?: ParseOptionsAllowed, + allowed?: ParseAllowedOption, + default?: ParseAllowedOption, defaultPath?: string, relations?: RelationsParseOutput }; diff --git a/docs/guide/filters-api-reference.md b/docs/guide/filters-api-reference.md index cd527899..cd017980 100644 --- a/docs/guide/filters-api-reference.md +++ b/docs/guide/filters-api-reference.md @@ -149,7 +149,7 @@ const input : FiltersBuildInput = { ```typescript type FiltersParseOptionsDefault> = { [K in keyof T]?: Flatten extends OnlyObject ? - FiltersParseOptionsDefault> : + FiltersParseDefaultOption> : (K extends string ? FilterValue> : never) } | { [K in NestedKeys]?: FilterValue> @@ -159,8 +159,8 @@ type FiltersParseOptions< T extends Record = Record, > = { mapping?: Record, - allowed?: ParseOptionsAllowed, - default?: FiltersParseOptionsDefault, + allowed?: ParseAllowedOption, + default?: FiltersParseDefaultOption, defaultByElement?: boolean, defaultPath?: string, relations?: RelationsParseOutput diff --git a/docs/guide/parse.md b/docs/guide/parse.md index 8d5dea60..4fbedc66 100644 --- a/docs/guide/parse.md +++ b/docs/guide/parse.md @@ -81,98 +81,65 @@ export class Item { } ``` -## Extended Example +## Separate -In the following code snippet, all query parameter parse functions (`parseQueryFields`, `parseQueryFilters`, ...) -will be imported separately, to show the usage in detail. +The following variant will `parse` and `apply` the query parameters in **two** steps. + +After the [ParseOutput](parse-api-reference.md#parseoutput) is generated using the [parseQuery](parse-api-reference.md#parsequery) function, +the output can be applied on the typeorm QueryBuilder using the `applyQueryParseOutput` function of +the [typeorm-extension](https://www.npmjs.com/package/typeorm-extension). ```typescript -import {Request, Response} from 'express'; +import { Request, Response } from 'express'; import { - parseQueryFields, - parseQueryFilters, - parseQueryRelations, - parseQueryPagination, - parseQuerySort, -} from "rapiq"; + parseQuery, + ParseOutput +} from 'rapiq'; import { applyQueryParseOutput, useDataSource } from 'typeorm-extension'; -import { User } from './entities'; - /** * Get many users. * * Request example * - url: /users?page[limit]=10&page[offset]=0&include=realm&filter[id]=1&fields=id,name * - * Return Example: - * { - * data: [ - * { - * id: 1, - * name: 'tada5hi', - * realm: { - * id: 'xxx', - * name: 'xxx' - * } - * } - * ], - * meta: { - * total: 1, - * limit: 20, - * offset: 0 - * } - * } * @param req * @param res */ export async function getUsers(req: Request, res: Response) { - const {fields, filter, include, page, sort} = req.query; - - const dataSource = await useDataSource(); - const repository = dataSource.getRepository(User); - const query = repository.createQueryBuilder('user'); - - // ----------------------------------------------------- - - const parsed = applyQueryParseOutput(query, { + const output: ParseOutput = parseQuery(req.query, { defaultPath: 'user', - fields: parseQueryFields(fields, { - defaultPath: 'user', - // The fields id & name of the realm entity can only be used, - // if the relation 'realm' is included. + fields: { allowed: ['id', 'name', 'realm.id', 'realm.name'], - relations: relationsParsed - }), - // only allow filtering users by id & name - filters: parseQueryFilters(filter, { - defaultPath: 'user', - // realm.id can only be used as filter key, - // if the relation 'realm' is included. + }, + filters: { allowed: ['id', 'name', 'realm.id'], - relations: relationsParsed - }), - relations: parseQueryRelations(include, { + }, + relations: { allowed: ['items', 'realm'] - }), - // only allow to select 20 items at maximum. - pagination: parseQueryPagination(page, { + }, + pagination: { maxLimit: 20 - }), - sort: parseQuerySort(sort, { - defaultPath: 'user', - // profile.id can only be used as sorting key, - // if the relation 'realm' is included. + }, + sort: { allowed: ['id', 'name', 'realm.id'], - relations: relationsParsed - }) + } }); + const dataSource = await useDataSource(); + const repository = dataSource.getRepository(User); + const query = repository.createQueryBuilder('user'); + + // ----------------------------------------------------- + + // apply parsed data on the db query. + applyQueryParseOutput(query, output); + // ----------------------------------------------------- const [entities, total] = await query.getManyAndCount(); @@ -182,70 +149,73 @@ export async function getUsers(req: Request, res: Response) { data: entities, meta: { total, - ...parsed.pagination + ...output.pagination } } }); } ``` -## Simple Example +## Compact -Another way is to directly import the [parseQuery](parse-api-reference#parsequery) method, which will handle a group of query parameter values & options. -The [ParseInput](parse-api-reference#parseinput) argument of the `parseQuery` method accepts multiple (alias-) property keys. +Another way is to use the `applyQuery` function which will `parse` and `apply` the query parameters in **one** step. -```typescript -import { Request, Response } from 'express'; +This is much shorter than the previous example and has less explicit dependencies ⚡. -import { - parseQuery, - ParseOutput -} from 'rapiq'; +```typescript +import {Request, Response} from 'express'; import { - applyQueryParseOutput, + applyQuery, useDataSource } from 'typeorm-extension'; +import { User } from './entities'; + /** * Get many users. * - * ... + * Request example + * - url: /users?page[limit]=10&page[offset]=0&include=realm&filter[id]=1&fields=id,name * * @param req * @param res */ export async function getUsers(req: Request, res: Response) { - // const {fields, filter, include, page, sort} = req.query; + const dataSource = await useDataSource(); + const repository = dataSource.getRepository(User); + const query = repository.createQueryBuilder('user'); - const output: ParseOutput = parseQuery(req.query, { - defaultPath: 'user', + // ----------------------------------------------------- + + const { pagination } = applyQuery(query, req.query, { + // defaultAlais is an alias for the defaultPath option + defaultAlias: 'user', fields: { - allowed: ['id', 'name', 'realm.id', 'realm.name'], + // The fields id & name of the realm entity can only be used, + // if the relation 'realm' is included. + allowed: ['id', 'name', 'realm.id', 'realm.name'] }, + // only allow filtering users by id & name filters: { - allowed: ['id', 'name', 'realm.id'], + // realm.id can only be used as filter key, + // if the relation 'realm' is included. + allowed: ['id', 'name', 'realm.id'] }, relations: { allowed: ['items', 'realm'] }, + // only allow to select 20 items at maximum. pagination: { maxLimit: 20 }, sort: { - allowed: ['id', 'name', 'realm.id'], + // profile.id can only be used as sorting key, + // if the relation 'realm' is included. + allowed: ['id', 'name', 'realm.id'] } }); - const dataSource = await useDataSource(); - const repository = dataSource.getRepository(User); - const query = repository.createQueryBuilder('user'); - - // ----------------------------------------------------- - - // apply parsed data on the db query. - const parsed = applyQueryParseOutput(query, output); - // ----------------------------------------------------- const [entities, total] = await query.getManyAndCount(); @@ -255,17 +225,9 @@ export async function getUsers(req: Request, res: Response) { data: entities, meta: { total, - ...output.pagination + ...pagination } } }); } ``` - -## Third Party Support - -It can even be much simpler to parse the query key-value pairs with the `typeorm-extension` library, because it -uses this library under the hood ⚡. -This is much shorter than the previous example and has less explicit dependencies 😁. - -[read more](https://www.npmjs.com/package/typeorm-extension) diff --git a/docs/guide/sort-api-reference.md b/docs/guide/sort-api-reference.md index 0d872e7e..8ef6d2e5 100644 --- a/docs/guide/sort-api-reference.md +++ b/docs/guide/sort-api-reference.md @@ -73,9 +73,9 @@ const input : SortBuildInput = [ ## `SortParseOptions` ```typescript -type SortParseOptionsDefault> = { +type SortPaseDefaultOption> = { [K in keyof T]?: Flatten extends OnlyObject ? - SortParseOptionsDefault> : + SortPaseDefaultOption> : `${SortDirection}` } | { [K in NestedKeys]?: `${SortDirection}` @@ -84,9 +84,9 @@ type SortParseOptionsDefault> = { type SortParseOptions< T extends Record = Record, > = { - allowed?: ParseOptionsAllowed | ParseOptionsAllowed[], + allowed?: ParseAllowedOption, mapping?: Record, - default?: SortParseOptionsDefault, + default?: SortPaseDefaultOption, defaultPath?: string, relations?: RelationsParseOutput, }; diff --git a/src/parameter/fields/parse.ts b/src/parameter/fields/parse.ts index 8a1031b9..a1cc208d 100644 --- a/src/parameter/fields/parse.ts +++ b/src/parameter/fields/parse.ts @@ -10,7 +10,7 @@ import { ObjectLiteral } from '../../type'; import { applyMapping, buildFieldWithPath, groupArrayByKeyPath, hasOwnProperty, isFieldPathAllowedByRelations, } from '../../utils'; -import { flattenParseOptionsAllowed } from '../utils'; +import { flattenParseAllowedOption } from '../utils'; import { FieldsInputTransformed, FieldsParseOptions, FieldsParseOutput, } from './type'; @@ -42,11 +42,11 @@ export function parseQueryFields( options ??= {}; const defaultDomainFields = groupArrayByKeyPath( - flattenParseOptionsAllowed(options.default), + flattenParseAllowedOption(options.default), ); const allowedDomainFields = groupArrayByKeyPath( - flattenParseOptionsAllowed(options.allowed), + flattenParseAllowedOption(options.allowed), ); const domainFields = merge( diff --git a/src/parameter/fields/type.ts b/src/parameter/fields/type.ts index 07a0e17e..0e41c49a 100644 --- a/src/parameter/fields/type.ts +++ b/src/parameter/fields/type.ts @@ -10,7 +10,7 @@ import { } from '../../type'; import { RelationsParseOutput } from '../relations'; import { - ParseAllowedKeys, + ParseAllowedOption, } from '../type'; import { FieldOperator } from './constants'; @@ -48,8 +48,8 @@ export type FieldsParseOptions< T extends Record = Record, > = { mapping?: Record, - allowed?: ParseAllowedKeys, - default?: ParseAllowedKeys, + allowed?: ParseAllowedOption, + default?: ParseAllowedOption, defaultPath?: string, relations?: RelationsParseOutput, }; diff --git a/src/parameter/filters/parse.ts b/src/parameter/filters/parse.ts index 842327bf..cfa1bd93 100644 --- a/src/parameter/filters/parse.ts +++ b/src/parameter/filters/parse.ts @@ -14,7 +14,7 @@ import { getFieldDetails, hasOwnProperty, isFieldNonRelational, isFieldPathAllowedByRelations, } from '../../utils'; -import { isPathCoveredByParseAllowed } from '../utils'; +import { isPathCoveredByParseAllowedOption } from '../utils'; import { FilterComparisonOperator } from './constants'; import { FiltersParseOptions, FiltersParseOutput, FiltersParseOutputElement } from './type'; import { parseFilterValue, transformFilterValue } from './utils'; @@ -150,27 +150,19 @@ export function parseQueryFilters( continue; } - let value : unknown = data[keys[i]]; + const value : unknown = data[keys[i]]; if ( typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean' && - value !== null + typeof value !== 'undefined' && + value !== null && + !Array.isArray(value) ) { - // eslint-disable-next-line no-continue continue; } - if (typeof value === 'string') { - value = value.trim(); - const stripped : string = (value as string).replace('/,/g', ''); - if (stripped.length === 0) { - // eslint-disable-next-line no-continue - continue; - } - } - keys[i] = applyMapping(keys[i], options.mapping); const fieldDetails : FieldDetails = getFieldDetails(keys[i]); @@ -186,7 +178,7 @@ export function parseQueryFilters( if ( options.allowed && - !isPathCoveredByParseAllowed(options.allowed, [keys[i], fullKey]) + !isPathCoveredByParseAllowedOption(options.allowed, [keys[i], fullKey]) ) { continue; } @@ -198,7 +190,14 @@ export function parseQueryFilters( if (options.validate) { if (Array.isArray(filter.value)) { - filter.value = (filter.value as any[]).filter((item: unknown) => options.validate(filter.key as NestedKeys, item)); + const output : (string | number)[] = []; + for (let j = 0; j < filter.value.length; j++) { + if (options.validate(filter.key as NestedKeys, filter.value[j])) { + output.push(filter.value[j]); + } + } + + filter.value = output as string[] | number[]; if (filter.value.length === 0) { continue; } @@ -207,6 +206,20 @@ export function parseQueryFilters( } } + if ( + typeof filter.value === 'string' && + filter.value.length === 0 + ) { + continue; + } + + if ( + Array.isArray(filter.value) && + filter.value.length === 0 + ) { + continue; + } + if (fieldDetails.path || options.defaultPath) { filter.path = fieldDetails.path || options.defaultPath; } diff --git a/src/parameter/filters/type.ts b/src/parameter/filters/type.ts index 9cd9681c..2d54a77a 100644 --- a/src/parameter/filters/type.ts +++ b/src/parameter/filters/type.ts @@ -11,7 +11,7 @@ import { } from '../../type'; import { RelationsParseOutput } from '../relations'; import { - ParseAllowedKeys, + ParseAllowedOption, } from '../type'; import { FilterComparisonOperator } from './constants'; @@ -47,26 +47,26 @@ export type FiltersBuildInput> = { // Parse // ----------------------------------------------------------- -export type FiltersDefaultKeys> = { +export type FiltersParseDefaultOption> = { [K in keyof T]?: Flatten extends OnlyObject ? - FiltersDefaultKeys> : + FiltersParseDefaultOption> : (K extends string ? FilterValue> : never) } | { [K in NestedKeys]?: FilterValue> }; -export type FiltersValidator = (key: K, value: unknown) => boolean; +export type FiltersValidatorOption = (key: K, value: unknown) => boolean; export type FiltersParseOptions< T extends ObjectLiteral = ObjectLiteral, > = { mapping?: Record, - allowed?: ParseAllowedKeys, - default?: FiltersDefaultKeys, + allowed?: ParseAllowedOption, + default?: FiltersParseDefaultOption, defaultByElement?: boolean, defaultPath?: string, relations?: RelationsParseOutput, - validate?: FiltersValidator> + validate?: FiltersValidatorOption> }; export type FiltersParseOutputElement = { diff --git a/src/parameter/filters/utils/operator.ts b/src/parameter/filters/utils/operator.ts index d2b02ac6..8f0e1037 100644 --- a/src/parameter/filters/utils/operator.ts +++ b/src/parameter/filters/utils/operator.ts @@ -6,30 +6,57 @@ */ import { FilterComparisonOperator, FilterInputOperatorValue } from '../constants'; +import { FilterValueSimple } from '../type'; -function matchOperator(key: string, value: string, position: 'start' | 'end' | 'global') : string | undefined { - switch (position) { - case 'start': { - if (value.substring(0, key.length) === key) { - return value.substring(key.length); +function matchOperator(key: string, value: FilterValueSimple, position: 'start' | 'end' | 'global') : FilterValueSimple | undefined { + if (typeof value === 'string') { + switch (position) { + case 'start': { + if (value.substring(0, key.length) === key) { + return value.substring(key.length); + } + break; + } + case 'end': { + if (value.substring(0 - key.length) === key) { + return value.substring(0, value.length - key.length - 1); + } + break; } - break; } - case 'end': { - if (value.substring(0 - key.length) === key) { - return value.substring(0, value.length - key.length - 1); + + return undefined; + } + + if (Array.isArray(value)) { + let match = false; + for (let i = 0; i < value.length; i++) { + const output = matchOperator(key, value[i], position); + if (typeof output !== 'undefined') { + match = true; + value[i] = output as string | number; } - break; + } + + if (match) { + return value; } } return undefined; } -export function parseFilterValue(input: string) : { +export function parseFilterValue(input: FilterValueSimple) : { operator: `${FilterComparisonOperator}`, - value: string | string[] + value: FilterValueSimple } { + if ( + typeof input === 'string' && + input.includes(FilterInputOperatorValue.IN) + ) { + input = input.split(FilterInputOperatorValue.IN); + } + let negation = false; let value = matchOperator(FilterInputOperatorValue.NEGATION, input, 'start'); @@ -38,6 +65,15 @@ export function parseFilterValue(input: string) : { input = value; } + if (Array.isArray(input)) { + return { + value: input, + operator: negation ? + FilterComparisonOperator.NOT_IN : + FilterComparisonOperator.IN, + }; + } + value = matchOperator(FilterInputOperatorValue.LIKE, input, 'start'); if (typeof value !== 'undefined') { return { @@ -80,15 +116,6 @@ export function parseFilterValue(input: string) : { }; } - if (input.includes(FilterInputOperatorValue.IN)) { - return { - value: input.split(FilterInputOperatorValue.IN), - operator: negation ? - FilterComparisonOperator.NOT_IN : - FilterComparisonOperator.IN, - }; - } - return { value: input, operator: negation ? diff --git a/src/parameter/filters/utils/value.ts b/src/parameter/filters/utils/value.ts index 00c58739..86d719c5 100644 --- a/src/parameter/filters/utils/value.ts +++ b/src/parameter/filters/utils/value.ts @@ -5,11 +5,12 @@ * view the LICENSE file that was distributed with this source code. */ -import { FilterValue, FilterValueSimple } from '../type'; +import { FilterValueSimple } from '../type'; -export function transformFilterValue(input: FilterValue) : FilterValueSimple { +export function transformFilterValue(input: FilterValueSimple) : FilterValueSimple { if (typeof input === 'string') { - const lower = input.trim().toLowerCase(); + input = input.trim(); + const lower = input.toLowerCase(); if (lower === 'true') { return true; @@ -23,6 +24,10 @@ export function transformFilterValue(input: FilterValue) : FilterValueSimple { return null; } + if (input.length === 0) { + return input; + } + const num = Number(input); if (!Number.isNaN(num)) { return num; diff --git a/src/parameter/relations/parse.ts b/src/parameter/relations/parse.ts index f9e705e0..9528d5f8 100644 --- a/src/parameter/relations/parse.ts +++ b/src/parameter/relations/parse.ts @@ -8,7 +8,7 @@ import minimatch from 'minimatch'; import { ObjectLiteral } from '../../type'; import { applyMapping, hasOwnProperty } from '../../utils'; -import { isPathCoveredByParseAllowed } from '../utils'; +import { isPathCoveredByParseAllowedOption } from '../utils'; import { RelationsParseOptions, RelationsParseOutput } from './type'; import { includeParents } from './utils'; @@ -55,12 +55,15 @@ export function parseQueryRelations( return []; } - for (let i = 0; i < items.length; i++) { - items[i] = applyMapping(items[i], options.mapping); + const mappingKeys = Object.keys(options.mapping); + if (mappingKeys.length > 0) { + for (let i = 0; i < items.length; i++) { + items[i] = applyMapping(items[i], options.mapping); + } } if (options.allowed) { - items = items.filter((item) => isPathCoveredByParseAllowed(options.allowed, item)); + items = items.filter((item) => isPathCoveredByParseAllowedOption(options.allowed, item)); } if (options.includeParents) { @@ -81,15 +84,6 @@ export function parseQueryRelations( .map((key) => { const parts = key.split('.'); - /* - let key : string; - if (path.includes('.')) { - key = parts.slice(-2).join('.'); - } else { - key = options.defaultAlias ? `${options.defaultAlias}.${path}` : path; - } - */ - let value : string; if ( options.pathMapping && diff --git a/src/parameter/sort/parse.ts b/src/parameter/sort/parse.ts index acbb9540..b16384f8 100644 --- a/src/parameter/sort/parse.ts +++ b/src/parameter/sort/parse.ts @@ -13,7 +13,7 @@ import { hasOwnProperty, isFieldNonRelational, isFieldPathAllowedByRelations, } from '../../utils'; -import { flattenParseOptionsAllowed, isPathCoveredByParseAllowed } from '../utils'; +import { flattenParseAllowedOption, isPathCoveredByParseAllowedOption } from '../utils'; import { SortParseOptions, @@ -149,7 +149,7 @@ export function parseQuerySort( if ( typeof options.allowed !== 'undefined' && !isMultiDimensionalArray(options.allowed) && - !isPathCoveredByParseAllowed(options.allowed, [key, keyWithAlias]) + !isPathCoveredByParseAllowedOption(options.allowed, [key, keyWithAlias]) ) { continue; } @@ -180,7 +180,7 @@ export function parseQuerySort( for (let i = 0; i < options.allowed.length; i++) { const temp : SortParseOutput = []; - const keyPaths = flattenParseOptionsAllowed(options.allowed[i]); + const keyPaths = flattenParseAllowedOption(options.allowed[i]); for (let j = 0; j < keyPaths.length; j++) { let keyWithAlias : string = keyPaths[j]; diff --git a/src/parameter/sort/type.ts b/src/parameter/sort/type.ts index 8b630cb1..60c3ebe9 100644 --- a/src/parameter/sort/type.ts +++ b/src/parameter/sort/type.ts @@ -10,7 +10,7 @@ import { } from '../../type'; import { RelationsParseOutput } from '../relations'; import { - ParseAllowedKeys, + ParseAllowedOption, } from '../type'; export enum SortDirection { @@ -47,9 +47,9 @@ export type SortBuildInput> = // Parse // ----------------------------------------------------------- -export type SortParseOptionsDefault> = { +export type SortParseDefaultOption> = { [K in keyof T]?: Flatten extends OnlyObject ? - SortParseOptionsDefault> : + SortParseDefaultOption> : `${SortDirection}` } | { [K in NestedKeys]?: `${SortDirection}` @@ -58,9 +58,9 @@ export type SortParseOptionsDefault> = { export type SortParseOptions< T extends Record = Record, > = { - allowed?: ParseAllowedKeys, + allowed?: ParseAllowedOption, mapping?: Record, - default?: SortParseOptionsDefault, + default?: SortParseDefaultOption, defaultPath?: string, relations?: RelationsParseOutput, }; diff --git a/src/parameter/type.ts b/src/parameter/type.ts index 29881af0..82a46dc7 100644 --- a/src/parameter/type.ts +++ b/src/parameter/type.ts @@ -11,18 +11,18 @@ import { // ----------------------------------------------------------- -type ParseAllowedObject = { +type ParseAllowedObjectOption = { [K in keyof T]?: T[K] extends OnlyObject ? - ParseAllowedKeys> : + ParseAllowedOption> : never }; -export type ParseAllowedKeys = T extends ObjectLiteral ? +export type ParseAllowedOption = T extends ObjectLiteral ? ( - ParseAllowedObject | + ParseAllowedObjectOption | ( SimpleKeys[] | - ParseAllowedObject + ParseAllowedObjectOption )[] | NestedKeys[] diff --git a/src/parameter/utils/parse/options-allowed.ts b/src/parameter/utils/parse/allowed-option.ts similarity index 76% rename from src/parameter/utils/parse/options-allowed.ts rename to src/parameter/utils/parse/allowed-option.ts index f645c252..4a4c9634 100644 --- a/src/parameter/utils/parse/options-allowed.ts +++ b/src/parameter/utils/parse/allowed-option.ts @@ -7,16 +7,16 @@ import { NestedKeys, NestedResourceKeys } from '../../../type'; import { flattenToKeyPathArray } from '../../../utils'; -import { ParseAllowedKeys } from '../../type'; +import { ParseAllowedOption } from '../../type'; -export function flattenParseOptionsAllowed( - input: ParseAllowedKeys, +export function flattenParseAllowedOption( + input: ParseAllowedOption, ) : string[] { return flattenToKeyPathArray(input); } -export function isPathCoveredByParseAllowed( - input: ParseAllowedKeys | +export function isPathCoveredByParseAllowedOption( + input: ParseAllowedOption | NestedKeys[] | NestedResourceKeys[], path: string | string[], diff --git a/src/parameter/utils/parse/index.ts b/src/parameter/utils/parse/index.ts index 00dbac16..4022af77 100644 --- a/src/parameter/utils/parse/index.ts +++ b/src/parameter/utils/parse/index.ts @@ -5,4 +5,4 @@ * view the LICENSE file that was distributed with this source code. */ -export * from './options-allowed'; +export * from './allowed-option'; diff --git a/test/unit/utils.spec.ts b/test/unit/utils.spec.ts index 7fcc1ce4..a24ba204 100644 --- a/test/unit/utils.spec.ts +++ b/test/unit/utils.spec.ts @@ -5,7 +5,7 @@ * view the LICENSE file that was distributed with this source code. */ -import { flattenParseOptionsAllowed, isPathCoveredByParseAllowed} from "../../src"; +import { flattenParseAllowedOption, isPathCoveredByParseAllowedOption} from "../../src"; import {applyMapping} from "../../src/utils"; import { User } from "../data"; @@ -31,10 +31,10 @@ describe('src/utils/*.ts', () => { }); it('should flatten nested parse option keys', () => { - let data = flattenParseOptionsAllowed(['id', 'name']); + let data = flattenParseAllowedOption(['id', 'name']); expect(data).toEqual(['id', 'name']); - data = flattenParseOptionsAllowed({ + data = flattenParseAllowedOption({ realm: ['id'], items: ['realm.name'] }); @@ -46,56 +46,56 @@ describe('src/utils/*.ts', () => { }); it('should verify if path is covered by parse options', () => { - let result = isPathCoveredByParseAllowed(['id', 'name'], 'id'); + let result = isPathCoveredByParseAllowedOption(['id', 'name'], 'id'); expect(result).toBeTruthy(); - result = isPathCoveredByParseAllowed(['id', 'name'], 'description'); + result = isPathCoveredByParseAllowedOption(['id', 'name'], 'description'); expect(result).toBeFalsy(); // ----------------------------------------------------------- - result = isPathCoveredByParseAllowed({realm: ['id', 'name']}, 'realm.id'); + result = isPathCoveredByParseAllowedOption({realm: ['id', 'name']}, 'realm.id'); expect(result).toBeTruthy(); - result = isPathCoveredByParseAllowed({realm: ['id', 'name']}, 'realm.description'); + result = isPathCoveredByParseAllowedOption({realm: ['id', 'name']}, 'realm.description'); expect(result).toBeFalsy(); // ----------------------------------------------------------- - result = isPathCoveredByParseAllowed(['realm.id', 'realm.name'], 'realm.id'); + result = isPathCoveredByParseAllowedOption(['realm.id', 'realm.name'], 'realm.id'); expect(result).toBeTruthy(); - result = isPathCoveredByParseAllowed(['realm.id', 'realm.name'], 'realm.description'); + result = isPathCoveredByParseAllowedOption(['realm.id', 'realm.name'], 'realm.description'); expect(result).toBeFalsy(); // ----------------------------------------------------------- - result = isPathCoveredByParseAllowed([['name'], { realm: ['id'] }], 'name'); + result = isPathCoveredByParseAllowedOption([['name'], { realm: ['id'] }], 'name'); expect(result).toBeTruthy(); - result = isPathCoveredByParseAllowed([['name'], { realm: ['id'] }], 'id'); + result = isPathCoveredByParseAllowedOption([['name'], { realm: ['id'] }], 'id'); expect(result).toBeFalsy(); - result = isPathCoveredByParseAllowed([['name'], { realm: ['id'] }], 'realm.id'); + result = isPathCoveredByParseAllowedOption([['name'], { realm: ['id'] }], 'realm.id'); expect(result).toBeTruthy(); - result = isPathCoveredByParseAllowed([['name'], { realm: ['id'] }], 'realm.name'); + result = isPathCoveredByParseAllowedOption([['name'], { realm: ['id'] }], 'realm.name'); expect(result).toBeFalsy(); // ----------------------------------------------------------- - result = isPathCoveredByParseAllowed({items: ['realm.id']}, 'items.realm.id'); + result = isPathCoveredByParseAllowedOption({items: ['realm.id']}, 'items.realm.id'); expect(result).toBeTruthy(); - result = isPathCoveredByParseAllowed({items: ['realm.name']}, 'items.realm.id'); + result = isPathCoveredByParseAllowedOption({items: ['realm.name']}, 'items.realm.id'); expect(result).toBeFalsy(); // ----------------------------------------------------------- - result = isPathCoveredByParseAllowed({items: {realm: ['id']}}, 'items.realm.id'); + result = isPathCoveredByParseAllowedOption({items: {realm: ['id']}}, 'items.realm.id'); expect(result).toBeTruthy(); - result = isPathCoveredByParseAllowed({items: {realm: ['name']}}, 'items.realm.id'); + result = isPathCoveredByParseAllowedOption({items: {realm: ['name']}}, 'items.realm.id'); expect(result).toBeFalsy(); }) })