feathers-utils 3.1.2 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +21 -59
- package/dist/index.d.cts +23 -14
- package/dist/index.d.mts +23 -14
- package/dist/index.d.ts +23 -14
- package/dist/index.mjs +21 -59
- package/package.json +1 -1
- package/src/utils/filterQuery.ts +92 -39
- package/src/utils/getItemsIsArray.ts +10 -5
- package/src/utils/mergeQuery/mergeQuery.ts +5 -45
- package/src/utils/mergeQuery/types.ts +1 -2
- package/src/utils/mergeQuery/utils.ts +9 -9
package/dist/index.cjs
CHANGED
|
@@ -8,7 +8,6 @@ const _has = require('lodash/has.js');
|
|
|
8
8
|
const _set = require('lodash/set.js');
|
|
9
9
|
const _uniqWith = require('lodash/uniqWith.js');
|
|
10
10
|
const fastEquals = require('fast-equals');
|
|
11
|
-
const adapterCommons = require('@feathersjs/adapter-commons');
|
|
12
11
|
const _isEqual = require('lodash/isEqual.js');
|
|
13
12
|
const commons = require('@feathersjs/commons');
|
|
14
13
|
const feathersHooksCommon = require('feathers-hooks-common');
|
|
@@ -284,15 +283,6 @@ function makeDefaultOptions$1(options) {
|
|
|
284
283
|
}
|
|
285
284
|
return options;
|
|
286
285
|
}
|
|
287
|
-
function moveProperty(from, to, ...keys) {
|
|
288
|
-
keys.forEach((key) => {
|
|
289
|
-
if (!hasOwnProperty(from, key)) {
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
to[key] = from[key];
|
|
293
|
-
delete from[key];
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
286
|
function getParentProp(target, path) {
|
|
297
287
|
if (path.length <= 1) {
|
|
298
288
|
return target;
|
|
@@ -362,59 +352,29 @@ function areQueriesOverlapping(target, source) {
|
|
|
362
352
|
return false;
|
|
363
353
|
}
|
|
364
354
|
|
|
365
|
-
function filterQuery(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
const {
|
|
369
|
-
if (
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
optionsForFilterQuery.filters = filters;
|
|
378
|
-
}
|
|
379
|
-
if (service && "filterQuery" in service && typeof service.filterQuery === "function") {
|
|
380
|
-
return service.filterQuery({ query }, optionsForFilterQuery);
|
|
381
|
-
} else {
|
|
382
|
-
return adapterCommons.filterQuery(query, optionsForFilterQuery);
|
|
383
|
-
}
|
|
355
|
+
function filterQuery(providedQuery) {
|
|
356
|
+
providedQuery ?? (providedQuery = {});
|
|
357
|
+
const { $select, $limit, $skip, $sort, ...query } = providedQuery;
|
|
358
|
+
const result = { query };
|
|
359
|
+
if ("$select" in providedQuery) {
|
|
360
|
+
result.$select = $select;
|
|
361
|
+
}
|
|
362
|
+
if ("$limit" in providedQuery) {
|
|
363
|
+
result.$limit = $limit;
|
|
364
|
+
}
|
|
365
|
+
if ("$skip" in providedQuery) {
|
|
366
|
+
result.$skip = $skip;
|
|
384
367
|
}
|
|
385
|
-
|
|
368
|
+
if ("$sort" in providedQuery) {
|
|
369
|
+
result.$sort = $sort;
|
|
370
|
+
}
|
|
371
|
+
return result;
|
|
386
372
|
}
|
|
387
373
|
|
|
388
374
|
function mergeQuery(target, source, _options) {
|
|
389
375
|
const options = makeDefaultOptions$1(_options);
|
|
390
|
-
const {
|
|
391
|
-
|
|
392
|
-
filters: options.filters,
|
|
393
|
-
service: options.service
|
|
394
|
-
});
|
|
395
|
-
moveProperty(targetFilters, targetQuery, "$or", "$and");
|
|
396
|
-
if ("$limit" in target) {
|
|
397
|
-
targetFilters.$limit = target.$limit;
|
|
398
|
-
}
|
|
399
|
-
let {
|
|
400
|
-
// eslint-disable-next-line prefer-const
|
|
401
|
-
filters: sourceFilters,
|
|
402
|
-
query: sourceQuery
|
|
403
|
-
} = filterQuery(source, {
|
|
404
|
-
operators: options.operators,
|
|
405
|
-
filters: options.filters,
|
|
406
|
-
service: options.service
|
|
407
|
-
});
|
|
408
|
-
moveProperty(sourceFilters, sourceQuery, "$or", "$and");
|
|
409
|
-
if (source.$limit) {
|
|
410
|
-
sourceFilters.$limit = source.$limit;
|
|
411
|
-
}
|
|
412
|
-
if (target && !hasOwnProperty(target, "$limit") && hasOwnProperty(targetFilters, "$limit")) {
|
|
413
|
-
delete targetFilters.$limit;
|
|
414
|
-
}
|
|
415
|
-
if (source && !hasOwnProperty(source, "$limit") && hasOwnProperty(sourceFilters, "$limit")) {
|
|
416
|
-
delete sourceFilters.$limit;
|
|
417
|
-
}
|
|
376
|
+
const { query: targetQuery, ...targetFilters } = filterQuery(target);
|
|
377
|
+
let { query: sourceQuery, ...sourceFilters } = filterQuery(source);
|
|
418
378
|
handleArray(targetFilters, sourceFilters, ["$select"], options);
|
|
419
379
|
delete sourceFilters["$select"];
|
|
420
380
|
_merge__default(targetFilters, sourceFilters);
|
|
@@ -459,12 +419,14 @@ const getItemsIsArray = (context, options) => {
|
|
|
459
419
|
let itemOrItems;
|
|
460
420
|
if (from === "automatic") {
|
|
461
421
|
itemOrItems = context.type === "before" ? context.data : context.result;
|
|
462
|
-
itemOrItems = itemOrItems && context.method === "find" ? itemOrItems.data || itemOrItems : itemOrItems;
|
|
463
422
|
} else if (from === "data") {
|
|
464
423
|
itemOrItems = context.data;
|
|
465
424
|
} else if (from === "result") {
|
|
466
425
|
itemOrItems = context.result;
|
|
467
426
|
}
|
|
427
|
+
if ((from === "automatic" || from === "result") && context.type === "after") {
|
|
428
|
+
itemOrItems = itemOrItems && context.method === "find" ? itemOrItems.data || itemOrItems : itemOrItems;
|
|
429
|
+
}
|
|
468
430
|
const isArray = Array.isArray(itemOrItems);
|
|
469
431
|
return {
|
|
470
432
|
items: isArray ? itemOrItems : itemOrItems != null ? [itemOrItems] : [],
|
package/dist/index.d.cts
CHANGED
|
@@ -2,7 +2,7 @@ import * as _feathersjs_feathers from '@feathersjs/feathers';
|
|
|
2
2
|
import { HookContext, Application, Id, Query, Params } from '@feathersjs/feathers';
|
|
3
3
|
import { HookContext as HookContext$1, Application as Application$1 } from '@feathersjs/feathers/lib';
|
|
4
4
|
import { PropertyPath, DebouncedFunc } from 'lodash';
|
|
5
|
-
import {
|
|
5
|
+
import { PaginationOptions, FilterQueryOptions } from '@feathersjs/adapter-commons';
|
|
6
6
|
import { HookType } from 'feathers-hooks-common';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -26,8 +26,9 @@ interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
26
26
|
*/
|
|
27
27
|
declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, multi, data, createItemsInDataArraySeparately, }: CreateRelatedOptions<S>): (context: H) => Promise<H>;
|
|
28
28
|
|
|
29
|
+
type GetItemsIsArrayFrom = "data" | "result" | "automatic";
|
|
29
30
|
type GetItemsIsArrayOptions = {
|
|
30
|
-
from
|
|
31
|
+
from?: GetItemsIsArrayFrom;
|
|
31
32
|
};
|
|
32
33
|
interface GetItemsIsArrayResult<T = any> {
|
|
33
34
|
items: T[];
|
|
@@ -124,17 +125,10 @@ declare class DebouncedStore {
|
|
|
124
125
|
|
|
125
126
|
declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): (app: Application$1) => void;
|
|
126
127
|
|
|
127
|
-
interface FilterQueryOptions<T> {
|
|
128
|
-
service?: AdapterBase<T>;
|
|
129
|
-
operators?: FilterQueryOptions$1["operators"];
|
|
130
|
-
filters?: FilterQueryOptions$1["filters"];
|
|
131
|
-
}
|
|
132
|
-
declare function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>): any;
|
|
133
|
-
|
|
134
128
|
type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
|
|
135
129
|
type FirstLast = "first" | "last";
|
|
136
130
|
type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
|
|
137
|
-
interface MergeQueryOptions
|
|
131
|
+
interface MergeQueryOptions {
|
|
138
132
|
defaultHandle: Handle;
|
|
139
133
|
actionOnEmptyIntersect: ActionOnEmptyIntersect;
|
|
140
134
|
useLogicalConjunction: boolean;
|
|
@@ -152,7 +146,22 @@ declare function mergeArrays<T>(targetArr: T[] | undefined, sourceArr: T[] | und
|
|
|
152
146
|
* @param _options
|
|
153
147
|
* @returns Query
|
|
154
148
|
*/
|
|
155
|
-
declare function mergeQuery
|
|
149
|
+
declare function mergeQuery(target: Query, source: Query, _options?: Partial<MergeQueryOptions>): Query;
|
|
150
|
+
|
|
151
|
+
type FilterQueryResult<Q extends Query> = {
|
|
152
|
+
$select: Q["$select"] extends any ? Q["$select"] : never;
|
|
153
|
+
$limit: Q["$limit"] extends any ? Q["$limit"] : never;
|
|
154
|
+
$skip: Q["$skip"] extends any ? Q["$skip"] : never;
|
|
155
|
+
$sort: Q["$sort"] extends any ? Q["$sort"] : never;
|
|
156
|
+
query: Omit<Q, "$select" | "$limit" | "$skip" | "$sort">;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Extracts $select, $limit, $skip, $sort from a query and returns the rest as a query object.
|
|
160
|
+
*
|
|
161
|
+
* @param providedQuery
|
|
162
|
+
* @returns
|
|
163
|
+
*/
|
|
164
|
+
declare function filterQuery<Q extends Query>(providedQuery?: Q): FilterQueryResult<Q>;
|
|
156
165
|
|
|
157
166
|
/**
|
|
158
167
|
* util to get paginate options from context
|
|
@@ -216,9 +225,9 @@ type SetQueryKeySafelyOptions = {
|
|
|
216
225
|
};
|
|
217
226
|
declare const setQueryKeySafely: <P extends Params<_feathersjs_feathers.Query> = Params<_feathersjs_feathers.Query>>(params: P, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => P;
|
|
218
227
|
|
|
219
|
-
declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions
|
|
228
|
+
declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
|
|
220
229
|
|
|
221
|
-
declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions
|
|
230
|
+
declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
|
|
222
231
|
|
|
223
232
|
type Single<T> = T extends Array<infer U> ? U : T;
|
|
224
233
|
type AsArray<T> = T extends any[] ? T : [T];
|
|
@@ -266,4 +275,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
|
|
|
266
275
|
type InferDataFromPath<App extends Application, Path extends string, Method extends "create" | "update" | "patch"> = Method extends "create" ? InferCreateDataFromPath<App, Path> : Method extends "update" ? InferUpdateDataFromPath<App, Path> : Method extends "patch" ? InferPatchDataFromPath<App, Path> : never;
|
|
267
276
|
type InferResultFromPath<App extends Application, Path extends string, Method extends "get" | "find" | "create" | "update" | "patch" | "remove"> = Method extends "get" ? InferGetResultFromPath<App, Path> : Method extends "find" ? InferFindResultFromPath<App, Path> : Method extends "create" ? InferCreateResultFromPath<App, Path> : Method extends "update" ? InferUpdateResultFromPath<App, Path> : Method extends "patch" ? InferPatchResultFromPath<App, Path> : Method extends "remove" ? InferRemoveResultFromPath<App, Path> : never;
|
|
268
277
|
|
|
269
|
-
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type
|
|
278
|
+
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FirstLast, type GetItemsIsArrayFrom, type GetItemsIsArrayOptions, type GetItemsIsArrayResult, type GetService, type Handle, type HookForEachOptions, type HookRunPerItemOptions, type HookSetDataOptions, type InferCreateData, type InferCreateDataFromPath, type InferCreateDataSingle, type InferCreateDataSingleFromPath, type InferCreateResult, type InferCreateResultFromPath, type InferCreateResultSingle, type InferCreateResultSingleFromPath, type InferDataFromPath, type InferFindResult, type InferFindResultFromPath, type InferGetResult, type InferGetResultFromPath, type InferPatchData, type InferPatchDataFromPath, type InferPatchResult, type InferPatchResultFromPath, type InferRemoveResult, type InferRemoveResultFromPath, type InferResultFromPath, type InferUpdateData, type InferUpdateDataFromPath, type InferUpdateResult, type InferUpdateResultFromPath, type InitDebounceMixinOptions, type MergeQueryOptions, type OnDeleteAction, type OnDeleteOptions, type Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import * as _feathersjs_feathers from '@feathersjs/feathers';
|
|
|
2
2
|
import { HookContext, Application, Id, Query, Params } from '@feathersjs/feathers';
|
|
3
3
|
import { HookContext as HookContext$1, Application as Application$1 } from '@feathersjs/feathers/lib';
|
|
4
4
|
import { PropertyPath, DebouncedFunc } from 'lodash';
|
|
5
|
-
import {
|
|
5
|
+
import { PaginationOptions, FilterQueryOptions } from '@feathersjs/adapter-commons';
|
|
6
6
|
import { HookType } from 'feathers-hooks-common';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -26,8 +26,9 @@ interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
26
26
|
*/
|
|
27
27
|
declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, multi, data, createItemsInDataArraySeparately, }: CreateRelatedOptions<S>): (context: H) => Promise<H>;
|
|
28
28
|
|
|
29
|
+
type GetItemsIsArrayFrom = "data" | "result" | "automatic";
|
|
29
30
|
type GetItemsIsArrayOptions = {
|
|
30
|
-
from
|
|
31
|
+
from?: GetItemsIsArrayFrom;
|
|
31
32
|
};
|
|
32
33
|
interface GetItemsIsArrayResult<T = any> {
|
|
33
34
|
items: T[];
|
|
@@ -124,17 +125,10 @@ declare class DebouncedStore {
|
|
|
124
125
|
|
|
125
126
|
declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): (app: Application$1) => void;
|
|
126
127
|
|
|
127
|
-
interface FilterQueryOptions<T> {
|
|
128
|
-
service?: AdapterBase<T>;
|
|
129
|
-
operators?: FilterQueryOptions$1["operators"];
|
|
130
|
-
filters?: FilterQueryOptions$1["filters"];
|
|
131
|
-
}
|
|
132
|
-
declare function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>): any;
|
|
133
|
-
|
|
134
128
|
type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
|
|
135
129
|
type FirstLast = "first" | "last";
|
|
136
130
|
type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
|
|
137
|
-
interface MergeQueryOptions
|
|
131
|
+
interface MergeQueryOptions {
|
|
138
132
|
defaultHandle: Handle;
|
|
139
133
|
actionOnEmptyIntersect: ActionOnEmptyIntersect;
|
|
140
134
|
useLogicalConjunction: boolean;
|
|
@@ -152,7 +146,22 @@ declare function mergeArrays<T>(targetArr: T[] | undefined, sourceArr: T[] | und
|
|
|
152
146
|
* @param _options
|
|
153
147
|
* @returns Query
|
|
154
148
|
*/
|
|
155
|
-
declare function mergeQuery
|
|
149
|
+
declare function mergeQuery(target: Query, source: Query, _options?: Partial<MergeQueryOptions>): Query;
|
|
150
|
+
|
|
151
|
+
type FilterQueryResult<Q extends Query> = {
|
|
152
|
+
$select: Q["$select"] extends any ? Q["$select"] : never;
|
|
153
|
+
$limit: Q["$limit"] extends any ? Q["$limit"] : never;
|
|
154
|
+
$skip: Q["$skip"] extends any ? Q["$skip"] : never;
|
|
155
|
+
$sort: Q["$sort"] extends any ? Q["$sort"] : never;
|
|
156
|
+
query: Omit<Q, "$select" | "$limit" | "$skip" | "$sort">;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Extracts $select, $limit, $skip, $sort from a query and returns the rest as a query object.
|
|
160
|
+
*
|
|
161
|
+
* @param providedQuery
|
|
162
|
+
* @returns
|
|
163
|
+
*/
|
|
164
|
+
declare function filterQuery<Q extends Query>(providedQuery?: Q): FilterQueryResult<Q>;
|
|
156
165
|
|
|
157
166
|
/**
|
|
158
167
|
* util to get paginate options from context
|
|
@@ -216,9 +225,9 @@ type SetQueryKeySafelyOptions = {
|
|
|
216
225
|
};
|
|
217
226
|
declare const setQueryKeySafely: <P extends Params<_feathersjs_feathers.Query> = Params<_feathersjs_feathers.Query>>(params: P, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => P;
|
|
218
227
|
|
|
219
|
-
declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions
|
|
228
|
+
declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
|
|
220
229
|
|
|
221
|
-
declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions
|
|
230
|
+
declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
|
|
222
231
|
|
|
223
232
|
type Single<T> = T extends Array<infer U> ? U : T;
|
|
224
233
|
type AsArray<T> = T extends any[] ? T : [T];
|
|
@@ -266,4 +275,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
|
|
|
266
275
|
type InferDataFromPath<App extends Application, Path extends string, Method extends "create" | "update" | "patch"> = Method extends "create" ? InferCreateDataFromPath<App, Path> : Method extends "update" ? InferUpdateDataFromPath<App, Path> : Method extends "patch" ? InferPatchDataFromPath<App, Path> : never;
|
|
267
276
|
type InferResultFromPath<App extends Application, Path extends string, Method extends "get" | "find" | "create" | "update" | "patch" | "remove"> = Method extends "get" ? InferGetResultFromPath<App, Path> : Method extends "find" ? InferFindResultFromPath<App, Path> : Method extends "create" ? InferCreateResultFromPath<App, Path> : Method extends "update" ? InferUpdateResultFromPath<App, Path> : Method extends "patch" ? InferPatchResultFromPath<App, Path> : Method extends "remove" ? InferRemoveResultFromPath<App, Path> : never;
|
|
268
277
|
|
|
269
|
-
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type
|
|
278
|
+
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FirstLast, type GetItemsIsArrayFrom, type GetItemsIsArrayOptions, type GetItemsIsArrayResult, type GetService, type Handle, type HookForEachOptions, type HookRunPerItemOptions, type HookSetDataOptions, type InferCreateData, type InferCreateDataFromPath, type InferCreateDataSingle, type InferCreateDataSingleFromPath, type InferCreateResult, type InferCreateResultFromPath, type InferCreateResultSingle, type InferCreateResultSingleFromPath, type InferDataFromPath, type InferFindResult, type InferFindResultFromPath, type InferGetResult, type InferGetResultFromPath, type InferPatchData, type InferPatchDataFromPath, type InferPatchResult, type InferPatchResultFromPath, type InferRemoveResult, type InferRemoveResultFromPath, type InferResultFromPath, type InferUpdateData, type InferUpdateDataFromPath, type InferUpdateResult, type InferUpdateResultFromPath, type InitDebounceMixinOptions, type MergeQueryOptions, type OnDeleteAction, type OnDeleteOptions, type Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as _feathersjs_feathers from '@feathersjs/feathers';
|
|
|
2
2
|
import { HookContext, Application, Id, Query, Params } from '@feathersjs/feathers';
|
|
3
3
|
import { HookContext as HookContext$1, Application as Application$1 } from '@feathersjs/feathers/lib';
|
|
4
4
|
import { PropertyPath, DebouncedFunc } from 'lodash';
|
|
5
|
-
import {
|
|
5
|
+
import { PaginationOptions, FilterQueryOptions } from '@feathersjs/adapter-commons';
|
|
6
6
|
import { HookType } from 'feathers-hooks-common';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -26,8 +26,9 @@ interface CreateRelatedOptions<S = Record<string, any>> {
|
|
|
26
26
|
*/
|
|
27
27
|
declare function createRelated<S = Record<string, any>, H extends HookContext = HookContext>({ service, multi, data, createItemsInDataArraySeparately, }: CreateRelatedOptions<S>): (context: H) => Promise<H>;
|
|
28
28
|
|
|
29
|
+
type GetItemsIsArrayFrom = "data" | "result" | "automatic";
|
|
29
30
|
type GetItemsIsArrayOptions = {
|
|
30
|
-
from
|
|
31
|
+
from?: GetItemsIsArrayFrom;
|
|
31
32
|
};
|
|
32
33
|
interface GetItemsIsArrayResult<T = any> {
|
|
33
34
|
items: T[];
|
|
@@ -124,17 +125,10 @@ declare class DebouncedStore {
|
|
|
124
125
|
|
|
125
126
|
declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): (app: Application$1) => void;
|
|
126
127
|
|
|
127
|
-
interface FilterQueryOptions<T> {
|
|
128
|
-
service?: AdapterBase<T>;
|
|
129
|
-
operators?: FilterQueryOptions$1["operators"];
|
|
130
|
-
filters?: FilterQueryOptions$1["filters"];
|
|
131
|
-
}
|
|
132
|
-
declare function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>): any;
|
|
133
|
-
|
|
134
128
|
type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
|
|
135
129
|
type FirstLast = "first" | "last";
|
|
136
130
|
type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
|
|
137
|
-
interface MergeQueryOptions
|
|
131
|
+
interface MergeQueryOptions {
|
|
138
132
|
defaultHandle: Handle;
|
|
139
133
|
actionOnEmptyIntersect: ActionOnEmptyIntersect;
|
|
140
134
|
useLogicalConjunction: boolean;
|
|
@@ -152,7 +146,22 @@ declare function mergeArrays<T>(targetArr: T[] | undefined, sourceArr: T[] | und
|
|
|
152
146
|
* @param _options
|
|
153
147
|
* @returns Query
|
|
154
148
|
*/
|
|
155
|
-
declare function mergeQuery
|
|
149
|
+
declare function mergeQuery(target: Query, source: Query, _options?: Partial<MergeQueryOptions>): Query;
|
|
150
|
+
|
|
151
|
+
type FilterQueryResult<Q extends Query> = {
|
|
152
|
+
$select: Q["$select"] extends any ? Q["$select"] : never;
|
|
153
|
+
$limit: Q["$limit"] extends any ? Q["$limit"] : never;
|
|
154
|
+
$skip: Q["$skip"] extends any ? Q["$skip"] : never;
|
|
155
|
+
$sort: Q["$sort"] extends any ? Q["$sort"] : never;
|
|
156
|
+
query: Omit<Q, "$select" | "$limit" | "$skip" | "$sort">;
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Extracts $select, $limit, $skip, $sort from a query and returns the rest as a query object.
|
|
160
|
+
*
|
|
161
|
+
* @param providedQuery
|
|
162
|
+
* @returns
|
|
163
|
+
*/
|
|
164
|
+
declare function filterQuery<Q extends Query>(providedQuery?: Q): FilterQueryResult<Q>;
|
|
156
165
|
|
|
157
166
|
/**
|
|
158
167
|
* util to get paginate options from context
|
|
@@ -216,9 +225,9 @@ type SetQueryKeySafelyOptions = {
|
|
|
216
225
|
};
|
|
217
226
|
declare const setQueryKeySafely: <P extends Params<_feathersjs_feathers.Query> = Params<_feathersjs_feathers.Query>>(params: P, key: string, value: any, operator?: string, options?: SetQueryKeySafelyOptions) => P;
|
|
218
227
|
|
|
219
|
-
declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions
|
|
228
|
+
declare const filterArray: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
|
|
220
229
|
|
|
221
|
-
declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions
|
|
230
|
+
declare const filterObject: <T extends string[]>(...keys: T) => { [key in T[number]]: (value: any, options: FilterQueryOptions) => any; };
|
|
222
231
|
|
|
223
232
|
type Single<T> = T extends Array<infer U> ? U : T;
|
|
224
233
|
type AsArray<T> = T extends any[] ? T : [T];
|
|
@@ -266,4 +275,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
|
|
|
266
275
|
type InferDataFromPath<App extends Application, Path extends string, Method extends "create" | "update" | "patch"> = Method extends "create" ? InferCreateDataFromPath<App, Path> : Method extends "update" ? InferUpdateDataFromPath<App, Path> : Method extends "patch" ? InferPatchDataFromPath<App, Path> : never;
|
|
267
276
|
type InferResultFromPath<App extends Application, Path extends string, Method extends "get" | "find" | "create" | "update" | "patch" | "remove"> = Method extends "get" ? InferGetResultFromPath<App, Path> : Method extends "find" ? InferFindResultFromPath<App, Path> : Method extends "create" ? InferCreateResultFromPath<App, Path> : Method extends "update" ? InferUpdateResultFromPath<App, Path> : Method extends "patch" ? InferPatchResultFromPath<App, Path> : Method extends "remove" ? InferRemoveResultFromPath<App, Path> : never;
|
|
268
277
|
|
|
269
|
-
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type
|
|
278
|
+
export { type ActionOnEmptyIntersect, type CreateRelatedOptions, type DebouncedFunctionApp, type DebouncedService, DebouncedStore, type DebouncedStoreOptions, type FirstLast, type GetItemsIsArrayFrom, type GetItemsIsArrayOptions, type GetItemsIsArrayResult, type GetService, type Handle, type HookForEachOptions, type HookRunPerItemOptions, type HookSetDataOptions, type InferCreateData, type InferCreateDataFromPath, type InferCreateDataSingle, type InferCreateDataSingleFromPath, type InferCreateResult, type InferCreateResultFromPath, type InferCreateResultSingle, type InferCreateResultSingleFromPath, type InferDataFromPath, type InferFindResult, type InferFindResultFromPath, type InferGetResult, type InferGetResultFromPath, type InferPatchData, type InferPatchDataFromPath, type InferPatchResult, type InferPatchResultFromPath, type InferRemoveResult, type InferRemoveResultFromPath, type InferResultFromPath, type InferUpdateData, type InferUpdateDataFromPath, type InferUpdateResult, type InferUpdateResultFromPath, type InitDebounceMixinOptions, type MergeQueryOptions, type OnDeleteAction, type OnDeleteOptions, type Predicate, type PredicateWithContext, type PushSetOptions, type RemoveRelatedOptions, type SetQueryKeySafelyOptions, type ShouldSkipOptions, checkMulti, createRelated, debounceMixin, filterArray, filterObject, filterQuery, forEach, getItemsIsArray, getPaginate, isMulti, isPaginated, makeDefaultOptions, markHookForSkip, mergeArrays, mergeQuery, onDelete, parseFields, pushSet, removeRelated, runPerItem, setData, setQueryKeySafely, setResultEmpty, shouldSkip, toJSON, validateQueryProperty };
|
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,6 @@ import _has from 'lodash/has.js';
|
|
|
6
6
|
import _set from 'lodash/set.js';
|
|
7
7
|
import _uniqWith from 'lodash/uniqWith.js';
|
|
8
8
|
import { deepEqual } from 'fast-equals';
|
|
9
|
-
import { filterQuery as filterQuery$1 } from '@feathersjs/adapter-commons';
|
|
10
9
|
import _isEqual from 'lodash/isEqual.js';
|
|
11
10
|
import { _ } from '@feathersjs/commons';
|
|
12
11
|
import { checkContext } from 'feathers-hooks-common';
|
|
@@ -270,15 +269,6 @@ function makeDefaultOptions$1(options) {
|
|
|
270
269
|
}
|
|
271
270
|
return options;
|
|
272
271
|
}
|
|
273
|
-
function moveProperty(from, to, ...keys) {
|
|
274
|
-
keys.forEach((key) => {
|
|
275
|
-
if (!hasOwnProperty(from, key)) {
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
to[key] = from[key];
|
|
279
|
-
delete from[key];
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
272
|
function getParentProp(target, path) {
|
|
283
273
|
if (path.length <= 1) {
|
|
284
274
|
return target;
|
|
@@ -348,59 +338,29 @@ function areQueriesOverlapping(target, source) {
|
|
|
348
338
|
return false;
|
|
349
339
|
}
|
|
350
340
|
|
|
351
|
-
function filterQuery(
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
const {
|
|
355
|
-
if (
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
return service.filterQuery({ query }, optionsForFilterQuery);
|
|
367
|
-
} else {
|
|
368
|
-
return filterQuery$1(query, optionsForFilterQuery);
|
|
369
|
-
}
|
|
341
|
+
function filterQuery(providedQuery) {
|
|
342
|
+
providedQuery ?? (providedQuery = {});
|
|
343
|
+
const { $select, $limit, $skip, $sort, ...query } = providedQuery;
|
|
344
|
+
const result = { query };
|
|
345
|
+
if ("$select" in providedQuery) {
|
|
346
|
+
result.$select = $select;
|
|
347
|
+
}
|
|
348
|
+
if ("$limit" in providedQuery) {
|
|
349
|
+
result.$limit = $limit;
|
|
350
|
+
}
|
|
351
|
+
if ("$skip" in providedQuery) {
|
|
352
|
+
result.$skip = $skip;
|
|
353
|
+
}
|
|
354
|
+
if ("$sort" in providedQuery) {
|
|
355
|
+
result.$sort = $sort;
|
|
370
356
|
}
|
|
371
|
-
return
|
|
357
|
+
return result;
|
|
372
358
|
}
|
|
373
359
|
|
|
374
360
|
function mergeQuery(target, source, _options) {
|
|
375
361
|
const options = makeDefaultOptions$1(_options);
|
|
376
|
-
const {
|
|
377
|
-
|
|
378
|
-
filters: options.filters,
|
|
379
|
-
service: options.service
|
|
380
|
-
});
|
|
381
|
-
moveProperty(targetFilters, targetQuery, "$or", "$and");
|
|
382
|
-
if ("$limit" in target) {
|
|
383
|
-
targetFilters.$limit = target.$limit;
|
|
384
|
-
}
|
|
385
|
-
let {
|
|
386
|
-
// eslint-disable-next-line prefer-const
|
|
387
|
-
filters: sourceFilters,
|
|
388
|
-
query: sourceQuery
|
|
389
|
-
} = filterQuery(source, {
|
|
390
|
-
operators: options.operators,
|
|
391
|
-
filters: options.filters,
|
|
392
|
-
service: options.service
|
|
393
|
-
});
|
|
394
|
-
moveProperty(sourceFilters, sourceQuery, "$or", "$and");
|
|
395
|
-
if (source.$limit) {
|
|
396
|
-
sourceFilters.$limit = source.$limit;
|
|
397
|
-
}
|
|
398
|
-
if (target && !hasOwnProperty(target, "$limit") && hasOwnProperty(targetFilters, "$limit")) {
|
|
399
|
-
delete targetFilters.$limit;
|
|
400
|
-
}
|
|
401
|
-
if (source && !hasOwnProperty(source, "$limit") && hasOwnProperty(sourceFilters, "$limit")) {
|
|
402
|
-
delete sourceFilters.$limit;
|
|
403
|
-
}
|
|
362
|
+
const { query: targetQuery, ...targetFilters } = filterQuery(target);
|
|
363
|
+
let { query: sourceQuery, ...sourceFilters } = filterQuery(source);
|
|
404
364
|
handleArray(targetFilters, sourceFilters, ["$select"], options);
|
|
405
365
|
delete sourceFilters["$select"];
|
|
406
366
|
_merge(targetFilters, sourceFilters);
|
|
@@ -445,12 +405,14 @@ const getItemsIsArray = (context, options) => {
|
|
|
445
405
|
let itemOrItems;
|
|
446
406
|
if (from === "automatic") {
|
|
447
407
|
itemOrItems = context.type === "before" ? context.data : context.result;
|
|
448
|
-
itemOrItems = itemOrItems && context.method === "find" ? itemOrItems.data || itemOrItems : itemOrItems;
|
|
449
408
|
} else if (from === "data") {
|
|
450
409
|
itemOrItems = context.data;
|
|
451
410
|
} else if (from === "result") {
|
|
452
411
|
itemOrItems = context.result;
|
|
453
412
|
}
|
|
413
|
+
if ((from === "automatic" || from === "result") && context.type === "after") {
|
|
414
|
+
itemOrItems = itemOrItems && context.method === "find" ? itemOrItems.data || itemOrItems : itemOrItems;
|
|
415
|
+
}
|
|
454
416
|
const isArray = Array.isArray(itemOrItems);
|
|
455
417
|
return {
|
|
456
418
|
items: isArray ? itemOrItems : itemOrItems != null ? [itemOrItems] : [],
|
package/package.json
CHANGED
package/src/utils/filterQuery.ts
CHANGED
|
@@ -1,45 +1,98 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Query } from "@feathersjs/feathers";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
type FilterQueryResult<Q extends Query> = {
|
|
4
|
+
$select: Q["$select"] extends any ? Q["$select"] : never;
|
|
5
|
+
$limit: Q["$limit"] extends any ? Q["$limit"] : never;
|
|
6
|
+
$skip: Q["$skip"] extends any ? Q["$skip"] : never;
|
|
7
|
+
$sort: Q["$sort"] extends any ? Q["$sort"] : never;
|
|
8
|
+
query: Omit<Q, "$select" | "$limit" | "$skip" | "$sort">;
|
|
9
|
+
};
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Extracts $select, $limit, $skip, $sort from a query and returns the rest as a query object.
|
|
13
|
+
*
|
|
14
|
+
* @param providedQuery
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
export function filterQuery<Q extends Query>(
|
|
18
|
+
providedQuery?: Q,
|
|
19
|
+
): FilterQueryResult<Q> {
|
|
20
|
+
providedQuery ??= {} as Q;
|
|
21
|
+
const { $select, $limit, $skip, $sort, ...query } = providedQuery;
|
|
9
22
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
23
|
+
const result: FilterQueryResult<Q> = { query } as any;
|
|
24
|
+
|
|
25
|
+
if ("$select" in providedQuery) {
|
|
26
|
+
result.$select = $select;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if ("$limit" in providedQuery) {
|
|
30
|
+
result.$limit = $limit;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if ("$skip" in providedQuery) {
|
|
34
|
+
result.$skip = $skip;
|
|
35
|
+
}
|
|
15
36
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
_options = _options || {};
|
|
19
|
-
const { service, ...options } = _options;
|
|
20
|
-
if (service) {
|
|
21
|
-
const operators = options.operators
|
|
22
|
-
? options.operators
|
|
23
|
-
: service.options?.operators;
|
|
24
|
-
const filters = options.filters
|
|
25
|
-
? options.filters
|
|
26
|
-
: service.options?.filters;
|
|
27
|
-
const optionsForFilterQuery: PlainFilterQueryOptions = {};
|
|
28
|
-
if (operators) {
|
|
29
|
-
optionsForFilterQuery.operators = operators;
|
|
30
|
-
}
|
|
31
|
-
if (filters) {
|
|
32
|
-
optionsForFilterQuery.filters = filters;
|
|
33
|
-
}
|
|
34
|
-
if (
|
|
35
|
-
service &&
|
|
36
|
-
"filterQuery" in service &&
|
|
37
|
-
typeof service.filterQuery === "function"
|
|
38
|
-
) {
|
|
39
|
-
return service.filterQuery({ query }, optionsForFilterQuery);
|
|
40
|
-
} else {
|
|
41
|
-
return plainFilterQuery(query, optionsForFilterQuery);
|
|
42
|
-
}
|
|
37
|
+
if ("$sort" in providedQuery) {
|
|
38
|
+
result.$sort = $sort;
|
|
43
39
|
}
|
|
44
|
-
|
|
40
|
+
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (import.meta.vitest) {
|
|
45
|
+
const { it, expect } = import.meta.vitest;
|
|
46
|
+
|
|
47
|
+
it("should filter query", () => {
|
|
48
|
+
const query = {
|
|
49
|
+
$select: ["a"],
|
|
50
|
+
$limit: 10,
|
|
51
|
+
$skip: 10,
|
|
52
|
+
$sort: {
|
|
53
|
+
a: 1,
|
|
54
|
+
},
|
|
55
|
+
a: 1,
|
|
56
|
+
b: 2,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
expect(filterQuery(query)).toEqual({
|
|
60
|
+
$select: ["a"],
|
|
61
|
+
$limit: 10,
|
|
62
|
+
$skip: 10,
|
|
63
|
+
$sort: {
|
|
64
|
+
a: 1,
|
|
65
|
+
},
|
|
66
|
+
query: {
|
|
67
|
+
a: 1,
|
|
68
|
+
b: 2,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("should not include filters if not provided", () => {
|
|
74
|
+
const query = {
|
|
75
|
+
a: 1,
|
|
76
|
+
b: 2,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
expect(filterQuery(query)).toEqual({
|
|
80
|
+
query: {
|
|
81
|
+
a: 1,
|
|
82
|
+
b: 2,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("sets empty query object if empty object is provided", () => {
|
|
88
|
+
expect(filterQuery({})).toEqual({
|
|
89
|
+
query: {},
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("sets empty query object if undefined is provided", () => {
|
|
94
|
+
expect(filterQuery(undefined)).toEqual({
|
|
95
|
+
query: {},
|
|
96
|
+
});
|
|
97
|
+
});
|
|
45
98
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { HookContext } from "@feathersjs/feathers";
|
|
2
2
|
|
|
3
|
+
export type GetItemsIsArrayFrom = "data" | "result" | "automatic";
|
|
4
|
+
|
|
3
5
|
export type GetItemsIsArrayOptions = {
|
|
4
|
-
from
|
|
6
|
+
from?: GetItemsIsArrayFrom;
|
|
5
7
|
};
|
|
6
8
|
|
|
7
9
|
export interface GetItemsIsArrayResult<T = any> {
|
|
@@ -20,16 +22,19 @@ export const getItemsIsArray = <T = any, H extends HookContext = HookContext>(
|
|
|
20
22
|
|
|
21
23
|
if (from === "automatic") {
|
|
22
24
|
itemOrItems = context.type === "before" ? context.data : context.result;
|
|
23
|
-
itemOrItems =
|
|
24
|
-
itemOrItems && context.method === "find"
|
|
25
|
-
? itemOrItems.data || itemOrItems
|
|
26
|
-
: itemOrItems;
|
|
27
25
|
} else if (from === "data") {
|
|
28
26
|
itemOrItems = context.data;
|
|
29
27
|
} else if (from === "result") {
|
|
30
28
|
itemOrItems = context.result;
|
|
31
29
|
}
|
|
32
30
|
|
|
31
|
+
if ((from === "automatic" || from === "result") && context.type === "after") {
|
|
32
|
+
itemOrItems =
|
|
33
|
+
itemOrItems && context.method === "find"
|
|
34
|
+
? itemOrItems.data || itemOrItems
|
|
35
|
+
: itemOrItems;
|
|
36
|
+
}
|
|
37
|
+
|
|
33
38
|
const isArray = Array.isArray(itemOrItems);
|
|
34
39
|
return {
|
|
35
40
|
items: isArray ? itemOrItems : itemOrItems != null ? [itemOrItems] : [],
|
|
@@ -7,7 +7,6 @@ import {
|
|
|
7
7
|
handleCircular,
|
|
8
8
|
isQueryMoreExplicitThanQuery,
|
|
9
9
|
makeDefaultOptions,
|
|
10
|
-
moveProperty,
|
|
11
10
|
} from "./utils";
|
|
12
11
|
import type { MergeQueryOptions } from "./types";
|
|
13
12
|
import { filterQuery } from "../filterQuery";
|
|
@@ -20,58 +19,19 @@ import { hasOwnProperty } from "../internal.utils";
|
|
|
20
19
|
* @param _options
|
|
21
20
|
* @returns Query
|
|
22
21
|
*/
|
|
23
|
-
export function mergeQuery
|
|
22
|
+
export function mergeQuery(
|
|
24
23
|
target: Query,
|
|
25
24
|
source: Query,
|
|
26
|
-
_options?: Partial<MergeQueryOptions
|
|
25
|
+
_options?: Partial<MergeQueryOptions>,
|
|
27
26
|
): Query {
|
|
28
27
|
const options = makeDefaultOptions(_options);
|
|
29
|
-
const { filters: targetFilters, query: targetQuery } = filterQuery(target, {
|
|
30
|
-
operators: options.operators,
|
|
31
|
-
filters: options.filters,
|
|
32
|
-
service: options.service,
|
|
33
|
-
});
|
|
34
28
|
|
|
35
|
-
|
|
29
|
+
const { query: targetQuery, ...targetFilters } = filterQuery(target);
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
let {
|
|
42
|
-
// eslint-disable-next-line prefer-const
|
|
43
|
-
filters: sourceFilters,
|
|
44
|
-
query: sourceQuery,
|
|
45
|
-
} = filterQuery(source, {
|
|
46
|
-
operators: options.operators,
|
|
47
|
-
filters: options.filters,
|
|
48
|
-
service: options.service,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
moveProperty(sourceFilters, sourceQuery, "$or", "$and");
|
|
52
|
-
|
|
53
|
-
if (source.$limit) {
|
|
54
|
-
sourceFilters.$limit = source.$limit;
|
|
55
|
-
}
|
|
31
|
+
// eslint-disable-next-line prefer-const
|
|
32
|
+
let { query: sourceQuery, ...sourceFilters } = filterQuery(source);
|
|
56
33
|
|
|
57
34
|
//#region filters
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
target &&
|
|
61
|
-
!hasOwnProperty(target, "$limit") &&
|
|
62
|
-
hasOwnProperty(targetFilters, "$limit")
|
|
63
|
-
) {
|
|
64
|
-
delete targetFilters.$limit;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
source &&
|
|
69
|
-
!hasOwnProperty(source, "$limit") &&
|
|
70
|
-
hasOwnProperty(sourceFilters, "$limit")
|
|
71
|
-
) {
|
|
72
|
-
delete sourceFilters.$limit;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
35
|
handleArray(targetFilters, sourceFilters, ["$select"], options);
|
|
76
36
|
// remaining filters
|
|
77
37
|
delete sourceFilters["$select"];
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Path } from "../../typesInternal";
|
|
2
|
-
import type { FilterQueryOptions } from "../filterQuery";
|
|
3
2
|
|
|
4
3
|
export type Handle =
|
|
5
4
|
| "target"
|
|
@@ -15,7 +14,7 @@ export type ActionOnEmptyIntersect = (
|
|
|
15
14
|
prependKey: Path,
|
|
16
15
|
) => void;
|
|
17
16
|
|
|
18
|
-
export interface MergeQueryOptions
|
|
17
|
+
export interface MergeQueryOptions {
|
|
19
18
|
defaultHandle: Handle;
|
|
20
19
|
actionOnEmptyIntersect: ActionOnEmptyIntersect;
|
|
21
20
|
useLogicalConjunction: boolean;
|
|
@@ -12,11 +12,11 @@ import { deepEqual as _isEqual } from "fast-equals";
|
|
|
12
12
|
import type { Query } from "@feathersjs/feathers";
|
|
13
13
|
import { hasOwnProperty } from "../internal.utils";
|
|
14
14
|
|
|
15
|
-
export function handleArray
|
|
15
|
+
export function handleArray(
|
|
16
16
|
target: Record<string, unknown>,
|
|
17
17
|
source: Record<string, unknown>,
|
|
18
18
|
key: Path,
|
|
19
|
-
options: MergeQueryOptions
|
|
19
|
+
options: MergeQueryOptions,
|
|
20
20
|
): void {
|
|
21
21
|
const targetVal = _get(target, key);
|
|
22
22
|
const sourceVal = _get(source, key);
|
|
@@ -38,11 +38,11 @@ export function handleArray<T>(
|
|
|
38
38
|
_set(target, key, arr);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
export function handleCircular
|
|
41
|
+
export function handleCircular(
|
|
42
42
|
target: Record<string, unknown>,
|
|
43
43
|
source: Record<string, unknown>,
|
|
44
44
|
prependKey: Path,
|
|
45
|
-
options: MergeQueryOptions
|
|
45
|
+
options: MergeQueryOptions,
|
|
46
46
|
): void {
|
|
47
47
|
if (target?.$or) {
|
|
48
48
|
target.$or = cleanOr(target.$or as Record<string, unknown>[]);
|
|
@@ -257,10 +257,10 @@ export function handleCircular<T>(
|
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
export function makeDefaultOptions
|
|
261
|
-
options?: Partial<MergeQueryOptions
|
|
262
|
-
): MergeQueryOptions
|
|
263
|
-
options ??= {} as MergeQueryOptions
|
|
260
|
+
export function makeDefaultOptions(
|
|
261
|
+
options?: Partial<MergeQueryOptions>,
|
|
262
|
+
): MergeQueryOptions {
|
|
263
|
+
options ??= {} as MergeQueryOptions;
|
|
264
264
|
options.defaultHandle ??= "combine";
|
|
265
265
|
options.useLogicalConjunction ??= false;
|
|
266
266
|
options.actionOnEmptyIntersect ??= () => {
|
|
@@ -270,7 +270,7 @@ export function makeDefaultOptions<T>(
|
|
|
270
270
|
if (options.defaultHandle === "intersect") {
|
|
271
271
|
options.handle.$select = options.handle.$select || "intersectOrFull";
|
|
272
272
|
}
|
|
273
|
-
return options as MergeQueryOptions
|
|
273
|
+
return options as MergeQueryOptions;
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
export function moveProperty(
|