integreat 0.7.33 → 0.7.37
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/lib/actions/sync.js +218 -74
- package/lib/authenticators/options.js +7 -7
- package/lib/dispatch.js +43 -19
- package/lib/integreat.js +41 -33
- package/lib/mapping/index.js +90 -46
- package/lib/mapping/normalize.js +47 -25
- package/lib/queue/enqueue.js +17 -6
- package/lib/queue/middleware.js +5 -2
- package/package.json +13 -13
package/lib/actions/sync.js
CHANGED
|
@@ -4,66 +4,124 @@ const pLimit = require('p-limit')
|
|
|
4
4
|
const action = require('../utils/createAction')
|
|
5
5
|
const createError = require('../utils/createError')
|
|
6
6
|
|
|
7
|
-
const createTransformAction = (
|
|
8
|
-
action
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
const createTransformAction = (
|
|
8
|
+
{ action: type, ...payload },
|
|
9
|
+
data,
|
|
10
|
+
{ ident, project }
|
|
11
|
+
) => action(type, { ...payload, data }, { ident, project })
|
|
12
|
+
|
|
13
|
+
const makeErrorString = (results) =>
|
|
14
|
+
results
|
|
15
|
+
.map((result, index) =>
|
|
16
|
+
result.status === 'ok' ? null : `[${index}]: ${result.error}`
|
|
17
|
+
)
|
|
18
|
+
.filter(Boolean)
|
|
19
|
+
.join('\n')
|
|
14
20
|
|
|
15
21
|
const addDeltaToDate = (date, delta) =>
|
|
16
22
|
delta ? new Date(date.getTime() + delta) : date
|
|
17
23
|
|
|
18
24
|
const generateUpdatedAfter = (updatedAfter, afterDelta) => ({
|
|
19
25
|
updatedAfter: addDeltaToDate(updatedAfter, afterDelta),
|
|
20
|
-
updatedSince: addDeltaToDate(updatedAfter, 1)
|
|
26
|
+
updatedSince: addDeltaToDate(updatedAfter, 1),
|
|
21
27
|
})
|
|
22
28
|
|
|
23
|
-
const setUpdatedParams =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
const setUpdatedParams =
|
|
30
|
+
(dispatch, dontSetUntil, afterDelta, untilDelta, metaKey, ident) =>
|
|
31
|
+
async (params) => {
|
|
32
|
+
const { status, data, error } = await dispatch(
|
|
33
|
+
action(
|
|
34
|
+
'GET_META',
|
|
35
|
+
{ service: params.service, metaKey, keys: 'lastSyncedAt' },
|
|
36
|
+
{ ident }
|
|
37
|
+
)
|
|
38
|
+
)
|
|
27
39
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
if (status === 'ok' && data && data.meta && data.meta.lastSyncedAt) {
|
|
41
|
+
return {
|
|
42
|
+
...params,
|
|
43
|
+
...generateUpdatedAfter(data.meta.lastSyncedAt, afterDelta),
|
|
44
|
+
updatedUntil: dontSetUntil
|
|
45
|
+
? undefined
|
|
46
|
+
: addDeltaToDate(new Date(), untilDelta),
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
debug(
|
|
50
|
+
'SYNC: Could not get meta for service %s. Error: %s %s',
|
|
51
|
+
params.service,
|
|
52
|
+
status,
|
|
53
|
+
error
|
|
54
|
+
)
|
|
33
55
|
}
|
|
34
|
-
|
|
35
|
-
debug('SYNC: Could not get meta for service %s. Error: %s %s', params.service, status, error)
|
|
56
|
+
return params
|
|
36
57
|
}
|
|
37
|
-
return params
|
|
38
|
-
}
|
|
39
58
|
|
|
40
|
-
const generateParamsWithUpdatedDates = async (
|
|
59
|
+
const generateParamsWithUpdatedDates = async (
|
|
60
|
+
params,
|
|
61
|
+
dispatch,
|
|
62
|
+
ident,
|
|
63
|
+
updatedAfter,
|
|
64
|
+
updatedUntil,
|
|
65
|
+
afterDelta,
|
|
66
|
+
untilDelta,
|
|
67
|
+
metaKey
|
|
68
|
+
) => {
|
|
41
69
|
if (updatedAfter) {
|
|
42
70
|
return params.map((params) => ({
|
|
43
71
|
...params,
|
|
44
72
|
...generateUpdatedAfter(new Date(updatedAfter), afterDelta),
|
|
45
|
-
updatedUntil:
|
|
46
|
-
|
|
47
|
-
|
|
73
|
+
updatedUntil:
|
|
74
|
+
updatedUntil === 'open'
|
|
75
|
+
? undefined
|
|
76
|
+
: addDeltaToDate(
|
|
77
|
+
updatedUntil ? new Date(updatedUntil) : new Date(),
|
|
78
|
+
untilDelta
|
|
79
|
+
),
|
|
48
80
|
}))
|
|
49
81
|
} else {
|
|
50
82
|
return Promise.all(
|
|
51
|
-
params.map(
|
|
83
|
+
params.map(
|
|
84
|
+
setUpdatedParams(
|
|
85
|
+
dispatch,
|
|
86
|
+
updatedUntil === 'open',
|
|
87
|
+
afterDelta,
|
|
88
|
+
untilDelta,
|
|
89
|
+
metaKey,
|
|
90
|
+
ident
|
|
91
|
+
)
|
|
92
|
+
)
|
|
52
93
|
)
|
|
53
94
|
}
|
|
54
95
|
}
|
|
55
96
|
|
|
56
97
|
const paramsFromStringOrObject = (params) =>
|
|
57
|
-
|
|
98
|
+
typeof params === 'string' ? { service: params } : params
|
|
58
99
|
|
|
59
100
|
const generateFromParams = async (
|
|
60
|
-
{
|
|
101
|
+
{
|
|
102
|
+
retrieve,
|
|
103
|
+
from,
|
|
104
|
+
updatedAfter,
|
|
105
|
+
updatedUntil,
|
|
106
|
+
afterDelta,
|
|
107
|
+
untilDelta,
|
|
108
|
+
metaKey,
|
|
109
|
+
},
|
|
61
110
|
{ ident },
|
|
62
111
|
dispatch
|
|
63
112
|
) => {
|
|
64
113
|
const fromParams = [].concat(from).map(paramsFromStringOrObject)
|
|
65
114
|
if (retrieve === 'updated') {
|
|
66
|
-
return generateParamsWithUpdatedDates(
|
|
115
|
+
return generateParamsWithUpdatedDates(
|
|
116
|
+
fromParams,
|
|
117
|
+
dispatch,
|
|
118
|
+
ident,
|
|
119
|
+
updatedAfter,
|
|
120
|
+
updatedUntil,
|
|
121
|
+
afterDelta,
|
|
122
|
+
untilDelta,
|
|
123
|
+
metaKey
|
|
124
|
+
)
|
|
67
125
|
} else {
|
|
68
126
|
return fromParams
|
|
69
127
|
}
|
|
@@ -89,15 +147,15 @@ const generateTransformParams = ({ transform }, { service, type }) => {
|
|
|
89
147
|
const generateToParams = ({ to, type }, fromParams) => {
|
|
90
148
|
const { updatedAfter, updatedUntil } = fromParams[0]
|
|
91
149
|
return {
|
|
92
|
-
...(
|
|
150
|
+
...(typeof to === 'string' ? { service: to } : to),
|
|
93
151
|
type,
|
|
94
152
|
updatedAfter,
|
|
95
|
-
updatedUntil
|
|
153
|
+
updatedUntil,
|
|
96
154
|
}
|
|
97
155
|
}
|
|
98
156
|
|
|
99
157
|
const filterDataOnUpdatedDates = (data, updatedAfter, updatedUntil) =>
|
|
100
|
-
|
|
158
|
+
Array.isArray(data) && data.length > 0 && (updatedAfter || updatedUntil)
|
|
101
159
|
? data.filter(isWithinUpdateWindow(updatedAfter, updatedUntil))
|
|
102
160
|
: data
|
|
103
161
|
|
|
@@ -106,66 +164,124 @@ const isWithinUpdateWindow = (updatedAfter, updatedUntil) => (item) =>
|
|
|
106
164
|
(!updatedAfter || item.attributes.updatedAt > updatedAfter) &&
|
|
107
165
|
(!updatedUntil || item.attributes.updatedAt <= updatedUntil)
|
|
108
166
|
|
|
109
|
-
const getFromService =
|
|
167
|
+
const getFromService =
|
|
168
|
+
(dispatch, type, noFilter = false, { project, ident }) =>
|
|
110
169
|
async ({ action: fromAction = 'GET', ...fromParams }) => {
|
|
111
|
-
const response = await dispatch(
|
|
170
|
+
const response = await dispatch(
|
|
171
|
+
action(fromAction, { type, ...fromParams }, { project, ident })
|
|
172
|
+
)
|
|
112
173
|
if (response.status !== 'ok') {
|
|
113
|
-
return createError(
|
|
174
|
+
return createError(
|
|
175
|
+
`Could not get items from service '${fromParams.service}'. Reason: ${response.status} ${response.error}`
|
|
176
|
+
)
|
|
114
177
|
}
|
|
115
178
|
|
|
116
179
|
return {
|
|
117
180
|
status: 'ok',
|
|
118
|
-
data: noFilter
|
|
181
|
+
data: noFilter
|
|
182
|
+
? response.data
|
|
183
|
+
: filterDataOnUpdatedDates(
|
|
184
|
+
response.data,
|
|
185
|
+
fromParams.updatedAfter,
|
|
186
|
+
fromParams.updatedUntil
|
|
187
|
+
),
|
|
119
188
|
}
|
|
120
189
|
}
|
|
121
190
|
|
|
122
|
-
function isConfiguredWithMeta
|
|
191
|
+
function isConfiguredWithMeta(serviceId, getService) {
|
|
123
192
|
const service = getService(null, serviceId)
|
|
124
193
|
return !!(service && service.meta)
|
|
125
194
|
}
|
|
126
195
|
|
|
127
|
-
const createSetMetas = (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
196
|
+
const createSetMetas = (
|
|
197
|
+
fromParams,
|
|
198
|
+
lastSyncedAt,
|
|
199
|
+
metaKey,
|
|
200
|
+
ident,
|
|
201
|
+
dispatch,
|
|
202
|
+
getService
|
|
203
|
+
) =>
|
|
204
|
+
fromParams
|
|
205
|
+
.reduce(
|
|
206
|
+
(services, params) =>
|
|
207
|
+
params.service &&
|
|
208
|
+
!services.includes(params.service) &&
|
|
209
|
+
isConfiguredWithMeta(params.service, getService)
|
|
210
|
+
? [...services, params.service]
|
|
211
|
+
: services,
|
|
212
|
+
[]
|
|
213
|
+
)
|
|
214
|
+
.map((service) =>
|
|
215
|
+
dispatch(
|
|
216
|
+
action(
|
|
217
|
+
'SET_META',
|
|
218
|
+
{ service, metaKey, meta: { lastSyncedAt } },
|
|
219
|
+
{ ident }
|
|
220
|
+
)
|
|
221
|
+
)
|
|
133
222
|
)
|
|
134
|
-
? [...services, params.service] : services,
|
|
135
|
-
[])
|
|
136
|
-
.map((service) =>
|
|
137
|
-
dispatch(action('SET_META', { service, metaKey, meta: { lastSyncedAt } }, { ident })))
|
|
138
223
|
|
|
139
224
|
const createSetActions = (toAction, data, toParams, meta, useIndividualSet) =>
|
|
140
225
|
useIndividualSet
|
|
141
|
-
? data.map(item => action(toAction, { data: item, ...toParams }, meta))
|
|
226
|
+
? data.map((item) => action(toAction, { data: item, ...toParams }, meta))
|
|
142
227
|
: [action(toAction, { data, ...toParams }, meta)]
|
|
143
228
|
|
|
144
|
-
const createDoneAction = (
|
|
229
|
+
const createDoneAction = (
|
|
230
|
+
data,
|
|
231
|
+
{ action: type = 'SET', ...params },
|
|
232
|
+
{ ident, project }
|
|
233
|
+
) => ({
|
|
145
234
|
type,
|
|
146
235
|
payload: { ...params, data },
|
|
147
|
-
meta: { ident, project }
|
|
236
|
+
meta: { ident, project },
|
|
148
237
|
})
|
|
149
238
|
|
|
150
239
|
const isError = (response) =>
|
|
151
240
|
!['ok', 'queued', 'noaction'].includes(response.status)
|
|
152
241
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
242
|
+
function getLastSyncedAt(
|
|
243
|
+
fromParams,
|
|
244
|
+
data,
|
|
245
|
+
setLastSyncedAtFromData = false,
|
|
246
|
+
untilDelta = 0
|
|
247
|
+
) {
|
|
248
|
+
if (setLastSyncedAtFromData) {
|
|
249
|
+
return data
|
|
250
|
+
.map((item) => item.attributes.updatedAt)
|
|
251
|
+
.reduce((latest, date) => (latest > date ? latest : date))
|
|
252
|
+
} else if (fromParams[0]) {
|
|
253
|
+
const lastSyncedAt = fromParams
|
|
254
|
+
.map((param) => param.updatedUntil)
|
|
255
|
+
.sort((a, b) =>
|
|
256
|
+
a instanceof Date && b instanceof Date ? a.getTime() - b.getTime() : 0
|
|
257
|
+
)[0]
|
|
258
|
+
return addDeltaToDate(lastSyncedAt, untilDelta * -1) // Subtract delta to get the actual updatedUntil date
|
|
259
|
+
}
|
|
260
|
+
return undefined
|
|
261
|
+
}
|
|
262
|
+
async function transformData(
|
|
263
|
+
data,
|
|
264
|
+
dispatch,
|
|
265
|
+
transformParams,
|
|
266
|
+
meta,
|
|
267
|
+
useIndividualTransform
|
|
268
|
+
) {
|
|
159
269
|
if (useIndividualTransform) {
|
|
160
270
|
const responses = await Promise.all(
|
|
161
271
|
data
|
|
162
|
-
.map(item =>
|
|
163
|
-
|
|
272
|
+
.map((item) =>
|
|
273
|
+
dispatch(createTransformAction(transformParams, item, meta))
|
|
274
|
+
)
|
|
275
|
+
.map((p) => pLimit(1)(() => p))
|
|
276
|
+
)
|
|
277
|
+
return responses.flatMap((response, index) =>
|
|
278
|
+
response.status === 'ok' ? response.data : data[index]
|
|
164
279
|
)
|
|
165
|
-
return responses.flatMap((response, index) => response.status === 'ok' ? response.data : data[index])
|
|
166
280
|
} else {
|
|
167
|
-
const transformResponse = await dispatch(
|
|
168
|
-
|
|
281
|
+
const transformResponse = await dispatch(
|
|
282
|
+
createTransformAction(transformParams, data, meta)
|
|
283
|
+
)
|
|
284
|
+
return transformResponse.status === 'ok' ? transformResponse.data : data
|
|
169
285
|
}
|
|
170
286
|
}
|
|
171
287
|
|
|
@@ -186,36 +302,61 @@ async function transformData (data, dispatch, transformParams, meta, useIndividu
|
|
|
186
302
|
* @param {Object} resources - Dispatch function
|
|
187
303
|
* @returns {Promise} Promise of the action result
|
|
188
304
|
*/
|
|
189
|
-
async function sync
|
|
305
|
+
async function sync({ payload, meta = {} }, { dispatch, getService }) {
|
|
190
306
|
debug('Action: SYNC')
|
|
191
307
|
const fromParams = await generateFromParams(payload, meta, dispatch)
|
|
192
|
-
const { action: toAction = 'SET', ...toParams } = generateToParams(
|
|
308
|
+
const { action: toAction = 'SET', ...toParams } = generateToParams(
|
|
309
|
+
payload,
|
|
310
|
+
fromParams
|
|
311
|
+
)
|
|
193
312
|
const transformParams = generateTransformParams(payload, toParams)
|
|
194
313
|
const { queueSet = true, metaKey, useIndividualSet = false } = payload
|
|
195
314
|
const doneParams = generateDoneParams(payload)
|
|
196
315
|
|
|
197
316
|
const results = await Promise.all(
|
|
198
|
-
fromParams.map(
|
|
317
|
+
fromParams.map(
|
|
318
|
+
getFromService(dispatch, payload.type, payload.noFilter, meta)
|
|
319
|
+
)
|
|
199
320
|
)
|
|
200
321
|
|
|
201
322
|
if (results.some((result) => result.status !== 'ok')) {
|
|
202
|
-
return
|
|
323
|
+
return results.length === 1
|
|
324
|
+
? results[0]
|
|
325
|
+
: createError(makeErrorString(results))
|
|
203
326
|
}
|
|
204
327
|
|
|
205
328
|
let data = flatten(results.map((result) => result.data)).filter(Boolean)
|
|
206
329
|
|
|
207
330
|
if (data.length === 0 && payload.syncNoData !== true) {
|
|
208
|
-
return createError(
|
|
331
|
+
return createError(
|
|
332
|
+
`No items to update from service '${fromParams[0].service}'`,
|
|
333
|
+
'noaction'
|
|
334
|
+
)
|
|
209
335
|
}
|
|
210
336
|
|
|
211
|
-
const lastSyncedAt =
|
|
337
|
+
const lastSyncedAt =
|
|
338
|
+
getLastSyncedAt(
|
|
339
|
+
fromParams,
|
|
340
|
+
data,
|
|
341
|
+
payload.setLastSyncedAtFromData,
|
|
342
|
+
payload.untilDelta
|
|
343
|
+
) || new Date()
|
|
212
344
|
|
|
213
345
|
// Dispatch transform action
|
|
214
346
|
if (transformParams) {
|
|
215
|
-
data = await transformData(
|
|
347
|
+
data = await transformData(
|
|
348
|
+
data,
|
|
349
|
+
dispatch,
|
|
350
|
+
transformParams,
|
|
351
|
+
meta,
|
|
352
|
+
payload.useIndividualTransform
|
|
353
|
+
)
|
|
216
354
|
|
|
217
355
|
if (data.length === 0 && payload.syncNoData !== true) {
|
|
218
|
-
return createError(
|
|
356
|
+
return createError(
|
|
357
|
+
`No items to update from service '${fromParams[0].service}' after transform action`,
|
|
358
|
+
'noaction'
|
|
359
|
+
)
|
|
219
360
|
}
|
|
220
361
|
}
|
|
221
362
|
|
|
@@ -236,10 +377,11 @@ async function sync ({ payload, meta = {} }, { dispatch, getService }) {
|
|
|
236
377
|
)
|
|
237
378
|
|
|
238
379
|
// Dispatch set actions
|
|
239
|
-
const responses = await Promise.all(
|
|
240
|
-
...setMetaActions,
|
|
241
|
-
|
|
242
|
-
|
|
380
|
+
const responses = await Promise.all(
|
|
381
|
+
[...setMetaActions, ...setActions.map(dispatch)].map((p) =>
|
|
382
|
+
pLimit(1)(() => p)
|
|
383
|
+
)
|
|
384
|
+
)
|
|
243
385
|
|
|
244
386
|
// Get responses, excluding set meta actions
|
|
245
387
|
const setResponses = responses.slice(setMetaActions.length)
|
|
@@ -258,7 +400,9 @@ async function sync ({ payload, meta = {} }, { dispatch, getService }) {
|
|
|
258
400
|
return {
|
|
259
401
|
status: errors.length ? 'error' : 'ok',
|
|
260
402
|
data: setResponses,
|
|
261
|
-
...(errors.length
|
|
403
|
+
...(errors.length
|
|
404
|
+
? { error: `${errors.length} of ${setResponses.length} actions failed` }
|
|
405
|
+
: {}),
|
|
262
406
|
}
|
|
263
407
|
}
|
|
264
408
|
|
|
@@ -12,7 +12,7 @@ const optionsAuth = {
|
|
|
12
12
|
* @param {Object} options - An options object
|
|
13
13
|
* @returns {Object} An authentication object
|
|
14
14
|
*/
|
|
15
|
-
async authenticate
|
|
15
|
+
async authenticate(options) {
|
|
16
16
|
return { status: 'granted', ...options }
|
|
17
17
|
},
|
|
18
18
|
|
|
@@ -23,7 +23,7 @@ const optionsAuth = {
|
|
|
23
23
|
* @param {Object} authentication - The object returned from `authenticate()`
|
|
24
24
|
* @returns {boolean} `true` if already authenticated, otherwise `false`
|
|
25
25
|
*/
|
|
26
|
-
isAuthenticated
|
|
26
|
+
isAuthenticated(authentication) {
|
|
27
27
|
return !!(authentication && authentication.status === 'granted')
|
|
28
28
|
},
|
|
29
29
|
|
|
@@ -35,8 +35,8 @@ const optionsAuth = {
|
|
|
35
35
|
* @param {Object} authentication - The object returned from `authenticate()`
|
|
36
36
|
* @returns {Object} Auth object
|
|
37
37
|
*/
|
|
38
|
-
asObject
|
|
39
|
-
return
|
|
38
|
+
asObject({ status, ...options }) {
|
|
39
|
+
return status === 'granted' ? options : {}
|
|
40
40
|
},
|
|
41
41
|
|
|
42
42
|
/**
|
|
@@ -45,9 +45,9 @@ const optionsAuth = {
|
|
|
45
45
|
* @param {Object} authentication - The object returned from `authenticate()`
|
|
46
46
|
* @returns {Object} Headers object
|
|
47
47
|
*/
|
|
48
|
-
asHttpHeaders
|
|
49
|
-
return {}
|
|
50
|
-
}
|
|
48
|
+
asHttpHeaders({ status, ...options }) {
|
|
49
|
+
return status === 'granted' ? options : {}
|
|
50
|
+
},
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
module.exports = optionsAuth
|
package/lib/dispatch.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
const debug = require('debug')('great')
|
|
2
|
+
const PProgress = require('p-progress')
|
|
2
3
|
const setupGetService = require('./utils/getService')
|
|
3
4
|
|
|
4
|
-
const compose = (...fns) =>
|
|
5
|
+
const compose = (...fns) =>
|
|
6
|
+
fns.reduce(
|
|
7
|
+
(f, g) =>
|
|
8
|
+
(...args) =>
|
|
9
|
+
f(g(...args))
|
|
10
|
+
)
|
|
5
11
|
|
|
6
12
|
const handleAction = (action, resources, actionHandlers) => {
|
|
7
13
|
if (action) {
|
|
@@ -13,7 +19,7 @@ const handleAction = (action, resources, actionHandlers) => {
|
|
|
13
19
|
}
|
|
14
20
|
}
|
|
15
21
|
|
|
16
|
-
return { status: 'noaction' }
|
|
22
|
+
return PProgress.resolve({ status: 'noaction' })
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
/**
|
|
@@ -22,26 +28,44 @@ const handleAction = (action, resources, actionHandlers) => {
|
|
|
22
28
|
* @param {Object} resources - Object with actions, schemas, services, and middlewares
|
|
23
29
|
* @returns {function} Dispatch function, accepting an action as only argument
|
|
24
30
|
*/
|
|
25
|
-
function setupDispatch
|
|
31
|
+
function setupDispatch({
|
|
32
|
+
actions: actionHandlers = {},
|
|
33
|
+
schemas = {},
|
|
34
|
+
services = {},
|
|
35
|
+
middlewares = [],
|
|
36
|
+
identOptions = {},
|
|
37
|
+
}) {
|
|
26
38
|
const getService = setupGetService(schemas, services)
|
|
39
|
+
const middlewareFn =
|
|
40
|
+
middlewares.length > 0
|
|
41
|
+
? compose(...middlewares)
|
|
42
|
+
: (next) => async (action) => next(action)
|
|
27
43
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
action,
|
|
32
|
-
{
|
|
33
|
-
schemas,
|
|
34
|
-
services,
|
|
35
|
-
dispatch,
|
|
36
|
-
identOptions,
|
|
37
|
-
getService
|
|
38
|
-
},
|
|
39
|
-
actionHandlers
|
|
40
|
-
)
|
|
41
|
-
}
|
|
44
|
+
const dispatch = (action) => {
|
|
45
|
+
return new PProgress(async (resolve, reject, setProgress) => {
|
|
46
|
+
debug('Dispatch: %o', action)
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
try {
|
|
49
|
+
resolve(
|
|
50
|
+
middlewareFn((action) =>
|
|
51
|
+
handleAction(
|
|
52
|
+
action,
|
|
53
|
+
{
|
|
54
|
+
schemas,
|
|
55
|
+
services,
|
|
56
|
+
dispatch,
|
|
57
|
+
identOptions,
|
|
58
|
+
getService,
|
|
59
|
+
setProgress,
|
|
60
|
+
},
|
|
61
|
+
actionHandlers
|
|
62
|
+
)
|
|
63
|
+
)(action)
|
|
64
|
+
)
|
|
65
|
+
} catch (err) {
|
|
66
|
+
reject(err)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
45
69
|
}
|
|
46
70
|
|
|
47
71
|
return dispatch
|
package/lib/integreat.js
CHANGED
|
@@ -5,7 +5,7 @@ const setupMapping = require('./mapping')
|
|
|
5
5
|
const setupDispatch = require('./dispatch')
|
|
6
6
|
const builtinActions = require('./actions')
|
|
7
7
|
|
|
8
|
-
const version = '0.7.
|
|
8
|
+
const version = '0.7.37'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Return an Integreat instance with a dispatch method.
|
|
@@ -16,20 +16,20 @@ const version = '0.7.33'
|
|
|
16
16
|
* @param {Array} middlewares - Array of middlewares
|
|
17
17
|
* @returns {Object} Integration object with the dispatch method
|
|
18
18
|
*/
|
|
19
|
-
function integreat
|
|
19
|
+
function integreat(
|
|
20
20
|
{
|
|
21
21
|
schemas: typeDefs,
|
|
22
22
|
services: serviceDefs,
|
|
23
23
|
mappings = [],
|
|
24
24
|
auths: authDefs = [],
|
|
25
|
-
ident: identOptions = {}
|
|
25
|
+
ident: identOptions = {},
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
adapters = {},
|
|
29
29
|
authenticators = {},
|
|
30
30
|
filters = {},
|
|
31
31
|
transformers = {},
|
|
32
|
-
actions = {}
|
|
32
|
+
actions = {},
|
|
33
33
|
} = {},
|
|
34
34
|
middlewares = []
|
|
35
35
|
) {
|
|
@@ -41,38 +41,46 @@ function integreat (
|
|
|
41
41
|
actions = { ...builtinActions, ...actions }
|
|
42
42
|
|
|
43
43
|
// Setup schemas object from type defs
|
|
44
|
-
const schemas = R.compose(
|
|
45
|
-
R.indexBy(R.prop('id')),
|
|
46
|
-
R.map(schema)
|
|
47
|
-
)(typeDefs)
|
|
44
|
+
const schemas = R.compose(R.indexBy(R.prop('id')), R.map(schema))(typeDefs)
|
|
48
45
|
|
|
49
|
-
const pluralTypes = Object.keys(schemas)
|
|
50
|
-
|
|
46
|
+
const pluralTypes = Object.keys(schemas).reduce(
|
|
47
|
+
(plurals, type) => ({ ...plurals, [schemas[type].plural]: type }),
|
|
48
|
+
{}
|
|
49
|
+
)
|
|
51
50
|
|
|
52
51
|
// Setup auths object from auth defs
|
|
53
|
-
const auths = authDefs
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
const auths = authDefs.reduce(
|
|
53
|
+
(auths, def) =>
|
|
54
|
+
def
|
|
55
|
+
? {
|
|
56
|
+
...auths,
|
|
57
|
+
[def.id]: {
|
|
58
|
+
authenticator: authenticators[def && def.authenticator],
|
|
59
|
+
options: def.options,
|
|
60
|
+
authentication: null,
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
: auths,
|
|
64
|
+
{}
|
|
65
|
+
)
|
|
65
66
|
|
|
66
67
|
// Setup services object from service defs.
|
|
67
68
|
const services = R.compose(
|
|
68
69
|
R.indexBy(R.prop('id')),
|
|
69
|
-
R.map(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
R.map(
|
|
71
|
+
createService({
|
|
72
|
+
adapters,
|
|
73
|
+
auths,
|
|
74
|
+
transformers,
|
|
75
|
+
schemas,
|
|
76
|
+
setupMapping: setupMapping({
|
|
77
|
+
filters,
|
|
78
|
+
transformers,
|
|
79
|
+
schemas,
|
|
80
|
+
mappings,
|
|
81
|
+
}),
|
|
82
|
+
})
|
|
83
|
+
)
|
|
76
84
|
)(serviceDefs)
|
|
77
85
|
|
|
78
86
|
// Return Integreat instance
|
|
@@ -93,14 +101,14 @@ function integreat (
|
|
|
93
101
|
services,
|
|
94
102
|
schemas,
|
|
95
103
|
middlewares,
|
|
96
|
-
identOptions
|
|
104
|
+
identOptions,
|
|
97
105
|
}),
|
|
98
106
|
|
|
99
107
|
/**
|
|
100
108
|
* Adds the `listener` function to the service's emitter for events with the
|
|
101
109
|
* given `eventName` name.
|
|
102
110
|
*/
|
|
103
|
-
on
|
|
111
|
+
on(eventName, serviceId, listener) {
|
|
104
112
|
const service = services[serviceId]
|
|
105
113
|
if (service && service.on) {
|
|
106
114
|
service.on(eventName, listener)
|
|
@@ -110,9 +118,9 @@ function integreat (
|
|
|
110
118
|
/**
|
|
111
119
|
* Return schema type from its plural form.
|
|
112
120
|
*/
|
|
113
|
-
typeFromPlural
|
|
121
|
+
typeFromPlural(plural) {
|
|
114
122
|
return pluralTypes[plural]
|
|
115
|
-
}
|
|
123
|
+
},
|
|
116
124
|
}
|
|
117
125
|
}
|
|
118
126
|
|
package/lib/mapping/index.js
CHANGED
|
@@ -1,33 +1,60 @@
|
|
|
1
1
|
const { compose, map, mergeDeepWith } = require('ramda')
|
|
2
|
-
const {
|
|
2
|
+
const {
|
|
3
|
+
mapTransform,
|
|
4
|
+
transform,
|
|
5
|
+
filter,
|
|
6
|
+
set,
|
|
7
|
+
fwd,
|
|
8
|
+
rev,
|
|
9
|
+
functions,
|
|
10
|
+
} = require('map-transform')
|
|
3
11
|
const is = require('@sindresorhus/is')
|
|
4
|
-
const {
|
|
5
|
-
|
|
12
|
+
const {
|
|
13
|
+
preparePipeline,
|
|
14
|
+
prepareRevPipeline,
|
|
15
|
+
} = require('../utils/preparePipeline')
|
|
16
|
+
const { normalizeFieldMapping, pathToPipeline } = require('./normalize')
|
|
6
17
|
|
|
7
18
|
const { compare } = functions
|
|
8
19
|
|
|
9
20
|
const hasFieldMappings = (id, attributes, relationships) =>
|
|
10
|
-
id ||
|
|
21
|
+
id ||
|
|
22
|
+
Object.keys(attributes).length > 0 ||
|
|
23
|
+
Object.keys(relationships).length > 0
|
|
11
24
|
|
|
12
25
|
const prepareRelationship = (normalize, createPipeline) => (relationship) =>
|
|
13
|
-
|
|
26
|
+
relationship.mapping
|
|
27
|
+
? createPipeline(relationship.mapping, undefined, relationship.path)
|
|
28
|
+
.pipeline
|
|
29
|
+
: normalize(relationship)
|
|
14
30
|
|
|
15
|
-
function prepareMapping
|
|
31
|
+
function prepareMapping(
|
|
32
|
+
{
|
|
33
|
+
attributes: { id = null, type = null, ...attributes } = {},
|
|
34
|
+
relationships = {},
|
|
35
|
+
toService = {},
|
|
36
|
+
},
|
|
37
|
+
transformers,
|
|
38
|
+
createPipeline
|
|
39
|
+
) {
|
|
16
40
|
if (hasFieldMappings(id, attributes, relationships)) {
|
|
17
41
|
const normalize = normalizeFieldMapping(transformers)
|
|
18
42
|
return {
|
|
19
|
-
id:
|
|
20
|
-
type:
|
|
43
|
+
id: id ? normalize(id) : null,
|
|
44
|
+
type: type ? rev(type) : null,
|
|
21
45
|
attributes: map(normalize, attributes),
|
|
22
|
-
relationships: map(
|
|
23
|
-
|
|
46
|
+
relationships: map(
|
|
47
|
+
prepareRelationship(normalize, createPipeline),
|
|
48
|
+
relationships
|
|
49
|
+
),
|
|
50
|
+
...map(normalize, toService),
|
|
24
51
|
}
|
|
25
52
|
} else {
|
|
26
53
|
return {
|
|
27
54
|
id: 'id',
|
|
28
55
|
type: rev('type'),
|
|
29
56
|
attributes: 'attributes',
|
|
30
|
-
relationships: 'relationships'
|
|
57
|
+
relationships: 'relationships',
|
|
31
58
|
}
|
|
32
59
|
}
|
|
33
60
|
}
|
|
@@ -39,29 +66,38 @@ const createCompareFilter = ([path, value]) => {
|
|
|
39
66
|
return []
|
|
40
67
|
}
|
|
41
68
|
}
|
|
42
|
-
const prepareQualifier = (qualifier) =>
|
|
69
|
+
const prepareQualifier = (qualifier) =>
|
|
70
|
+
qualifier ? createCompareFilter(qualifier.split('=')) : []
|
|
43
71
|
|
|
44
|
-
const prepareTypeQualifier = ({ attributes = {}, relationships = {}, type }) =>
|
|
45
|
-
|
|
46
|
-
|
|
72
|
+
const prepareTypeQualifier = ({ attributes = {}, relationships = {}, type }) =>
|
|
73
|
+
is.emptyObject(attributes) && is.emptyObject(relationships)
|
|
74
|
+
? [filter(compare({ path: 'type', match: type }))]
|
|
75
|
+
: []
|
|
47
76
|
|
|
48
|
-
const concatOrRight = (left, right) =>
|
|
77
|
+
const concatOrRight = (left, right) =>
|
|
78
|
+
Array.isArray(left) ? left.concat(right) : right
|
|
49
79
|
|
|
50
|
-
const ensureArray = (data) => (Array.isArray(data)
|
|
80
|
+
const ensureArray = (data) => (Array.isArray(data) ? data : data ? [data] : [])
|
|
51
81
|
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
82
|
+
const joinPaths = (...paths) => paths.filter(Boolean).join('.')
|
|
83
|
+
|
|
84
|
+
const overrideMappingProps = (mapping, overrideType, prependPath) =>
|
|
85
|
+
mapping
|
|
86
|
+
? {
|
|
87
|
+
...mapping,
|
|
88
|
+
type: overrideType || mapping.type,
|
|
89
|
+
path: Array.isArray(prependPath)
|
|
90
|
+
? prependPath.map((path) => joinPaths(path, mapping.path))
|
|
91
|
+
: joinPaths(prependPath, mapping.path),
|
|
92
|
+
}
|
|
93
|
+
: undefined
|
|
59
94
|
|
|
60
|
-
const lookupMapping = (mapping, mappings) =>
|
|
95
|
+
const lookupMapping = (mapping, mappings) =>
|
|
96
|
+
mappings[mapping] ? { ...mappings[mapping], id: mapping } : null
|
|
61
97
|
|
|
62
98
|
const expandMapping = (mapping, mappings, overrideType, prependPath) =>
|
|
63
99
|
overrideMappingProps(
|
|
64
|
-
|
|
100
|
+
typeof mapping === 'string' ? lookupMapping(mapping, mappings) : mapping,
|
|
65
101
|
overrideType,
|
|
66
102
|
prependPath
|
|
67
103
|
)
|
|
@@ -87,7 +123,7 @@ const createPipelines = (mapping, transformers, filters) => {
|
|
|
87
123
|
transform: transformDef = null,
|
|
88
124
|
transformTo: transformToDef = null,
|
|
89
125
|
filterFrom = null,
|
|
90
|
-
filterTo = null
|
|
126
|
+
filterTo = null,
|
|
91
127
|
} = mapping
|
|
92
128
|
|
|
93
129
|
const transformPipeline = preparePipeline(transformDef, transformers)
|
|
@@ -100,15 +136,19 @@ const createPipelines = (mapping, transformers, filters) => {
|
|
|
100
136
|
transformers
|
|
101
137
|
).map(transformRev),
|
|
102
138
|
filterFrom: preparePipeline(filterFrom, filters).map(filterFwd),
|
|
103
|
-
filterTo: preparePipeline(filterTo, filters).map(filterRev)
|
|
139
|
+
filterTo: preparePipeline(filterTo, filters).map(filterRev),
|
|
104
140
|
}
|
|
105
141
|
}
|
|
106
142
|
|
|
107
|
-
const concatPipeline = (
|
|
143
|
+
const concatPipeline = (
|
|
144
|
+
mapping,
|
|
145
|
+
schema,
|
|
146
|
+
{ createPipelineFn, transformers, filters }
|
|
147
|
+
) => {
|
|
108
148
|
const pipelines = createPipelines(mapping, transformers, filters)
|
|
109
149
|
|
|
110
150
|
return [
|
|
111
|
-
mapping.path,
|
|
151
|
+
...pathToPipeline(mapping.path),
|
|
112
152
|
...prepareQualifier(mapping.qualifier),
|
|
113
153
|
...prepareTypeQualifier(mapping),
|
|
114
154
|
prepareMapping(mapping, transformers, createPipelineFn),
|
|
@@ -117,7 +157,7 @@ const concatPipeline = (mapping, schema, { createPipelineFn, transformers, filte
|
|
|
117
157
|
...pipelines.transformRev,
|
|
118
158
|
...pipelines.filterFrom,
|
|
119
159
|
...pipelines.filterTo,
|
|
120
|
-
filter(item => typeof item !== 'undefined')
|
|
160
|
+
filter((item) => typeof item !== 'undefined'),
|
|
121
161
|
]
|
|
122
162
|
}
|
|
123
163
|
|
|
@@ -133,7 +173,7 @@ const createPipeline = (filters, transformers, schemas, mappings) => {
|
|
|
133
173
|
const pipeline = concatPipeline(mapping, schema, {
|
|
134
174
|
createPipelineFn,
|
|
135
175
|
transformers,
|
|
136
|
-
filters
|
|
176
|
+
filters,
|
|
137
177
|
})
|
|
138
178
|
|
|
139
179
|
return { id, type, schema, pipeline }
|
|
@@ -147,29 +187,33 @@ const createPipeline = (filters, transformers, schemas, mappings) => {
|
|
|
147
187
|
* @param {Object} resources - filters, transformers, and schemas
|
|
148
188
|
* @returns {Object} Item mapping def
|
|
149
189
|
*/
|
|
150
|
-
function mapping
|
|
190
|
+
function mapping({
|
|
151
191
|
filters,
|
|
152
192
|
transformers,
|
|
153
193
|
schemas = {},
|
|
154
|
-
mappings: mappingsArr = []
|
|
194
|
+
mappings: mappingsArr = [],
|
|
155
195
|
} = {}) {
|
|
156
196
|
const mappings = mappingsArr.reduce(
|
|
157
197
|
(mappings, def) => ({ ...mappings, [def.id]: def }),
|
|
158
198
|
{}
|
|
159
199
|
)
|
|
160
|
-
const createPipelineFn = createPipeline(
|
|
200
|
+
const createPipelineFn = createPipeline(
|
|
201
|
+
filters,
|
|
202
|
+
transformers,
|
|
203
|
+
schemas,
|
|
204
|
+
mappings
|
|
205
|
+
)
|
|
161
206
|
|
|
162
207
|
return (mapping, overrideType) => {
|
|
163
|
-
const { id, type, schema, pipeline } = createPipelineFn(
|
|
208
|
+
const { id, type, schema, pipeline } = createPipelineFn(
|
|
209
|
+
mapping,
|
|
210
|
+
overrideType
|
|
211
|
+
)
|
|
164
212
|
if (!pipeline) {
|
|
165
213
|
return null
|
|
166
214
|
}
|
|
167
215
|
|
|
168
|
-
const mapper = mapTransform([
|
|
169
|
-
fwd('data'),
|
|
170
|
-
...pipeline,
|
|
171
|
-
rev(set('data'))
|
|
172
|
-
])
|
|
216
|
+
const mapper = mapTransform([fwd('data'), ...pipeline, rev(set('data'))])
|
|
173
217
|
|
|
174
218
|
return {
|
|
175
219
|
id,
|
|
@@ -182,11 +226,11 @@ function mapping ({
|
|
|
182
226
|
* @param {Object} options - onlyMappedValues
|
|
183
227
|
* @returns {Object} Target item
|
|
184
228
|
*/
|
|
185
|
-
fromService
|
|
229
|
+
fromService(data, { onlyMappedValues = true } = {}) {
|
|
186
230
|
return data
|
|
187
231
|
? ensureArray(
|
|
188
|
-
|
|
189
|
-
|
|
232
|
+
onlyMappedValues ? mapper.onlyMappedValues(data) : mapper(data)
|
|
233
|
+
)
|
|
190
234
|
: []
|
|
191
235
|
},
|
|
192
236
|
|
|
@@ -196,7 +240,7 @@ function mapping ({
|
|
|
196
240
|
* @param {Object} target - Optional object to map to data on
|
|
197
241
|
* @returns {Object} Mapped data
|
|
198
242
|
*/
|
|
199
|
-
toService
|
|
243
|
+
toService(data, target = null) {
|
|
200
244
|
const mapped = mapper.rev.onlyMappedValues(data)
|
|
201
245
|
return (
|
|
202
246
|
(target
|
|
@@ -205,7 +249,7 @@ function mapping ({
|
|
|
205
249
|
: mergeDeepWith(concatOrRight, target, mapped)
|
|
206
250
|
: mapped) || null
|
|
207
251
|
)
|
|
208
|
-
}
|
|
252
|
+
},
|
|
209
253
|
}
|
|
210
254
|
}
|
|
211
255
|
}
|
package/lib/mapping/normalize.js
CHANGED
|
@@ -1,45 +1,66 @@
|
|
|
1
1
|
const { compose, map } = require('ramda')
|
|
2
2
|
const is = require('@sindresorhus/is')
|
|
3
3
|
const { transform, fwd, rev, value, fixed, set, alt } = require('map-transform')
|
|
4
|
-
const {
|
|
4
|
+
const {
|
|
5
|
+
preparePipeline,
|
|
6
|
+
prepareRevPipeline,
|
|
7
|
+
} = require('../utils/preparePipeline')
|
|
5
8
|
|
|
6
9
|
const pathPipelineSetAlts = ([primary, ...alts]) => [
|
|
7
10
|
primary,
|
|
8
|
-
...alts.map(compose(fwd, alt))
|
|
11
|
+
...alts.map(compose(fwd, alt)),
|
|
9
12
|
]
|
|
10
13
|
|
|
11
|
-
const pathToPipeline = (path) =>
|
|
12
|
-
? pathPipelineSetAlts(path)
|
|
13
|
-
: [path]
|
|
14
|
+
const pathToPipeline = (path) =>
|
|
15
|
+
is.array(path) ? pathPipelineSetAlts(path) : [path]
|
|
14
16
|
|
|
15
17
|
const createSubMapping = (sub, transformers, switchTransforms) =>
|
|
16
|
-
|
|
18
|
+
switchTransforms && typeof sub === 'string'
|
|
17
19
|
? set(sub)
|
|
18
20
|
: normalizeFieldMapping(transformers, switchTransforms)(sub)
|
|
19
21
|
|
|
20
|
-
const createFieldPipeline = (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
const createFieldPipeline = (
|
|
23
|
+
{
|
|
24
|
+
path,
|
|
25
|
+
transform: transformDef = [],
|
|
26
|
+
transformTo: transformToDef = null,
|
|
27
|
+
default: defValue,
|
|
28
|
+
const: constValue,
|
|
29
|
+
sub,
|
|
30
|
+
},
|
|
31
|
+
transformers,
|
|
32
|
+
switchTransforms
|
|
33
|
+
) => {
|
|
28
34
|
const transformPipeline = preparePipeline(transformDef, transformers)
|
|
29
|
-
const revTransformPipeline = prepareRevPipeline(
|
|
35
|
+
const revTransformPipeline = prepareRevPipeline(
|
|
36
|
+
transformToDef,
|
|
37
|
+
transformPipeline,
|
|
38
|
+
transformers
|
|
39
|
+
)
|
|
30
40
|
return [
|
|
31
41
|
...pathToPipeline(path),
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
(
|
|
42
|
+
typeof constValue !== 'undefined' ? fixed(constValue) : null,
|
|
43
|
+
typeof defValue !== 'undefined' ? alt(value(defValue)) : null,
|
|
44
|
+
sub && switchTransforms
|
|
45
|
+
? createSubMapping(sub, transformers, switchTransforms)
|
|
46
|
+
: null,
|
|
47
|
+
...(switchTransforms ? revTransformPipeline : transformPipeline).map(
|
|
48
|
+
compose(fwd, transform)
|
|
49
|
+
),
|
|
50
|
+
...(switchTransforms ? transformPipeline : revTransformPipeline).map(
|
|
51
|
+
compose(rev, transform)
|
|
52
|
+
),
|
|
53
|
+
sub && !switchTransforms
|
|
54
|
+
? createSubMapping(sub, transformers, switchTransforms)
|
|
55
|
+
: null,
|
|
38
56
|
].filter(Boolean)
|
|
39
57
|
}
|
|
40
|
-
const normalizeFieldMapping =
|
|
41
|
-
|
|
42
|
-
|
|
58
|
+
const normalizeFieldMapping =
|
|
59
|
+
(transformers = {}, switchTransforms = false) =>
|
|
60
|
+
(def) =>
|
|
61
|
+
is.string(def) || is.array(def)
|
|
62
|
+
? pathToPipeline(def)
|
|
63
|
+
: createFieldPipeline(def, transformers, switchTransforms)
|
|
43
64
|
|
|
44
65
|
const normalizeMapping = (mapping, transformers = {}) =>
|
|
45
66
|
map(normalizeFieldMapping(transformers), mapping)
|
|
@@ -50,5 +71,6 @@ const normalizeMappingWithSwitchedTransforms = (mapping, transformers = {}) =>
|
|
|
50
71
|
module.exports = {
|
|
51
72
|
normalizeMapping,
|
|
52
73
|
normalizeFieldMapping,
|
|
53
|
-
normalizeMappingWithSwitchedTransforms
|
|
74
|
+
normalizeMappingWithSwitchedTransforms,
|
|
75
|
+
pathToPipeline,
|
|
54
76
|
}
|
package/lib/queue/enqueue.js
CHANGED
|
@@ -3,30 +3,41 @@ const createError = require('../utils/createError')
|
|
|
3
3
|
|
|
4
4
|
const prepareMetaForQueue = ({ queue, ...rest }) => ({
|
|
5
5
|
...rest,
|
|
6
|
-
queuedAt: Date.now()
|
|
6
|
+
queuedAt: Date.now(),
|
|
7
7
|
})
|
|
8
8
|
|
|
9
9
|
const prepareForQueue = (action) => ({
|
|
10
10
|
...action,
|
|
11
|
-
meta: prepareMetaForQueue(action.meta)
|
|
11
|
+
meta: prepareMetaForQueue(action.meta),
|
|
12
12
|
})
|
|
13
13
|
|
|
14
14
|
const enqueue = async (queue, action) => {
|
|
15
15
|
const { meta } = action
|
|
16
16
|
const queuedAction = prepareForQueue(action)
|
|
17
|
-
const timestamp =
|
|
17
|
+
const timestamp = typeof meta.queue === 'boolean' ? null : meta.queue
|
|
18
18
|
const actionId = meta.id || null
|
|
19
19
|
|
|
20
20
|
let id
|
|
21
21
|
try {
|
|
22
22
|
id = await queue.push(queuedAction, timestamp, actionId)
|
|
23
23
|
} catch (error) {
|
|
24
|
-
debug(
|
|
24
|
+
debug(
|
|
25
|
+
'Error from queue when pushing %o with timestamp %s. Error: %s',
|
|
26
|
+
queuedAction,
|
|
27
|
+
timestamp,
|
|
28
|
+
error
|
|
29
|
+
)
|
|
25
30
|
return createError(`Could not push to queue. ${error}`)
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
debug(
|
|
29
|
-
|
|
33
|
+
debug(
|
|
34
|
+
"Pushed to queue with timestamp %s and id '%s': %o",
|
|
35
|
+
timestamp,
|
|
36
|
+
id,
|
|
37
|
+
queuedAction
|
|
38
|
+
)
|
|
39
|
+
const queuedStatus = action.meta.queuedStatus || 'queued'
|
|
40
|
+
return { status: queuedStatus, data: { id } }
|
|
30
41
|
}
|
|
31
42
|
|
|
32
43
|
module.exports = enqueue
|
package/lib/queue/middleware.js
CHANGED
|
@@ -17,12 +17,15 @@ const enqueueNext = (queue, action) => {
|
|
|
17
17
|
const nextTime = getNextTime(action)
|
|
18
18
|
|
|
19
19
|
if (nextTime) {
|
|
20
|
-
const nextAction = {
|
|
20
|
+
const nextAction = {
|
|
21
|
+
...action,
|
|
22
|
+
meta: { ...action.meta, queue: nextTime.getTime() },
|
|
23
|
+
}
|
|
21
24
|
return enqueue(queue, nextAction)
|
|
22
25
|
}
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
function middleware
|
|
28
|
+
function middleware(next, queue) {
|
|
26
29
|
return async (action) => {
|
|
27
30
|
if (action.meta && action.meta.queue) {
|
|
28
31
|
return enqueue(queue, action)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "integreat",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.37",
|
|
4
4
|
"description": "Node.js integration layer",
|
|
5
5
|
"author": "Kjell-Morten Bratsberg Thorsen <post@kjellmorten.no> (http://kjellmorten.no/)",
|
|
6
6
|
"license": "ISC",
|
|
@@ -13,12 +13,11 @@
|
|
|
13
13
|
"main": "index.js",
|
|
14
14
|
"types": "index.d.ts",
|
|
15
15
|
"scripts": {
|
|
16
|
-
"test": "
|
|
16
|
+
"test": "NODE_ENV=test nyc --reporter=text-summary ava",
|
|
17
17
|
"test:inspect": "node --inspect node_modules/ava/profile.js",
|
|
18
18
|
"dev": "NODE_ENV=test ava --watch",
|
|
19
19
|
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
|
20
|
-
"nyc:report": "nyc report --reporter=text --reporter=html"
|
|
21
|
-
"lint": "standard"
|
|
20
|
+
"nyc:report": "nyc report --reporter=text --reporter=html"
|
|
22
21
|
},
|
|
23
22
|
"ava": {
|
|
24
23
|
"babel": true,
|
|
@@ -47,24 +46,25 @@
|
|
|
47
46
|
},
|
|
48
47
|
"dependencies": {
|
|
49
48
|
"@sindresorhus/is": "^1.2.0",
|
|
50
|
-
"debug": "^4.3.
|
|
49
|
+
"debug": "^4.3.3",
|
|
51
50
|
"got": "^9.6.0",
|
|
52
51
|
"later": "^1.2.0",
|
|
53
52
|
"map-any": "^0.2.1",
|
|
54
|
-
"map-transform": "^0.3.
|
|
53
|
+
"map-transform": "^0.3.12",
|
|
55
54
|
"p-limit": "^2.3.0",
|
|
55
|
+
"p-progress": "^0.5.1",
|
|
56
56
|
"ramda": "^0.27.1",
|
|
57
57
|
"uuid": "^3.4.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@ava/babel": "^
|
|
61
|
-
"ava": "3.
|
|
62
|
-
"coveralls": "^3.1.
|
|
63
|
-
"dotenv": "^
|
|
60
|
+
"@ava/babel": "^2.0.0",
|
|
61
|
+
"ava": "3.15.0",
|
|
62
|
+
"coveralls": "^3.1.1",
|
|
63
|
+
"dotenv": "^10.0.0",
|
|
64
64
|
"integreat-adapter-json": "^0.2.1",
|
|
65
|
-
"nock": "^
|
|
65
|
+
"nock": "^13.2.1",
|
|
66
66
|
"nyc": "^15.1.0",
|
|
67
|
-
"
|
|
68
|
-
"
|
|
67
|
+
"prettier": "^2.5.1",
|
|
68
|
+
"sinon": "^11.1.2"
|
|
69
69
|
}
|
|
70
70
|
}
|