@dhis2/app-service-data 3.11.2 → 3.12.0-alpha.1

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.
Files changed (113) hide show
  1. package/build/cjs/__tests__/integration.test.js +6 -15
  2. package/build/cjs/__tests__/mutations.test.js +4 -11
  3. package/build/cjs/engine/DataEngine.js +4 -14
  4. package/build/cjs/engine/DataEngine.test.js +0 -2
  5. package/build/cjs/engine/helpers/getMutationFetchType.js +0 -2
  6. package/build/cjs/engine/helpers/getMutationFetchType.test.js +0 -1
  7. package/build/cjs/engine/helpers/resolveDynamicQuery.js +0 -2
  8. package/build/cjs/engine/helpers/resolveDynamicQuery.test.js +3 -4
  9. package/build/cjs/engine/helpers/validate.js +0 -21
  10. package/build/cjs/engine/helpers/validate.test.js +0 -1
  11. package/build/cjs/engine/index.js +0 -18
  12. package/build/cjs/engine/types/FetchError.js +3 -8
  13. package/build/cjs/engine/types/FetchError.test.js +0 -1
  14. package/build/cjs/engine/types/InvalidQueryError.js +3 -8
  15. package/build/cjs/index.js +0 -2
  16. package/build/cjs/links/CustomDataLink.js +3 -17
  17. package/build/cjs/links/CustomDataLink.test.js +0 -1
  18. package/build/cjs/links/ErrorLink.js +3 -7
  19. package/build/cjs/links/RestAPILink/fetchData.js +12 -22
  20. package/build/cjs/links/RestAPILink/fetchData.test.js +0 -2
  21. package/build/cjs/links/RestAPILink/metadataResources.js +9 -7
  22. package/build/cjs/links/RestAPILink/path.js +0 -3
  23. package/build/cjs/links/RestAPILink/path.test.js +0 -1
  24. package/build/cjs/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.js +9 -14
  25. package/build/cjs/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.test.js +0 -1
  26. package/build/cjs/links/RestAPILink/queryToRequestOptions/requestContentType.js +4 -31
  27. package/build/cjs/links/RestAPILink/queryToRequestOptions/requestContentType.test.js +0 -1
  28. package/build/cjs/links/RestAPILink/queryToRequestOptions/textPlainMatchers.js +24 -40
  29. package/build/cjs/links/RestAPILink/queryToRequestOptions/textPlainMatchers.test.js +10 -1
  30. package/build/cjs/links/RestAPILink/queryToRequestOptions/xWwwFormUrlencodedMatchers.js +0 -2
  31. package/build/cjs/links/RestAPILink/queryToRequestOptions/xWwwFormUrlencodedMatchers.test.js +0 -1
  32. package/build/cjs/links/RestAPILink/queryToRequestOptions.js +0 -9
  33. package/build/cjs/links/RestAPILink/queryToRequestOptions.test.js +0 -1
  34. package/build/cjs/links/RestAPILink/queryToResourcePath.js +3 -24
  35. package/build/cjs/links/RestAPILink/queryToResourcePath.test.js +2 -4
  36. package/build/cjs/links/RestAPILink/validateQuery.js +4 -18
  37. package/build/cjs/links/RestAPILink/validateQuery.test.js +0 -1
  38. package/build/cjs/links/RestAPILink.js +3 -14
  39. package/build/cjs/links/RestAPILink.test.js +0 -2
  40. package/build/cjs/links/index.js +0 -6
  41. package/build/cjs/react/components/CustomDataProvider.js +2 -11
  42. package/build/cjs/react/components/DataMutation.js +1 -4
  43. package/build/cjs/react/components/DataProvider.js +5 -14
  44. package/build/cjs/react/components/DataProvider.test.js +2 -9
  45. package/build/cjs/react/components/DataQuery.js +1 -4
  46. package/build/cjs/react/context/DataContext.js +2 -8
  47. package/build/cjs/react/context/defaultContext.js +2 -6
  48. package/build/cjs/react/context/defaultContext.test.js +0 -1
  49. package/build/cjs/react/hooks/mergeAndCompareVariables.js +4 -6
  50. package/build/cjs/react/hooks/mergeAndCompareVariables.test.js +2 -3
  51. package/build/cjs/react/hooks/stableVariablesHash.js +11 -16
  52. package/build/cjs/react/hooks/stableVariablesHash.test.js +0 -1
  53. package/build/cjs/react/hooks/useDataEngine.js +0 -4
  54. package/build/cjs/react/hooks/useDataMutation.js +0 -7
  55. package/build/cjs/react/hooks/useDataMutation.test.js +42 -71
  56. package/build/cjs/react/hooks/useDataQuery.js +11 -22
  57. package/build/cjs/react/hooks/useDataQuery.test.js +318 -374
  58. package/build/cjs/react/hooks/useQueryExecutor.js +6 -14
  59. package/build/cjs/react/hooks/useQueryExecutor.test.js +42 -45
  60. package/build/cjs/react/hooks/useStaticInput.js +0 -3
  61. package/build/cjs/react/hooks/useStaticInput.test.js +8 -10
  62. package/build/cjs/react/index.js +0 -11
  63. package/build/cjs/setupRTL.js +1 -2
  64. package/build/es/__tests__/integration.test.js +4 -8
  65. package/build/es/__tests__/mutations.test.js +2 -4
  66. package/build/es/engine/DataEngine.js +3 -8
  67. package/build/es/engine/DataEngine.test.js +0 -1
  68. package/build/es/engine/helpers/resolveDynamicQuery.test.js +3 -3
  69. package/build/es/engine/helpers/validate.js +0 -13
  70. package/build/es/engine/types/FetchError.js +3 -6
  71. package/build/es/engine/types/InvalidQueryError.js +3 -6
  72. package/build/es/links/CustomDataLink.js +3 -15
  73. package/build/es/links/ErrorLink.js +3 -5
  74. package/build/es/links/RestAPILink/fetchData.js +12 -16
  75. package/build/es/links/RestAPILink/metadataResources.js +8 -3
  76. package/build/es/links/RestAPILink/path.js +0 -1
  77. package/build/es/links/RestAPILink/queryToRequestOptions/multipartFormDataMatchers.js +9 -4
  78. package/build/es/links/RestAPILink/queryToRequestOptions/requestContentType.js +2 -19
  79. package/build/es/links/RestAPILink/queryToRequestOptions/textPlainMatchers.js +24 -20
  80. package/build/es/links/RestAPILink/queryToRequestOptions/textPlainMatchers.test.js +10 -0
  81. package/build/es/links/RestAPILink/queryToRequestOptions.js +0 -7
  82. package/build/es/links/RestAPILink/queryToResourcePath.js +3 -21
  83. package/build/es/links/RestAPILink/queryToResourcePath.test.js +2 -3
  84. package/build/es/links/RestAPILink/validateQuery.js +4 -16
  85. package/build/es/links/RestAPILink.js +3 -8
  86. package/build/es/react/components/CustomDataProvider.js +1 -1
  87. package/build/es/react/components/DataMutation.js +1 -1
  88. package/build/es/react/components/DataProvider.js +3 -1
  89. package/build/es/react/components/DataProvider.test.js +1 -1
  90. package/build/es/react/components/DataQuery.js +1 -1
  91. package/build/es/react/hooks/mergeAndCompareVariables.js +4 -3
  92. package/build/es/react/hooks/mergeAndCompareVariables.test.js +2 -1
  93. package/build/es/react/hooks/stableVariablesHash.js +11 -14
  94. package/build/es/react/hooks/useDataMutation.test.js +17 -39
  95. package/build/es/react/hooks/useDataQuery.js +11 -15
  96. package/build/es/react/hooks/useDataQuery.test.js +268 -318
  97. package/build/es/react/hooks/useQueryExecutor.js +6 -9
  98. package/build/es/react/hooks/useQueryExecutor.test.js +33 -34
  99. package/build/es/react/hooks/useStaticInput.test.js +6 -6
  100. package/build/es/setupRTL.js +1 -1
  101. package/build/types/engine/types/ExecuteOptions.d.ts +1 -1
  102. package/build/types/engine/types/FetchError.d.ts +2 -2
  103. package/build/types/engine/types/JsonValue.d.ts +1 -1
  104. package/build/types/engine/types/Mutation.d.ts +2 -2
  105. package/build/types/engine/types/PossiblyDynamic.d.ts +1 -1
  106. package/build/types/engine/types/Query.d.ts +3 -3
  107. package/build/types/engine/types/QueryParameters.d.ts +4 -4
  108. package/build/types/links/CustomDataLink.d.ts +2 -2
  109. package/build/types/links/RestAPILink/queryToRequestOptions/requestContentType.d.ts +1 -1
  110. package/build/types/links/RestAPILink/queryToRequestOptions.d.ts +1 -1
  111. package/build/types/react/hooks/mergeAndCompareVariables.d.ts +1 -1
  112. package/build/types/types.d.ts +6 -6
  113. package/package.json +4 -4
