@shakerquiz/utilities 0.2.34 → 0.2.36
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/package.json +1 -1
- package/source/enumerations/features.js +113 -48
- package/source/functions/fetch.js +88 -150
- package/source/functions/{origins.js → origin.js} +18 -2
- package/source/index.d.ts +1 -1
- package/source/index.js +1 -1
package/package.json
CHANGED
|
@@ -77,61 +77,19 @@ export var FeatureKinds = {
|
|
|
77
77
|
export var FeaturePathnames = /** @type {const} */ ({
|
|
78
78
|
[Features.Checkin]: '/checkin',
|
|
79
79
|
[Features.Cities]: '/cities',
|
|
80
|
-
[Features.City]:
|
|
81
|
-
[Features.Game]:
|
|
80
|
+
[Features.City]: `/city/:city?`,
|
|
81
|
+
[Features.Game]: `/game/:game?`,
|
|
82
82
|
[Features.Games]: '/games',
|
|
83
|
-
[Features.Location]:
|
|
83
|
+
[Features.Location]: `/location/:location?`,
|
|
84
84
|
[Features.Locations]: '/locations',
|
|
85
|
-
[Features.Registration]:
|
|
85
|
+
[Features.Registration]: `/registration/:registration?`,
|
|
86
86
|
[Features.Registrations]: '/registrations',
|
|
87
|
-
[Features.Theme]:
|
|
87
|
+
[Features.Theme]: `/theme/:theme?`,
|
|
88
88
|
[Features.Themes]: '/themes',
|
|
89
|
-
[Features.User]:
|
|
89
|
+
[Features.User]: `/user/:user?`,
|
|
90
90
|
[Features.Users]: '/users',
|
|
91
91
|
})
|
|
92
92
|
|
|
93
|
-
export var FeaturePatterns = {
|
|
94
|
-
[Features.Checkin]: new URLPattern({
|
|
95
|
-
pathname: FeaturePathnames[Features.Checkin],
|
|
96
|
-
}),
|
|
97
|
-
[Features.Cities]: new URLPattern({
|
|
98
|
-
pathname: FeaturePathnames[Features.Cities],
|
|
99
|
-
}),
|
|
100
|
-
[Features.City]: new URLPattern({
|
|
101
|
-
pathname: FeaturePathnames[Features.City],
|
|
102
|
-
}),
|
|
103
|
-
[Features.Game]: new URLPattern({
|
|
104
|
-
pathname: FeaturePathnames[Features.Game],
|
|
105
|
-
}),
|
|
106
|
-
[Features.Games]: new URLPattern({
|
|
107
|
-
pathname: FeaturePathnames[Features.Games],
|
|
108
|
-
}),
|
|
109
|
-
[Features.Location]: new URLPattern({
|
|
110
|
-
pathname: FeaturePathnames[Features.Location],
|
|
111
|
-
}),
|
|
112
|
-
[Features.Locations]: new URLPattern({
|
|
113
|
-
pathname: FeaturePathnames[Features.Locations],
|
|
114
|
-
}),
|
|
115
|
-
[Features.Registration]: new URLPattern({
|
|
116
|
-
pathname: FeaturePathnames[Features.Registration],
|
|
117
|
-
}),
|
|
118
|
-
[Features.Registrations]: new URLPattern({
|
|
119
|
-
pathname: FeaturePathnames[Features.Registrations],
|
|
120
|
-
}),
|
|
121
|
-
[Features.Theme]: new URLPattern({
|
|
122
|
-
pathname: FeaturePathnames[Features.Theme],
|
|
123
|
-
}),
|
|
124
|
-
[Features.Themes]: new URLPattern({
|
|
125
|
-
pathname: FeaturePathnames[Features.Themes],
|
|
126
|
-
}),
|
|
127
|
-
[Features.User]: new URLPattern({
|
|
128
|
-
pathname: FeaturePathnames[Features.User],
|
|
129
|
-
}),
|
|
130
|
-
[Features.Users]: new URLPattern({
|
|
131
|
-
pathname: FeaturePathnames[Features.Users],
|
|
132
|
-
}),
|
|
133
|
-
}
|
|
134
|
-
|
|
135
93
|
export var FeatureMethodRequirements = {
|
|
136
94
|
[Features.Checkin]: {
|
|
137
95
|
[Methods.DELETE]: new Set([]),
|
|
@@ -345,3 +303,110 @@ export var FeatureNetworkOrigins = new Map([
|
|
|
345
303
|
]),
|
|
346
304
|
],
|
|
347
305
|
])
|
|
306
|
+
|
|
307
|
+
export var FeatureNetworkUrls = new Map([
|
|
308
|
+
[
|
|
309
|
+
Features.Checkin,
|
|
310
|
+
new Map([
|
|
311
|
+
[Networks.Docker, null],
|
|
312
|
+
[Networks.Local, null],
|
|
313
|
+
[Networks.Public, null],
|
|
314
|
+
]),
|
|
315
|
+
],
|
|
316
|
+
[
|
|
317
|
+
Features.Cities,
|
|
318
|
+
new Map([
|
|
319
|
+
[Networks.Docker, null],
|
|
320
|
+
[Networks.Local, null],
|
|
321
|
+
[Networks.Public, null],
|
|
322
|
+
]),
|
|
323
|
+
],
|
|
324
|
+
[
|
|
325
|
+
Features.City,
|
|
326
|
+
new Map([
|
|
327
|
+
[Networks.Docker, null],
|
|
328
|
+
[Networks.Local, null],
|
|
329
|
+
[Networks.Public, null],
|
|
330
|
+
]),
|
|
331
|
+
],
|
|
332
|
+
[
|
|
333
|
+
Features.Game,
|
|
334
|
+
new Map([
|
|
335
|
+
[Networks.Docker, null],
|
|
336
|
+
[Networks.Local, null],
|
|
337
|
+
[Networks.Public, null],
|
|
338
|
+
]),
|
|
339
|
+
],
|
|
340
|
+
[
|
|
341
|
+
Features.Games,
|
|
342
|
+
new Map([
|
|
343
|
+
[Networks.Docker, null],
|
|
344
|
+
[Networks.Local, null],
|
|
345
|
+
[Networks.Public, null],
|
|
346
|
+
]),
|
|
347
|
+
],
|
|
348
|
+
[
|
|
349
|
+
Features.Location,
|
|
350
|
+
new Map([
|
|
351
|
+
[Networks.Docker, null],
|
|
352
|
+
[Networks.Local, null],
|
|
353
|
+
[Networks.Public, null],
|
|
354
|
+
]),
|
|
355
|
+
],
|
|
356
|
+
[
|
|
357
|
+
Features.Locations,
|
|
358
|
+
new Map([
|
|
359
|
+
[Networks.Docker, null],
|
|
360
|
+
[Networks.Local, null],
|
|
361
|
+
[Networks.Public, null],
|
|
362
|
+
]),
|
|
363
|
+
],
|
|
364
|
+
[
|
|
365
|
+
Features.Registration,
|
|
366
|
+
new Map([
|
|
367
|
+
[Networks.Docker, null],
|
|
368
|
+
[Networks.Local, null],
|
|
369
|
+
[Networks.Public, null],
|
|
370
|
+
]),
|
|
371
|
+
],
|
|
372
|
+
[
|
|
373
|
+
Features.Registrations,
|
|
374
|
+
new Map([
|
|
375
|
+
[Networks.Docker, null],
|
|
376
|
+
[Networks.Local, null],
|
|
377
|
+
[Networks.Public, null],
|
|
378
|
+
]),
|
|
379
|
+
],
|
|
380
|
+
[
|
|
381
|
+
Features.Theme,
|
|
382
|
+
new Map([
|
|
383
|
+
[Networks.Docker, null],
|
|
384
|
+
[Networks.Local, null],
|
|
385
|
+
[Networks.Public, null],
|
|
386
|
+
]),
|
|
387
|
+
],
|
|
388
|
+
[
|
|
389
|
+
Features.Themes,
|
|
390
|
+
new Map([
|
|
391
|
+
[Networks.Docker, null],
|
|
392
|
+
[Networks.Local, null],
|
|
393
|
+
[Networks.Public, null],
|
|
394
|
+
]),
|
|
395
|
+
],
|
|
396
|
+
[
|
|
397
|
+
Features.User,
|
|
398
|
+
new Map([
|
|
399
|
+
[Networks.Docker, null],
|
|
400
|
+
[Networks.Local, null],
|
|
401
|
+
[Networks.Public, null],
|
|
402
|
+
]),
|
|
403
|
+
],
|
|
404
|
+
[
|
|
405
|
+
Features.Users,
|
|
406
|
+
new Map([
|
|
407
|
+
[Networks.Docker, null],
|
|
408
|
+
[Networks.Local, null],
|
|
409
|
+
[Networks.Public, null],
|
|
410
|
+
]),
|
|
411
|
+
],
|
|
412
|
+
])
|
|
@@ -2,12 +2,11 @@ import * as cookies from '@yurkimus/cookies'
|
|
|
2
2
|
import { MessageError } from '@yurkimus/errors'
|
|
3
3
|
import * as message from '@yurkimus/message'
|
|
4
4
|
import { ResponseStatus } from '@yurkimus/response-status'
|
|
5
|
-
import { url } from '@yurkimus/url'
|
|
6
5
|
|
|
7
6
|
import { Cookies } from '../enumerations/cookies.js'
|
|
8
7
|
import {
|
|
9
8
|
FeatureKinds,
|
|
10
|
-
|
|
9
|
+
FeatureNetworkUrls,
|
|
11
10
|
FeaturePathnames,
|
|
12
11
|
Features,
|
|
13
12
|
} from '../enumerations/features.js'
|
|
@@ -16,7 +15,20 @@ import { Methods } from '../enumerations/methods.js'
|
|
|
16
15
|
import { Networks } from '../enumerations/networks.js'
|
|
17
16
|
import { Roles } from '../enumerations/roles.js'
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {'onbefore' | 'onfulfilled' | 'onrejected'} ExtensionHooks
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {WeakMap<Function, Map<ExtensionHooks, Set<Function>>>} Extensions
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @type {Extensions}
|
|
28
|
+
*/
|
|
29
|
+
export var extensions = new WeakMap()
|
|
30
|
+
|
|
31
|
+
var handleMessage = (feature, [response, body]) => {
|
|
20
32
|
switch (response.status) {
|
|
21
33
|
case 200:
|
|
22
34
|
case 201:
|
|
@@ -41,177 +53,103 @@ let handleMessage = (feature, [response, body]) => {
|
|
|
41
53
|
|
|
42
54
|
/**
|
|
43
55
|
* @template {keyof typeof Features} Feature
|
|
44
|
-
* @template {keyof typeof Methods} Method
|
|
45
56
|
* @template {keyof typeof Networks} Network
|
|
46
57
|
*
|
|
47
58
|
* @param {Feature} feature
|
|
48
|
-
* @param {Method} method
|
|
49
59
|
* @param {Network} network
|
|
50
|
-
* @param {import('@yurkimus/url').URLOptions | undefined} options
|
|
51
|
-
* @param {RequestInit} init
|
|
52
60
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
instance.headers.set(
|
|
68
|
-
'Content-Type',
|
|
69
|
-
'application/json',
|
|
70
|
-
)
|
|
61
|
+
export var useFetch = (feature, network) =>
|
|
62
|
+
/**
|
|
63
|
+
* @template {keyof typeof Roles} Role
|
|
64
|
+
*
|
|
65
|
+
* @param {import('@yurkimus/url').URLOptions | undefined} options
|
|
66
|
+
* @param {RequestInit} init
|
|
67
|
+
*
|
|
68
|
+
* @returns {Promise<FetchResults[Feature][Method][Role]>}
|
|
69
|
+
*/
|
|
70
|
+
function fetcher(options, init) {
|
|
71
|
+
if (!(feature in Features))
|
|
72
|
+
throw TypeError(
|
|
73
|
+
`Feature '${feature}' must be listed in 'Features'.`,
|
|
74
|
+
)
|
|
71
75
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
)
|
|
76
|
+
if (!(init.method in Methods))
|
|
77
|
+
throw TypeError(
|
|
78
|
+
`Method '${init.method}' must be listed in 'Methods'.`,
|
|
79
|
+
)
|
|
77
80
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
feature,
|
|
83
|
-
))
|
|
84
|
-
}
|
|
81
|
+
if (!(network in Networks))
|
|
82
|
+
throw TypeError(
|
|
83
|
+
`Network '${network}' must be listed in 'Networks'.`,
|
|
84
|
+
)
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
if (!(feature in FeaturePathnames))
|
|
87
|
+
throw TypeError(
|
|
88
|
+
`Feature '${feature}' must be listed in 'FeaturePathnames'.`,
|
|
89
|
+
)
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
*
|
|
96
|
-
* @param {Feature} feature
|
|
97
|
-
* @param {Method} method
|
|
98
|
-
* @param {Network} network
|
|
99
|
-
*/
|
|
100
|
-
export let useFetch = (feature, method, network) => {
|
|
101
|
-
if (!(feature in Features))
|
|
102
|
-
throw TypeError(
|
|
103
|
-
`Feature '${feature}' must be listed in 'Features'.`,
|
|
104
|
-
)
|
|
91
|
+
if (!FeatureNetworkUrls.has(feature))
|
|
92
|
+
throw TypeError(
|
|
93
|
+
`Feature '${feature}' must be listed in 'FeatureNetworkUrls'.`,
|
|
94
|
+
)
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
96
|
+
if (!FeatureNetworkUrls.get(feature).has(network))
|
|
97
|
+
throw TypeError(
|
|
98
|
+
`Feature's '${feature}' Network '${network}' must be listed in 'FeatureNetworkUrls'.`,
|
|
99
|
+
)
|
|
110
100
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
101
|
+
if (!FeatureNetworkUrls.get(feature).get(network))
|
|
102
|
+
throw TypeError(
|
|
103
|
+
`Feature's '${feature}' Network '${network}' in 'FeatureNetworkUrls' must have a value.`,
|
|
104
|
+
)
|
|
115
105
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
106
|
+
extensions.set(
|
|
107
|
+
fetcher,
|
|
108
|
+
new Map([
|
|
109
|
+
['onbefore', new Set([])],
|
|
110
|
+
['onfulfilled', new Set([])],
|
|
111
|
+
['onrejected', new Set([])],
|
|
112
|
+
]),
|
|
119
113
|
)
|
|
120
114
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
115
|
+
var url = FeatureNetworkUrls
|
|
116
|
+
.get(feature)
|
|
117
|
+
.get(network)
|
|
118
|
+
.call(undefined, options)
|
|
125
119
|
|
|
126
|
-
|
|
127
|
-
throw TypeError(
|
|
128
|
-
`Feature's '${feature}' Network '${network}' must be listed in 'FeatureNetworkOrigins'.`,
|
|
129
|
-
)
|
|
120
|
+
var request = new Request(url, init)
|
|
130
121
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
122
|
+
if ('cookie' in init)
|
|
123
|
+
request.headers.set(
|
|
124
|
+
'Authorization',
|
|
125
|
+
cookies.read(Cookies.Token, init.cookie),
|
|
126
|
+
)
|
|
135
127
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
*
|
|
142
|
-
* @returns {Promise<FetchResults[Feature][Method][Role]>}
|
|
143
|
-
*/
|
|
144
|
-
let fetch = (options, init) => {
|
|
145
|
-
let onbefore = parameters => {
|
|
146
|
-
let predicates = Extensions
|
|
147
|
-
.get(fetch)
|
|
148
|
-
.get('onbefore')
|
|
149
|
-
|
|
150
|
-
return (predicates.size > 0)
|
|
151
|
-
? Array
|
|
152
|
-
.from(predicates)
|
|
153
|
-
.reduce(
|
|
154
|
-
(parameters, onbefore) => onbefore(parameters),
|
|
155
|
-
parameters,
|
|
156
|
-
)
|
|
157
|
-
: parameters
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
let onfulfilled = contract => {
|
|
161
|
-
let predicates = Extensions
|
|
162
|
-
.get(fetch)
|
|
163
|
-
.get('onfulfilled')
|
|
164
|
-
|
|
165
|
-
return (predicates.size > 0)
|
|
166
|
-
? Array
|
|
167
|
-
.from(predicates)
|
|
168
|
-
.reduce(
|
|
169
|
-
(contract, onfulfilled) => onfulfilled(contract),
|
|
170
|
-
contract,
|
|
171
|
-
)
|
|
172
|
-
: contract
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
let onrejected = reason => {
|
|
176
|
-
let predicates = Extensions
|
|
177
|
-
.get(fetch)
|
|
178
|
-
.get('onrejected')
|
|
128
|
+
if (!request.headers.has('Content-Type'))
|
|
129
|
+
request.headers.set(
|
|
130
|
+
'Content-Type',
|
|
131
|
+
'application/json',
|
|
132
|
+
)
|
|
179
133
|
|
|
134
|
+
/**
|
|
135
|
+
* @param {ExtensionHooks} name
|
|
136
|
+
* @param {any} value
|
|
137
|
+
*/
|
|
138
|
+
var hook = (name, value) =>
|
|
180
139
|
Array
|
|
181
|
-
.from(
|
|
182
|
-
.
|
|
183
|
-
|
|
184
|
-
throw reason
|
|
185
|
-
}
|
|
140
|
+
.from(extensions.get(fetcher).get(name))
|
|
141
|
+
.reduce((x, f) => f(x), value)
|
|
186
142
|
|
|
187
143
|
return new Promise((resolve, reject) => {
|
|
188
144
|
try {
|
|
189
|
-
resolve(onbefore
|
|
145
|
+
resolve(hook('onbefore', request))
|
|
190
146
|
} catch (reason) {
|
|
191
147
|
reject(reason)
|
|
192
148
|
}
|
|
193
149
|
})
|
|
194
|
-
.then(
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
options,
|
|
200
|
-
init,
|
|
201
|
-
)
|
|
202
|
-
)
|
|
203
|
-
.then(onfulfilled)
|
|
204
|
-
.catch(onrejected)
|
|
150
|
+
.then(fetch)
|
|
151
|
+
.then(message.read)
|
|
152
|
+
.then(handleMessage.bind(undefined, feature))
|
|
153
|
+
.then(hook.bind(undefined, 'onfulfilled'))
|
|
154
|
+
.catch(hook.bind(undefined, 'onrejected'))
|
|
205
155
|
}
|
|
206
|
-
|
|
207
|
-
Extensions.set(
|
|
208
|
-
fetch,
|
|
209
|
-
new Map([
|
|
210
|
-
['onbefore', new Set([])],
|
|
211
|
-
['onfulfilled', new Set([])],
|
|
212
|
-
['onrejected', new Set([])],
|
|
213
|
-
]),
|
|
214
|
-
)
|
|
215
|
-
|
|
216
|
-
return fetch
|
|
217
|
-
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { url } from '@yurkimus/url'
|
|
2
|
+
|
|
1
3
|
import {
|
|
2
4
|
FeatureNetworkOrigins,
|
|
5
|
+
FeatureNetworkUrls,
|
|
6
|
+
FeaturePathnames,
|
|
3
7
|
Features,
|
|
4
8
|
ServiceFeatures,
|
|
5
9
|
} from '../enumerations/features.js'
|
|
@@ -27,15 +31,27 @@ export var setFeatureNetworkOrigins = origins => {
|
|
|
27
31
|
`Feature '${feature}' must be listed in 'Features'.`,
|
|
28
32
|
)
|
|
29
33
|
|
|
34
|
+
if (!(feature in FeaturePathnames))
|
|
35
|
+
throw TypeError(
|
|
36
|
+
`Feature '${feature}' must be listed in 'FeaturePathnames'.`,
|
|
37
|
+
)
|
|
38
|
+
|
|
30
39
|
for (let network in origins[service]) {
|
|
31
40
|
if (!(network in Networks))
|
|
32
41
|
throw TypeError(
|
|
33
42
|
`Network '${network}' must be listed in 'Networks'.`,
|
|
34
43
|
)
|
|
35
44
|
|
|
36
|
-
|
|
45
|
+
var origin = origins[service][network]
|
|
46
|
+
var pathname = FeaturePathnames[feature]
|
|
47
|
+
|
|
48
|
+
FeatureNetworkOrigins
|
|
49
|
+
.get(feature)
|
|
50
|
+
.set(network, origin)
|
|
51
|
+
|
|
52
|
+
FeatureNetworkUrls
|
|
37
53
|
.get(feature)
|
|
38
|
-
.set(network,
|
|
54
|
+
.set(network, url.bind(undefined, origin, pathname))
|
|
39
55
|
}
|
|
40
56
|
}
|
|
41
57
|
}
|
package/source/index.d.ts
CHANGED
package/source/index.js
CHANGED