♻️ Migrated to actix rs
This commit is contained in:
		| @@ -5,24 +5,24 @@ on: | ||||
|     branches: [ master ] | ||||
| 
 | ||||
| jobs: | ||||
|   build-docker: | ||||
|     runs-on: edge | ||||
|   build-image: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v4 | ||||
|       - name: Set up QEMU | ||||
|         uses: docker/setup-qemu-action@v2 | ||||
|         uses: docker/setup-qemu-action@v3 | ||||
|       - name: Set up Docker Buildx | ||||
|         uses: docker/setup-buildx-action@v2 | ||||
|         uses: docker/setup-buildx-action@v3 | ||||
|       - name: Login to Docker Hub | ||||
|         uses: docker/login-action@v2 | ||||
|         uses: docker/login-action@v3 | ||||
|         with: | ||||
|           username: ${{ secrets.DOCKER_REGISTRY_USERNAME }} | ||||
|           password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} | ||||
|       - name: Build and push | ||||
|         uses: docker/build-push-action@v4 | ||||
|         uses: docker/build-push-action@v5 | ||||
|         with: | ||||
|           context: . | ||||
|           file: ./Dockerfile | ||||
|           push: true | ||||
|           tags: xsheep2010/roadsign:nightly | ||||
|           file: ./Dockerfile | ||||
|           tags: xsheep2010/roadsign:sigma | ||||
							
								
								
									
										490
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										490
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -2,6 +2,240 @@ | ||||
| # It is not intended for manual editing. | ||||
| version = 3 | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-codec" | ||||
| version = "0.5.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" | ||||
| dependencies = [ | ||||
|  "bitflags 2.4.1", | ||||
|  "bytes", | ||||
|  "futures-core", | ||||
|  "futures-sink", | ||||
|  "memchr", | ||||
|  "pin-project-lite", | ||||
|  "tokio", | ||||
|  "tokio-util", | ||||
|  "tracing", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-files" | ||||
| version = "0.6.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bf0bdd6ff79de7c9a021f5d9ea79ce23e108d8bfc9b49b5b4a2cf6fad5a35212" | ||||
| dependencies = [ | ||||
|  "actix-http", | ||||
|  "actix-service", | ||||
|  "actix-utils", | ||||
|  "actix-web", | ||||
|  "bitflags 2.4.1", | ||||
|  "bytes", | ||||
|  "derive_more", | ||||
|  "futures-core", | ||||
|  "http-range", | ||||
|  "log", | ||||
|  "mime", | ||||
|  "mime_guess", | ||||
|  "percent-encoding", | ||||
|  "pin-project-lite", | ||||
|  "v_htmlescape", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-http" | ||||
| version = "3.6.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d223b13fd481fc0d1f83bb12659ae774d9e3601814c68a0bc539731698cca743" | ||||
| dependencies = [ | ||||
|  "actix-codec", | ||||
|  "actix-rt", | ||||
|  "actix-service", | ||||
|  "actix-utils", | ||||
|  "ahash 0.8.8", | ||||
|  "base64 0.21.7", | ||||
|  "bitflags 2.4.1", | ||||
|  "brotli", | ||||
|  "bytes", | ||||
|  "bytestring", | ||||
|  "derive_more", | ||||
|  "encoding_rs", | ||||
|  "flate2", | ||||
|  "futures-core", | ||||
|  "h2 0.3.24", | ||||
|  "http 0.2.11", | ||||
|  "httparse", | ||||
|  "httpdate", | ||||
|  "itoa", | ||||
|  "language-tags", | ||||
|  "local-channel", | ||||
|  "mime", | ||||
|  "percent-encoding", | ||||
|  "pin-project-lite", | ||||
|  "rand", | ||||
|  "sha1", | ||||
|  "smallvec", | ||||
|  "tokio", | ||||
|  "tokio-util", | ||||
|  "tracing", | ||||
|  "zstd", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-macros" | ||||
| version = "0.2.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" | ||||
| dependencies = [ | ||||
|  "quote", | ||||
|  "syn 2.0.48", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-proxy" | ||||
| version = "0.2.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3eb1ba1258bd79835d602dffb79f62aae42da7569036c67929e21961e2b3693c" | ||||
| dependencies = [ | ||||
|  "actix-web", | ||||
|  "awc", | ||||
|  "openssl", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-router" | ||||
| version = "0.5.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511" | ||||
| dependencies = [ | ||||
|  "bytestring", | ||||
|  "http 0.2.11", | ||||
|  "regex", | ||||
|  "serde", | ||||
|  "tracing", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-rt" | ||||
| version = "2.9.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" | ||||
| dependencies = [ | ||||
|  "futures-core", | ||||
|  "tokio", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-server" | ||||
| version = "2.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" | ||||
| dependencies = [ | ||||
|  "actix-rt", | ||||
|  "actix-service", | ||||
|  "actix-utils", | ||||
|  "futures-core", | ||||
|  "futures-util", | ||||
|  "mio", | ||||
|  "socket2", | ||||
|  "tokio", | ||||
|  "tracing", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-service" | ||||
| version = "2.0.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" | ||||
| dependencies = [ | ||||
|  "futures-core", | ||||
|  "paste", | ||||
|  "pin-project-lite", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-tls" | ||||
| version = "3.3.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d4cce60a2f2b477bc72e5cde0af1812a6e82d8fd85b5570a5dcf2a5bf2c5be5f" | ||||
| dependencies = [ | ||||
|  "actix-rt", | ||||
|  "actix-service", | ||||
|  "actix-utils", | ||||
|  "futures-core", | ||||
|  "http 0.2.11", | ||||
|  "http 1.0.0", | ||||
|  "impl-more", | ||||
|  "openssl", | ||||
|  "pin-project-lite", | ||||
|  "tokio", | ||||
|  "tokio-openssl", | ||||
|  "tokio-util", | ||||
|  "tracing", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-utils" | ||||
| version = "3.0.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" | ||||
| dependencies = [ | ||||
|  "local-waker", | ||||
|  "pin-project-lite", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-web" | ||||
| version = "4.5.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "43a6556ddebb638c2358714d853257ed226ece6023ef9364f23f0c70737ea984" | ||||
| dependencies = [ | ||||
|  "actix-codec", | ||||
|  "actix-http", | ||||
|  "actix-macros", | ||||
|  "actix-router", | ||||
|  "actix-rt", | ||||
|  "actix-server", | ||||
|  "actix-service", | ||||
|  "actix-utils", | ||||
|  "actix-web-codegen", | ||||
|  "ahash 0.8.8", | ||||
|  "bytes", | ||||
|  "bytestring", | ||||
|  "cfg-if", | ||||
|  "cookie 0.16.2", | ||||
|  "derive_more", | ||||
|  "encoding_rs", | ||||
|  "futures-core", | ||||
|  "futures-util", | ||||
|  "itoa", | ||||
|  "language-tags", | ||||
|  "log", | ||||
|  "mime", | ||||
|  "once_cell", | ||||
|  "pin-project-lite", | ||||
|  "regex", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "serde_urlencoded", | ||||
|  "smallvec", | ||||
|  "socket2", | ||||
|  "time", | ||||
|  "url", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "actix-web-codegen" | ||||
| version = "4.2.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" | ||||
| dependencies = [ | ||||
|  "actix-router", | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn 2.0.48", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "addr2line" | ||||
| version = "0.21.0" | ||||
| @@ -63,6 +297,19 @@ dependencies = [ | ||||
|  "version_check", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "ahash" | ||||
| version = "0.8.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
|  "getrandom", | ||||
|  "once_cell", | ||||
|  "version_check", | ||||
|  "zerocopy", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "aho-corasick" | ||||
| version = "1.1.2" | ||||
| @@ -72,6 +319,21 @@ dependencies = [ | ||||
|  "memchr", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "alloc-no-stdlib" | ||||
| version = "2.0.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" | ||||
|  | ||||
| [[package]] | ||||
| name = "alloc-stdlib" | ||||
| version = "0.2.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" | ||||
| dependencies = [ | ||||
|  "alloc-no-stdlib", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "android-tzdata" | ||||
| version = "0.1.1" | ||||
| @@ -104,6 +366,40 @@ version = "1.1.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" | ||||
|  | ||||
| [[package]] | ||||
| name = "awc" | ||||
| version = "3.4.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "68c09cc97310b926f01621faee652f3d1b0962545a3cec6c9ac07def9ea36c2c" | ||||
| dependencies = [ | ||||
|  "actix-codec", | ||||
|  "actix-http", | ||||
|  "actix-rt", | ||||
|  "actix-service", | ||||
|  "actix-tls", | ||||
|  "actix-utils", | ||||
|  "base64 0.21.7", | ||||
|  "bytes", | ||||
|  "cfg-if", | ||||
|  "cookie 0.16.2", | ||||
|  "derive_more", | ||||
|  "futures-core", | ||||
|  "futures-util", | ||||
|  "h2 0.3.24", | ||||
|  "http 0.2.11", | ||||
|  "itoa", | ||||
|  "log", | ||||
|  "mime", | ||||
|  "openssl", | ||||
|  "percent-encoding", | ||||
|  "pin-project-lite", | ||||
|  "rand", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "serde_urlencoded", | ||||
|  "tokio", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "backtrace" | ||||
| version = "0.3.69" | ||||
| @@ -152,6 +448,27 @@ dependencies = [ | ||||
|  "generic-array", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "brotli" | ||||
| version = "3.4.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" | ||||
| dependencies = [ | ||||
|  "alloc-no-stdlib", | ||||
|  "alloc-stdlib", | ||||
|  "brotli-decompressor", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "brotli-decompressor" | ||||
| version = "2.5.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" | ||||
| dependencies = [ | ||||
|  "alloc-no-stdlib", | ||||
|  "alloc-stdlib", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "bumpalo" | ||||
| version = "3.14.0" | ||||
| @@ -170,12 +487,22 @@ version = "1.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" | ||||
|  | ||||
| [[package]] | ||||
| name = "bytestring" | ||||
| version = "1.3.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" | ||||
| dependencies = [ | ||||
|  "bytes", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "cc" | ||||
| version = "1.0.83" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" | ||||
| dependencies = [ | ||||
|  "jobserver", | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| @@ -232,6 +559,17 @@ version = "0.4.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" | ||||
|  | ||||
| [[package]] | ||||
| name = "cookie" | ||||
| version = "0.16.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" | ||||
| dependencies = [ | ||||
|  "percent-encoding", | ||||
|  "time", | ||||
|  "version_check", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "cookie" | ||||
| version = "0.17.0" | ||||
| @@ -275,6 +613,15 @@ dependencies = [ | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "crc32fast" | ||||
| version = "1.3.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" | ||||
| dependencies = [ | ||||
|  "cfg-if", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "crypto-common" | ||||
| version = "0.1.6" | ||||
| @@ -406,6 +753,16 @@ version = "2.0.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" | ||||
|  | ||||
| [[package]] | ||||
| name = "flate2" | ||||
| version = "1.0.28" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" | ||||
| dependencies = [ | ||||
|  "crc32fast", | ||||
|  "miniz_oxide", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "fnv" | ||||
| version = "1.0.7" | ||||
| @@ -528,9 +885,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" | ||||
|  | ||||
| [[package]] | ||||
| name = "h2" | ||||
| version = "0.3.23" | ||||
| version = "0.3.24" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" | ||||
| checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" | ||||
| dependencies = [ | ||||
|  "bytes", | ||||
|  "fnv", | ||||
| @@ -570,7 +927,7 @@ version = "0.12.3" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" | ||||
| dependencies = [ | ||||
|  "ahash", | ||||
|  "ahash 0.7.7", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @@ -683,6 +1040,12 @@ dependencies = [ | ||||
|  "pin-project-lite", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "http-range" | ||||
| version = "0.1.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" | ||||
|  | ||||
| [[package]] | ||||
| name = "httparse" | ||||
| version = "1.8.0" | ||||
| @@ -705,7 +1068,7 @@ dependencies = [ | ||||
|  "futures-channel", | ||||
|  "futures-core", | ||||
|  "futures-util", | ||||
|  "h2 0.3.23", | ||||
|  "h2 0.3.24", | ||||
|  "http 0.2.11", | ||||
|  "http-body 0.4.6", | ||||
|  "httparse", | ||||
| @@ -814,6 +1177,12 @@ dependencies = [ | ||||
|  "unicode-normalization", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "impl-more" | ||||
| version = "0.1.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" | ||||
|  | ||||
| [[package]] | ||||
| name = "indexmap" | ||||
| version = "2.1.0" | ||||
| @@ -845,6 +1214,15 @@ version = "1.0.10" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" | ||||
|  | ||||
| [[package]] | ||||
| name = "jobserver" | ||||
| version = "0.1.28" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "js-sys" | ||||
| version = "0.3.67" | ||||
| @@ -865,6 +1243,12 @@ dependencies = [ | ||||
|  "serde", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "language-tags" | ||||
| version = "0.3.2" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" | ||||
|  | ||||
| [[package]] | ||||
| name = "lazy_static" | ||||
| version = "1.4.0" | ||||
| @@ -889,6 +1273,23 @@ version = "0.4.12" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" | ||||
|  | ||||
| [[package]] | ||||
| name = "local-channel" | ||||
| version = "0.1.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" | ||||
| dependencies = [ | ||||
|  "futures-core", | ||||
|  "futures-sink", | ||||
|  "local-waker", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "local-waker" | ||||
| version = "0.1.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" | ||||
|  | ||||
| [[package]] | ||||
| name = "lock_api" | ||||
| version = "0.4.11" | ||||
| @@ -949,6 +1350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
|  "log", | ||||
|  "wasi", | ||||
|  "windows-sys 0.48.0", | ||||
| ] | ||||
| @@ -1144,6 +1546,12 @@ dependencies = [ | ||||
|  "windows-targets 0.48.5", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "paste" | ||||
| version = "1.0.14" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" | ||||
|  | ||||
| [[package]] | ||||
| name = "pathdiff" | ||||
| version = "0.2.1" | ||||
| @@ -1249,7 +1657,7 @@ dependencies = [ | ||||
|  "base64 0.21.7", | ||||
|  "bytes", | ||||
|  "chrono", | ||||
|  "cookie", | ||||
|  "cookie 0.17.0", | ||||
|  "futures-util", | ||||
|  "headers", | ||||
|  "http 1.0.0", | ||||
| @@ -1495,7 +1903,7 @@ dependencies = [ | ||||
|  "encoding_rs", | ||||
|  "futures-core", | ||||
|  "futures-util", | ||||
|  "h2 0.3.23", | ||||
|  "h2 0.3.24", | ||||
|  "http 0.2.11", | ||||
|  "http-body 0.4.6", | ||||
|  "hyper 0.14.28", | ||||
| @@ -1571,6 +1979,10 @@ dependencies = [ | ||||
| name = "roadsign" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "actix-files", | ||||
|  "actix-proxy", | ||||
|  "actix-web", | ||||
|  "awc", | ||||
|  "config", | ||||
|  "futures-util", | ||||
|  "http 1.0.0", | ||||
| @@ -2032,6 +2444,18 @@ dependencies = [ | ||||
|  "tokio", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio-openssl" | ||||
| version = "0.6.4" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6ffab79df67727f6acf57f1ff743091873c24c579b1e2ce4d8f53e47ded4d63d" | ||||
| dependencies = [ | ||||
|  "futures-util", | ||||
|  "openssl", | ||||
|  "openssl-sys", | ||||
|  "tokio", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "tokio-stream" | ||||
| version = "0.1.14" | ||||
| @@ -2318,6 +2742,12 @@ version = "0.7.6" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" | ||||
|  | ||||
| [[package]] | ||||
| name = "v_htmlescape" | ||||
| version = "0.15.8" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4e8257fbc510f0a46eb602c10215901938b5c2a7d5e70fc11483b1d3c9b5b18c" | ||||
|  | ||||
| [[package]] | ||||
| name = "valuable" | ||||
| version = "0.1.0" | ||||
| @@ -2623,3 +3053,51 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" | ||||
| dependencies = [ | ||||
|  "linked-hash-map", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "zerocopy" | ||||
| version = "0.7.32" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" | ||||
| dependencies = [ | ||||
|  "zerocopy-derive", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "zerocopy-derive" | ||||
| version = "0.7.32" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" | ||||
| dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "syn 2.0.48", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "zstd" | ||||
| version = "0.13.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" | ||||
| dependencies = [ | ||||
|  "zstd-safe", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "zstd-safe" | ||||
| version = "7.0.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" | ||||
| dependencies = [ | ||||
|  "zstd-sys", | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "zstd-sys" | ||||
| version = "2.0.9+zstd.1.5.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" | ||||
| dependencies = [ | ||||
|  "cc", | ||||
|  "pkg-config", | ||||
| ] | ||||
|   | ||||
| @@ -6,6 +6,10 @@ edition = "2021" | ||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||
|  | ||||
| [dependencies] | ||||
| actix-files = "0.6.5" | ||||
| actix-proxy = "0.2.0" | ||||
| actix-web = "4.5.1" | ||||
| awc = "3.4.0" | ||||
| config = { version = "0.13.4", features = ["toml"] } | ||||
| futures-util = "0.3.30" | ||||
| http = "1.0.0" | ||||
|   | ||||
							
								
								
									
										98
									
								
								certs/fullchain.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								certs/fullchain.pem
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIGITCCBQmgAwIBAgISBPa2ahmRa5l0SrbR75K29TlqMA0GCSqGSIb3DQEBCwUA | ||||
| MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD | ||||
| EwJSMzAeFw0yNDAxMjgxNjM1MzZaFw0yNDA0MjcxNjM1MzVaMBwxGjAYBgNVBAMT | ||||
| EXNtYXJ0c2hlZXAuc3R1ZGlvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC | ||||
| AgEAumtDoEkBHiqBGNl9JUbt3Nw1a/iLa2JHZvCmUuilvafAj0k1UPEu457iJVjh | ||||
| nxlTl/tgpCooRNviboB0lMAecwiKb5PIZzInY2/gb+rceL7rycalDAjWnwZZg8Tl | ||||
| 3JWJaU0D3+jeBQ9p7xkRPTcRpkGxFX9hRdInRqFGmCK4/OXrBwI3FkoP9Z8Nvgzc | ||||
| RyIhmMEafOi2AaLJSXZQE508djHpcxlwoxvVmFIYsjTMJiq+zdqCZDTjDqt7bZC+ | ||||
| mp3n/DFLL0sTzIBLuHnPkrjwlE4w/XTLkMLgrGPvEJVHn4kOvnJSWJb95d3sRZqB | ||||
| PLrekQGDtcb0dpFx8ctWycVp0qhBTpuLAoN+AK6cJ3IkxOcGm7sKzYwRINjAblMe | ||||
| n1Y6as6JKL4zSZBt1jxua1NGIRQ1c4ReA78NniTMrFIk1mFL4kNT9ppgDsWGNTJx | ||||
| FqC76rr3TdKXKzD/c8h57j3CPTF9lGB4Vmlkrq/zA++br0IG7Ki/+1n04Q1UDN0E | ||||
| 8z/vgUsT+pMItrmUhpnhb+4QWLQHTWOg1CyWT9xSm77ArkuNSdzNFGjpSbYZEPlh | ||||
| pmAYTz+kWvnyg7T3Lt7fmSPCBnnIWhi9CJofvyomICWfcKEfwc0msJquXMyJBayA | ||||
| K91VMoudbveI+CX8Zuc5u4uCOk/Dr6JJWnYkIDK7cW+tFh0CAwEAAaOCAkUwggJB | ||||
| MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw | ||||
| DAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUPabqUNdBFv+3fEpgh2seAHvPQFgwHwYD | ||||
| VR0jBBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsUwsYwVQYIKwYBBQUHAQEESTBHMCEG | ||||
| CCsGAQUFBzABhhVodHRwOi8vcjMuby5sZW5jci5vcmcwIgYIKwYBBQUHMAKGFmh0 | ||||
| dHA6Ly9yMy5pLmxlbmNyLm9yZy8wTQYDVR0RBEYwRIIaKi5wbGF5bWMuc21hcnRz | ||||
| aGVlcC5zdHVkaW+CEyouc21hcnRzaGVlcC5zdHVkaW+CEXNtYXJ0c2hlZXAuc3R1 | ||||
| ZGlvMBMGA1UdIAQMMAowCAYGZ4EMAQIBMIIBBQYKKwYBBAHWeQIEAgSB9gSB8wDx | ||||
| AHcAO1N3dT4tuYBOizBbBv5AO2fYT8P0x70ADS1yb+H61BcAAAGNUSQZ5gAABAMA | ||||
| SDBGAiEA9i8QVPKh68OY9Ug+KqZ1aWSx5SVUvPKVyp8KkI/RMssCIQD0JsqwhLFx | ||||
| SQFVROa1yhbZIdIHs9NMuW7lHbOWOU4F+AB2AO7N0GTV2xrOxVy3nbTNE6Iyh0Z8 | ||||
| vOzew1FIWUZxH7WbAAABjVEkGesAAAQDAEcwRQIhAKXGxcDa/aGK50QyhOXAdlKl | ||||
| VCk0Yo9wYzw2sB48BF1TAiBsW2R+CJXhnCBzcRRh8GQuj+aBcYIzHBaRvsanC9nx | ||||
| 9zANBgkqhkiG9w0BAQsFAAOCAQEAgYR8uizQZkkvlEyI5dsz/tGJ0Vuejnd6yfoE | ||||
| OT6BaNF45UtdMfSoJRLwgW6SM1hsuwmPjoUVS9VZ83NAhnWQqSeR9P4m7aMfhaeK | ||||
| qPlDDcGh/SZOvgeja8AsUhCq+9csUzR+FEfk7xJXFflcG1FNGzRglzmqrSvFHKhE | ||||
| EyJQuk6Oa/UiL0ICdKiLxh75gTJvTB/7wznTP7NGsayzqkBj4nxqHIwCGh7hPe2c | ||||
| 2xMEbcFA9aArInJEg2PzlYRy1C9qtuhU2hJUhLjEix4WVCHUyAV/X6kwjqIaUEOz | ||||
| NdUrFCahGkWDVZZcPgl/FdFSPfSL/pnT8jOotELnhj0AiX2SNQ== | ||||
| -----END CERTIFICATE----- | ||||
|  | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw | ||||
| TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh | ||||
| cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw | ||||
| WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg | ||||
| RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK | ||||
| AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP | ||||
| R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx | ||||
| sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm | ||||
| NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg | ||||
| Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG | ||||
| /kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC | ||||
| AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB | ||||
| Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA | ||||
| FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw | ||||
| AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw | ||||
| Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB | ||||
| gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W | ||||
| PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl | ||||
| ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz | ||||
| CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm | ||||
| lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 | ||||
| avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 | ||||
| yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O | ||||
| yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids | ||||
| hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ | ||||
| HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv | ||||
| MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX | ||||
| nLRbwHOoq7hHwg== | ||||
| -----END CERTIFICATE----- | ||||
|  | ||||
| -----BEGIN CERTIFICATE----- | ||||
| MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/ | ||||
| MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT | ||||
| DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow | ||||
| TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh | ||||
| cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB | ||||
| AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC | ||||
| ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL | ||||
| wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D | ||||
| LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK | ||||
| 4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5 | ||||
| bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y | ||||
| sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ | ||||
| Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4 | ||||
| FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc | ||||
| SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql | ||||
| PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND | ||||
| TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw | ||||
| SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1 | ||||
| c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx | ||||
| +tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB | ||||
| ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu | ||||
| b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E | ||||
| U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu | ||||
| MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC | ||||
| 5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW | ||||
| 9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG | ||||
| WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O | ||||
| he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC | ||||
| Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5 | ||||
| -----END CERTIFICATE----- | ||||
							
								
								
									
										51
									
								
								certs/privkey.pem
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								certs/privkey.pem
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| -----BEGIN RSA PRIVATE KEY----- | ||||
| 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 | ||||
| -----END RSA PRIVATE KEY----- | ||||
							
								
								
									
										44
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -1,16 +1,14 @@ | ||||
| pub mod auth; | ||||
| mod config; | ||||
| mod proxies; | ||||
| mod sideload; | ||||
| pub mod warden; | ||||
|  | ||||
| use actix_web::{App, HttpServer, web}; | ||||
| use awc::Client; | ||||
| use lazy_static::lazy_static; | ||||
| use poem::{listener::TcpListener, EndpointExt, Route, Server}; | ||||
| use poem_openapi::OpenApiService; | ||||
| use proxies::RoadInstance; | ||||
| use tokio::sync::Mutex; | ||||
| use tracing::{error, info, Level}; | ||||
|  | ||||
| use crate::proxies::route; | ||||
|  | ||||
| lazy_static! { | ||||
| @@ -20,9 +18,6 @@ lazy_static! { | ||||
| #[tokio::main] | ||||
| async fn main() -> Result<(), std::io::Error> { | ||||
|     // Setting up logging | ||||
|     if std::env::var_os("RUST_LOG").is_none() { | ||||
|         std::env::set_var("RUST_LOG", "poem=debug"); | ||||
|     } | ||||
|     tracing_subscriber::fmt() | ||||
|         .with_max_level(Level::DEBUG) | ||||
|         .init(); | ||||
| @@ -44,36 +39,17 @@ async fn main() -> Result<(), std::io::Error> { | ||||
|     }; | ||||
|  | ||||
|     // Proxies | ||||
|     let proxies_server = Server::new(TcpListener::bind( | ||||
|     let proxies_server = HttpServer::new(|| { | ||||
|         App::new() | ||||
|             .app_data(web::Data::new(Client::default())) | ||||
|             .route("/", web::to(route::handle)) | ||||
|     }).bind( | ||||
|         config::C | ||||
|             .read() | ||||
|             .await | ||||
|             .get_string("listen.proxies") | ||||
|             .unwrap_or("0.0.0.0:80".to_string()), | ||||
|     )) | ||||
|     .run(route::handle); | ||||
|  | ||||
|     // Sideload | ||||
|     let sideload = OpenApiService::new(sideload::SideloadApi, "Sideload API", "1.0") | ||||
|         .server("http://localhost:3000/cgi"); | ||||
|  | ||||
|     let sideload_server = Server::new(TcpListener::bind( | ||||
|         config::C | ||||
|             .read() | ||||
|             .await | ||||
|             .get_string("listen.sideload") | ||||
|             .unwrap_or("0.0.0.0:81".to_string()), | ||||
|     )) | ||||
|     .run( | ||||
|         Route::new().nest("/cgi", sideload).with(auth::BasicAuth { | ||||
|             username: "RoadSign".to_string(), | ||||
|             password: config::C | ||||
|                 .read() | ||||
|                 .await | ||||
|                 .get_string("secret") | ||||
|                 .unwrap_or("password".to_string()), | ||||
|         }), | ||||
|     ); | ||||
|             .unwrap_or("0.0.0.0:80".to_string()) | ||||
|     )?.run(); | ||||
|  | ||||
|     // Process manager | ||||
|     { | ||||
| @@ -85,7 +61,7 @@ async fn main() -> Result<(), std::io::Error> { | ||||
|         app.warden.start().await; | ||||
|     } | ||||
|  | ||||
|     tokio::try_join!(proxies_server, sideload_server)?; | ||||
|     tokio::try_join!(proxies_server)?; | ||||
|  | ||||
|     Ok(()) | ||||
| } | ||||
|   | ||||
| @@ -1,52 +0,0 @@ | ||||
| use std::fmt::Write; | ||||
|  | ||||
| pub struct DirectoryTemplate<'a> { | ||||
|     pub path: &'a str, | ||||
|     pub files: Vec<FileRef>, | ||||
| } | ||||
|  | ||||
| impl<'a> DirectoryTemplate<'a> { | ||||
|     pub fn render(&self) -> String { | ||||
|         let mut s = format!( | ||||
|             r#" | ||||
|         <html> | ||||
|             <head> | ||||
|             <title>Index of {}</title> | ||||
|         </head> | ||||
|         <body> | ||||
|         <h1>Index of /{}</h1> | ||||
|         <ul>"#, | ||||
|             self.path, self.path | ||||
|         ); | ||||
|  | ||||
|         for file in &self.files { | ||||
|             if file.is_dir { | ||||
|                 let _ = write!( | ||||
|                     s, | ||||
|                     r#"<li><a href="{}">{}/</a></li>"#, | ||||
|                     file.url, file.filename | ||||
|                 ); | ||||
|             } else { | ||||
|                 let _ = write!( | ||||
|                     s, | ||||
|                     r#"<li><a href="{}">{}</a></li>"#, | ||||
|                     file.url, file.filename | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         s.push_str( | ||||
|             r#"</ul> | ||||
|         </body> | ||||
|         </html>"#, | ||||
|         ); | ||||
|  | ||||
|         s | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub struct FileRef { | ||||
|     pub url: String, | ||||
|     pub filename: String, | ||||
|     pub is_dir: bool, | ||||
| } | ||||
| @@ -75,15 +75,6 @@ impl Destination { | ||||
|         .collect::<Vec<_>>()[0] | ||||
|     } | ||||
|  | ||||
|     pub fn get_websocket_uri(&self) -> Result<String, ()> { | ||||
|         let parts = self.uri.as_str().splitn(2, "://").collect::<Vec<_>>(); | ||||
|         let url = parts.get(1).unwrap_or(&""); | ||||
|         match self.get_protocol() { | ||||
|             "http" | "https" => Ok(url.replace("http", "ws")), | ||||
|             _ => Err(()), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn get_hypertext_uri(&self) -> Result<String, ()> { | ||||
|         match self.get_protocol() { | ||||
|             "http" => Ok("http://".to_string() + self.get_host()), | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| use http::Method; | ||||
| use poem::http::{HeaderMap, Uri}; | ||||
| use actix_web::http::header::HeaderMap; | ||||
| use actix_web::http::{Method, Uri}; | ||||
| use regex::Regex; | ||||
| use wildmatch::WildMatch; | ||||
|  | ||||
| @@ -10,7 +10,6 @@ use self::{ | ||||
|     metrics::RoadMetrics, | ||||
| }; | ||||
|  | ||||
| pub mod browser; | ||||
| pub mod config; | ||||
| pub mod loader; | ||||
| pub mod metrics; | ||||
| @@ -38,7 +37,7 @@ impl RoadInstance { | ||||
|     pub fn filter( | ||||
|         &self, | ||||
|         uri: &Uri, | ||||
|         method: Method, | ||||
|         method: &Method, | ||||
|         headers: &HeaderMap, | ||||
|     ) -> Option<(&Region, &Location)> { | ||||
|         self.regions.iter().find_map(|region| { | ||||
|   | ||||
| @@ -1,117 +1,50 @@ | ||||
| use futures_util::{SinkExt, StreamExt}; | ||||
| use http::{header, request::Builder, HeaderMap, Method, StatusCode, Uri}; | ||||
| use lazy_static::lazy_static; | ||||
| use poem::{ | ||||
|     web::{websocket::WebSocket, StaticFileRequest}, | ||||
|     Body, Error, FromRequest, IntoResponse, Request, Response, | ||||
| }; | ||||
| use futures_util::{SinkExt}; | ||||
| use std::{ | ||||
|     ffi::OsStr, | ||||
|     path::{Path, PathBuf}, | ||||
|     sync::Arc, | ||||
| }; | ||||
| use tokio::sync::RwLock; | ||||
| use tokio_tungstenite::connect_async; | ||||
|  | ||||
| use super::browser::{DirectoryTemplate, FileRef}; | ||||
|  | ||||
| lazy_static! { | ||||
|     pub static ref CLIENT: reqwest::Client = reqwest::Client::new(); | ||||
| } | ||||
|  | ||||
| pub async fn repond_websocket(req: Builder, ws: WebSocket) -> Response { | ||||
|     ws.on_upgrade(move |socket| async move { | ||||
|         let (mut clientsink, mut clientstream) = socket.split(); | ||||
|  | ||||
|         // Start connection to server | ||||
|         let (serversocket, _) = connect_async(req.body(()).unwrap()).await.unwrap(); | ||||
|         let (mut serversink, mut serverstream) = serversocket.split(); | ||||
|  | ||||
|         let client_live = Arc::new(RwLock::new(true)); | ||||
|         let server_live = client_live.clone(); | ||||
|  | ||||
|         tokio::spawn(async move { | ||||
|             while let Some(Ok(msg)) = clientstream.next().await { | ||||
|                 if (serversink.send(msg.into()).await).is_err() { | ||||
|                     break; | ||||
|                 }; | ||||
|                 if !*client_live.read().await { | ||||
|                     break; | ||||
|                 }; | ||||
|             } | ||||
|  | ||||
|             *client_live.write().await = false; | ||||
|         }); | ||||
|  | ||||
|         // Relay server messages to the client | ||||
|         tokio::spawn(async move { | ||||
|             while let Some(Ok(msg)) = serverstream.next().await { | ||||
|                 if (clientsink.send(msg.into()).await).is_err() { | ||||
|                     break; | ||||
|                 }; | ||||
|                 if !*server_live.read().await { | ||||
|                     break; | ||||
|                 }; | ||||
|             } | ||||
|  | ||||
|             *server_live.write().await = false; | ||||
|         }); | ||||
|     }) | ||||
|     .into_response() | ||||
| } | ||||
| use actix_files::{NamedFile}; | ||||
| use actix_proxy::IntoHttpResponse; | ||||
| use actix_web::{HttpRequest, HttpResponse, web}; | ||||
| use actix_web::http::Method; | ||||
| use awc::Client; | ||||
|  | ||||
| pub async fn respond_hypertext( | ||||
|     uri: String, | ||||
|     ori: &Uri, | ||||
|     req: &Request, | ||||
|     method: Method, | ||||
|     body: Body, | ||||
|     headers: &HeaderMap, | ||||
| ) -> Result<Response, Error> { | ||||
|     let ip = req.remote_addr().to_string(); | ||||
|     req: HttpRequest, | ||||
|     client: web::Data<Client>, | ||||
| ) -> Result<HttpResponse, HttpResponse> { | ||||
|     let ip = req.peer_addr().unwrap().ip().to_string(); | ||||
|     let proto = req.uri().scheme_str().unwrap(); | ||||
|     let host = req.uri().host().unwrap(); | ||||
|  | ||||
|     let mut headers = headers.clone(); | ||||
|     headers.insert("Server", "RoadSign".parse().unwrap()); | ||||
|     headers.insert("X-Forward-For", ip.parse().unwrap()); | ||||
|     headers.insert("X-Forwarded-Proto", proto.parse().unwrap()); | ||||
|     headers.insert("X-Forwarded-Host", host.parse().unwrap()); | ||||
|     headers.insert("X-Real-IP", ip.parse().unwrap()); | ||||
|     let mut headers = req.headers().clone(); | ||||
|     headers.insert("Server".parse().unwrap(), "RoadSign".parse().unwrap()); | ||||
|     headers.insert("X-Forward-For".parse().unwrap(), ip.parse().unwrap()); | ||||
|     headers.insert("X-Forwarded-Proto".parse().unwrap(), proto.parse().unwrap()); | ||||
|     headers.insert("X-Forwarded-Host".parse().unwrap(), host.parse().unwrap()); | ||||
|     headers.insert("X-Real-IP".parse().unwrap(), ip.parse().unwrap()); | ||||
|     headers.insert( | ||||
|         "Forwarded", | ||||
|         "Forwarded".parse().unwrap(), | ||||
|         format!("by={};for={};host={};proto={}", ip, ip, host, proto) | ||||
|             .parse() | ||||
|             .unwrap(), | ||||
|     ); | ||||
|  | ||||
|     let res = CLIENT | ||||
|         .request(method, uri + ori.path() + ori.query().unwrap_or("")) | ||||
|         .headers(headers.clone()) | ||||
|         .body(body.into_bytes().await.unwrap()) | ||||
|         .send() | ||||
|         .await; | ||||
|     let res = client.get(uri).send().await; | ||||
|  | ||||
|     match res { | ||||
|     return match res { | ||||
|         Ok(result) => { | ||||
|             let mut res = Response::default(); | ||||
|             res.extensions().clone_from(&result.extensions()); | ||||
|             result.headers().iter().for_each(|(key, val)| { | ||||
|                 res.headers_mut().insert(key, val.to_owned()); | ||||
|             }); | ||||
|             res.headers_mut() | ||||
|                 .insert("Server", "RoadSign".parse().unwrap()); | ||||
|             res.set_status(result.status()); | ||||
|             res.set_version(result.version()); | ||||
|             res.set_body(result.bytes().await.unwrap()); | ||||
|             let mut res = result.into_http_response(); | ||||
|             res.headers_mut().insert("Server".parse().unwrap(), "RoadSign".parse().unwrap()); | ||||
|             Ok(res) | ||||
|         } | ||||
|  | ||||
|         Err(error) => Err(Error::from_string( | ||||
|             error.to_string(), | ||||
|             error.status().unwrap_or(StatusCode::BAD_GATEWAY), | ||||
|         )), | ||||
|     } | ||||
|         Err(error) => { | ||||
|             Err(HttpResponse::BadGateway() | ||||
|                 .body(format!("Something went wrong... {:}", error))) | ||||
|         } | ||||
|     }; | ||||
| } | ||||
|  | ||||
| pub struct StaticResponderConfig { | ||||
| @@ -126,14 +59,11 @@ pub struct StaticResponderConfig { | ||||
|  | ||||
| pub async fn respond_static( | ||||
|     cfg: StaticResponderConfig, | ||||
|     method: Method, | ||||
|     req: &Request, | ||||
| ) -> Result<Response, Error> { | ||||
|     if method != Method::GET { | ||||
|         return Err(Error::from_string( | ||||
|             "This destination only support GET request.", | ||||
|             StatusCode::METHOD_NOT_ALLOWED, | ||||
|         )); | ||||
|     req: HttpRequest, | ||||
| ) -> Result<HttpResponse, HttpResponse> { | ||||
|     if req.method() != Method::GET { | ||||
|         return Err(HttpResponse::MethodNotAllowed() | ||||
|             .body("This destination only support GET request.")); | ||||
|     } | ||||
|  | ||||
|     let path = req | ||||
| @@ -142,9 +72,12 @@ pub async fn respond_static( | ||||
|         .trim_start_matches('/') | ||||
|         .trim_end_matches('/'); | ||||
|  | ||||
|     let path = percent_encoding::percent_decode_str(path) | ||||
|         .decode_utf8() | ||||
|         .map_err(|_| Error::from_status(StatusCode::NOT_FOUND))?; | ||||
|     let path = match percent_encoding::percent_decode_str(path).decode_utf8() { | ||||
|         Ok(val) => val, | ||||
|         Err(_) => { | ||||
|             return Err(HttpResponse::NotFound().body("Not found.")); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     let base_path = cfg.uri.parse::<PathBuf>().unwrap(); | ||||
|     let mut file_path = base_path.clone(); | ||||
| @@ -159,7 +92,8 @@ pub async fn respond_static( | ||||
|     } | ||||
|  | ||||
|     if !file_path.starts_with(cfg.uri) { | ||||
|         return Err(Error::from_status(StatusCode::FORBIDDEN)); | ||||
|         return Err(HttpResponse::Forbidden() | ||||
|             .body("Unexpected path.")); | ||||
|     } | ||||
|  | ||||
|     if !file_path.exists() { | ||||
| @@ -172,87 +106,30 @@ pub async fn respond_static( | ||||
|             file_path.pop(); | ||||
|             file_path.push((file_name + &suffix).as_str()); | ||||
|             if file_path.is_file() { | ||||
|                 return Ok(StaticFileRequest::from_request_without_body(req) | ||||
|                     .await? | ||||
|                     .create_response(&file_path, cfg.utf8)? | ||||
|                     .into_response()); | ||||
|                 return Ok(NamedFile::open(file_path).unwrap().into_response(&req)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if let Some(file) = cfg.fallback { | ||||
|             let fallback_path = base_path.join(file); | ||||
|             if fallback_path.is_file() { | ||||
|                 return Ok(StaticFileRequest::from_request_without_body(req) | ||||
|                     .await? | ||||
|                     .create_response(&fallback_path, cfg.utf8)? | ||||
|                     .into_response()); | ||||
|                 return Ok(NamedFile::open(fallback_path).unwrap().into_response(&req)); | ||||
|             } | ||||
|         } | ||||
|         return Err(Error::from_status(StatusCode::NOT_FOUND)); | ||||
|  | ||||
|         return Err(HttpResponse::NotFound().body("Not found.")); | ||||
|     } | ||||
|  | ||||
|     if file_path.is_file() { | ||||
|         Ok(StaticFileRequest::from_request_without_body(req) | ||||
|             .await? | ||||
|             .create_response(&file_path, cfg.utf8)? | ||||
|             .into_response()) | ||||
|     return if file_path.is_file() { | ||||
|         Ok(NamedFile::open(file_path).unwrap().into_response(&req)) | ||||
|     } else { | ||||
|         if cfg.with_slash | ||||
|             && !req.original_uri().path().ends_with('/') | ||||
|             && (cfg.index.is_some() || cfg.browse) | ||||
|         { | ||||
|             let redirect_to = format!("{}/", req.original_uri().path()); | ||||
|             return Ok(Response::builder() | ||||
|                 .status(StatusCode::FOUND) | ||||
|                 .header(header::LOCATION, redirect_to) | ||||
|                 .finish()); | ||||
|         } | ||||
|  | ||||
|         if let Some(index_file) = &cfg.index { | ||||
|             let index_path = file_path.join(index_file); | ||||
|             if index_path.is_file() { | ||||
|                 return Ok(StaticFileRequest::from_request_without_body(req) | ||||
|                     .await? | ||||
|                     .create_response(&index_path, cfg.utf8)? | ||||
|                     .into_response()); | ||||
|                 return Ok(NamedFile::open(index_path).unwrap().into_response(&req)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if cfg.browse { | ||||
|             let read_dir = file_path | ||||
|                 .read_dir() | ||||
|                 .map_err(|_| Error::from_status(StatusCode::FORBIDDEN))?; | ||||
|             let mut template = DirectoryTemplate { | ||||
|                 path: &path, | ||||
|                 files: Vec::new(), | ||||
|             }; | ||||
|  | ||||
|             for res in read_dir { | ||||
|                 let entry = res.map_err(|_| Error::from_status(StatusCode::FORBIDDEN))?; | ||||
|  | ||||
|                 if let Some(filename) = entry.file_name().to_str() { | ||||
|                     let mut base_url = req.original_uri().path().to_string(); | ||||
|                     if !base_url.ends_with('/') { | ||||
|                         base_url.push('/'); | ||||
|                     } | ||||
|                     let filename_url = percent_encoding::percent_encode( | ||||
|                         filename.as_bytes(), | ||||
|                         percent_encoding::NON_ALPHANUMERIC, | ||||
|                     ); | ||||
|                     template.files.push(FileRef { | ||||
|                         url: format!("{base_url}{filename_url}"), | ||||
|                         filename: filename.to_string(), | ||||
|                         is_dir: entry.path().is_dir(), | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             let html = template.render(); | ||||
|             Ok(Response::builder() | ||||
|                 .header(header::CONTENT_TYPE, mime::TEXT_HTML_UTF_8.as_ref()) | ||||
|                 .body(Body::from_string(html))) | ||||
|         } else { | ||||
|             Err(Error::from_status(StatusCode::NOT_FOUND)) | ||||
|         } | ||||
|     } | ||||
|         Err(HttpResponse::NotFound().body("Not found.")) | ||||
|     }; | ||||
| } | ||||
|   | ||||
| @@ -1,10 +1,5 @@ | ||||
| use http::Method; | ||||
| use poem::{ | ||||
|     handler, | ||||
|     http::{HeaderMap, StatusCode, Uri}, | ||||
|     web::websocket::WebSocket, | ||||
|     Body, Error, FromRequest, IntoResponse, Request, Response, Result, | ||||
| }; | ||||
| use actix_web::{HttpRequest, HttpResponse, web}; | ||||
| use awc::Client; | ||||
| use rand::seq::SliceRandom; | ||||
|  | ||||
| use crate::{ | ||||
| @@ -15,22 +10,13 @@ use crate::{ | ||||
|     ROAD, | ||||
| }; | ||||
|  | ||||
| #[handler] | ||||
| pub async fn handle( | ||||
|     req: &Request, | ||||
|     uri: &Uri, | ||||
|     headers: &HeaderMap, | ||||
|     method: Method, | ||||
|     body: Body, | ||||
| ) -> Result<impl IntoResponse, Error> { | ||||
| pub async fn handle(req: HttpRequest, client: web::Data<Client>) -> HttpResponse { | ||||
|     let readable_app = ROAD.lock().await; | ||||
|     let (region, location) = match readable_app.filter(uri, method.clone(), headers) { | ||||
|     let (region, location) = match readable_app.filter(req.uri(), req.method(), req.headers()) { | ||||
|         Some(val) => val, | ||||
|         None => { | ||||
|             return Err(Error::from_string( | ||||
|                 "There are no region be able to respone this request.", | ||||
|                 StatusCode::NOT_FOUND, | ||||
|             )) | ||||
|             return HttpResponse::NotFound() | ||||
|                 .body("There are no region be able to respone this request."); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| @@ -41,58 +27,31 @@ pub async fn handle( | ||||
|  | ||||
|     async fn forward( | ||||
|         end: &Destination, | ||||
|         req: &Request, | ||||
|         ori: &Uri, | ||||
|         headers: &HeaderMap, | ||||
|         method: Method, | ||||
|         body: Body, | ||||
|     ) -> Result<Response, Error> { | ||||
|         // Handle websocket | ||||
|         if let Ok(ws) = WebSocket::from_request_without_body(req).await { | ||||
|             // Get uri | ||||
|             let Ok(uri) = end.get_websocket_uri() else { | ||||
|                 return Err(Error::from_string( | ||||
|                     "This destination was not support websockets.", | ||||
|                     StatusCode::NOT_IMPLEMENTED, | ||||
|                 )); | ||||
|             }; | ||||
|  | ||||
|             // Build request | ||||
|             let mut ws_req = http::Request::builder().uri(&uri); | ||||
|             for (key, value) in headers.iter() { | ||||
|                 ws_req = ws_req.header(key, value); | ||||
|             } | ||||
|  | ||||
|             // Start the websocket connection | ||||
|             return Ok(responder::repond_websocket(ws_req, ws).await); | ||||
|         } | ||||
|  | ||||
|         req: HttpRequest, | ||||
|         client: web::Data<Client>, | ||||
|     ) -> Result<HttpResponse, HttpResponse> { | ||||
|         // Handle normal web request | ||||
|         match end.get_type() { | ||||
|             DestinationType::Hypertext => { | ||||
|                 let Ok(uri) = end.get_hypertext_uri() else { | ||||
|                     return Err(Error::from_string( | ||||
|                         "This destination was not support web requests.", | ||||
|                         StatusCode::NOT_IMPLEMENTED, | ||||
|                     )); | ||||
|                     return Err(HttpResponse::NotImplemented() | ||||
|                         .body("This destination was not support web requests.")); | ||||
|                 }; | ||||
|  | ||||
|                 responder::respond_hypertext(uri, ori, req, method, body, headers).await | ||||
|                 responder::respond_hypertext(uri, req, client).await | ||||
|             } | ||||
|             DestinationType::StaticFiles => { | ||||
|                 let Ok(cfg) = end.get_static_config() else { | ||||
|                     return Err(Error::from_string( | ||||
|                         "This destination was not support static files.", | ||||
|                         StatusCode::NOT_IMPLEMENTED, | ||||
|                     )); | ||||
|                     return Err(HttpResponse::NotImplemented() | ||||
|                         .body("This destination was not support static files.")); | ||||
|                 }; | ||||
|  | ||||
|                 responder::respond_static(cfg, method, req).await | ||||
|                 responder::respond_static(cfg, req).await | ||||
|             } | ||||
|             _ => { | ||||
|                 return Err(HttpResponse::NotImplemented() | ||||
|                     .body("Unsupported destination protocol.")); | ||||
|             } | ||||
|             _ => Err(Error::from_string( | ||||
|                 "Unsupported destination protocol.", | ||||
|                 StatusCode::NOT_IMPLEMENTED, | ||||
|             )), | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -100,23 +59,22 @@ pub async fn handle( | ||||
|     let loc = location.clone(); | ||||
|     let end = destination.clone(); | ||||
|  | ||||
|     match forward(&end, req, uri, headers, method, body).await { | ||||
|     return match forward(&end, req, client).await { | ||||
|         Ok(resp) => { | ||||
|             tokio::spawn(async move { | ||||
|                 let writable_app = &mut ROAD.lock().await; | ||||
|                 writable_app.metrics.add_success_request(reg, loc, end); | ||||
|             }); | ||||
|             Ok(resp) | ||||
|             resp | ||||
|         } | ||||
|         Err(err) => { | ||||
|             let message = format!("{:}", err); | ||||
|         Err(resp) => { | ||||
|             tokio::spawn(async move { | ||||
|                 let writable_app = &mut ROAD.lock().await; | ||||
|                 writable_app | ||||
|                     .metrics | ||||
|                     .add_faliure_request(reg, loc, end, message); | ||||
|                     .add_faliure_request(reg, loc, end, "TODO".to_owned()); | ||||
|             }); | ||||
|             Err(err) | ||||
|             resp | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,19 +0,0 @@ | ||||
| use poem_openapi::OpenApi; | ||||
|  | ||||
| pub mod overview; | ||||
| pub mod regions; | ||||
|  | ||||
| pub struct SideloadApi; | ||||
|  | ||||
| #[OpenApi] | ||||
| impl SideloadApi { | ||||
|     #[oai(path = "/", method = "get")] | ||||
|     async fn index(&self) -> overview::OverviewResponse { | ||||
|         overview::index().await | ||||
|     } | ||||
|  | ||||
|     #[oai(path = "/regions", method = "get")] | ||||
|     async fn regions_index(&self) -> regions::RegionResponse { | ||||
|         regions::index().await | ||||
|     } | ||||
| } | ||||
| @@ -1,75 +0,0 @@ | ||||
| use poem_openapi::{payload::Json, ApiResponse, Object}; | ||||
|  | ||||
| use crate::{ | ||||
|     proxies::{ | ||||
|         config::{Destination, Location}, | ||||
|         metrics::RoadTrace, | ||||
|     }, | ||||
|     ROAD, | ||||
| }; | ||||
|  | ||||
| #[derive(ApiResponse)] | ||||
| pub enum OverviewResponse { | ||||
|     /// Return the overview data. | ||||
|     #[oai(status = 200)] | ||||
|     Ok(Json<OverviewData>), | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Object, Clone, PartialEq)] | ||||
| pub struct OverviewData { | ||||
|     /// Loaded regions count | ||||
|     #[oai(read_only)] | ||||
|     regions: usize, | ||||
|     /// Loaded locations count | ||||
|     #[oai(read_only)] | ||||
|     locations: usize, | ||||
|     /// Loaded destnations count | ||||
|     #[oai(read_only)] | ||||
|     destinations: usize, | ||||
|     /// Recent requests count | ||||
|     requests_count: u64, | ||||
|     /// Recent requests success count | ||||
|     faliures_count: u64, | ||||
|     /// Recent requests falied count | ||||
|     successes_count: u64, | ||||
|     /// Recent requests success rate | ||||
|     success_rate: f64, | ||||
|     /// Recent successes | ||||
|     recent_successes: Vec<RoadTrace>, | ||||
|     /// Recent errors | ||||
|     recent_errors: Vec<RoadTrace>, | ||||
| } | ||||
|  | ||||
| pub async fn index() -> OverviewResponse { | ||||
|     let locked_app = ROAD.lock().await; | ||||
|     let regions = locked_app.regions.clone(); | ||||
|     let locations = regions | ||||
|         .iter() | ||||
|         .flat_map(|item| item.locations.clone()) | ||||
|         .collect::<Vec<Location>>(); | ||||
|     let destinations = locations | ||||
|         .iter() | ||||
|         .flat_map(|item| item.destinations.clone()) | ||||
|         .collect::<Vec<Destination>>(); | ||||
|     OverviewResponse::Ok(Json(OverviewData { | ||||
|         regions: regions.len(), | ||||
|         locations: locations.len(), | ||||
|         destinations: destinations.len(), | ||||
|         requests_count: locked_app.metrics.requests_count, | ||||
|         successes_count: locked_app.metrics.requests_count - locked_app.metrics.failures_count, | ||||
|         faliures_count: locked_app.metrics.failures_count, | ||||
|         success_rate: locked_app.metrics.get_success_rate(), | ||||
|         recent_successes: locked_app | ||||
|             .metrics | ||||
|             .recent_successes | ||||
|             .clone() | ||||
|             .into_iter() | ||||
|             .collect::<Vec<_>>(), | ||||
|         recent_errors: locked_app | ||||
|             .metrics | ||||
|             .recent_errors | ||||
|             .clone() | ||||
|             .into_iter() | ||||
|             .collect::<Vec<_>>(), | ||||
|     })) | ||||
| } | ||||
| @@ -1,25 +0,0 @@ | ||||
| use poem_openapi::{payload::Json, ApiResponse}; | ||||
|  | ||||
| use crate::{proxies::config::Region, ROAD}; | ||||
|  | ||||
| #[derive(ApiResponse)] | ||||
| pub enum RegionResponse { | ||||
|     /// Return the region data. | ||||
|     #[oai(status = 200)] | ||||
|     Ok(Json<Region>), | ||||
|     /// Return the list of region data. | ||||
|     #[oai(status = 200)] | ||||
|     OkMany(Json<Vec<Region>>), | ||||
|     /// Return the region data after created. | ||||
|     #[oai(status = 201)] | ||||
|     Created(Json<Region>), | ||||
|     /// Return was not found. | ||||
|     #[oai(status = 404)] | ||||
|     NotFound, | ||||
| } | ||||
|  | ||||
| pub async fn index() -> RegionResponse { | ||||
|     let locked_app = ROAD.lock().await; | ||||
|  | ||||
|     RegionResponse::OkMany(Json(locked_app.regions.clone())) | ||||
| } | ||||
							
								
								
									
										179
									
								
								test/data/warden/dist/client/_astro/Media.7FWSwaPB.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								test/data/warden/dist/client/_astro/Media.7FWSwaPB.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								test/data/warden/dist/client/_astro/Media.Co8_pG1j.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/_astro/Media.Co8_pG1j.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								test/data/warden/dist/client/_astro/_slug_.bcjV8AoT.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/_astro/_slug_.bcjV8AoT.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| :root{--bs-body-font-family: "IBM Plex Serif", "Noto Serif SC", sans-serif !important}html,body{font-family:var(--bs-body-font-family)}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:100;src:url(/_astro/ibm-plex-serif-v19-latin-100.6qNbweSL.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:100;src:url(/_astro/ibm-plex-serif-v19-latin-100italic.E22nrI7z.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:200;src:url(/_astro/ibm-plex-serif-v19-latin-200.GFXE_YJc.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:200;src:url(/_astro/ibm-plex-serif-v19-latin-200italic.pJK4yaaG.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:300;src:url(/_astro/ibm-plex-serif-v19-latin-300.RVbRgkxX.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:300;src:url(/_astro/ibm-plex-serif-v19-latin-300italic.ZdSVgmcR.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:400;src:url(/_astro/ibm-plex-serif-v19-latin-regular.HRmMD3sQ.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:400;src:url(/_astro/ibm-plex-serif-v19-latin-italic.MiJiQVsi.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:500;src:url(/_astro/ibm-plex-serif-v19-latin-500.xAA_w-Ac.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:500;src:url(/_astro/ibm-plex-serif-v19-latin-500italic.Unq84pJ7.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:600;src:url(/_astro/ibm-plex-serif-v19-latin-600.cuuqzllG.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:600;src:url(/_astro/ibm-plex-serif-v19-latin-600italic.vDhUog1q.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:normal;font-weight:700;src:url(/_astro/ibm-plex-serif-v19-latin-700.yX9JjmCp.woff2) format("woff2")}@font-face{font-display:swap;font-family:"IBM Plex Serif";font-style:italic;font-weight:700;src:url(/_astro/ibm-plex-serif-v19-latin-700italic.QM1RA0vx.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:200;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-200.g4OBZhIi.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:300;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-300.yFtdUYoh.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:400;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-regular.9muiKgFz.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:500;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-500.exkAspFQ.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:600;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-600.4n6uFOXj.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:700;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-700.HyiB9Pzv.woff2) format("woff2")}@font-face{font-display:swap;font-family:"Noto Serif SC";font-style:normal;font-weight:900;src:url(/_astro/noto-serif-sc-v22-chinese-simplified-900.ERSRy_0V.woff2) format("woff2")}.astro-route-announcer{position:absolute;left:0;top:0;clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);overflow:hidden;white-space:nowrap;width:1px;height:1px}.h-fullpage{height:calc(100vh - 64px)}.max-h-fullpage{max-height:calc(100vh - 64px)}.mt-header{margin-top:64px}.top-header{top:64px}html{overflow-x:hidden!important;overflow-y:auto!important}@keyframes astroFadeInOut{0%{opacity:1}to{opacity:0}}@keyframes astroFadeIn{0%{opacity:0}}@keyframes astroFadeOut{to{opacity:0}}@keyframes astroSlideFromRight{0%{transform:translate(100%)}}@keyframes astroSlideFromLeft{0%{transform:translate(-100%)}}@keyframes astroSlideToRight{to{transform:translate(100%)}}@keyframes astroSlideToLeft{to{transform:translate(-100%)}}@media (prefers-reduced-motion){::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}[data-astro-transition-scope]{animation:none!important}} | ||||
							
								
								
									
										1
									
								
								test/data/warden/dist/client/_astro/_slug_.yOjdTrIk.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/_astro/_slug_.yOjdTrIk.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										24
									
								
								test/data/warden/dist/client/_astro/client.olTvLX7Y.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								test/data/warden/dist/client/_astro/client.olTvLX7Y.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										1
									
								
								test/data/warden/dist/client/_astro/hoisted.l-JsOPk0.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/_astro/hoisted.l-JsOPk0.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-100.6qNbweSL.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-100.6qNbweSL.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-100italic.E22nrI7z.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-100italic.E22nrI7z.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-200.GFXE_YJc.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-200.GFXE_YJc.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-200italic.pJK4yaaG.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-200italic.pJK4yaaG.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-300.RVbRgkxX.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-300.RVbRgkxX.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-300italic.ZdSVgmcR.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-300italic.ZdSVgmcR.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-500.xAA_w-Ac.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-500.xAA_w-Ac.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-500italic.Unq84pJ7.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-500italic.Unq84pJ7.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-600.cuuqzllG.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-600.cuuqzllG.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-600italic.vDhUog1q.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-600italic.vDhUog1q.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-700.yX9JjmCp.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-700.yX9JjmCp.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-700italic.QM1RA0vx.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-700italic.QM1RA0vx.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-italic.MiJiQVsi.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-italic.MiJiQVsi.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-regular.HRmMD3sQ.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/ibm-plex-serif-v19-latin-regular.HRmMD3sQ.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										9
									
								
								test/data/warden/dist/client/_astro/index.LFf77hJu.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/data/warden/dist/client/_astro/index.LFf77hJu.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-200.g4OBZhIi.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-200.g4OBZhIi.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-300.yFtdUYoh.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-300.yFtdUYoh.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-500.exkAspFQ.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-500.exkAspFQ.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-600.4n6uFOXj.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-600.4n6uFOXj.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-700.HyiB9Pzv.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-700.HyiB9Pzv.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-900.ERSRy_0V.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-900.ERSRy_0V.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-regular.9muiKgFz.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/_astro/noto-serif-sc-v22-chinese-simplified-regular.9muiKgFz.woff2
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2
									
								
								test/data/warden/dist/client/admin/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								test/data/warden/dist/client/admin/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| index.html | ||||
| assets/ | ||||
							
								
								
									
										21
									
								
								test/data/warden/dist/client/favicon.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								test/data/warden/dist/client/favicon.svg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" width="1024" height="1024"> | ||||
| 	<title>SmartSheep Logo</title> | ||||
| 	<defs> | ||||
| 		<image  width="124" height="198" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHwAAADGCAMAAAAnkRSfAAAAAXNSR0IB2cksfwAAAq9QTFRFAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////J9QBRAAAAOV0Uk5TAA0WEiFfjMLMr40/BRdmtuz//vbQYAQmpfLdQAGovyURj/iOD0r07loDGJfbPDTf/bhd94QLdPrrVQLWcPmtHU31egknzehRg9Ev1xnzbgYHhfzmTMorSOSbFJloKsniReXDKG/7kQ6m8WMw3ue7I4cKNdTZOFTqsR5/Hzra0zZY7al4Ir5SPWHvnpbG4MRrlKJs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"/> | ||||
| 		<image  width="122" height="142" id="img2" href="data:image/png;base64,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"/> | ||||
| 	</defs> | ||||
| 	<style> | ||||
| 		.s0 { fill: #ffffff;stroke: #000000;stroke-miterlimit:100;stroke-width: 56 }  | ||||
| 		.s1 { fill: #4750a3;stroke: #000000;stroke-miterlimit:100;stroke-width: 56 }  | ||||
| 	</style> | ||||
| 	<path id="Wool" fill-rule="evenodd" class="s0" d="m128 608.4c0 95.9 77.4 173.6 172.8 173.6h441.6c84.8 0 153.6-69.1 153.6-154.3 0-74.6-52.8-136.9-122.9-151.1 4.9-12.9 7.7-27 7.7-41.7 0-63.9-51.6-115.8-115.2-115.8-23.6 0-45.7 7.3-64 19.6-33.2-57.9-95.2-96.7-166.4-96.7-106.1 0-192 86.3-192 192.9 0 3.2 0.1 6.5 0.2 9.7-67.2 23.8-115.4 88.1-115.4 163.8z"/> | ||||
| 	<g id="Crystal"> | ||||
| 		<path id="Crystal" class="s1" d="m699 224l138.6 80v160l-138.6 80-138.6-80v-160z"/> | ||||
| 		<use id="Highlight" href="#img1" x="688" y="255"/> | ||||
| 	</g> | ||||
| 	<g id="Horn"> | ||||
| 	</g> | ||||
| 	<g id="Face"> | ||||
| 		<use id="Slime" href="#img2" x="233" y="538"/> | ||||
| 	</g> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 8.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								test/data/warden/dist/client/media/nicolas-saintot-xkFhOdId7mA-unsplash.jpg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/data/warden/dist/client/media/nicolas-saintot-xkFhOdId7mA-unsplash.jpg
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.3 MiB | 
							
								
								
									
										1
									
								
								test/data/warden/dist/client/sitemap-0.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/sitemap-0.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://smartsheep.studio/</loc></url><url><loc>https://smartsheep.studio/events/</loc></url><url><loc>https://smartsheep.studio/posts/</loc></url></urlset> | ||||
							
								
								
									
										1
									
								
								test/data/warden/dist/client/sitemap-index.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/data/warden/dist/client/sitemap-index.xml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>https://smartsheep.studio/sitemap-0.xml</loc></sitemap></sitemapindex> | ||||
							
								
								
									
										3
									
								
								test/data/warden/dist/server/_empty-middleware.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/data/warden/dist/server/_empty-middleware.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| const onRequest = undefined; | ||||
|  | ||||
| export { onRequest }; | ||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__3BAY271A.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__3BAY271A.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| export { renderers } from '../renderers.mjs'; | ||||
| export { onRequest } from '../_empty-middleware.mjs'; | ||||
|  | ||||
| const page = () => import('./pages/_slug__TUDhKBhQ.mjs').then(n => n.c); | ||||
|  | ||||
| export { page }; | ||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__EgGcJ0nJ.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__EgGcJ0nJ.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| export { renderers } from '../renderers.mjs'; | ||||
| export { onRequest } from '../_empty-middleware.mjs'; | ||||
|  | ||||
| const page = () => import('./pages/_slug__TUDhKBhQ.mjs').then(n => n._); | ||||
|  | ||||
| export { page }; | ||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__wxGnmrgA.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/_slug__wxGnmrgA.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| export { renderers } from '../renderers.mjs'; | ||||
| export { onRequest } from '../_empty-middleware.mjs'; | ||||
|  | ||||
| const page = () => import('./pages/_slug__TUDhKBhQ.mjs').then(n => n.d); | ||||
|  | ||||
| export { page }; | ||||
							
								
								
									
										342
									
								
								test/data/warden/dist/server/chunks/astro/assets-service_4dMyVCFm.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								test/data/warden/dist/server/chunks/astro/assets-service_4dMyVCFm.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,342 @@ | ||||
| import { isRemotePath, joinPaths } from '@astrojs/internal-helpers/path'; | ||||
| import { A as AstroError, E as ExpectedImage, L as LocalImageUsedWrongly, M as MissingImageDimension, U as UnsupportedImageFormat, I as IncompatibleDescriptorOptions, a as UnsupportedImageConversion, b as MissingSharp } from '../astro_5WdVqH1c.mjs'; | ||||
|  | ||||
| const VALID_SUPPORTED_FORMATS = [ | ||||
|   "jpeg", | ||||
|   "jpg", | ||||
|   "png", | ||||
|   "tiff", | ||||
|   "webp", | ||||
|   "gif", | ||||
|   "svg", | ||||
|   "avif" | ||||
| ]; | ||||
| const DEFAULT_OUTPUT_FORMAT = "webp"; | ||||
| const DEFAULT_HASH_PROPS = ["src", "width", "height", "format", "quality"]; | ||||
|  | ||||
| function isESMImportedImage(src) { | ||||
|   return typeof src === "object"; | ||||
| } | ||||
| function isRemoteImage(src) { | ||||
|   return typeof src === "string"; | ||||
| } | ||||
|  | ||||
| function matchPattern(url, remotePattern) { | ||||
|   return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true); | ||||
| } | ||||
| function matchPort(url, port) { | ||||
|   return !port || port === url.port; | ||||
| } | ||||
| function matchProtocol(url, protocol) { | ||||
|   return !protocol || protocol === url.protocol.slice(0, -1); | ||||
| } | ||||
| function matchHostname(url, hostname, allowWildcard) { | ||||
|   if (!hostname) { | ||||
|     return true; | ||||
|   } else if (!allowWildcard || !hostname.startsWith("*")) { | ||||
|     return hostname === url.hostname; | ||||
|   } else if (hostname.startsWith("**.")) { | ||||
|     const slicedHostname = hostname.slice(2); | ||||
|     return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname); | ||||
|   } else if (hostname.startsWith("*.")) { | ||||
|     const slicedHostname = hostname.slice(1); | ||||
|     const additionalSubdomains = url.hostname.replace(slicedHostname, "").split(".").filter(Boolean); | ||||
|     return additionalSubdomains.length === 1; | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| function matchPathname(url, pathname, allowWildcard) { | ||||
|   if (!pathname) { | ||||
|     return true; | ||||
|   } else if (!allowWildcard || !pathname.endsWith("*")) { | ||||
|     return pathname === url.pathname; | ||||
|   } else if (pathname.endsWith("/**")) { | ||||
|     const slicedPathname = pathname.slice(0, -2); | ||||
|     return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname); | ||||
|   } else if (pathname.endsWith("/*")) { | ||||
|     const slicedPathname = pathname.slice(0, -1); | ||||
|     const additionalPathChunks = url.pathname.replace(slicedPathname, "").split("/").filter(Boolean); | ||||
|     return additionalPathChunks.length === 1; | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| function isRemoteAllowed(src, { | ||||
|   domains = [], | ||||
|   remotePatterns = [] | ||||
| }) { | ||||
|   if (!isRemotePath(src)) | ||||
|     return false; | ||||
|   const url = new URL(src); | ||||
|   return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern)); | ||||
| } | ||||
|  | ||||
| function isLocalService(service) { | ||||
|   if (!service) { | ||||
|     return false; | ||||
|   } | ||||
|   return "transform" in service; | ||||
| } | ||||
| function parseQuality(quality) { | ||||
|   let result = parseInt(quality); | ||||
|   if (Number.isNaN(result)) { | ||||
|     return quality; | ||||
|   } | ||||
|   return result; | ||||
| } | ||||
| const baseService = { | ||||
|   propertiesToHash: DEFAULT_HASH_PROPS, | ||||
|   validateOptions(options) { | ||||
|     if (!options.src || typeof options.src !== "string" && typeof options.src !== "object") { | ||||
|       throw new AstroError({ | ||||
|         ...ExpectedImage, | ||||
|         message: ExpectedImage.message( | ||||
|           JSON.stringify(options.src), | ||||
|           typeof options.src, | ||||
|           JSON.stringify(options, (_, v) => v === void 0 ? null : v) | ||||
|         ) | ||||
|       }); | ||||
|     } | ||||
|     if (!isESMImportedImage(options.src)) { | ||||
|       if (options.src.startsWith("/@fs/") || !isRemotePath(options.src) && !options.src.startsWith("/")) { | ||||
|         throw new AstroError({ | ||||
|           ...LocalImageUsedWrongly, | ||||
|           message: LocalImageUsedWrongly.message(options.src) | ||||
|         }); | ||||
|       } | ||||
|       let missingDimension; | ||||
|       if (!options.width && !options.height) { | ||||
|         missingDimension = "both"; | ||||
|       } else if (!options.width && options.height) { | ||||
|         missingDimension = "width"; | ||||
|       } else if (options.width && !options.height) { | ||||
|         missingDimension = "height"; | ||||
|       } | ||||
|       if (missingDimension) { | ||||
|         throw new AstroError({ | ||||
|           ...MissingImageDimension, | ||||
|           message: MissingImageDimension.message(missingDimension, options.src) | ||||
|         }); | ||||
|       } | ||||
|     } else { | ||||
|       if (!VALID_SUPPORTED_FORMATS.includes(options.src.format)) { | ||||
|         throw new AstroError({ | ||||
|           ...UnsupportedImageFormat, | ||||
|           message: UnsupportedImageFormat.message( | ||||
|             options.src.format, | ||||
|             options.src.src, | ||||
|             VALID_SUPPORTED_FORMATS | ||||
|           ) | ||||
|         }); | ||||
|       } | ||||
|       if (options.widths && options.densities) { | ||||
|         throw new AstroError(IncompatibleDescriptorOptions); | ||||
|       } | ||||
|       if (options.src.format === "svg") { | ||||
|         options.format = "svg"; | ||||
|       } | ||||
|       if (options.src.format === "svg" && options.format !== "svg" || options.src.format !== "svg" && options.format === "svg") { | ||||
|         throw new AstroError(UnsupportedImageConversion); | ||||
|       } | ||||
|     } | ||||
|     if (!options.format) { | ||||
|       options.format = DEFAULT_OUTPUT_FORMAT; | ||||
|     } | ||||
|     if (options.width) | ||||
|       options.width = Math.round(options.width); | ||||
|     if (options.height) | ||||
|       options.height = Math.round(options.height); | ||||
|     return options; | ||||
|   }, | ||||
|   getHTMLAttributes(options) { | ||||
|     const { targetWidth, targetHeight } = getTargetDimensions(options); | ||||
|     const { src, width, height, format, quality, densities, widths, formats, ...attributes } = options; | ||||
|     return { | ||||
|       ...attributes, | ||||
|       width: targetWidth, | ||||
|       height: targetHeight, | ||||
|       loading: attributes.loading ?? "lazy", | ||||
|       decoding: attributes.decoding ?? "async" | ||||
|     }; | ||||
|   }, | ||||
|   getSrcSet(options) { | ||||
|     const srcSet = []; | ||||
|     const { targetWidth } = getTargetDimensions(options); | ||||
|     const { widths, densities } = options; | ||||
|     const targetFormat = options.format ?? DEFAULT_OUTPUT_FORMAT; | ||||
|     let imageWidth = options.width; | ||||
|     let maxWidth = Infinity; | ||||
|     if (isESMImportedImage(options.src)) { | ||||
|       imageWidth = options.src.width; | ||||
|       maxWidth = imageWidth; | ||||
|     } | ||||
|     const { | ||||
|       width: transformWidth, | ||||
|       height: transformHeight, | ||||
|       ...transformWithoutDimensions | ||||
|     } = options; | ||||
|     const allWidths = []; | ||||
|     if (densities) { | ||||
|       const densityValues = densities.map((density) => { | ||||
|         if (typeof density === "number") { | ||||
|           return density; | ||||
|         } else { | ||||
|           return parseFloat(density); | ||||
|         } | ||||
|       }); | ||||
|       const densityWidths = densityValues.sort().map((density) => Math.round(targetWidth * density)); | ||||
|       allWidths.push( | ||||
|         ...densityWidths.map((width, index) => ({ | ||||
|           maxTargetWidth: Math.min(width, maxWidth), | ||||
|           descriptor: `${densityValues[index]}x` | ||||
|         })) | ||||
|       ); | ||||
|     } else if (widths) { | ||||
|       allWidths.push( | ||||
|         ...widths.map((width) => ({ | ||||
|           maxTargetWidth: Math.min(width, maxWidth), | ||||
|           descriptor: `${width}w` | ||||
|         })) | ||||
|       ); | ||||
|     } | ||||
|     for (const { maxTargetWidth, descriptor } of allWidths) { | ||||
|       const srcSetTransform = { ...transformWithoutDimensions }; | ||||
|       if (maxTargetWidth !== imageWidth) { | ||||
|         srcSetTransform.width = maxTargetWidth; | ||||
|       } else { | ||||
|         if (options.width && options.height) { | ||||
|           srcSetTransform.width = options.width; | ||||
|           srcSetTransform.height = options.height; | ||||
|         } | ||||
|       } | ||||
|       srcSet.push({ | ||||
|         transform: srcSetTransform, | ||||
|         descriptor, | ||||
|         attributes: { | ||||
|           type: `image/${targetFormat}` | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|     return srcSet; | ||||
|   }, | ||||
|   getURL(options, imageConfig) { | ||||
|     const searchParams = new URLSearchParams(); | ||||
|     if (isESMImportedImage(options.src)) { | ||||
|       searchParams.append("href", options.src.src); | ||||
|     } else if (isRemoteAllowed(options.src, imageConfig)) { | ||||
|       searchParams.append("href", options.src); | ||||
|     } else { | ||||
|       return options.src; | ||||
|     } | ||||
|     const params = { | ||||
|       w: "width", | ||||
|       h: "height", | ||||
|       q: "quality", | ||||
|       f: "format" | ||||
|     }; | ||||
|     Object.entries(params).forEach(([param, key]) => { | ||||
|       options[key] && searchParams.append(param, options[key].toString()); | ||||
|     }); | ||||
|     const imageEndpoint = joinPaths("/", "/_image"); | ||||
|     return `${imageEndpoint}?${searchParams}`; | ||||
|   }, | ||||
|   parseURL(url) { | ||||
|     const params = url.searchParams; | ||||
|     if (!params.has("href")) { | ||||
|       return void 0; | ||||
|     } | ||||
|     const transform = { | ||||
|       src: params.get("href"), | ||||
|       width: params.has("w") ? parseInt(params.get("w")) : void 0, | ||||
|       height: params.has("h") ? parseInt(params.get("h")) : void 0, | ||||
|       format: params.get("f"), | ||||
|       quality: params.get("q") | ||||
|     }; | ||||
|     return transform; | ||||
|   } | ||||
| }; | ||||
| function getTargetDimensions(options) { | ||||
|   let targetWidth = options.width; | ||||
|   let targetHeight = options.height; | ||||
|   if (isESMImportedImage(options.src)) { | ||||
|     const aspectRatio = options.src.width / options.src.height; | ||||
|     if (targetHeight && !targetWidth) { | ||||
|       targetWidth = Math.round(targetHeight * aspectRatio); | ||||
|     } else if (targetWidth && !targetHeight) { | ||||
|       targetHeight = Math.round(targetWidth / aspectRatio); | ||||
|     } else if (!targetWidth && !targetHeight) { | ||||
|       targetWidth = options.src.width; | ||||
|       targetHeight = options.src.height; | ||||
|     } | ||||
|   } | ||||
|   return { | ||||
|     targetWidth, | ||||
|     targetHeight | ||||
|   }; | ||||
| } | ||||
|  | ||||
| let sharp; | ||||
| const qualityTable = { | ||||
|   low: 25, | ||||
|   mid: 50, | ||||
|   high: 80, | ||||
|   max: 100 | ||||
| }; | ||||
| async function loadSharp() { | ||||
|   let sharpImport; | ||||
|   try { | ||||
|     sharpImport = (await import('sharp')).default; | ||||
|   } catch (e) { | ||||
|     throw new AstroError(MissingSharp); | ||||
|   } | ||||
|   return sharpImport; | ||||
| } | ||||
| const sharpService = { | ||||
|   validateOptions: baseService.validateOptions, | ||||
|   getURL: baseService.getURL, | ||||
|   parseURL: baseService.parseURL, | ||||
|   getHTMLAttributes: baseService.getHTMLAttributes, | ||||
|   getSrcSet: baseService.getSrcSet, | ||||
|   async transform(inputBuffer, transformOptions, config) { | ||||
|     if (!sharp) | ||||
|       sharp = await loadSharp(); | ||||
|     const transform = transformOptions; | ||||
|     if (transform.format === "svg") | ||||
|       return { data: inputBuffer, format: "svg" }; | ||||
|     const result = sharp(inputBuffer, { | ||||
|       failOnError: false, | ||||
|       pages: -1, | ||||
|       limitInputPixels: config.service.config.limitInputPixels | ||||
|     }); | ||||
|     result.rotate(); | ||||
|     if (transform.height && !transform.width) { | ||||
|       result.resize({ height: Math.round(transform.height) }); | ||||
|     } else if (transform.width) { | ||||
|       result.resize({ width: Math.round(transform.width) }); | ||||
|     } | ||||
|     if (transform.format) { | ||||
|       let quality = void 0; | ||||
|       if (transform.quality) { | ||||
|         const parsedQuality = parseQuality(transform.quality); | ||||
|         if (typeof parsedQuality === "number") { | ||||
|           quality = parsedQuality; | ||||
|         } else { | ||||
|           quality = transform.quality in qualityTable ? qualityTable[transform.quality] : void 0; | ||||
|         } | ||||
|       } | ||||
|       result.toFormat(transform.format, { quality }); | ||||
|     } | ||||
|     const { data, info } = await result.toBuffer({ resolveWithObject: true }); | ||||
|     return { | ||||
|       data, | ||||
|       format: info.format | ||||
|     }; | ||||
|   } | ||||
| }; | ||||
| var sharp_default = sharpService; | ||||
|  | ||||
| const sharp$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||
|   __proto__: null, | ||||
|   default: sharp_default | ||||
| }, Symbol.toStringTag, { value: 'Module' })); | ||||
|  | ||||
| export { DEFAULT_HASH_PROPS as D, isLocalService as a, isRemoteImage as b, isRemoteAllowed as c, isESMImportedImage as i, sharp$1 as s }; | ||||
							
								
								
									
										2196
									
								
								test/data/warden/dist/server/chunks/astro_5WdVqH1c.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2196
									
								
								test/data/warden/dist/server/chunks/astro_5WdVqH1c.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/index_5_WFUSxR.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/index_5_WFUSxR.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| export { renderers } from '../renderers.mjs'; | ||||
| export { onRequest } from '../_empty-middleware.mjs'; | ||||
|  | ||||
| const page = () => import('./pages/index_l5vwnKzb.mjs').then(n => n.b); | ||||
|  | ||||
| export { page }; | ||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/index_6C3b8yBv.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/index_6C3b8yBv.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| export { renderers } from '../renderers.mjs'; | ||||
| export { onRequest } from '../_empty-middleware.mjs'; | ||||
|  | ||||
| const page = () => import('./pages/index_l5vwnKzb.mjs').then(n => n.i); | ||||
|  | ||||
| export { page }; | ||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/index_Ij1Dwoh1.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/index_Ij1Dwoh1.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| export { renderers } from '../renderers.mjs'; | ||||
| export { onRequest } from '../_empty-middleware.mjs'; | ||||
|  | ||||
| const page = () => import('./pages/index_l5vwnKzb.mjs').then(n => n.a); | ||||
|  | ||||
| export { page }; | ||||
							
								
								
									
										6
									
								
								test/data/warden/dist/server/chunks/node_0Fr8CwHA.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/data/warden/dist/server/chunks/node_0Fr8CwHA.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| export { renderers } from '../renderers.mjs'; | ||||
| export { onRequest } from '../_empty-middleware.mjs'; | ||||
|  | ||||
| const page = () => import('./pages/node_hIg2I-Kh.mjs'); | ||||
|  | ||||
| export { page }; | ||||
							
								
								
									
										245
									
								
								test/data/warden/dist/server/chunks/pages/_slug__TUDhKBhQ.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								test/data/warden/dist/server/chunks/pages/_slug__TUDhKBhQ.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,245 @@ | ||||
| /* empty css                           */ | ||||
| import 'html-escaper'; | ||||
| import { c as createAstro, d as createComponent, r as renderTemplate, m as maybeRenderHead, e as addAttribute, f as renderSlot, g as renderTransition, h as renderComponent, i as renderHead } from '../astro_5WdVqH1c.mjs'; | ||||
| import 'kleur/colors'; | ||||
| import 'clsx'; | ||||
| import { DocumentRenderer } from '@keystone-6/document-renderer'; | ||||
| /* empty css                           */ | ||||
| /* empty css                           */ | ||||
|  | ||||
| const $$Astro$7 = createAstro("https://smartsheep.studio"); | ||||
| const $$Navbar = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$7, $$props, $$slots); | ||||
|   Astro2.self = $$Navbar; | ||||
|   const items = [ | ||||
|     { | ||||
|       label: "\u60C5\u62A5", | ||||
|       children: [ | ||||
|         { href: "/posts", label: "\u8BB0\u5F55" }, | ||||
|         { href: "/events", label: "\u6D3B\u52A8" } | ||||
|       ] | ||||
|     } | ||||
|   ]; | ||||
|   return renderTemplate`${maybeRenderHead()}<div class="fixed top-0 navbar shadow-md bg-base-100 lg:px-5 z-10"> <div class="navbar-start"> <div class="dropdown"> <div tabindex="0" role="button" class="btn btn-ghost lg:hidden"> <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16"></path> </svg> </div> <ul tabindex="0" class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52"> ${items.map((item) => renderTemplate`<li> <a${addAttribute(item.href, "href")}>${item.label}</a> ${item.children && renderTemplate`<ul class="p-2"> ${item.children?.map((child) => renderTemplate`<li> <a${addAttribute(child.href, "href")}>${child.label}</a> </li>`)} </ul>`} </li>`)} </ul> </div> <a class="btn btn-ghost text-xl" href="/">山羊寒舍</a> </div> <div class="navbar-center hidden lg:flex"> <ul class="menu menu-horizontal px-1"> ${items.map((item) => renderTemplate`<li> ${item.children ? renderTemplate`<details> <summary>${item.label}</summary> <ul class="p-2"> ${item.children?.map((child) => renderTemplate`<li> <a${addAttribute(child.href, "href")}>${child.label}</a> </li>`)} </ul> </details>` : renderTemplate`<a${addAttribute(item.href, "href")}>${item.label}</a>`} </li>`)} </ul> </div> <div class="navbar-end"> <label class="swap swap-rotate px-[16px]"> <input type="checkbox" class="theme-controller" value="light" checked> <svg class="swap-on fill-current w-8 h-8" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"></path> </svg> <svg class="swap-off fill-current w-8 h-8" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"></path> </svg> </label> </div> </div>`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/components/Navbar.astro", void 0); | ||||
|  | ||||
| const $$Astro$6 = createAstro("https://smartsheep.studio"); | ||||
| const $$ViewTransitions = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$6, $$props, $$slots); | ||||
|   Astro2.self = $$ViewTransitions; | ||||
|   const { fallback = "animate" } = Astro2.props; | ||||
|   return renderTemplate`<meta name="astro-view-transitions-enabled" content="true"><meta name="astro-view-transitions-fallback"${addAttribute(fallback, "content")}>`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/node_modules/astro/components/ViewTransitions.astro", void 0); | ||||
|  | ||||
| var __freeze = Object.freeze; | ||||
| var __defProp = Object.defineProperty; | ||||
| var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(raw || cooked.slice()) })); | ||||
| var _a; | ||||
| const $$Astro$5 = createAstro("https://smartsheep.studio"); | ||||
| const $$RootLayout = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$5, $$props, $$slots); | ||||
|   Astro2.self = $$RootLayout; | ||||
|   const { title } = Astro2.props; | ||||
|   return renderTemplate(_a || (_a = __template(['<html lang="en" data-astro-cid-mdysn4oi> <head><meta charset="utf-8"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><meta name="viewport" content="width=device-width"><meta name="generator"', ">", "", "", "", "</head> <body data-astro-cid-mdysn4oi> <!-- Header --> ", " <!-- Content --> <main data-astro-cid-mdysn4oi", "> ", ' </main> <!-- Styles -->   <script async src="https://analytics.smartsheep.studio/script.js" data-website-id="9d676a27-b473-44a3-b444-5a7d851e31e8"><\/script> </body> </html>'])), addAttribute(Astro2.generator, "content"), title && renderTemplate`<title>山羊寒舍 | ${title}</title>`, !title && renderTemplate`<title>山羊寒舍</title>`, renderComponent($$result, "ViewTransitions", $$ViewTransitions, { "data-astro-cid-mdysn4oi": true }), renderHead(), renderComponent($$result, "Navbar", $$Navbar, { "data-astro-cid-mdysn4oi": true }), addAttribute(renderTransition($$result, "53mar5bf", "slide", ""), "data-astro-transition-scope"), renderSlot($$result, $$slots["default"])); | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/layouts/RootLayout.astro", "self"); | ||||
|  | ||||
| const $$Astro$4 = createAstro("https://smartsheep.studio"); | ||||
| const $$PageLayout = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$4, $$props, $$slots); | ||||
|   Astro2.self = $$PageLayout; | ||||
|   const { title } = Astro2.props; | ||||
|   return renderTemplate`${renderComponent($$result, "RootLayout", $$RootLayout, { "title": title }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<main class="container mx-auto h-fullpage mt-header"> ${renderSlot($$result2, $$slots["default"])} </main> ` })}`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/layouts/PageLayout.astro", void 0); | ||||
|  | ||||
| const defaultCms = "https://smartsheep.studio"; | ||||
| async function graphQuery(query, variables) { | ||||
|   const response = await fetch(`${process.env.PUBLIC_CMS ?? defaultCms}/api/graphql`, { | ||||
|     method: "POST", | ||||
|     headers: { "Content-Type": "application/json" }, | ||||
|     body: JSON.stringify({ | ||||
|       query, | ||||
|       variables | ||||
|     }) | ||||
|   }); | ||||
|   return await response.json(); | ||||
| } | ||||
|  | ||||
| const POST_TYPES = { | ||||
|   article: "文章", | ||||
|   podcast: "播客", | ||||
|   announcements: "通告" | ||||
| }; | ||||
|  | ||||
| const $$Astro$3 = createAstro("https://smartsheep.studio"); | ||||
| const $$PostList = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$3, $$props, $$slots); | ||||
|   Astro2.self = $$PostList; | ||||
|   const { posts } = Astro2.props; | ||||
|   return renderTemplate`${maybeRenderHead()}<div class="grid justify-items-strench shadow-lg"> ${posts?.map((item) => renderTemplate`<a${addAttribute(`/p/${item.slug}`, "href")}> <div class="card sm:card-side hover:bg-base-200 transition-colors sm:max-w-none"> ${item.cover.image.url && renderTemplate`<figure class="mx-auto w-full object-cover p-6 max-sm:pb-0 sm:max-w-[12rem] sm:pe-0"> <img loading="lazy"${addAttribute(item.cover.image.url, "src")} class="border-base-content bg-base-300 rounded-btn border border-opacity-5"${addAttribute(item.title, "alt")}> </figure>`} <div class="card-body"> <h2 class="text-xl">${item.title}</h2> <div class="mx-[-2px] mt-[-4px]"> <span class="badge badge-accent">${POST_TYPES[item.type]}</span> ${item.categories?.map((category) => renderTemplate`<span class="badge badge-primary">${category.name}</span>`)} ${item.tags?.map((tag) => renderTemplate`<span class="badge badge-secondary">${tag.name}</span>`)} </div> <div class="text-xs opacity-60 line-clamp-3"> ${item.description} </div> </div> </div> </a>`)} </div>`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/components/PostList.astro", void 0); | ||||
|  | ||||
| const $$Astro$2 = createAstro("https://smartsheep.studio"); | ||||
| const prerender$2 = false; | ||||
| const $$slug$2 = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$2, $$props, $$slots); | ||||
|   Astro2.self = $$slug$2; | ||||
|   const { slug } = Astro2.params; | ||||
|   const { posts } = (await graphQuery( | ||||
|     `query Query($where: PostWhereInput!, $orderBy: [PostOrderByInput!]!) { | ||||
|   posts(where: $where, orderBy: $orderBy) { | ||||
|     slug | ||||
|     type | ||||
|     title | ||||
|     description | ||||
|     cover { | ||||
|       image { | ||||
|         url | ||||
|       } | ||||
|     } | ||||
|     content { | ||||
|       document | ||||
|     } | ||||
|     categories { | ||||
|       name | ||||
|     } | ||||
|     tags { | ||||
|       name | ||||
|     } | ||||
|     createdAt | ||||
|   } | ||||
| }`, | ||||
|     { | ||||
|       orderBy: [ | ||||
|         { | ||||
|           createdAt: "desc" | ||||
|         } | ||||
|       ], | ||||
|       where: { categories: { some: { slug: { equals: slug } } } } | ||||
|     } | ||||
|   )).data; | ||||
|   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": "\u5206\u7C7B\u68C0\u7D22" }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-w-[720px] mx-auto"> <div class="pt-16 pb-6 px-6"> <h1 class="text-4xl font-bold">分类检索</h1> <p class="pt-3">以下是包含该分类的记录……</p> </div> ${renderComponent($$result2, "PostList", $$PostList, { "posts": posts })} </div> ` })}`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/categories/[slug].astro", void 0); | ||||
|  | ||||
| const $$file$2 = "/Users/littlesheep/Documents/Projects/Capital/src/pages/categories/[slug].astro"; | ||||
| const $$url$2 = "/categories/[slug]"; | ||||
|  | ||||
| const _slug_$2 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||
|   __proto__: null, | ||||
|   default: $$slug$2, | ||||
|   file: $$file$2, | ||||
|   prerender: prerender$2, | ||||
|   url: $$url$2 | ||||
| }, Symbol.toStringTag, { value: 'Module' })); | ||||
|  | ||||
| const $$Astro$1 = createAstro("https://smartsheep.studio"); | ||||
| const prerender$1 = false; | ||||
| const $$slug$1 = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); | ||||
|   Astro2.self = $$slug$1; | ||||
|   const { slug } = Astro2.params; | ||||
|   const { post } = (await graphQuery( | ||||
|     `query Query($where: PostWhereUniqueInput!) { | ||||
|   post(where: $where) { | ||||
|     slug | ||||
|     type | ||||
|     title | ||||
|     description | ||||
|     author { | ||||
|       name | ||||
|     } | ||||
|     assets { | ||||
|       caption | ||||
|       url | ||||
|       type | ||||
|     } | ||||
|     cover { | ||||
|       image { | ||||
|         url | ||||
|       } | ||||
|     } | ||||
|     content { | ||||
|       document | ||||
|     } | ||||
|     categories { | ||||
|       slug | ||||
|       name | ||||
|     } | ||||
|     tags { | ||||
|       slug | ||||
|       name | ||||
|     } | ||||
|     createdAt | ||||
|   } | ||||
| }`, | ||||
|     { | ||||
|       where: { slug } | ||||
|     } | ||||
|   )).data; | ||||
|   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": post.title, "data-astro-cid-gysqo7gh": true }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="wrapper" data-astro-cid-gysqo7gh> <div class="card w-full shadow-xl" data-astro-cid-gysqo7gh> ${post.cover && renderTemplate`<figure data-astro-cid-gysqo7gh> <img${addAttribute(post.cover.image.url, "src")}${addAttribute(post.title, "alt")} data-astro-cid-gysqo7gh> </figure>`} <div class="card-body" data-astro-cid-gysqo7gh> <h2 class="card-title" data-astro-cid-gysqo7gh>${post.title}</h2> <p class="description" data-astro-cid-gysqo7gh>${post.description ?? "No description"}</p> <div class="divider" data-astro-cid-gysqo7gh></div> ${post.assets?.length > 0 && renderTemplate`<div class="mb-5 w-full" data-astro-cid-gysqo7gh> ${renderComponent($$result2, "Media", null, { "client:only": true, "sources": post.assets, "author": post.author, "client:component-hydration": "only", "data-astro-cid-gysqo7gh": true, "client:component-path": "/Users/littlesheep/Documents/Projects/Capital/src/components/posts/Media", "client:component-export": "default" })} </div>`} <div class="prose max-w-none" data-astro-cid-gysqo7gh> ${renderComponent($$result2, "DocumentRenderer", DocumentRenderer, { "document": post.content.document, "data-astro-cid-gysqo7gh": true })} </div> </div> </div> <div class="h-fit sticky top-header" data-astro-cid-gysqo7gh> <div class="card shadow-xl" data-astro-cid-gysqo7gh> <div class="card-body" data-astro-cid-gysqo7gh> <div class="gap-2 text-sm metadata description" data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>作者</div> <div data-astro-cid-gysqo7gh>${post.author?.name ?? "\u4F5A\u540D"}</div> </div> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>类型</div> <div class="text-accent" data-astro-cid-gysqo7gh> ${POST_TYPES[post.type]} </div> </div> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>分类</div> <div class="flex gap-1" data-astro-cid-gysqo7gh> ${post.categories?.map((category) => renderTemplate`<a${addAttribute(`/categories/${category.slug}`, "href")} class="link link-primary" data-astro-cid-gysqo7gh> ${category.name} </a>`)} </div> </div> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>标签</div> <div class="flex gap-1" data-astro-cid-gysqo7gh> ${post.tags?.map((tag) => renderTemplate`<a${addAttribute(`/tags/${tag.slug}`, "href")} class="link link-secondary" data-astro-cid-gysqo7gh> ${tag.name} </a>`)} </div> </div> <div data-astro-cid-gysqo7gh> <div data-astro-cid-gysqo7gh>发布于</div> <div data-astro-cid-gysqo7gh>${new Date(post.createdAt).toLocaleString()}</div> </div> </div> </div> </div> </div> </div> ` })} `; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/posts/[slug].astro", void 0); | ||||
|  | ||||
| const $$file$1 = "/Users/littlesheep/Documents/Projects/Capital/src/pages/posts/[slug].astro"; | ||||
| const $$url$1 = "/posts/[slug]"; | ||||
|  | ||||
| const _slug_$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||
|   __proto__: null, | ||||
|   default: $$slug$1, | ||||
|   file: $$file$1, | ||||
|   prerender: prerender$1, | ||||
|   url: $$url$1 | ||||
| }, Symbol.toStringTag, { value: 'Module' })); | ||||
|  | ||||
| const $$Astro = createAstro("https://smartsheep.studio"); | ||||
| const prerender = false; | ||||
| const $$slug = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); | ||||
|   Astro2.self = $$slug; | ||||
|   const { slug } = Astro2.params; | ||||
|   const { posts } = (await graphQuery( | ||||
|     `query Query($where: PostWhereInput!, $orderBy: [PostOrderByInput!]!) { | ||||
|   posts(where: $where, orderBy: $orderBy) { | ||||
|     slug | ||||
|     type | ||||
|     title | ||||
|     description | ||||
|     cover { | ||||
|       image { | ||||
|         url | ||||
|       } | ||||
|     } | ||||
|     content { | ||||
|       document | ||||
|     } | ||||
|     categories { | ||||
|       name | ||||
|     } | ||||
|     tags { | ||||
|       name | ||||
|     } | ||||
|     createdAt | ||||
|   } | ||||
| }`, | ||||
|     { | ||||
|       orderBy: [ | ||||
|         { | ||||
|           createdAt: "desc" | ||||
|         } | ||||
|       ], | ||||
|       where: { tags: { some: { slug: { equals: slug } } } } | ||||
|     } | ||||
|   )).data; | ||||
|   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": "\u6807\u7B7E\u68C0\u7D22" }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-w-[720px] mx-auto"> <div class="pt-16 pb-6 px-6"> <h1 class="text-4xl font-bold">标签检索</h1> <p class="pt-3">以下是包含该标签的记录……</p> </div> ${renderComponent($$result2, "PostList", $$PostList, { "posts": posts })} </div> ` })}`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/tags/[slug].astro", void 0); | ||||
|  | ||||
| const $$file = "/Users/littlesheep/Documents/Projects/Capital/src/pages/tags/[slug].astro"; | ||||
| const $$url = "/tags/[slug]"; | ||||
|  | ||||
| const _slug_ = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||
|   __proto__: null, | ||||
|   default: $$slug, | ||||
|   file: $$file, | ||||
|   prerender, | ||||
|   url: $$url | ||||
| }, Symbol.toStringTag, { value: 'Module' })); | ||||
|  | ||||
| export { $$PageLayout as $, _slug_$2 as _, $$PostList as a, $$RootLayout as b, _slug_$1 as c, _slug_ as d, graphQuery as g }; | ||||
							
								
								
									
										153
									
								
								test/data/warden/dist/server/chunks/pages/index_l5vwnKzb.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								test/data/warden/dist/server/chunks/pages/index_l5vwnKzb.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | ||||
| /* empty css                           */ | ||||
| import { c as createAstro, d as createComponent, r as renderTemplate, h as renderComponent, m as maybeRenderHead, e as addAttribute } from '../astro_5WdVqH1c.mjs'; | ||||
| import 'kleur/colors'; | ||||
| import 'html-escaper'; | ||||
| import { g as graphQuery, $ as $$PageLayout, a as $$PostList, b as $$RootLayout } from './_slug__TUDhKBhQ.mjs'; | ||||
| import { DocumentRenderer } from '@keystone-6/document-renderer'; | ||||
| import 'clsx'; | ||||
| /* empty css                          */ | ||||
|  | ||||
| const $$Astro$2 = createAstro("https://smartsheep.studio"); | ||||
| const prerender$2 = false; | ||||
| const $$Index$2 = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$2, $$props, $$slots); | ||||
|   Astro2.self = $$Index$2; | ||||
|   const { events } = (await graphQuery( | ||||
|     `query Query($where: EventWhereInput!) { | ||||
|   events(where: $where) { | ||||
|     slug | ||||
|     title | ||||
|     description | ||||
|     content { | ||||
|       document | ||||
|     } | ||||
|     createdAt | ||||
|   } | ||||
| }`, | ||||
|     { | ||||
|       where: { | ||||
|         isHistory: { | ||||
|           equals: true | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   )).data; | ||||
|   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": "\u6D3B\u52A8" }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-w-[720px] mx-auto"> <div class="card w-full shadow-xl"> <div class="card-body"> <h2 class="card-title">活动</h2> <p>读岁月史书,涨人生阅历</p> <div class="divider"></div> <ul class="timeline timeline-snap-icon max-md:timeline-compact timeline-vertical"> ${events?.map((item, idx) => { | ||||
|     let align = idx % 2 === 0 ? "timeline-start" : "timeline-end"; | ||||
|     let textAlign = idx % 2 === 0 ? "md:text-right" : "md:text-left"; | ||||
|     return renderTemplate`<li> ${idx > 0 && renderTemplate`<hr>`} <div class="timeline-middle"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5"> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd"></path> </svg> </div> <div${addAttribute(`${align} ${textAlign} mb-10`, "class")}> <time class="font-mono italic"> ${new Date(item.createdAt).toLocaleDateString()} </time> <div class="text-lg font-black">${item.title}</div> ${renderComponent($$result2, "DocumentRenderer", DocumentRenderer, { "document": item.content.document })} </div> <hr> </li>`; | ||||
|   })} </ul> <div class="text-center max-md:text-left italic"> | ||||
| 我们的故事还在继续…… | ||||
| </div> </div> </div> </div> ` })}`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/events/index.astro", void 0); | ||||
|  | ||||
| const $$file$2 = "/Users/littlesheep/Documents/Projects/Capital/src/pages/events/index.astro"; | ||||
| const $$url$2 = "/events"; | ||||
|  | ||||
| const index$2 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||
|   __proto__: null, | ||||
|   default: $$Index$2, | ||||
|   file: $$file$2, | ||||
|   prerender: prerender$2, | ||||
|   url: $$url$2 | ||||
| }, Symbol.toStringTag, { value: 'Module' })); | ||||
|  | ||||
| const $$Astro$1 = createAstro("https://smartsheep.studio"); | ||||
| const prerender$1 = false; | ||||
| const $$Index$1 = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); | ||||
|   Astro2.self = $$Index$1; | ||||
|   const { posts } = (await graphQuery( | ||||
|     `query Query($where: PostWhereInput!, $orderBy: [PostOrderByInput!]!) { | ||||
|   posts(where: $where, orderBy: $orderBy) { | ||||
|     slug | ||||
|     type | ||||
|     title | ||||
|     description | ||||
|     cover { | ||||
|       image { | ||||
|         url | ||||
|       } | ||||
|     } | ||||
|     content { | ||||
|       document | ||||
|     } | ||||
|     categories { | ||||
|       name | ||||
|     } | ||||
|     tags { | ||||
|       name | ||||
|     } | ||||
|     createdAt | ||||
|   } | ||||
| }`, | ||||
|     { | ||||
|       orderBy: [ | ||||
|         { | ||||
|           createdAt: "desc" | ||||
|         } | ||||
|       ], | ||||
|       where: {} | ||||
|     } | ||||
|   )).data; | ||||
|   return renderTemplate`${renderComponent($$result, "PageLayout", $$PageLayout, { "title": "\u8BB0\u5F55" }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-w-[720px] mx-auto"> <div class="pt-16 pb-6 px-6"> <h1 class="text-4xl font-bold">记录</h1> <p class="pt-2">记录生活,记录理想,记录记录……</p> </div> ${renderComponent($$result2, "PostList", $$PostList, { "posts": posts })} </div> ` })}`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/posts/index.astro", void 0); | ||||
|  | ||||
| const $$file$1 = "/Users/littlesheep/Documents/Projects/Capital/src/pages/posts/index.astro"; | ||||
| const $$url$1 = "/posts"; | ||||
|  | ||||
| const index$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||
|   __proto__: null, | ||||
|   default: $$Index$1, | ||||
|   file: $$file$1, | ||||
|   prerender: prerender$1, | ||||
|   url: $$url$1 | ||||
| }, Symbol.toStringTag, { value: 'Module' })); | ||||
|  | ||||
| const $$Astro = createAstro("https://smartsheep.studio"); | ||||
| const prerender = false; | ||||
| const $$Index = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); | ||||
|   Astro2.self = $$Index; | ||||
|   const { events } = (await graphQuery( | ||||
|     `query Query($where: EventWhereInput!) { | ||||
|   events(where: $where) { | ||||
|     slug | ||||
|     title | ||||
|     description | ||||
|     createdAt | ||||
|   } | ||||
| }`, | ||||
|     { | ||||
|       where: { | ||||
|         isHistory: { | ||||
|           equals: true | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   )).data; | ||||
|   return renderTemplate`${renderComponent($$result, "RootLayout", $$RootLayout, { "data-astro-cid-j7pv25f6": true }, { "default": ($$result2) => renderTemplate` ${maybeRenderHead()}<div class="max-h-fullpage mt-header wrapper px-5 snap-y snap-mandatory" data-astro-cid-j7pv25f6> <div id="hello" class="hero h-fullpage snap-start" data-astro-cid-j7pv25f6> <div class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]" data-astro-cid-j7pv25f6> <div class="max-md:text-center" data-astro-cid-j7pv25f6> <h1 class="text-5xl font-bold" data-astro-cid-j7pv25f6>你好呀 👋</h1> <p class="py-6" data-astro-cid-j7pv25f6> | ||||
| 欢迎来到 SmartSheep Studio | ||||
|             的官方网站!在这里了解,订阅,跟踪我们的最新消息。 | ||||
|             接触我们最大的官方社区,并且尝试最新产品,参与各种活动,提供反馈,让我们更好的服务您。 | ||||
| </p> <a href="#about" class="btn btn-primary btn-md" data-astro-cid-j7pv25f6>了解更多</a> </div> <div class="flex justify-center md:justify-end max-md:order-first" data-astro-cid-j7pv25f6> <div class="spinning p-3 md:p-5 shadow-2xl aspect-square rounded-[30%] w-[192px] md:w-[256px] lg:w-[384px]" data-astro-cid-j7pv25f6> <img src="/favicon.svg" alt="logo" loading="lazy" data-astro-cid-j7pv25f6> </div> </div> </div> </div> <div id="about" class="hero h-fullpage snap-start" data-astro-cid-j7pv25f6> <div class="hero-content w-full grid grid-cols-1 md:grid-cols-2 max-md:gap-[60px]" data-astro-cid-j7pv25f6> <div class="flex justify-center md:justify-start" data-astro-cid-j7pv25f6> <div class="stats shadow overflow-x-auto" data-astro-cid-j7pv25f6> <div class="stat" data-astro-cid-j7pv25f6> <div class="stat-figure text-secondary" data-astro-cid-j7pv25f6> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current" data-astro-cid-j7pv25f6><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" data-astro-cid-j7pv25f6></path></svg> </div> <div class="stat-title" data-astro-cid-j7pv25f6>People</div> <div class="stat-value" data-astro-cid-j7pv25f6>1</div> <div class="stat-desc" data-astro-cid-j7pv25f6>2019 - ${(/* @__PURE__ */ new Date()).getFullYear()}</div> </div> <div class="stat" data-astro-cid-j7pv25f6> <div class="stat-figure text-secondary" data-astro-cid-j7pv25f6> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current" data-astro-cid-j7pv25f6><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" data-astro-cid-j7pv25f6></path></svg> </div> <div class="stat-title" data-astro-cid-j7pv25f6>Clients</div> <div class="stat-value" data-astro-cid-j7pv25f6>180</div> <div class="stat-desc" data-astro-cid-j7pv25f6>↗︎ 80 (44%)</div> </div> <div class="stat" data-astro-cid-j7pv25f6> <div class="stat-figure text-secondary" data-astro-cid-j7pv25f6> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="inline-block w-8 h-8 stroke-current" data-astro-cid-j7pv25f6><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" data-astro-cid-j7pv25f6></path></svg> </div> <div class="stat-title" data-astro-cid-j7pv25f6>Products</div> <div class="stat-value" data-astro-cid-j7pv25f6>4</div> <div class="stat-desc" data-astro-cid-j7pv25f6>↘︎ 8 (67%)</div> </div> </div> </div> <div class="max-md:text-center" data-astro-cid-j7pv25f6> <h1 class="text-5xl font-bold" data-astro-cid-j7pv25f6>关于我们 🔖</h1> <p class="py-6" data-astro-cid-j7pv25f6> | ||||
| 我们是一群充满活力、对开源充满热情的开发者。成立于 2019 | ||||
|             年。自那年起我们一直在开发让人喜欢的开源软件。在我们这里,“取之于开源,用之于开源” | ||||
|             不仅是原则,更是我们信仰的座右铭。 | ||||
| </p> <a href="#history" class="btn btn-primary btn-md pl-[24px]" data-astro-cid-j7pv25f6> | ||||
| 查看「岁月史书」 | ||||
| </a> </div> </div> </div> <div id="history" class="flex flex-col justify-center items-center h-fullpage snap-start" data-astro-cid-j7pv25f6> <div class="text-center" data-astro-cid-j7pv25f6> <div data-astro-cid-j7pv25f6> <h1 class="text-4xl font-bold" data-astro-cid-j7pv25f6>岁月史书</h1> <p class="pt-2 pb-4 tracking-[8px]" data-astro-cid-j7pv25f6>但当涉猎,见往事耳</p> <ul class="pb-6 mx-[-20px] max-w-[100vw] px-5 flex justify-center history timeline timeline-horizontal" data-astro-cid-j7pv25f6> ${events?.map((item, idx) => renderTemplate`<li data-astro-cid-j7pv25f6> ${idx > 0 && renderTemplate`<hr data-astro-cid-j7pv25f6>`} <div class="timeline-start" data-astro-cid-j7pv25f6> ${new Date(item.createdAt).toLocaleDateString()} </div> <div class="timeline-middle" data-astro-cid-j7pv25f6> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5" data-astro-cid-j7pv25f6> <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" data-astro-cid-j7pv25f6></path> </svg> </div> <div class="timeline-end timeline-box" data-astro-cid-j7pv25f6> <h2 class="font-bold text-lg" data-astro-cid-j7pv25f6>${item.title}</h2> <div class="line-clamp-2" data-astro-cid-j7pv25f6>${item.description}</div> </div> ${idx < events?.length - 1 && renderTemplate`<hr data-astro-cid-j7pv25f6>`} </li>`)} </ul> <a class="btn btn-primary" href="/events" data-astro-cid-j7pv25f6>查看更多</a> </div> </div> </div> </div> ` })}  `; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/src/pages/index.astro", void 0); | ||||
|  | ||||
| const $$file = "/Users/littlesheep/Documents/Projects/Capital/src/pages/index.astro"; | ||||
| const $$url = ""; | ||||
|  | ||||
| const index = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ | ||||
|   __proto__: null, | ||||
|   default: $$Index, | ||||
|   file: $$file, | ||||
|   prerender, | ||||
|   url: $$url | ||||
| }, Symbol.toStringTag, { value: 'Module' })); | ||||
|  | ||||
| export { index$1 as a, index as b, index$2 as i }; | ||||
							
								
								
									
										240
									
								
								test/data/warden/dist/server/chunks/pages/node_hIg2I-Kh.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								test/data/warden/dist/server/chunks/pages/node_hIg2I-Kh.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,240 @@ | ||||
| import { isRemotePath } from '@astrojs/internal-helpers/path'; | ||||
| import { readFile } from 'fs/promises'; | ||||
| import mime from 'mime/lite.js'; | ||||
| import 'os'; | ||||
| import { A as AstroError, j as InvalidImageService, k as ExpectedImageOptions, E as ExpectedImage, c as createAstro, d as createComponent, l as ImageMissingAlt, r as renderTemplate, m as maybeRenderHead, e as addAttribute, s as spreadAttributes } from '../astro_5WdVqH1c.mjs'; | ||||
| import { i as isESMImportedImage, a as isLocalService, b as isRemoteImage, D as DEFAULT_HASH_PROPS, c as isRemoteAllowed } from '../astro/assets-service_4dMyVCFm.mjs'; | ||||
| import 'html-escaper'; | ||||
| import 'clsx'; | ||||
|  | ||||
| async function getConfiguredImageService() { | ||||
|   if (!globalThis?.astroAsset?.imageService) { | ||||
|     const { default: service } = await import( | ||||
|       // @ts-expect-error | ||||
|       '../astro/assets-service_4dMyVCFm.mjs' | ||||
|     ).then(n => n.s).catch((e) => { | ||||
|       const error = new AstroError(InvalidImageService); | ||||
|       error.cause = e; | ||||
|       throw error; | ||||
|     }); | ||||
|     if (!globalThis.astroAsset) | ||||
|       globalThis.astroAsset = {}; | ||||
|     globalThis.astroAsset.imageService = service; | ||||
|     return service; | ||||
|   } | ||||
|   return globalThis.astroAsset.imageService; | ||||
| } | ||||
| async function getImage$1(options, imageConfig) { | ||||
|   if (!options || typeof options !== "object") { | ||||
|     throw new AstroError({ | ||||
|       ...ExpectedImageOptions, | ||||
|       message: ExpectedImageOptions.message(JSON.stringify(options)) | ||||
|     }); | ||||
|   } | ||||
|   if (typeof options.src === "undefined") { | ||||
|     throw new AstroError({ | ||||
|       ...ExpectedImage, | ||||
|       message: ExpectedImage.message( | ||||
|         options.src, | ||||
|         "undefined", | ||||
|         JSON.stringify(options) | ||||
|       ) | ||||
|     }); | ||||
|   } | ||||
|   const service = await getConfiguredImageService(); | ||||
|   const resolvedOptions = { | ||||
|     ...options, | ||||
|     src: typeof options.src === "object" && "then" in options.src ? (await options.src).default ?? await options.src : options.src | ||||
|   }; | ||||
|   const originalPath = isESMImportedImage(resolvedOptions.src) ? resolvedOptions.src.fsPath : resolvedOptions.src; | ||||
|   const clonedSrc = isESMImportedImage(resolvedOptions.src) ? ( | ||||
|     // @ts-expect-error - clone is a private, hidden prop | ||||
|     resolvedOptions.src.clone ?? resolvedOptions.src | ||||
|   ) : resolvedOptions.src; | ||||
|   resolvedOptions.src = clonedSrc; | ||||
|   const validatedOptions = service.validateOptions ? await service.validateOptions(resolvedOptions, imageConfig) : resolvedOptions; | ||||
|   const srcSetTransforms = service.getSrcSet ? await service.getSrcSet(validatedOptions, imageConfig) : []; | ||||
|   let imageURL = await service.getURL(validatedOptions, imageConfig); | ||||
|   let srcSets = await Promise.all( | ||||
|     srcSetTransforms.map(async (srcSet) => ({ | ||||
|       transform: srcSet.transform, | ||||
|       url: await service.getURL(srcSet.transform, imageConfig), | ||||
|       descriptor: srcSet.descriptor, | ||||
|       attributes: srcSet.attributes | ||||
|     })) | ||||
|   ); | ||||
|   if (isLocalService(service) && globalThis.astroAsset.addStaticImage && !(isRemoteImage(validatedOptions.src) && imageURL === validatedOptions.src)) { | ||||
|     const propsToHash = service.propertiesToHash ?? DEFAULT_HASH_PROPS; | ||||
|     imageURL = globalThis.astroAsset.addStaticImage(validatedOptions, propsToHash, originalPath); | ||||
|     srcSets = srcSetTransforms.map((srcSet) => ({ | ||||
|       transform: srcSet.transform, | ||||
|       url: globalThis.astroAsset.addStaticImage(srcSet.transform, propsToHash, originalPath), | ||||
|       descriptor: srcSet.descriptor, | ||||
|       attributes: srcSet.attributes | ||||
|     })); | ||||
|   } | ||||
|   return { | ||||
|     rawOptions: resolvedOptions, | ||||
|     options: validatedOptions, | ||||
|     src: imageURL, | ||||
|     srcSet: { | ||||
|       values: srcSets, | ||||
|       attribute: srcSets.map((srcSet) => `${srcSet.url} ${srcSet.descriptor}`).join(", ") | ||||
|     }, | ||||
|     attributes: service.getHTMLAttributes !== void 0 ? await service.getHTMLAttributes(validatedOptions, imageConfig) : {} | ||||
|   }; | ||||
| } | ||||
|  | ||||
| const fnv1a52 = (str) => { | ||||
|   const len = str.length; | ||||
|   let i = 0, t0 = 0, v0 = 8997, t1 = 0, v1 = 33826, t2 = 0, v2 = 40164, t3 = 0, v3 = 52210; | ||||
|   while (i < len) { | ||||
|     v0 ^= str.charCodeAt(i++); | ||||
|     t0 = v0 * 435; | ||||
|     t1 = v1 * 435; | ||||
|     t2 = v2 * 435; | ||||
|     t3 = v3 * 435; | ||||
|     t2 += v0 << 8; | ||||
|     t3 += v1 << 8; | ||||
|     t1 += t0 >>> 16; | ||||
|     v0 = t0 & 65535; | ||||
|     t2 += t1 >>> 16; | ||||
|     v1 = t1 & 65535; | ||||
|     v3 = t3 + (t2 >>> 16) & 65535; | ||||
|     v2 = t2 & 65535; | ||||
|   } | ||||
|   return (v3 & 15) * 281474976710656 + v2 * 4294967296 + v1 * 65536 + (v0 ^ v3 >> 4); | ||||
| }; | ||||
| const etag = (payload, weak = false) => { | ||||
|   const prefix = weak ? 'W/"' : '"'; | ||||
|   return prefix + fnv1a52(payload).toString(36) + payload.length.toString(36) + '"'; | ||||
| }; | ||||
|  | ||||
| const $$Astro$1 = createAstro("https://smartsheep.studio"); | ||||
| const $$Image = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots); | ||||
|   Astro2.self = $$Image; | ||||
|   const props = Astro2.props; | ||||
|   if (props.alt === void 0 || props.alt === null) { | ||||
|     throw new AstroError(ImageMissingAlt); | ||||
|   } | ||||
|   if (typeof props.width === "string") { | ||||
|     props.width = parseInt(props.width); | ||||
|   } | ||||
|   if (typeof props.height === "string") { | ||||
|     props.height = parseInt(props.height); | ||||
|   } | ||||
|   const image = await getImage(props); | ||||
|   const additionalAttributes = {}; | ||||
|   if (image.srcSet.values.length > 0) { | ||||
|     additionalAttributes.srcset = image.srcSet.attribute; | ||||
|   } | ||||
|   return renderTemplate`${maybeRenderHead()}<img${addAttribute(image.src, "src")}${spreadAttributes(additionalAttributes)}${spreadAttributes(image.attributes)}>`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/node_modules/astro/components/Image.astro", void 0); | ||||
|  | ||||
| const $$Astro = createAstro("https://smartsheep.studio"); | ||||
| const $$Picture = createComponent(async ($$result, $$props, $$slots) => { | ||||
|   const Astro2 = $$result.createAstro($$Astro, $$props, $$slots); | ||||
|   Astro2.self = $$Picture; | ||||
|   const defaultFormats = ["webp"]; | ||||
|   const defaultFallbackFormat = "png"; | ||||
|   const specialFormatsFallback = ["gif", "svg", "jpg", "jpeg"]; | ||||
|   const { formats = defaultFormats, pictureAttributes = {}, fallbackFormat, ...props } = Astro2.props; | ||||
|   if (props.alt === void 0 || props.alt === null) { | ||||
|     throw new AstroError(ImageMissingAlt); | ||||
|   } | ||||
|   const optimizedImages = await Promise.all( | ||||
|     formats.map( | ||||
|       async (format) => await getImage({ ...props, format, widths: props.widths, densities: props.densities }) | ||||
|     ) | ||||
|   ); | ||||
|   let resultFallbackFormat = fallbackFormat ?? defaultFallbackFormat; | ||||
|   if (!fallbackFormat && isESMImportedImage(props.src) && specialFormatsFallback.includes(props.src.format)) { | ||||
|     resultFallbackFormat = props.src.format; | ||||
|   } | ||||
|   const fallbackImage = await getImage({ | ||||
|     ...props, | ||||
|     format: resultFallbackFormat, | ||||
|     widths: props.widths, | ||||
|     densities: props.densities | ||||
|   }); | ||||
|   const imgAdditionalAttributes = {}; | ||||
|   const sourceAdditionaAttributes = {}; | ||||
|   if (props.sizes) { | ||||
|     sourceAdditionaAttributes.sizes = props.sizes; | ||||
|   } | ||||
|   if (fallbackImage.srcSet.values.length > 0) { | ||||
|     imgAdditionalAttributes.srcset = fallbackImage.srcSet.attribute; | ||||
|   } | ||||
|   return renderTemplate`${maybeRenderHead()}<picture${spreadAttributes(pictureAttributes)}> ${Object.entries(optimizedImages).map(([_, image]) => { | ||||
|     const srcsetAttribute = props.densities || !props.densities && !props.widths ? `${image.src}${image.srcSet.values.length > 0 ? ", " + image.srcSet.attribute : ""}` : image.srcSet.attribute; | ||||
|     return renderTemplate`<source${addAttribute(srcsetAttribute, "srcset")}${addAttribute("image/" + image.options.format, "type")}${spreadAttributes(sourceAdditionaAttributes)}>`; | ||||
|   })} <img${addAttribute(fallbackImage.src, "src")}${spreadAttributes(imgAdditionalAttributes)}${spreadAttributes(fallbackImage.attributes)}> </picture>`; | ||||
| }, "/Users/littlesheep/Documents/Projects/Capital/node_modules/astro/components/Picture.astro", void 0); | ||||
|  | ||||
| const imageConfig = {"service":{"entrypoint":"astro/assets/services/sharp","config":{}},"domains":[],"remotePatterns":[],"endpoint":"astro/assets/endpoint/node"}; | ||||
| 					const assetsDir = new URL("file:///Users/littlesheep/Documents/Projects/Capital/dist/client/"); | ||||
| 					const getImage = async (options) => await getImage$1(options, imageConfig); | ||||
|  | ||||
| async function loadLocalImage(src, url) { | ||||
|   const filePath = new URL("." + src, assetsDir); | ||||
|   let buffer = void 0; | ||||
|   try { | ||||
|     buffer = await readFile(filePath); | ||||
|   } catch (e) { | ||||
|     const sourceUrl = new URL(src, url.origin); | ||||
|     buffer = await loadRemoteImage(sourceUrl); | ||||
|   } | ||||
|   return buffer; | ||||
| } | ||||
| async function loadRemoteImage(src) { | ||||
|   try { | ||||
|     const res = await fetch(src); | ||||
|     if (!res.ok) { | ||||
|       return void 0; | ||||
|     } | ||||
|     return Buffer.from(await res.arrayBuffer()); | ||||
|   } catch (err) { | ||||
|     return void 0; | ||||
|   } | ||||
| } | ||||
| const GET = async ({ request }) => { | ||||
|   try { | ||||
|     const imageService = await getConfiguredImageService(); | ||||
|     if (!("transform" in imageService)) { | ||||
|       throw new Error("Configured image service is not a local service"); | ||||
|     } | ||||
|     const url = new URL(request.url); | ||||
|     const transform = await imageService.parseURL(url, imageConfig); | ||||
|     if (!transform?.src) { | ||||
|       throw new Error("Incorrect transform returned by `parseURL`"); | ||||
|     } | ||||
|     let inputBuffer = void 0; | ||||
|     if (isRemotePath(transform.src)) { | ||||
|       if (isRemoteAllowed(transform.src, imageConfig) === false) { | ||||
|         return new Response("Forbidden", { status: 403 }); | ||||
|       } | ||||
|       inputBuffer = await loadRemoteImage(new URL(transform.src)); | ||||
|     } else { | ||||
|       inputBuffer = await loadLocalImage(transform.src, url); | ||||
|     } | ||||
|     if (!inputBuffer) { | ||||
|       return new Response("Not Found", { status: 404 }); | ||||
|     } | ||||
|     const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig); | ||||
|     return new Response(data, { | ||||
|       status: 200, | ||||
|       headers: { | ||||
|         "Content-Type": mime.getType(format) ?? `image/${format}`, | ||||
|         "Cache-Control": "public, max-age=31536000", | ||||
|         ETag: etag(data.toString()), | ||||
|         Date: (/* @__PURE__ */ new Date()).toUTCString() | ||||
|       } | ||||
|     }); | ||||
|   } catch (err) { | ||||
|     console.error("Could not process image request:", err); | ||||
|     return new Response(`Server Error: ${err}`, { status: 500 }); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| export { GET }; | ||||
							
								
								
									
										31
									
								
								test/data/warden/dist/server/chunks/vnode-children_3wEZly-Z.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								test/data/warden/dist/server/chunks/vnode-children_3wEZly-Z.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| import { parse, DOCUMENT_NODE, ELEMENT_NODE, TEXT_NODE } from 'ultrahtml'; | ||||
| import { createElement, Fragment } from 'react'; | ||||
|  | ||||
| let ids = 0; | ||||
| function convert(children) { | ||||
| 	let doc = parse(children.toString().trim()); | ||||
| 	let id = ids++; | ||||
| 	let key = 0; | ||||
|  | ||||
| 	function createReactElementFromNode(node) { | ||||
| 		const childVnodes = | ||||
| 			Array.isArray(node.children) && node.children.length | ||||
| 				? node.children.map((child) => createReactElementFromNode(child)).filter(Boolean) | ||||
| 				: undefined; | ||||
|  | ||||
| 		if (node.type === DOCUMENT_NODE) { | ||||
| 			return createElement(Fragment, {}, childVnodes); | ||||
| 		} else if (node.type === ELEMENT_NODE) { | ||||
| 			const { class: className, ...props } = node.attributes; | ||||
| 			return createElement(node.name, { ...props, className, key: `${id}-${key++}` }, childVnodes); | ||||
| 		} else if (node.type === TEXT_NODE) { | ||||
| 			// 0-length text gets omitted in JSX | ||||
| 			return node.value.trim() ? node.value : undefined; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	const root = createReactElementFromNode(doc); | ||||
| 	return root.props.children; | ||||
| } | ||||
|  | ||||
| export { convert as default }; | ||||
							
								
								
									
										2355
									
								
								test/data/warden/dist/server/entry.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2355
									
								
								test/data/warden/dist/server/entry.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										197
									
								
								test/data/warden/dist/server/manifest_irk0fM_a.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								test/data/warden/dist/server/manifest_irk0fM_a.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										263
									
								
								test/data/warden/dist/server/renderers.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								test/data/warden/dist/server/renderers.mjs
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,263 @@ | ||||
| import React, { createElement } from 'react'; | ||||
| import ReactDOM from 'react-dom/server'; | ||||
|  | ||||
| /** | ||||
|  * Astro passes `children` as a string of HTML, so we need | ||||
|  * a wrapper `div` to render that content as VNodes. | ||||
|  * | ||||
|  * As a bonus, we can signal to React that this subtree is | ||||
|  * entirely static and will never change via `shouldComponentUpdate`. | ||||
|  */ | ||||
| const StaticHtml = ({ value, name, hydrate = true }) => { | ||||
| 	if (!value) return null; | ||||
| 	const tagName = hydrate ? 'astro-slot' : 'astro-static-slot'; | ||||
| 	return createElement(tagName, { | ||||
| 		name, | ||||
| 		suppressHydrationWarning: true, | ||||
| 		dangerouslySetInnerHTML: { __html: value }, | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * This tells React to opt-out of re-rendering this subtree, | ||||
|  * In addition to being a performance optimization, | ||||
|  * this also allows other frameworks to attach to `children`. | ||||
|  * | ||||
|  * See https://preactjs.com/guide/v8/external-dom-mutations | ||||
|  */ | ||||
| StaticHtml.shouldComponentUpdate = () => false; | ||||
|  | ||||
| const contexts = new WeakMap(); | ||||
|  | ||||
| const ID_PREFIX = 'r'; | ||||
|  | ||||
| function getContext(rendererContextResult) { | ||||
| 	if (contexts.has(rendererContextResult)) { | ||||
| 		return contexts.get(rendererContextResult); | ||||
| 	} | ||||
| 	const ctx = { | ||||
| 		currentIndex: 0, | ||||
| 		get id() { | ||||
| 			return ID_PREFIX + this.currentIndex.toString(); | ||||
| 		}, | ||||
| 	}; | ||||
| 	contexts.set(rendererContextResult, ctx); | ||||
| 	return ctx; | ||||
| } | ||||
|  | ||||
| function incrementId(rendererContextResult) { | ||||
| 	const ctx = getContext(rendererContextResult); | ||||
| 	const id = ctx.id; | ||||
| 	ctx.currentIndex++; | ||||
| 	return id; | ||||
| } | ||||
|  | ||||
| const opts = { | ||||
| 						experimentalReactChildren: false | ||||
| 					}; | ||||
|  | ||||
| const slotName = (str) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase()); | ||||
| const reactTypeof = Symbol.for('react.element'); | ||||
|  | ||||
| function errorIsComingFromPreactComponent(err) { | ||||
| 	return ( | ||||
| 		err.message && | ||||
| 		(err.message.startsWith("Cannot read property '__H'") || | ||||
| 			err.message.includes("(reading '__H')")) | ||||
| 	); | ||||
| } | ||||
|  | ||||
| async function check(Component, props, children) { | ||||
| 	// Note: there are packages that do some unholy things to create "components". | ||||
| 	// Checking the $$typeof property catches most of these patterns. | ||||
| 	if (typeof Component === 'object') { | ||||
| 		return Component['$$typeof'].toString().slice('Symbol('.length).startsWith('react'); | ||||
| 	} | ||||
| 	if (typeof Component !== 'function') return false; | ||||
| 	if (Component.name === 'QwikComponent') return false; | ||||
|  | ||||
| 	// Preact forwarded-ref components can be functions, which React does not support | ||||
| 	if (typeof Component === 'function' && Component['$$typeof'] === Symbol.for('react.forward_ref')) | ||||
| 		return false; | ||||
|  | ||||
| 	if (Component.prototype != null && typeof Component.prototype.render === 'function') { | ||||
| 		return React.Component.isPrototypeOf(Component) || React.PureComponent.isPrototypeOf(Component); | ||||
| 	} | ||||
|  | ||||
| 	let error = null; | ||||
| 	let isReactComponent = false; | ||||
| 	function Tester(...args) { | ||||
| 		try { | ||||
| 			const vnode = Component(...args); | ||||
| 			if (vnode && vnode['$$typeof'] === reactTypeof) { | ||||
| 				isReactComponent = true; | ||||
| 			} | ||||
| 		} catch (err) { | ||||
| 			if (!errorIsComingFromPreactComponent(err)) { | ||||
| 				error = err; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return React.createElement('div'); | ||||
| 	} | ||||
|  | ||||
| 	await renderToStaticMarkup(Tester, props, children, {}); | ||||
|  | ||||
| 	if (error) { | ||||
| 		throw error; | ||||
| 	} | ||||
| 	return isReactComponent; | ||||
| } | ||||
|  | ||||
| async function getNodeWritable() { | ||||
| 	let nodeStreamBuiltinModuleName = 'node:stream'; | ||||
| 	let { Writable } = await import(/* @vite-ignore */ nodeStreamBuiltinModuleName); | ||||
| 	return Writable; | ||||
| } | ||||
|  | ||||
| function needsHydration(metadata) { | ||||
| 	// Adjust how this is hydrated only when the version of Astro supports `astroStaticSlot` | ||||
| 	return metadata.astroStaticSlot ? !!metadata.hydrate : true; | ||||
| } | ||||
|  | ||||
| async function renderToStaticMarkup(Component, props, { default: children, ...slotted }, metadata) { | ||||
| 	let prefix; | ||||
| 	if (this && this.result) { | ||||
| 		prefix = incrementId(this.result); | ||||
| 	} | ||||
| 	const attrs = { prefix }; | ||||
|  | ||||
| 	delete props['class']; | ||||
| 	const slots = {}; | ||||
| 	for (const [key, value] of Object.entries(slotted)) { | ||||
| 		const name = slotName(key); | ||||
| 		slots[name] = React.createElement(StaticHtml, { | ||||
| 			hydrate: needsHydration(metadata), | ||||
| 			value, | ||||
| 			name, | ||||
| 		}); | ||||
| 	} | ||||
| 	// Note: create newProps to avoid mutating `props` before they are serialized | ||||
| 	const newProps = { | ||||
| 		...props, | ||||
| 		...slots, | ||||
| 	}; | ||||
| 	const newChildren = children ?? props.children; | ||||
| 	if (children && opts.experimentalReactChildren) { | ||||
| 		attrs['data-react-children'] = true; | ||||
| 		const convert = await import('./chunks/vnode-children_3wEZly-Z.mjs').then((mod) => mod.default); | ||||
| 		newProps.children = convert(children); | ||||
| 	} else if (newChildren != null) { | ||||
| 		newProps.children = React.createElement(StaticHtml, { | ||||
| 			hydrate: needsHydration(metadata), | ||||
| 			value: newChildren, | ||||
| 		}); | ||||
| 	} | ||||
| 	const vnode = React.createElement(Component, newProps); | ||||
| 	const renderOptions = { | ||||
| 		identifierPrefix: prefix, | ||||
| 	}; | ||||
| 	let html; | ||||
| 	if (metadata?.hydrate) { | ||||
| 		if ('renderToReadableStream' in ReactDOM) { | ||||
| 			html = await renderToReadableStreamAsync(vnode, renderOptions); | ||||
| 		} else { | ||||
| 			html = await renderToPipeableStreamAsync(vnode, renderOptions); | ||||
| 		} | ||||
| 	} else { | ||||
| 		if ('renderToReadableStream' in ReactDOM) { | ||||
| 			html = await renderToReadableStreamAsync(vnode, renderOptions); | ||||
| 		} else { | ||||
| 			html = await renderToStaticNodeStreamAsync(vnode, renderOptions); | ||||
| 		} | ||||
| 	} | ||||
| 	return { html, attrs }; | ||||
| } | ||||
|  | ||||
| async function renderToPipeableStreamAsync(vnode, options) { | ||||
| 	const Writable = await getNodeWritable(); | ||||
| 	let html = ''; | ||||
| 	return new Promise((resolve, reject) => { | ||||
| 		let error = undefined; | ||||
| 		let stream = ReactDOM.renderToPipeableStream(vnode, { | ||||
| 			...options, | ||||
| 			onError(err) { | ||||
| 				error = err; | ||||
| 				reject(error); | ||||
| 			}, | ||||
| 			onAllReady() { | ||||
| 				stream.pipe( | ||||
| 					new Writable({ | ||||
| 						write(chunk, _encoding, callback) { | ||||
| 							html += chunk.toString('utf-8'); | ||||
| 							callback(); | ||||
| 						}, | ||||
| 						destroy() { | ||||
| 							resolve(html); | ||||
| 						}, | ||||
| 					}) | ||||
| 				); | ||||
| 			}, | ||||
| 		}); | ||||
| 	}); | ||||
| } | ||||
|  | ||||
| async function renderToStaticNodeStreamAsync(vnode, options) { | ||||
| 	const Writable = await getNodeWritable(); | ||||
| 	let html = ''; | ||||
| 	return new Promise((resolve, reject) => { | ||||
| 		let stream = ReactDOM.renderToStaticNodeStream(vnode, options); | ||||
| 		stream.on('error', (err) => { | ||||
| 			reject(err); | ||||
| 		}); | ||||
| 		stream.pipe( | ||||
| 			new Writable({ | ||||
| 				write(chunk, _encoding, callback) { | ||||
| 					html += chunk.toString('utf-8'); | ||||
| 					callback(); | ||||
| 				}, | ||||
| 				destroy() { | ||||
| 					resolve(html); | ||||
| 				}, | ||||
| 			}) | ||||
| 		); | ||||
| 	}); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Use a while loop instead of "for await" due to cloudflare and Vercel Edge issues | ||||
|  * See https://github.com/facebook/react/issues/24169 | ||||
|  */ | ||||
| async function readResult(stream) { | ||||
| 	const reader = stream.getReader(); | ||||
| 	let result = ''; | ||||
| 	const decoder = new TextDecoder('utf-8'); | ||||
| 	while (true) { | ||||
| 		const { done, value } = await reader.read(); | ||||
| 		if (done) { | ||||
| 			if (value) { | ||||
| 				result += decoder.decode(value); | ||||
| 			} else { | ||||
| 				// This closes the decoder | ||||
| 				decoder.decode(new Uint8Array()); | ||||
| 			} | ||||
|  | ||||
| 			return result; | ||||
| 		} | ||||
| 		result += decoder.decode(value, { stream: true }); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| async function renderToReadableStreamAsync(vnode, options) { | ||||
| 	return await readResult(await ReactDOM.renderToReadableStream(vnode, options)); | ||||
| } | ||||
|  | ||||
| const _renderer0 = { | ||||
| 	check, | ||||
| 	renderToStaticMarkup, | ||||
| 	supportsAstroStaticSlot: true, | ||||
| }; | ||||
|  | ||||
| const renderers = [Object.assign({"name":"@astrojs/react","clientEntrypoint":"@astrojs/react/client.js","serverEntrypoint":"@astrojs/react/server.js"}, { ssr: _renderer0 }),]; | ||||
|  | ||||
| export { renderers }; | ||||
		Reference in New Issue
	
	Block a user