feathers-utils 5.2.0 → 6.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/README.md CHANGED
@@ -1,10 +1,9 @@
1
1
  # feathers-utils
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/feathers-utils)](https://www.npmjs.com/package/feathers-utils)
4
- [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/fratzinger/feathers-utils/Node.js%20CI)](https://github.com/fratzinger/feathers-utils/actions/workflows/node.js.yml?query=branch%3Amain)
4
+ [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/fratzinger/feathers-utils/node.js.yml?branch=main)](https://github.com/fratzinger/feathers-utils/actions/workflows/node.js.yml?query=branch%3Amain)
5
5
  [![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/fratzinger/feathers-utils)](https://codeclimate.com/github/fratzinger/feathers-utils)
6
6
  [![Code Climate coverage](https://img.shields.io/codeclimate/coverage/fratzinger/feathers-utils)](https://codeclimate.com/github/fratzinger/feathers-utils)
7
- [![libraries.io](https://img.shields.io/librariesio/release/npm/feathers-utils)](https://libraries.io/npm/feathers-utils)
8
7
  [![npm](https://img.shields.io/npm/dm/feathers-utils)](https://www.npmjs.com/package/feathers-utils)
9
8
  [![GitHub license](https://img.shields.io/github/license/fratzinger/feathers-utils)](https://github.com/fratzinger/feathers-utils/blob/main/LICENSE.md)
10
9
 
package/dist/index.cjs CHANGED
@@ -620,13 +620,18 @@ const validateQueryProperty = (query, operators = []) => {
620
620
 
621
621
  function optimizeBatchPatch(items, options) {
622
622
  const map = [];
623
- const id = options?.id ?? "id";
624
- for (const [id2, data] of items) {
625
- const index = map.findIndex((item) => fastEquals.deepEqual(item.data, data));
623
+ const idKey = options?.id ?? "id";
624
+ for (const _data of items) {
625
+ const data = _data;
626
+ const id = _data[idKey];
627
+ delete data[idKey];
628
+ const index = map.findIndex((item) => {
629
+ return fastEquals.deepEqual(item.data, data);
630
+ });
626
631
  if (index === -1) {
627
- map.push({ ids: [id2], data });
632
+ map.push({ ids: [id], data });
628
633
  } else {
629
- map[index].ids.push(id2);
634
+ map[index].ids.push(id);
630
635
  }
631
636
  }
632
637
  return map.map(({ ids, data }) => {
@@ -635,7 +640,7 @@ function optimizeBatchPatch(items, options) {
635
640
  data,
636
641
  {
637
642
  query: {
638
- [id]: { $in: ids }
643
+ [idKey]: { $in: ids }
639
644
  }
640
645
  }
641
646
  ];
package/dist/index.d.cts CHANGED
@@ -14,6 +14,7 @@ type MaybeArray<T> = T | T[];
14
14
  type Promisable<T> = T | Promise<T>;
15
15
  type Path = Array<string | number>;
16
16
  type ReturnAsyncHook<H extends HookContext$1 = HookContext$1> = (context: H) => Promise<H>;
17
+ type KeyOf<T> = Extract<keyof T, string>;
17
18
 
18
19
  interface CreateRelatedOptions<S = Record<string, any>> {
19
20
  service: keyof S;
@@ -253,11 +254,12 @@ declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers
253
254
  */
254
255
  declare const validateQueryProperty: (query: any, operators?: string[]) => Query;
255
256
 
256
- type OptimizeBatchPatchOptions = {
257
- id?: string;
257
+ type OptimizeBatchPatchOptions<IdKey extends string> = {
258
+ /** the key of the id property */
259
+ id?: IdKey;
258
260
  };
259
261
  type OptimizeBatchPatchResultItem<T = Record<string, unknown>, P = Params> = [Id, T, P | undefined];
260
- declare function optimizeBatchPatch<T extends Record<string, unknown>, P extends Params>(items: Map<Id, T>, options?: OptimizeBatchPatchOptions): OptimizeBatchPatchResultItem<T, P>[];
262
+ declare function optimizeBatchPatch<T extends Record<string, any>, IdKey extends KeyOf<T>, P extends Params, R extends Omit<T, IdKey> = Omit<T, IdKey>>(items: T[], options?: OptimizeBatchPatchOptions<IdKey>): OptimizeBatchPatchResultItem<R, P>[];
261
263
 
262
264
  declare function flattenQuery(q: Query): any;
263
265
 
package/dist/index.d.mts CHANGED
@@ -14,6 +14,7 @@ type MaybeArray<T> = T | T[];
14
14
  type Promisable<T> = T | Promise<T>;
15
15
  type Path = Array<string | number>;
16
16
  type ReturnAsyncHook<H extends HookContext$1 = HookContext$1> = (context: H) => Promise<H>;
17
+ type KeyOf<T> = Extract<keyof T, string>;
17
18
 
18
19
  interface CreateRelatedOptions<S = Record<string, any>> {
19
20
  service: keyof S;
@@ -253,11 +254,12 @@ declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers
253
254
  */
254
255
  declare const validateQueryProperty: (query: any, operators?: string[]) => Query;
255
256
 
256
- type OptimizeBatchPatchOptions = {
257
- id?: string;
257
+ type OptimizeBatchPatchOptions<IdKey extends string> = {
258
+ /** the key of the id property */
259
+ id?: IdKey;
258
260
  };
259
261
  type OptimizeBatchPatchResultItem<T = Record<string, unknown>, P = Params> = [Id, T, P | undefined];
260
- declare function optimizeBatchPatch<T extends Record<string, unknown>, P extends Params>(items: Map<Id, T>, options?: OptimizeBatchPatchOptions): OptimizeBatchPatchResultItem<T, P>[];
262
+ declare function optimizeBatchPatch<T extends Record<string, any>, IdKey extends KeyOf<T>, P extends Params, R extends Omit<T, IdKey> = Omit<T, IdKey>>(items: T[], options?: OptimizeBatchPatchOptions<IdKey>): OptimizeBatchPatchResultItem<R, P>[];
261
263
 
262
264
  declare function flattenQuery(q: Query): any;
263
265
 
package/dist/index.d.ts CHANGED
@@ -14,6 +14,7 @@ type MaybeArray<T> = T | T[];
14
14
  type Promisable<T> = T | Promise<T>;
15
15
  type Path = Array<string | number>;
16
16
  type ReturnAsyncHook<H extends HookContext$1 = HookContext$1> = (context: H) => Promise<H>;
17
+ type KeyOf<T> = Extract<keyof T, string>;
17
18
 
18
19
  interface CreateRelatedOptions<S = Record<string, any>> {
19
20
  service: keyof S;
@@ -253,11 +254,12 @@ declare const toJSON: (context: HookContext) => HookContext<_feathersjs_feathers
253
254
  */
254
255
  declare const validateQueryProperty: (query: any, operators?: string[]) => Query;
255
256
 
256
- type OptimizeBatchPatchOptions = {
257
- id?: string;
257
+ type OptimizeBatchPatchOptions<IdKey extends string> = {
258
+ /** the key of the id property */
259
+ id?: IdKey;
258
260
  };
259
261
  type OptimizeBatchPatchResultItem<T = Record<string, unknown>, P = Params> = [Id, T, P | undefined];
260
- declare function optimizeBatchPatch<T extends Record<string, unknown>, P extends Params>(items: Map<Id, T>, options?: OptimizeBatchPatchOptions): OptimizeBatchPatchResultItem<T, P>[];
262
+ declare function optimizeBatchPatch<T extends Record<string, any>, IdKey extends KeyOf<T>, P extends Params, R extends Omit<T, IdKey> = Omit<T, IdKey>>(items: T[], options?: OptimizeBatchPatchOptions<IdKey>): OptimizeBatchPatchResultItem<R, P>[];
261
263
 
262
264
  declare function flattenQuery(q: Query): any;
263
265
 
package/dist/index.mjs CHANGED
@@ -609,13 +609,18 @@ const validateQueryProperty = (query, operators = []) => {
609
609
 
610
610
  function optimizeBatchPatch(items, options) {
611
611
  const map = [];
612
- const id = options?.id ?? "id";
613
- for (const [id2, data] of items) {
614
- const index = map.findIndex((item) => deepEqual(item.data, data));
612
+ const idKey = options?.id ?? "id";
613
+ for (const _data of items) {
614
+ const data = _data;
615
+ const id = _data[idKey];
616
+ delete data[idKey];
617
+ const index = map.findIndex((item) => {
618
+ return deepEqual(item.data, data);
619
+ });
615
620
  if (index === -1) {
616
- map.push({ ids: [id2], data });
621
+ map.push({ ids: [id], data });
617
622
  } else {
618
- map[index].ids.push(id2);
623
+ map[index].ids.push(id);
619
624
  }
620
625
  }
621
626
  return map.map(({ ids, data }) => {
@@ -624,7 +629,7 @@ function optimizeBatchPatch(items, options) {
624
629
  data,
625
630
  {
626
631
  query: {
627
- [id]: { $in: ids }
632
+ [idKey]: { $in: ids }
628
633
  }
629
634
  }
630
635
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feathers-utils",
3
- "version": "5.2.0",
3
+ "version": "6.0.0",
4
4
  "description": "Some utils for projects using '@feathersjs/feathers'",
5
5
  "author": "fratzinger",
6
6
  "repository": {
@@ -22,3 +22,5 @@ export type ReturnSyncHook<H extends HookContext = HookContext> = (
22
22
  export type ReturnAsyncHook<H extends HookContext = HookContext> = (
23
23
  context: H,
24
24
  ) => Promise<H>;
25
+
26
+ export type KeyOf<T> = Extract<keyof T, string>;
@@ -1,8 +1,10 @@
1
1
  import type { Id, Params } from "@feathersjs/feathers";
2
2
  import { deepEqual } from "fast-equals";
3
+ import type { KeyOf } from "../typesInternal";
3
4
 
4
- export type OptimizeBatchPatchOptions = {
5
- id?: string;
5
+ export type OptimizeBatchPatchOptions<IdKey extends string> = {
6
+ /** the key of the id property */
7
+ id?: IdKey;
6
8
  };
7
9
 
8
10
  export type OptimizeBatchPatchResultItem<
@@ -11,18 +13,26 @@ export type OptimizeBatchPatchResultItem<
11
13
  > = [Id, T, P | undefined];
12
14
 
13
15
  export function optimizeBatchPatch<
14
- T extends Record<string, unknown>,
16
+ T extends Record<string, any>,
17
+ IdKey extends KeyOf<T>,
15
18
  P extends Params,
19
+ R extends Omit<T, IdKey> = Omit<T, IdKey>,
16
20
  >(
17
- items: Map<Id, T>,
18
- options?: OptimizeBatchPatchOptions,
19
- ): OptimizeBatchPatchResultItem<T, P>[] {
20
- const map: { ids: Id[]; data: T }[] = [];
21
+ items: T[],
22
+ options?: OptimizeBatchPatchOptions<IdKey>,
23
+ ): OptimizeBatchPatchResultItem<R, P>[] {
24
+ const map: { ids: Id[]; data: R }[] = [];
21
25
 
22
- const id = options?.id ?? "id";
26
+ const idKey = options?.id ?? "id";
23
27
 
24
- for (const [id, data] of items) {
25
- const index = map.findIndex((item) => deepEqual(item.data, data));
28
+ for (const _data of items) {
29
+ const data = _data as unknown as R;
30
+ const id = _data[idKey];
31
+ delete data[idKey as any];
32
+
33
+ const index = map.findIndex((item) => {
34
+ return deepEqual(item.data, data);
35
+ });
26
36
 
27
37
  if (index === -1) {
28
38
  map.push({ ids: [id], data });
@@ -33,34 +43,56 @@ export function optimizeBatchPatch<
33
43
 
34
44
  return map.map(({ ids, data }) => {
35
45
  return ids.length === 1
36
- ? ([ids[0], data, undefined] as OptimizeBatchPatchResultItem<T, P>)
46
+ ? ([ids[0], data, undefined] as OptimizeBatchPatchResultItem<R, P>)
37
47
  : ([
38
48
  null,
39
49
  data,
40
50
  {
41
51
  query: {
42
- [id]: { $in: ids },
52
+ [idKey]: { $in: ids },
43
53
  },
44
54
  },
45
- ] as OptimizeBatchPatchResultItem<T, P>);
55
+ ] as OptimizeBatchPatchResultItem<R, P>);
46
56
  });
47
57
  }
48
58
 
49
59
  if (import.meta.vitest) {
50
60
  const { it, expect } = import.meta.vitest;
51
61
  it("optimizeBatchPatch", () => {
52
- const items = new Map<Id, Record<string, unknown>>([
53
- ["1", { name: "John" }],
54
- ["2", { name: "Jane" }],
55
- ["3", { name: "John" }],
56
- ["4", { name: "Jane" }],
57
- [5, { name: "Jack" }],
58
- ]);
59
-
60
- expect(optimizeBatchPatch(items)).toEqual([
62
+ expect(
63
+ optimizeBatchPatch(
64
+ [
65
+ { id: "1", name: "John" },
66
+ { id: "2", name: "Jane" },
67
+ { id: "3", name: "John" },
68
+ { id: "4", name: "Jane" },
69
+ { id: 5, name: "Jack" },
70
+ ],
71
+ { id: "id" },
72
+ ),
73
+ ).toEqual([
61
74
  [null, { name: "John" }, { query: { id: { $in: ["1", "3"] } } }],
62
75
  [null, { name: "Jane" }, { query: { id: { $in: ["2", "4"] } } }],
63
76
  [5, { name: "Jack" }, undefined],
64
77
  ]);
65
78
  });
79
+
80
+ it("optimizeBatchPatch with _id", () => {
81
+ expect(
82
+ optimizeBatchPatch(
83
+ [
84
+ { _id: "1", name: "John" },
85
+ { _id: "2", name: "Jane" },
86
+ { _id: "3", name: "John" },
87
+ { _id: "4", name: "Jane" },
88
+ { _id: 5, name: "Jack" },
89
+ ],
90
+ { id: "_id" },
91
+ ),
92
+ ).toEqual([
93
+ [null, { name: "John" }, { query: { _id: { $in: ["1", "3"] } } }],
94
+ [null, { name: "Jane" }, { query: { _id: { $in: ["2", "4"] } } }],
95
+ [5, { name: "Jack" }, undefined],
96
+ ]);
97
+ });
66
98
  }