@suveren/gateway 0.7.6 → 0.8.1
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/content/integrations/deploy-github.json +10 -1
- package/content/integrations/mollie.json +103 -28
- package/dist/mcp-server/http.mjs +510 -132
- package/dist/ui/assets/{index-CsrM6RQr.js → index-BFnSVa9N.js} +22 -22
- package/dist/ui/index.html +1 -1
- package/node_modules/@hap/core/dist/index.d.mts +29 -6
- package/node_modules/@hap/core/dist/index.d.ts +29 -6
- package/node_modules/@hap/core/dist/index.js +54 -8
- package/node_modules/@hap/core/dist/index.mjs +53 -8
- package/node_modules/@hap/core/package.json +2 -1
- package/node_modules/@hap/core/src/frame.ts +115 -14
- package/node_modules/@hap/core/src/gatekeeper.ts +26 -0
- package/node_modules/@hap/core/src/types.ts +7 -1
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/buffer.buffer.d.ts +5 -0
- package/node_modules/@types/node/crypto.d.ts +0 -2
- package/node_modules/@types/node/dgram.d.ts +119 -4
- package/node_modules/@types/node/ffi.d.ts +1 -1
- package/node_modules/@types/node/fs/promises.d.ts +61 -65
- package/node_modules/@types/node/fs.d.ts +86 -76
- package/node_modules/@types/node/http.d.ts +1 -1
- package/node_modules/@types/node/http2.d.ts +2 -2
- package/node_modules/@types/node/index.d.ts +1 -0
- package/node_modules/@types/node/inspector.d.ts +2 -1
- package/node_modules/@types/node/net.d.ts +108 -16
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/quic.d.ts +37 -11
- package/node_modules/@types/node/stream/iter.d.ts +4 -4
- package/node_modules/@types/node/tls.d.ts +24 -0
- package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +5 -0
- package/node_modules/@types/node/ts5.6/index.d.ts +1 -0
- package/node_modules/@types/node/ts5.7/index.d.ts +1 -0
- package/node_modules/@types/node/tty.d.ts +4 -3
- package/node_modules/@types/node/vfs.d.ts +210 -0
- package/node_modules/@types/node/vm.d.ts +1 -1
- package/node_modules/express-rate-limit/dist/index.cjs +6 -3
- package/node_modules/express-rate-limit/dist/index.d.cts +11 -0
- package/node_modules/express-rate-limit/dist/index.d.mts +11 -0
- package/node_modules/express-rate-limit/dist/index.d.ts +11 -0
- package/node_modules/express-rate-limit/dist/index.mjs +6 -3
- package/node_modules/express-rate-limit/{license.md → license} +7 -6
- package/node_modules/express-rate-limit/package.json +5 -5
- package/node_modules/express-rate-limit/readme.md +1 -0
- package/node_modules/fast-uri/index.js +20 -5
- package/node_modules/fast-uri/lib/utils.js +8 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/component-safe-serialization.test.js +58 -0
- package/node_modules/fast-uri/test/ipv6-validation.test.js +34 -0
- package/node_modules/hono/dist/cjs/client/client.js +4 -4
- package/node_modules/hono/dist/cjs/hono-base.js +7 -6
- package/node_modules/hono/dist/cjs/jsx/base.js +18 -1
- package/node_modules/hono/dist/cjs/jsx/components.js +25 -26
- package/node_modules/hono/dist/cjs/jsx/context.js +5 -5
- package/node_modules/hono/dist/cjs/jsx/dom/server.js +5 -1
- package/node_modules/hono/dist/cjs/jsx/intrinsic-element/components.js +2 -2
- package/node_modules/hono/dist/cjs/jsx/streaming.js +4 -5
- package/node_modules/hono/dist/client/client.js +4 -4
- package/node_modules/hono/dist/hono-base.js +7 -6
- package/node_modules/hono/dist/jsx/base.js +15 -1
- package/node_modules/hono/dist/jsx/components.js +26 -27
- package/node_modules/hono/dist/jsx/context.js +6 -6
- package/node_modules/hono/dist/jsx/dom/server.js +5 -1
- package/node_modules/hono/dist/jsx/intrinsic-element/components.js +3 -3
- package/node_modules/hono/dist/jsx/streaming.js +5 -6
- package/node_modules/hono/dist/types/context.d.ts +2 -2
- package/node_modules/hono/dist/types/jsx/base.d.ts +3 -0
- package/node_modules/hono/package.json +2 -2
- package/node_modules/ip-address/README.md +92 -82
- package/node_modules/ip-address/dist/common.d.ts +20 -0
- package/node_modules/ip-address/dist/common.js +36 -0
- package/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +50 -0
- package/node_modules/ip-address/dist/ipv4.js +75 -0
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +79 -10
- package/node_modules/ip-address/dist/ipv6.js +120 -30
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/dist/v4/constants.d.ts +12 -0
- package/node_modules/ip-address/dist/v4/constants.js +40 -1
- package/node_modules/ip-address/dist/v4/constants.js.map +1 -1
- package/node_modules/ip-address/dist/v6/constants.d.ts +14 -0
- package/node_modules/ip-address/dist/v6/constants.js +47 -1
- package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/ip-address/package.json +1 -1
- package/node_modules/jose/dist/types/jwe/compact/decrypt.d.ts +7 -16
- package/node_modules/jose/dist/types/jwe/compact/encrypt.d.ts +6 -17
- package/node_modules/jose/dist/types/jwe/flattened/decrypt.d.ts +7 -16
- package/node_modules/jose/dist/types/jwe/flattened/encrypt.d.ts +11 -34
- package/node_modules/jose/dist/types/jwe/general/decrypt.d.ts +7 -16
- package/node_modules/jose/dist/types/jwe/general/encrypt.d.ts +15 -35
- package/node_modules/jose/dist/types/jwk/embedded.d.ts +3 -8
- package/node_modules/jose/dist/types/jwk/thumbprint.d.ts +5 -5
- package/node_modules/jose/dist/types/jwks/local.d.ts +6 -10
- package/node_modules/jose/dist/types/jwks/remote.d.ts +13 -24
- package/node_modules/jose/dist/types/jws/compact/sign.d.ts +5 -10
- package/node_modules/jose/dist/types/jws/compact/verify.d.ts +9 -18
- package/node_modules/jose/dist/types/jws/flattened/sign.d.ts +7 -16
- package/node_modules/jose/dist/types/jws/flattened/verify.d.ts +9 -18
- package/node_modules/jose/dist/types/jws/general/sign.d.ts +11 -21
- package/node_modules/jose/dist/types/jws/general/verify.d.ts +9 -18
- package/node_modules/jose/dist/types/jwt/decrypt.d.ts +10 -20
- package/node_modules/jose/dist/types/jwt/encrypt.d.ts +6 -13
- package/node_modules/jose/dist/types/jwt/sign.d.ts +5 -6
- package/node_modules/jose/dist/types/jwt/unsecured.d.ts +9 -14
- package/node_modules/jose/dist/types/jwt/verify.d.ts +9 -19
- package/node_modules/jose/dist/types/key/export.d.ts +4 -4
- package/node_modules/jose/dist/types/key/generate_key_pair.d.ts +6 -8
- package/node_modules/jose/dist/types/key/generate_secret.d.ts +4 -11
- package/node_modules/jose/dist/types/key/import.d.ts +10 -17
- package/node_modules/jose/dist/types/types.d.ts +44 -84
- package/node_modules/jose/dist/types/util/base64url.d.ts +2 -2
- package/node_modules/jose/dist/types/util/decode_jwt.d.ts +3 -10
- package/node_modules/jose/dist/types/util/decode_protected_header.d.ts +4 -4
- package/node_modules/jose/dist/types/util/errors.d.ts +26 -53
- package/node_modules/jose/dist/webapi/index.js +70 -32
- package/node_modules/jose/dist/webapi/jwe/compact/decrypt.js +7 -8
- package/node_modules/jose/dist/webapi/jwe/compact/encrypt.js +42 -48
- package/node_modules/jose/dist/webapi/jwe/flattened/decrypt.js +14 -14
- package/node_modules/jose/dist/webapi/jwe/flattened/encrypt.js +53 -64
- package/node_modules/jose/dist/webapi/jwe/general/decrypt.js +38 -49
- package/node_modules/jose/dist/webapi/jwe/general/encrypt.js +121 -169
- package/node_modules/jose/dist/webapi/jwk/embedded.js +30 -32
- package/node_modules/jose/dist/webapi/jwk/thumbprint.js +54 -70
- package/node_modules/jose/dist/webapi/jwks/local.js +47 -64
- package/node_modules/jose/dist/webapi/jwks/remote.js +88 -136
- package/node_modules/jose/dist/webapi/jws/compact/sign.js +21 -21
- package/node_modules/jose/dist/webapi/jws/compact/verify.js +7 -8
- package/node_modules/jose/dist/webapi/jws/flattened/sign.js +29 -31
- package/node_modules/jose/dist/webapi/jws/flattened/verify.js +21 -24
- package/node_modules/jose/dist/webapi/jws/general/sign.js +61 -72
- package/node_modules/jose/dist/webapi/jws/general/verify.js +45 -69
- package/node_modules/jose/dist/webapi/jwt/decrypt.js +13 -20
- package/node_modules/jose/dist/webapi/jwt/encrypt.js +57 -70
- package/node_modules/jose/dist/webapi/jwt/sign.js +17 -16
- package/node_modules/jose/dist/webapi/jwt/unsecured.js +32 -40
- package/node_modules/jose/dist/webapi/jwt/verify.js +12 -14
- package/node_modules/jose/dist/webapi/key/export.js +32 -37
- package/node_modules/jose/dist/webapi/key/generate_key_pair.js +40 -48
- package/node_modules/jose/dist/webapi/key/generate_secret.js +35 -40
- package/node_modules/jose/dist/webapi/key/import.js +52 -56
- package/node_modules/jose/dist/webapi/lib/asn1.js +130 -169
- package/node_modules/jose/dist/webapi/lib/base64.js +18 -20
- package/node_modules/jose/dist/webapi/lib/buffer_utils.js +34 -38
- package/node_modules/jose/dist/webapi/lib/content_encryption.js +79 -115
- package/node_modules/jose/dist/webapi/lib/crypto_key.js +24 -25
- package/node_modules/jose/dist/webapi/lib/deflate.js +45 -47
- package/node_modules/jose/dist/webapi/lib/helpers.js +40 -37
- package/node_modules/jose/dist/webapi/lib/invalid_key_input.js +10 -24
- package/node_modules/jose/dist/webapi/lib/is_key_like.js +17 -15
- package/node_modules/jose/dist/webapi/lib/jwe_algorithms.js +106 -93
- package/node_modules/jose/dist/webapi/lib/jwe_decrypt.js +207 -230
- package/node_modules/jose/dist/webapi/lib/jwe_encrypt.js +104 -138
- package/node_modules/jose/dist/webapi/lib/jwk_metadata.js +17 -18
- package/node_modules/jose/dist/webapi/lib/jwk_to_key.js +9 -16
- package/node_modules/jose/dist/webapi/lib/jws_algorithms.js +62 -61
- package/node_modules/jose/dist/webapi/lib/jws_sign.js +50 -75
- package/node_modules/jose/dist/webapi/lib/jws_verify.js +80 -125
- package/node_modules/jose/dist/webapi/lib/jwt_claims_set.js +123 -209
- package/node_modules/jose/dist/webapi/lib/key.js +84 -136
- package/node_modules/jose/dist/webapi/lib/key_algorithm.js +13 -8
- package/node_modules/jose/dist/webapi/lib/key_descriptor.js +8 -6
- package/node_modules/jose/dist/webapi/lib/key_management.js +200 -231
- package/node_modules/jose/dist/webapi/lib/key_options.js +7 -5
- package/node_modules/jose/dist/webapi/lib/options.js +55 -68
- package/node_modules/jose/dist/webapi/lib/signing.js +18 -22
- package/node_modules/jose/dist/webapi/lib/type_checks.js +26 -29
- package/node_modules/jose/dist/webapi/util/base64url.js +26 -35
- package/node_modules/jose/dist/webapi/util/decode_jwt.js +32 -31
- package/node_modules/jose/dist/webapi/util/decode_protected_header.js +18 -23
- package/node_modules/jose/dist/webapi/util/errors.js +94 -84
- package/node_modules/jose/package.json +17 -81
- package/package.json +2 -2
- package/profiles/calendar/0.5.profile.json +190 -0
- package/profiles/charge/0.5.profile.json +210 -0
- package/profiles/customers/0.7.profile.json +157 -0
- package/profiles/deploy/0.9.profile.json +176 -0
- package/profiles/email/0.6.profile.json +208 -0
- package/profiles/index.json +9 -1
- package/profiles/publish/0.5.profile.json +186 -0
- package/profiles/purchase/0.5.profile.json +231 -0
- package/profiles/records/0.5.profile.json +117 -0
|
@@ -408,6 +408,17 @@ export type Options = {
|
|
|
408
408
|
* Defaults to `{limit}-in-{window}`.
|
|
409
409
|
*/
|
|
410
410
|
identifier: string | ValueDeterminingMiddleware<string>;
|
|
411
|
+
/**
|
|
412
|
+
* Method to generate a custom `Retry-After` header value (in seconds) when
|
|
413
|
+
* a client is rate limited.
|
|
414
|
+
*
|
|
415
|
+
* This is advisory only, it customizes what the header says, it does not
|
|
416
|
+
* change how long the limiter actually keeps blocking the client for.
|
|
417
|
+
* That is still controlled by `windowMs`.
|
|
418
|
+
*
|
|
419
|
+
* By default, the number of seconds remaining until the window resets.
|
|
420
|
+
*/
|
|
421
|
+
retryAfter?: number | ValueDeterminingMiddleware<number>;
|
|
411
422
|
/**
|
|
412
423
|
* The name of the property on the request object to store the rate limit info.
|
|
413
424
|
*
|
|
@@ -408,6 +408,17 @@ export type Options = {
|
|
|
408
408
|
* Defaults to `{limit}-in-{window}`.
|
|
409
409
|
*/
|
|
410
410
|
identifier: string | ValueDeterminingMiddleware<string>;
|
|
411
|
+
/**
|
|
412
|
+
* Method to generate a custom `Retry-After` header value (in seconds) when
|
|
413
|
+
* a client is rate limited.
|
|
414
|
+
*
|
|
415
|
+
* This is advisory only, it customizes what the header says, it does not
|
|
416
|
+
* change how long the limiter actually keeps blocking the client for.
|
|
417
|
+
* That is still controlled by `windowMs`.
|
|
418
|
+
*
|
|
419
|
+
* By default, the number of seconds remaining until the window resets.
|
|
420
|
+
*/
|
|
421
|
+
retryAfter?: number | ValueDeterminingMiddleware<number>;
|
|
411
422
|
/**
|
|
412
423
|
* The name of the property on the request object to store the rate limit info.
|
|
413
424
|
*
|
|
@@ -254,9 +254,9 @@ var setDraft8Headers = (response, info, windowMs, name, key) => {
|
|
|
254
254
|
response.append("RateLimit", `"${name}"; ${header}`);
|
|
255
255
|
response.append("RateLimit-Policy", `"${name}"; ${policy}`);
|
|
256
256
|
};
|
|
257
|
-
var setRetryAfterHeader = (response, info, windowMs) => {
|
|
257
|
+
var setRetryAfterHeader = (response, info, windowMs, retryAfter) => {
|
|
258
258
|
if (response.headersSent) return;
|
|
259
|
-
const resetSeconds = getResetSeconds(windowMs, info.resetTime);
|
|
259
|
+
const resetSeconds = retryAfter ?? getResetSeconds(windowMs, info.resetTime);
|
|
260
260
|
response.setHeader("Retry-After", resetSeconds.toString());
|
|
261
261
|
};
|
|
262
262
|
|
|
@@ -523,6 +523,7 @@ var validations = {
|
|
|
523
523
|
legacyHeaders: true,
|
|
524
524
|
standardHeaders: true,
|
|
525
525
|
identifier: true,
|
|
526
|
+
retryAfter: true,
|
|
526
527
|
requestPropertyName: true,
|
|
527
528
|
skipFailedRequests: true,
|
|
528
529
|
skipSuccessfulRequests: true,
|
|
@@ -1007,7 +1008,9 @@ var rateLimit = (passedOptions) => {
|
|
|
1007
1008
|
debug("limit exceeded");
|
|
1008
1009
|
if (config.legacyHeaders || config.standardHeaders) {
|
|
1009
1010
|
debug("set retry-after header");
|
|
1010
|
-
|
|
1011
|
+
const retrieveRetryAfter = typeof config.retryAfter === "function" ? config.retryAfter(request, response) : config.retryAfter;
|
|
1012
|
+
const retryAfter = await retrieveRetryAfter;
|
|
1013
|
+
setRetryAfterHeader(response, info, config.windowMs, retryAfter);
|
|
1011
1014
|
}
|
|
1012
1015
|
config.handler(request, response, next, options);
|
|
1013
1016
|
return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright 2023 Nathan Friedly, Vedant K
|
|
4
4
|
|
|
@@ -13,8 +13,9 @@ The above copyright notice and this permission notice shall be included in all
|
|
|
13
13
|
copies or substantial portions of the Software.
|
|
14
14
|
|
|
15
15
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-rate-limit",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.7.0",
|
|
4
4
|
"description": "Basic IP rate-limiting middleware for Express. Use to limit repeated requests to public APIs and/or endpoints such as password reset.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Nathan Friedly",
|
|
@@ -90,16 +90,16 @@
|
|
|
90
90
|
"@types/debug": "4.1.13",
|
|
91
91
|
"@types/express": "5.0.6",
|
|
92
92
|
"@types/jest": "30.0.0",
|
|
93
|
-
"@types/node": "26.
|
|
93
|
+
"@types/node": "26.2.0",
|
|
94
94
|
"@types/supertest": "7.2.1",
|
|
95
95
|
"del-cli": "7.0.0",
|
|
96
96
|
"dts-bundle-generator": "8.1.2",
|
|
97
|
-
"esbuild": "0.28.
|
|
97
|
+
"esbuild": "0.28.2",
|
|
98
98
|
"express": "5.2.1",
|
|
99
99
|
"husky": "9.1.7",
|
|
100
100
|
"jest": "30.4.2",
|
|
101
|
-
"lint-staged": "17.
|
|
102
|
-
"mintlify": "4.2.
|
|
101
|
+
"lint-staged": "17.3.0",
|
|
102
|
+
"mintlify": "4.2.817",
|
|
103
103
|
"npm-run-all": "4.1.5",
|
|
104
104
|
"prettier": "3.9.6",
|
|
105
105
|
"ratelimit-header-parser": "0.1.0",
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
[](https://github.com/express-rate-limit/express-rate-limit/actions/workflows/ci.yaml)
|
|
6
6
|
[](https://npmjs.org/package/express-rate-limit 'View this project on NPM')
|
|
7
7
|
[](https://www.npmjs.com/package/express-rate-limit)
|
|
8
|
+
[](https://inspect.software/software/express-rate-limit/express-rate-limit)
|
|
8
9
|
[](license.md)
|
|
9
10
|
|
|
10
11
|
</div>
|
|
@@ -324,6 +324,18 @@ function hasMalformedPercentEncoding (component) {
|
|
|
324
324
|
return false
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Whether the host is a bracketed IP literal (RFC 3986 `IP-literal`).
|
|
329
|
+
* An unterminated `[` is not a literal, so it must still be validated as a
|
|
330
|
+
* reg-name instead of being waved through as an IP.
|
|
331
|
+
*
|
|
332
|
+
* @param {string} host
|
|
333
|
+
* @returns {boolean}
|
|
334
|
+
*/
|
|
335
|
+
function isIPLiteral (host) {
|
|
336
|
+
return host[0] === '[' && host[host.length - 1] === ']'
|
|
337
|
+
}
|
|
338
|
+
|
|
327
339
|
/**
|
|
328
340
|
* @param {RegExpMatchArray} matches
|
|
329
341
|
* @returns {boolean}
|
|
@@ -333,7 +345,7 @@ function hasMalformedComponentPercentEncoding (matches) {
|
|
|
333
345
|
// compatibility. Their parsing is intentionally left to normalizeIPv6.
|
|
334
346
|
const host = matches[4]
|
|
335
347
|
return hasMalformedPercentEncoding(matches[3]) ||
|
|
336
|
-
(host !== undefined && !(host
|
|
348
|
+
(host !== undefined && !isIPLiteral(host) && hasMalformedPercentEncoding(host)) ||
|
|
337
349
|
hasMalformedPercentEncoding(matches[6]) ||
|
|
338
350
|
hasMalformedPercentEncoding(matches[7]) ||
|
|
339
351
|
hasMalformedPercentEncoding(matches[8])
|
|
@@ -351,7 +363,7 @@ function canonicalizeHost (parsed, options, schemeHandler, isIP) {
|
|
|
351
363
|
!options.unicodeSupport &&
|
|
352
364
|
(!schemeHandler || !schemeHandler.unicodeSupport) &&
|
|
353
365
|
parsed.host &&
|
|
354
|
-
parsed.host
|
|
366
|
+
!isIPLiteral(parsed.host) &&
|
|
355
367
|
(options.domainHost || (schemeHandler && schemeHandler.domainHost)) &&
|
|
356
368
|
isIP === false &&
|
|
357
369
|
nonSimpleDomain(parsed.host)
|
|
@@ -476,10 +488,11 @@ function parseWithStatus (uri, opts) {
|
|
|
476
488
|
if (parsed.host) {
|
|
477
489
|
const ipv4result = isIPv4(parsed.host)
|
|
478
490
|
if (ipv4result === false) {
|
|
479
|
-
const bracketedIPLiteral = parsed.host
|
|
491
|
+
const bracketedIPLiteral = isIPLiteral(parsed.host)
|
|
492
|
+
const hasIPLiteralBracket = parsed.host.indexOf('[') !== -1 || parsed.host.indexOf(']') !== -1
|
|
480
493
|
const ipv6result = normalizeIPv6(parsed.host)
|
|
481
494
|
isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true
|
|
482
|
-
malformedIPLiteral =
|
|
495
|
+
malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true)
|
|
483
496
|
parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase()
|
|
484
497
|
|
|
485
498
|
if (malformedIPLiteral) {
|
|
@@ -509,7 +522,9 @@ function parseWithStatus (uri, opts) {
|
|
|
509
522
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme)
|
|
510
523
|
|
|
511
524
|
// convert Unicode IDN -> ASCII IDN when the effective scheme uses domain hosts
|
|
512
|
-
|
|
525
|
+
if (!malformedIPLiteral) {
|
|
526
|
+
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP)
|
|
527
|
+
}
|
|
513
528
|
|
|
514
529
|
if (!schemeHandler || (schemeHandler && !schemeHandler.skipNormalize)) {
|
|
515
530
|
if (uri.indexOf('%') !== -1) {
|
|
@@ -6,6 +6,9 @@ const isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\d
|
|
|
6
6
|
/** @type {(value: string) => boolean} */
|
|
7
7
|
const isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u)
|
|
8
8
|
|
|
9
|
+
/** @type {(value: string) => boolean} */
|
|
10
|
+
const isPort = RegExp.prototype.test.bind(/^\d*$/u)
|
|
11
|
+
|
|
9
12
|
/** @type {(value: string) => boolean} */
|
|
10
13
|
const isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu)
|
|
11
14
|
|
|
@@ -713,8 +716,12 @@ function recomposeAuthority (component) {
|
|
|
713
716
|
}
|
|
714
717
|
|
|
715
718
|
if (typeof component.port === 'number' || typeof component.port === 'string') {
|
|
719
|
+
const port = String(component.port)
|
|
720
|
+
if (!isPort(port)) {
|
|
721
|
+
throw new TypeError('URI port is malformed.')
|
|
722
|
+
}
|
|
716
723
|
uriTokens.push(':')
|
|
717
|
-
uriTokens.push(
|
|
724
|
+
uriTokens.push(port)
|
|
718
725
|
}
|
|
719
726
|
|
|
720
727
|
return uriTokens.length ? uriTokens.join('') : undefined
|
|
@@ -24,6 +24,64 @@ test('userinfo serialization cannot terminate the authority', (t) => {
|
|
|
24
24
|
t.end()
|
|
25
25
|
})
|
|
26
26
|
|
|
27
|
+
test('port serialization rejects non-digit values', (t) => {
|
|
28
|
+
const malformedPorts = [
|
|
29
|
+
'@127.0.0.1:8124',
|
|
30
|
+
'8080@evil.example',
|
|
31
|
+
'8080/path',
|
|
32
|
+
'8080?query',
|
|
33
|
+
'8080#fragment',
|
|
34
|
+
'8080:9000',
|
|
35
|
+
'-1',
|
|
36
|
+
'1.5',
|
|
37
|
+
1.5,
|
|
38
|
+
NaN,
|
|
39
|
+
Infinity,
|
|
40
|
+
'\u0661'
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
for (const port of malformedPorts) {
|
|
44
|
+
t.throws(
|
|
45
|
+
() => fastURI.serialize({ scheme: 'http', host: 'trusted.example', port, path: '/app' }),
|
|
46
|
+
/URI port is malformed\./,
|
|
47
|
+
String(port)
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
t.throws(
|
|
52
|
+
() => fastURI.normalize({ scheme: 'http', host: 'trusted.example', port: '@evil.example' }),
|
|
53
|
+
/URI port is malformed\./,
|
|
54
|
+
'object normalization rejects a malformed port'
|
|
55
|
+
)
|
|
56
|
+
t.equal(
|
|
57
|
+
fastURI.equal(
|
|
58
|
+
{ scheme: 'http', host: 'trusted.example', port: '@evil.example' },
|
|
59
|
+
{ scheme: 'http', host: 'trusted.example', port: '@evil.example' }
|
|
60
|
+
),
|
|
61
|
+
false,
|
|
62
|
+
'object equality fails closed for a malformed port'
|
|
63
|
+
)
|
|
64
|
+
t.end()
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('port serialization preserves RFC 3986 digit values', (t) => {
|
|
68
|
+
const validPorts = [
|
|
69
|
+
[8080, '8080'],
|
|
70
|
+
['8080', '8080'],
|
|
71
|
+
['00080', '00080'],
|
|
72
|
+
['', '']
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
for (const [port, expected] of validPorts) {
|
|
76
|
+
t.equal(
|
|
77
|
+
fastURI.serialize({ scheme: 'uri', host: 'example.test', port }),
|
|
78
|
+
`uri://example.test:${expected}`,
|
|
79
|
+
JSON.stringify(port)
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
t.end()
|
|
83
|
+
})
|
|
84
|
+
|
|
27
85
|
test('query and fragment serialization cannot inject component delimiters', (t) => {
|
|
28
86
|
const uri = fastURI.serialize({
|
|
29
87
|
scheme: 'x',
|
|
@@ -88,3 +88,37 @@ test('valid IPv6, IPvFuture, embedded IPv4, and zone forms normalize safely', (t
|
|
|
88
88
|
}
|
|
89
89
|
t.end()
|
|
90
90
|
})
|
|
91
|
+
|
|
92
|
+
test('hosts with unbalanced or misplaced IP-literal brackets are rejected', (t) => {
|
|
93
|
+
const malformed = [
|
|
94
|
+
'http://[fe80',
|
|
95
|
+
'http://[',
|
|
96
|
+
'http://[not-an-ip',
|
|
97
|
+
'http://[\u65e5\u672c',
|
|
98
|
+
'http://user@[@127.0.0.1:8123/admin',
|
|
99
|
+
'http://user@]127.0.0.1:8123/admin',
|
|
100
|
+
'http://user@prefix[@127.0.0.1:8123/admin',
|
|
101
|
+
'http://user@prefix]@127.0.0.1:8123/admin'
|
|
102
|
+
]
|
|
103
|
+
const modes = [
|
|
104
|
+
['default', undefined],
|
|
105
|
+
['Unicode', { unicodeSupport: true }]
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
for (const [mode, options] of modes) {
|
|
109
|
+
for (const uri of malformed) {
|
|
110
|
+
const parsed = fastURI.parse(uri, options)
|
|
111
|
+
const message = `${mode} mode rejects ${uri}`
|
|
112
|
+
|
|
113
|
+
t.equal(parsed.error, HOST_ERROR, `parse ${message}`)
|
|
114
|
+
t.equal(fastURI.normalize(uri, options), uri, `normalize preserves ${uri} in ${mode} mode`)
|
|
115
|
+
t.equal(fastURI.equal(uri, uri, options), false, `equal ${message}`)
|
|
116
|
+
t.throws(
|
|
117
|
+
() => fastURI.resolve('http://example.com/', uri, options),
|
|
118
|
+
/URI host is malformed\./,
|
|
119
|
+
`resolve ${message}`
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
t.end()
|
|
124
|
+
})
|
|
@@ -157,24 +157,24 @@ const hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
|
|
|
157
157
|
const path = parts.join("/");
|
|
158
158
|
const url = (0, import_utils.mergePath)(baseUrl, path);
|
|
159
159
|
if (method === "url" || method === "path") {
|
|
160
|
-
let result = url;
|
|
160
|
+
let result = (0, import_utils.removeIndexString)(url);
|
|
161
161
|
if (opts.args[0]) {
|
|
162
162
|
if (opts.args[0].param) {
|
|
163
|
-
result = (0, import_utils.replaceUrlParam)(
|
|
163
|
+
result = (0, import_utils.replaceUrlParam)(result, opts.args[0].param);
|
|
164
164
|
}
|
|
165
165
|
if (opts.args[0].query) {
|
|
166
166
|
result = appendQueryParams(result, buildSearchParamsOption(opts.args[0].query));
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
result = (0, import_utils.removeIndexString)(result);
|
|
170
169
|
if (method === "url") {
|
|
171
170
|
return new URL(result);
|
|
172
171
|
}
|
|
173
172
|
return result.slice(baseUrl.replace(/\/+$/, "").length).replace(/^\/?/, "/");
|
|
174
173
|
}
|
|
175
174
|
if (method === "ws") {
|
|
175
|
+
const normalizedUrl = (0, import_utils.removeIndexString)(url);
|
|
176
176
|
const webSocketUrl = (0, import_utils.replaceUrlProtocol)(
|
|
177
|
-
opts.args[0]?.param ? (0, import_utils.replaceUrlParam)(
|
|
177
|
+
opts.args[0]?.param ? (0, import_utils.replaceUrlParam)(normalizedUrl, opts.args[0].param) : normalizedUrl,
|
|
178
178
|
"ws"
|
|
179
179
|
);
|
|
180
180
|
const targetUrl = new URL(webSocketUrl);
|
|
@@ -61,13 +61,14 @@ class Hono {
|
|
|
61
61
|
const allMethods = [...import_router.METHODS, import_router.METHOD_NAME_ALL_LOWERCASE];
|
|
62
62
|
allMethods.forEach((method) => {
|
|
63
63
|
this[method] = (args1, ...args) => {
|
|
64
|
+
const methodName = method.toUpperCase();
|
|
64
65
|
if (typeof args1 === "string") {
|
|
65
66
|
this.#path = args1;
|
|
66
67
|
} else {
|
|
67
|
-
this.#addRoute(
|
|
68
|
+
this.#addRoute(methodName, this.#path, args1);
|
|
68
69
|
}
|
|
69
70
|
args.forEach((handler) => {
|
|
70
|
-
this.#addRoute(
|
|
71
|
+
this.#addRoute(methodName, this.#path, handler);
|
|
71
72
|
});
|
|
72
73
|
return this;
|
|
73
74
|
};
|
|
@@ -76,9 +77,10 @@ class Hono {
|
|
|
76
77
|
for (const p of [path].flat()) {
|
|
77
78
|
this.#path = p;
|
|
78
79
|
for (const m of [method].flat()) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
const methodName = m.toUpperCase();
|
|
81
|
+
for (const handler of handlers) {
|
|
82
|
+
this.#addRoute(methodName, this.#path, handler);
|
|
83
|
+
}
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
return this;
|
|
@@ -279,7 +281,6 @@ class Hono {
|
|
|
279
281
|
return this;
|
|
280
282
|
}
|
|
281
283
|
#addRoute(method, path, handler, baseRoutePath) {
|
|
282
|
-
method = method.toUpperCase();
|
|
283
284
|
path = (0, import_url.mergePath)(this._basePath, path);
|
|
284
285
|
const r = {
|
|
285
286
|
basePath: baseRoutePath !== void 0 ? (0, import_url.mergePath)(this._basePath, baseRoutePath) : this._basePath,
|
|
@@ -33,11 +33,14 @@ __export(base_exports, {
|
|
|
33
33
|
booleanAttributes: () => booleanAttributes,
|
|
34
34
|
cloneElement: () => cloneElement,
|
|
35
35
|
getNameSpaceContext: () => getNameSpaceContext,
|
|
36
|
+
isUntrustedObject: () => isUntrustedObject,
|
|
36
37
|
isValidElement: () => isValidElement,
|
|
37
38
|
jsx: () => jsx,
|
|
38
39
|
jsxFn: () => jsxFn,
|
|
39
40
|
memo: () => memo,
|
|
40
41
|
reactAPICompatVersion: () => reactAPICompatVersion,
|
|
42
|
+
renderChildren: () => renderChildren,
|
|
43
|
+
renderUntrustedObject: () => renderUntrustedObject,
|
|
41
44
|
shallowEqual: () => shallowEqual
|
|
42
45
|
});
|
|
43
46
|
module.exports = __toCommonJS(base_exports);
|
|
@@ -101,7 +104,7 @@ const booleanAttributes = [
|
|
|
101
104
|
"selected"
|
|
102
105
|
];
|
|
103
106
|
const resolveFunctionComponentResult = (result, suspendedContext) => result.then((resolved) => {
|
|
104
|
-
if (!Array.isArray(resolved) && !(resolved instanceof JSXNode)) {
|
|
107
|
+
if (typeof resolved !== "string" && !Array.isArray(resolved) && !(resolved instanceof JSXNode)) {
|
|
105
108
|
return resolved;
|
|
106
109
|
}
|
|
107
110
|
const children = Array.isArray(resolved) ? resolved : [resolved];
|
|
@@ -139,6 +142,17 @@ const childrenToStringToBuffer = (children, buffer) => {
|
|
|
139
142
|
}
|
|
140
143
|
}
|
|
141
144
|
};
|
|
145
|
+
const renderChildren = (children) => (0, import_context.runWithRenderContext)(() => {
|
|
146
|
+
const buffer = [""];
|
|
147
|
+
childrenToStringToBuffer(children, buffer);
|
|
148
|
+
return buffer.length === 1 ? (0, import_html.raw)(buffer[0], buffer.callbacks) : (0, import_html2.stringBufferToString)(buffer, buffer.callbacks);
|
|
149
|
+
});
|
|
150
|
+
const isUntrustedObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof JSXNode) && !(value instanceof Promise) && !value.isEscaped && typeof value.toString === "function";
|
|
151
|
+
const renderUntrustedObject = (value) => {
|
|
152
|
+
const stringified = value.toString();
|
|
153
|
+
const escape = (result) => renderChildren([String(result)]);
|
|
154
|
+
return stringified instanceof Promise ? stringified.then(escape) : escape(stringified);
|
|
155
|
+
};
|
|
142
156
|
class JSXNode {
|
|
143
157
|
tag;
|
|
144
158
|
props;
|
|
@@ -369,10 +383,13 @@ const reactAPICompatVersion = "19.0.0-hono-jsx";
|
|
|
369
383
|
booleanAttributes,
|
|
370
384
|
cloneElement,
|
|
371
385
|
getNameSpaceContext,
|
|
386
|
+
isUntrustedObject,
|
|
372
387
|
isValidElement,
|
|
373
388
|
jsx,
|
|
374
389
|
jsxFn,
|
|
375
390
|
memo,
|
|
376
391
|
reactAPICompatVersion,
|
|
392
|
+
renderChildren,
|
|
393
|
+
renderUntrustedObject,
|
|
377
394
|
shallowEqual
|
|
378
395
|
});
|
|
@@ -31,7 +31,7 @@ var import_streaming = require("./streaming");
|
|
|
31
31
|
let errorBoundaryCounter = 0;
|
|
32
32
|
const childrenToString = async (children) => {
|
|
33
33
|
try {
|
|
34
|
-
return children.flat().map(
|
|
34
|
+
return children.flat().map(resolveChildEarly);
|
|
35
35
|
} catch (e) {
|
|
36
36
|
if (e instanceof Promise) {
|
|
37
37
|
const resume = (0, import_context.captureRenderContext)();
|
|
@@ -42,18 +42,16 @@ const childrenToString = async (children) => {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
-
const resolveChildEarly = (
|
|
46
|
-
if (
|
|
45
|
+
const resolveChildEarly = (child) => {
|
|
46
|
+
if (child == null || typeof child === "boolean") {
|
|
47
47
|
return "";
|
|
48
|
-
} else if (typeof
|
|
49
|
-
return
|
|
48
|
+
} else if (typeof child === "string" || Array.isArray(child)) {
|
|
49
|
+
return (0, import_base.renderChildren)([child]);
|
|
50
|
+
} else if ((0, import_base.isUntrustedObject)(child)) {
|
|
51
|
+
return (0, import_base.renderUntrustedObject)(child);
|
|
50
52
|
} else {
|
|
51
|
-
const str =
|
|
52
|
-
|
|
53
|
-
return (0, import_html.raw)(str);
|
|
54
|
-
} else {
|
|
55
|
-
return str;
|
|
56
|
-
}
|
|
53
|
+
const str = child.toString();
|
|
54
|
+
return str instanceof Promise ? str : (0, import_html.raw)(str);
|
|
57
55
|
}
|
|
58
56
|
};
|
|
59
57
|
const ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) => {
|
|
@@ -69,26 +67,27 @@ const ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) =>
|
|
|
69
67
|
let fallbackStrPromise;
|
|
70
68
|
const resolveFallbackStr = () => fallbackStrPromise ||= (async () => {
|
|
71
69
|
const awaitedFallback = await fallback;
|
|
72
|
-
if (
|
|
73
|
-
return
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
);
|
|
81
|
-
}
|
|
70
|
+
if (awaitedFallback === null || awaitedFallback === void 0) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (typeof awaitedFallback === "string" || Array.isArray(awaitedFallback)) {
|
|
74
|
+
return getResume()(() => (0, import_base.renderChildren)([awaitedFallback]));
|
|
75
|
+
}
|
|
76
|
+
if ((0, import_base.isUntrustedObject)(awaitedFallback)) {
|
|
77
|
+
return getResume()(() => (0, import_base.renderUntrustedObject)(awaitedFallback));
|
|
82
78
|
}
|
|
79
|
+
const fallbackResult = await getResume()(() => awaitedFallback.toString());
|
|
80
|
+
return (0, import_html.raw)(
|
|
81
|
+
fallbackResult,
|
|
82
|
+
fallbackResult.callbacks || awaitedFallback.callbacks
|
|
83
|
+
);
|
|
83
84
|
})();
|
|
84
85
|
const renderFallback = async (error) => {
|
|
85
86
|
const fallbackStr = await resolveFallbackStr();
|
|
86
87
|
return getResume()(async () => {
|
|
87
88
|
onError?.(error);
|
|
88
89
|
const fallbackRes = fallbackStr !== void 0 ? fallbackStr : fallbackRender && (0, import_base.jsx)(import_base.Fragment, {}, fallbackRender(error)) || "";
|
|
89
|
-
const fallbackResString = await (0, import_base.Fragment)({
|
|
90
|
-
children: fallbackRes
|
|
91
|
-
}).toString();
|
|
90
|
+
const fallbackResString = await (0, import_base.Fragment)({ children: fallbackRes }).toString();
|
|
92
91
|
return (0, import_html.raw)(
|
|
93
92
|
fallbackResString,
|
|
94
93
|
fallbackResString.callbacks || fallbackRes.callbacks
|
|
@@ -121,7 +120,7 @@ const ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) =>
|
|
|
121
120
|
const fallbackResString = await renderFallback(error2);
|
|
122
121
|
const fallbackCallbacks = fallbackResString.callbacks;
|
|
123
122
|
if (buffer) {
|
|
124
|
-
buffer[0] = buffer[0].replace(replaceRe, fallbackResString);
|
|
123
|
+
buffer[0] = buffer[0].replace(replaceRe, () => fallbackResString);
|
|
125
124
|
return fallbackCallbacks?.length ? (0, import_html.raw)("", fallbackCallbacks) : "";
|
|
126
125
|
}
|
|
127
126
|
return (0, import_html.raw)(
|
|
@@ -160,7 +159,7 @@ d.parentElement.insertBefore(c.content,d.nextSibling)
|
|
|
160
159
|
</script>`;
|
|
161
160
|
if (htmlArray.every((html2) => !html2.callbacks?.length)) {
|
|
162
161
|
if (buffer) {
|
|
163
|
-
buffer[0] = buffer[0].replace(replaceRe, content);
|
|
162
|
+
buffer[0] = buffer[0].replace(replaceRe, () => content);
|
|
164
163
|
}
|
|
165
164
|
return html;
|
|
166
165
|
}
|
|
@@ -155,18 +155,18 @@ const createContext = (defaultValue) => {
|
|
|
155
155
|
const context = ((props) => {
|
|
156
156
|
const contextValues = getContextValuesIn(getCurrentStore(), context);
|
|
157
157
|
contextValues.push(props.value);
|
|
158
|
-
let
|
|
158
|
+
let rendered;
|
|
159
159
|
try {
|
|
160
|
-
|
|
160
|
+
rendered = typeof props.children === "string" ? (0, import_base.renderChildren)([props.children]) : (0, import_base.isUntrustedObject)(props.children) ? (0, import_base.renderUntrustedObject)(props.children) : props.children ? (Array.isArray(props.children) ? new import_base.JSXFragmentNode("", {}, props.children) : props.children).toString() : (0, import_html.raw)("");
|
|
161
161
|
} catch (e) {
|
|
162
162
|
contextValues.pop();
|
|
163
163
|
throw e;
|
|
164
164
|
}
|
|
165
|
-
if (
|
|
166
|
-
return
|
|
165
|
+
if (rendered instanceof Promise) {
|
|
166
|
+
return rendered.finally(() => contextValues.pop()).then((resString) => (0, import_html.raw)(resString, resString.callbacks));
|
|
167
167
|
} else {
|
|
168
168
|
contextValues.pop();
|
|
169
|
-
return (0, import_html.raw)(
|
|
169
|
+
return (0, import_html.raw)(rendered);
|
|
170
170
|
}
|
|
171
171
|
});
|
|
172
172
|
context.values = values;
|
|
@@ -33,13 +33,16 @@ __export(server_exports, {
|
|
|
33
33
|
version: () => import__.default
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(server_exports);
|
|
36
|
+
var import_base = require("../base");
|
|
36
37
|
var import_streaming = require("../streaming");
|
|
37
38
|
var import__ = __toESM(require("./"), 1);
|
|
39
|
+
const prepareRoot = (element) => typeof element === "string" || Array.isArray(element) ? (0, import_base.renderChildren)([element]) : element;
|
|
38
40
|
const renderToString = (element, options = {}) => {
|
|
39
41
|
if (Object.keys(options).length > 0) {
|
|
40
42
|
console.warn("options are not supported yet");
|
|
41
43
|
}
|
|
42
|
-
|
|
44
|
+
element = prepareRoot(element);
|
|
45
|
+
const res = element instanceof Promise ? element : element?.toString() ?? "";
|
|
43
46
|
if (typeof res !== "string") {
|
|
44
47
|
throw new Error("Async component is not supported in renderToString");
|
|
45
48
|
}
|
|
@@ -49,6 +52,7 @@ const renderToReadableStream = async (element, options = {}) => {
|
|
|
49
52
|
if (Object.keys(options).some((key) => key !== "onError")) {
|
|
50
53
|
console.warn("options are not supported yet, except onError");
|
|
51
54
|
}
|
|
55
|
+
element = prepareRoot(element);
|
|
52
56
|
if (!element || typeof element !== "object") {
|
|
53
57
|
element = element?.toString() ?? "";
|
|
54
58
|
}
|
|
@@ -85,10 +85,10 @@ const insertIntoHead = (tagName, tag, props, precedence) => ({ buffer, context }
|
|
|
85
85
|
insertTags.forEach((tag2) => {
|
|
86
86
|
buffer[0] = buffer[0].replaceAll(tag2, "");
|
|
87
87
|
});
|
|
88
|
-
buffer[0] = buffer[0].replace(/(?=<\/head>)/, insertTags.join(""));
|
|
88
|
+
buffer[0] = buffer[0].replace(/(?=<\/head>)/, () => insertTags.join(""));
|
|
89
89
|
}
|
|
90
90
|
};
|
|
91
|
-
const returnWithoutSpecialBehavior = (tag, children, props) => (0,
|
|
91
|
+
const returnWithoutSpecialBehavior = (tag, children, props) => (0, import_base.renderChildren)([new import_base.JSXNode(tag, props, (0, import_children.toArray)(children ?? []))]);
|
|
92
92
|
const documentMetadataTag = (tag, children, props, sort) => {
|
|
93
93
|
if ("itemProp" in props) {
|
|
94
94
|
return returnWithoutSpecialBehavior(tag, children, props);
|
|
@@ -32,6 +32,7 @@ var import_components2 = require("./dom/components");
|
|
|
32
32
|
var import_render = require("./dom/render");
|
|
33
33
|
const StreamingContext = (0, import_context.createContext)(null);
|
|
34
34
|
let suspenseCounter = 0;
|
|
35
|
+
const serializeBoundaryChild = (child) => typeof child === "string" || Array.isArray(child) ? (0, import_base.renderChildren)([child]) : child == null || typeof child === "boolean" ? "" : (0, import_base.isUntrustedObject)(child) ? (0, import_base.renderUntrustedObject)(child) : child.toString();
|
|
35
36
|
const Suspense = async ({
|
|
36
37
|
children,
|
|
37
38
|
fallback
|
|
@@ -48,9 +49,7 @@ const Suspense = async ({
|
|
|
48
49
|
try {
|
|
49
50
|
stackNode[import_constants.DOM_STASH][0] = 0;
|
|
50
51
|
import_render.buildDataStack.push([[], stackNode]);
|
|
51
|
-
resArray = children.map(
|
|
52
|
-
(c) => c == null || typeof c === "boolean" ? "" : c.toString()
|
|
53
|
-
);
|
|
52
|
+
resArray = children.map(serializeBoundaryChild);
|
|
54
53
|
} catch (e) {
|
|
55
54
|
if (e instanceof Promise) {
|
|
56
55
|
const resume = (0, import_context.captureRenderContext)();
|
|
@@ -71,7 +70,7 @@ const Suspense = async ({
|
|
|
71
70
|
}
|
|
72
71
|
if (resArray.some((res) => res instanceof Promise)) {
|
|
73
72
|
const index = suspenseCounter++;
|
|
74
|
-
const fallbackStr = await fallback.toString();
|
|
73
|
+
const fallbackStr = await (typeof fallback === "string" || Array.isArray(fallback) ? (0, import_base.renderChildren)([fallback]) : (0, import_base.isUntrustedObject)(fallback) ? (0, import_base.renderUntrustedObject)(fallback) : fallback.toString());
|
|
75
74
|
return (0, import_html.raw)(`<template id="H:${index}"></template>${fallbackStr}<!--/$-->`, [
|
|
76
75
|
...fallbackStr.callbacks || [],
|
|
77
76
|
({ phase, buffer, context }) => {
|
|
@@ -84,7 +83,7 @@ const Suspense = async ({
|
|
|
84
83
|
if (buffer) {
|
|
85
84
|
buffer[0] = buffer[0].replace(
|
|
86
85
|
new RegExp(`<template id="H:${index}"></template>.*?<!--/\\$-->`),
|
|
87
|
-
content
|
|
86
|
+
() => content
|
|
88
87
|
);
|
|
89
88
|
}
|
|
90
89
|
let html = buffer ? "" : `<template data-hono-target="H:${index}">${content}</template><script${nonce ? ` nonce="${nonce}"` : ""}>
|