velocious 1.0.661 → 1.0.662
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 +11 -0
- package/build/application.js +1 -1
- package/build/configuration-types.js +3 -1
- package/build/configuration.js +33 -0
- package/build/http-server/client/errors.js +27 -0
- package/build/http-server/client/index.js +26 -1
- package/build/http-server/client/request-buffer/index.js +38 -6
- package/build/http-server/client/request-runner.js +8 -1
- package/build/http-server/client/response.js +11 -0
- package/build/routes/resolver.js +1 -1
- package/build/src/application.js +2 -2
- package/build/src/configuration-types.d.ts +13 -3
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +4 -2
- package/build/src/configuration.d.ts +14 -2
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +31 -1
- package/build/src/http-server/client/errors.d.ts +25 -0
- package/build/src/http-server/client/errors.d.ts.map +1 -0
- package/build/src/http-server/client/errors.js +26 -0
- package/build/src/http-server/client/index.d.ts +5 -0
- package/build/src/http-server/client/index.d.ts.map +1 -1
- package/build/src/http-server/client/index.js +26 -2
- package/build/src/http-server/client/request-buffer/index.d.ts +13 -0
- package/build/src/http-server/client/request-buffer/index.d.ts.map +1 -1
- package/build/src/http-server/client/request-buffer/index.js +34 -8
- package/build/src/http-server/client/request-runner.d.ts.map +1 -1
- package/build/src/http-server/client/request-runner.js +10 -2
- package/build/src/http-server/client/response.d.ts.map +1 -1
- package/build/src/http-server/client/response.js +8 -1
- package/build/src/routes/resolver.js +2 -2
- package/package.json +1 -1
- package/src/application.js +1 -1
- package/src/configuration-types.js +3 -1
- package/src/configuration.js +33 -0
- package/src/http-server/client/errors.js +27 -0
- package/src/http-server/client/index.js +26 -1
- package/src/http-server/client/request-buffer/index.js +38 -6
- package/src/http-server/client/request-runner.js +8 -1
- package/src/http-server/client/response.js +11 -0
- package/src/routes/resolver.js +1 -1
package/README.md
CHANGED
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
* Cross-process broadcast bus for `broadcastToChannel` via `velocious beacon`, including background job runner processes (see [docs/beacon.md](docs/beacon.md))
|
|
35
35
|
* Rails-style application process initializer teardown with immutable process identity, reverse idempotent shutdown, and explicit HTTP/background-job ownership (see [docs/application-process-lifecycle.md](docs/application-process-lifecycle.md))
|
|
36
36
|
* Configurable HTTP server worker handlers plus backpressured, descriptor-only file responses with completion callbacks (see [docs/http-server.md](docs/http-server.md))
|
|
37
|
+
* Explicit database-free in-process HTTP applications with optional request and buffered-response byte limits (see [docs/http-server.md](docs/http-server.md#database-free-applications))
|
|
37
38
|
* Default-on buffered HTTP response compression with Brotli/gzip content negotiation, global and per-response opt-outs, and HEAD-correct representation headers (see [docs/http-server.md](docs/http-server.md#response-compression))
|
|
38
39
|
* Background jobs with Node SQL/TCP workers plus a Browser/Expo local SQLite store and in-process dispatcher, including failure events, authorized database-scoped dashboard counts, and an opt-in release-scoped main/worker generation protocol with acknowledged activation, asynchronous retirement, and retired-main recovery. Production compliance additionally requires downstream supervisor retention/activation ordering and release pins (see [docs/background-jobs.md](docs/background-jobs.md), [docs/local-background-jobs.md](docs/local-background-jobs.md), and [docs/background-jobs-dashboard.md](docs/background-jobs-dashboard.md))
|
|
39
40
|
* Durable one-off background-job scheduling with exact epoch timestamps (see [docs/scheduled-background-job-enqueue.md](docs/scheduled-background-job-enqueue.md))
|
|
@@ -2907,6 +2908,16 @@ When the server runs in the `development` environment, Velocious watches applica
|
|
|
2907
2908
|
|
|
2908
2909
|
Starting the HTTP server creates `tmp/server.lock` under the configured application directory before Beacon, workers, or the TCP listener start. A second server for the same app fails fast with the lock owner details instead of partially starting. Normal shutdown removes the lock; stale locks with a dead local PID are reclaimed automatically, while locks from another host or unreadable metadata should be removed manually only after confirming no server is running. See [docs/http-server.md](docs/http-server.md#server-lock).
|
|
2909
2910
|
|
|
2911
|
+
Set `database: false` for an explicitly database-free application; its HTTP and
|
|
2912
|
+
initializer lifecycle remains intact without creating a default pool or an
|
|
2913
|
+
implicit route connection checkout. Optional
|
|
2914
|
+
`httpServer.maxRequestBodyBytes` and
|
|
2915
|
+
`httpServer.maxBufferedResponseBodyBytes` positive byte limits reject oversized
|
|
2916
|
+
request bodies with a connection-closing `413` and oversized buffered responses
|
|
2917
|
+
with a reported, empty `500`. Both remain unbounded when omitted, and streamed
|
|
2918
|
+
`sendFile` responses are unaffected. The request limit is enforced while
|
|
2919
|
+
unframed multipart bodies accumulate. See [docs/http-server.md](docs/http-server.md#database-free-applications).
|
|
2920
|
+
|
|
2910
2921
|
Buffered string and `Uint8Array` responses are compressed with Brotli (`br`) or gzip by default whenever request negotiation and response eligibility allow — no opt-in is required. Disable compression globally with `httpServer.compression: false` or `httpServer.compression: {enabled: false}`, and tune it with `threshold`/`brotliQuality`/`gzipLevel` overrides. Negotiation honors `Accept-Encoding` q-values, wildcards, and identity semantics (empty `406` when no acceptable representation exists), combines repeated `Accept-Encoding` header fields in wire order, and advertises a framework-owned `Vary: Accept-Encoding` on every framework-selected representation (transformed, identity, `406`, and file) so caches key on the field. Streamed `sendFile` responses are never buffered or re-encoded: they are sent identity, so when the client forbids identity the server answers with the same empty `406` without opening or streaming the file. Transformation also skips already-encoded or `no-transform` responses, server-sent events, partial/range responses, bodyless statuses, and non-allowlisted content types. Transformation is additionally excluded automatically for credentialed traffic and validator-carrying responses — requests with `Authorization`/`Cookie` and responses with `Set-Cookie`, `ETag`, `Digest`, or `Content-Digest` are never compressed (compression-oracle protection, and validators stay application-owned). Controllers opt out per response with `response.disableCompression()`, and HEAD requests compute GET-equivalent representation headers without emitting a body. See [docs/http-server.md](docs/http-server.md#response-compression).
|
|
2911
2922
|
|
|
2912
2923
|
# Authorization (CanCan-style)
|
package/build/application.js
CHANGED
|
@@ -66,7 +66,7 @@ export default class VelociousApplication {
|
|
|
66
66
|
|
|
67
67
|
this.configuration.setRoutes(routes)
|
|
68
68
|
|
|
69
|
-
if (!this.configuration.isDatabasePoolInitialized()) {
|
|
69
|
+
if (this.configuration.database !== false && !this.configuration.isDatabasePoolInitialized()) {
|
|
70
70
|
await this.configuration.initializeDatabasePool()
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -293,6 +293,8 @@
|
|
|
293
293
|
* @property {boolean | HttpCompressionConfiguration} [compression] - Buffered response compression. Enabled with documented defaults when absent; false or {enabled: false} disables it globally.
|
|
294
294
|
* @property {string} [host] - Hostname to bind the HTTP server to.
|
|
295
295
|
* @property {boolean} [inProcess] - Run HTTP handlers in the main thread instead of worker threads.
|
|
296
|
+
* @property {number} [maxBufferedResponseBodyBytes] - Maximum UTF-8/binary byte length accepted by buffered response bodies. Unbounded when absent; streamed file responses are unaffected.
|
|
297
|
+
* @property {number} [maxRequestBodyBytes] - Maximum decoded request-body bytes accepted before routing. Unbounded when absent.
|
|
296
298
|
* @property {number} [maxWorkers] - Backward-compatible alias for workers.
|
|
297
299
|
* @property {number} [port] - Port to bind the HTTP server to.
|
|
298
300
|
* @property {{maxPendingBytes?: number, maxPendingMessages?: number}} [websocketInboundQueue] - Per-session retained inbound WebSocket message limits.
|
|
@@ -735,7 +737,7 @@
|
|
|
735
737
|
* @property {AttachmentsConfiguration} [attachments] - Attachment storage configuration.
|
|
736
738
|
* @property {BackendProjectConfiguration[]} [backendProjects] - Backend project definitions used for frontend model generation.
|
|
737
739
|
* @property {VelociousPackageConfiguration[]} [packages] - External Velocious packages that contribute models, frontend-model resources and migrations.
|
|
738
|
-
* @property {{[key: string]: {[key: string]: DatabaseConfigurationType}}} database - Database configurations keyed by environment and identifier.
|
|
740
|
+
* @property {false | {[key: string]: {[key: string]: DatabaseConfigurationType}}} [database] - Database configurations keyed by environment and identifier, or false for an explicitly database-free application.
|
|
739
741
|
* @property {boolean} [debug] - Enable debug logging.
|
|
740
742
|
* @property {boolean | DebugEndpointConfiguration} [debugEndpoint] - Enable the built-in debug endpoint. Defaults to false.
|
|
741
743
|
* @property {boolean | ApiManifestConfiguration} [apiManifest] - Enable the built-in API manifest endpoint. Defaults to false.
|
package/build/configuration.js
CHANGED
|
@@ -155,6 +155,21 @@ function positiveSafeInteger(value, name, defaultValue) {
|
|
|
155
155
|
return value
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Validates an optional positive safe integer configuration value.
|
|
160
|
+
* @param {ReturnType<typeof JSON.parse>} value - Configured positive safe integer.
|
|
161
|
+
* @param {string} name - Configuration key.
|
|
162
|
+
* @returns {number | undefined} - Validated configured value.
|
|
163
|
+
*/
|
|
164
|
+
function optionalPositiveSafeInteger(value, name) {
|
|
165
|
+
if (value === undefined) return undefined
|
|
166
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
|
|
167
|
+
throw new TypeError(`${name} must be a positive safe integer`)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return value
|
|
171
|
+
}
|
|
172
|
+
|
|
158
173
|
/**
|
|
159
174
|
* Validates an integer configuration value inside an inclusive range.
|
|
160
175
|
* @param {ReturnType<typeof JSON.parse>} value - Configured integer.
|
|
@@ -347,6 +362,8 @@ export default class VelociousConfiguration {
|
|
|
347
362
|
this.httpServer = {
|
|
348
363
|
...(httpServer || {}),
|
|
349
364
|
compression: normalizeHttpCompression(httpServer?.compression),
|
|
365
|
+
maxBufferedResponseBodyBytes: optionalPositiveSafeInteger(httpServer?.maxBufferedResponseBodyBytes, "httpServer.maxBufferedResponseBodyBytes"),
|
|
366
|
+
maxRequestBodyBytes: optionalPositiveSafeInteger(httpServer?.maxRequestBodyBytes, "httpServer.maxRequestBodyBytes"),
|
|
350
367
|
websocketInboundQueue: {
|
|
351
368
|
maxPendingBytes: positiveSafeInteger(websocketInboundQueue?.maxPendingBytes, "httpServer.websocketInboundQueue.maxPendingBytes", DEFAULT_WEBSOCKET_INBOUND_MAX_PENDING_BYTES),
|
|
352
369
|
maxPendingMessages: positiveSafeInteger(websocketInboundQueue?.maxPendingMessages, "httpServer.websocketInboundQueue.maxPendingMessages", DEFAULT_WEBSOCKET_INBOUND_MAX_PENDING_MESSAGES)
|
|
@@ -644,6 +661,22 @@ export default class VelociousConfiguration {
|
|
|
644
661
|
return this.httpServer.compression
|
|
645
662
|
}
|
|
646
663
|
|
|
664
|
+
/**
|
|
665
|
+
* Runs get maximum buffered response body bytes.
|
|
666
|
+
* @returns {number | undefined} - Configured byte limit, or undefined when unbounded.
|
|
667
|
+
*/
|
|
668
|
+
getHttpServerMaxBufferedResponseBodyBytes() {
|
|
669
|
+
return this.httpServer.maxBufferedResponseBodyBytes
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Runs get maximum request body bytes.
|
|
674
|
+
* @returns {number | undefined} - Configured byte limit, or undefined when unbounded.
|
|
675
|
+
*/
|
|
676
|
+
getHttpServerMaxRequestBodyBytes() {
|
|
677
|
+
return this.httpServer.maxRequestBodyBytes
|
|
678
|
+
}
|
|
679
|
+
|
|
647
680
|
/**
|
|
648
681
|
* Runs get cookie secret.
|
|
649
682
|
* @returns {string | undefined} - Cookie secret.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
export class HttpRequestBodyTooLargeError extends Error {
|
|
4
|
+
/**
|
|
5
|
+
* Creates a request-body limit error.
|
|
6
|
+
* @param {object} args - Size details.
|
|
7
|
+
* @param {number} args.actualBytes - Declared or accumulated body size.
|
|
8
|
+
* @param {number} args.maxBytes - Configured maximum body size.
|
|
9
|
+
*/
|
|
10
|
+
constructor({actualBytes, maxBytes}) {
|
|
11
|
+
super(`HTTP request body exceeds ${maxBytes} bytes (received or declared ${actualBytes})`)
|
|
12
|
+
this.name = "HttpRequestBodyTooLargeError"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class HttpResponseBodyTooLargeError extends Error {
|
|
17
|
+
/**
|
|
18
|
+
* Creates a buffered-response limit error.
|
|
19
|
+
* @param {object} args - Size details.
|
|
20
|
+
* @param {number} args.actualBytes - Buffered response body size.
|
|
21
|
+
* @param {number} args.maxBytes - Configured maximum body size.
|
|
22
|
+
*/
|
|
23
|
+
constructor({actualBytes, maxBytes}) {
|
|
24
|
+
super(`Buffered HTTP response body exceeds ${maxBytes} bytes (received ${actualBytes})`)
|
|
25
|
+
this.name = "HttpResponseBodyTooLargeError"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -5,6 +5,7 @@ import fs from "node:fs/promises"
|
|
|
5
5
|
import {digg} from "diggerize"
|
|
6
6
|
import {ensureError} from "typanic"
|
|
7
7
|
import EventEmitter from "../../utils/event-emitter.js"
|
|
8
|
+
import {HttpRequestBodyTooLargeError} from "./errors.js"
|
|
8
9
|
import Logger from "../../logger.js"
|
|
9
10
|
import Request from "./request.js"
|
|
10
11
|
import RequestRunner from "./request-runner.js"
|
|
@@ -104,6 +105,26 @@ export default class VeoliciousHttpServerClient {
|
|
|
104
105
|
this.events.emit("close")
|
|
105
106
|
}
|
|
106
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Sends a deterministic request-body limit response and closes the connection.
|
|
110
|
+
* @returns {void} - No return value.
|
|
111
|
+
*/
|
|
112
|
+
_sendPayloadTooLargeResponse() {
|
|
113
|
+
const httpVersion = this.currentRequest?.httpVersion() || "1.1"
|
|
114
|
+
const body = "Payload Too Large\n"
|
|
115
|
+
const headers = [
|
|
116
|
+
`HTTP/${httpVersion} 413 Payload Too Large`,
|
|
117
|
+
"Connection: Close",
|
|
118
|
+
"Content-Type: text/plain; charset=UTF-8",
|
|
119
|
+
`Content-Length: ${Buffer.byteLength(body, "utf8")}`,
|
|
120
|
+
"",
|
|
121
|
+
body
|
|
122
|
+
].join("\r\n")
|
|
123
|
+
|
|
124
|
+
this.events.emit("output", headers)
|
|
125
|
+
this.events.emit("close")
|
|
126
|
+
}
|
|
127
|
+
|
|
107
128
|
/**
|
|
108
129
|
* Runs handle bad request.
|
|
109
130
|
* @param {Error} error - Error instance.
|
|
@@ -121,7 +142,11 @@ export default class VeoliciousHttpServerClient {
|
|
|
121
142
|
this.currentRequest = undefined
|
|
122
143
|
this.state = "initial"
|
|
123
144
|
|
|
124
|
-
|
|
145
|
+
if (error instanceof HttpRequestBodyTooLargeError) {
|
|
146
|
+
this._sendPayloadTooLargeResponse()
|
|
147
|
+
} else {
|
|
148
|
+
this._sendBadRequestResponse("Bad Request")
|
|
149
|
+
}
|
|
125
150
|
}
|
|
126
151
|
|
|
127
152
|
executeCurrentRequest = () => {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import EventEmitter from "../../../utils/event-emitter.js"
|
|
4
4
|
import FormDataPart from "./form-data-part.js"
|
|
5
5
|
import Header from "./header.js"
|
|
6
|
+
import {HttpRequestBodyTooLargeError} from "../errors.js"
|
|
6
7
|
import {incorporate} from "incorporator"
|
|
7
8
|
import Logger from "../../../logger.js"
|
|
8
9
|
import ParamsToObject from "../params-to-object.js"
|
|
@@ -66,6 +67,31 @@ export default class RequestBuffer {
|
|
|
66
67
|
this.logger = new Logger(this, {debug: false})
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Raises before buffering a request body beyond the configured bound.
|
|
72
|
+
* @param {number} actualBytes - Declared or accumulated decoded body bytes.
|
|
73
|
+
* @returns {void}
|
|
74
|
+
*/
|
|
75
|
+
assertRequestBodySize(actualBytes) {
|
|
76
|
+
const maxBytes = this.configuration.getHttpServerMaxRequestBodyBytes()
|
|
77
|
+
|
|
78
|
+
if (maxBytes !== undefined && actualBytes > maxBytes) {
|
|
79
|
+
throw new HttpRequestBodyTooLargeError({actualBytes, maxBytes})
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Records bytes consumed after request headers. Multipart parsing can accept
|
|
85
|
+
* an unframed body, so enforce its configured bound during accumulation.
|
|
86
|
+
* @param {number} bytes - Newly consumed body bytes.
|
|
87
|
+
* @returns {void}
|
|
88
|
+
*/
|
|
89
|
+
recordBodyBytes(bytes) {
|
|
90
|
+
this.bodyLength += bytes
|
|
91
|
+
|
|
92
|
+
if (this.multiPartyFormData) this.assertRequestBodySize(this.bodyLength)
|
|
93
|
+
}
|
|
94
|
+
|
|
69
95
|
destroy() {
|
|
70
96
|
// Do nothing for now...
|
|
71
97
|
}
|
|
@@ -113,7 +139,7 @@ export default class RequestBuffer {
|
|
|
113
139
|
const newlineIndex = data.indexOf(10, index)
|
|
114
140
|
|
|
115
141
|
if (newlineIndex === -1) {
|
|
116
|
-
if (this.readingBody) this.
|
|
142
|
+
if (this.readingBody) this.recordBodyBytes(data.length - index)
|
|
117
143
|
|
|
118
144
|
for (let dataIndex = index; dataIndex < data.length; dataIndex += 1) {
|
|
119
145
|
this.data.push(data[dataIndex])
|
|
@@ -122,7 +148,7 @@ export default class RequestBuffer {
|
|
|
122
148
|
return data.length
|
|
123
149
|
}
|
|
124
150
|
|
|
125
|
-
if (this.readingBody) this.
|
|
151
|
+
if (this.readingBody) this.recordBodyBytes(newlineIndex + 1 - index)
|
|
126
152
|
|
|
127
153
|
let line
|
|
128
154
|
|
|
@@ -157,7 +183,7 @@ export default class RequestBuffer {
|
|
|
157
183
|
const endIndex = Math.min(data.length, index + remainingBodyBytes)
|
|
158
184
|
|
|
159
185
|
this.postBodyBuffers.push(data.subarray(index, endIndex))
|
|
160
|
-
this.
|
|
186
|
+
this.recordBodyBytes(endIndex - index)
|
|
161
187
|
|
|
162
188
|
if (this.contentLength && this.bodyLength >= this.contentLength) {
|
|
163
189
|
this.postRequestDone()
|
|
@@ -175,7 +201,7 @@ export default class RequestBuffer {
|
|
|
175
201
|
feedByte(data, index) {
|
|
176
202
|
const char = data[index]
|
|
177
203
|
|
|
178
|
-
if (this.readingBody) this.
|
|
204
|
+
if (this.readingBody) this.recordBodyBytes(1)
|
|
179
205
|
|
|
180
206
|
switch(this.state) {
|
|
181
207
|
case "chunked-data": {
|
|
@@ -414,6 +440,12 @@ export default class RequestBuffer {
|
|
|
414
440
|
this.readingBody = true
|
|
415
441
|
this.bodyLength = 0
|
|
416
442
|
|
|
443
|
+
if (this.contentLength !== undefined) {
|
|
444
|
+
if (Number.isNaN(this.contentLength)) throw new Error("Content length is invalid")
|
|
445
|
+
|
|
446
|
+
this.assertRequestBodySize(this.contentLength)
|
|
447
|
+
}
|
|
448
|
+
|
|
417
449
|
const match = this.getHeader("content-type")?.value?.match(/^multipart\/form-data;\s*boundary=(.+)$/i)
|
|
418
450
|
|
|
419
451
|
if (match) {
|
|
@@ -425,8 +457,6 @@ export default class RequestBuffer {
|
|
|
425
457
|
this.setState("multi-part-form-data")
|
|
426
458
|
} else if (this.contentLength === 0 || this.contentLength === undefined) {
|
|
427
459
|
this.completeRequest()
|
|
428
|
-
} else if (Number.isNaN(this.contentLength)) {
|
|
429
|
-
throw new Error("Content length is invalid")
|
|
430
460
|
} else {
|
|
431
461
|
/**
|
|
432
462
|
* Narrows the runtime value to the documented type.
|
|
@@ -521,6 +551,8 @@ export default class RequestBuffer {
|
|
|
521
551
|
return
|
|
522
552
|
}
|
|
523
553
|
|
|
554
|
+
this.assertRequestBodySize((this.chunkedBodyChars?.length || 0) + size)
|
|
555
|
+
|
|
524
556
|
this.currentChunkSize = size
|
|
525
557
|
this.currentChunkBytesRead = 0
|
|
526
558
|
this.setState("chunked-data")
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import {ensureError} from "typanic"
|
|
4
4
|
import BacktraceCleaner from "../../utils/backtrace-cleaner-node.js"
|
|
5
5
|
import EventEmitter from "../../utils/event-emitter.js"
|
|
6
|
+
import {HttpResponseBodyTooLargeError} from "./errors.js"
|
|
6
7
|
import Logger from "../../logger.js"
|
|
7
8
|
import RequestTiming from "./request-timing.js"
|
|
8
9
|
import Response from "./response.js"
|
|
@@ -304,7 +305,13 @@ export default class VelociousHttpServerClientRequestRunner {
|
|
|
304
305
|
})
|
|
305
306
|
|
|
306
307
|
response.setStatus(500)
|
|
307
|
-
|
|
308
|
+
try {
|
|
309
|
+
response.setErrorBody(error)
|
|
310
|
+
} catch (responseError) {
|
|
311
|
+
if (!(responseError instanceof HttpResponseBodyTooLargeError)) throw responseError
|
|
312
|
+
|
|
313
|
+
response.setBody("")
|
|
314
|
+
}
|
|
308
315
|
}
|
|
309
316
|
|
|
310
317
|
await this.logger.debug(() => ["Request runner done", {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
+
import {HttpResponseBodyTooLargeError} from "./errors.js"
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Named status aliases.
|
|
5
7
|
* @type {Record<string, number>} */
|
|
@@ -226,6 +228,15 @@ export default class VelociousHttpServerClientResponse {
|
|
|
226
228
|
setBody(value) {
|
|
227
229
|
this.filePath = null
|
|
228
230
|
this.fileOnFinished = null
|
|
231
|
+
|
|
232
|
+
const actualBytes = typeof value === "string" ? Buffer.byteLength(value, "utf8") : value.byteLength
|
|
233
|
+
const maxBytes = this.configuration.getHttpServerMaxBufferedResponseBodyBytes()
|
|
234
|
+
|
|
235
|
+
if (maxBytes !== undefined && actualBytes > maxBytes) {
|
|
236
|
+
this.body = ""
|
|
237
|
+
throw new HttpResponseBodyTooLargeError({actualBytes, maxBytes})
|
|
238
|
+
}
|
|
239
|
+
|
|
229
240
|
this.body = value
|
|
230
241
|
}
|
|
231
242
|
|
package/build/routes/resolver.js
CHANGED
|
@@ -92,7 +92,7 @@ export default class VelociousRoutesResolver {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
const routeResolverHookMatch = await this.resolveRouteResolverHooks(currentPath, {hasMatchingCustomRoute})
|
|
95
|
-
let skipControllerConnections = routeResolverHookMatch?.skipControllerConnections === true
|
|
95
|
+
let skipControllerConnections = this.configuration.database === false || routeResolverHookMatch?.skipControllerConnections === true
|
|
96
96
|
let skipAbilityResolution = routeResolverHookMatch?.skipAbilityResolution === true
|
|
97
97
|
let skipTenantResolution = routeResolverHookMatch?.skipTenantResolution === true
|
|
98
98
|
const matchResult = routeResolverHookMatch || !currentRoute ? undefined : this.matchPathWithRoutes(currentRoute, currentPath)
|
package/build/src/application.js
CHANGED
|
@@ -54,7 +54,7 @@ export default class VelociousApplication {
|
|
|
54
54
|
SyncWebsocketChannel.registerFromConfiguration(this.configuration);
|
|
55
55
|
await SyncPublisher.startFromConfiguration(this.configuration);
|
|
56
56
|
this.configuration.setRoutes(routes);
|
|
57
|
-
if (!this.configuration.isDatabasePoolInitialized()) {
|
|
57
|
+
if (this.configuration.database !== false && !this.configuration.isDatabasePoolInitialized()) {
|
|
58
58
|
await this.configuration.initializeDatabasePool();
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -223,4 +223,4 @@ export default class VelociousApplication {
|
|
|
223
223
|
});
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBwbGljYXRpb24uanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sU0FBUyxNQUFNLHdCQUF3QixDQUFBO0FBQzlDLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQTtBQUNoQyxPQUFPLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQTtBQUMvQyxPQUFPLGNBQWMsTUFBTSw4QkFBOEIsQ0FBQTtBQUN6RCxPQUFPLGlCQUFpQixNQUFNLCtCQUErQixDQUFBO0FBQzdELE9BQU8sYUFBYSxNQUFNLDBCQUEwQixDQUFBO0FBQ3BELE9BQU8sb0JBQW9CLE1BQU0sa0NBQWtDLENBQUE7QUFDbkUsT0FBTyxtQkFBbUIsTUFBTSx3Q0FBd0MsQ0FBQTtBQUN4RSxPQUFPLGFBQWEsTUFBTSw0QkFBNEIsQ0FBQTtBQUN0RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQTtBQUVoRTs7bUdBRW1HO0FBRW5HLE1BQU0sQ0FBQyxPQUFPLE9BQU8sb0JBQW9CO0lBQ3ZDOzs7Ozs7T0FNRztJQUNILFlBQVksRUFBQyxhQUFhLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxHQUFHLFFBQVEsRUFBQztRQUN4RCxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUE7UUFFdkIsSUFBSSxDQUFDLGFBQWE7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUE7UUFFaEUsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUE7UUFFbEM7OzZDQUVxQztRQUNyQyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsVUFBVSxJQUFJLEVBQUUsQ0FBQTtRQUUvQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzlCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO1FBQ2pCOztnREFFd0M7UUFDeEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUE7UUFDL0Isd0NBQXdDO1FBQ3hDLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFBO0lBQy9CLENBQUM7SUFFRDs7O09BR0c7SUFDSCxPQUFPLEtBQUssT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFBLENBQUMsQ0FBQztJQUUvQjs7O09BR0c7SUFDSCxLQUFLLENBQUMsVUFBVTtRQUNkLE1BQU0sTUFBTSxHQUFHLE1BQU0sU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUE7UUFFNUQsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxFQUFDLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUMsQ0FBQyxDQUFBO1FBRTNELGlCQUFpQixDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQTtRQUM1RCxvQkFBb0IsQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUE7UUFDbEUsTUFBTSxhQUFhLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO1FBRTlELElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBRXBDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLHlCQUF5QixFQUFFLEVBQUUsQ0FBQztZQUNwRCxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsc0JBQXNCLEVBQUUsQ0FBQTtRQUNuRCxDQUFDO0lBRUgsQ0FBQztJQUVEOzs7T0FHRztJQUNILFFBQVE7UUFDTixJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNwQixPQUFPLElBQUksQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFLENBQUE7UUFDcEMsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVE7UUFDaEIsTUFBTSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUE7UUFFNUIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEVBQUUsQ0FBQTtRQUNsQixDQUFDO2dCQUFTLENBQUM7WUFDVCxNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQTtRQUNuQixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxlQUFlO1FBQ25CLE1BQU0sRUFBQyxhQUFhLEVBQUMsR0FBRyxJQUFJLENBQUE7UUFDNUIsTUFBTSx1QkFBdUIsR0FBRztZQUM5QixHQUFHLGFBQWEsQ0FBQyxVQUFVO1lBQzNCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QjtTQUNoQyxDQUFBO1FBQ0QsTUFBTSxJQUFJLEdBQUcsdUJBQXVCLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQTtRQUNqRCxNQUFNLElBQUksR0FBRyx1QkFBdUIsQ0FBQyxJQUFJLENBQUE7UUFFekMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBMkIsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUMxRCxNQUFNLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxFQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsSUFBSSxJQUFJLFNBQVMsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO1FBQ2hGLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLEVBQUMsYUFBYSxFQUFFLElBQUksRUFBRSx1QkFBdUIsRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFBO0lBQ3hGLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxFQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsdUJBQXVCLEVBQUUsSUFBSSxFQUFDO1FBQzlFLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxDQUFDO2dCQUN4QyxhQUFhLENBQUMsa0JBQWtCLENBQUMsNENBQTRDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUE7WUFDdEcsQ0FBQztZQUVELE1BQU0sYUFBYSxDQUFDLGFBQWEsQ0FBQyxFQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFBO1lBRXZELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO2dCQUN0QyxhQUFhO2dCQUNiLElBQUk7Z0JBQ0osU0FBUyxFQUFFLHVCQUF1QixDQUFDLFNBQVM7Z0JBQzVDLFVBQVUsRUFBRSx1QkFBdUIsQ0FBQyxVQUFVO2dCQUM5QyxJQUFJO2dCQUNKLE9BQU8sRUFBRSx1QkFBdUIsQ0FBQyxPQUFPO2FBQ3pDLENBQUMsQ0FBQTtZQUNGLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUE7WUFDMUQsYUFBYSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUE7WUFFbkQsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQy9CLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsTUFBTSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQTtZQUNsQyxhQUFhLENBQUMsbUJBQW1CLEdBQUcsU0FBUyxDQUFBO1lBRTdDLE1BQU0sS0FBSyxDQUFBO1FBQ2IsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLHFCQUFxQixDQUFDLEVBQUMsYUFBYSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUM7UUFDckQsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssYUFBYTtZQUFFLE9BQU07UUFFNUMsTUFBTSxjQUFjLEdBQUcsSUFBSSxjQUFjLENBQUMsRUFBQyxhQUFhLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBQyxDQUFDLENBQUE7UUFDdEUsTUFBTSxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDOUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUE7SUFDdEMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxnQkFBZ0IsQ0FBQyxFQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFDO1FBQzFFLE9BQU8sSUFBSSxVQUFVLENBQUMsRUFBQyxhQUFhLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBQyxDQUFDLENBQUE7SUFDcEYsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQUk7UUFDRixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVk7WUFBRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUV4RCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUE7SUFDMUIsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxLQUFLO1FBQ1QsTUFBTSxnQkFBZ0IsQ0FBQztZQUNyQixPQUFPLEVBQUUsMkNBQTJDO1lBQ3BELEtBQUssRUFBRTtnQkFDTCxLQUFLLElBQUksRUFBRSxDQUFDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUM7Z0JBQ3RELEtBQUssSUFBSSxFQUFFO29CQUNULElBQUksQ0FBQzt3QkFDSCxNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUE7b0JBQy9CLENBQUM7NEJBQVMsQ0FBQzt3QkFDVCxJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixHQUFHLFNBQVMsQ0FBQTtvQkFDcEQsQ0FBQztnQkFDSCxDQUFDO2dCQUNELEtBQUssSUFBSSxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRTtnQkFDL0MsS0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLEVBQUU7Z0JBQ3ZELEtBQUssSUFBSSxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLHdCQUF3QixFQUFFO2dCQUMvRCxLQUFLLElBQUksRUFBRSxDQUFDLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixFQUFFO2FBQy9DO1NBQ0YsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxxQkFBcUI7UUFDekIsTUFBTSxFQUFDLGNBQWMsRUFBQyxHQUFHLElBQUksQ0FBQTtRQUU3QixJQUFJLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQTtRQUMvQixJQUFJLGNBQWM7WUFBRSxNQUFNLGNBQWMsQ0FBQyxPQUFPLEVBQUUsQ0FBQTtJQUNwRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsaUJBQWlCLEdBQUcsR0FBRyxFQUFFO1FBQ3ZCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUE7UUFFdkMsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBQ3BCLENBQUM7SUFDSCxDQUFDLENBQUE7SUFFRDs7O09BR0c7SUFDSCxJQUFJO1FBQ0YsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzdCLElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFBO1FBQzVCLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBBcHBSb3V0ZXMgZnJvbSBcIi4vcm91dGVzL2FwcC1yb3V0ZXMuanNcIlxuaW1wb3J0IExvZ2dlciBmcm9tIFwiLi9sb2dnZXIuanNcIlxuaW1wb3J0IEh0dHBTZXJ2ZXIgZnJvbSBcIi4vaHR0cC1zZXJ2ZXIvaW5kZXguanNcIlxuaW1wb3J0IEh0dHBTZXJ2ZXJMb2NrIGZyb20gXCIuL2h0dHAtc2VydmVyL3NlcnZlci1sb2NrLmpzXCJcbmltcG9ydCBTeW5jQXBpQ29udHJvbGxlciBmcm9tIFwiLi9zeW5jL3N5bmMtYXBpLWNvbnRyb2xsZXIuanNcIlxuaW1wb3J0IFN5bmNQdWJsaXNoZXIgZnJvbSBcIi4vc3luYy9zeW5jLXB1Ymxpc2hlci5qc1wiXG5pbXBvcnQgU3luY1dlYnNvY2tldENoYW5uZWwgZnJvbSBcIi4vc3luYy9zeW5jLXdlYnNvY2tldC1jaGFubmVsLmpzXCJcbmltcG9ydCB3ZWJzb2NrZXRFdmVudHNIb3N0IGZyb20gXCIuL2h0dHAtc2VydmVyL3dlYnNvY2tldC1ldmVudHMtaG9zdC5qc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuaW1wb3J0IHsgcnVuU2h1dGRvd25TdGVwcyB9IGZyb20gXCIuL3V0aWxzL3NodXRkb3duLWxpZmVjeWNsZS5qc1wiXG5cbi8qKlxuICogSHR0cFNlcnZlckNvbmZpZ3VyYXRpb24gdHlwZS5cbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuSHR0cFNlcnZlckNvbmZpZ3VyYXRpb259IEh0dHBTZXJ2ZXJDb25maWd1cmF0aW9uICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0FwcGxpY2F0aW9uIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IGFyZ3MuY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7SHR0cFNlcnZlckNvbmZpZ3VyYXRpb259IFthcmdzLmh0dHBTZXJ2ZXJdIC0gSHR0cCBzZXJ2ZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnR5cGUgLSBUeXBlIGlkZW50aWZpZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgaHR0cFNlcnZlciwgdHlwZSwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcblxuICAgIGlmICghY29uZmlndXJhdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiY29uZmlndXJhdGlvbiBpcyByZXF1aXJlZFwiKVxuXG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuXG4gICAgLyoqXG4gICAgICogU3RvcmVzIHRoZSBodHRwIHNlcnZlciBjb25maWd1cmF0aW9uIHZhbHVlLlxuICAgICAqIEB0eXBlIHtIdHRwU2VydmVyQ29uZmlndXJhdGlvbn0gKi9cbiAgICB0aGlzLmh0dHBTZXJ2ZXJDb25maWd1cmF0aW9uID0gaHR0cFNlcnZlciA/PyB7fVxuXG4gICAgdGhpcy5sb2dnZXIgPSBuZXcgTG9nZ2VyKHRoaXMpXG4gICAgdGhpcy5fdHlwZSA9IHR5cGVcbiAgICAvKipcbiAgICAgKiBTdG9yZXMgdGhlIGh0dHAgc2VydmVyIGxvY2sgdmFsdWUuXG4gICAgICogQHR5cGUge0h0dHBTZXJ2ZXJMb2NrIHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuaHR0cFNlcnZlckxvY2sgPSB1bmRlZmluZWRcbiAgICAvKiogQHR5cGUge1Byb21pc2U8dm9pZD4gfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy5fc3RvcFByb21pc2UgPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCB0eXBlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSB0eXBlLlxuICAgKi9cbiAgZ2V0VHlwZSgpIHsgcmV0dXJuIHRoaXMuX3R5cGUgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGluaXRpYWxpemUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBpbml0aWFsaXplKCkge1xuICAgIGNvbnN0IHJvdXRlcyA9IGF3YWl0IEFwcFJvdXRlcy5nZXRSb3V0ZXModGhpcy5jb25maWd1cmF0aW9uKVxuXG4gICAgYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmluaXRpYWxpemUoe3R5cGU6IHRoaXMuZ2V0VHlwZSgpfSlcblxuICAgIFN5bmNBcGlDb250cm9sbGVyLm1vdW50RnJvbUNvbmZpZ3VyYXRpb24odGhpcy5jb25maWd1cmF0aW9uKVxuICAgIFN5bmNXZWJzb2NrZXRDaGFubmVsLnJlZ2lzdGVyRnJvbUNvbmZpZ3VyYXRpb24odGhpcy5jb25maWd1cmF0aW9uKVxuICAgIGF3YWl0IFN5bmNQdWJsaXNoZXIuc3RhcnRGcm9tQ29uZmlndXJhdGlvbih0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24uc2V0Um91dGVzKHJvdXRlcylcblxuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uLmlzRGF0YWJhc2VQb29sSW5pdGlhbGl6ZWQoKSkge1xuICAgICAgYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmluaXRpYWxpemVEYXRhYmFzZVBvb2woKVxuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaXMgYWN0aXZlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFjdGl2ZS5cbiAgICovXG4gIGlzQWN0aXZlKCkge1xuICAgIGlmICh0aGlzLmh0dHBTZXJ2ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmh0dHBTZXJ2ZXI/LmlzQWN0aXZlKClcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1bi5cbiAgICogQHBhcmFtIHsoKSA9PiB2b2lkfSBjYWxsYmFjayAtIENhbGxiYWNrIGZ1bmN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcnVuKGNhbGxiYWNrKSB7XG4gICAgYXdhaXQgdGhpcy5zdGFydEh0dHBTZXJ2ZXIoKVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNhbGxiYWNrKClcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgdGhpcy5zdG9wKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBzdGFydCBodHRwIHNlcnZlci5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHN0YXJ0SHR0cFNlcnZlcigpIHtcbiAgICBjb25zdCB7Y29uZmlndXJhdGlvbn0gPSB0aGlzXG4gICAgY29uc3QgaHR0cFNlcnZlckNvbmZpZ3VyYXRpb24gPSB7XG4gICAgICAuLi5jb25maWd1cmF0aW9uLmh0dHBTZXJ2ZXIsXG4gICAgICAuLi50aGlzLmh0dHBTZXJ2ZXJDb25maWd1cmF0aW9uXG4gICAgfVxuICAgIGNvbnN0IHBvcnQgPSBodHRwU2VydmVyQ29uZmlndXJhdGlvbi5wb3J0ID8/IDMwMDZcbiAgICBjb25zdCBob3N0ID0gaHR0cFNlcnZlckNvbmZpZ3VyYXRpb24uaG9zdFxuXG4gICAgYXdhaXQgdGhpcy5sb2dnZXIuZGVidWcoYFN0YXJ0aW5nIHNlcnZlciBvbiBwb3J0ICR7cG9ydH1gKVxuICAgIGF3YWl0IHRoaXMuYWNxdWlyZUh0dHBTZXJ2ZXJMb2NrKHtjb25maWd1cmF0aW9uLCBob3N0OiBob3N0ID8/IFwiMC4wLjAuMFwiLCBwb3J0fSlcbiAgICBhd2FpdCB0aGlzLnN0YXJ0TG9ja2VkSHR0cFNlcnZlcih7Y29uZmlndXJhdGlvbiwgaG9zdCwgaHR0cFNlcnZlckNvbmZpZ3VyYXRpb24sIHBvcnR9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3RhcnQgbG9ja2VkIGh0dHAgc2VydmVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEhUVFAgc2VydmVyIHN0YXJ0dXAgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuaG9zdF0gLSBIVFRQIHNlcnZlciBob3N0LlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gYXJncy5odHRwU2VydmVyQ29uZmlndXJhdGlvbiAtIE1lcmdlZCBIVFRQIHNlcnZlciBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYXJncy5wb3J0IC0gSFRUUCBzZXJ2ZXIgcG9ydC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgdGhlIEhUVFAgc2VydmVyIGhhcyBzdGFydGVkLlxuICAgKi9cbiAgYXN5bmMgc3RhcnRMb2NrZWRIdHRwU2VydmVyKHtjb25maWd1cmF0aW9uLCBob3N0LCBodHRwU2VydmVyQ29uZmlndXJhdGlvbiwgcG9ydH0pIHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFjb25maWd1cmF0aW9uLmdldFdlYnNvY2tldEV2ZW50cygpKSB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24uc2V0V2Vic29ja2V0RXZlbnRzKC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59ICovICh3ZWJzb2NrZXRFdmVudHNIb3N0KSlcbiAgICAgIH1cblxuICAgICAgYXdhaXQgY29uZmlndXJhdGlvbi5jb25uZWN0QmVhY29uKHtwZWVyVHlwZTogXCJzZXJ2ZXJcIn0pXG5cbiAgICAgIHRoaXMuaHR0cFNlcnZlciA9IHRoaXMuY3JlYXRlSHR0cFNlcnZlcih7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24sXG4gICAgICAgIGhvc3QsXG4gICAgICAgIGluUHJvY2VzczogaHR0cFNlcnZlckNvbmZpZ3VyYXRpb24uaW5Qcm9jZXNzLFxuICAgICAgICBtYXhXb3JrZXJzOiBodHRwU2VydmVyQ29uZmlndXJhdGlvbi5tYXhXb3JrZXJzLFxuICAgICAgICBwb3J0LFxuICAgICAgICB3b3JrZXJzOiBodHRwU2VydmVyQ29uZmlndXJhdGlvbi53b3JrZXJzXG4gICAgICB9KVxuICAgICAgdGhpcy5odHRwU2VydmVyLmV2ZW50cy5vbihcImNsb3NlXCIsIHRoaXMub25IdHRwU2VydmVyQ2xvc2UpXG4gICAgICBjb25maWd1cmF0aW9uLl9odHRwU2VydmVySW5zdGFuY2UgPSB0aGlzLmh0dHBTZXJ2ZXJcblxuICAgICAgYXdhaXQgdGhpcy5odHRwU2VydmVyLnN0YXJ0KClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5yZWxlYXNlSHR0cFNlcnZlckxvY2soKVxuICAgICAgY29uZmlndXJhdGlvbi5faHR0cFNlcnZlckluc3RhbmNlID0gdW5kZWZpbmVkXG5cbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYWNxdWlyZSBodHRwIHNlcnZlciBsb2NrLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIExvY2sgYWNxdWlzaXRpb24gYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5ob3N0IC0gSFRUUCBzZXJ2ZXIgaG9zdC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MucG9ydCAtIEhUVFAgc2VydmVyIHBvcnQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGFjcXVpcmluZyB0aGUgc2VydmVyIGxvY2sgd2hlbiBuZWVkZWQuXG4gICAqL1xuICBhc3luYyBhY3F1aXJlSHR0cFNlcnZlckxvY2soe2NvbmZpZ3VyYXRpb24sIGhvc3QsIHBvcnR9KSB7XG4gICAgaWYgKHRoaXMuZ2V0VHlwZSgpID09PSBcInRlc3QtcnVubmVyXCIpIHJldHVyblxuXG4gICAgY29uc3QgaHR0cFNlcnZlckxvY2sgPSBuZXcgSHR0cFNlcnZlckxvY2soe2NvbmZpZ3VyYXRpb24sIGhvc3QsIHBvcnR9KVxuICAgIGF3YWl0IGh0dHBTZXJ2ZXJMb2NrLmFjcXVpcmUoKVxuICAgIHRoaXMuaHR0cFNlcnZlckxvY2sgPSBodHRwU2VydmVyTG9ja1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3JlYXRlIGh0dHAgc2VydmVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEhUVFAgc2VydmVyIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFthcmdzLmhvc3RdIC0gSG9zdC5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5pblByb2Nlc3NdIC0gUnVuIEhUVFAgaGFuZGxlcnMgaW4gdGhlIG1haW4gdGhyZWFkLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MubWF4V29ya2Vyc10gLSBNYXggd29ya2Vycy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MucG9ydCAtIFBvcnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJncy53b3JrZXJzXSAtIFdvcmtlciBjb3VudC5cbiAgICogQHJldHVybnMge0h0dHBTZXJ2ZXJ9IC0gSFRUUCBzZXJ2ZXIgaW5zdGFuY2UuXG4gICAqL1xuICBjcmVhdGVIdHRwU2VydmVyKHtjb25maWd1cmF0aW9uLCBob3N0LCBpblByb2Nlc3MsIG1heFdvcmtlcnMsIHBvcnQsIHdvcmtlcnN9KSB7XG4gICAgcmV0dXJuIG5ldyBIdHRwU2VydmVyKHtjb25maWd1cmF0aW9uLCBob3N0LCBpblByb2Nlc3MsIG1heFdvcmtlcnMsIHBvcnQsIHdvcmtlcnN9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3RvcC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIHN0b3AoKSB7XG4gICAgaWYgKCF0aGlzLl9zdG9wUHJvbWlzZSkgdGhpcy5fc3RvcFByb21pc2UgPSB0aGlzLl9zdG9wKClcblxuICAgIHJldHVybiB0aGlzLl9zdG9wUHJvbWlzZVxuICB9XG5cbiAgLyoqXG4gICAqIFN0b3BzIGFwcGxpY2F0aW9uIGFuZCBmcmFtZXdvcmsgcmVzb3VyY2VzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBldmVyeSBhcHBsaWNhdGlvbiBhbmQgZnJhbWV3b3JrIGNsb3NlIHN1Y2NlZWRzLlxuICAgKi9cbiAgYXN5bmMgX3N0b3AoKSB7XG4gICAgYXdhaXQgcnVuU2h1dGRvd25TdGVwcyh7XG4gICAgICBtZXNzYWdlOiBcIkFwcGxpY2F0aW9uIGFuZCBmcmFtZXdvcmsgc2h1dGRvd24gZmFpbGVkXCIsXG4gICAgICBzdGVwczogW1xuICAgICAgICBhc3luYyAoKSA9PiBhd2FpdCB0aGlzLmxvZ2dlci5kZWJ1ZyhcIlN0b3BwaW5nIHNlcnZlclwiKSxcbiAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmh0dHBTZXJ2ZXI/LnN0b3AoKVxuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uX2h0dHBTZXJ2ZXJJbnN0YW5jZSA9IHVuZGVmaW5lZFxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLnNodXRkb3duKCksXG4gICAgICAgIGFzeW5jICgpID0+IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5kaXNjb25uZWN0QmVhY29uKCksXG4gICAgICAgIGFzeW5jICgpID0+IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5jbG9zZURhdGFiYXNlQ29ubmVjdGlvbnMoKSxcbiAgICAgICAgYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5yZWxlYXNlSHR0cFNlcnZlckxvY2soKVxuICAgICAgXVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyByZWxlYXNlIGh0dHAgc2VydmVyIGxvY2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIHRoZSBIVFRQIHNlcnZlciBsb2NrIGhhcyBiZWVuIHJlbGVhc2VkLlxuICAgKi9cbiAgYXN5bmMgcmVsZWFzZUh0dHBTZXJ2ZXJMb2NrKCkge1xuICAgIGNvbnN0IHtodHRwU2VydmVyTG9ja30gPSB0aGlzXG5cbiAgICB0aGlzLmh0dHBTZXJ2ZXJMb2NrID0gdW5kZWZpbmVkXG4gICAgaWYgKGh0dHBTZXJ2ZXJMb2NrKSBhd2FpdCBodHRwU2VydmVyTG9jay5yZWxlYXNlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBPbiBodHRwIHNlcnZlciBjbG9zZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgb25IdHRwU2VydmVyQ2xvc2UgPSAoKSA9PiB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXCJIVFRQIHNlcnZlciBjbG9zZWRcIilcblxuICAgIGlmICh0aGlzLndhaXRSZXNvbHZlKSB7XG4gICAgICB0aGlzLndhaXRSZXNvbHZlKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB3YWl0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgd2FpdCgpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIHRoaXMud2FpdFJlc29sdmUgPSByZXNvbHZlXG4gICAgfSlcbiAgfVxufVxuIl19
|
|
226
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBwbGljYXRpb24uanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sU0FBUyxNQUFNLHdCQUF3QixDQUFBO0FBQzlDLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQTtBQUNoQyxPQUFPLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQTtBQUMvQyxPQUFPLGNBQWMsTUFBTSw4QkFBOEIsQ0FBQTtBQUN6RCxPQUFPLGlCQUFpQixNQUFNLCtCQUErQixDQUFBO0FBQzdELE9BQU8sYUFBYSxNQUFNLDBCQUEwQixDQUFBO0FBQ3BELE9BQU8sb0JBQW9CLE1BQU0sa0NBQWtDLENBQUE7QUFDbkUsT0FBTyxtQkFBbUIsTUFBTSx3Q0FBd0MsQ0FBQTtBQUN4RSxPQUFPLGFBQWEsTUFBTSw0QkFBNEIsQ0FBQTtBQUN0RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQTtBQUVoRTs7bUdBRW1HO0FBRW5HLE1BQU0sQ0FBQyxPQUFPLE9BQU8sb0JBQW9CO0lBQ3ZDOzs7Ozs7T0FNRztJQUNILFlBQVksRUFBQyxhQUFhLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxHQUFHLFFBQVEsRUFBQztRQUN4RCxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUE7UUFFdkIsSUFBSSxDQUFDLGFBQWE7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUE7UUFFaEUsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUE7UUFFbEM7OzZDQUVxQztRQUNyQyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsVUFBVSxJQUFJLEVBQUUsQ0FBQTtRQUUvQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzlCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFBO1FBQ2pCOztnREFFd0M7UUFDeEMsSUFB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RTtnQkFDL0QsS0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLElBQUksQ0FBQyxxQkFBcUIsRUFBRTthQUMvQztTQUNGLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMscUJBQXFCO1FBQ3pCLE1BQU0sRUFBQyxjQUFjLEVBQUMsR0FBRyxJQUFJLENBQUE7UUFFN0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUE7UUFDL0IsSUFBSSxjQUFjO1lBQUUsTUFBTSxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUE7SUFDcEQsQ0FBQztJQUVEOzs7T0FHRztJQUNILGlCQUFpQixHQUFHLEdBQUcsRUFBRTtRQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFBO1FBRXZDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtRQUNwQixDQUFDO0lBQ0gsQ0FBQyxDQUFBO0lBRUQ7OztPQUdHO0lBQ0gsSUFBSTtRQUNGLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM3QixJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQTtRQUM1QixDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgQXBwUm91dGVzIGZyb20gXCIuL3JvdXRlcy9hcHAtcm91dGVzLmpzXCJcbmltcG9ydCBMb2dnZXIgZnJvbSBcIi4vbG9nZ2VyLmpzXCJcbmltcG9ydCBIdHRwU2VydmVyIGZyb20gXCIuL2h0dHAtc2VydmVyL2luZGV4LmpzXCJcbmltcG9ydCBIdHRwU2VydmVyTG9jayBmcm9tIFwiLi9odHRwLXNlcnZlci9zZXJ2ZXItbG9jay5qc1wiXG5pbXBvcnQgU3luY0FwaUNvbnRyb2xsZXIgZnJvbSBcIi4vc3luYy9zeW5jLWFwaS1jb250cm9sbGVyLmpzXCJcbmltcG9ydCBTeW5jUHVibGlzaGVyIGZyb20gXCIuL3N5bmMvc3luYy1wdWJsaXNoZXIuanNcIlxuaW1wb3J0IFN5bmNXZWJzb2NrZXRDaGFubmVsIGZyb20gXCIuL3N5bmMvc3luYy13ZWJzb2NrZXQtY2hhbm5lbC5qc1wiXG5pbXBvcnQgd2Vic29ja2V0RXZlbnRzSG9zdCBmcm9tIFwiLi9odHRwLXNlcnZlci93ZWJzb2NrZXQtZXZlbnRzLWhvc3QuanNcIlxuaW1wb3J0IHJlc3RBcmdzRXJyb3IgZnJvbSBcIi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcbmltcG9ydCB7IHJ1blNodXRkb3duU3RlcHMgfSBmcm9tIFwiLi91dGlscy9zaHV0ZG93bi1saWZlY3ljbGUuanNcIlxuXG4vKipcbiAqIEh0dHBTZXJ2ZXJDb25maWd1cmF0aW9uIHR5cGUuXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkh0dHBTZXJ2ZXJDb25maWd1cmF0aW9ufSBIdHRwU2VydmVyQ29uZmlndXJhdGlvbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNBcHBsaWNhdGlvbiB7XG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge0h0dHBTZXJ2ZXJDb25maWd1cmF0aW9ufSBbYXJncy5odHRwU2VydmVyXSAtIEh0dHAgc2VydmVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy50eXBlIC0gVHlwZSBpZGVudGlmaWVyLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb24sIGh0dHBTZXJ2ZXIsIHR5cGUsIC4uLnJlc3RBcmdzfSkge1xuICAgIHJlc3RBcmdzRXJyb3IocmVzdEFyZ3MpXG5cbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHRocm93IG5ldyBFcnJvcihcImNvbmZpZ3VyYXRpb24gaXMgcmVxdWlyZWRcIilcblxuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb25cblxuICAgIC8qKlxuICAgICAqIFN0b3JlcyB0aGUgaHR0cCBzZXJ2ZXIgY29uZmlndXJhdGlvbiB2YWx1ZS5cbiAgICAgKiBAdHlwZSB7SHR0cFNlcnZlckNvbmZpZ3VyYXRpb259ICovXG4gICAgdGhpcy5odHRwU2VydmVyQ29uZmlndXJhdGlvbiA9IGh0dHBTZXJ2ZXIgPz8ge31cblxuICAgIHRoaXMubG9nZ2VyID0gbmV3IExvZ2dlcih0aGlzKVxuICAgIHRoaXMuX3R5cGUgPSB0eXBlXG4gICAgLyoqXG4gICAgICogU3RvcmVzIHRoZSBodHRwIHNlcnZlciBsb2NrIHZhbHVlLlxuICAgICAqIEB0eXBlIHtIdHRwU2VydmVyTG9jayB8IHVuZGVmaW5lZH0gKi9cbiAgICB0aGlzLmh0dHBTZXJ2ZXJMb2NrID0gdW5kZWZpbmVkXG4gICAgLyoqIEB0eXBlIHtQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkfSAqL1xuICAgIHRoaXMuX3N0b3BQcm9taXNlID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgdHlwZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBUaGUgdHlwZS5cbiAgICovXG4gIGdldFR5cGUoKSB7IHJldHVybiB0aGlzLl90eXBlIH1cblxuICAvKipcbiAgICogUnVucyBpbml0aWFsaXplLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgaW5pdGlhbGl6ZSgpIHtcbiAgICBjb25zdCByb3V0ZXMgPSBhd2FpdCBBcHBSb3V0ZXMuZ2V0Um91dGVzKHRoaXMuY29uZmlndXJhdGlvbilcblxuICAgIGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5pbml0aWFsaXplKHt0eXBlOiB0aGlzLmdldFR5cGUoKX0pXG5cbiAgICBTeW5jQXBpQ29udHJvbGxlci5tb3VudEZyb21Db25maWd1cmF0aW9uKHRoaXMuY29uZmlndXJhdGlvbilcbiAgICBTeW5jV2Vic29ja2V0Q2hhbm5lbC5yZWdpc3RlckZyb21Db25maWd1cmF0aW9uKHRoaXMuY29uZmlndXJhdGlvbilcbiAgICBhd2FpdCBTeW5jUHVibGlzaGVyLnN0YXJ0RnJvbUNvbmZpZ3VyYXRpb24odGhpcy5jb25maWd1cmF0aW9uKVxuXG4gICAgdGhpcy5jb25maWd1cmF0aW9uLnNldFJvdXRlcyhyb3V0ZXMpXG5cbiAgICBpZiAodGhpcy5jb25maWd1cmF0aW9uLmRhdGFiYXNlICE9PSBmYWxzZSAmJiAhdGhpcy5jb25maWd1cmF0aW9uLmlzRGF0YWJhc2VQb29sSW5pdGlhbGl6ZWQoKSkge1xuICAgICAgYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmluaXRpYWxpemVEYXRhYmFzZVBvb2woKVxuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaXMgYWN0aXZlLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGFjdGl2ZS5cbiAgICovXG4gIGlzQWN0aXZlKCkge1xuICAgIGlmICh0aGlzLmh0dHBTZXJ2ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmh0dHBTZXJ2ZXI/LmlzQWN0aXZlKClcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1bi5cbiAgICogQHBhcmFtIHsoKSA9PiB2b2lkfSBjYWxsYmFjayAtIENhbGxiYWNrIGZ1bmN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcnVuKGNhbGxiYWNrKSB7XG4gICAgYXdhaXQgdGhpcy5zdGFydEh0dHBTZXJ2ZXIoKVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNhbGxiYWNrKClcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgdGhpcy5zdG9wKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBzdGFydCBodHRwIHNlcnZlci5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHN0YXJ0SHR0cFNlcnZlcigpIHtcbiAgICBjb25zdCB7Y29uZmlndXJhdGlvbn0gPSB0aGlzXG4gICAgY29uc3QgaHR0cFNlcnZlckNvbmZpZ3VyYXRpb24gPSB7XG4gICAgICAuLi5jb25maWd1cmF0aW9uLmh0dHBTZXJ2ZXIsXG4gICAgICAuLi50aGlzLmh0dHBTZXJ2ZXJDb25maWd1cmF0aW9uXG4gICAgfVxuICAgIGNvbnN0IHBvcnQgPSBodHRwU2VydmVyQ29uZmlndXJhdGlvbi5wb3J0ID8/IDMwMDZcbiAgICBjb25zdCBob3N0ID0gaHR0cFNlcnZlckNvbmZpZ3VyYXRpb24uaG9zdFxuXG4gICAgYXdhaXQgdGhpcy5sb2dnZXIuZGVidWcoYFN0YXJ0aW5nIHNlcnZlciBvbiBwb3J0ICR7cG9ydH1gKVxuICAgIGF3YWl0IHRoaXMuYWNxdWlyZUh0dHBTZXJ2ZXJMb2NrKHtjb25maWd1cmF0aW9uLCBob3N0OiBob3N0ID8/IFwiMC4wLjAuMFwiLCBwb3J0fSlcbiAgICBhd2FpdCB0aGlzLnN0YXJ0TG9ja2VkSHR0cFNlcnZlcih7Y29uZmlndXJhdGlvbiwgaG9zdCwgaHR0cFNlcnZlckNvbmZpZ3VyYXRpb24sIHBvcnR9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3RhcnQgbG9ja2VkIGh0dHAgc2VydmVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEhUVFAgc2VydmVyIHN0YXJ0dXAgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuaG9zdF0gLSBIVFRQIHNlcnZlciBob3N0LlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gYXJncy5odHRwU2VydmVyQ29uZmlndXJhdGlvbiAtIE1lcmdlZCBIVFRQIHNlcnZlciBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge251bWJlcn0gYXJncy5wb3J0IC0gSFRUUCBzZXJ2ZXIgcG9ydC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgdGhlIEhUVFAgc2VydmVyIGhhcyBzdGFydGVkLlxuICAgKi9cbiAgYXN5bmMgc3RhcnRMb2NrZWRIdHRwU2VydmVyKHtjb25maWd1cmF0aW9uLCBob3N0LCBodHRwU2VydmVyQ29uZmlndXJhdGlvbiwgcG9ydH0pIHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFjb25maWd1cmF0aW9uLmdldFdlYnNvY2tldEV2ZW50cygpKSB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24uc2V0V2Vic29ja2V0RXZlbnRzKC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59ICovICh3ZWJzb2NrZXRFdmVudHNIb3N0KSlcbiAgICAgIH1cblxuICAgICAgYXdhaXQgY29uZmlndXJhdGlvbi5jb25uZWN0QmVhY29uKHtwZWVyVHlwZTogXCJzZXJ2ZXJcIn0pXG5cbiAgICAgIHRoaXMuaHR0cFNlcnZlciA9IHRoaXMuY3JlYXRlSHR0cFNlcnZlcih7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24sXG4gICAgICAgIGhvc3QsXG4gICAgICAgIGluUHJvY2VzczogaHR0cFNlcnZlckNvbmZpZ3VyYXRpb24uaW5Qcm9jZXNzLFxuICAgICAgICBtYXhXb3JrZXJzOiBodHRwU2VydmVyQ29uZmlndXJhdGlvbi5tYXhXb3JrZXJzLFxuICAgICAgICBwb3J0LFxuICAgICAgICB3b3JrZXJzOiBodHRwU2VydmVyQ29uZmlndXJhdGlvbi53b3JrZXJzXG4gICAgICB9KVxuICAgICAgdGhpcy5odHRwU2VydmVyLmV2ZW50cy5vbihcImNsb3NlXCIsIHRoaXMub25IdHRwU2VydmVyQ2xvc2UpXG4gICAgICBjb25maWd1cmF0aW9uLl9odHRwU2VydmVySW5zdGFuY2UgPSB0aGlzLmh0dHBTZXJ2ZXJcblxuICAgICAgYXdhaXQgdGhpcy5odHRwU2VydmVyLnN0YXJ0KClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5yZWxlYXNlSHR0cFNlcnZlckxvY2soKVxuICAgICAgY29uZmlndXJhdGlvbi5faHR0cFNlcnZlckluc3RhbmNlID0gdW5kZWZpbmVkXG5cbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYWNxdWlyZSBodHRwIHNlcnZlciBsb2NrLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIExvY2sgYWNxdWlzaXRpb24gYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5ob3N0IC0gSFRUUCBzZXJ2ZXIgaG9zdC5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MucG9ydCAtIEhUVFAgc2VydmVyIHBvcnQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIGFjcXVpcmluZyB0aGUgc2VydmVyIGxvY2sgd2hlbiBuZWVkZWQuXG4gICAqL1xuICBhc3luYyBhY3F1aXJlSHR0cFNlcnZlckxvY2soe2NvbmZpZ3VyYXRpb24sIGhvc3QsIHBvcnR9KSB7XG4gICAgaWYgKHRoaXMuZ2V0VHlwZSgpID09PSBcInRlc3QtcnVubmVyXCIpIHJldHVyblxuXG4gICAgY29uc3QgaHR0cFNlcnZlckxvY2sgPSBuZXcgSHR0cFNlcnZlckxvY2soe2NvbmZpZ3VyYXRpb24sIGhvc3QsIHBvcnR9KVxuICAgIGF3YWl0IGh0dHBTZXJ2ZXJMb2NrLmFjcXVpcmUoKVxuICAgIHRoaXMuaHR0cFNlcnZlckxvY2sgPSBodHRwU2VydmVyTG9ja1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3JlYXRlIGh0dHAgc2VydmVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEhUVFAgc2VydmVyIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFthcmdzLmhvc3RdIC0gSG9zdC5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5pblByb2Nlc3NdIC0gUnVuIEhUVFAgaGFuZGxlcnMgaW4gdGhlIG1haW4gdGhyZWFkLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2FyZ3MubWF4V29ya2Vyc10gLSBNYXggd29ya2Vycy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MucG9ydCAtIFBvcnQuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbYXJncy53b3JrZXJzXSAtIFdvcmtlciBjb3VudC5cbiAgICogQHJldHVybnMge0h0dHBTZXJ2ZXJ9IC0gSFRUUCBzZXJ2ZXIgaW5zdGFuY2UuXG4gICAqL1xuICBjcmVhdGVIdHRwU2VydmVyKHtjb25maWd1cmF0aW9uLCBob3N0LCBpblByb2Nlc3MsIG1heFdvcmtlcnMsIHBvcnQsIHdvcmtlcnN9KSB7XG4gICAgcmV0dXJuIG5ldyBIdHRwU2VydmVyKHtjb25maWd1cmF0aW9uLCBob3N0LCBpblByb2Nlc3MsIG1heFdvcmtlcnMsIHBvcnQsIHdvcmtlcnN9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3RvcC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIHN0b3AoKSB7XG4gICAgaWYgKCF0aGlzLl9zdG9wUHJvbWlzZSkgdGhpcy5fc3RvcFByb21pc2UgPSB0aGlzLl9zdG9wKClcblxuICAgIHJldHVybiB0aGlzLl9zdG9wUHJvbWlzZVxuICB9XG5cbiAgLyoqXG4gICAqIFN0b3BzIGFwcGxpY2F0aW9uIGFuZCBmcmFtZXdvcmsgcmVzb3VyY2VzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciBldmVyeSBhcHBsaWNhdGlvbiBhbmQgZnJhbWV3b3JrIGNsb3NlIHN1Y2NlZWRzLlxuICAgKi9cbiAgYXN5bmMgX3N0b3AoKSB7XG4gICAgYXdhaXQgcnVuU2h1dGRvd25TdGVwcyh7XG4gICAgICBtZXNzYWdlOiBcIkFwcGxpY2F0aW9uIGFuZCBmcmFtZXdvcmsgc2h1dGRvd24gZmFpbGVkXCIsXG4gICAgICBzdGVwczogW1xuICAgICAgICBhc3luYyAoKSA9PiBhd2FpdCB0aGlzLmxvZ2dlci5kZWJ1ZyhcIlN0b3BwaW5nIHNlcnZlclwiKSxcbiAgICAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmh0dHBTZXJ2ZXI/LnN0b3AoKVxuICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uX2h0dHBTZXJ2ZXJJbnN0YW5jZSA9IHVuZGVmaW5lZFxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLnNodXRkb3duKCksXG4gICAgICAgIGFzeW5jICgpID0+IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5kaXNjb25uZWN0QmVhY29uKCksXG4gICAgICAgIGFzeW5jICgpID0+IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5jbG9zZURhdGFiYXNlQ29ubmVjdGlvbnMoKSxcbiAgICAgICAgYXN5bmMgKCkgPT4gYXdhaXQgdGhpcy5yZWxlYXNlSHR0cFNlcnZlckxvY2soKVxuICAgICAgXVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyByZWxlYXNlIGh0dHAgc2VydmVyIGxvY2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIGFmdGVyIHRoZSBIVFRQIHNlcnZlciBsb2NrIGhhcyBiZWVuIHJlbGVhc2VkLlxuICAgKi9cbiAgYXN5bmMgcmVsZWFzZUh0dHBTZXJ2ZXJMb2NrKCkge1xuICAgIGNvbnN0IHtodHRwU2VydmVyTG9ja30gPSB0aGlzXG5cbiAgICB0aGlzLmh0dHBTZXJ2ZXJMb2NrID0gdW5kZWZpbmVkXG4gICAgaWYgKGh0dHBTZXJ2ZXJMb2NrKSBhd2FpdCBodHRwU2VydmVyTG9jay5yZWxlYXNlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBPbiBodHRwIHNlcnZlciBjbG9zZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgb25IdHRwU2VydmVyQ2xvc2UgPSAoKSA9PiB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXCJIVFRQIHNlcnZlciBjbG9zZWRcIilcblxuICAgIGlmICh0aGlzLndhaXRSZXNvbHZlKSB7XG4gICAgICB0aGlzLndhaXRSZXNvbHZlKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyB3YWl0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgd2FpdCgpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIHRoaXMud2FpdFJlc29sdmUgPSByZXNvbHZlXG4gICAgfSlcbiAgfVxufVxuIl19
|
|
@@ -600,6 +600,14 @@ export type HttpServerConfiguration = {
|
|
|
600
600
|
* - Run HTTP handlers in the main thread instead of worker threads.
|
|
601
601
|
*/
|
|
602
602
|
inProcess?: boolean;
|
|
603
|
+
/**
|
|
604
|
+
* - Maximum UTF-8/binary byte length accepted by buffered response bodies. Unbounded when absent; streamed file responses are unaffected.
|
|
605
|
+
*/
|
|
606
|
+
maxBufferedResponseBodyBytes?: number;
|
|
607
|
+
/**
|
|
608
|
+
* - Maximum decoded request-body bytes accepted before routing. Unbounded when absent.
|
|
609
|
+
*/
|
|
610
|
+
maxRequestBodyBytes?: number;
|
|
603
611
|
/**
|
|
604
612
|
* - Backward-compatible alias for workers.
|
|
605
613
|
*/
|
|
@@ -1547,9 +1555,9 @@ export type ConfigurationArgsType = {
|
|
|
1547
1555
|
*/
|
|
1548
1556
|
packages?: VelociousPackageConfiguration[];
|
|
1549
1557
|
/**
|
|
1550
|
-
* - Database configurations keyed by environment and identifier.
|
|
1558
|
+
* - Database configurations keyed by environment and identifier, or false for an explicitly database-free application.
|
|
1551
1559
|
*/
|
|
1552
|
-
database
|
|
1560
|
+
database?: false | {
|
|
1553
1561
|
[key: string]: {
|
|
1554
1562
|
[key: string]: DatabaseConfigurationType;
|
|
1555
1563
|
};
|
|
@@ -1965,6 +1973,8 @@ export type ConfigurationArgsType = {
|
|
|
1965
1973
|
* @property {boolean | HttpCompressionConfiguration} [compression] - Buffered response compression. Enabled with documented defaults when absent; false or {enabled: false} disables it globally.
|
|
1966
1974
|
* @property {string} [host] - Hostname to bind the HTTP server to.
|
|
1967
1975
|
* @property {boolean} [inProcess] - Run HTTP handlers in the main thread instead of worker threads.
|
|
1976
|
+
* @property {number} [maxBufferedResponseBodyBytes] - Maximum UTF-8/binary byte length accepted by buffered response bodies. Unbounded when absent; streamed file responses are unaffected.
|
|
1977
|
+
* @property {number} [maxRequestBodyBytes] - Maximum decoded request-body bytes accepted before routing. Unbounded when absent.
|
|
1968
1978
|
* @property {number} [maxWorkers] - Backward-compatible alias for workers.
|
|
1969
1979
|
* @property {number} [port] - Port to bind the HTTP server to.
|
|
1970
1980
|
* @property {{maxPendingBytes?: number, maxPendingMessages?: number}} [websocketInboundQueue] - Per-session retained inbound WebSocket message limits.
|
|
@@ -2351,7 +2361,7 @@ export type ConfigurationArgsType = {
|
|
|
2351
2361
|
* @property {AttachmentsConfiguration} [attachments] - Attachment storage configuration.
|
|
2352
2362
|
* @property {BackendProjectConfiguration[]} [backendProjects] - Backend project definitions used for frontend model generation.
|
|
2353
2363
|
* @property {VelociousPackageConfiguration[]} [packages] - External Velocious packages that contribute models, frontend-model resources and migrations.
|
|
2354
|
-
* @property {{[key: string]: {[key: string]: DatabaseConfigurationType}}} database - Database configurations keyed by environment and identifier.
|
|
2364
|
+
* @property {false | {[key: string]: {[key: string]: DatabaseConfigurationType}}} [database] - Database configurations keyed by environment and identifier, or false for an explicitly database-free application.
|
|
2355
2365
|
* @property {boolean} [debug] - Enable debug logging.
|
|
2356
2366
|
* @property {boolean | DebugEndpointConfiguration} [debugEndpoint] - Enable the built-in debug endpoint. Defaults to false.
|
|
2357
2367
|
* @property {boolean | ApiManifestConfiguration} [apiManifest] - Enable the built-in API manifest endpoint. Defaults to false.
|