@toa.io/extensions.exposition 1.0.0-alpha.25 → 1.0.0-alpha.27
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/documentation/query.md +8 -4
- package/features/debug.feature +34 -0
- package/features/octets.feature +11 -0
- package/features/probes.feature +14 -0
- package/features/{queries.feature → query.feature} +31 -0
- package/features/routes.feature +1 -2
- package/features/timing.feature +1 -1
- package/package.json +7 -7
- package/source/Gateway.ts +4 -4
- package/source/HTTP/Context.ts +13 -0
- package/source/HTTP/Server.ts +32 -16
- package/source/Mapping.ts +6 -1
- package/source/Query.test.ts +1 -1
- package/source/Query.ts +29 -22
- package/source/deployment.ts +8 -2
- package/transpiled/Gateway.js +4 -4
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +1 -0
- package/transpiled/HTTP/Context.js +9 -0
- package/transpiled/HTTP/Context.js.map +1 -1
- package/transpiled/HTTP/Server.d.ts +5 -1
- package/transpiled/HTTP/Server.js +25 -13
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/Mapping.js +4 -1
- package/transpiled/Mapping.js.map +1 -1
- package/transpiled/Query.d.ts +1 -0
- package/transpiled/Query.js +19 -18
- package/transpiled/Query.js.map +1 -1
- package/transpiled/deployment.js +8 -2
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/tsconfig.tsbuildinfo +1 -1
package/documentation/query.md
CHANGED
|
@@ -77,8 +77,12 @@ query:
|
|
|
77
77
|
|
|
78
78
|
### Path variables
|
|
79
79
|
|
|
80
|
-
Path variables are prepended to the `criteria` request query parameter
|
|
81
|
-
|
|
80
|
+
Path variables are prepended to the `criteria` request query parameter except for
|
|
81
|
+
the [`POST` method](#post-method).
|
|
82
|
+
|
|
83
|
+
If query criteria starts with logical operator (`,` or `;`), then path variables are prepended
|
|
84
|
+
accordingly.
|
|
85
|
+
`AND` logical operator is used by default.
|
|
82
86
|
|
|
83
87
|
Given the following declaration:
|
|
84
88
|
|
|
@@ -92,7 +96,7 @@ exposition:
|
|
|
92
96
|
GET:
|
|
93
97
|
endpoint: observe
|
|
94
98
|
query:
|
|
95
|
-
criteria: state==hot; # open criteria
|
|
99
|
+
criteria: ,state==hot; # open criteria
|
|
96
100
|
```
|
|
97
101
|
|
|
98
102
|
and the following request:
|
|
@@ -104,7 +108,7 @@ GET /dummies/cool/?criteria=rank==5
|
|
|
104
108
|
Operation call will have the following query criteria:
|
|
105
109
|
|
|
106
110
|
```yaml
|
|
107
|
-
criteria: state==hot;
|
|
111
|
+
criteria: (type==cool,state==hot);(rank=5)
|
|
108
112
|
```
|
|
109
113
|
|
|
110
114
|
#### POST method
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Feature: Debugging
|
|
2
|
+
|
|
3
|
+
Scenario: Operation call
|
|
4
|
+
Given the `identity.basic` database contains:
|
|
5
|
+
| _id | authority | username | password |
|
|
6
|
+
| efe3a65ebbee47ed95a73edd911ea328 | nex | developer | $2b$10$ZRSKkgZoGnrcTNA5w5eCcu3pxDzdTduhteVYXcp56AaNcilNkwJ.O |
|
|
7
|
+
And the `identity.roles` database contains:
|
|
8
|
+
| _id | identity | role |
|
|
9
|
+
| 775a648d054e4ce1a65f8f17e5b51803 | efe3a65ebbee47ed95a73edd911ea328 | developer |
|
|
10
|
+
And the annotation:
|
|
11
|
+
"""yaml
|
|
12
|
+
debug: true
|
|
13
|
+
"""
|
|
14
|
+
And the `greeter` is running with the following manifest:
|
|
15
|
+
"""yaml
|
|
16
|
+
exposition:
|
|
17
|
+
/:
|
|
18
|
+
auth:role: developer
|
|
19
|
+
io:output: true
|
|
20
|
+
GET: greet
|
|
21
|
+
"""
|
|
22
|
+
When the following request is received:
|
|
23
|
+
"""
|
|
24
|
+
GET /greeter/ HTTP/1.1
|
|
25
|
+
host: nex.toa.io
|
|
26
|
+
authorization: Basic ZGV2ZWxvcGVyOnNlY3JldA==
|
|
27
|
+
accept: text/plain
|
|
28
|
+
"""
|
|
29
|
+
Then the following reply is sent:
|
|
30
|
+
"""
|
|
31
|
+
200 OK
|
|
32
|
+
|
|
33
|
+
Hello
|
|
34
|
+
"""
|
package/features/octets.feature
CHANGED
|
@@ -183,6 +183,17 @@ Feature: Octets directive family
|
|
|
183
183
|
type: image/svg+xml
|
|
184
184
|
"""
|
|
185
185
|
|
|
186
|
+
Scenario: Rejection video/avi
|
|
187
|
+
When the stream of `sample.avi` is received with the following headers:
|
|
188
|
+
"""
|
|
189
|
+
POST /media/images/ HTTP/1.1
|
|
190
|
+
host: nex.toa.io
|
|
191
|
+
"""
|
|
192
|
+
Then the following reply is sent:
|
|
193
|
+
"""
|
|
194
|
+
415 Unsupported Media Type
|
|
195
|
+
"""
|
|
196
|
+
|
|
186
197
|
Scenario: Fetching non-existent BLOB
|
|
187
198
|
When the following request is received:
|
|
188
199
|
"""
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Feature: Probes
|
|
2
|
+
|
|
3
|
+
Scenario: Startup probe
|
|
4
|
+
Given the Gateway is running
|
|
5
|
+
And after 1 second
|
|
6
|
+
When the following request is received:
|
|
7
|
+
"""
|
|
8
|
+
GET /.ready HTTP/1.1
|
|
9
|
+
"""
|
|
10
|
+
Then the following reply is sent:
|
|
11
|
+
"""
|
|
12
|
+
200 OK
|
|
13
|
+
cache-control: no-store
|
|
14
|
+
"""
|
|
@@ -137,6 +137,37 @@ Feature: Queries
|
|
|
137
137
|
volume: 200
|
|
138
138
|
"""
|
|
139
139
|
|
|
140
|
+
Scenario: Request to a route with path variable using OR operator
|
|
141
|
+
Given the `pots` is running with the following manifest:
|
|
142
|
+
"""yaml
|
|
143
|
+
exposition:
|
|
144
|
+
/:volume:
|
|
145
|
+
io:output: true
|
|
146
|
+
GET:
|
|
147
|
+
query:
|
|
148
|
+
criteria: ',volume==100'
|
|
149
|
+
endpoint: enumerate
|
|
150
|
+
"""
|
|
151
|
+
When the following request is received:
|
|
152
|
+
"""
|
|
153
|
+
GET /pots/200/ HTTP/1.1
|
|
154
|
+
host: nex.toa.io
|
|
155
|
+
accept: application/yaml
|
|
156
|
+
"""
|
|
157
|
+
Then the following reply is sent:
|
|
158
|
+
"""
|
|
159
|
+
200 OK
|
|
160
|
+
content-type: application/yaml
|
|
161
|
+
|
|
162
|
+
- id: 4c4759e6f9c74da989d64511df42d6f4
|
|
163
|
+
title: First pot
|
|
164
|
+
volume: 100
|
|
165
|
+
temperature: 80
|
|
166
|
+
- id: 99988d785d7d445cad45dbf8531f560b
|
|
167
|
+
title: Second pot
|
|
168
|
+
volume: 200
|
|
169
|
+
"""
|
|
170
|
+
|
|
140
171
|
Scenario: Request to a route with predefined criteria
|
|
141
172
|
Given the `pots` is running with the following manifest:
|
|
142
173
|
"""yaml
|
package/features/routes.feature
CHANGED
|
@@ -99,8 +99,7 @@ Feature: Routes
|
|
|
99
99
|
"""
|
|
100
100
|
|
|
101
101
|
Scenario: Routes with naming conflicts
|
|
102
|
-
Given the
|
|
103
|
-
And the `users` is running with the following manifest:
|
|
102
|
+
Given the `users` is running with the following manifest:
|
|
104
103
|
"""yaml
|
|
105
104
|
exposition:
|
|
106
105
|
/:
|
package/features/timing.feature
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/extensions.exposition",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.27",
|
|
4
4
|
"description": "Toa Exposition",
|
|
5
5
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@toa.io/core": "1.0.0-alpha.
|
|
21
|
-
"@toa.io/generic": "1.0.0-alpha.
|
|
22
|
-
"@toa.io/schemas": "1.0.0-alpha.
|
|
20
|
+
"@toa.io/core": "1.0.0-alpha.27",
|
|
21
|
+
"@toa.io/generic": "1.0.0-alpha.27",
|
|
22
|
+
"@toa.io/schemas": "1.0.0-alpha.27",
|
|
23
23
|
"bcryptjs": "2.4.3",
|
|
24
24
|
"error-value": "0.3.0",
|
|
25
25
|
"js-yaml": "4.1.0",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"features:security": "cucumber-js --tags @security"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@toa.io/agent": "1.0.0-alpha.
|
|
49
|
-
"@toa.io/extensions.storages": "1.0.0-alpha.
|
|
48
|
+
"@toa.io/agent": "1.0.0-alpha.27",
|
|
49
|
+
"@toa.io/extensions.storages": "1.0.0-alpha.27",
|
|
50
50
|
"@types/bcryptjs": "2.4.3",
|
|
51
51
|
"@types/cors": "2.8.13",
|
|
52
52
|
"@types/negotiator": "0.6.1"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "9bc4bdb919688c5272791020746f70d51a520750"
|
|
55
55
|
}
|
package/source/Gateway.ts
CHANGED
|
@@ -55,16 +55,16 @@ export class Gateway extends Connector {
|
|
|
55
55
|
protected override async open (): Promise<void> {
|
|
56
56
|
await this.discover()
|
|
57
57
|
|
|
58
|
-
console.info('Gateway has started and is awaiting resource branches
|
|
58
|
+
console.info('Gateway has started and is awaiting resource branches')
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
protected override dispose (): void {
|
|
62
|
-
console.info('Gateway is closed
|
|
62
|
+
console.info('Gateway is closed')
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
private async call (method: Method, context: http.Context, parameters: Parameter[]): Promise<http.OutgoingMessage> {
|
|
66
66
|
if (context.url.pathname[context.url.pathname.length - 1] !== '/')
|
|
67
|
-
throw new http.NotFound('Trailing slash is required
|
|
67
|
+
throw new http.NotFound('Trailing slash is required')
|
|
68
68
|
|
|
69
69
|
if (context.encoder === null)
|
|
70
70
|
throw new http.NotAcceptable()
|
|
@@ -87,7 +87,7 @@ export class Gateway extends Connector {
|
|
|
87
87
|
this.tree.merge(branch.node, branch)
|
|
88
88
|
|
|
89
89
|
console.info('Resource branch of ' +
|
|
90
|
-
`'${branch.namespace}.${branch.component}' has been merged
|
|
90
|
+
`'${branch.namespace}.${branch.component}' has been merged`)
|
|
91
91
|
} catch (exception) {
|
|
92
92
|
console.error(exception)
|
|
93
93
|
}
|
package/source/HTTP/Context.ts
CHANGED
|
@@ -27,6 +27,9 @@ export class Context {
|
|
|
27
27
|
this.timing = new Timing(properties.trace)
|
|
28
28
|
this.debug = properties.debug
|
|
29
29
|
|
|
30
|
+
if (this.debug)
|
|
31
|
+
this.log(request)
|
|
32
|
+
|
|
30
33
|
if (this.request.headers.accept !== undefined) {
|
|
31
34
|
const match = SUBTYPE.exec(this.request.headers.accept)
|
|
32
35
|
|
|
@@ -56,6 +59,16 @@ export class Context {
|
|
|
56
59
|
? value
|
|
57
60
|
: this.pipelines.body.reduce((value, transform) => transform(value), value)
|
|
58
61
|
}
|
|
62
|
+
|
|
63
|
+
private log (request: IncomingMessage): void {
|
|
64
|
+
const message = `${request.method} ${request.url}`
|
|
65
|
+
const { authorization, ...headers } = request.headers
|
|
66
|
+
|
|
67
|
+
if (authorization !== undefined)
|
|
68
|
+
headers.authorization = authorization.slice(0, authorization.indexOf(' '))
|
|
69
|
+
|
|
70
|
+
console.debug(message, headers)
|
|
71
|
+
}
|
|
59
72
|
}
|
|
60
73
|
|
|
61
74
|
export interface IncomingMessage extends http.IncomingMessage {
|
package/source/HTTP/Server.ts
CHANGED
|
@@ -2,6 +2,7 @@ import fs from 'node:fs'
|
|
|
2
2
|
import os from 'node:os'
|
|
3
3
|
import * as http from 'node:http'
|
|
4
4
|
import { once } from 'node:events'
|
|
5
|
+
import { setTimeout } from 'node:timers/promises'
|
|
5
6
|
import { Connector } from '@toa.io/core'
|
|
6
7
|
import { type OutgoingMessage, write } from './messages'
|
|
7
8
|
import { ClientError, Exception } from './exceptions'
|
|
@@ -13,6 +14,8 @@ export class Server extends Connector {
|
|
|
13
14
|
private readonly properties: Properties
|
|
14
15
|
private readonly authorities: Record<string, string>
|
|
15
16
|
private process?: Processing
|
|
17
|
+
private ready: boolean = false
|
|
18
|
+
private startedAt: number = 0
|
|
16
19
|
|
|
17
20
|
private constructor (properties: Properties) {
|
|
18
21
|
super()
|
|
@@ -23,18 +26,6 @@ export class Server extends Connector {
|
|
|
23
26
|
this.server.on('request', (req, res) => this.listener(req, res))
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
public get port (): number {
|
|
27
|
-
if (this.properties.port !== 0)
|
|
28
|
-
return this.properties.port
|
|
29
|
-
|
|
30
|
-
const address = this.server.address()
|
|
31
|
-
|
|
32
|
-
if (address === null || typeof address === 'string')
|
|
33
|
-
throw new Error('Server is not listening on a port.')
|
|
34
|
-
|
|
35
|
-
return address.port
|
|
36
|
-
}
|
|
37
|
-
|
|
38
29
|
public static create (options: Options): Server {
|
|
39
30
|
const properties: Properties = Object.assign({}, DEFAULTS, options)
|
|
40
31
|
|
|
@@ -46,21 +37,29 @@ export class Server extends Connector {
|
|
|
46
37
|
}
|
|
47
38
|
|
|
48
39
|
protected override async open (): Promise<void> {
|
|
40
|
+
this.startedAt = Date.now()
|
|
49
41
|
this.server.listen(this.properties.port)
|
|
50
42
|
|
|
51
43
|
await once(this.server, 'listening')
|
|
52
44
|
|
|
53
|
-
console.info('HTTP Server is listening
|
|
45
|
+
console.info('HTTP Server is listening')
|
|
46
|
+
|
|
47
|
+
await setTimeout(this.properties.delay)
|
|
48
|
+
|
|
49
|
+
this.ready = true
|
|
50
|
+
|
|
51
|
+
console.info('Ready')
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
protected override async close (): Promise<void> {
|
|
57
55
|
this.server.close()
|
|
56
|
+
this.ready = false
|
|
58
57
|
|
|
59
|
-
console.info('HTTP Server stopped accepting new connections
|
|
58
|
+
console.info('HTTP Server stopped accepting new connections')
|
|
60
59
|
|
|
61
60
|
await once(this.server, 'close')
|
|
62
61
|
|
|
63
|
-
console.info('HTTP Server has been stopped
|
|
62
|
+
console.info('HTTP Server has been stopped')
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
private listener (request: http.IncomingMessage, response: http.ServerResponse): void {
|
|
@@ -70,6 +69,18 @@ export class Server extends Connector {
|
|
|
70
69
|
return
|
|
71
70
|
}
|
|
72
71
|
|
|
72
|
+
if (request.url === '/.ready') {
|
|
73
|
+
if (this.ready)
|
|
74
|
+
response.writeHead(200, { 'cache-control': 'no-store' }).end()
|
|
75
|
+
else {
|
|
76
|
+
const remaining = (Math.ceil((Date.now() - this.startedAt) / 1000)).toString()
|
|
77
|
+
|
|
78
|
+
response.writeHead(503, { 'retry-after': remaining }).end()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
73
84
|
if (request.headers.host === undefined || !(request.headers.host in this.authorities)) {
|
|
74
85
|
response.writeHead(404).end('Unknown authority')
|
|
75
86
|
|
|
@@ -133,11 +144,15 @@ async function adam (request: http.IncomingMessage): Promise<any> {
|
|
|
133
144
|
return once(request, 'end')
|
|
134
145
|
}
|
|
135
146
|
|
|
147
|
+
export const PORT = 8000
|
|
148
|
+
export const DELAY = 3 // seconds
|
|
149
|
+
|
|
136
150
|
const DEFAULTS: Omit<Properties, 'authorities'> = {
|
|
137
151
|
methods: new Set<string>(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']),
|
|
138
152
|
debug: false,
|
|
139
153
|
trace: false,
|
|
140
|
-
port:
|
|
154
|
+
port: PORT,
|
|
155
|
+
delay: DELAY * 1000
|
|
141
156
|
}
|
|
142
157
|
|
|
143
158
|
interface Properties {
|
|
@@ -146,6 +161,7 @@ interface Properties {
|
|
|
146
161
|
debug: boolean
|
|
147
162
|
trace: boolean
|
|
148
163
|
port: number
|
|
164
|
+
delay: number
|
|
149
165
|
}
|
|
150
166
|
|
|
151
167
|
export type Options = { authorities: Properties['authorities'] } & {
|
package/source/Mapping.ts
CHANGED
|
@@ -38,6 +38,8 @@ class QueryableMapping extends Mapping {
|
|
|
38
38
|
|
|
39
39
|
class InputMapping extends Mapping {
|
|
40
40
|
public fit (input: any, _: unknown, parameters: Parameter[]): core.Request {
|
|
41
|
+
const request: core.Request = {}
|
|
42
|
+
|
|
41
43
|
if (input === undefined && parameters.length > 0)
|
|
42
44
|
input = {}
|
|
43
45
|
|
|
@@ -45,6 +47,9 @@ class InputMapping extends Mapping {
|
|
|
45
47
|
for (const parameter of parameters)
|
|
46
48
|
input[parameter.name] = parameter.value
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
if (input !== undefined)
|
|
51
|
+
request.input = input
|
|
52
|
+
|
|
53
|
+
return request
|
|
49
54
|
}
|
|
50
55
|
}
|
package/source/Query.test.ts
CHANGED
|
@@ -16,7 +16,7 @@ it('should combine request criteria', async () => {
|
|
|
16
16
|
const instance = new Query(query)
|
|
17
17
|
const result = instance.fit({ criteria: 'qux==4' }, parameters)
|
|
18
18
|
|
|
19
|
-
expect(result.criteria).toStrictEqual('(
|
|
19
|
+
expect(result.criteria).toStrictEqual('(bar==2;baz==3);(foo==1);(qux==4)')
|
|
20
20
|
})
|
|
21
21
|
|
|
22
22
|
it('should set id parameter as query.id', async () => {
|
package/source/Query.ts
CHANGED
|
@@ -7,15 +7,20 @@ import type * as core from '@toa.io/core'
|
|
|
7
7
|
export class Query {
|
|
8
8
|
private readonly query: syntax.Query
|
|
9
9
|
private readonly closed: boolean = false
|
|
10
|
+
private readonly prepend: ',' | ';' = ';'
|
|
10
11
|
|
|
11
12
|
public constructor (query: syntax.Query) {
|
|
12
13
|
if (query.criteria !== undefined) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (open)
|
|
14
|
+
if (query.criteria.endsWith(';'))
|
|
16
15
|
query.criteria = query.criteria.slice(0, -1)
|
|
17
16
|
else
|
|
18
17
|
this.closed = true
|
|
18
|
+
|
|
19
|
+
if (query.criteria.startsWith(',') || query.criteria.startsWith(';')) {
|
|
20
|
+
this.prepend = query.criteria[0] as ',' | ';'
|
|
21
|
+
|
|
22
|
+
query.criteria = query.criteria.slice(1)
|
|
23
|
+
}
|
|
19
24
|
}
|
|
20
25
|
|
|
21
26
|
this.query = query
|
|
@@ -35,11 +40,7 @@ export class Query {
|
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
private fitCriteria (query: http.Query, parameters: Parameter[]): void {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
if (this.query.criteria !== undefined)
|
|
41
|
-
criteria.push(this.query.criteria)
|
|
42
|
-
|
|
43
|
+
const groups: CriteriaGroup[] = []
|
|
43
44
|
const idx = parameters.findIndex((parameter) => parameter.name === 'id')
|
|
44
45
|
|
|
45
46
|
if (idx !== -1) {
|
|
@@ -49,29 +50,28 @@ export class Query {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
if (parameters.length > 0) {
|
|
52
|
-
const
|
|
53
|
+
const criteria = parameters
|
|
53
54
|
.map(({ name, value }) => `${name}==${value}`)
|
|
54
55
|
.join(';')
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
groups.push({ criteria, operator: this.prepend })
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
if (this.query.criteria !== undefined)
|
|
61
|
+
groups.push({ criteria: this.query.criteria, operator: ';' })
|
|
62
|
+
|
|
59
63
|
if (query.criteria !== undefined)
|
|
60
64
|
if (this.closed)
|
|
61
65
|
throw new http.BadRequest('Query criteria is closed')
|
|
62
66
|
else
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
default:
|
|
72
|
-
query.criteria = '(' + criteria.join(');(') + ')'
|
|
73
|
-
break
|
|
74
|
-
}
|
|
67
|
+
groups.push({ criteria: query.criteria, operator: WHATEVER })
|
|
68
|
+
|
|
69
|
+
if (groups.length > 0)
|
|
70
|
+
query.criteria = groups.reduce((acc, { criteria, operator }, i) => {
|
|
71
|
+
return i === groups.length - 1
|
|
72
|
+
? `${acc}(${criteria})`
|
|
73
|
+
: `${acc}(${criteria})${operator}`
|
|
74
|
+
}, '')
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
private fitRanges (qs: http.Query): void {
|
|
@@ -107,3 +107,10 @@ function fit (string: string, range: [number, number], name: string): number {
|
|
|
107
107
|
|
|
108
108
|
return number
|
|
109
109
|
}
|
|
110
|
+
|
|
111
|
+
const WHATEVER = ';'
|
|
112
|
+
|
|
113
|
+
interface CriteriaGroup {
|
|
114
|
+
criteria: string
|
|
115
|
+
operator: ',' | ';'
|
|
116
|
+
}
|
package/source/deployment.ts
CHANGED
|
@@ -6,6 +6,7 @@ import * as schemas from './schemas'
|
|
|
6
6
|
import { shortcuts } from './Directive'
|
|
7
7
|
import { components } from './Composition'
|
|
8
8
|
import { parse } from './RTD/syntax'
|
|
9
|
+
import { DELAY, PORT } from './HTTP/Server'
|
|
9
10
|
|
|
10
11
|
export function deployment (_: unknown, annotation?: Annotation): Dependency {
|
|
11
12
|
assert.ok(annotation !== undefined, 'Exposition context annotation is required')
|
|
@@ -16,12 +17,17 @@ export function deployment (_: unknown, annotation?: Annotation): Dependency {
|
|
|
16
17
|
const service: Service = {
|
|
17
18
|
group: 'exposition',
|
|
18
19
|
name: 'gateway',
|
|
19
|
-
port:
|
|
20
|
+
port: PORT,
|
|
20
21
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
21
22
|
version: require('../package.json').version,
|
|
22
23
|
variables: [],
|
|
23
24
|
components: labels,
|
|
24
|
-
ingress: { hosts: [] }
|
|
25
|
+
ingress: { hosts: [] },
|
|
26
|
+
probe: {
|
|
27
|
+
path: '/.ready',
|
|
28
|
+
port: PORT,
|
|
29
|
+
delay: DELAY
|
|
30
|
+
}
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
if (annotation?.['/'] !== undefined) {
|
package/transpiled/Gateway.js
CHANGED
|
@@ -57,14 +57,14 @@ class Gateway extends core_1.Connector {
|
|
|
57
57
|
}
|
|
58
58
|
async open() {
|
|
59
59
|
await this.discover();
|
|
60
|
-
console.info('Gateway has started and is awaiting resource branches
|
|
60
|
+
console.info('Gateway has started and is awaiting resource branches');
|
|
61
61
|
}
|
|
62
62
|
dispose() {
|
|
63
|
-
console.info('Gateway is closed
|
|
63
|
+
console.info('Gateway is closed');
|
|
64
64
|
}
|
|
65
65
|
async call(method, context, parameters) {
|
|
66
66
|
if (context.url.pathname[context.url.pathname.length - 1] !== '/')
|
|
67
|
-
throw new http.NotFound('Trailing slash is required
|
|
67
|
+
throw new http.NotFound('Trailing slash is required');
|
|
68
68
|
if (context.encoder === null)
|
|
69
69
|
throw new http.NotAcceptable();
|
|
70
70
|
if (method.endpoint === null)
|
|
@@ -81,7 +81,7 @@ class Gateway extends core_1.Connector {
|
|
|
81
81
|
try {
|
|
82
82
|
this.tree.merge(branch.node, branch);
|
|
83
83
|
console.info('Resource branch of ' +
|
|
84
|
-
`'${branch.namespace}.${branch.component}' has been merged
|
|
84
|
+
`'${branch.namespace}.${branch.component}' has been merged`);
|
|
85
85
|
}
|
|
86
86
|
catch (exception) {
|
|
87
87
|
console.error(exception);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Gateway.js","sourceRoot":"","sources":["../source/Gateway.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAuD;AACvD,6CAA8B;AAC9B,6CAAsC;AAMtC,MAAa,OAAQ,SAAQ,gBAAS;IACnB,SAAS,CAAW;IACpB,IAAI,CAAM;IACV,WAAW,CAAc;IAE1C,YAAoB,SAAoB,EAAE,IAAU,EAAE,YAA0B;QAC9E,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,WAAW,GAAG,YAAY,CAAA;QAE/B,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACzB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAE,OAAqB;QACzC,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAC3D,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;QAEtC,IAAI,YAAY,KAAK,IAAI;YACvB,OAAO,YAAY,CAAA;QAErB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAEnD,IAAI,KAAK,KAAK,IAAI;YAChB,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAA;QAE5C,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;QAElC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;YAC3C,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAA;QAEnC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAEnD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAC3D,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAO,CAAC,CAAA;QAElE,MAAM,QAAQ,GAAG,YAAY;YAC3B,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAA;QAE9E,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EACnC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,oBAAO,CAAC,CAAA;QAE7D,OAAO,QAAQ,CAAA;IACjB,CAAC;IAEkB,KAAK,CAAC,IAAI;QAC3B,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAA;QAErB,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"Gateway.js","sourceRoot":"","sources":["../source/Gateway.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ export declare class Context {
|
|
|
14
14
|
readonly pipelines: Pipelines;
|
|
15
15
|
constructor(authority: string, request: IncomingMessage, properties: Properties);
|
|
16
16
|
body<T>(): Promise<T>;
|
|
17
|
+
private log;
|
|
17
18
|
}
|
|
18
19
|
export interface IncomingMessage extends http.IncomingMessage {
|
|
19
20
|
url: string;
|
|
@@ -26,6 +26,8 @@ class Context {
|
|
|
26
26
|
this.url = new URL(request.url, `https://${request.headers.host}`);
|
|
27
27
|
this.timing = new Timing_1.Timing(properties.trace);
|
|
28
28
|
this.debug = properties.debug;
|
|
29
|
+
if (this.debug)
|
|
30
|
+
this.log(request);
|
|
29
31
|
if (this.request.headers.accept !== undefined) {
|
|
30
32
|
const match = SUBTYPE.exec(this.request.headers.accept);
|
|
31
33
|
if (match !== null) {
|
|
@@ -45,6 +47,13 @@ class Context {
|
|
|
45
47
|
? value
|
|
46
48
|
: this.pipelines.body.reduce((value, transform) => transform(value), value);
|
|
47
49
|
}
|
|
50
|
+
log(request) {
|
|
51
|
+
const message = `${request.method} ${request.url}`;
|
|
52
|
+
const { authorization, ...headers } = request.headers;
|
|
53
|
+
if (authorization !== undefined)
|
|
54
|
+
headers.authorization = authorization.slice(0, authorization.indexOf(' '));
|
|
55
|
+
console.debug(message, headers);
|
|
56
|
+
}
|
|
48
57
|
}
|
|
49
58
|
exports.Context = Context;
|
|
50
59
|
const SUBTYPE = /^(?<type>\w{1,32})\/(vnd\.toa\.(?<subtype>\S{1,32})\+)(?<suffix>\S{1,32})$/;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Context.js","sourceRoot":"","sources":["../../source/HTTP/Context.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAmC;AACnC,qCAAiC;AACjC,uCAAuD;AACvD,yCAAiC;AAIjC,MAAa,OAAO;IACF,SAAS,CAAQ;IACjB,OAAO,CAAiB;IACxB,GAAG,CAAK;IACR,OAAO,GAAkB,IAAI,CAAA;IAC7B,OAAO,GAAkB,IAAI,CAAA;IAC7B,MAAM,CAAQ;IACd,KAAK,CAAS;IAEd,SAAS,GAAc;QACrC,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE,EAAE;KACb,CAAA;IAED,YAAoB,SAAiB,EAAE,OAAwB,EAAE,UAAsB;QACrF,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QAEtB,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;QAClE,IAAI,CAAC,MAAM,GAAG,IAAI,eAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QAC1C,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;QAE7B,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;YAEvD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,MAAM,EACJ,IAAI,EACJ,OAAO,EACP,MAAM,EACP,GAAG,KAAK,CAAC,MAAO,CAAA;gBAEjB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,IAAI,IAAI,MAAM,EAAE,CAAA;gBACjD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;YACxB,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,oBAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/C,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,eAAK,CAAC,CAAA;QAE7C,IAAI,SAAS,KAAK,SAAS;YACzB,IAAI,CAAC,OAAO,GAAG,iBAAO,CAAC,SAAS,CAAC,CAAA;IACrC,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,KAAK,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,CAAA;QAE9B,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YACrC,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;IAC/E,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"Context.js","sourceRoot":"","sources":["../../source/HTTP/Context.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAmC;AACnC,qCAAiC;AACjC,uCAAuD;AACvD,yCAAiC;AAIjC,MAAa,OAAO;IACF,SAAS,CAAQ;IACjB,OAAO,CAAiB;IACxB,GAAG,CAAK;IACR,OAAO,GAAkB,IAAI,CAAA;IAC7B,OAAO,GAAkB,IAAI,CAAA;IAC7B,MAAM,CAAQ;IACd,KAAK,CAAS;IAEd,SAAS,GAAc;QACrC,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE,EAAE;KACb,CAAA;IAED,YAAoB,SAAiB,EAAE,OAAwB,EAAE,UAAsB;QACrF,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QAEtB,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;QAClE,IAAI,CAAC,MAAM,GAAG,IAAI,eAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QAC1C,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;QAE7B,IAAI,IAAI,CAAC,KAAK;YACZ,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAEnB,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;YAEvD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,MAAM,EACJ,IAAI,EACJ,OAAO,EACP,MAAM,EACP,GAAG,KAAK,CAAC,MAAO,CAAA;gBAEjB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,IAAI,IAAI,MAAM,EAAE,CAAA;gBACjD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;YACxB,CAAC;QACH,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,oBAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/C,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,eAAK,CAAC,CAAA;QAE7C,IAAI,SAAS,KAAK,SAAS;YACzB,IAAI,CAAC,OAAO,GAAG,iBAAO,CAAC,SAAS,CAAC,CAAA;IACrC,CAAC;IAEM,KAAK,CAAC,IAAI;QACf,MAAM,KAAK,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,CAAA;QAE9B,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YACrC,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;IAC/E,CAAC;IAEO,GAAG,CAAE,OAAwB;QACnC,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;QAClD,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAA;QAErD,IAAI,aAAa,KAAK,SAAS;YAC7B,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;QAE5E,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACjC,CAAC;CACF;AAhED,0BAgEC;AAiBD,MAAM,OAAO,GAAG,4EAA4E,CAAA"}
|
|
@@ -6,8 +6,9 @@ export declare class Server extends Connector {
|
|
|
6
6
|
private readonly properties;
|
|
7
7
|
private readonly authorities;
|
|
8
8
|
private process?;
|
|
9
|
+
private ready;
|
|
10
|
+
private startedAt;
|
|
9
11
|
private constructor();
|
|
10
|
-
get port(): number;
|
|
11
12
|
static create(options: Options): Server;
|
|
12
13
|
attach(process: Processing): void;
|
|
13
14
|
protected open(): Promise<void>;
|
|
@@ -16,12 +17,15 @@ export declare class Server extends Connector {
|
|
|
16
17
|
private success;
|
|
17
18
|
private fail;
|
|
18
19
|
}
|
|
20
|
+
export declare const PORT = 8000;
|
|
21
|
+
export declare const DELAY = 3;
|
|
19
22
|
interface Properties {
|
|
20
23
|
authorities: Record<string, string>;
|
|
21
24
|
methods: Set<string>;
|
|
22
25
|
debug: boolean;
|
|
23
26
|
trace: boolean;
|
|
24
27
|
port: number;
|
|
28
|
+
delay: number;
|
|
25
29
|
}
|
|
26
30
|
export type Options = {
|
|
27
31
|
authorities: Properties['authorities'];
|