integreat 0.7.34 → 0.7.38
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/index.d.ts +45 -40
- 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/lib/service/mapFromService.js +44 -22
- package/package.json +10 -9
package/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export as namespace integreat
|
|
2
2
|
export = integreat
|
|
3
3
|
|
|
4
|
-
declare function integreat
|
|
4
|
+
declare function integreat(
|
|
5
5
|
defs: integreat.Definitions,
|
|
6
6
|
resources: integreat.Resources,
|
|
7
7
|
middlewares?: integreat.Middleware[]
|
|
@@ -20,58 +20,63 @@ declare namespace integreat {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export interface Ident {
|
|
23
|
-
id?: string
|
|
23
|
+
id?: string
|
|
24
24
|
root?: boolean
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export interface Meta {
|
|
28
|
-
queue?: boolean
|
|
29
|
-
ident?: Ident
|
|
28
|
+
queue?: boolean
|
|
29
|
+
ident?: Ident
|
|
30
30
|
[key: string]: unknown
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export interface Action<P = Payload> {
|
|
34
|
-
type: string
|
|
35
|
-
payload: P
|
|
34
|
+
type: string
|
|
35
|
+
payload: P
|
|
36
36
|
meta?: Meta
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export type ActionHandlerResources = {
|
|
40
40
|
dispatch: Dispatch
|
|
41
|
+
setProgress: (progress: number) => void
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
export interface Instance {
|
|
44
|
-
version: string
|
|
45
|
-
schemas: object
|
|
46
|
-
services: object
|
|
47
|
-
identType: string
|
|
45
|
+
version: string
|
|
46
|
+
schemas: object
|
|
47
|
+
services: object
|
|
48
|
+
identType: string
|
|
48
49
|
|
|
49
|
-
dispatch: Dispatch
|
|
50
|
-
on: (
|
|
50
|
+
dispatch: Dispatch
|
|
51
|
+
on: (
|
|
52
|
+
eventName: string,
|
|
53
|
+
serviceId: string,
|
|
54
|
+
listener: (request: Request, response: Response) => void
|
|
55
|
+
) => void
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
export interface IdentDefinitions {
|
|
54
59
|
type: string
|
|
55
60
|
props?: {
|
|
56
|
-
id?: string
|
|
57
|
-
roles?: string
|
|
61
|
+
id?: string
|
|
62
|
+
roles?: string
|
|
58
63
|
tokens?: string
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
export interface Definitions {
|
|
63
|
-
schemas: object[]
|
|
64
|
-
services: object[]
|
|
65
|
-
mappings: object[]
|
|
66
|
-
auths?: object[]
|
|
68
|
+
schemas: object[]
|
|
69
|
+
services: object[]
|
|
70
|
+
mappings: object[]
|
|
71
|
+
auths?: object[]
|
|
67
72
|
ident?: IdentDefinitions
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
export interface Resources {
|
|
71
|
-
adapters: any
|
|
72
|
-
authenticators?: any
|
|
73
|
-
transformers?: any
|
|
74
|
-
filters?: any
|
|
76
|
+
adapters: any
|
|
77
|
+
authenticators?: any
|
|
78
|
+
transformers?: any
|
|
79
|
+
filters?: any
|
|
75
80
|
actions?: any
|
|
76
81
|
}
|
|
77
82
|
|
|
@@ -80,9 +85,9 @@ declare namespace integreat {
|
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
export interface Queue {
|
|
83
|
-
queue: object
|
|
84
|
-
setDispatch: (dispatch: Dispatch) => Promise<void
|
|
85
|
-
middleware: Middleware
|
|
88
|
+
queue: object
|
|
89
|
+
setDispatch: (dispatch: Dispatch) => Promise<void>
|
|
90
|
+
middleware: Middleware
|
|
86
91
|
schedule: (schedule: object) => Promise<Response>
|
|
87
92
|
}
|
|
88
93
|
|
|
@@ -97,10 +102,10 @@ declare namespace integreat {
|
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
type Relationship = {
|
|
100
|
-
id: string | null | undefined
|
|
101
|
-
type: string
|
|
102
|
-
attributes?: Attributes
|
|
103
|
-
relationships?: Relationships
|
|
105
|
+
id: string | null | undefined
|
|
106
|
+
type: string
|
|
107
|
+
attributes?: Attributes
|
|
108
|
+
relationships?: Relationships
|
|
104
109
|
meta?: object
|
|
105
110
|
}
|
|
106
111
|
|
|
@@ -109,30 +114,30 @@ declare namespace integreat {
|
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
export type Data = {
|
|
112
|
-
id: string | null | undefined
|
|
113
|
-
type: string
|
|
114
|
-
attributes: Attributes
|
|
117
|
+
id: string | null | undefined
|
|
118
|
+
type: string
|
|
119
|
+
attributes: Attributes
|
|
115
120
|
relationships: Relationships
|
|
116
121
|
}
|
|
117
122
|
|
|
118
123
|
interface Request<T = Data[] | Data | null> {
|
|
119
|
-
action: string
|
|
124
|
+
action: string
|
|
120
125
|
params?: {
|
|
121
126
|
[param: string]: any
|
|
122
|
-
}
|
|
127
|
+
}
|
|
123
128
|
endpoint?: {
|
|
124
129
|
[option: string]: any
|
|
125
130
|
}
|
|
126
|
-
data: T
|
|
127
|
-
auth?: object | boolean
|
|
131
|
+
data: T
|
|
132
|
+
auth?: object | boolean
|
|
128
133
|
access?: { ident: Ident }
|
|
129
134
|
}
|
|
130
135
|
|
|
131
136
|
interface Response<T = Data[]> {
|
|
132
|
-
status: string
|
|
133
|
-
data?: T
|
|
134
|
-
error?: string
|
|
135
|
-
responses?: Response[]
|
|
137
|
+
status: string
|
|
138
|
+
data?: T
|
|
139
|
+
error?: string
|
|
140
|
+
responses?: Response[]
|
|
136
141
|
access?: object
|
|
137
142
|
}
|
|
138
143
|
}
|
|
@@ -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.38'
|
|
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)
|
|
@@ -5,13 +5,19 @@ const mergeWithParams = (response, params) => ({
|
|
|
5
5
|
...response,
|
|
6
6
|
params: {
|
|
7
7
|
...params,
|
|
8
|
-
...response.params
|
|
9
|
-
}
|
|
8
|
+
...response.params,
|
|
9
|
+
},
|
|
10
10
|
})
|
|
11
11
|
|
|
12
12
|
const mapWithEndpoint = (responseMapper, response, params, actionType) => {
|
|
13
|
-
if (
|
|
14
|
-
|
|
13
|
+
if (
|
|
14
|
+
responseMapper ||
|
|
15
|
+
actionType.startsWith('GET') ||
|
|
16
|
+
actionType === 'REQUEST'
|
|
17
|
+
) {
|
|
18
|
+
return responseMapper
|
|
19
|
+
? responseMapper(mergeWithParams(response, params)) || {}
|
|
20
|
+
: response
|
|
15
21
|
} else {
|
|
16
22
|
return {}
|
|
17
23
|
}
|
|
@@ -25,8 +31,14 @@ const mapWithEndpoint = (responseMapper, response, params, actionType) => {
|
|
|
25
31
|
* @param {Object} options - mappings, params, onlyMappedValues, and endpoint
|
|
26
32
|
* @returns {Object[]} Array of mapped items
|
|
27
33
|
*/
|
|
28
|
-
function mapFromService
|
|
29
|
-
return ({
|
|
34
|
+
function mapFromService() {
|
|
35
|
+
return ({
|
|
36
|
+
response,
|
|
37
|
+
request,
|
|
38
|
+
responseMapper,
|
|
39
|
+
mappings,
|
|
40
|
+
mapResponseWithType = true,
|
|
41
|
+
}) => {
|
|
30
42
|
const type = request.params.type || Object.keys(mappings)
|
|
31
43
|
const { onlyMappedValues, unmapped = false } = request.params
|
|
32
44
|
|
|
@@ -34,28 +46,38 @@ function mapFromService () {
|
|
|
34
46
|
return response
|
|
35
47
|
}
|
|
36
48
|
|
|
37
|
-
const {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
const { data, status, error, paging, params } = mapWithEndpoint(
|
|
50
|
+
responseMapper,
|
|
51
|
+
response,
|
|
52
|
+
request.params,
|
|
53
|
+
request.action
|
|
54
|
+
)
|
|
55
|
+
|
|
44
56
|
const responseError = [response.error, error].filter(Boolean).join(' | ')
|
|
57
|
+
const responseStatus =
|
|
58
|
+
response.status !== 'ok'
|
|
59
|
+
? response.status
|
|
60
|
+
: status || (responseError ? 'error' : 'ok')
|
|
45
61
|
|
|
46
62
|
const ret = {
|
|
47
63
|
...response,
|
|
48
|
-
status:
|
|
49
|
-
...(
|
|
50
|
-
...(
|
|
51
|
-
...(
|
|
52
|
-
...(
|
|
64
|
+
status: responseStatus,
|
|
65
|
+
...(responseError ? { error: responseError } : {}),
|
|
66
|
+
...(paging ? { paging } : {}),
|
|
67
|
+
...(params ? { params } : {}),
|
|
68
|
+
...(responseStatus === 'ok' || data
|
|
69
|
+
? { data: data === null ? undefined : data }
|
|
70
|
+
: {}),
|
|
53
71
|
}
|
|
54
72
|
|
|
55
|
-
if (status === 'ok' && data && mapResponseWithType) {
|
|
56
|
-
const mapType = (type) =>
|
|
57
|
-
|
|
58
|
-
|
|
73
|
+
if (ret.status === 'ok' && data && mapResponseWithType) {
|
|
74
|
+
const mapType = (type) =>
|
|
75
|
+
mappings[type]
|
|
76
|
+
? mappings[type].fromService(
|
|
77
|
+
{ ...request, data },
|
|
78
|
+
{ onlyMappedValues }
|
|
79
|
+
)
|
|
80
|
+
: []
|
|
59
81
|
ret.data = flatten(mapAny(mapType, type))
|
|
60
82
|
}
|
|
61
83
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "integreat",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.38",
|
|
4
4
|
"description": "Node.js integration layer",
|
|
5
5
|
"author": "Kjell-Morten Bratsberg Thorsen <post@kjellmorten.no> (http://kjellmorten.no/)",
|
|
6
6
|
"license": "ISC",
|
|
@@ -46,24 +46,25 @@
|
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@sindresorhus/is": "^1.2.0",
|
|
49
|
-
"debug": "^4.3.
|
|
49
|
+
"debug": "^4.3.3",
|
|
50
50
|
"got": "^9.6.0",
|
|
51
51
|
"later": "^1.2.0",
|
|
52
52
|
"map-any": "^0.2.1",
|
|
53
53
|
"map-transform": "^0.3.12",
|
|
54
54
|
"p-limit": "^2.3.0",
|
|
55
|
+
"p-progress": "^0.5.1",
|
|
55
56
|
"ramda": "^0.27.1",
|
|
56
57
|
"uuid": "^3.4.0"
|
|
57
58
|
},
|
|
58
59
|
"devDependencies": {
|
|
59
|
-
"@ava/babel": "^
|
|
60
|
-
"ava": "3.
|
|
61
|
-
"coveralls": "^3.1.
|
|
62
|
-
"dotenv": "^
|
|
60
|
+
"@ava/babel": "^2.0.0",
|
|
61
|
+
"ava": "3.15.0",
|
|
62
|
+
"coveralls": "^3.1.1",
|
|
63
|
+
"dotenv": "^10.0.0",
|
|
63
64
|
"integreat-adapter-json": "^0.2.1",
|
|
64
|
-
"nock": "^
|
|
65
|
+
"nock": "^13.2.1",
|
|
65
66
|
"nyc": "^15.1.0",
|
|
66
|
-
"prettier": "^2.
|
|
67
|
-
"sinon": "^
|
|
67
|
+
"prettier": "^2.5.1",
|
|
68
|
+
"sinon": "^11.1.2"
|
|
68
69
|
}
|
|
69
70
|
}
|