@modernpoacher/halacious 7.0.3 → 7.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -17
- package/package.json +11 -4
- package/src/index.d.mts +205 -20
- package/src/plugin.mjs +765 -671
- package/src/representation.mjs +251 -137
- package/src/representationFactory.mjs +60 -0
- package/src/utils/getFieldValueByPath.mjs +20 -0
- package/src/utils/getMediaType.mjs +15 -0
- package/src/utils/getTemplateContext.mjs +32 -0
- package/src/utils.mjs +382 -0
- package/views/namespaces.jade +11 -0
- package/views/rel.jade +7 -0
- package/index.d.mts +0 -7
package/src/representation.mjs
CHANGED
|
@@ -1,48 +1,123 @@
|
|
|
1
|
-
import _ from 'lodash'
|
|
2
1
|
import * as hoek from '@hapi/hoek'
|
|
3
2
|
import URI from 'urijs'
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
getSelf,
|
|
6
|
+
getHref,
|
|
7
|
+
getPrefix
|
|
8
|
+
} from './utils.mjs'
|
|
9
|
+
|
|
10
|
+
const TEMPLATE = /{*}/
|
|
6
11
|
|
|
7
12
|
/**
|
|
8
13
|
* A HAL wrapper interface around an entity. Provides an api for adding new links and recursively embedding child
|
|
9
14
|
* entities.
|
|
10
15
|
*
|
|
11
16
|
* @param factory
|
|
12
|
-
* @param self
|
|
13
17
|
* @param entity
|
|
18
|
+
* @param self
|
|
14
19
|
* @param root
|
|
15
20
|
* @constructor
|
|
16
21
|
*/
|
|
17
22
|
export class Representation {
|
|
18
|
-
constructor (factory,
|
|
19
|
-
|
|
23
|
+
constructor (factory, entity, link, root = this) {
|
|
24
|
+
const {
|
|
25
|
+
_halacious: halacious,
|
|
26
|
+
_request: request
|
|
27
|
+
} = factory
|
|
28
|
+
|
|
29
|
+
const {
|
|
30
|
+
href
|
|
31
|
+
} = link
|
|
32
|
+
|
|
33
|
+
const links = {
|
|
34
|
+
self: link
|
|
35
|
+
}
|
|
36
|
+
|
|
20
37
|
this.factory = factory
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
38
|
+
this.entity = entity
|
|
39
|
+
this.self = href
|
|
40
|
+
this._root = root
|
|
41
|
+
this._halacious = halacious
|
|
42
|
+
this._request = request
|
|
43
|
+
this._links = links
|
|
25
44
|
this._embedded = {}
|
|
26
45
|
this._namespaces = {}
|
|
27
|
-
this._props =
|
|
28
|
-
this._ignore =
|
|
29
|
-
|
|
46
|
+
this._props = new Map()
|
|
47
|
+
this._ignore = new Set()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
getHalacious () {
|
|
51
|
+
return this._halacious
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
getRequest () {
|
|
55
|
+
return this._request
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
getRoot () {
|
|
59
|
+
return this._root
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getLinks () {
|
|
63
|
+
return this._links
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
getEmbedded () {
|
|
67
|
+
return this._embedded
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
getNamespaces () {
|
|
71
|
+
return this._namespaces
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getProps () {
|
|
75
|
+
return this._props
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getIgnore () {
|
|
79
|
+
return this._ignore
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
get halacious () {
|
|
83
|
+
return this._halacious
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get request () {
|
|
87
|
+
return this._request
|
|
30
88
|
}
|
|
31
89
|
|
|
32
90
|
/**
|
|
33
91
|
* Adds a namespace to the 'curie' link collection. all curies in a response, top level or nested, should be declared
|
|
34
92
|
* in the top level _links collection. a reference '_root' is kept to the top level representation for this purpose
|
|
93
|
+
*
|
|
35
94
|
* @param namespace
|
|
36
95
|
*/
|
|
37
96
|
curie (namespace) {
|
|
38
|
-
if (namespace
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
97
|
+
if (namespace) {
|
|
98
|
+
const root = this.getRoot()
|
|
99
|
+
|
|
100
|
+
const namespaces = root.getNamespaces()
|
|
101
|
+
|
|
102
|
+
const prefix = getPrefix(namespace)
|
|
103
|
+
|
|
104
|
+
if (Reflect.has(namespaces, prefix)) return
|
|
105
|
+
|
|
106
|
+
Reflect.set(namespaces, prefix, namespace)
|
|
107
|
+
|
|
108
|
+
const links = root.getLinks()
|
|
109
|
+
|
|
110
|
+
const curies = Reflect.get(links, 'curies') ?? []
|
|
111
|
+
|
|
112
|
+
const request = this.getRequest()
|
|
113
|
+
|
|
114
|
+
const namespaceUrl = this.getHalacious().namespaceUrl(request, namespace)
|
|
115
|
+
|
|
116
|
+
Reflect.set(links, 'curies', curies.concat({
|
|
117
|
+
name: prefix,
|
|
118
|
+
href: `${namespaceUrl}/{rel}`,
|
|
44
119
|
templated: true
|
|
45
|
-
})
|
|
120
|
+
}))
|
|
46
121
|
}
|
|
47
122
|
}
|
|
48
123
|
|
|
@@ -53,121 +128,169 @@ export class Representation {
|
|
|
53
128
|
* @return {Representation}
|
|
54
129
|
*/
|
|
55
130
|
prop (name, value) {
|
|
56
|
-
this.
|
|
131
|
+
this.getProps()
|
|
132
|
+
.set(name, value)
|
|
133
|
+
|
|
57
134
|
return this
|
|
58
135
|
}
|
|
59
136
|
|
|
60
137
|
/**
|
|
61
|
-
* Merges an object's properties into the custom properties collection
|
|
138
|
+
* Merges an object's properties into the custom properties collection
|
|
139
|
+
*
|
|
62
140
|
* @param prop
|
|
63
141
|
*/
|
|
64
142
|
merge (prop) {
|
|
65
|
-
|
|
143
|
+
const props = this.getProps()
|
|
144
|
+
|
|
145
|
+
Object
|
|
146
|
+
.entries(prop)
|
|
147
|
+
.forEach(([name, value]) => {
|
|
148
|
+
props.set(name, value)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
return this
|
|
66
152
|
}
|
|
67
153
|
|
|
68
154
|
/**
|
|
69
155
|
* @param {...String || String[]} args properties to ignore
|
|
70
156
|
* @return {Representation}
|
|
71
157
|
*/
|
|
72
|
-
ignore (...args) {
|
|
73
|
-
const props =
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
158
|
+
ignore (arg, ...args) {
|
|
159
|
+
const props = (
|
|
160
|
+
Array.isArray(arg)
|
|
161
|
+
? arg
|
|
162
|
+
: [arg].concat(args)
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
const ignore = this.getIgnore()
|
|
166
|
+
|
|
167
|
+
props
|
|
168
|
+
.filter(Boolean)
|
|
169
|
+
.forEach((prop) => {
|
|
170
|
+
ignore.add(prop)
|
|
171
|
+
})
|
|
172
|
+
|
|
77
173
|
return this
|
|
78
174
|
}
|
|
79
175
|
|
|
80
176
|
/**
|
|
81
|
-
* Prepares the representation for JSON serialization
|
|
177
|
+
* Prepares the representation for JSON serialization
|
|
178
|
+
*
|
|
82
179
|
* @return {{}}
|
|
83
180
|
*/
|
|
84
181
|
toJSON () {
|
|
85
|
-
// initialize the
|
|
86
|
-
const
|
|
87
|
-
const self = this
|
|
182
|
+
// initialize the entity
|
|
183
|
+
const object = { _links: this.getLinks() }
|
|
88
184
|
|
|
89
185
|
// copy all target properties in the entity using JSON.stringify(). if the entity has a .toJSON() implementation,
|
|
90
186
|
// it will be called. properties on the ignore list will not be copied
|
|
91
|
-
const {
|
|
187
|
+
const {
|
|
188
|
+
entity
|
|
189
|
+
} = this
|
|
190
|
+
|
|
191
|
+
const ignore = this.getIgnore()
|
|
192
|
+
|
|
92
193
|
JSON.stringify(entity, (key, value) => {
|
|
93
|
-
if (!key)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (!self._ignore[key]) {
|
|
97
|
-
payload[key] = value
|
|
98
|
-
}
|
|
194
|
+
if (!key) return value
|
|
195
|
+
|
|
196
|
+
if (!ignore.has(key)) Reflect.set(object, key, value)
|
|
99
197
|
})
|
|
100
198
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
199
|
+
const embedded = this.getEmbedded()
|
|
200
|
+
|
|
201
|
+
const entries = Object.entries(embedded)
|
|
202
|
+
if (entries.length) {
|
|
203
|
+
object._embedded = (
|
|
204
|
+
entries
|
|
205
|
+
.reduce((accumulator, [entryKey, entryValue]) => {
|
|
206
|
+
let currentValue
|
|
207
|
+
|
|
208
|
+
if (entryValue instanceof Representation) {
|
|
209
|
+
currentValue = {}
|
|
210
|
+
} else {
|
|
211
|
+
if (Array.isArray(entryValue)) {
|
|
212
|
+
currentValue = []
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
JSON.stringify(entryValue, (key, value) => {
|
|
217
|
+
if (!key) return value
|
|
218
|
+
|
|
219
|
+
if (!ignore.has(key)) Reflect.set(currentValue, key, value)
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
return (
|
|
223
|
+
Object.assign(accumulator, { [entryKey]: currentValue })
|
|
224
|
+
)
|
|
225
|
+
}, {})
|
|
226
|
+
)
|
|
124
227
|
}
|
|
125
228
|
|
|
126
|
-
|
|
229
|
+
const props = this.getProps()
|
|
230
|
+
|
|
231
|
+
// merge in any extra properties
|
|
232
|
+
return (
|
|
233
|
+
Object.assign(object, Object.fromEntries(Array.from(props.entries()).filter(([key]) => !ignore.has(key))))
|
|
234
|
+
)
|
|
127
235
|
}
|
|
128
236
|
|
|
129
237
|
/**
|
|
130
238
|
* Creates a new link and adds it to the _links collection
|
|
239
|
+
*
|
|
131
240
|
* @param rel
|
|
132
241
|
* @param link
|
|
133
242
|
* @return {{} || []} the new link
|
|
134
243
|
*/
|
|
135
|
-
link (
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
244
|
+
link (relName, link) {
|
|
245
|
+
const halacious = this.getHalacious()
|
|
246
|
+
|
|
247
|
+
const rel = halacious.rel(relName)
|
|
248
|
+
const key = rel.qname()
|
|
249
|
+
|
|
250
|
+
const links = this.getLinks()
|
|
251
|
+
|
|
252
|
+
if (Array.isArray(link)) {
|
|
253
|
+
if (!Reflect.has(links, key)) Reflect.set(links, key, [])
|
|
254
|
+
|
|
255
|
+
return (
|
|
256
|
+
link.map((href) => this.link(relName, href))
|
|
257
|
+
)
|
|
143
258
|
}
|
|
144
259
|
|
|
145
260
|
// adds the namespace to the top level curie list
|
|
146
261
|
this.curie(rel.namespace)
|
|
147
262
|
|
|
148
|
-
|
|
149
|
-
|
|
263
|
+
const href = getHref(getSelf(links)) ?? ''
|
|
264
|
+
|
|
265
|
+
link = halacious.link(link, href)
|
|
266
|
+
|
|
267
|
+
if (TEMPLATE.test(link.href)) link.templated = true
|
|
268
|
+
|
|
150
269
|
// e.g. 'mco:rel'
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
270
|
+
|
|
271
|
+
Reflect.set(links, key, (
|
|
272
|
+
Reflect.has(links, key)
|
|
273
|
+
? [].concat(Reflect.get(links, key), link)
|
|
274
|
+
: link
|
|
275
|
+
))
|
|
158
276
|
|
|
159
277
|
return link
|
|
160
278
|
}
|
|
161
279
|
|
|
162
280
|
/**
|
|
163
281
|
* Resolves a relative path against the representation's self href
|
|
282
|
+
*
|
|
164
283
|
* @param relativePath
|
|
165
284
|
* @return {*}
|
|
166
285
|
*/
|
|
167
286
|
resolve (relativePath) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
287
|
+
const href = getHref(getSelf(this.getLinks())) ?? ''
|
|
288
|
+
|
|
289
|
+
return (
|
|
290
|
+
new URI(relativePath)
|
|
291
|
+
.absoluteTo(href.concat('/'))
|
|
292
|
+
.toString()
|
|
293
|
+
)
|
|
171
294
|
}
|
|
172
295
|
|
|
173
296
|
/**
|
|
@@ -178,7 +301,9 @@ export class Representation {
|
|
|
178
301
|
* @return {*}
|
|
179
302
|
*/
|
|
180
303
|
route (routeName, params) {
|
|
181
|
-
return
|
|
304
|
+
return (
|
|
305
|
+
this.getHalacious().route(routeName, params)
|
|
306
|
+
)
|
|
182
307
|
}
|
|
183
308
|
|
|
184
309
|
/**
|
|
@@ -188,45 +313,62 @@ export class Representation {
|
|
|
188
313
|
* @param {{} || []} entity an object to wrap
|
|
189
314
|
* @return {entity || []}
|
|
190
315
|
*/
|
|
191
|
-
embed (
|
|
192
|
-
const
|
|
193
|
-
|
|
316
|
+
embed (relName, self, entity) {
|
|
317
|
+
const halacious = this.getHalacious()
|
|
318
|
+
|
|
319
|
+
const rel = halacious.rel(relName)
|
|
320
|
+
const key = rel.qname()
|
|
194
321
|
|
|
195
322
|
this.curie(rel.namespace)
|
|
196
323
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
324
|
+
const embedded = this.getEmbedded()
|
|
325
|
+
|
|
326
|
+
if (Array.isArray(entity)) {
|
|
327
|
+
if (!Reflect.has(embedded, key)) Reflect.set(embedded, key, [])
|
|
328
|
+
|
|
329
|
+
return (
|
|
330
|
+
entity.map((entity) => this.embed(relName, self, entity))
|
|
331
|
+
)
|
|
201
332
|
}
|
|
202
333
|
|
|
203
|
-
|
|
334
|
+
const href = getHref(getSelf(this.getLinks())) ?? ''
|
|
204
335
|
|
|
205
|
-
|
|
336
|
+
self = halacious.link(self, href)
|
|
206
337
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
338
|
+
const root = this.getRoot()
|
|
339
|
+
|
|
340
|
+
const embed = this.factory.create(entity, self, root)
|
|
341
|
+
|
|
342
|
+
Reflect.set(embedded, key, (
|
|
343
|
+
Reflect.has(embedded, key)
|
|
344
|
+
? [].concat(Reflect.get(embedded, key), embed)
|
|
345
|
+
: embed
|
|
346
|
+
))
|
|
214
347
|
|
|
215
|
-
return
|
|
348
|
+
return embed
|
|
216
349
|
}
|
|
217
350
|
|
|
218
351
|
/**
|
|
219
|
-
* Convenience method for embedding an array of entities
|
|
352
|
+
* Convenience method for embedding an entity or array of entities
|
|
353
|
+
*
|
|
220
354
|
* @param rel
|
|
221
355
|
* @param self
|
|
222
|
-
* @param
|
|
356
|
+
* @param arg
|
|
223
357
|
* @return {Representation}
|
|
224
358
|
*/
|
|
225
|
-
embedCollection (rel, self,
|
|
226
|
-
entities =
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
359
|
+
embedCollection (rel, self, arg, ...args) {
|
|
360
|
+
const entities = (
|
|
361
|
+
Array.isArray(arg)
|
|
362
|
+
? arg
|
|
363
|
+
: [arg].concat(args)
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
entities
|
|
367
|
+
.filter(Boolean)
|
|
368
|
+
.forEach((entity) => {
|
|
369
|
+
this.embed(rel, hoek.clone(self), entity)
|
|
370
|
+
})
|
|
371
|
+
|
|
230
372
|
return this
|
|
231
373
|
}
|
|
232
374
|
|
|
@@ -236,36 +378,8 @@ export class Representation {
|
|
|
236
378
|
* @param callback
|
|
237
379
|
*/
|
|
238
380
|
configure (config, callback) {
|
|
239
|
-
this.
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Responsible for creating all hal entities, top level or embedded, needed for a hapi request
|
|
245
|
-
* @param halacious a reference to the plugin api
|
|
246
|
-
* @param request a hapi request object
|
|
247
|
-
* @constructor
|
|
248
|
-
*/
|
|
249
|
-
export class RepresentationFactory {
|
|
250
|
-
constructor (halacious, request) {
|
|
251
|
-
this._halacious = halacious
|
|
252
|
-
this._request = request
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Creates a new hal representation out of a javascript object
|
|
257
|
-
* @param {{}=} entity the entity to wrap with a representation. an empty object is created by default
|
|
258
|
-
* @param {String || {}=} self the self href or link object. The request's path is used by default
|
|
259
|
-
* @param {Representation} root a pointer to the top level representation for adding curied links
|
|
260
|
-
* should be expanded into absolute urls
|
|
261
|
-
* @return {Representation}
|
|
262
|
-
*/
|
|
263
|
-
create (entity, self, root) {
|
|
264
|
-
entity = entity || {}
|
|
265
|
-
self = self || (this._request && this._request.path)
|
|
266
|
-
self = this._halacious.link(self)
|
|
267
|
-
return new Representation(this, self, entity, root)
|
|
381
|
+
this.getHalacious().configureRepresentation(config, this, callback)
|
|
268
382
|
}
|
|
269
383
|
}
|
|
270
384
|
|
|
271
|
-
export default
|
|
385
|
+
export default Representation
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import Representation from './representation.mjs'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Responsible for creating all hal entities, top level or embedded, needed for a Hapi request
|
|
5
|
+
*
|
|
6
|
+
* @param halacious a reference to the plugin api
|
|
7
|
+
* @param request a hapi request object
|
|
8
|
+
* @constructor
|
|
9
|
+
*/
|
|
10
|
+
export class RepresentationFactory {
|
|
11
|
+
constructor (halacious, request) {
|
|
12
|
+
this._halacious = halacious
|
|
13
|
+
this._request = request
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
getHalacious () {
|
|
17
|
+
return this._halacious
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getRequest () {
|
|
21
|
+
return this._request
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getRequestPath () {
|
|
25
|
+
console.log(this.getRequest()?.path)
|
|
26
|
+
return this.getRequest()?.path
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get halacious () {
|
|
30
|
+
return this._halacious
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get request () {
|
|
34
|
+
return this._request
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
get requestPath () {
|
|
38
|
+
return this.request?.path
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a new hal representation out of a javascript object
|
|
43
|
+
* @param {{}=} entity the entity to wrap with a representation. an empty object is created by default
|
|
44
|
+
* @param {String || {}=} self the self href or link object. The request's path is used by default
|
|
45
|
+
* @param {Representation} root a pointer to the top level representation for adding curied links
|
|
46
|
+
* should be expanded into absolute urls
|
|
47
|
+
* @return {Representation}
|
|
48
|
+
*/
|
|
49
|
+
create (entity = {}, self = this.getRequestPath(), root) {
|
|
50
|
+
const halacious = this.getHalacious()
|
|
51
|
+
|
|
52
|
+
const link = halacious.link(self)
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
new Representation(this, entity, link, root)
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default RepresentationFactory
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function reduce (accumulator, fieldName) {
|
|
2
|
+
return (
|
|
3
|
+
Reflect.has(accumulator, fieldName)
|
|
4
|
+
? Reflect.get(accumulator, fieldName)
|
|
5
|
+
: accumulator
|
|
6
|
+
)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Previously `reach`
|
|
11
|
+
*/
|
|
12
|
+
export default function getFieldValueByPath (path = '', context = {}) {
|
|
13
|
+
const fieldNames = String(path ?? '').split('.')
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
fieldNames
|
|
17
|
+
.filter(Boolean)
|
|
18
|
+
.reduce(reduce, context)
|
|
19
|
+
)
|
|
20
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Negotiator from 'negotiator'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Selects the media type based on the request's Accept header and a ranked ordering of configured
|
|
5
|
+
* media types
|
|
6
|
+
*
|
|
7
|
+
* @param request
|
|
8
|
+
* @param mediaTypes
|
|
9
|
+
* @return {*}
|
|
10
|
+
*/
|
|
11
|
+
export default function getMediaType (request, mediaTypes) {
|
|
12
|
+
return (
|
|
13
|
+
new Negotiator(request).mediaType([].concat(mediaTypes))
|
|
14
|
+
)
|
|
15
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import getFieldValueByPath from './getFieldValueByPath.mjs'
|
|
2
|
+
|
|
3
|
+
const REG = /{([^{}]+)}|([^{}]+)/g
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Evaluates and flattens deep expressions (e.g. '/{foo.a.b}') into a single level context object: {'foo.a.b': value}
|
|
7
|
+
* so that it may be used by url-template library
|
|
8
|
+
*
|
|
9
|
+
* @param template
|
|
10
|
+
* @param context
|
|
11
|
+
* @return {{}}
|
|
12
|
+
*/
|
|
13
|
+
export default function getTemplateContext (template, context) {
|
|
14
|
+
const templateContext = {}
|
|
15
|
+
let matches
|
|
16
|
+
|
|
17
|
+
while ((matches = REG.exec(template))) {
|
|
18
|
+
if (Array.isArray(matches)) {
|
|
19
|
+
const [
|
|
20
|
+
, // input,
|
|
21
|
+
path
|
|
22
|
+
] = matches
|
|
23
|
+
|
|
24
|
+
if (path) {
|
|
25
|
+
const fieldValue = getFieldValueByPath(path, context)
|
|
26
|
+
if (fieldValue) Reflect.set(templateContext, path, fieldValue.toString())
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return templateContext
|
|
32
|
+
}
|