├── .github ├── renovate.json └── workflows │ ├── apollo.yaml │ ├── checks.yaml │ └── deploy.yaml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── src ├── graceful_shutdown.rs ├── lib.rs ├── main.rs ├── router_auth.rs └── thing.rs └── tests ├── helpers └── mod.rs ├── router_secret.rs ├── thing.graphql └── thing.rs /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base", 5 | ":semanticCommits", 6 | ":semanticCommitTypeAll(chore)" 7 | ], 8 | "platformAutomerge": true, 9 | "automerge": true, 10 | "automergeStrategy": "squash", 11 | "lockFileMaintenance": { 12 | "enabled": true, 13 | "automerge": true 14 | }, 15 | "packageRules": [ 16 | { 17 | "matchPackagePatterns": ["async-graphql", "async-graphql-axum"], 18 | "groupName": "async-graphql" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/apollo.yaml: -------------------------------------------------------------------------------- 1 | name: Introspect current schema and subgraph name 2 | 3 | on: 4 | workflow_call: 5 | outputs: 6 | subgraph_name: 7 | description: 'Name of the subgraph to check or publish' 8 | value: ${{ jobs.get_subgraph_name.outputs.name }} 9 | schema: 10 | description: 'Name of the schema file from the artifact' 11 | value: ${{ jobs.get_schema.outputs.schema }} 12 | schema_artifact: 13 | description: 'Name of the artifact to download to get the schema' 14 | value: ${{ jobs.get_schema.outputs.schema_artifact }} 15 | jobs: 16 | get_schema: 17 | name: Start server and introspect schema 18 | runs-on: ubuntu-latest 19 | env: 20 | SCHEMA_FILE: __rover_schema.graphql 21 | SCHEMA_ARTIFACT: schema 22 | outputs: 23 | schema: ${{ env.SCHEMA_FILE }} 24 | schema_artifact: ${{ env.SCHEMA_ARTIFACT }} 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: Install Rover 28 | run: | 29 | curl -sSL https://rover.apollo.dev/nix/latest | sh 30 | echo "$HOME/.rover/bin" >> $GITHUB_PATH 31 | - uses: Swatinem/rust-cache@v2 32 | - name: Build Service 33 | run: cargo build 34 | - name: Start Service 35 | run: cargo run & 36 | env: 37 | PORT: 4000 38 | - name: Introspect schema 39 | run: rover subgraph introspect http://localhost:4000 > ${{ env.SCHEMA_FILE }} 40 | - uses: actions/upload-artifact@v4 41 | with: 42 | path: ${{ env.SCHEMA_FILE }} 43 | name: ${{ env.SCHEMA_ARTIFACT }} 44 | 45 | get_subgraph_name: 46 | name: Introspect Cargo.toml to get subgraph name 47 | runs-on: ubuntu-latest 48 | steps: 49 | - uses: actions/checkout@v4 50 | - uses: Swatinem/rust-cache@v2 51 | - name: Install cargo-get 52 | run: cargo install cargo-get 53 | - name: Get package name as subgraph name 54 | id: get_subgraph_name 55 | run: echo "name=$(cargo get --name)" >> $GITHUB_OUTPUT 56 | outputs: 57 | name: ${{ steps.get_subgraph_name.outputs.name }} 58 | -------------------------------------------------------------------------------- /.github/workflows/checks.yaml: -------------------------------------------------------------------------------- 1 | name: Tests and Checks 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | merge_group: 8 | 9 | jobs: 10 | prepare_schema: 11 | if: false 12 | uses: ./.github/workflows/apollo.yaml 13 | 14 | check_schema: 15 | name: Check Schema with Apollo Studio 16 | needs: [ prepare_schema ] 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/download-artifact@v4 20 | with: 21 | name: ${{ needs.prepare_schema.outputs.schema_artifact }} 22 | - name: Install Rover 23 | run: | 24 | curl -sSL https://rover.apollo.dev/nix/latest | sh 25 | echo "$HOME/.rover/bin" >> $GITHUB_PATH 26 | - run: rover subgraph check ${{ secrets.APOLLO_GRAPH_REF }} --schema ${{ needs.prepare_schema.outputs.schema }} --name ${{ needs.prepare_schema.outputs.subgraph_name }} 27 | env: 28 | APOLLO_KEY: ${{ secrets.APOLLO_KEY }} 29 | APOLLO_VCS_COMMIT: ${{ github.event.pull_request.head.sha }} 30 | test: 31 | name: Test 32 | runs-on: ubuntu-latest 33 | steps: 34 | - uses: actions/checkout@v4 35 | - uses: Swatinem/rust-cache@v2 36 | - name: Test 37 | run: cargo test 38 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | jobs: 10 | deploy: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Deploy 14 | run: echo "::warning file=.github/workflows/deploy.yaml,line=10,endLine=14,title=No Deploy step defined::Define your custom workflow for deploying your subgraph here." 15 | 16 | prepare_schema: 17 | if: false 18 | uses: ./.github/workflows/apollo.yaml 19 | 20 | publish_schema: 21 | name: Publish new schema to Apollo Studio 22 | needs: [ deploy, prepare_schema ] 23 | runs-on: ubuntu-latest 24 | steps: 25 | - uses: actions/download-artifact@v4 26 | with: 27 | name: ${{ needs.prepare_schema.outputs.schema_artifact }} 28 | - name: Install Rover 29 | run: | 30 | curl -sSL https://rover.apollo.dev/nix/latest | sh 31 | echo "$HOME/.rover/bin" >> $GITHUB_PATH 32 | - name: Publish Schema 33 | run: rover subgraph publish ${{ secrets.APOLLO_GRAPH_REF }} --schema ${{ needs.prepare_schema.outputs.schema }} --name ${{ needs.prepare_schema.outputs.subgraph_name }} --routing-url ${{ secrets.PRODUCTION_URL }} 34 | env: 35 | APOLLO_KEY: ${{ secrets.APOLLO_KEY }} 36 | APOLLO_VCS_COMMIT: ${{ github.event.pull_request.head.sha }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Rust 2 | target/ 3 | 4 | # JetBrains 5 | .idea 6 | .graphqlconfig 7 | schema.graphql 8 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "Inflector" 7 | version = "0.11.4" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" 10 | dependencies = [ 11 | "lazy_static", 12 | "regex", 13 | ] 14 | 15 | [[package]] 16 | name = "addr2line" 17 | version = "0.24.2" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 20 | dependencies = [ 21 | "gimli", 22 | ] 23 | 24 | [[package]] 25 | name = "adler2" 26 | version = "2.0.0" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 29 | 30 | [[package]] 31 | name = "aho-corasick" 32 | version = "1.1.3" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 35 | dependencies = [ 36 | "memchr", 37 | ] 38 | 39 | [[package]] 40 | name = "alloc-no-stdlib" 41 | version = "2.0.4" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 44 | 45 | [[package]] 46 | name = "alloc-stdlib" 47 | version = "0.2.2" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 50 | dependencies = [ 51 | "alloc-no-stdlib", 52 | ] 53 | 54 | [[package]] 55 | name = "async-compression" 56 | version = "0.4.23" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "b37fc50485c4f3f736a4fb14199f6d5f5ba008d7f28fe710306c92780f004c07" 59 | dependencies = [ 60 | "brotli", 61 | "flate2", 62 | "futures-core", 63 | "memchr", 64 | "pin-project-lite", 65 | "tokio", 66 | ] 67 | 68 | [[package]] 69 | name = "async-graphql" 70 | version = "7.0.17" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "036618f842229ba0b89652ffe425f96c7c16a49f7e3cb23b56fca7f61fd74980" 73 | dependencies = [ 74 | "async-graphql-derive", 75 | "async-graphql-parser", 76 | "async-graphql-value", 77 | "async-stream", 78 | "async-trait", 79 | "base64", 80 | "bytes", 81 | "fnv", 82 | "futures-timer", 83 | "futures-util", 84 | "http", 85 | "indexmap", 86 | "mime", 87 | "multer", 88 | "num-traits", 89 | "pin-project-lite", 90 | "regex", 91 | "serde", 92 | "serde_json", 93 | "serde_urlencoded", 94 | "static_assertions_next", 95 | "thiserror 1.0.69", 96 | "tracing", 97 | "tracing-futures", 98 | ] 99 | 100 | [[package]] 101 | name = "async-graphql-axum" 102 | version = "7.0.17" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "8725874ecfbf399e071150b8619c4071d7b2b7a2f117e173dddef53c6bdb6bb1" 105 | dependencies = [ 106 | "async-graphql", 107 | "axum", 108 | "bytes", 109 | "futures-util", 110 | "serde_json", 111 | "tokio", 112 | "tokio-stream", 113 | "tokio-util", 114 | "tower-service", 115 | ] 116 | 117 | [[package]] 118 | name = "async-graphql-derive" 119 | version = "7.0.17" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "fd45deb3dbe5da5cdb8d6a670a7736d735ba65b455328440f236dfb113727a3d" 122 | dependencies = [ 123 | "Inflector", 124 | "async-graphql-parser", 125 | "darling", 126 | "proc-macro-crate", 127 | "proc-macro2", 128 | "quote", 129 | "strum", 130 | "syn", 131 | "thiserror 1.0.69", 132 | ] 133 | 134 | [[package]] 135 | name = "async-graphql-parser" 136 | version = "7.0.17" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "60b7607e59424a35dadbc085b0d513aa54ec28160ee640cf79ec3b634eba66d3" 139 | dependencies = [ 140 | "async-graphql-value", 141 | "pest", 142 | "serde", 143 | "serde_json", 144 | ] 145 | 146 | [[package]] 147 | name = "async-graphql-value" 148 | version = "7.0.17" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "34ecdaff7c9cffa3614a9f9999bf9ee4c3078fe3ce4d6a6e161736b56febf2de" 151 | dependencies = [ 152 | "bytes", 153 | "indexmap", 154 | "serde", 155 | "serde_json", 156 | ] 157 | 158 | [[package]] 159 | name = "async-stream" 160 | version = "0.3.6" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" 163 | dependencies = [ 164 | "async-stream-impl", 165 | "futures-core", 166 | "pin-project-lite", 167 | ] 168 | 169 | [[package]] 170 | name = "async-stream-impl" 171 | version = "0.3.6" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" 174 | dependencies = [ 175 | "proc-macro2", 176 | "quote", 177 | "syn", 178 | ] 179 | 180 | [[package]] 181 | name = "async-trait" 182 | version = "0.1.88" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" 185 | dependencies = [ 186 | "proc-macro2", 187 | "quote", 188 | "syn", 189 | ] 190 | 191 | [[package]] 192 | name = "autocfg" 193 | version = "1.4.0" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 196 | 197 | [[package]] 198 | name = "axum" 199 | version = "0.8.4" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" 202 | dependencies = [ 203 | "axum-core", 204 | "base64", 205 | "bytes", 206 | "form_urlencoded", 207 | "futures-util", 208 | "http", 209 | "http-body", 210 | "http-body-util", 211 | "hyper", 212 | "hyper-util", 213 | "itoa", 214 | "matchit", 215 | "memchr", 216 | "mime", 217 | "percent-encoding", 218 | "pin-project-lite", 219 | "rustversion", 220 | "serde", 221 | "serde_json", 222 | "serde_path_to_error", 223 | "serde_urlencoded", 224 | "sha1", 225 | "sync_wrapper", 226 | "tokio", 227 | "tokio-tungstenite", 228 | "tower", 229 | "tower-layer", 230 | "tower-service", 231 | "tracing", 232 | ] 233 | 234 | [[package]] 235 | name = "axum-core" 236 | version = "0.5.2" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" 239 | dependencies = [ 240 | "bytes", 241 | "futures-core", 242 | "http", 243 | "http-body", 244 | "http-body-util", 245 | "mime", 246 | "pin-project-lite", 247 | "rustversion", 248 | "sync_wrapper", 249 | "tower-layer", 250 | "tower-service", 251 | "tracing", 252 | ] 253 | 254 | [[package]] 255 | name = "backtrace" 256 | version = "0.3.75" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" 259 | dependencies = [ 260 | "addr2line", 261 | "cfg-if", 262 | "libc", 263 | "miniz_oxide", 264 | "object", 265 | "rustc-demangle", 266 | "windows-targets", 267 | ] 268 | 269 | [[package]] 270 | name = "base64" 271 | version = "0.22.1" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 274 | 275 | [[package]] 276 | name = "bitflags" 277 | version = "2.9.1" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 280 | 281 | [[package]] 282 | name = "block-buffer" 283 | version = "0.10.4" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 286 | dependencies = [ 287 | "generic-array", 288 | ] 289 | 290 | [[package]] 291 | name = "brotli" 292 | version = "8.0.1" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d" 295 | dependencies = [ 296 | "alloc-no-stdlib", 297 | "alloc-stdlib", 298 | "brotli-decompressor", 299 | ] 300 | 301 | [[package]] 302 | name = "brotli-decompressor" 303 | version = "5.0.0" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" 306 | dependencies = [ 307 | "alloc-no-stdlib", 308 | "alloc-stdlib", 309 | ] 310 | 311 | [[package]] 312 | name = "bytes" 313 | version = "1.10.1" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 316 | dependencies = [ 317 | "serde", 318 | ] 319 | 320 | [[package]] 321 | name = "cfg-if" 322 | version = "1.0.0" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 325 | 326 | [[package]] 327 | name = "cpufeatures" 328 | version = "0.2.17" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 331 | dependencies = [ 332 | "libc", 333 | ] 334 | 335 | [[package]] 336 | name = "crc32fast" 337 | version = "1.4.2" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 340 | dependencies = [ 341 | "cfg-if", 342 | ] 343 | 344 | [[package]] 345 | name = "crypto-common" 346 | version = "0.1.6" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 349 | dependencies = [ 350 | "generic-array", 351 | "typenum", 352 | ] 353 | 354 | [[package]] 355 | name = "darling" 356 | version = "0.20.11" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" 359 | dependencies = [ 360 | "darling_core", 361 | "darling_macro", 362 | ] 363 | 364 | [[package]] 365 | name = "darling_core" 366 | version = "0.20.11" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" 369 | dependencies = [ 370 | "fnv", 371 | "ident_case", 372 | "proc-macro2", 373 | "quote", 374 | "strsim", 375 | "syn", 376 | ] 377 | 378 | [[package]] 379 | name = "darling_macro" 380 | version = "0.20.11" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" 383 | dependencies = [ 384 | "darling_core", 385 | "quote", 386 | "syn", 387 | ] 388 | 389 | [[package]] 390 | name = "data-encoding" 391 | version = "2.9.0" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" 394 | 395 | [[package]] 396 | name = "digest" 397 | version = "0.10.7" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 400 | dependencies = [ 401 | "block-buffer", 402 | "crypto-common", 403 | ] 404 | 405 | [[package]] 406 | name = "encoding_rs" 407 | version = "0.8.35" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 410 | dependencies = [ 411 | "cfg-if", 412 | ] 413 | 414 | [[package]] 415 | name = "equivalent" 416 | version = "1.0.2" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 419 | 420 | [[package]] 421 | name = "flate2" 422 | version = "1.1.1" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" 425 | dependencies = [ 426 | "crc32fast", 427 | "miniz_oxide", 428 | ] 429 | 430 | [[package]] 431 | name = "fnv" 432 | version = "1.0.7" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 435 | 436 | [[package]] 437 | name = "form_urlencoded" 438 | version = "1.2.1" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 441 | dependencies = [ 442 | "percent-encoding", 443 | ] 444 | 445 | [[package]] 446 | name = "futures" 447 | version = "0.3.31" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" 450 | dependencies = [ 451 | "futures-channel", 452 | "futures-core", 453 | "futures-executor", 454 | "futures-io", 455 | "futures-sink", 456 | "futures-task", 457 | "futures-util", 458 | ] 459 | 460 | [[package]] 461 | name = "futures-channel" 462 | version = "0.3.31" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 465 | dependencies = [ 466 | "futures-core", 467 | "futures-sink", 468 | ] 469 | 470 | [[package]] 471 | name = "futures-core" 472 | version = "0.3.31" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 475 | 476 | [[package]] 477 | name = "futures-executor" 478 | version = "0.3.31" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" 481 | dependencies = [ 482 | "futures-core", 483 | "futures-task", 484 | "futures-util", 485 | ] 486 | 487 | [[package]] 488 | name = "futures-io" 489 | version = "0.3.31" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 492 | 493 | [[package]] 494 | name = "futures-macro" 495 | version = "0.3.31" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" 498 | dependencies = [ 499 | "proc-macro2", 500 | "quote", 501 | "syn", 502 | ] 503 | 504 | [[package]] 505 | name = "futures-sink" 506 | version = "0.3.31" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 509 | 510 | [[package]] 511 | name = "futures-task" 512 | version = "0.3.31" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 515 | 516 | [[package]] 517 | name = "futures-timer" 518 | version = "3.0.3" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" 521 | 522 | [[package]] 523 | name = "futures-util" 524 | version = "0.3.31" 525 | source = "registry+https://github.com/rust-lang/crates.io-index" 526 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 527 | dependencies = [ 528 | "futures-channel", 529 | "futures-core", 530 | "futures-io", 531 | "futures-macro", 532 | "futures-sink", 533 | "futures-task", 534 | "memchr", 535 | "pin-project-lite", 536 | "pin-utils", 537 | "slab", 538 | ] 539 | 540 | [[package]] 541 | name = "generic-array" 542 | version = "0.14.7" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 545 | dependencies = [ 546 | "typenum", 547 | "version_check", 548 | ] 549 | 550 | [[package]] 551 | name = "getrandom" 552 | version = "0.3.3" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 555 | dependencies = [ 556 | "cfg-if", 557 | "libc", 558 | "r-efi", 559 | "wasi 0.14.2+wasi-0.2.4", 560 | ] 561 | 562 | [[package]] 563 | name = "gimli" 564 | version = "0.31.1" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 567 | 568 | [[package]] 569 | name = "hashbrown" 570 | version = "0.15.3" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" 573 | 574 | [[package]] 575 | name = "headers" 576 | version = "0.4.1" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" 579 | dependencies = [ 580 | "base64", 581 | "bytes", 582 | "headers-core", 583 | "http", 584 | "httpdate", 585 | "mime", 586 | "sha1", 587 | ] 588 | 589 | [[package]] 590 | name = "headers-core" 591 | version = "0.3.0" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" 594 | dependencies = [ 595 | "http", 596 | ] 597 | 598 | [[package]] 599 | name = "heck" 600 | version = "0.5.0" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 603 | 604 | [[package]] 605 | name = "http" 606 | version = "1.3.1" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" 609 | dependencies = [ 610 | "bytes", 611 | "fnv", 612 | "itoa", 613 | ] 614 | 615 | [[package]] 616 | name = "http-body" 617 | version = "1.0.1" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 620 | dependencies = [ 621 | "bytes", 622 | "http", 623 | ] 624 | 625 | [[package]] 626 | name = "http-body-util" 627 | version = "0.1.3" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" 630 | dependencies = [ 631 | "bytes", 632 | "futures-core", 633 | "http", 634 | "http-body", 635 | "pin-project-lite", 636 | ] 637 | 638 | [[package]] 639 | name = "httparse" 640 | version = "1.10.1" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 643 | 644 | [[package]] 645 | name = "httpdate" 646 | version = "1.0.3" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 649 | 650 | [[package]] 651 | name = "hyper" 652 | version = "1.6.0" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 655 | dependencies = [ 656 | "bytes", 657 | "futures-channel", 658 | "futures-util", 659 | "http", 660 | "http-body", 661 | "httparse", 662 | "httpdate", 663 | "itoa", 664 | "pin-project-lite", 665 | "smallvec", 666 | "tokio", 667 | ] 668 | 669 | [[package]] 670 | name = "hyper-util" 671 | version = "0.1.13" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" 674 | dependencies = [ 675 | "bytes", 676 | "futures-core", 677 | "http", 678 | "http-body", 679 | "hyper", 680 | "pin-project-lite", 681 | "tokio", 682 | "tower-service", 683 | ] 684 | 685 | [[package]] 686 | name = "ident_case" 687 | version = "1.0.1" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 690 | 691 | [[package]] 692 | name = "indexmap" 693 | version = "2.9.0" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" 696 | dependencies = [ 697 | "equivalent", 698 | "hashbrown", 699 | "serde", 700 | ] 701 | 702 | [[package]] 703 | name = "itoa" 704 | version = "1.0.15" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 707 | 708 | [[package]] 709 | name = "lazy_static" 710 | version = "1.5.0" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 713 | 714 | [[package]] 715 | name = "libc" 716 | version = "0.2.172" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 719 | 720 | [[package]] 721 | name = "log" 722 | version = "0.4.27" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 725 | 726 | [[package]] 727 | name = "matchers" 728 | version = "0.1.0" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 731 | dependencies = [ 732 | "regex-automata 0.1.10", 733 | ] 734 | 735 | [[package]] 736 | name = "matchit" 737 | version = "0.8.4" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" 740 | 741 | [[package]] 742 | name = "memchr" 743 | version = "2.7.4" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 746 | 747 | [[package]] 748 | name = "mime" 749 | version = "0.3.17" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 752 | 753 | [[package]] 754 | name = "miniz_oxide" 755 | version = "0.8.8" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" 758 | dependencies = [ 759 | "adler2", 760 | ] 761 | 762 | [[package]] 763 | name = "mio" 764 | version = "1.0.4" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" 767 | dependencies = [ 768 | "libc", 769 | "wasi 0.11.0+wasi-snapshot-preview1", 770 | "windows-sys 0.59.0", 771 | ] 772 | 773 | [[package]] 774 | name = "multer" 775 | version = "3.1.0" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" 778 | dependencies = [ 779 | "bytes", 780 | "encoding_rs", 781 | "futures-util", 782 | "http", 783 | "httparse", 784 | "memchr", 785 | "mime", 786 | "spin", 787 | "version_check", 788 | ] 789 | 790 | [[package]] 791 | name = "my-subgraph" 792 | version = "0.1.0" 793 | dependencies = [ 794 | "async-graphql", 795 | "async-graphql-axum", 796 | "async-trait", 797 | "axum", 798 | "headers", 799 | "http", 800 | "hyper", 801 | "serde_json", 802 | "tokio", 803 | "tower", 804 | "tower-http", 805 | "tracing", 806 | "tracing-subscriber", 807 | "urlencoding", 808 | ] 809 | 810 | [[package]] 811 | name = "nu-ansi-term" 812 | version = "0.46.0" 813 | source = "registry+https://github.com/rust-lang/crates.io-index" 814 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 815 | dependencies = [ 816 | "overload", 817 | "winapi", 818 | ] 819 | 820 | [[package]] 821 | name = "num-traits" 822 | version = "0.2.19" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 825 | dependencies = [ 826 | "autocfg", 827 | ] 828 | 829 | [[package]] 830 | name = "object" 831 | version = "0.36.7" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 834 | dependencies = [ 835 | "memchr", 836 | ] 837 | 838 | [[package]] 839 | name = "once_cell" 840 | version = "1.21.3" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 843 | 844 | [[package]] 845 | name = "overload" 846 | version = "0.1.1" 847 | source = "registry+https://github.com/rust-lang/crates.io-index" 848 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 849 | 850 | [[package]] 851 | name = "percent-encoding" 852 | version = "2.3.1" 853 | source = "registry+https://github.com/rust-lang/crates.io-index" 854 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 855 | 856 | [[package]] 857 | name = "pest" 858 | version = "2.8.0" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" 861 | dependencies = [ 862 | "memchr", 863 | "thiserror 2.0.12", 864 | "ucd-trie", 865 | ] 866 | 867 | [[package]] 868 | name = "pin-project" 869 | version = "1.1.10" 870 | source = "registry+https://github.com/rust-lang/crates.io-index" 871 | checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" 872 | dependencies = [ 873 | "pin-project-internal", 874 | ] 875 | 876 | [[package]] 877 | name = "pin-project-internal" 878 | version = "1.1.10" 879 | source = "registry+https://github.com/rust-lang/crates.io-index" 880 | checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" 881 | dependencies = [ 882 | "proc-macro2", 883 | "quote", 884 | "syn", 885 | ] 886 | 887 | [[package]] 888 | name = "pin-project-lite" 889 | version = "0.2.16" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 892 | 893 | [[package]] 894 | name = "pin-utils" 895 | version = "0.1.0" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 898 | 899 | [[package]] 900 | name = "ppv-lite86" 901 | version = "0.2.21" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" 904 | dependencies = [ 905 | "zerocopy", 906 | ] 907 | 908 | [[package]] 909 | name = "proc-macro-crate" 910 | version = "3.3.0" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" 913 | dependencies = [ 914 | "toml_edit", 915 | ] 916 | 917 | [[package]] 918 | name = "proc-macro2" 919 | version = "1.0.95" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 922 | dependencies = [ 923 | "unicode-ident", 924 | ] 925 | 926 | [[package]] 927 | name = "quote" 928 | version = "1.0.40" 929 | source = "registry+https://github.com/rust-lang/crates.io-index" 930 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 931 | dependencies = [ 932 | "proc-macro2", 933 | ] 934 | 935 | [[package]] 936 | name = "r-efi" 937 | version = "5.2.0" 938 | source = "registry+https://github.com/rust-lang/crates.io-index" 939 | checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" 940 | 941 | [[package]] 942 | name = "rand" 943 | version = "0.9.1" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" 946 | dependencies = [ 947 | "rand_chacha", 948 | "rand_core", 949 | ] 950 | 951 | [[package]] 952 | name = "rand_chacha" 953 | version = "0.9.0" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" 956 | dependencies = [ 957 | "ppv-lite86", 958 | "rand_core", 959 | ] 960 | 961 | [[package]] 962 | name = "rand_core" 963 | version = "0.9.3" 964 | source = "registry+https://github.com/rust-lang/crates.io-index" 965 | checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" 966 | dependencies = [ 967 | "getrandom", 968 | ] 969 | 970 | [[package]] 971 | name = "regex" 972 | version = "1.11.1" 973 | source = "registry+https://github.com/rust-lang/crates.io-index" 974 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 975 | dependencies = [ 976 | "aho-corasick", 977 | "memchr", 978 | "regex-automata 0.4.9", 979 | "regex-syntax 0.8.5", 980 | ] 981 | 982 | [[package]] 983 | name = "regex-automata" 984 | version = "0.1.10" 985 | source = "registry+https://github.com/rust-lang/crates.io-index" 986 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 987 | dependencies = [ 988 | "regex-syntax 0.6.29", 989 | ] 990 | 991 | [[package]] 992 | name = "regex-automata" 993 | version = "0.4.9" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 996 | dependencies = [ 997 | "aho-corasick", 998 | "memchr", 999 | "regex-syntax 0.8.5", 1000 | ] 1001 | 1002 | [[package]] 1003 | name = "regex-syntax" 1004 | version = "0.6.29" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1007 | 1008 | [[package]] 1009 | name = "regex-syntax" 1010 | version = "0.8.5" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1013 | 1014 | [[package]] 1015 | name = "rustc-demangle" 1016 | version = "0.1.24" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1019 | 1020 | [[package]] 1021 | name = "rustversion" 1022 | version = "1.0.21" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" 1025 | 1026 | [[package]] 1027 | name = "ryu" 1028 | version = "1.0.20" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 1031 | 1032 | [[package]] 1033 | name = "serde" 1034 | version = "1.0.219" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 1037 | dependencies = [ 1038 | "serde_derive", 1039 | ] 1040 | 1041 | [[package]] 1042 | name = "serde_derive" 1043 | version = "1.0.219" 1044 | source = "registry+https://github.com/rust-lang/crates.io-index" 1045 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 1046 | dependencies = [ 1047 | "proc-macro2", 1048 | "quote", 1049 | "syn", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "serde_json" 1054 | version = "1.0.140" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 1057 | dependencies = [ 1058 | "itoa", 1059 | "memchr", 1060 | "ryu", 1061 | "serde", 1062 | ] 1063 | 1064 | [[package]] 1065 | name = "serde_path_to_error" 1066 | version = "0.1.17" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" 1069 | dependencies = [ 1070 | "itoa", 1071 | "serde", 1072 | ] 1073 | 1074 | [[package]] 1075 | name = "serde_urlencoded" 1076 | version = "0.7.1" 1077 | source = "registry+https://github.com/rust-lang/crates.io-index" 1078 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1079 | dependencies = [ 1080 | "form_urlencoded", 1081 | "itoa", 1082 | "ryu", 1083 | "serde", 1084 | ] 1085 | 1086 | [[package]] 1087 | name = "sha1" 1088 | version = "0.10.6" 1089 | source = "registry+https://github.com/rust-lang/crates.io-index" 1090 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1091 | dependencies = [ 1092 | "cfg-if", 1093 | "cpufeatures", 1094 | "digest", 1095 | ] 1096 | 1097 | [[package]] 1098 | name = "sharded-slab" 1099 | version = "0.1.7" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1102 | dependencies = [ 1103 | "lazy_static", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "signal-hook-registry" 1108 | version = "1.4.5" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" 1111 | dependencies = [ 1112 | "libc", 1113 | ] 1114 | 1115 | [[package]] 1116 | name = "slab" 1117 | version = "0.4.9" 1118 | source = "registry+https://github.com/rust-lang/crates.io-index" 1119 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1120 | dependencies = [ 1121 | "autocfg", 1122 | ] 1123 | 1124 | [[package]] 1125 | name = "smallvec" 1126 | version = "1.15.0" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" 1129 | 1130 | [[package]] 1131 | name = "socket2" 1132 | version = "0.5.10" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" 1135 | dependencies = [ 1136 | "libc", 1137 | "windows-sys 0.52.0", 1138 | ] 1139 | 1140 | [[package]] 1141 | name = "spin" 1142 | version = "0.9.8" 1143 | source = "registry+https://github.com/rust-lang/crates.io-index" 1144 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1145 | 1146 | [[package]] 1147 | name = "static_assertions_next" 1148 | version = "1.1.2" 1149 | source = "registry+https://github.com/rust-lang/crates.io-index" 1150 | checksum = "d7beae5182595e9a8b683fa98c4317f956c9a2dec3b9716990d20023cc60c766" 1151 | 1152 | [[package]] 1153 | name = "strsim" 1154 | version = "0.11.1" 1155 | source = "registry+https://github.com/rust-lang/crates.io-index" 1156 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1157 | 1158 | [[package]] 1159 | name = "strum" 1160 | version = "0.26.3" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" 1163 | dependencies = [ 1164 | "strum_macros", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "strum_macros" 1169 | version = "0.26.4" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" 1172 | dependencies = [ 1173 | "heck", 1174 | "proc-macro2", 1175 | "quote", 1176 | "rustversion", 1177 | "syn", 1178 | ] 1179 | 1180 | [[package]] 1181 | name = "syn" 1182 | version = "2.0.101" 1183 | source = "registry+https://github.com/rust-lang/crates.io-index" 1184 | checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" 1185 | dependencies = [ 1186 | "proc-macro2", 1187 | "quote", 1188 | "unicode-ident", 1189 | ] 1190 | 1191 | [[package]] 1192 | name = "sync_wrapper" 1193 | version = "1.0.2" 1194 | source = "registry+https://github.com/rust-lang/crates.io-index" 1195 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 1196 | 1197 | [[package]] 1198 | name = "thiserror" 1199 | version = "1.0.69" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 1202 | dependencies = [ 1203 | "thiserror-impl 1.0.69", 1204 | ] 1205 | 1206 | [[package]] 1207 | name = "thiserror" 1208 | version = "2.0.12" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 1211 | dependencies = [ 1212 | "thiserror-impl 2.0.12", 1213 | ] 1214 | 1215 | [[package]] 1216 | name = "thiserror-impl" 1217 | version = "1.0.69" 1218 | source = "registry+https://github.com/rust-lang/crates.io-index" 1219 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 1220 | dependencies = [ 1221 | "proc-macro2", 1222 | "quote", 1223 | "syn", 1224 | ] 1225 | 1226 | [[package]] 1227 | name = "thiserror-impl" 1228 | version = "2.0.12" 1229 | source = "registry+https://github.com/rust-lang/crates.io-index" 1230 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 1231 | dependencies = [ 1232 | "proc-macro2", 1233 | "quote", 1234 | "syn", 1235 | ] 1236 | 1237 | [[package]] 1238 | name = "thread_local" 1239 | version = "1.1.8" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 1242 | dependencies = [ 1243 | "cfg-if", 1244 | "once_cell", 1245 | ] 1246 | 1247 | [[package]] 1248 | name = "tokio" 1249 | version = "1.45.1" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" 1252 | dependencies = [ 1253 | "backtrace", 1254 | "bytes", 1255 | "libc", 1256 | "mio", 1257 | "pin-project-lite", 1258 | "signal-hook-registry", 1259 | "socket2", 1260 | "tokio-macros", 1261 | "windows-sys 0.52.0", 1262 | ] 1263 | 1264 | [[package]] 1265 | name = "tokio-macros" 1266 | version = "2.5.0" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1269 | dependencies = [ 1270 | "proc-macro2", 1271 | "quote", 1272 | "syn", 1273 | ] 1274 | 1275 | [[package]] 1276 | name = "tokio-stream" 1277 | version = "0.1.17" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" 1280 | dependencies = [ 1281 | "futures-core", 1282 | "pin-project-lite", 1283 | "tokio", 1284 | ] 1285 | 1286 | [[package]] 1287 | name = "tokio-tungstenite" 1288 | version = "0.26.2" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" 1291 | dependencies = [ 1292 | "futures-util", 1293 | "log", 1294 | "tokio", 1295 | "tungstenite", 1296 | ] 1297 | 1298 | [[package]] 1299 | name = "tokio-util" 1300 | version = "0.7.15" 1301 | source = "registry+https://github.com/rust-lang/crates.io-index" 1302 | checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" 1303 | dependencies = [ 1304 | "bytes", 1305 | "futures-core", 1306 | "futures-io", 1307 | "futures-sink", 1308 | "pin-project-lite", 1309 | "tokio", 1310 | ] 1311 | 1312 | [[package]] 1313 | name = "toml_datetime" 1314 | version = "0.6.9" 1315 | source = "registry+https://github.com/rust-lang/crates.io-index" 1316 | checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" 1317 | 1318 | [[package]] 1319 | name = "toml_edit" 1320 | version = "0.22.26" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" 1323 | dependencies = [ 1324 | "indexmap", 1325 | "toml_datetime", 1326 | "winnow", 1327 | ] 1328 | 1329 | [[package]] 1330 | name = "tower" 1331 | version = "0.5.2" 1332 | source = "registry+https://github.com/rust-lang/crates.io-index" 1333 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 1334 | dependencies = [ 1335 | "futures-core", 1336 | "futures-util", 1337 | "pin-project-lite", 1338 | "sync_wrapper", 1339 | "tokio", 1340 | "tower-layer", 1341 | "tower-service", 1342 | "tracing", 1343 | ] 1344 | 1345 | [[package]] 1346 | name = "tower-http" 1347 | version = "0.6.6" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" 1350 | dependencies = [ 1351 | "async-compression", 1352 | "bitflags", 1353 | "bytes", 1354 | "futures-core", 1355 | "http", 1356 | "http-body", 1357 | "pin-project-lite", 1358 | "tokio", 1359 | "tokio-util", 1360 | "tower-layer", 1361 | "tower-service", 1362 | ] 1363 | 1364 | [[package]] 1365 | name = "tower-layer" 1366 | version = "0.3.3" 1367 | source = "registry+https://github.com/rust-lang/crates.io-index" 1368 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 1369 | 1370 | [[package]] 1371 | name = "tower-service" 1372 | version = "0.3.3" 1373 | source = "registry+https://github.com/rust-lang/crates.io-index" 1374 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1375 | 1376 | [[package]] 1377 | name = "tracing" 1378 | version = "0.1.41" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1381 | dependencies = [ 1382 | "log", 1383 | "pin-project-lite", 1384 | "tracing-attributes", 1385 | "tracing-core", 1386 | ] 1387 | 1388 | [[package]] 1389 | name = "tracing-attributes" 1390 | version = "0.1.28" 1391 | source = "registry+https://github.com/rust-lang/crates.io-index" 1392 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 1393 | dependencies = [ 1394 | "proc-macro2", 1395 | "quote", 1396 | "syn", 1397 | ] 1398 | 1399 | [[package]] 1400 | name = "tracing-core" 1401 | version = "0.1.33" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1404 | dependencies = [ 1405 | "once_cell", 1406 | "valuable", 1407 | ] 1408 | 1409 | [[package]] 1410 | name = "tracing-futures" 1411 | version = "0.2.5" 1412 | source = "registry+https://github.com/rust-lang/crates.io-index" 1413 | checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" 1414 | dependencies = [ 1415 | "futures", 1416 | "futures-task", 1417 | "pin-project", 1418 | "tracing", 1419 | ] 1420 | 1421 | [[package]] 1422 | name = "tracing-log" 1423 | version = "0.2.0" 1424 | source = "registry+https://github.com/rust-lang/crates.io-index" 1425 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 1426 | dependencies = [ 1427 | "log", 1428 | "once_cell", 1429 | "tracing-core", 1430 | ] 1431 | 1432 | [[package]] 1433 | name = "tracing-subscriber" 1434 | version = "0.3.19" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" 1437 | dependencies = [ 1438 | "matchers", 1439 | "nu-ansi-term", 1440 | "once_cell", 1441 | "regex", 1442 | "sharded-slab", 1443 | "smallvec", 1444 | "thread_local", 1445 | "tracing", 1446 | "tracing-core", 1447 | "tracing-log", 1448 | ] 1449 | 1450 | [[package]] 1451 | name = "tungstenite" 1452 | version = "0.26.2" 1453 | source = "registry+https://github.com/rust-lang/crates.io-index" 1454 | checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" 1455 | dependencies = [ 1456 | "bytes", 1457 | "data-encoding", 1458 | "http", 1459 | "httparse", 1460 | "log", 1461 | "rand", 1462 | "sha1", 1463 | "thiserror 2.0.12", 1464 | "utf-8", 1465 | ] 1466 | 1467 | [[package]] 1468 | name = "typenum" 1469 | version = "1.18.0" 1470 | source = "registry+https://github.com/rust-lang/crates.io-index" 1471 | checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 1472 | 1473 | [[package]] 1474 | name = "ucd-trie" 1475 | version = "0.1.7" 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" 1477 | checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" 1478 | 1479 | [[package]] 1480 | name = "unicode-ident" 1481 | version = "1.0.18" 1482 | source = "registry+https://github.com/rust-lang/crates.io-index" 1483 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1484 | 1485 | [[package]] 1486 | name = "urlencoding" 1487 | version = "2.1.3" 1488 | source = "registry+https://github.com/rust-lang/crates.io-index" 1489 | checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" 1490 | 1491 | [[package]] 1492 | name = "utf-8" 1493 | version = "0.7.6" 1494 | source = "registry+https://github.com/rust-lang/crates.io-index" 1495 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 1496 | 1497 | [[package]] 1498 | name = "valuable" 1499 | version = "0.1.1" 1500 | source = "registry+https://github.com/rust-lang/crates.io-index" 1501 | checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" 1502 | 1503 | [[package]] 1504 | name = "version_check" 1505 | version = "0.9.5" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1508 | 1509 | [[package]] 1510 | name = "wasi" 1511 | version = "0.11.0+wasi-snapshot-preview1" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1514 | 1515 | [[package]] 1516 | name = "wasi" 1517 | version = "0.14.2+wasi-0.2.4" 1518 | source = "registry+https://github.com/rust-lang/crates.io-index" 1519 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 1520 | dependencies = [ 1521 | "wit-bindgen-rt", 1522 | ] 1523 | 1524 | [[package]] 1525 | name = "winapi" 1526 | version = "0.3.9" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1529 | dependencies = [ 1530 | "winapi-i686-pc-windows-gnu", 1531 | "winapi-x86_64-pc-windows-gnu", 1532 | ] 1533 | 1534 | [[package]] 1535 | name = "winapi-i686-pc-windows-gnu" 1536 | version = "0.4.0" 1537 | source = "registry+https://github.com/rust-lang/crates.io-index" 1538 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1539 | 1540 | [[package]] 1541 | name = "winapi-x86_64-pc-windows-gnu" 1542 | version = "0.4.0" 1543 | source = "registry+https://github.com/rust-lang/crates.io-index" 1544 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1545 | 1546 | [[package]] 1547 | name = "windows-sys" 1548 | version = "0.52.0" 1549 | source = "registry+https://github.com/rust-lang/crates.io-index" 1550 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1551 | dependencies = [ 1552 | "windows-targets", 1553 | ] 1554 | 1555 | [[package]] 1556 | name = "windows-sys" 1557 | version = "0.59.0" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1560 | dependencies = [ 1561 | "windows-targets", 1562 | ] 1563 | 1564 | [[package]] 1565 | name = "windows-targets" 1566 | version = "0.52.6" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1569 | dependencies = [ 1570 | "windows_aarch64_gnullvm", 1571 | "windows_aarch64_msvc", 1572 | "windows_i686_gnu", 1573 | "windows_i686_gnullvm", 1574 | "windows_i686_msvc", 1575 | "windows_x86_64_gnu", 1576 | "windows_x86_64_gnullvm", 1577 | "windows_x86_64_msvc", 1578 | ] 1579 | 1580 | [[package]] 1581 | name = "windows_aarch64_gnullvm" 1582 | version = "0.52.6" 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" 1584 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1585 | 1586 | [[package]] 1587 | name = "windows_aarch64_msvc" 1588 | version = "0.52.6" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1591 | 1592 | [[package]] 1593 | name = "windows_i686_gnu" 1594 | version = "0.52.6" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1597 | 1598 | [[package]] 1599 | name = "windows_i686_gnullvm" 1600 | version = "0.52.6" 1601 | source = "registry+https://github.com/rust-lang/crates.io-index" 1602 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1603 | 1604 | [[package]] 1605 | name = "windows_i686_msvc" 1606 | version = "0.52.6" 1607 | source = "registry+https://github.com/rust-lang/crates.io-index" 1608 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1609 | 1610 | [[package]] 1611 | name = "windows_x86_64_gnu" 1612 | version = "0.52.6" 1613 | source = "registry+https://github.com/rust-lang/crates.io-index" 1614 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1615 | 1616 | [[package]] 1617 | name = "windows_x86_64_gnullvm" 1618 | version = "0.52.6" 1619 | source = "registry+https://github.com/rust-lang/crates.io-index" 1620 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1621 | 1622 | [[package]] 1623 | name = "windows_x86_64_msvc" 1624 | version = "0.52.6" 1625 | source = "registry+https://github.com/rust-lang/crates.io-index" 1626 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1627 | 1628 | [[package]] 1629 | name = "winnow" 1630 | version = "0.7.10" 1631 | source = "registry+https://github.com/rust-lang/crates.io-index" 1632 | checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" 1633 | dependencies = [ 1634 | "memchr", 1635 | ] 1636 | 1637 | [[package]] 1638 | name = "wit-bindgen-rt" 1639 | version = "0.39.0" 1640 | source = "registry+https://github.com/rust-lang/crates.io-index" 1641 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 1642 | dependencies = [ 1643 | "bitflags", 1644 | ] 1645 | 1646 | [[package]] 1647 | name = "zerocopy" 1648 | version = "0.8.25" 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" 1650 | checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" 1651 | dependencies = [ 1652 | "zerocopy-derive", 1653 | ] 1654 | 1655 | [[package]] 1656 | name = "zerocopy-derive" 1657 | version = "0.8.25" 1658 | source = "registry+https://github.com/rust-lang/crates.io-index" 1659 | checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" 1660 | dependencies = [ 1661 | "proc-macro2", 1662 | "quote", 1663 | "syn", 1664 | ] 1665 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "my-subgraph" # TODO: Rename This 3 | version = "0.1.0" 4 | edition = "2021" 5 | rust-version = "1.70.0" 6 | publish = false 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | async-graphql = { version = "7.0.3", default-features = false, features = ["tracing"] } 12 | async-graphql-axum = { version = "7.0.3", default-features = false } 13 | async-trait = "0.1.80" 14 | axum = { version = "0.8.0", default-features = false } 15 | headers = "0.4.0" 16 | http = "1.1.0" 17 | hyper = "1.3.1" 18 | tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread", "signal"] } 19 | tower = "0.5.0" 20 | tower-http = { version = "0.6.0", features = ["compression-br", "compression-gzip", "cors"] } 21 | tracing = "0.1.40" 22 | tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } 23 | urlencoding = "2.1.3" 24 | 25 | [dev-dependencies] 26 | tower = { version = "0.5.0", features = ["util"] } 27 | serde_json = "1.0.116" 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Apollo Graph, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # async-graphql Subgraph Template 2 | 3 | [![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/1KF0vV) 4 | 5 | This template can be used to quickly create an [Apollo Federation] subgraph with the [async-graphql] crate. 6 | 7 | ## What's Included 8 | 9 | - A basic, [Apollo Federation] subgraph with simple examples for queries, entities, and mutations. You can run this subgraph with `cargo run` or `cargo watch -x run` if using [cargo-watch] for auto-reloading. 10 | - Example tests in the `tests` directory. You can run these tests with `cargo test`. 11 | - GitHub Actions workflows which will: 12 | - Run `cargo test` on every push. 13 | - Check the schema against Apollo Studio on every push. 14 | - Publish the subgraph to Apollo Studio on every push to the `main` branch. 15 | 16 | ## Next Steps 17 | 18 | - Download [Rover] and start it using the command printed out from `cargo run` to start a local version of Apollo Explorer. 19 | - Replace "my-subgraph" in `Cargo.toml` with the name of your subgraph. 20 | - Start filling in your own types and resolvers in `src/lib.rs`. 21 | - Set these secrets in GitHub Actions: 22 | - `APOLLO_KEY`: An Apollo Studio API key for the supergraph to enable schema checks and publishing of the subgraph. 23 | - `APOLLO_GRAPH_REF`: The name of the supergraph in Apollo Studio. 24 | - `PRODUCTION_URL`: The URL of the deployed subgraph that the supergraph gateway will route to. 25 | - Remove the `if: false` lines from `.github/workflows/checks.yaml` and `.github/workflows/deploy.yaml` to enable schema checks and publishing. 26 | - Write your custom deploy logic in `.github/workflows/deploy.yaml`. 27 | - Send the `Router-Authorization` header [from your Cloud router](https://www.apollographql.com/docs/graphos/routing/cloud-configuration#managing-secrets) and set the `ROUTER_SECRET` environment variable wherever you deploy this to. 28 | 29 | [apollo federation]: https://www.apollographql.com/docs/federation/ 30 | [async-graphql]: https://async-graphql.github.io/async-graphql/ 31 | [cargo-watch]: https://crates.io/crates/cargo-watch 32 | [rover]: https://www.apollographql.com/docs/rover/ 33 | -------------------------------------------------------------------------------- /src/graceful_shutdown.rs: -------------------------------------------------------------------------------- 1 | //! Implements common graceful shutdown listeners so that connections won't be suddenly dropped 2 | //! during deployments. Typically, this involves sending SIGTERM to the process (e.g., the default 3 | //! for Kubernetes pods), but can also mean sending SIGINT. 4 | 5 | use tokio::{ 6 | select, 7 | signal::{ 8 | ctrl_c, 9 | unix::{signal, SignalKind}, 10 | }, 11 | }; 12 | 13 | /// Returns when receiving a signal that indicates the server should shut down gracefully. This is 14 | /// CTRL+C on all platforms, and additionally SIGTERM on Unix platforms. 15 | /// 16 | /// # Panics 17 | /// 18 | /// If underlying signals cannot be attached. 19 | #[cfg(not(target_os = "windows"))] 20 | pub async fn graceful_shutdown() { 21 | let mut signal = signal(SignalKind::terminate()).unwrap(); 22 | select! { 23 | _ = signal.recv() => { 24 | println!("Received SIGTERM, shutting down"); 25 | } 26 | _ = ctrl_c() => { 27 | println!("Received SIGINT, shutting down"); 28 | } 29 | } 30 | } 31 | 32 | /// Returns when receiving a signal that indicates the server should shut down gracefully. This is 33 | /// CTRL+C on all platforms, and additionally SIGTERM on Unix platforms. 34 | #[cfg(target_os = "windows")] 35 | pub async fn graceful_shutdown() { 36 | ctrl_c().await; 37 | println!("Received CTRL+C, shutting down"); 38 | } 39 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use async_graphql::{extensions::Tracing, EmptySubscription, Object, ID}; 4 | use async_graphql_axum::{GraphQLRequest, GraphQLResponse}; 5 | use axum::{extract::Extension, middleware::from_fn_with_state, routing::post, Router}; 6 | use http::{HeaderValue, Method}; 7 | use tower::ServiceBuilder; 8 | use tower_http::{ 9 | compression::CompressionLayer, 10 | cors::{Any, CorsLayer}, 11 | }; 12 | 13 | pub use crate::graceful_shutdown::graceful_shutdown; 14 | use crate::{ 15 | router_auth::require_router_auth, 16 | thing::{get_thing, CreateThing, Thing}, 17 | }; 18 | 19 | mod graceful_shutdown; 20 | mod router_auth; 21 | mod thing; 22 | 23 | struct Query; 24 | 25 | #[Object] 26 | impl Query { 27 | // TODO: Fill in query AND entity resolvers 28 | /// This will show up in the supergraph schema as part of Query. 29 | async fn thing(&self, id: ID) -> Option { 30 | get_thing(id) 31 | } 32 | 33 | /// This will be available to other subgraphs as an entity. 34 | #[graphql(entity)] 35 | async fn thing_entity_by_id(&self, id: ID) -> Option { 36 | get_thing(id) 37 | } 38 | } 39 | 40 | struct Mutation; 41 | 42 | #[Object] 43 | impl Mutation { 44 | // TODO: Fill in mutation resolvers 45 | async fn create_thing(&self, thing: CreateThing) -> Thing { 46 | let CreateThing { id, name } = thing; 47 | Thing { id, name } 48 | } 49 | } 50 | 51 | type Schema = async_graphql::Schema; 52 | 53 | async fn graphql_handler(schema: Extension, req: GraphQLRequest) -> GraphQLResponse { 54 | schema.execute(req.into_inner()).await.into() 55 | } 56 | 57 | pub fn app(router_secret: Option) -> Router { 58 | let schema: Schema = Schema::build(Query, Mutation, EmptySubscription) 59 | .enable_federation() 60 | .limit_complexity(250) 61 | .extension(Tracing) 62 | .finish(); 63 | 64 | let cors = CorsLayer::new() 65 | .allow_methods([Method::POST]) 66 | .allow_headers(Any) 67 | .allow_origin( 68 | "https://studio.apollographql.com" 69 | .parse::() 70 | .expect("Can enable sandbox CORS"), 71 | ); 72 | 73 | let router_secret = router_secret.map(Arc::from); 74 | 75 | Router::new().route("/", post(graphql_handler)).layer( 76 | ServiceBuilder::new() 77 | .layer(Extension(schema)) 78 | .layer(CompressionLayer::new()) 79 | .layer(cors) 80 | .layer(from_fn_with_state(router_secret, require_router_auth)), 81 | ) 82 | } 83 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use tokio::net::TcpListener; 2 | use tracing::info; 3 | use tracing_subscriber::{EnvFilter, FmtSubscriber, layer::SubscriberExt, util::SubscriberInitExt}; 4 | 5 | use my_subgraph::{app, graceful_shutdown}; 6 | 7 | #[tokio::main] 8 | async fn main() { 9 | FmtSubscriber::new() 10 | .with( 11 | EnvFilter::builder() 12 | .with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into()) 13 | .from_env() 14 | .expect("Could not set up tracing subscriber"), 15 | ) 16 | .init(); 17 | let app = app(std::env::var("ROUTER_SECRET").ok()); 18 | let port = std::env::var("PORT") 19 | .unwrap_or_else(|_| "4001".to_string()) 20 | .parse::() 21 | .unwrap(); 22 | 23 | info!( 24 | "Explore this graph at https://studio.apollographql.com/sandbox/explorer?endpoint={}", 25 | urlencoding::encode(&format!("http://localhost:{port}")) 26 | ); 27 | 28 | let listener = TcpListener::bind(("0.0.0.0", port)) 29 | .await 30 | .expect("Could not bind to port"); 31 | axum::serve(listener, app) 32 | .with_graceful_shutdown(graceful_shutdown()) 33 | .await 34 | .unwrap(); 35 | } 36 | -------------------------------------------------------------------------------- /src/router_auth.rs: -------------------------------------------------------------------------------- 1 | use std::sync::Arc; 2 | 3 | use axum::{body::Body, extract::State, http::StatusCode, middleware::Next, response::Response}; 4 | use http::Request; 5 | 6 | pub(crate) async fn require_router_auth( 7 | State(secret): State>>, 8 | request: Request, 9 | next: Next, 10 | ) -> Response { 11 | if let Some(token) = secret.as_deref() { 12 | let auth = request 13 | .headers() 14 | .get("Router-Authorization") 15 | .map(|header_value| header_value.to_str().unwrap_or_default()); 16 | match auth { 17 | Some(header) if header == token => (), 18 | _ => { 19 | return Response::builder() 20 | .status(StatusCode::UNAUTHORIZED) 21 | .body(Body::empty()) 22 | .unwrap() 23 | } 24 | } 25 | } 26 | next.run(request).await 27 | } 28 | -------------------------------------------------------------------------------- /src/thing.rs: -------------------------------------------------------------------------------- 1 | use async_graphql::{InputObject, SimpleObject, ID}; 2 | 3 | #[derive(SimpleObject)] 4 | /// An example type which can be resolved either as an entity or via direct query 5 | pub(crate) struct Thing { 6 | pub(crate) id: ID, 7 | pub(crate) name: Option, 8 | } 9 | 10 | #[derive(InputObject)] 11 | pub(crate) struct CreateThing { 12 | pub(crate) id: ID, 13 | pub(crate) name: Option, 14 | } 15 | 16 | pub(crate) fn get_thing(id: ID) -> Option { 17 | if id == "1" { 18 | Some(Thing { 19 | id, 20 | name: Some(String::from("Name")), 21 | }) 22 | } else { 23 | None 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/helpers/mod.rs: -------------------------------------------------------------------------------- 1 | use axum::{ 2 | body::Body, 3 | http::{self, Request, StatusCode}, 4 | }; 5 | use axum::body::to_bytes; 6 | use my_subgraph::app; 7 | use serde_json::{json, Value}; 8 | use tower::ServiceExt; 9 | 10 | pub(crate) async fn run_graphql_query(query: &str, operation: &str) -> Value { 11 | let app = app(None); 12 | let response = app 13 | .oneshot( 14 | Request::builder() 15 | .method(http::Method::POST) 16 | .uri("/") 17 | .header(http::header::CONTENT_TYPE, "application/json") 18 | .body(Body::from( 19 | json!({"query": query, "operationName": operation}).to_string(), 20 | )) 21 | .unwrap(), 22 | ) 23 | .await 24 | .unwrap(); 25 | let status = response.status(); 26 | let body = to_bytes(response.into_body(), usize::MAX).await.unwrap(); 27 | assert_eq!(status, StatusCode::OK, "{:#?}", body); 28 | 29 | serde_json::from_slice(&body).unwrap() 30 | } 31 | -------------------------------------------------------------------------------- /tests/router_secret.rs: -------------------------------------------------------------------------------- 1 | use axum::body::{to_bytes, Body, Bytes}; 2 | use http::{Request, StatusCode}; 3 | use my_subgraph::app; 4 | use serde_json::{json, Value}; 5 | use tower::ServiceExt; 6 | 7 | async fn run_graphql_query( 8 | query: &str, 9 | app_secret: Option, 10 | header_secret: Option, 11 | ) -> (StatusCode, Bytes) { 12 | let app = app(app_secret); 13 | let mut request = Request::builder() 14 | .method(http::Method::POST) 15 | .uri("/") 16 | .header(http::header::CONTENT_TYPE, "application/json"); 17 | if let Some(header_secret) = header_secret { 18 | request = request.header("Router-Authorization", header_secret); 19 | } 20 | let response = app 21 | .oneshot( 22 | request 23 | .body(Body::from(json!({"query": query}).to_string())) 24 | .unwrap(), 25 | ) 26 | .await 27 | .unwrap(); 28 | let status = response.status(); 29 | let body = to_bytes(response.into_body(), usize::MAX).await.unwrap(); 30 | (status, body) 31 | } 32 | 33 | #[tokio::test] 34 | async fn test_missing_secret() { 35 | let (status, body) = run_graphql_query( 36 | r#" 37 | query { 38 | _service { 39 | sdl 40 | } 41 | } 42 | "#, 43 | Some("secret".to_string()), 44 | None, 45 | ) 46 | .await; 47 | assert_eq!(status, StatusCode::UNAUTHORIZED); 48 | assert!(body.is_empty()) 49 | } 50 | 51 | #[tokio::test] 52 | async fn test_incorrect_secret() { 53 | let (status, body) = run_graphql_query( 54 | r#" 55 | query { 56 | _service { 57 | sdl 58 | } 59 | } 60 | "#, 61 | Some("secret".to_string()), 62 | Some("secret2".to_string()), 63 | ) 64 | .await; 65 | assert_eq!(status, StatusCode::UNAUTHORIZED); 66 | assert!(body.is_empty()) 67 | } 68 | 69 | #[tokio::test] 70 | async fn test_authorized() { 71 | let (status, body) = run_graphql_query( 72 | r#" 73 | query { 74 | _service { 75 | sdl 76 | } 77 | } 78 | "#, 79 | Some("secret".to_string()), 80 | Some("secret".to_string()), 81 | ) 82 | .await; 83 | assert_eq!(status, StatusCode::OK); 84 | let json = serde_json::from_slice::(&body).expect("invalid json"); 85 | assert!(json.get("data").is_some()); 86 | assert!(json.get("errors").is_none()); 87 | } 88 | -------------------------------------------------------------------------------- /tests/thing.graphql: -------------------------------------------------------------------------------- 1 | query getThing { 2 | thing(id: "1") { 3 | name 4 | } 5 | } 6 | 7 | query getThingEntity { 8 | _entities(representations: [{__typename: "Thing", id: "1"}]) { 9 | ... on Thing { 10 | name 11 | } 12 | } 13 | } 14 | 15 | mutation createThing { 16 | createThing(thing: {id: "1"}) { 17 | name 18 | } 19 | } -------------------------------------------------------------------------------- /tests/thing.rs: -------------------------------------------------------------------------------- 1 | //! Tests for the `Thing` type, queries are in `thing.graphql` 2 | 3 | use serde_json::{json, Value}; 4 | 5 | mod helpers; 6 | 7 | async fn run_graphql_query(operation: &str) -> Value { 8 | helpers::run_graphql_query(include_str!("thing.graphql"), operation).await 9 | } 10 | 11 | #[tokio::test] 12 | async fn get_thing() { 13 | let value = run_graphql_query("getThing").await; 14 | 15 | assert_eq!(value, json!({ "data": { "thing": { "name": "Name" } } })); 16 | } 17 | 18 | #[tokio::test] 19 | async fn get_thing_entity() { 20 | let value = run_graphql_query("getThingEntity").await; 21 | 22 | assert_eq!( 23 | value, 24 | json!({ "data": { "_entities": [{"name": "Name" }] } }) 25 | ); 26 | } 27 | 28 | #[tokio::test] 29 | async fn create_thing() { 30 | let value = run_graphql_query("createThing").await; 31 | 32 | assert_eq!( 33 | value, 34 | json!({ "data": { "createThing": { "name": null } } }) 35 | ); 36 | } 37 | --------------------------------------------------------------------------------