@@ -4,7 +4,7 @@ import { DataEngine } from '../../engine';
4
4
  import { CustomDataLink } from '../../links';
5
5
  import { DataContext } from '../context/DataContext';
6
6
  import { queryClientOptions as queryClientDefaults } from './DataProvider';
7
- export const CustomDataProvider = (_ref) => {
7
+ export const CustomDataProvider = _ref => {
8
8
  let {
9
9
  children,
10
10
  data,
@@ -1,5 +1,5 @@
1
1
  import { useDataMutation } from '../hooks/useDataMutation';
2
- export const DataMutation = (_ref) => {
2
+ export const DataMutation = _ref => {
3
3
  let {
4
4
  mutation,
5
5
  onComplete,
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable react/no-unused-prop-types */
2
+
2
3
  import { useConfig } from '@dhis2/app-service-config';
3
4
  import React from 'react';
4
5
  import { QueryClient, QueryClientProvider } from 'react-query';
@@ -23,7 +24,8 @@ export const queryClientOptions = {
23
24
  };
24
25
  const queryClient = new QueryClient(queryClientOptions);
25
26
  export const DataProvider = props => {
26
- const config = { ...useConfig(),
27
+ const config = {
28
+ ...useConfig(),
27
29
  ...props
28
30
  };
29
31
  const link = new RestAPILink(config);
@@ -7,7 +7,7 @@ import { DataProvider } from './DataProvider';
7
7
  describe('DataProvider', () => {
8
8
  it('Should pass a new engine and RestAPILink to consumers', () => {
9
9
  const renderFunction = jest.fn();
10
- render( /*#__PURE__*/React.createElement(DataProvider, {
10
+ render(/*#__PURE__*/React.createElement(DataProvider, {
11
11
  baseUrl: "test",
12
12
  apiVersion: 42
13
13
  }, /*#__PURE__*/React.createElement(DataContext.Consumer, null, renderFunction)));
@@ -1,5 +1,5 @@
1
1
  import { useDataQuery } from '../hooks/useDataQuery';
2
- export const DataQuery = (_ref) => {
2
+ export const DataQuery = _ref => {
3
3
  let {
4
4
  query,
5
5
  onComplete,
@@ -6,11 +6,12 @@ export const mergeAndCompareVariables = (previousVariables, newVariables, previo
6
6
  mergedVariablesHash: previousHash,
7
7
  mergedVariables: previousVariables
8
8
  };
9
- } // Use cached hash if it exists
10
-
9
+ }
11
10
 
11
+ // Use cached hash if it exists
12
12
  const currentHash = previousHash || stableVariablesHash(previousVariables);
13
- const mergedVariables = { ...previousVariables,
13
+ const mergedVariables = {
14
+ ...previousVariables,
14
15
  ...newVariables
15
16
  };
16
17
  const mergedVariablesHash = stableVariablesHash(mergedVariables);
@@ -41,7 +41,8 @@ describe('mergeAndCompareVariables', () => {
41
41
  const newVariables = {
42
42
  answer: 43
43
43
  };
44
- const expectedMergedVariables = { ...testVariables,
44
+ const expectedMergedVariables = {
45
+ ...testVariables,
45
46
  ...newVariables
46
47
  };
47
48
  expect(mergeAndCompareVariables(testVariables, newVariables, testHash)).toMatchObject({
@@ -1,42 +1,40 @@
1
1
  function hasObjectPrototype(o) {
2
2
  return Object.prototype.toString.call(o) === '[object Object]';
3
- } // eslint-disable-next-line @typescript-eslint/ban-types
4
-
3
+ }
5
4
 
5
+ // eslint-disable-next-line @typescript-eslint/ban-types
6
6
  export function isPlainObject(o) {
7
7
  if (!hasObjectPrototype(o)) {
8
8
  return false;
9
- } // If has modified constructor
10
-
9
+ }
11
10
 
11
+ // If has modified constructor
12
12
  const ctor = o.constructor;
13
-
14
13
  if (typeof ctor === 'undefined') {
15
14
  return true;
16
- } // If has modified prototype
17
-
15
+ }
18
16
 
17
+ // If has modified prototype
19
18
  const prot = ctor.prototype;
20
-
21
19
  if (!hasObjectPrototype(prot)) {
22
20
  return false;
23
- } // If constructor does not have an Object-specific method
24
-
21
+ }
25
22
 
23
+ // If constructor does not have an Object-specific method
26
24
  if (!Object.prototype.hasOwnProperty.call(prot, 'isPrototypeOf')) {
27
25
  return false;
28
- } // Most likely a plain Object
29
-
26
+ }
30
27
 
28
+ // Most likely a plain Object
31
29
  return true;
32
30
  }
31
+
33
32
  /**
34
33
  * Hashes the value into a stable hash.
35
34
  */
36
35
 
37
36
  export function stableVariablesHash(value) {
38
37
  let hash;
39
-
40
38
  try {
41
39
  hash = JSON.stringify(value, (_, val) => isPlainObject(val) ? Object.keys(val).sort().reduce((result, key) => {
42
40
  result[key] = val[key];
@@ -45,6 +43,5 @@ export function stableVariablesHash(value) {
45
43
  } catch (e) {
46
44
  throw new Error('Could not serialize variables. Make sure that the variables do not contain circular references and can be processed by JSON.stringify.');
47
45
  }
48
-
49
46
  return hash;
50
47
  }
@@ -1,4 +1,4 @@
1
- import { renderHook, act } from '@testing-library/react-hooks';
1
+ import { renderHook, act, waitFor } from '@testing-library/react';
2
2
  import * as React from 'react';
3
3
  import { CustomDataProvider } from '../components/CustomDataProvider';
4
4
  import { useDataEngine } from './useDataEngine';
@@ -15,8 +15,7 @@ describe('useDataMutation', () => {
15
15
  const data = {
16
16
  answer: 42
17
17
  };
18
-
19
- const wrapper = (_ref) => {
18
+ const wrapper = _ref => {
20
19
  let {
21
20
  children
22
21
  } = _ref;
@@ -24,10 +23,8 @@ describe('useDataMutation', () => {
24
23
  data: data
25
24
  }, children);
26
25
  };
27
-
28
26
  const {
29
- result,
30
- waitFor
27
+ result
31
28
  } = renderHook(() => useDataMutation(mutation), {
32
29
  wrapper
33
30
  });
@@ -66,8 +63,7 @@ describe('useDataMutation', () => {
66
63
  const data = {
67
64
  answer: 42
68
65
  };
69
-
70
- const wrapper = (_ref2) => {
66
+ const wrapper = _ref2 => {
71
67
  let {
72
68
  children
73
69
  } = _ref2;
@@ -75,10 +71,8 @@ describe('useDataMutation', () => {
75
71
  data: data
76
72
  }, children);
77
73
  };
78
-
79
74
  const {
80
- result,
81
- waitFor
75
+ result
82
76
  } = renderHook(() => useDataMutation(mutation, {
83
77
  lazy: false
84
78
  }), {
@@ -110,8 +104,7 @@ describe('useDataMutation', () => {
110
104
  const data = {
111
105
  answer: 42
112
106
  };
113
-
114
- const wrapper = (_ref3) => {
107
+ const wrapper = _ref3 => {
115
108
  let {
116
109
  children
117
110
  } = _ref3;
@@ -119,10 +112,8 @@ describe('useDataMutation', () => {
119
112
  data: data
120
113
  }, children);
121
114
  };
122
-
123
115
  const {
124
- result,
125
- waitFor
116
+ result
126
117
  } = renderHook(() => useDataMutation(mutation, {
127
118
  onComplete
128
119
  }), {
@@ -159,8 +150,7 @@ describe('useDataMutation', () => {
159
150
  throw error;
160
151
  }
161
152
  };
162
-
163
- const wrapper = (_ref4) => {
153
+ const wrapper = _ref4 => {
164
154
  let {
165
155
  children
166
156
  } = _ref4;
@@ -168,10 +158,8 @@ describe('useDataMutation', () => {
168
158
  data: data
169
159
  }, children);
170
160
  };
171
-
172
161
  const {
173
- result,
174
- waitFor
162
+ result
175
163
  } = renderHook(() => useDataMutation(mutation, {
176
164
  onError
177
165
  }), {
@@ -197,7 +185,7 @@ describe('useDataMutation', () => {
197
185
  const mutation = {
198
186
  type: 'update',
199
187
  resource: 'answer',
200
- id: (_ref5) => {
188
+ id: _ref5 => {
201
189
  let {
202
190
  id
203
191
  } = _ref5;
@@ -211,8 +199,7 @@ describe('useDataMutation', () => {
211
199
  const data = {
212
200
  answer: answerSpy
213
201
  };
214
-
215
- const wrapper = (_ref6) => {
202
+ const wrapper = _ref6 => {
216
203
  let {
217
204
  children
218
205
  } = _ref6;
@@ -220,10 +207,8 @@ describe('useDataMutation', () => {
220
207
  data: data
221
208
  }, children);
222
209
  };
223
-
224
210
  const {
225
- result,
226
- waitFor
211
+ result
227
212
  } = renderHook(() => useDataMutation(mutation, {
228
213
  lazy: false,
229
214
  variables: {
@@ -257,8 +242,7 @@ describe('useDataMutation', () => {
257
242
  answer: '?'
258
243
  }
259
244
  };
260
-
261
- const wrapper = (_ref7) => {
245
+ const wrapper = _ref7 => {
262
246
  let {
263
247
  children
264
248
  } = _ref7;
@@ -266,18 +250,17 @@ describe('useDataMutation', () => {
266
250
  data: {}
267
251
  }, children);
268
252
  };
269
-
270
253
  const engineHook = renderHook(() => useDataEngine(), {
271
254
  wrapper
272
255
  });
273
256
  const mutationHook = renderHook(() => useDataMutation(mutation), {
274
257
  wrapper
275
258
  });
259
+
276
260
  /**
277
261
  * Ideally we'd check referential equality here with .toBe, but since
278
262
  * both hooks run in a different context that doesn't work.
279
263
  */
280
-
281
264
  expect(mutationHook.result.current[1].engine).toStrictEqual(engineHook.result.current);
282
265
  });
283
266
  it('should return a stable mutate function', async () => {
@@ -291,8 +274,7 @@ describe('useDataMutation', () => {
291
274
  const data = {
292
275
  answer: 42
293
276
  };
294
-
295
- const wrapper = (_ref8) => {
277
+ const wrapper = _ref8 => {
296
278
  let {
297
279
  children
298
280
  } = _ref8;
@@ -300,7 +282,6 @@ describe('useDataMutation', () => {
300
282
  data: data
301
283
  }, children);
302
284
  };
303
-
304
285
  const {
305
286
  result
306
287
  } = renderHook(() => useDataMutation(mutation), {
@@ -330,8 +311,7 @@ describe('useDataMutation', () => {
330
311
  const data = {
331
312
  answer: 42
332
313
  };
333
-
334
- const wrapper = (_ref9) => {
314
+ const wrapper = _ref9 => {
335
315
  let {
336
316
  children
337
317
  } = _ref9;
@@ -339,10 +319,8 @@ describe('useDataMutation', () => {
339
319
  data: data
340
320
  }, children);
341
321
  };
342
-
343
322
  const {
344
- result,
345
- waitFor
323
+ result
346
324
  } = renderHook(() => useDataMutation(mutation), {
347
325
  wrapper
348
326
  });
@@ -3,7 +3,6 @@ import { useQuery, setLogger } from 'react-query';
3
3
  import { mergeAndCompareVariables } from './mergeAndCompareVariables';
4
4
  import { useDataEngine } from './useDataEngine';
5
5
  import { useStaticInput } from './useStaticInput';
6
-
7
6
  const noop = () => {
8
7
  /**
9
8
  * Used to silence the default react-query logger. Eventually we
@@ -11,7 +10,6 @@ const noop = () => {
11
10
  * to setLogger here.
12
11
  */
13
12
  };
14
-
15
13
  setLogger({
16
14
  log: noop,
17
15
  warn: noop,
@@ -35,6 +33,7 @@ export const useDataQuery = function (query) {
35
33
  enabled: !initialLazy,
36
34
  refetchCallback: undefined
37
35
  });
36
+
38
37
  /**
39
38
  * Display current query state and refetch count in React DevTools
40
39
  */
@@ -44,41 +43,36 @@ export const useDataQuery = function (query) {
44
43
  enabled: queryState.current.enabled,
45
44
  variables: queryState.current.variables
46
45
  }, debugValue => JSON.stringify(debugValue));
46
+
47
47
  /**
48
48
  * User callbacks and refetch handling
49
49
  */
50
50
 
51
51
  const onSuccess = data => {
52
52
  var _queryState$current$r, _queryState$current;
53
-
54
53
  (_queryState$current$r = (_queryState$current = queryState.current).refetchCallback) === null || _queryState$current$r === void 0 ? void 0 : _queryState$current$r.call(_queryState$current, data);
55
54
  queryState.current.refetchCallback = undefined;
56
-
57
55
  if (userOnSuccess) {
58
56
  userOnSuccess(data);
59
57
  }
60
58
  };
61
-
62
59
  const onError = error => {
63
60
  // If we'd want to reject on errors we'd call the cb with the error here
64
61
  queryState.current.refetchCallback = undefined;
65
-
66
62
  if (userOnError) {
67
63
  userOnError(error);
68
64
  }
69
65
  };
66
+
70
67
  /**
71
68
  * Setting up react-query
72
69
  */
73
70
 
74
-
75
71
  const engine = useDataEngine();
76
72
  const queryKey = [staticQuery, queryState.current.variables];
77
-
78
73
  const queryFn = () => engine.query(staticQuery, {
79
74
  variables: queryState.current.variables
80
75
  });
81
-
82
76
  const {
83
77
  isIdle,
84
78
  isFetching,
@@ -91,6 +85,7 @@ export const useDataQuery = function (query) {
91
85
  onSuccess,
92
86
  onError
93
87
  });
88
+
94
89
  /**
95
90
  * Refetch allows a user to update the variables or just
96
91
  * trigger a refetch of the query with the current variables.
@@ -106,41 +101,42 @@ export const useDataQuery = function (query) {
106
101
  mergedVariables,
107
102
  mergedVariablesHash
108
103
  } = mergeAndCompareVariables(queryState.current.variables, newVariables, queryState.current.variablesHash);
104
+
109
105
  /**
110
106
  * If there are no updates that will trigger an automatic refetch
111
107
  * we'll need to call react-query's refetch directly
112
108
  */
113
-
114
109
  if (queryState.current.enabled && identical) {
115
110
  return queryRefetch({
116
111
  cancelRefetch: true,
117
112
  throwOnError: false
118
- }).then((_ref) => {
113
+ }).then(_ref => {
119
114
  let {
120
115
  data
121
116
  } = _ref;
122
117
  return data;
123
118
  });
124
119
  }
125
-
126
120
  queryState.current.variables = mergedVariables;
127
121
  queryState.current.variablesHash = mergedVariablesHash;
128
- queryState.current.enabled = true; // This promise does not currently reject on errors
122
+ queryState.current.enabled = true;
129
123
 
124
+ // This promise does not currently reject on errors
130
125
  const refetchPromise = new Promise(resolve => {
131
126
  queryState.current.refetchCallback = data => {
132
127
  resolve(data);
133
128
  };
134
- }); // Trigger a react-query refetch by incrementing variablesUpdateCount state
129
+ });
135
130
 
131
+ // Trigger a react-query refetch by incrementing variablesUpdateCount state
136
132
  setVariablesUpdateCount(prevCount => prevCount + 1);
137
133
  return refetchPromise;
138
134
  }, [queryRefetch]);
135
+
139
136
  /**
140
137
  * react-query returns null or an error, but we return undefined
141
138
  * or an error, so this ensures consistency with the other types.
142
139
  */
143
-
144
140
  const ourError = error || undefined;
145
141
  return {
146
142
  engine,