feathers-utils 3.1.3 → 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 +18 -58
- package/dist/index.d.cts +21 -13
- package/dist/index.d.mts +21 -13
- package/dist/index.d.ts +21 -13
- package/dist/index.mjs +18 -58
- package/package.json +1 -1
- package/src/utils/filterQuery.ts +92 -39
- 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
|
-
optionsForFilterQuery.operators = operators;
|
|
375
|
-
}
|
|
376
|
-
if (filters) {
|
|
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;
|
|
384
364
|
}
|
|
385
|
-
|
|
365
|
+
if ("$skip" in providedQuery) {
|
|
366
|
+
result.$skip = $skip;
|
|
367
|
+
}
|
|
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);
|
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
|
/**
|
|
@@ -125,17 +125,10 @@ declare class DebouncedStore {
|
|
|
125
125
|
|
|
126
126
|
declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): (app: Application$1) => void;
|
|
127
127
|
|
|
128
|
-
interface FilterQueryOptions<T> {
|
|
129
|
-
service?: AdapterBase<T>;
|
|
130
|
-
operators?: FilterQueryOptions$1["operators"];
|
|
131
|
-
filters?: FilterQueryOptions$1["filters"];
|
|
132
|
-
}
|
|
133
|
-
declare function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>): any;
|
|
134
|
-
|
|
135
128
|
type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
|
|
136
129
|
type FirstLast = "first" | "last";
|
|
137
130
|
type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
|
|
138
|
-
interface MergeQueryOptions
|
|
131
|
+
interface MergeQueryOptions {
|
|
139
132
|
defaultHandle: Handle;
|
|
140
133
|
actionOnEmptyIntersect: ActionOnEmptyIntersect;
|
|
141
134
|
useLogicalConjunction: boolean;
|
|
@@ -153,7 +146,22 @@ declare function mergeArrays<T>(targetArr: T[] | undefined, sourceArr: T[] | und
|
|
|
153
146
|
* @param _options
|
|
154
147
|
* @returns Query
|
|
155
148
|
*/
|
|
156
|
-
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>;
|
|
157
165
|
|
|
158
166
|
/**
|
|
159
167
|
* util to get paginate options from context
|
|
@@ -217,9 +225,9 @@ type SetQueryKeySafelyOptions = {
|
|
|
217
225
|
};
|
|
218
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;
|
|
219
227
|
|
|
220
|
-
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; };
|
|
221
229
|
|
|
222
|
-
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; };
|
|
223
231
|
|
|
224
232
|
type Single<T> = T extends Array<infer U> ? U : T;
|
|
225
233
|
type AsArray<T> = T extends any[] ? T : [T];
|
|
@@ -267,4 +275,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
|
|
|
267
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;
|
|
268
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;
|
|
269
277
|
|
|
270
|
-
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
|
/**
|
|
@@ -125,17 +125,10 @@ declare class DebouncedStore {
|
|
|
125
125
|
|
|
126
126
|
declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): (app: Application$1) => void;
|
|
127
127
|
|
|
128
|
-
interface FilterQueryOptions<T> {
|
|
129
|
-
service?: AdapterBase<T>;
|
|
130
|
-
operators?: FilterQueryOptions$1["operators"];
|
|
131
|
-
filters?: FilterQueryOptions$1["filters"];
|
|
132
|
-
}
|
|
133
|
-
declare function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>): any;
|
|
134
|
-
|
|
135
128
|
type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
|
|
136
129
|
type FirstLast = "first" | "last";
|
|
137
130
|
type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
|
|
138
|
-
interface MergeQueryOptions
|
|
131
|
+
interface MergeQueryOptions {
|
|
139
132
|
defaultHandle: Handle;
|
|
140
133
|
actionOnEmptyIntersect: ActionOnEmptyIntersect;
|
|
141
134
|
useLogicalConjunction: boolean;
|
|
@@ -153,7 +146,22 @@ declare function mergeArrays<T>(targetArr: T[] | undefined, sourceArr: T[] | und
|
|
|
153
146
|
* @param _options
|
|
154
147
|
* @returns Query
|
|
155
148
|
*/
|
|
156
|
-
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>;
|
|
157
165
|
|
|
158
166
|
/**
|
|
159
167
|
* util to get paginate options from context
|
|
@@ -217,9 +225,9 @@ type SetQueryKeySafelyOptions = {
|
|
|
217
225
|
};
|
|
218
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;
|
|
219
227
|
|
|
220
|
-
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; };
|
|
221
229
|
|
|
222
|
-
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; };
|
|
223
231
|
|
|
224
232
|
type Single<T> = T extends Array<infer U> ? U : T;
|
|
225
233
|
type AsArray<T> = T extends any[] ? T : [T];
|
|
@@ -267,4 +275,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
|
|
|
267
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;
|
|
268
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;
|
|
269
277
|
|
|
270
|
-
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
|
/**
|
|
@@ -125,17 +125,10 @@ declare class DebouncedStore {
|
|
|
125
125
|
|
|
126
126
|
declare function debounceMixin(options?: Partial<InitDebounceMixinOptions>): (app: Application$1) => void;
|
|
127
127
|
|
|
128
|
-
interface FilterQueryOptions<T> {
|
|
129
|
-
service?: AdapterBase<T>;
|
|
130
|
-
operators?: FilterQueryOptions$1["operators"];
|
|
131
|
-
filters?: FilterQueryOptions$1["filters"];
|
|
132
|
-
}
|
|
133
|
-
declare function filterQuery<T>(query: Query, _options?: FilterQueryOptions<T>): any;
|
|
134
|
-
|
|
135
128
|
type Handle = "target" | "source" | "combine" | "intersect" | "intersectOrFull";
|
|
136
129
|
type FirstLast = "first" | "last";
|
|
137
130
|
type ActionOnEmptyIntersect = (target: unknown, source: unknown, prependKey: Path) => void;
|
|
138
|
-
interface MergeQueryOptions
|
|
131
|
+
interface MergeQueryOptions {
|
|
139
132
|
defaultHandle: Handle;
|
|
140
133
|
actionOnEmptyIntersect: ActionOnEmptyIntersect;
|
|
141
134
|
useLogicalConjunction: boolean;
|
|
@@ -153,7 +146,22 @@ declare function mergeArrays<T>(targetArr: T[] | undefined, sourceArr: T[] | und
|
|
|
153
146
|
* @param _options
|
|
154
147
|
* @returns Query
|
|
155
148
|
*/
|
|
156
|
-
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>;
|
|
157
165
|
|
|
158
166
|
/**
|
|
159
167
|
* util to get paginate options from context
|
|
@@ -217,9 +225,9 @@ type SetQueryKeySafelyOptions = {
|
|
|
217
225
|
};
|
|
218
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;
|
|
219
227
|
|
|
220
|
-
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; };
|
|
221
229
|
|
|
222
|
-
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; };
|
|
223
231
|
|
|
224
232
|
type Single<T> = T extends Array<infer U> ? U : T;
|
|
225
233
|
type AsArray<T> = T extends any[] ? T : [T];
|
|
@@ -267,4 +275,4 @@ type InferRemoveResultFromPath<App extends Application, Path extends string, IdO
|
|
|
267
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;
|
|
268
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;
|
|
269
277
|
|
|
270
|
-
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
|
-
optionsForFilterQuery.filters = filters;
|
|
364
|
-
}
|
|
365
|
-
if (service && "filterQuery" in service && typeof service.filterQuery === "function") {
|
|
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;
|
|
370
353
|
}
|
|
371
|
-
|
|
354
|
+
if ("$sort" in providedQuery) {
|
|
355
|
+
result.$sort = $sort;
|
|
356
|
+
}
|
|
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);
|
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
|
}
|
|
@@ -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(
|