├── .cargo └── config.toml ├── .dockerignore ├── .editorconfig ├── .github └── workflows │ ├── approve-merge.yaml │ ├── build.yaml │ ├── pr-lint.yml │ ├── release-pr.yaml │ └── release.yaml ├── .gitignore ├── .releaserc.json ├── Cargo.lock ├── Cargo.toml ├── Dockerfile ├── LICENSE ├── README.adoc ├── TODO.md ├── build.rs ├── buildImage.bash ├── cfg ├── config.json ├── config_development.json └── config_production.json ├── docs ├── antora.yml └── modules │ └── ROOT │ ├── assets │ └── images │ │ └── fonts.png │ ├── nav.adoc │ └── pages │ └── index.adoc ├── lint.sh ├── pdf_rendering.proto └── src ├── main.rs ├── pdf_utils.rs ├── proto.rs ├── renderer.rs ├── s3.rs ├── server.rs └── types.rs /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | rustflags = ["--cfg", "tokio_unstable"] 3 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !Cargo.lock 3 | !Cargo.toml 4 | !src/ 5 | !build.rs 6 | !pdf_rendering.proto 7 | !cfg 8 | !.cargo -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = true 13 | -------------------------------------------------------------------------------- /.github/workflows/approve-merge.yaml: -------------------------------------------------------------------------------- 1 | name: Merge Release PR 2 | 3 | on: 4 | pull_request_review: 5 | types: [submitted] 6 | 7 | jobs: 8 | pr_approved: 9 | if: ${{ github.event.review.state == 'approved' && github.event.pull_request.base.ref == 'master' && github.event.pull_request.head.ref == 'next' }} 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Clone git repo 13 | uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | 17 | - name: Merge PR 18 | run: | 19 | git config --global user.email "bot@restorecommerce.io" 20 | git config --global user.name "Restorecommerce Bot" 21 | git checkout master 22 | git merge --ff origin/next 23 | git push -u origin master 24 | - uses: benc-uk/workflow-dispatch@v1 25 | with: 26 | workflow: release.yaml 27 | ref: master -------------------------------------------------------------------------------- /.github/workflows/build.yaml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: push 4 | 5 | jobs: 6 | image: 7 | runs-on: ubuntu-22.04 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v2 11 | 12 | - name: Setup buildx 13 | uses: docker/setup-buildx-action@v1 14 | 15 | - name: Set variables 16 | id: vars 17 | run: | 18 | echo ::set-output name=version_tag::$(echo ${GITHUB_REF#refs/*/}) 19 | echo ::set-output name=repo_name::$(echo ${GITHUB_REPOSITORY#*/*}) 20 | 21 | - name: Build 22 | uses: docker/build-push-action@v2 23 | with: 24 | context: . 25 | file: ./Dockerfile 26 | platforms: linux/amd64 27 | push: false 28 | build-args: | 29 | APP_HOME=/home/node/${{ steps.vars.outputs.repo_name }} 30 | cache-from: | 31 | ${{ github.repository }}:latest 32 | -------------------------------------------------------------------------------- /.github/workflows/pr-lint.yml: -------------------------------------------------------------------------------- 1 | name: "Lint PR" 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | permissions: 11 | pull-requests: read 12 | 13 | jobs: 14 | lint: 15 | name: pr-lint 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: amannn/action-semantic-pull-request@v5 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/release-pr.yaml: -------------------------------------------------------------------------------- 1 | name: Release PR 2 | 3 | on: 4 | push: 5 | branches: 6 | - next 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | release_pr: 13 | permissions: 14 | issues: write 15 | pull-requests: write 16 | contents: write 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 22 | 23 | - name: Generate Changes 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | run: | 27 | set -ex 28 | echo '# Release Changes' > changes.md 29 | npx semantic-release@22.0.12 -d -p '@semantic-release/release-notes-generator' -b next | grep -v semantic-release | tee -a changes.md 30 | printf '\n---\n\n### Approve this PR to release above packages!' >> changes.md 31 | - name: Create PR 32 | env: 33 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | run: | 35 | set -ex 36 | export PR_NUMBER=$(gh pr list -B master -H next --json number | jq -r '.[0].number') 37 | if [[ "$(git rev-parse origin/master)" == "$(git rev-parse origin/next)" ]]; then exit 0; fi 38 | if [[ "$PR_NUMBER" == "null" ]]; then gh pr create -B master -H next -t "chore: release" -F changes.md; fi 39 | if [[ "$PR_NUMBER" != "null" ]]; then gh pr edit $PR_NUMBER -F changes.md; fi -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | release: 14 | permissions: 15 | contents: write 16 | issues: write 17 | pull-requests: write 18 | runs-on: ubuntu-22.04 19 | steps: 20 | - uses: actions/checkout@v4 21 | with: 22 | ref: master 23 | 24 | - uses: docker/login-action@v3 25 | with: 26 | username: ${{ secrets.DOCKERHUB_USERNAME }} 27 | password: ${{ secrets.DOCKERHUB_TOKEN }} 28 | 29 | - uses: docker/login-action@v3 30 | with: 31 | registry: ghcr.io 32 | username: ${{ github.repository_owner }} 33 | password: ${{ secrets.CR_PAT }} 34 | 35 | - uses: docker/setup-buildx-action@v3 36 | with: 37 | install: true 38 | 39 | - name: Set variables 40 | id: vars 41 | run: | 42 | echo ::set-output name=repo_name::$(echo ${GITHUB_REPOSITORY#*/*}) 43 | 44 | - uses: docker/metadata-action@v5 45 | id: docker_meta 46 | with: 47 | images: ${{ github.repository }} 48 | 49 | - uses: docker/build-push-action@v5 50 | with: 51 | load: true 52 | tags: ${{ github.repository }} 53 | labels: ${{ steps.docker_meta.outputs.labels }} 54 | 55 | - name: Install Dependencies 56 | run: npm i --no-save @semantic-release-plus/docker 57 | 58 | - run: npx semantic-release@22.0.12 59 | env: 60 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 61 | 62 | - uses: benc-uk/workflow-dispatch@v1 63 | with: 64 | workflow: upgrade-services.yaml 65 | ref: master 66 | repo: restorecommerce/charts 67 | token: "${{ secrets.CHARTS_WORKFLOW_TOKEN }}" -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | target 4 | 5 | .nyc_output 6 | .project 7 | .settings 8 | .directory 9 | .vscode 10 | .env 11 | .vscode/* 12 | .DS_Store 13 | .idea 14 | 15 | *.js 16 | *.d.ts 17 | !.eslintrc.js 18 | !setupTopics.js 19 | config 20 | id_rsa 21 | id_rsa.pub 22 | known_hosts 23 | # 24 | -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "branches": [ 3 | "master" 4 | ], 5 | "plugins": [ 6 | "@semantic-release/commit-analyzer", 7 | "@semantic-release/release-notes-generator", 8 | "@semantic-release/github", 9 | [ 10 | "@semantic-release-plus/docker", 11 | { 12 | "name": "docker.io/restorecommerce/pdf-rendering-srv", 13 | "skipLogin": true 14 | } 15 | ], 16 | [ 17 | "@semantic-release-plus/docker", 18 | { 19 | "name": "ghcr.io/restorecommerce/pdf-rendering-srv", 20 | "skipLogin": true 21 | } 22 | ] 23 | ] 24 | } -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "aes" 22 | version = "0.8.4" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" 25 | dependencies = [ 26 | "cfg-if", 27 | "cipher", 28 | "cpufeatures", 29 | ] 30 | 31 | [[package]] 32 | name = "aho-corasick" 33 | version = "1.1.3" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 36 | dependencies = [ 37 | "memchr", 38 | ] 39 | 40 | [[package]] 41 | name = "allocator-api2" 42 | version = "0.2.21" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" 45 | 46 | [[package]] 47 | name = "android-tzdata" 48 | version = "0.1.1" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 51 | 52 | [[package]] 53 | name = "android_system_properties" 54 | version = "0.1.5" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 57 | dependencies = [ 58 | "libc", 59 | ] 60 | 61 | [[package]] 62 | name = "anstream" 63 | version = "0.6.18" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 66 | dependencies = [ 67 | "anstyle", 68 | "anstyle-parse", 69 | "anstyle-query", 70 | "anstyle-wincon", 71 | "colorchoice", 72 | "is_terminal_polyfill", 73 | "utf8parse", 74 | ] 75 | 76 | [[package]] 77 | name = "anstyle" 78 | version = "1.0.10" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 81 | 82 | [[package]] 83 | name = "anstyle-parse" 84 | version = "0.2.6" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 87 | dependencies = [ 88 | "utf8parse", 89 | ] 90 | 91 | [[package]] 92 | name = "anstyle-query" 93 | version = "1.1.2" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 96 | dependencies = [ 97 | "windows-sys 0.59.0", 98 | ] 99 | 100 | [[package]] 101 | name = "anstyle-wincon" 102 | version = "3.0.7" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" 105 | dependencies = [ 106 | "anstyle", 107 | "once_cell", 108 | "windows-sys 0.59.0", 109 | ] 110 | 111 | [[package]] 112 | name = "anyhow" 113 | version = "1.0.97" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" 116 | 117 | [[package]] 118 | name = "arraydeque" 119 | version = "0.5.1" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" 122 | 123 | [[package]] 124 | name = "ascii" 125 | version = "1.1.0" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" 128 | 129 | [[package]] 130 | name = "async-trait" 131 | version = "0.1.88" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" 134 | dependencies = [ 135 | "proc-macro2", 136 | "quote", 137 | "syn", 138 | ] 139 | 140 | [[package]] 141 | name = "atomic-waker" 142 | version = "1.1.2" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 145 | 146 | [[package]] 147 | name = "auto_generate_cdp" 148 | version = "0.4.5" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "d6e1961a0d5d77969057eba90d448e610d3c439024d135d9dbd98e33ec973520" 151 | dependencies = [ 152 | "convert_case 0.4.0", 153 | "proc-macro2", 154 | "quote", 155 | "serde", 156 | "serde_json", 157 | "ureq", 158 | ] 159 | 160 | [[package]] 161 | name = "autocfg" 162 | version = "1.4.0" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 165 | 166 | [[package]] 167 | name = "aws-credential-types" 168 | version = "1.2.2" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "4471bef4c22a06d2c7a1b6492493d3fdf24a805323109d6874f9c94d5906ac14" 171 | dependencies = [ 172 | "aws-smithy-async", 173 | "aws-smithy-runtime-api", 174 | "aws-smithy-types", 175 | "zeroize", 176 | ] 177 | 178 | [[package]] 179 | name = "aws-lc-rs" 180 | version = "1.12.6" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01" 183 | dependencies = [ 184 | "aws-lc-sys", 185 | "zeroize", 186 | ] 187 | 188 | [[package]] 189 | name = "aws-lc-sys" 190 | version = "0.27.1" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "77926887776171ced7d662120a75998e444d3750c951abfe07f90da130514b1f" 193 | dependencies = [ 194 | "bindgen", 195 | "cc", 196 | "cmake", 197 | "dunce", 198 | "fs_extra", 199 | ] 200 | 201 | [[package]] 202 | name = "aws-runtime" 203 | version = "1.5.6" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "0aff45ffe35196e593ea3b9dd65b320e51e2dda95aff4390bc459e461d09c6ad" 206 | dependencies = [ 207 | "aws-credential-types", 208 | "aws-sigv4", 209 | "aws-smithy-async", 210 | "aws-smithy-eventstream", 211 | "aws-smithy-http", 212 | "aws-smithy-runtime", 213 | "aws-smithy-runtime-api", 214 | "aws-smithy-types", 215 | "aws-types", 216 | "bytes", 217 | "fastrand", 218 | "http 0.2.12", 219 | "http-body 0.4.6", 220 | "once_cell", 221 | "percent-encoding", 222 | "pin-project-lite", 223 | "tracing", 224 | "uuid", 225 | ] 226 | 227 | [[package]] 228 | name = "aws-sdk-config" 229 | version = "1.65.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "2645fb2c8b9876a46a3d79f06aad47063baf054085ea887a1e6d6f159e8a7501" 232 | dependencies = [ 233 | "aws-credential-types", 234 | "aws-runtime", 235 | "aws-smithy-async", 236 | "aws-smithy-http", 237 | "aws-smithy-json", 238 | "aws-smithy-runtime", 239 | "aws-smithy-runtime-api", 240 | "aws-smithy-types", 241 | "aws-types", 242 | "bytes", 243 | "http 0.2.12", 244 | "once_cell", 245 | "regex-lite", 246 | "tracing", 247 | ] 248 | 249 | [[package]] 250 | name = "aws-sdk-s3" 251 | version = "1.79.0" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "a8f63ba8f5fca32061c7d62d866ef65470edde38d4c5f8a0ebb8ff40a0521e1c" 254 | dependencies = [ 255 | "aws-credential-types", 256 | "aws-runtime", 257 | "aws-sigv4", 258 | "aws-smithy-async", 259 | "aws-smithy-checksums", 260 | "aws-smithy-eventstream", 261 | "aws-smithy-http", 262 | "aws-smithy-json", 263 | "aws-smithy-runtime", 264 | "aws-smithy-runtime-api", 265 | "aws-smithy-types", 266 | "aws-smithy-xml", 267 | "aws-types", 268 | "bytes", 269 | "fastrand", 270 | "hex", 271 | "hmac", 272 | "http 0.2.12", 273 | "http 1.3.1", 274 | "http-body 0.4.6", 275 | "lru", 276 | "once_cell", 277 | "percent-encoding", 278 | "regex-lite", 279 | "sha2", 280 | "tracing", 281 | "url", 282 | ] 283 | 284 | [[package]] 285 | name = "aws-sigv4" 286 | version = "1.3.0" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "69d03c3c05ff80d54ff860fe38c726f6f494c639ae975203a101335f223386db" 289 | dependencies = [ 290 | "aws-credential-types", 291 | "aws-smithy-eventstream", 292 | "aws-smithy-http", 293 | "aws-smithy-runtime-api", 294 | "aws-smithy-types", 295 | "bytes", 296 | "crypto-bigint 0.5.5", 297 | "form_urlencoded", 298 | "hex", 299 | "hmac", 300 | "http 0.2.12", 301 | "http 1.3.1", 302 | "once_cell", 303 | "p256", 304 | "percent-encoding", 305 | "ring", 306 | "sha2", 307 | "subtle", 308 | "time", 309 | "tracing", 310 | "zeroize", 311 | ] 312 | 313 | [[package]] 314 | name = "aws-smithy-async" 315 | version = "1.2.5" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "1e190749ea56f8c42bf15dd76c65e14f8f765233e6df9b0506d9d934ebef867c" 318 | dependencies = [ 319 | "futures-util", 320 | "pin-project-lite", 321 | "tokio", 322 | ] 323 | 324 | [[package]] 325 | name = "aws-smithy-checksums" 326 | version = "0.63.1" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "b65d21e1ba6f2cdec92044f904356a19f5ad86961acf015741106cdfafd747c0" 329 | dependencies = [ 330 | "aws-smithy-http", 331 | "aws-smithy-types", 332 | "bytes", 333 | "crc32c", 334 | "crc32fast", 335 | "crc64fast-nvme", 336 | "hex", 337 | "http 0.2.12", 338 | "http-body 0.4.6", 339 | "md-5", 340 | "pin-project-lite", 341 | "sha1", 342 | "sha2", 343 | "tracing", 344 | ] 345 | 346 | [[package]] 347 | name = "aws-smithy-eventstream" 348 | version = "0.60.8" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "7c45d3dddac16c5c59d553ece225a88870cf81b7b813c9cc17b78cf4685eac7a" 351 | dependencies = [ 352 | "aws-smithy-types", 353 | "bytes", 354 | "crc32fast", 355 | ] 356 | 357 | [[package]] 358 | name = "aws-smithy-http" 359 | version = "0.62.0" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "c5949124d11e538ca21142d1fba61ab0a2a2c1bc3ed323cdb3e4b878bfb83166" 362 | dependencies = [ 363 | "aws-smithy-eventstream", 364 | "aws-smithy-runtime-api", 365 | "aws-smithy-types", 366 | "bytes", 367 | "bytes-utils", 368 | "futures-core", 369 | "http 0.2.12", 370 | "http 1.3.1", 371 | "http-body 0.4.6", 372 | "once_cell", 373 | "percent-encoding", 374 | "pin-project-lite", 375 | "pin-utils", 376 | "tracing", 377 | ] 378 | 379 | [[package]] 380 | name = "aws-smithy-http-client" 381 | version = "1.0.0" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "0497ef5d53065b7cd6a35e9c1654bd1fefeae5c52900d91d1b188b0af0f29324" 384 | dependencies = [ 385 | "aws-smithy-async", 386 | "aws-smithy-runtime-api", 387 | "aws-smithy-types", 388 | "h2 0.4.8", 389 | "http 0.2.12", 390 | "http 1.3.1", 391 | "http-body 0.4.6", 392 | "hyper 0.14.32", 393 | "hyper 1.6.0", 394 | "hyper-rustls 0.24.2", 395 | "hyper-rustls 0.27.5", 396 | "hyper-util", 397 | "pin-project-lite", 398 | "rustls 0.21.12", 399 | "rustls 0.23.25", 400 | "rustls-native-certs 0.8.1", 401 | "rustls-pki-types", 402 | "tokio", 403 | "tower", 404 | "tracing", 405 | ] 406 | 407 | [[package]] 408 | name = "aws-smithy-json" 409 | version = "0.61.3" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "92144e45819cae7dc62af23eac5a038a58aa544432d2102609654376a900bd07" 412 | dependencies = [ 413 | "aws-smithy-types", 414 | ] 415 | 416 | [[package]] 417 | name = "aws-smithy-observability" 418 | version = "0.1.2" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "445d065e76bc1ef54963db400319f1dd3ebb3e0a74af20f7f7630625b0cc7cc0" 421 | dependencies = [ 422 | "aws-smithy-runtime-api", 423 | "once_cell", 424 | ] 425 | 426 | [[package]] 427 | name = "aws-smithy-runtime" 428 | version = "1.8.1" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "0152749e17ce4d1b47c7747bdfec09dac1ccafdcbc741ebf9daa2a373356730f" 431 | dependencies = [ 432 | "aws-smithy-async", 433 | "aws-smithy-http", 434 | "aws-smithy-http-client", 435 | "aws-smithy-observability", 436 | "aws-smithy-runtime-api", 437 | "aws-smithy-types", 438 | "bytes", 439 | "fastrand", 440 | "http 0.2.12", 441 | "http 1.3.1", 442 | "http-body 0.4.6", 443 | "http-body 1.0.1", 444 | "once_cell", 445 | "pin-project-lite", 446 | "pin-utils", 447 | "tokio", 448 | "tracing", 449 | ] 450 | 451 | [[package]] 452 | name = "aws-smithy-runtime-api" 453 | version = "1.7.4" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "3da37cf5d57011cb1753456518ec76e31691f1f474b73934a284eb2a1c76510f" 456 | dependencies = [ 457 | "aws-smithy-async", 458 | "aws-smithy-types", 459 | "bytes", 460 | "http 0.2.12", 461 | "http 1.3.1", 462 | "pin-project-lite", 463 | "tokio", 464 | "tracing", 465 | "zeroize", 466 | ] 467 | 468 | [[package]] 469 | name = "aws-smithy-types" 470 | version = "1.3.0" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "836155caafba616c0ff9b07944324785de2ab016141c3550bd1c07882f8cee8f" 473 | dependencies = [ 474 | "base64-simd", 475 | "bytes", 476 | "bytes-utils", 477 | "futures-core", 478 | "http 0.2.12", 479 | "http 1.3.1", 480 | "http-body 0.4.6", 481 | "http-body 1.0.1", 482 | "http-body-util", 483 | "itoa", 484 | "num-integer", 485 | "pin-project-lite", 486 | "pin-utils", 487 | "ryu", 488 | "serde", 489 | "time", 490 | "tokio", 491 | "tokio-util", 492 | ] 493 | 494 | [[package]] 495 | name = "aws-smithy-xml" 496 | version = "0.60.9" 497 | source = "registry+https://github.com/rust-lang/crates.io-index" 498 | checksum = "ab0b0166827aa700d3dc519f72f8b3a91c35d0b8d042dc5d643a91e6f80648fc" 499 | dependencies = [ 500 | "xmlparser", 501 | ] 502 | 503 | [[package]] 504 | name = "aws-types" 505 | version = "1.3.6" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "3873f8deed8927ce8d04487630dc9ff73193bab64742a61d050e57a68dec4125" 508 | dependencies = [ 509 | "aws-credential-types", 510 | "aws-smithy-async", 511 | "aws-smithy-runtime-api", 512 | "aws-smithy-types", 513 | "rustc_version", 514 | "tracing", 515 | ] 516 | 517 | [[package]] 518 | name = "axum" 519 | version = "0.8.1" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8" 522 | dependencies = [ 523 | "axum-core", 524 | "bytes", 525 | "futures-util", 526 | "http 1.3.1", 527 | "http-body 1.0.1", 528 | "http-body-util", 529 | "itoa", 530 | "matchit", 531 | "memchr", 532 | "mime", 533 | "percent-encoding", 534 | "pin-project-lite", 535 | "rustversion", 536 | "serde", 537 | "sync_wrapper", 538 | "tower", 539 | "tower-layer", 540 | "tower-service", 541 | ] 542 | 543 | [[package]] 544 | name = "axum-core" 545 | version = "0.5.0" 546 | source = "registry+https://github.com/rust-lang/crates.io-index" 547 | checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733" 548 | dependencies = [ 549 | "bytes", 550 | "futures-util", 551 | "http 1.3.1", 552 | "http-body 1.0.1", 553 | "http-body-util", 554 | "mime", 555 | "pin-project-lite", 556 | "rustversion", 557 | "sync_wrapper", 558 | "tower-layer", 559 | "tower-service", 560 | ] 561 | 562 | [[package]] 563 | name = "backtrace" 564 | version = "0.3.74" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 567 | dependencies = [ 568 | "addr2line", 569 | "cfg-if", 570 | "libc", 571 | "miniz_oxide", 572 | "object", 573 | "rustc-demangle", 574 | "windows-targets 0.52.6", 575 | ] 576 | 577 | [[package]] 578 | name = "base16ct" 579 | version = "0.1.1" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" 582 | 583 | [[package]] 584 | name = "base64" 585 | version = "0.21.7" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 588 | 589 | [[package]] 590 | name = "base64" 591 | version = "0.22.1" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 594 | 595 | [[package]] 596 | name = "base64-simd" 597 | version = "0.8.0" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" 600 | dependencies = [ 601 | "outref", 602 | "vsimd", 603 | ] 604 | 605 | [[package]] 606 | name = "base64ct" 607 | version = "1.7.3" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" 610 | 611 | [[package]] 612 | name = "bindgen" 613 | version = "0.69.5" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" 616 | dependencies = [ 617 | "bitflags", 618 | "cexpr", 619 | "clang-sys", 620 | "itertools 0.12.1", 621 | "lazy_static", 622 | "lazycell", 623 | "log", 624 | "prettyplease", 625 | "proc-macro2", 626 | "quote", 627 | "regex", 628 | "rustc-hash", 629 | "shlex", 630 | "syn", 631 | "which 4.4.2", 632 | ] 633 | 634 | [[package]] 635 | name = "bitflags" 636 | version = "2.9.0" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 639 | dependencies = [ 640 | "serde", 641 | ] 642 | 643 | [[package]] 644 | name = "block-buffer" 645 | version = "0.10.4" 646 | source = "registry+https://github.com/rust-lang/crates.io-index" 647 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 648 | dependencies = [ 649 | "generic-array", 650 | ] 651 | 652 | [[package]] 653 | name = "block-padding" 654 | version = "0.3.3" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" 657 | dependencies = [ 658 | "generic-array", 659 | ] 660 | 661 | [[package]] 662 | name = "bumpalo" 663 | version = "3.17.0" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 666 | 667 | [[package]] 668 | name = "bytecount" 669 | version = "0.6.8" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" 672 | 673 | [[package]] 674 | name = "byteorder" 675 | version = "1.5.0" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 678 | 679 | [[package]] 680 | name = "bytes" 681 | version = "1.10.1" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 684 | 685 | [[package]] 686 | name = "bytes-utils" 687 | version = "0.1.4" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" 690 | dependencies = [ 691 | "bytes", 692 | "either", 693 | ] 694 | 695 | [[package]] 696 | name = "cbc" 697 | version = "0.1.2" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" 700 | dependencies = [ 701 | "cipher", 702 | ] 703 | 704 | [[package]] 705 | name = "cc" 706 | version = "1.2.17" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" 709 | dependencies = [ 710 | "jobserver", 711 | "libc", 712 | "shlex", 713 | ] 714 | 715 | [[package]] 716 | name = "cexpr" 717 | version = "0.6.0" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 720 | dependencies = [ 721 | "nom 7.1.3", 722 | ] 723 | 724 | [[package]] 725 | name = "cfg-if" 726 | version = "1.0.0" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 729 | 730 | [[package]] 731 | name = "chrono" 732 | version = "0.4.40" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" 735 | dependencies = [ 736 | "android-tzdata", 737 | "iana-time-zone", 738 | "num-traits", 739 | "serde", 740 | "windows-link", 741 | ] 742 | 743 | [[package]] 744 | name = "chunked_transfer" 745 | version = "1.5.0" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" 748 | 749 | [[package]] 750 | name = "cipher" 751 | version = "0.4.4" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" 754 | dependencies = [ 755 | "crypto-common", 756 | "inout", 757 | ] 758 | 759 | [[package]] 760 | name = "clang-sys" 761 | version = "1.8.1" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 764 | dependencies = [ 765 | "glob", 766 | "libc", 767 | "libloading", 768 | ] 769 | 770 | [[package]] 771 | name = "cmake" 772 | version = "0.1.54" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" 775 | dependencies = [ 776 | "cc", 777 | ] 778 | 779 | [[package]] 780 | name = "colorchoice" 781 | version = "1.0.3" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 784 | 785 | [[package]] 786 | name = "config" 787 | version = "0.15.11" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "595aae20e65c3be792d05818e8c63025294ac3cb7e200f11459063a352a6ef80" 790 | dependencies = [ 791 | "async-trait", 792 | "convert_case 0.6.0", 793 | "json5", 794 | "pathdiff", 795 | "ron", 796 | "rust-ini", 797 | "serde", 798 | "serde_json", 799 | "toml", 800 | "winnow", 801 | "yaml-rust2", 802 | ] 803 | 804 | [[package]] 805 | name = "const-oid" 806 | version = "0.9.6" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" 809 | 810 | [[package]] 811 | name = "const-random" 812 | version = "0.1.18" 813 | source = "registry+https://github.com/rust-lang/crates.io-index" 814 | checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" 815 | dependencies = [ 816 | "const-random-macro", 817 | ] 818 | 819 | [[package]] 820 | name = "const-random-macro" 821 | version = "0.1.16" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" 824 | dependencies = [ 825 | "getrandom 0.2.15", 826 | "once_cell", 827 | "tiny-keccak", 828 | ] 829 | 830 | [[package]] 831 | name = "convert_case" 832 | version = "0.4.0" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 835 | 836 | [[package]] 837 | name = "convert_case" 838 | version = "0.6.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" 841 | dependencies = [ 842 | "unicode-segmentation", 843 | ] 844 | 845 | [[package]] 846 | name = "core-foundation" 847 | version = "0.9.4" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 850 | dependencies = [ 851 | "core-foundation-sys", 852 | "libc", 853 | ] 854 | 855 | [[package]] 856 | name = "core-foundation" 857 | version = "0.10.0" 858 | source = "registry+https://github.com/rust-lang/crates.io-index" 859 | checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" 860 | dependencies = [ 861 | "core-foundation-sys", 862 | "libc", 863 | ] 864 | 865 | [[package]] 866 | name = "core-foundation-sys" 867 | version = "0.8.7" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 870 | 871 | [[package]] 872 | name = "cpufeatures" 873 | version = "0.2.17" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" 876 | dependencies = [ 877 | "libc", 878 | ] 879 | 880 | [[package]] 881 | name = "crc" 882 | version = "3.2.1" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" 885 | dependencies = [ 886 | "crc-catalog", 887 | ] 888 | 889 | [[package]] 890 | name = "crc-catalog" 891 | version = "2.4.0" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" 894 | 895 | [[package]] 896 | name = "crc32c" 897 | version = "0.6.8" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "3a47af21622d091a8f0fb295b88bc886ac74efcc613efc19f5d0b21de5c89e47" 900 | dependencies = [ 901 | "rustc_version", 902 | ] 903 | 904 | [[package]] 905 | name = "crc32fast" 906 | version = "1.4.2" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 909 | dependencies = [ 910 | "cfg-if", 911 | ] 912 | 913 | [[package]] 914 | name = "crc64fast-nvme" 915 | version = "1.2.0" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "4955638f00a809894c947f85a024020a20815b65a5eea633798ea7924edab2b3" 918 | dependencies = [ 919 | "crc", 920 | ] 921 | 922 | [[package]] 923 | name = "crossbeam-deque" 924 | version = "0.8.6" 925 | source = "registry+https://github.com/rust-lang/crates.io-index" 926 | checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" 927 | dependencies = [ 928 | "crossbeam-epoch", 929 | "crossbeam-utils", 930 | ] 931 | 932 | [[package]] 933 | name = "crossbeam-epoch" 934 | version = "0.9.18" 935 | source = "registry+https://github.com/rust-lang/crates.io-index" 936 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 937 | dependencies = [ 938 | "crossbeam-utils", 939 | ] 940 | 941 | [[package]] 942 | name = "crossbeam-utils" 943 | version = "0.8.21" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 946 | 947 | [[package]] 948 | name = "crunchy" 949 | version = "0.2.3" 950 | source = "registry+https://github.com/rust-lang/crates.io-index" 951 | checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" 952 | 953 | [[package]] 954 | name = "crypto-bigint" 955 | version = "0.4.9" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" 958 | dependencies = [ 959 | "generic-array", 960 | "rand_core 0.6.4", 961 | "subtle", 962 | "zeroize", 963 | ] 964 | 965 | [[package]] 966 | name = "crypto-bigint" 967 | version = "0.5.5" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" 970 | dependencies = [ 971 | "rand_core 0.6.4", 972 | "subtle", 973 | ] 974 | 975 | [[package]] 976 | name = "crypto-common" 977 | version = "0.1.6" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 980 | dependencies = [ 981 | "generic-array", 982 | "typenum", 983 | ] 984 | 985 | [[package]] 986 | name = "darling" 987 | version = "0.20.10" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" 990 | dependencies = [ 991 | "darling_core", 992 | "darling_macro", 993 | ] 994 | 995 | [[package]] 996 | name = "darling_core" 997 | version = "0.20.10" 998 | source = "registry+https://github.com/rust-lang/crates.io-index" 999 | checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" 1000 | dependencies = [ 1001 | "fnv", 1002 | "ident_case", 1003 | "proc-macro2", 1004 | "quote", 1005 | "strsim", 1006 | "syn", 1007 | ] 1008 | 1009 | [[package]] 1010 | name = "darling_macro" 1011 | version = "0.20.10" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" 1014 | dependencies = [ 1015 | "darling_core", 1016 | "quote", 1017 | "syn", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "data-encoding" 1022 | version = "2.8.0" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" 1025 | 1026 | [[package]] 1027 | name = "der" 1028 | version = "0.6.1" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" 1031 | dependencies = [ 1032 | "const-oid", 1033 | "zeroize", 1034 | ] 1035 | 1036 | [[package]] 1037 | name = "deranged" 1038 | version = "0.4.1" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" 1041 | dependencies = [ 1042 | "powerfmt", 1043 | ] 1044 | 1045 | [[package]] 1046 | name = "derive_builder" 1047 | version = "0.20.2" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" 1050 | dependencies = [ 1051 | "derive_builder_macro", 1052 | ] 1053 | 1054 | [[package]] 1055 | name = "derive_builder_core" 1056 | version = "0.20.2" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" 1059 | dependencies = [ 1060 | "darling", 1061 | "proc-macro2", 1062 | "quote", 1063 | "syn", 1064 | ] 1065 | 1066 | [[package]] 1067 | name = "derive_builder_macro" 1068 | version = "0.20.2" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" 1071 | dependencies = [ 1072 | "derive_builder_core", 1073 | "syn", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "digest" 1078 | version = "0.10.7" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 1081 | dependencies = [ 1082 | "block-buffer", 1083 | "crypto-common", 1084 | "subtle", 1085 | ] 1086 | 1087 | [[package]] 1088 | name = "displaydoc" 1089 | version = "0.2.5" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 1092 | dependencies = [ 1093 | "proc-macro2", 1094 | "quote", 1095 | "syn", 1096 | ] 1097 | 1098 | [[package]] 1099 | name = "dlv-list" 1100 | version = "0.5.2" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" 1103 | dependencies = [ 1104 | "const-random", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "dunce" 1109 | version = "1.0.5" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" 1112 | 1113 | [[package]] 1114 | name = "ecb" 1115 | version = "0.1.2" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "1a8bfa975b1aec2145850fcaa1c6fe269a16578c44705a532ae3edc92b8881c7" 1118 | dependencies = [ 1119 | "cipher", 1120 | ] 1121 | 1122 | [[package]] 1123 | name = "ecdsa" 1124 | version = "0.14.8" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" 1127 | dependencies = [ 1128 | "der", 1129 | "elliptic-curve", 1130 | "rfc6979", 1131 | "signature", 1132 | ] 1133 | 1134 | [[package]] 1135 | name = "either" 1136 | version = "1.15.0" 1137 | source = "registry+https://github.com/rust-lang/crates.io-index" 1138 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 1139 | 1140 | [[package]] 1141 | name = "elliptic-curve" 1142 | version = "0.12.3" 1143 | source = "registry+https://github.com/rust-lang/crates.io-index" 1144 | checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" 1145 | dependencies = [ 1146 | "base16ct", 1147 | "crypto-bigint 0.4.9", 1148 | "der", 1149 | "digest", 1150 | "ff", 1151 | "generic-array", 1152 | "group", 1153 | "pkcs8", 1154 | "rand_core 0.6.4", 1155 | "sec1", 1156 | "subtle", 1157 | "zeroize", 1158 | ] 1159 | 1160 | [[package]] 1161 | name = "encoding_rs" 1162 | version = "0.8.35" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 1165 | dependencies = [ 1166 | "cfg-if", 1167 | ] 1168 | 1169 | [[package]] 1170 | name = "env_filter" 1171 | version = "0.1.3" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" 1174 | dependencies = [ 1175 | "log", 1176 | "regex", 1177 | ] 1178 | 1179 | [[package]] 1180 | name = "env_home" 1181 | version = "0.1.0" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" 1184 | 1185 | [[package]] 1186 | name = "env_logger" 1187 | version = "0.11.7" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" 1190 | dependencies = [ 1191 | "anstream", 1192 | "anstyle", 1193 | "env_filter", 1194 | "jiff", 1195 | "log", 1196 | ] 1197 | 1198 | [[package]] 1199 | name = "equivalent" 1200 | version = "1.0.2" 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" 1202 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 1203 | 1204 | [[package]] 1205 | name = "erased-serde" 1206 | version = "0.4.6" 1207 | source = "registry+https://github.com/rust-lang/crates.io-index" 1208 | checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" 1209 | dependencies = [ 1210 | "serde", 1211 | "typeid", 1212 | ] 1213 | 1214 | [[package]] 1215 | name = "errno" 1216 | version = "0.3.10" 1217 | source = "registry+https://github.com/rust-lang/crates.io-index" 1218 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 1219 | dependencies = [ 1220 | "libc", 1221 | "windows-sys 0.59.0", 1222 | ] 1223 | 1224 | [[package]] 1225 | name = "fastrand" 1226 | version = "2.3.0" 1227 | source = "registry+https://github.com/rust-lang/crates.io-index" 1228 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 1229 | 1230 | [[package]] 1231 | name = "ff" 1232 | version = "0.12.1" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" 1235 | dependencies = [ 1236 | "rand_core 0.6.4", 1237 | "subtle", 1238 | ] 1239 | 1240 | [[package]] 1241 | name = "filetime" 1242 | version = "0.2.25" 1243 | source = "registry+https://github.com/rust-lang/crates.io-index" 1244 | checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" 1245 | dependencies = [ 1246 | "cfg-if", 1247 | "libc", 1248 | "libredox", 1249 | "windows-sys 0.59.0", 1250 | ] 1251 | 1252 | [[package]] 1253 | name = "fixedbitset" 1254 | version = "0.5.7" 1255 | source = "registry+https://github.com/rust-lang/crates.io-index" 1256 | checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" 1257 | 1258 | [[package]] 1259 | name = "flate2" 1260 | version = "1.1.0" 1261 | source = "registry+https://github.com/rust-lang/crates.io-index" 1262 | checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" 1263 | dependencies = [ 1264 | "crc32fast", 1265 | "miniz_oxide", 1266 | ] 1267 | 1268 | [[package]] 1269 | name = "fnv" 1270 | version = "1.0.7" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 1273 | 1274 | [[package]] 1275 | name = "foldhash" 1276 | version = "0.1.5" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" 1279 | 1280 | [[package]] 1281 | name = "foreign-types" 1282 | version = "0.3.2" 1283 | source = "registry+https://github.com/rust-lang/crates.io-index" 1284 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 1285 | dependencies = [ 1286 | "foreign-types-shared", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "foreign-types-shared" 1291 | version = "0.1.1" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 1294 | 1295 | [[package]] 1296 | name = "form_urlencoded" 1297 | version = "1.2.1" 1298 | source = "registry+https://github.com/rust-lang/crates.io-index" 1299 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 1300 | dependencies = [ 1301 | "percent-encoding", 1302 | ] 1303 | 1304 | [[package]] 1305 | name = "fs_extra" 1306 | version = "1.3.0" 1307 | source = "registry+https://github.com/rust-lang/crates.io-index" 1308 | checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" 1309 | 1310 | [[package]] 1311 | name = "futures-channel" 1312 | version = "0.3.31" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 1315 | dependencies = [ 1316 | "futures-core", 1317 | "futures-sink", 1318 | ] 1319 | 1320 | [[package]] 1321 | name = "futures-core" 1322 | version = "0.3.31" 1323 | source = "registry+https://github.com/rust-lang/crates.io-index" 1324 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 1325 | 1326 | [[package]] 1327 | name = "futures-io" 1328 | version = "0.3.31" 1329 | source = "registry+https://github.com/rust-lang/crates.io-index" 1330 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 1331 | 1332 | [[package]] 1333 | name = "futures-sink" 1334 | version = "0.3.31" 1335 | source = "registry+https://github.com/rust-lang/crates.io-index" 1336 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 1337 | 1338 | [[package]] 1339 | name = "futures-task" 1340 | version = "0.3.31" 1341 | source = "registry+https://github.com/rust-lang/crates.io-index" 1342 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 1343 | 1344 | [[package]] 1345 | name = "futures-util" 1346 | version = "0.3.31" 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" 1348 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 1349 | dependencies = [ 1350 | "futures-core", 1351 | "futures-io", 1352 | "futures-sink", 1353 | "futures-task", 1354 | "memchr", 1355 | "pin-project-lite", 1356 | "pin-utils", 1357 | "slab", 1358 | ] 1359 | 1360 | [[package]] 1361 | name = "generic-array" 1362 | version = "0.14.7" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 1365 | dependencies = [ 1366 | "typenum", 1367 | "version_check", 1368 | ] 1369 | 1370 | [[package]] 1371 | name = "getrandom" 1372 | version = "0.2.15" 1373 | source = "registry+https://github.com/rust-lang/crates.io-index" 1374 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 1375 | dependencies = [ 1376 | "cfg-if", 1377 | "libc", 1378 | "wasi 0.11.0+wasi-snapshot-preview1", 1379 | ] 1380 | 1381 | [[package]] 1382 | name = "getrandom" 1383 | version = "0.3.2" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" 1386 | dependencies = [ 1387 | "cfg-if", 1388 | "libc", 1389 | "r-efi", 1390 | "wasi 0.14.2+wasi-0.2.4", 1391 | ] 1392 | 1393 | [[package]] 1394 | name = "gimli" 1395 | version = "0.31.1" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 1398 | 1399 | [[package]] 1400 | name = "glob" 1401 | version = "0.3.2" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" 1404 | 1405 | [[package]] 1406 | name = "group" 1407 | version = "0.12.1" 1408 | source = "registry+https://github.com/rust-lang/crates.io-index" 1409 | checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" 1410 | dependencies = [ 1411 | "ff", 1412 | "rand_core 0.6.4", 1413 | "subtle", 1414 | ] 1415 | 1416 | [[package]] 1417 | name = "h2" 1418 | version = "0.3.26" 1419 | source = "registry+https://github.com/rust-lang/crates.io-index" 1420 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 1421 | dependencies = [ 1422 | "bytes", 1423 | "fnv", 1424 | "futures-core", 1425 | "futures-sink", 1426 | "futures-util", 1427 | "http 0.2.12", 1428 | "indexmap", 1429 | "slab", 1430 | "tokio", 1431 | "tokio-util", 1432 | "tracing", 1433 | ] 1434 | 1435 | [[package]] 1436 | name = "h2" 1437 | version = "0.4.8" 1438 | source = "registry+https://github.com/rust-lang/crates.io-index" 1439 | checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" 1440 | dependencies = [ 1441 | "atomic-waker", 1442 | "bytes", 1443 | "fnv", 1444 | "futures-core", 1445 | "futures-sink", 1446 | "http 1.3.1", 1447 | "indexmap", 1448 | "slab", 1449 | "tokio", 1450 | "tokio-util", 1451 | "tracing", 1452 | ] 1453 | 1454 | [[package]] 1455 | name = "hashbrown" 1456 | version = "0.14.5" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 1459 | 1460 | [[package]] 1461 | name = "hashbrown" 1462 | version = "0.15.2" 1463 | source = "registry+https://github.com/rust-lang/crates.io-index" 1464 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 1465 | dependencies = [ 1466 | "allocator-api2", 1467 | "equivalent", 1468 | "foldhash", 1469 | ] 1470 | 1471 | [[package]] 1472 | name = "hashlink" 1473 | version = "0.10.0" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" 1476 | dependencies = [ 1477 | "hashbrown 0.15.2", 1478 | ] 1479 | 1480 | [[package]] 1481 | name = "headless_chrome" 1482 | version = "1.0.17" 1483 | source = "registry+https://github.com/rust-lang/crates.io-index" 1484 | checksum = "c268ea01c2902b2acb382c1fae26818113dd661e0dba036a893f0ba40f00cdd8" 1485 | dependencies = [ 1486 | "anyhow", 1487 | "auto_generate_cdp", 1488 | "base64 0.22.1", 1489 | "derive_builder", 1490 | "log", 1491 | "rand", 1492 | "regex", 1493 | "serde", 1494 | "serde_json", 1495 | "tempfile", 1496 | "thiserror", 1497 | "tungstenite", 1498 | "url", 1499 | "which 7.0.2", 1500 | "winreg", 1501 | ] 1502 | 1503 | [[package]] 1504 | name = "heck" 1505 | version = "0.5.0" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 1508 | 1509 | [[package]] 1510 | name = "hex" 1511 | version = "0.4.3" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 1514 | 1515 | [[package]] 1516 | name = "hmac" 1517 | version = "0.12.1" 1518 | source = "registry+https://github.com/rust-lang/crates.io-index" 1519 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 1520 | dependencies = [ 1521 | "digest", 1522 | ] 1523 | 1524 | [[package]] 1525 | name = "home" 1526 | version = "0.5.11" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" 1529 | dependencies = [ 1530 | "windows-sys 0.59.0", 1531 | ] 1532 | 1533 | [[package]] 1534 | name = "http" 1535 | version = "0.2.12" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 1538 | dependencies = [ 1539 | "bytes", 1540 | "fnv", 1541 | "itoa", 1542 | ] 1543 | 1544 | [[package]] 1545 | name = "http" 1546 | version = "1.3.1" 1547 | source = "registry+https://github.com/rust-lang/crates.io-index" 1548 | checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" 1549 | dependencies = [ 1550 | "bytes", 1551 | "fnv", 1552 | "itoa", 1553 | ] 1554 | 1555 | [[package]] 1556 | name = "http-body" 1557 | version = "0.4.6" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 1560 | dependencies = [ 1561 | "bytes", 1562 | "http 0.2.12", 1563 | "pin-project-lite", 1564 | ] 1565 | 1566 | [[package]] 1567 | name = "http-body" 1568 | version = "1.0.1" 1569 | source = "registry+https://github.com/rust-lang/crates.io-index" 1570 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 1571 | dependencies = [ 1572 | "bytes", 1573 | "http 1.3.1", 1574 | ] 1575 | 1576 | [[package]] 1577 | name = "http-body-util" 1578 | version = "0.1.3" 1579 | source = "registry+https://github.com/rust-lang/crates.io-index" 1580 | checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" 1581 | dependencies = [ 1582 | "bytes", 1583 | "futures-core", 1584 | "http 1.3.1", 1585 | "http-body 1.0.1", 1586 | "pin-project-lite", 1587 | ] 1588 | 1589 | [[package]] 1590 | name = "httparse" 1591 | version = "1.10.1" 1592 | source = "registry+https://github.com/rust-lang/crates.io-index" 1593 | checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 1594 | 1595 | [[package]] 1596 | name = "httpdate" 1597 | version = "1.0.3" 1598 | source = "registry+https://github.com/rust-lang/crates.io-index" 1599 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 1600 | 1601 | [[package]] 1602 | name = "hyper" 1603 | version = "0.14.32" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" 1606 | dependencies = [ 1607 | "bytes", 1608 | "futures-channel", 1609 | "futures-core", 1610 | "futures-util", 1611 | "h2 0.3.26", 1612 | "http 0.2.12", 1613 | "http-body 0.4.6", 1614 | "httparse", 1615 | "httpdate", 1616 | "itoa", 1617 | "pin-project-lite", 1618 | "socket2", 1619 | "tokio", 1620 | "tower-service", 1621 | "tracing", 1622 | "want", 1623 | ] 1624 | 1625 | [[package]] 1626 | name = "hyper" 1627 | version = "1.6.0" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 1630 | dependencies = [ 1631 | "bytes", 1632 | "futures-channel", 1633 | "futures-util", 1634 | "h2 0.4.8", 1635 | "http 1.3.1", 1636 | "http-body 1.0.1", 1637 | "httparse", 1638 | "httpdate", 1639 | "itoa", 1640 | "pin-project-lite", 1641 | "smallvec", 1642 | "tokio", 1643 | "want", 1644 | ] 1645 | 1646 | [[package]] 1647 | name = "hyper-rustls" 1648 | version = "0.24.2" 1649 | source = "registry+https://github.com/rust-lang/crates.io-index" 1650 | checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" 1651 | dependencies = [ 1652 | "futures-util", 1653 | "http 0.2.12", 1654 | "hyper 0.14.32", 1655 | "log", 1656 | "rustls 0.21.12", 1657 | "rustls-native-certs 0.6.3", 1658 | "tokio", 1659 | "tokio-rustls 0.24.1", 1660 | ] 1661 | 1662 | [[package]] 1663 | name = "hyper-rustls" 1664 | version = "0.27.5" 1665 | source = "registry+https://github.com/rust-lang/crates.io-index" 1666 | checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" 1667 | dependencies = [ 1668 | "futures-util", 1669 | "http 1.3.1", 1670 | "hyper 1.6.0", 1671 | "hyper-util", 1672 | "rustls 0.23.25", 1673 | "rustls-native-certs 0.8.1", 1674 | "rustls-pki-types", 1675 | "tokio", 1676 | "tokio-rustls 0.26.2", 1677 | "tower-service", 1678 | ] 1679 | 1680 | [[package]] 1681 | name = "hyper-timeout" 1682 | version = "0.5.2" 1683 | source = "registry+https://github.com/rust-lang/crates.io-index" 1684 | checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" 1685 | dependencies = [ 1686 | "hyper 1.6.0", 1687 | "hyper-util", 1688 | "pin-project-lite", 1689 | "tokio", 1690 | "tower-service", 1691 | ] 1692 | 1693 | [[package]] 1694 | name = "hyper-tls" 1695 | version = "0.6.0" 1696 | source = "registry+https://github.com/rust-lang/crates.io-index" 1697 | checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 1698 | dependencies = [ 1699 | "bytes", 1700 | "http-body-util", 1701 | "hyper 1.6.0", 1702 | "hyper-util", 1703 | "native-tls", 1704 | "tokio", 1705 | "tokio-native-tls", 1706 | "tower-service", 1707 | ] 1708 | 1709 | [[package]] 1710 | name = "hyper-util" 1711 | version = "0.1.10" 1712 | source = "registry+https://github.com/rust-lang/crates.io-index" 1713 | checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" 1714 | dependencies = [ 1715 | "bytes", 1716 | "futures-channel", 1717 | "futures-util", 1718 | "http 1.3.1", 1719 | "http-body 1.0.1", 1720 | "hyper 1.6.0", 1721 | "pin-project-lite", 1722 | "socket2", 1723 | "tokio", 1724 | "tower-service", 1725 | "tracing", 1726 | ] 1727 | 1728 | [[package]] 1729 | name = "iana-time-zone" 1730 | version = "0.1.62" 1731 | source = "registry+https://github.com/rust-lang/crates.io-index" 1732 | checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127" 1733 | dependencies = [ 1734 | "android_system_properties", 1735 | "core-foundation-sys", 1736 | "iana-time-zone-haiku", 1737 | "js-sys", 1738 | "log", 1739 | "wasm-bindgen", 1740 | "windows-core", 1741 | ] 1742 | 1743 | [[package]] 1744 | name = "iana-time-zone-haiku" 1745 | version = "0.1.2" 1746 | source = "registry+https://github.com/rust-lang/crates.io-index" 1747 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 1748 | dependencies = [ 1749 | "cc", 1750 | ] 1751 | 1752 | [[package]] 1753 | name = "icu_collections" 1754 | version = "1.5.0" 1755 | source = "registry+https://github.com/rust-lang/crates.io-index" 1756 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 1757 | dependencies = [ 1758 | "displaydoc", 1759 | "yoke", 1760 | "zerofrom", 1761 | "zerovec", 1762 | ] 1763 | 1764 | [[package]] 1765 | name = "icu_locid" 1766 | version = "1.5.0" 1767 | source = "registry+https://github.com/rust-lang/crates.io-index" 1768 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 1769 | dependencies = [ 1770 | "displaydoc", 1771 | "litemap", 1772 | "tinystr", 1773 | "writeable", 1774 | "zerovec", 1775 | ] 1776 | 1777 | [[package]] 1778 | name = "icu_locid_transform" 1779 | version = "1.5.0" 1780 | source = "registry+https://github.com/rust-lang/crates.io-index" 1781 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 1782 | dependencies = [ 1783 | "displaydoc", 1784 | "icu_locid", 1785 | "icu_locid_transform_data", 1786 | "icu_provider", 1787 | "tinystr", 1788 | "zerovec", 1789 | ] 1790 | 1791 | [[package]] 1792 | name = "icu_locid_transform_data" 1793 | version = "1.5.0" 1794 | source = "registry+https://github.com/rust-lang/crates.io-index" 1795 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 1796 | 1797 | [[package]] 1798 | name = "icu_normalizer" 1799 | version = "1.5.0" 1800 | source = "registry+https://github.com/rust-lang/crates.io-index" 1801 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 1802 | dependencies = [ 1803 | "displaydoc", 1804 | "icu_collections", 1805 | "icu_normalizer_data", 1806 | "icu_properties", 1807 | "icu_provider", 1808 | "smallvec", 1809 | "utf16_iter", 1810 | "utf8_iter", 1811 | "write16", 1812 | "zerovec", 1813 | ] 1814 | 1815 | [[package]] 1816 | name = "icu_normalizer_data" 1817 | version = "1.5.0" 1818 | source = "registry+https://github.com/rust-lang/crates.io-index" 1819 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 1820 | 1821 | [[package]] 1822 | name = "icu_properties" 1823 | version = "1.5.1" 1824 | source = "registry+https://github.com/rust-lang/crates.io-index" 1825 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 1826 | dependencies = [ 1827 | "displaydoc", 1828 | "icu_collections", 1829 | "icu_locid_transform", 1830 | "icu_properties_data", 1831 | "icu_provider", 1832 | "tinystr", 1833 | "zerovec", 1834 | ] 1835 | 1836 | [[package]] 1837 | name = "icu_properties_data" 1838 | version = "1.5.0" 1839 | source = "registry+https://github.com/rust-lang/crates.io-index" 1840 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 1841 | 1842 | [[package]] 1843 | name = "icu_provider" 1844 | version = "1.5.0" 1845 | source = "registry+https://github.com/rust-lang/crates.io-index" 1846 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 1847 | dependencies = [ 1848 | "displaydoc", 1849 | "icu_locid", 1850 | "icu_provider_macros", 1851 | "stable_deref_trait", 1852 | "tinystr", 1853 | "writeable", 1854 | "yoke", 1855 | "zerofrom", 1856 | "zerovec", 1857 | ] 1858 | 1859 | [[package]] 1860 | name = "icu_provider_macros" 1861 | version = "1.5.0" 1862 | source = "registry+https://github.com/rust-lang/crates.io-index" 1863 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 1864 | dependencies = [ 1865 | "proc-macro2", 1866 | "quote", 1867 | "syn", 1868 | ] 1869 | 1870 | [[package]] 1871 | name = "ident_case" 1872 | version = "1.0.1" 1873 | source = "registry+https://github.com/rust-lang/crates.io-index" 1874 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1875 | 1876 | [[package]] 1877 | name = "idna" 1878 | version = "1.0.3" 1879 | source = "registry+https://github.com/rust-lang/crates.io-index" 1880 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 1881 | dependencies = [ 1882 | "idna_adapter", 1883 | "smallvec", 1884 | "utf8_iter", 1885 | ] 1886 | 1887 | [[package]] 1888 | name = "idna_adapter" 1889 | version = "1.2.0" 1890 | source = "registry+https://github.com/rust-lang/crates.io-index" 1891 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 1892 | dependencies = [ 1893 | "icu_normalizer", 1894 | "icu_properties", 1895 | ] 1896 | 1897 | [[package]] 1898 | name = "indexmap" 1899 | version = "2.8.0" 1900 | source = "registry+https://github.com/rust-lang/crates.io-index" 1901 | checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" 1902 | dependencies = [ 1903 | "equivalent", 1904 | "hashbrown 0.15.2", 1905 | ] 1906 | 1907 | [[package]] 1908 | name = "inout" 1909 | version = "0.1.4" 1910 | source = "registry+https://github.com/rust-lang/crates.io-index" 1911 | checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" 1912 | dependencies = [ 1913 | "block-padding", 1914 | "generic-array", 1915 | ] 1916 | 1917 | [[package]] 1918 | name = "inventory" 1919 | version = "0.3.20" 1920 | source = "registry+https://github.com/rust-lang/crates.io-index" 1921 | checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83" 1922 | dependencies = [ 1923 | "rustversion", 1924 | ] 1925 | 1926 | [[package]] 1927 | name = "ipnet" 1928 | version = "2.11.0" 1929 | source = "registry+https://github.com/rust-lang/crates.io-index" 1930 | checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" 1931 | 1932 | [[package]] 1933 | name = "is_terminal_polyfill" 1934 | version = "1.70.1" 1935 | source = "registry+https://github.com/rust-lang/crates.io-index" 1936 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 1937 | 1938 | [[package]] 1939 | name = "itertools" 1940 | version = "0.12.1" 1941 | source = "registry+https://github.com/rust-lang/crates.io-index" 1942 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 1943 | dependencies = [ 1944 | "either", 1945 | ] 1946 | 1947 | [[package]] 1948 | name = "itertools" 1949 | version = "0.14.0" 1950 | source = "registry+https://github.com/rust-lang/crates.io-index" 1951 | checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" 1952 | dependencies = [ 1953 | "either", 1954 | ] 1955 | 1956 | [[package]] 1957 | name = "itoa" 1958 | version = "1.0.15" 1959 | source = "registry+https://github.com/rust-lang/crates.io-index" 1960 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 1961 | 1962 | [[package]] 1963 | name = "jiff" 1964 | version = "0.2.5" 1965 | source = "registry+https://github.com/rust-lang/crates.io-index" 1966 | checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" 1967 | dependencies = [ 1968 | "jiff-static", 1969 | "jiff-tzdb-platform", 1970 | "log", 1971 | "portable-atomic", 1972 | "portable-atomic-util", 1973 | "serde", 1974 | "windows-sys 0.59.0", 1975 | ] 1976 | 1977 | [[package]] 1978 | name = "jiff-static" 1979 | version = "0.2.5" 1980 | source = "registry+https://github.com/rust-lang/crates.io-index" 1981 | checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" 1982 | dependencies = [ 1983 | "proc-macro2", 1984 | "quote", 1985 | "syn", 1986 | ] 1987 | 1988 | [[package]] 1989 | name = "jiff-tzdb" 1990 | version = "0.1.4" 1991 | source = "registry+https://github.com/rust-lang/crates.io-index" 1992 | checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" 1993 | 1994 | [[package]] 1995 | name = "jiff-tzdb-platform" 1996 | version = "0.1.3" 1997 | source = "registry+https://github.com/rust-lang/crates.io-index" 1998 | checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" 1999 | dependencies = [ 2000 | "jiff-tzdb", 2001 | ] 2002 | 2003 | [[package]] 2004 | name = "jobserver" 2005 | version = "0.1.32" 2006 | source = "registry+https://github.com/rust-lang/crates.io-index" 2007 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 2008 | dependencies = [ 2009 | "libc", 2010 | ] 2011 | 2012 | [[package]] 2013 | name = "js-sys" 2014 | version = "0.3.77" 2015 | source = "registry+https://github.com/rust-lang/crates.io-index" 2016 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 2017 | dependencies = [ 2018 | "once_cell", 2019 | "wasm-bindgen", 2020 | ] 2021 | 2022 | [[package]] 2023 | name = "json5" 2024 | version = "0.4.1" 2025 | source = "registry+https://github.com/rust-lang/crates.io-index" 2026 | checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" 2027 | dependencies = [ 2028 | "pest", 2029 | "pest_derive", 2030 | "serde", 2031 | ] 2032 | 2033 | [[package]] 2034 | name = "lazy_static" 2035 | version = "1.5.0" 2036 | source = "registry+https://github.com/rust-lang/crates.io-index" 2037 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 2038 | 2039 | [[package]] 2040 | name = "lazycell" 2041 | version = "1.3.0" 2042 | source = "registry+https://github.com/rust-lang/crates.io-index" 2043 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 2044 | 2045 | [[package]] 2046 | name = "libc" 2047 | version = "0.2.171" 2048 | source = "registry+https://github.com/rust-lang/crates.io-index" 2049 | checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" 2050 | 2051 | [[package]] 2052 | name = "libloading" 2053 | version = "0.8.6" 2054 | source = "registry+https://github.com/rust-lang/crates.io-index" 2055 | checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" 2056 | dependencies = [ 2057 | "cfg-if", 2058 | "windows-targets 0.52.6", 2059 | ] 2060 | 2061 | [[package]] 2062 | name = "libredox" 2063 | version = "0.1.3" 2064 | source = "registry+https://github.com/rust-lang/crates.io-index" 2065 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 2066 | dependencies = [ 2067 | "bitflags", 2068 | "libc", 2069 | "redox_syscall", 2070 | ] 2071 | 2072 | [[package]] 2073 | name = "linux-raw-sys" 2074 | version = "0.4.15" 2075 | source = "registry+https://github.com/rust-lang/crates.io-index" 2076 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 2077 | 2078 | [[package]] 2079 | name = "linux-raw-sys" 2080 | version = "0.9.3" 2081 | source = "registry+https://github.com/rust-lang/crates.io-index" 2082 | checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" 2083 | 2084 | [[package]] 2085 | name = "litemap" 2086 | version = "0.7.5" 2087 | source = "registry+https://github.com/rust-lang/crates.io-index" 2088 | checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" 2089 | 2090 | [[package]] 2091 | name = "lock_api" 2092 | version = "0.4.12" 2093 | source = "registry+https://github.com/rust-lang/crates.io-index" 2094 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 2095 | dependencies = [ 2096 | "autocfg", 2097 | "scopeguard", 2098 | ] 2099 | 2100 | [[package]] 2101 | name = "log" 2102 | version = "0.4.27" 2103 | source = "registry+https://github.com/rust-lang/crates.io-index" 2104 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 2105 | 2106 | [[package]] 2107 | name = "lopdf" 2108 | version = "0.36.0" 2109 | source = "registry+https://github.com/rust-lang/crates.io-index" 2110 | checksum = "59fa2559e99ba0f26a12458aabc754432c805bbb8cba516c427825a997af1fb7" 2111 | dependencies = [ 2112 | "aes", 2113 | "bitflags", 2114 | "cbc", 2115 | "chrono", 2116 | "ecb", 2117 | "encoding_rs", 2118 | "flate2", 2119 | "indexmap", 2120 | "itoa", 2121 | "jiff", 2122 | "log", 2123 | "md-5", 2124 | "nom 8.0.0", 2125 | "nom_locate", 2126 | "rand", 2127 | "rangemap", 2128 | "rayon", 2129 | "sha2", 2130 | "stringprep", 2131 | "thiserror", 2132 | "time", 2133 | "weezl", 2134 | ] 2135 | 2136 | [[package]] 2137 | name = "lru" 2138 | version = "0.12.5" 2139 | source = "registry+https://github.com/rust-lang/crates.io-index" 2140 | checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" 2141 | dependencies = [ 2142 | "hashbrown 0.15.2", 2143 | ] 2144 | 2145 | [[package]] 2146 | name = "matchit" 2147 | version = "0.8.4" 2148 | source = "registry+https://github.com/rust-lang/crates.io-index" 2149 | checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" 2150 | 2151 | [[package]] 2152 | name = "md-5" 2153 | version = "0.10.6" 2154 | source = "registry+https://github.com/rust-lang/crates.io-index" 2155 | checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" 2156 | dependencies = [ 2157 | "cfg-if", 2158 | "digest", 2159 | ] 2160 | 2161 | [[package]] 2162 | name = "memchr" 2163 | version = "2.7.4" 2164 | source = "registry+https://github.com/rust-lang/crates.io-index" 2165 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 2166 | 2167 | [[package]] 2168 | name = "mime" 2169 | version = "0.3.17" 2170 | source = "registry+https://github.com/rust-lang/crates.io-index" 2171 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 2172 | 2173 | [[package]] 2174 | name = "minimal-lexical" 2175 | version = "0.2.1" 2176 | source = "registry+https://github.com/rust-lang/crates.io-index" 2177 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 2178 | 2179 | [[package]] 2180 | name = "miniz_oxide" 2181 | version = "0.8.5" 2182 | source = "registry+https://github.com/rust-lang/crates.io-index" 2183 | checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" 2184 | dependencies = [ 2185 | "adler2", 2186 | ] 2187 | 2188 | [[package]] 2189 | name = "mio" 2190 | version = "1.0.3" 2191 | source = "registry+https://github.com/rust-lang/crates.io-index" 2192 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 2193 | dependencies = [ 2194 | "libc", 2195 | "wasi 0.11.0+wasi-snapshot-preview1", 2196 | "windows-sys 0.52.0", 2197 | ] 2198 | 2199 | [[package]] 2200 | name = "multimap" 2201 | version = "0.10.0" 2202 | source = "registry+https://github.com/rust-lang/crates.io-index" 2203 | checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" 2204 | 2205 | [[package]] 2206 | name = "native-tls" 2207 | version = "0.2.14" 2208 | source = "registry+https://github.com/rust-lang/crates.io-index" 2209 | checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" 2210 | dependencies = [ 2211 | "libc", 2212 | "log", 2213 | "openssl", 2214 | "openssl-probe", 2215 | "openssl-sys", 2216 | "schannel", 2217 | "security-framework 2.11.1", 2218 | "security-framework-sys", 2219 | "tempfile", 2220 | ] 2221 | 2222 | [[package]] 2223 | name = "nom" 2224 | version = "7.1.3" 2225 | source = "registry+https://github.com/rust-lang/crates.io-index" 2226 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 2227 | dependencies = [ 2228 | "memchr", 2229 | "minimal-lexical", 2230 | ] 2231 | 2232 | [[package]] 2233 | name = "nom" 2234 | version = "8.0.0" 2235 | source = "registry+https://github.com/rust-lang/crates.io-index" 2236 | checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" 2237 | dependencies = [ 2238 | "memchr", 2239 | ] 2240 | 2241 | [[package]] 2242 | name = "nom_locate" 2243 | version = "5.0.0" 2244 | source = "registry+https://github.com/rust-lang/crates.io-index" 2245 | checksum = "0b577e2d69827c4740cba2b52efaad1c4cc7c73042860b199710b3575c68438d" 2246 | dependencies = [ 2247 | "bytecount", 2248 | "memchr", 2249 | "nom 8.0.0", 2250 | ] 2251 | 2252 | [[package]] 2253 | name = "num-conv" 2254 | version = "0.1.0" 2255 | source = "registry+https://github.com/rust-lang/crates.io-index" 2256 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 2257 | 2258 | [[package]] 2259 | name = "num-integer" 2260 | version = "0.1.46" 2261 | source = "registry+https://github.com/rust-lang/crates.io-index" 2262 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 2263 | dependencies = [ 2264 | "num-traits", 2265 | ] 2266 | 2267 | [[package]] 2268 | name = "num-traits" 2269 | version = "0.2.19" 2270 | source = "registry+https://github.com/rust-lang/crates.io-index" 2271 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 2272 | dependencies = [ 2273 | "autocfg", 2274 | ] 2275 | 2276 | [[package]] 2277 | name = "object" 2278 | version = "0.36.7" 2279 | source = "registry+https://github.com/rust-lang/crates.io-index" 2280 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 2281 | dependencies = [ 2282 | "memchr", 2283 | ] 2284 | 2285 | [[package]] 2286 | name = "once_cell" 2287 | version = "1.21.1" 2288 | source = "registry+https://github.com/rust-lang/crates.io-index" 2289 | checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" 2290 | 2291 | [[package]] 2292 | name = "openssl" 2293 | version = "0.10.71" 2294 | source = "registry+https://github.com/rust-lang/crates.io-index" 2295 | checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" 2296 | dependencies = [ 2297 | "bitflags", 2298 | "cfg-if", 2299 | "foreign-types", 2300 | "libc", 2301 | "once_cell", 2302 | "openssl-macros", 2303 | "openssl-sys", 2304 | ] 2305 | 2306 | [[package]] 2307 | name = "openssl-macros" 2308 | version = "0.1.1" 2309 | source = "registry+https://github.com/rust-lang/crates.io-index" 2310 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 2311 | dependencies = [ 2312 | "proc-macro2", 2313 | "quote", 2314 | "syn", 2315 | ] 2316 | 2317 | [[package]] 2318 | name = "openssl-probe" 2319 | version = "0.1.6" 2320 | source = "registry+https://github.com/rust-lang/crates.io-index" 2321 | checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" 2322 | 2323 | [[package]] 2324 | name = "openssl-sys" 2325 | version = "0.9.106" 2326 | source = "registry+https://github.com/rust-lang/crates.io-index" 2327 | checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" 2328 | dependencies = [ 2329 | "cc", 2330 | "libc", 2331 | "pkg-config", 2332 | "vcpkg", 2333 | ] 2334 | 2335 | [[package]] 2336 | name = "ordered-multimap" 2337 | version = "0.7.3" 2338 | source = "registry+https://github.com/rust-lang/crates.io-index" 2339 | checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" 2340 | dependencies = [ 2341 | "dlv-list", 2342 | "hashbrown 0.14.5", 2343 | ] 2344 | 2345 | [[package]] 2346 | name = "outref" 2347 | version = "0.5.2" 2348 | source = "registry+https://github.com/rust-lang/crates.io-index" 2349 | checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" 2350 | 2351 | [[package]] 2352 | name = "p256" 2353 | version = "0.11.1" 2354 | source = "registry+https://github.com/rust-lang/crates.io-index" 2355 | checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" 2356 | dependencies = [ 2357 | "ecdsa", 2358 | "elliptic-curve", 2359 | "sha2", 2360 | ] 2361 | 2362 | [[package]] 2363 | name = "parking_lot" 2364 | version = "0.12.3" 2365 | source = "registry+https://github.com/rust-lang/crates.io-index" 2366 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 2367 | dependencies = [ 2368 | "lock_api", 2369 | "parking_lot_core", 2370 | ] 2371 | 2372 | [[package]] 2373 | name = "parking_lot_core" 2374 | version = "0.9.10" 2375 | source = "registry+https://github.com/rust-lang/crates.io-index" 2376 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 2377 | dependencies = [ 2378 | "cfg-if", 2379 | "libc", 2380 | "redox_syscall", 2381 | "smallvec", 2382 | "windows-targets 0.52.6", 2383 | ] 2384 | 2385 | [[package]] 2386 | name = "pathdiff" 2387 | version = "0.2.3" 2388 | source = "registry+https://github.com/rust-lang/crates.io-index" 2389 | checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" 2390 | 2391 | [[package]] 2392 | name = "pdf-rendering-srv" 2393 | version = "0.1.3" 2394 | dependencies = [ 2395 | "anyhow", 2396 | "aws-sdk-config", 2397 | "aws-sdk-s3", 2398 | "aws-smithy-runtime-api", 2399 | "config", 2400 | "env_logger", 2401 | "flate2", 2402 | "headless_chrome", 2403 | "log", 2404 | "lopdf", 2405 | "prost", 2406 | "prost-types", 2407 | "prost-wkt-types", 2408 | "reqwest", 2409 | "serde", 2410 | "serde_json", 2411 | "tar", 2412 | "tiny_http", 2413 | "tokio", 2414 | "tokio-stream", 2415 | "tonic", 2416 | "tonic-build", 2417 | "tonic-health", 2418 | "tonic-reflection", 2419 | "ulid", 2420 | ] 2421 | 2422 | [[package]] 2423 | name = "percent-encoding" 2424 | version = "2.3.1" 2425 | source = "registry+https://github.com/rust-lang/crates.io-index" 2426 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 2427 | 2428 | [[package]] 2429 | name = "pest" 2430 | version = "2.8.0" 2431 | source = "registry+https://github.com/rust-lang/crates.io-index" 2432 | checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" 2433 | dependencies = [ 2434 | "memchr", 2435 | "thiserror", 2436 | "ucd-trie", 2437 | ] 2438 | 2439 | [[package]] 2440 | name = "pest_derive" 2441 | version = "2.8.0" 2442 | source = "registry+https://github.com/rust-lang/crates.io-index" 2443 | checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5" 2444 | dependencies = [ 2445 | "pest", 2446 | "pest_generator", 2447 | ] 2448 | 2449 | [[package]] 2450 | name = "pest_generator" 2451 | version = "2.8.0" 2452 | source = "registry+https://github.com/rust-lang/crates.io-index" 2453 | checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841" 2454 | dependencies = [ 2455 | "pest", 2456 | "pest_meta", 2457 | "proc-macro2", 2458 | "quote", 2459 | "syn", 2460 | ] 2461 | 2462 | [[package]] 2463 | name = "pest_meta" 2464 | version = "2.8.0" 2465 | source = "registry+https://github.com/rust-lang/crates.io-index" 2466 | checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0" 2467 | dependencies = [ 2468 | "once_cell", 2469 | "pest", 2470 | "sha2", 2471 | ] 2472 | 2473 | [[package]] 2474 | name = "petgraph" 2475 | version = "0.7.1" 2476 | source = "registry+https://github.com/rust-lang/crates.io-index" 2477 | checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" 2478 | dependencies = [ 2479 | "fixedbitset", 2480 | "indexmap", 2481 | ] 2482 | 2483 | [[package]] 2484 | name = "pin-project" 2485 | version = "1.1.10" 2486 | source = "registry+https://github.com/rust-lang/crates.io-index" 2487 | checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" 2488 | dependencies = [ 2489 | "pin-project-internal", 2490 | ] 2491 | 2492 | [[package]] 2493 | name = "pin-project-internal" 2494 | version = "1.1.10" 2495 | source = "registry+https://github.com/rust-lang/crates.io-index" 2496 | checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" 2497 | dependencies = [ 2498 | "proc-macro2", 2499 | "quote", 2500 | "syn", 2501 | ] 2502 | 2503 | [[package]] 2504 | name = "pin-project-lite" 2505 | version = "0.2.16" 2506 | source = "registry+https://github.com/rust-lang/crates.io-index" 2507 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 2508 | 2509 | [[package]] 2510 | name = "pin-utils" 2511 | version = "0.1.0" 2512 | source = "registry+https://github.com/rust-lang/crates.io-index" 2513 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 2514 | 2515 | [[package]] 2516 | name = "pkcs8" 2517 | version = "0.9.0" 2518 | source = "registry+https://github.com/rust-lang/crates.io-index" 2519 | checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" 2520 | dependencies = [ 2521 | "der", 2522 | "spki", 2523 | ] 2524 | 2525 | [[package]] 2526 | name = "pkg-config" 2527 | version = "0.3.32" 2528 | source = "registry+https://github.com/rust-lang/crates.io-index" 2529 | checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 2530 | 2531 | [[package]] 2532 | name = "portable-atomic" 2533 | version = "1.11.0" 2534 | source = "registry+https://github.com/rust-lang/crates.io-index" 2535 | checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" 2536 | 2537 | [[package]] 2538 | name = "portable-atomic-util" 2539 | version = "0.2.4" 2540 | source = "registry+https://github.com/rust-lang/crates.io-index" 2541 | checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" 2542 | dependencies = [ 2543 | "portable-atomic", 2544 | ] 2545 | 2546 | [[package]] 2547 | name = "powerfmt" 2548 | version = "0.2.0" 2549 | source = "registry+https://github.com/rust-lang/crates.io-index" 2550 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 2551 | 2552 | [[package]] 2553 | name = "ppv-lite86" 2554 | version = "0.2.21" 2555 | source = "registry+https://github.com/rust-lang/crates.io-index" 2556 | checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" 2557 | dependencies = [ 2558 | "zerocopy", 2559 | ] 2560 | 2561 | [[package]] 2562 | name = "prettyplease" 2563 | version = "0.2.31" 2564 | source = "registry+https://github.com/rust-lang/crates.io-index" 2565 | checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" 2566 | dependencies = [ 2567 | "proc-macro2", 2568 | "syn", 2569 | ] 2570 | 2571 | [[package]] 2572 | name = "proc-macro2" 2573 | version = "1.0.94" 2574 | source = "registry+https://github.com/rust-lang/crates.io-index" 2575 | checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" 2576 | dependencies = [ 2577 | "unicode-ident", 2578 | ] 2579 | 2580 | [[package]] 2581 | name = "prost" 2582 | version = "0.13.5" 2583 | source = "registry+https://github.com/rust-lang/crates.io-index" 2584 | checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" 2585 | dependencies = [ 2586 | "bytes", 2587 | "prost-derive", 2588 | ] 2589 | 2590 | [[package]] 2591 | name = "prost-build" 2592 | version = "0.13.5" 2593 | source = "registry+https://github.com/rust-lang/crates.io-index" 2594 | checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" 2595 | dependencies = [ 2596 | "heck", 2597 | "itertools 0.14.0", 2598 | "log", 2599 | "multimap", 2600 | "once_cell", 2601 | "petgraph", 2602 | "prettyplease", 2603 | "prost", 2604 | "prost-types", 2605 | "regex", 2606 | "syn", 2607 | "tempfile", 2608 | ] 2609 | 2610 | [[package]] 2611 | name = "prost-derive" 2612 | version = "0.13.5" 2613 | source = "registry+https://github.com/rust-lang/crates.io-index" 2614 | checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" 2615 | dependencies = [ 2616 | "anyhow", 2617 | "itertools 0.14.0", 2618 | "proc-macro2", 2619 | "quote", 2620 | "syn", 2621 | ] 2622 | 2623 | [[package]] 2624 | name = "prost-types" 2625 | version = "0.13.5" 2626 | source = "registry+https://github.com/rust-lang/crates.io-index" 2627 | checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" 2628 | dependencies = [ 2629 | "prost", 2630 | ] 2631 | 2632 | [[package]] 2633 | name = "prost-wkt" 2634 | version = "0.6.0" 2635 | source = "registry+https://github.com/rust-lang/crates.io-index" 2636 | checksum = "a8d84e2bee181b04c2bac339f2bfe818c46a99750488cc6728ce4181d5aa8299" 2637 | dependencies = [ 2638 | "chrono", 2639 | "inventory", 2640 | "prost", 2641 | "serde", 2642 | "serde_derive", 2643 | "serde_json", 2644 | "typetag", 2645 | ] 2646 | 2647 | [[package]] 2648 | name = "prost-wkt-build" 2649 | version = "0.6.0" 2650 | source = "registry+https://github.com/rust-lang/crates.io-index" 2651 | checksum = "8a669d5acbe719010c6f62a64e6d7d88fdedc1fe46e419747949ecb6312e9b14" 2652 | dependencies = [ 2653 | "heck", 2654 | "prost", 2655 | "prost-build", 2656 | "prost-types", 2657 | "quote", 2658 | ] 2659 | 2660 | [[package]] 2661 | name = "prost-wkt-types" 2662 | version = "0.6.0" 2663 | source = "registry+https://github.com/rust-lang/crates.io-index" 2664 | checksum = "01ef068e9b82e654614b22e6b13699bd545b6c0e2e721736008b00b38aeb4f64" 2665 | dependencies = [ 2666 | "chrono", 2667 | "prost", 2668 | "prost-build", 2669 | "prost-types", 2670 | "prost-wkt", 2671 | "prost-wkt-build", 2672 | "regex", 2673 | "serde", 2674 | "serde_derive", 2675 | "serde_json", 2676 | ] 2677 | 2678 | [[package]] 2679 | name = "quote" 2680 | version = "1.0.40" 2681 | source = "registry+https://github.com/rust-lang/crates.io-index" 2682 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 2683 | dependencies = [ 2684 | "proc-macro2", 2685 | ] 2686 | 2687 | [[package]] 2688 | name = "r-efi" 2689 | version = "5.2.0" 2690 | source = "registry+https://github.com/rust-lang/crates.io-index" 2691 | checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" 2692 | 2693 | [[package]] 2694 | name = "rand" 2695 | version = "0.9.0" 2696 | source = "registry+https://github.com/rust-lang/crates.io-index" 2697 | checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" 2698 | dependencies = [ 2699 | "rand_chacha", 2700 | "rand_core 0.9.3", 2701 | "zerocopy", 2702 | ] 2703 | 2704 | [[package]] 2705 | name = "rand_chacha" 2706 | version = "0.9.0" 2707 | source = "registry+https://github.com/rust-lang/crates.io-index" 2708 | checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" 2709 | dependencies = [ 2710 | "ppv-lite86", 2711 | "rand_core 0.9.3", 2712 | ] 2713 | 2714 | [[package]] 2715 | name = "rand_core" 2716 | version = "0.6.4" 2717 | source = "registry+https://github.com/rust-lang/crates.io-index" 2718 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 2719 | dependencies = [ 2720 | "getrandom 0.2.15", 2721 | ] 2722 | 2723 | [[package]] 2724 | name = "rand_core" 2725 | version = "0.9.3" 2726 | source = "registry+https://github.com/rust-lang/crates.io-index" 2727 | checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" 2728 | dependencies = [ 2729 | "getrandom 0.3.2", 2730 | ] 2731 | 2732 | [[package]] 2733 | name = "rangemap" 2734 | version = "1.5.1" 2735 | source = "registry+https://github.com/rust-lang/crates.io-index" 2736 | checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" 2737 | 2738 | [[package]] 2739 | name = "rayon" 2740 | version = "1.10.0" 2741 | source = "registry+https://github.com/rust-lang/crates.io-index" 2742 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 2743 | dependencies = [ 2744 | "either", 2745 | "rayon-core", 2746 | ] 2747 | 2748 | [[package]] 2749 | name = "rayon-core" 2750 | version = "1.12.1" 2751 | source = "registry+https://github.com/rust-lang/crates.io-index" 2752 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 2753 | dependencies = [ 2754 | "crossbeam-deque", 2755 | "crossbeam-utils", 2756 | ] 2757 | 2758 | [[package]] 2759 | name = "redox_syscall" 2760 | version = "0.5.10" 2761 | source = "registry+https://github.com/rust-lang/crates.io-index" 2762 | checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" 2763 | dependencies = [ 2764 | "bitflags", 2765 | ] 2766 | 2767 | [[package]] 2768 | name = "regex" 2769 | version = "1.11.1" 2770 | source = "registry+https://github.com/rust-lang/crates.io-index" 2771 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 2772 | dependencies = [ 2773 | "aho-corasick", 2774 | "memchr", 2775 | "regex-automata", 2776 | "regex-syntax", 2777 | ] 2778 | 2779 | [[package]] 2780 | name = "regex-automata" 2781 | version = "0.4.9" 2782 | source = "registry+https://github.com/rust-lang/crates.io-index" 2783 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 2784 | dependencies = [ 2785 | "aho-corasick", 2786 | "memchr", 2787 | "regex-syntax", 2788 | ] 2789 | 2790 | [[package]] 2791 | name = "regex-lite" 2792 | version = "0.1.6" 2793 | source = "registry+https://github.com/rust-lang/crates.io-index" 2794 | checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" 2795 | 2796 | [[package]] 2797 | name = "regex-syntax" 2798 | version = "0.8.5" 2799 | source = "registry+https://github.com/rust-lang/crates.io-index" 2800 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 2801 | 2802 | [[package]] 2803 | name = "reqwest" 2804 | version = "0.12.15" 2805 | source = "registry+https://github.com/rust-lang/crates.io-index" 2806 | checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" 2807 | dependencies = [ 2808 | "base64 0.22.1", 2809 | "bytes", 2810 | "encoding_rs", 2811 | "futures-channel", 2812 | "futures-core", 2813 | "futures-util", 2814 | "h2 0.4.8", 2815 | "http 1.3.1", 2816 | "http-body 1.0.1", 2817 | "http-body-util", 2818 | "hyper 1.6.0", 2819 | "hyper-rustls 0.27.5", 2820 | "hyper-tls", 2821 | "hyper-util", 2822 | "ipnet", 2823 | "js-sys", 2824 | "log", 2825 | "mime", 2826 | "native-tls", 2827 | "once_cell", 2828 | "percent-encoding", 2829 | "pin-project-lite", 2830 | "rustls-pemfile 2.2.0", 2831 | "serde", 2832 | "serde_json", 2833 | "serde_urlencoded", 2834 | "sync_wrapper", 2835 | "system-configuration", 2836 | "tokio", 2837 | "tokio-native-tls", 2838 | "tower", 2839 | "tower-service", 2840 | "url", 2841 | "wasm-bindgen", 2842 | "wasm-bindgen-futures", 2843 | "web-sys", 2844 | "windows-registry", 2845 | ] 2846 | 2847 | [[package]] 2848 | name = "rfc6979" 2849 | version = "0.3.1" 2850 | source = "registry+https://github.com/rust-lang/crates.io-index" 2851 | checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" 2852 | dependencies = [ 2853 | "crypto-bigint 0.4.9", 2854 | "hmac", 2855 | "zeroize", 2856 | ] 2857 | 2858 | [[package]] 2859 | name = "ring" 2860 | version = "0.17.14" 2861 | source = "registry+https://github.com/rust-lang/crates.io-index" 2862 | checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" 2863 | dependencies = [ 2864 | "cc", 2865 | "cfg-if", 2866 | "getrandom 0.2.15", 2867 | "libc", 2868 | "untrusted", 2869 | "windows-sys 0.52.0", 2870 | ] 2871 | 2872 | [[package]] 2873 | name = "ron" 2874 | version = "0.8.1" 2875 | source = "registry+https://github.com/rust-lang/crates.io-index" 2876 | checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" 2877 | dependencies = [ 2878 | "base64 0.21.7", 2879 | "bitflags", 2880 | "serde", 2881 | "serde_derive", 2882 | ] 2883 | 2884 | [[package]] 2885 | name = "rust-ini" 2886 | version = "0.21.1" 2887 | source = "registry+https://github.com/rust-lang/crates.io-index" 2888 | checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" 2889 | dependencies = [ 2890 | "cfg-if", 2891 | "ordered-multimap", 2892 | "trim-in-place", 2893 | ] 2894 | 2895 | [[package]] 2896 | name = "rustc-demangle" 2897 | version = "0.1.24" 2898 | source = "registry+https://github.com/rust-lang/crates.io-index" 2899 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 2900 | 2901 | [[package]] 2902 | name = "rustc-hash" 2903 | version = "1.1.0" 2904 | source = "registry+https://github.com/rust-lang/crates.io-index" 2905 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 2906 | 2907 | [[package]] 2908 | name = "rustc_version" 2909 | version = "0.4.1" 2910 | source = "registry+https://github.com/rust-lang/crates.io-index" 2911 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 2912 | dependencies = [ 2913 | "semver", 2914 | ] 2915 | 2916 | [[package]] 2917 | name = "rustix" 2918 | version = "0.38.44" 2919 | source = "registry+https://github.com/rust-lang/crates.io-index" 2920 | checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 2921 | dependencies = [ 2922 | "bitflags", 2923 | "errno", 2924 | "libc", 2925 | "linux-raw-sys 0.4.15", 2926 | "windows-sys 0.59.0", 2927 | ] 2928 | 2929 | [[package]] 2930 | name = "rustix" 2931 | version = "1.0.3" 2932 | source = "registry+https://github.com/rust-lang/crates.io-index" 2933 | checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" 2934 | dependencies = [ 2935 | "bitflags", 2936 | "errno", 2937 | "libc", 2938 | "linux-raw-sys 0.9.3", 2939 | "windows-sys 0.59.0", 2940 | ] 2941 | 2942 | [[package]] 2943 | name = "rustls" 2944 | version = "0.21.12" 2945 | source = "registry+https://github.com/rust-lang/crates.io-index" 2946 | checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" 2947 | dependencies = [ 2948 | "log", 2949 | "ring", 2950 | "rustls-webpki 0.101.7", 2951 | "sct", 2952 | ] 2953 | 2954 | [[package]] 2955 | name = "rustls" 2956 | version = "0.23.25" 2957 | source = "registry+https://github.com/rust-lang/crates.io-index" 2958 | checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" 2959 | dependencies = [ 2960 | "aws-lc-rs", 2961 | "log", 2962 | "once_cell", 2963 | "ring", 2964 | "rustls-pki-types", 2965 | "rustls-webpki 0.103.1", 2966 | "subtle", 2967 | "zeroize", 2968 | ] 2969 | 2970 | [[package]] 2971 | name = "rustls-native-certs" 2972 | version = "0.6.3" 2973 | source = "registry+https://github.com/rust-lang/crates.io-index" 2974 | checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" 2975 | dependencies = [ 2976 | "openssl-probe", 2977 | "rustls-pemfile 1.0.4", 2978 | "schannel", 2979 | "security-framework 2.11.1", 2980 | ] 2981 | 2982 | [[package]] 2983 | name = "rustls-native-certs" 2984 | version = "0.8.1" 2985 | source = "registry+https://github.com/rust-lang/crates.io-index" 2986 | checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" 2987 | dependencies = [ 2988 | "openssl-probe", 2989 | "rustls-pki-types", 2990 | "schannel", 2991 | "security-framework 3.2.0", 2992 | ] 2993 | 2994 | [[package]] 2995 | name = "rustls-pemfile" 2996 | version = "1.0.4" 2997 | source = "registry+https://github.com/rust-lang/crates.io-index" 2998 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 2999 | dependencies = [ 3000 | "base64 0.21.7", 3001 | ] 3002 | 3003 | [[package]] 3004 | name = "rustls-pemfile" 3005 | version = "2.2.0" 3006 | source = "registry+https://github.com/rust-lang/crates.io-index" 3007 | checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" 3008 | dependencies = [ 3009 | "rustls-pki-types", 3010 | ] 3011 | 3012 | [[package]] 3013 | name = "rustls-pki-types" 3014 | version = "1.11.0" 3015 | source = "registry+https://github.com/rust-lang/crates.io-index" 3016 | checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" 3017 | 3018 | [[package]] 3019 | name = "rustls-webpki" 3020 | version = "0.101.7" 3021 | source = "registry+https://github.com/rust-lang/crates.io-index" 3022 | checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" 3023 | dependencies = [ 3024 | "ring", 3025 | "untrusted", 3026 | ] 3027 | 3028 | [[package]] 3029 | name = "rustls-webpki" 3030 | version = "0.103.1" 3031 | source = "registry+https://github.com/rust-lang/crates.io-index" 3032 | checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" 3033 | dependencies = [ 3034 | "aws-lc-rs", 3035 | "ring", 3036 | "rustls-pki-types", 3037 | "untrusted", 3038 | ] 3039 | 3040 | [[package]] 3041 | name = "rustversion" 3042 | version = "1.0.20" 3043 | source = "registry+https://github.com/rust-lang/crates.io-index" 3044 | checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" 3045 | 3046 | [[package]] 3047 | name = "ryu" 3048 | version = "1.0.20" 3049 | source = "registry+https://github.com/rust-lang/crates.io-index" 3050 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 3051 | 3052 | [[package]] 3053 | name = "schannel" 3054 | version = "0.1.27" 3055 | source = "registry+https://github.com/rust-lang/crates.io-index" 3056 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 3057 | dependencies = [ 3058 | "windows-sys 0.59.0", 3059 | ] 3060 | 3061 | [[package]] 3062 | name = "scopeguard" 3063 | version = "1.2.0" 3064 | source = "registry+https://github.com/rust-lang/crates.io-index" 3065 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 3066 | 3067 | [[package]] 3068 | name = "sct" 3069 | version = "0.7.1" 3070 | source = "registry+https://github.com/rust-lang/crates.io-index" 3071 | checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" 3072 | dependencies = [ 3073 | "ring", 3074 | "untrusted", 3075 | ] 3076 | 3077 | [[package]] 3078 | name = "sec1" 3079 | version = "0.3.0" 3080 | source = "registry+https://github.com/rust-lang/crates.io-index" 3081 | checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" 3082 | dependencies = [ 3083 | "base16ct", 3084 | "der", 3085 | "generic-array", 3086 | "pkcs8", 3087 | "subtle", 3088 | "zeroize", 3089 | ] 3090 | 3091 | [[package]] 3092 | name = "security-framework" 3093 | version = "2.11.1" 3094 | source = "registry+https://github.com/rust-lang/crates.io-index" 3095 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 3096 | dependencies = [ 3097 | "bitflags", 3098 | "core-foundation 0.9.4", 3099 | "core-foundation-sys", 3100 | "libc", 3101 | "security-framework-sys", 3102 | ] 3103 | 3104 | [[package]] 3105 | name = "security-framework" 3106 | version = "3.2.0" 3107 | source = "registry+https://github.com/rust-lang/crates.io-index" 3108 | checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" 3109 | dependencies = [ 3110 | "bitflags", 3111 | "core-foundation 0.10.0", 3112 | "core-foundation-sys", 3113 | "libc", 3114 | "security-framework-sys", 3115 | ] 3116 | 3117 | [[package]] 3118 | name = "security-framework-sys" 3119 | version = "2.14.0" 3120 | source = "registry+https://github.com/rust-lang/crates.io-index" 3121 | checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" 3122 | dependencies = [ 3123 | "core-foundation-sys", 3124 | "libc", 3125 | ] 3126 | 3127 | [[package]] 3128 | name = "semver" 3129 | version = "1.0.26" 3130 | source = "registry+https://github.com/rust-lang/crates.io-index" 3131 | checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" 3132 | 3133 | [[package]] 3134 | name = "serde" 3135 | version = "1.0.219" 3136 | source = "registry+https://github.com/rust-lang/crates.io-index" 3137 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 3138 | dependencies = [ 3139 | "serde_derive", 3140 | ] 3141 | 3142 | [[package]] 3143 | name = "serde_derive" 3144 | version = "1.0.219" 3145 | source = "registry+https://github.com/rust-lang/crates.io-index" 3146 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 3147 | dependencies = [ 3148 | "proc-macro2", 3149 | "quote", 3150 | "syn", 3151 | ] 3152 | 3153 | [[package]] 3154 | name = "serde_json" 3155 | version = "1.0.140" 3156 | source = "registry+https://github.com/rust-lang/crates.io-index" 3157 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 3158 | dependencies = [ 3159 | "itoa", 3160 | "memchr", 3161 | "ryu", 3162 | "serde", 3163 | ] 3164 | 3165 | [[package]] 3166 | name = "serde_spanned" 3167 | version = "0.6.8" 3168 | source = "registry+https://github.com/rust-lang/crates.io-index" 3169 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 3170 | dependencies = [ 3171 | "serde", 3172 | ] 3173 | 3174 | [[package]] 3175 | name = "serde_urlencoded" 3176 | version = "0.7.1" 3177 | source = "registry+https://github.com/rust-lang/crates.io-index" 3178 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 3179 | dependencies = [ 3180 | "form_urlencoded", 3181 | "itoa", 3182 | "ryu", 3183 | "serde", 3184 | ] 3185 | 3186 | [[package]] 3187 | name = "sha1" 3188 | version = "0.10.6" 3189 | source = "registry+https://github.com/rust-lang/crates.io-index" 3190 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 3191 | dependencies = [ 3192 | "cfg-if", 3193 | "cpufeatures", 3194 | "digest", 3195 | ] 3196 | 3197 | [[package]] 3198 | name = "sha2" 3199 | version = "0.10.8" 3200 | source = "registry+https://github.com/rust-lang/crates.io-index" 3201 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 3202 | dependencies = [ 3203 | "cfg-if", 3204 | "cpufeatures", 3205 | "digest", 3206 | ] 3207 | 3208 | [[package]] 3209 | name = "shlex" 3210 | version = "1.3.0" 3211 | source = "registry+https://github.com/rust-lang/crates.io-index" 3212 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 3213 | 3214 | [[package]] 3215 | name = "signal-hook-registry" 3216 | version = "1.4.2" 3217 | source = "registry+https://github.com/rust-lang/crates.io-index" 3218 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 3219 | dependencies = [ 3220 | "libc", 3221 | ] 3222 | 3223 | [[package]] 3224 | name = "signature" 3225 | version = "1.6.4" 3226 | source = "registry+https://github.com/rust-lang/crates.io-index" 3227 | checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" 3228 | dependencies = [ 3229 | "digest", 3230 | "rand_core 0.6.4", 3231 | ] 3232 | 3233 | [[package]] 3234 | name = "slab" 3235 | version = "0.4.9" 3236 | source = "registry+https://github.com/rust-lang/crates.io-index" 3237 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 3238 | dependencies = [ 3239 | "autocfg", 3240 | ] 3241 | 3242 | [[package]] 3243 | name = "smallvec" 3244 | version = "1.14.0" 3245 | source = "registry+https://github.com/rust-lang/crates.io-index" 3246 | checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" 3247 | 3248 | [[package]] 3249 | name = "socket2" 3250 | version = "0.5.8" 3251 | source = "registry+https://github.com/rust-lang/crates.io-index" 3252 | checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" 3253 | dependencies = [ 3254 | "libc", 3255 | "windows-sys 0.52.0", 3256 | ] 3257 | 3258 | [[package]] 3259 | name = "socks" 3260 | version = "0.3.4" 3261 | source = "registry+https://github.com/rust-lang/crates.io-index" 3262 | checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b" 3263 | dependencies = [ 3264 | "byteorder", 3265 | "libc", 3266 | "winapi", 3267 | ] 3268 | 3269 | [[package]] 3270 | name = "spki" 3271 | version = "0.6.0" 3272 | source = "registry+https://github.com/rust-lang/crates.io-index" 3273 | checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" 3274 | dependencies = [ 3275 | "base64ct", 3276 | "der", 3277 | ] 3278 | 3279 | [[package]] 3280 | name = "stable_deref_trait" 3281 | version = "1.2.0" 3282 | source = "registry+https://github.com/rust-lang/crates.io-index" 3283 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 3284 | 3285 | [[package]] 3286 | name = "stringprep" 3287 | version = "0.1.5" 3288 | source = "registry+https://github.com/rust-lang/crates.io-index" 3289 | checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" 3290 | dependencies = [ 3291 | "unicode-bidi", 3292 | "unicode-normalization", 3293 | "unicode-properties", 3294 | ] 3295 | 3296 | [[package]] 3297 | name = "strsim" 3298 | version = "0.11.1" 3299 | source = "registry+https://github.com/rust-lang/crates.io-index" 3300 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 3301 | 3302 | [[package]] 3303 | name = "subtle" 3304 | version = "2.6.1" 3305 | source = "registry+https://github.com/rust-lang/crates.io-index" 3306 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 3307 | 3308 | [[package]] 3309 | name = "syn" 3310 | version = "2.0.100" 3311 | source = "registry+https://github.com/rust-lang/crates.io-index" 3312 | checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" 3313 | dependencies = [ 3314 | "proc-macro2", 3315 | "quote", 3316 | "unicode-ident", 3317 | ] 3318 | 3319 | [[package]] 3320 | name = "sync_wrapper" 3321 | version = "1.0.2" 3322 | source = "registry+https://github.com/rust-lang/crates.io-index" 3323 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 3324 | dependencies = [ 3325 | "futures-core", 3326 | ] 3327 | 3328 | [[package]] 3329 | name = "synstructure" 3330 | version = "0.13.1" 3331 | source = "registry+https://github.com/rust-lang/crates.io-index" 3332 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 3333 | dependencies = [ 3334 | "proc-macro2", 3335 | "quote", 3336 | "syn", 3337 | ] 3338 | 3339 | [[package]] 3340 | name = "system-configuration" 3341 | version = "0.6.1" 3342 | source = "registry+https://github.com/rust-lang/crates.io-index" 3343 | checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" 3344 | dependencies = [ 3345 | "bitflags", 3346 | "core-foundation 0.9.4", 3347 | "system-configuration-sys", 3348 | ] 3349 | 3350 | [[package]] 3351 | name = "system-configuration-sys" 3352 | version = "0.6.0" 3353 | source = "registry+https://github.com/rust-lang/crates.io-index" 3354 | checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" 3355 | dependencies = [ 3356 | "core-foundation-sys", 3357 | "libc", 3358 | ] 3359 | 3360 | [[package]] 3361 | name = "tar" 3362 | version = "0.4.44" 3363 | source = "registry+https://github.com/rust-lang/crates.io-index" 3364 | checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" 3365 | dependencies = [ 3366 | "filetime", 3367 | "libc", 3368 | "xattr", 3369 | ] 3370 | 3371 | [[package]] 3372 | name = "tempfile" 3373 | version = "3.19.1" 3374 | source = "registry+https://github.com/rust-lang/crates.io-index" 3375 | checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" 3376 | dependencies = [ 3377 | "fastrand", 3378 | "getrandom 0.3.2", 3379 | "once_cell", 3380 | "rustix 1.0.3", 3381 | "windows-sys 0.59.0", 3382 | ] 3383 | 3384 | [[package]] 3385 | name = "thiserror" 3386 | version = "2.0.12" 3387 | source = "registry+https://github.com/rust-lang/crates.io-index" 3388 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 3389 | dependencies = [ 3390 | "thiserror-impl", 3391 | ] 3392 | 3393 | [[package]] 3394 | name = "thiserror-impl" 3395 | version = "2.0.12" 3396 | source = "registry+https://github.com/rust-lang/crates.io-index" 3397 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 3398 | dependencies = [ 3399 | "proc-macro2", 3400 | "quote", 3401 | "syn", 3402 | ] 3403 | 3404 | [[package]] 3405 | name = "time" 3406 | version = "0.3.41" 3407 | source = "registry+https://github.com/rust-lang/crates.io-index" 3408 | checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" 3409 | dependencies = [ 3410 | "deranged", 3411 | "itoa", 3412 | "num-conv", 3413 | "powerfmt", 3414 | "serde", 3415 | "time-core", 3416 | "time-macros", 3417 | ] 3418 | 3419 | [[package]] 3420 | name = "time-core" 3421 | version = "0.1.4" 3422 | source = "registry+https://github.com/rust-lang/crates.io-index" 3423 | checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" 3424 | 3425 | [[package]] 3426 | name = "time-macros" 3427 | version = "0.2.22" 3428 | source = "registry+https://github.com/rust-lang/crates.io-index" 3429 | checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" 3430 | dependencies = [ 3431 | "num-conv", 3432 | "time-core", 3433 | ] 3434 | 3435 | [[package]] 3436 | name = "tiny-keccak" 3437 | version = "2.0.2" 3438 | source = "registry+https://github.com/rust-lang/crates.io-index" 3439 | checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" 3440 | dependencies = [ 3441 | "crunchy", 3442 | ] 3443 | 3444 | [[package]] 3445 | name = "tiny_http" 3446 | version = "0.12.0" 3447 | source = "registry+https://github.com/rust-lang/crates.io-index" 3448 | checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" 3449 | dependencies = [ 3450 | "ascii", 3451 | "chunked_transfer", 3452 | "httpdate", 3453 | "log", 3454 | ] 3455 | 3456 | [[package]] 3457 | name = "tinystr" 3458 | version = "0.7.6" 3459 | source = "registry+https://github.com/rust-lang/crates.io-index" 3460 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 3461 | dependencies = [ 3462 | "displaydoc", 3463 | "zerovec", 3464 | ] 3465 | 3466 | [[package]] 3467 | name = "tinyvec" 3468 | version = "1.9.0" 3469 | source = "registry+https://github.com/rust-lang/crates.io-index" 3470 | checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" 3471 | dependencies = [ 3472 | "tinyvec_macros", 3473 | ] 3474 | 3475 | [[package]] 3476 | name = "tinyvec_macros" 3477 | version = "0.1.1" 3478 | source = "registry+https://github.com/rust-lang/crates.io-index" 3479 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 3480 | 3481 | [[package]] 3482 | name = "tokio" 3483 | version = "1.44.1" 3484 | source = "registry+https://github.com/rust-lang/crates.io-index" 3485 | checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" 3486 | dependencies = [ 3487 | "backtrace", 3488 | "bytes", 3489 | "libc", 3490 | "mio", 3491 | "parking_lot", 3492 | "pin-project-lite", 3493 | "signal-hook-registry", 3494 | "socket2", 3495 | "tokio-macros", 3496 | "windows-sys 0.52.0", 3497 | ] 3498 | 3499 | [[package]] 3500 | name = "tokio-macros" 3501 | version = "2.5.0" 3502 | source = "registry+https://github.com/rust-lang/crates.io-index" 3503 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 3504 | dependencies = [ 3505 | "proc-macro2", 3506 | "quote", 3507 | "syn", 3508 | ] 3509 | 3510 | [[package]] 3511 | name = "tokio-native-tls" 3512 | version = "0.3.1" 3513 | source = "registry+https://github.com/rust-lang/crates.io-index" 3514 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 3515 | dependencies = [ 3516 | "native-tls", 3517 | "tokio", 3518 | ] 3519 | 3520 | [[package]] 3521 | name = "tokio-rustls" 3522 | version = "0.24.1" 3523 | source = "registry+https://github.com/rust-lang/crates.io-index" 3524 | checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" 3525 | dependencies = [ 3526 | "rustls 0.21.12", 3527 | "tokio", 3528 | ] 3529 | 3530 | [[package]] 3531 | name = "tokio-rustls" 3532 | version = "0.26.2" 3533 | source = "registry+https://github.com/rust-lang/crates.io-index" 3534 | checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" 3535 | dependencies = [ 3536 | "rustls 0.23.25", 3537 | "tokio", 3538 | ] 3539 | 3540 | [[package]] 3541 | name = "tokio-stream" 3542 | version = "0.1.17" 3543 | source = "registry+https://github.com/rust-lang/crates.io-index" 3544 | checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" 3545 | dependencies = [ 3546 | "futures-core", 3547 | "pin-project-lite", 3548 | "tokio", 3549 | "tokio-util", 3550 | ] 3551 | 3552 | [[package]] 3553 | name = "tokio-util" 3554 | version = "0.7.14" 3555 | source = "registry+https://github.com/rust-lang/crates.io-index" 3556 | checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" 3557 | dependencies = [ 3558 | "bytes", 3559 | "futures-core", 3560 | "futures-sink", 3561 | "pin-project-lite", 3562 | "tokio", 3563 | ] 3564 | 3565 | [[package]] 3566 | name = "toml" 3567 | version = "0.8.20" 3568 | source = "registry+https://github.com/rust-lang/crates.io-index" 3569 | checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" 3570 | dependencies = [ 3571 | "serde", 3572 | "serde_spanned", 3573 | "toml_datetime", 3574 | "toml_edit", 3575 | ] 3576 | 3577 | [[package]] 3578 | name = "toml_datetime" 3579 | version = "0.6.8" 3580 | source = "registry+https://github.com/rust-lang/crates.io-index" 3581 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 3582 | dependencies = [ 3583 | "serde", 3584 | ] 3585 | 3586 | [[package]] 3587 | name = "toml_edit" 3588 | version = "0.22.24" 3589 | source = "registry+https://github.com/rust-lang/crates.io-index" 3590 | checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" 3591 | dependencies = [ 3592 | "indexmap", 3593 | "serde", 3594 | "serde_spanned", 3595 | "toml_datetime", 3596 | "winnow", 3597 | ] 3598 | 3599 | [[package]] 3600 | name = "tonic" 3601 | version = "0.13.0" 3602 | source = "registry+https://github.com/rust-lang/crates.io-index" 3603 | checksum = "85839f0b32fd242bb3209262371d07feda6d780d16ee9d2bc88581b89da1549b" 3604 | dependencies = [ 3605 | "async-trait", 3606 | "axum", 3607 | "base64 0.22.1", 3608 | "bytes", 3609 | "h2 0.4.8", 3610 | "http 1.3.1", 3611 | "http-body 1.0.1", 3612 | "http-body-util", 3613 | "hyper 1.6.0", 3614 | "hyper-timeout", 3615 | "hyper-util", 3616 | "percent-encoding", 3617 | "pin-project", 3618 | "prost", 3619 | "socket2", 3620 | "tokio", 3621 | "tokio-stream", 3622 | "tower", 3623 | "tower-layer", 3624 | "tower-service", 3625 | "tracing", 3626 | ] 3627 | 3628 | [[package]] 3629 | name = "tonic-build" 3630 | version = "0.13.0" 3631 | source = "registry+https://github.com/rust-lang/crates.io-index" 3632 | checksum = "d85f0383fadd15609306383a90e85eaed44169f931a5d2be1b42c76ceff1825e" 3633 | dependencies = [ 3634 | "prettyplease", 3635 | "proc-macro2", 3636 | "prost-build", 3637 | "prost-types", 3638 | "quote", 3639 | "syn", 3640 | ] 3641 | 3642 | [[package]] 3643 | name = "tonic-health" 3644 | version = "0.13.0" 3645 | source = "registry+https://github.com/rust-lang/crates.io-index" 3646 | checksum = "27b322337dbd837f3dec2c0d29074da49ec80b7ead45ec1c56d6805c43f370f5" 3647 | dependencies = [ 3648 | "prost", 3649 | "tokio", 3650 | "tokio-stream", 3651 | "tonic", 3652 | ] 3653 | 3654 | [[package]] 3655 | name = "tonic-reflection" 3656 | version = "0.13.0" 3657 | source = "registry+https://github.com/rust-lang/crates.io-index" 3658 | checksum = "88fa815be858816dad226a49439ee90b7bcf81ab55bee72fdb217f1e6778c3ca" 3659 | dependencies = [ 3660 | "prost", 3661 | "prost-types", 3662 | "tokio", 3663 | "tokio-stream", 3664 | "tonic", 3665 | ] 3666 | 3667 | [[package]] 3668 | name = "tower" 3669 | version = "0.5.2" 3670 | source = "registry+https://github.com/rust-lang/crates.io-index" 3671 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 3672 | dependencies = [ 3673 | "futures-core", 3674 | "futures-util", 3675 | "indexmap", 3676 | "pin-project-lite", 3677 | "slab", 3678 | "sync_wrapper", 3679 | "tokio", 3680 | "tokio-util", 3681 | "tower-layer", 3682 | "tower-service", 3683 | "tracing", 3684 | ] 3685 | 3686 | [[package]] 3687 | name = "tower-layer" 3688 | version = "0.3.3" 3689 | source = "registry+https://github.com/rust-lang/crates.io-index" 3690 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 3691 | 3692 | [[package]] 3693 | name = "tower-service" 3694 | version = "0.3.3" 3695 | source = "registry+https://github.com/rust-lang/crates.io-index" 3696 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 3697 | 3698 | [[package]] 3699 | name = "tracing" 3700 | version = "0.1.41" 3701 | source = "registry+https://github.com/rust-lang/crates.io-index" 3702 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 3703 | dependencies = [ 3704 | "pin-project-lite", 3705 | "tracing-attributes", 3706 | "tracing-core", 3707 | ] 3708 | 3709 | [[package]] 3710 | name = "tracing-attributes" 3711 | version = "0.1.28" 3712 | source = "registry+https://github.com/rust-lang/crates.io-index" 3713 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 3714 | dependencies = [ 3715 | "proc-macro2", 3716 | "quote", 3717 | "syn", 3718 | ] 3719 | 3720 | [[package]] 3721 | name = "tracing-core" 3722 | version = "0.1.33" 3723 | source = "registry+https://github.com/rust-lang/crates.io-index" 3724 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 3725 | dependencies = [ 3726 | "once_cell", 3727 | ] 3728 | 3729 | [[package]] 3730 | name = "trim-in-place" 3731 | version = "0.1.7" 3732 | source = "registry+https://github.com/rust-lang/crates.io-index" 3733 | checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" 3734 | 3735 | [[package]] 3736 | name = "try-lock" 3737 | version = "0.2.5" 3738 | source = "registry+https://github.com/rust-lang/crates.io-index" 3739 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 3740 | 3741 | [[package]] 3742 | name = "tungstenite" 3743 | version = "0.26.2" 3744 | source = "registry+https://github.com/rust-lang/crates.io-index" 3745 | checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" 3746 | dependencies = [ 3747 | "bytes", 3748 | "data-encoding", 3749 | "http 1.3.1", 3750 | "httparse", 3751 | "log", 3752 | "rand", 3753 | "sha1", 3754 | "thiserror", 3755 | "utf-8", 3756 | ] 3757 | 3758 | [[package]] 3759 | name = "typeid" 3760 | version = "1.0.3" 3761 | source = "registry+https://github.com/rust-lang/crates.io-index" 3762 | checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" 3763 | 3764 | [[package]] 3765 | name = "typenum" 3766 | version = "1.18.0" 3767 | source = "registry+https://github.com/rust-lang/crates.io-index" 3768 | checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" 3769 | 3770 | [[package]] 3771 | name = "typetag" 3772 | version = "0.2.20" 3773 | source = "registry+https://github.com/rust-lang/crates.io-index" 3774 | checksum = "73f22b40dd7bfe8c14230cf9702081366421890435b2d625fa92b4acc4c3de6f" 3775 | dependencies = [ 3776 | "erased-serde", 3777 | "inventory", 3778 | "once_cell", 3779 | "serde", 3780 | "typetag-impl", 3781 | ] 3782 | 3783 | [[package]] 3784 | name = "typetag-impl" 3785 | version = "0.2.20" 3786 | source = "registry+https://github.com/rust-lang/crates.io-index" 3787 | checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952" 3788 | dependencies = [ 3789 | "proc-macro2", 3790 | "quote", 3791 | "syn", 3792 | ] 3793 | 3794 | [[package]] 3795 | name = "ucd-trie" 3796 | version = "0.1.7" 3797 | source = "registry+https://github.com/rust-lang/crates.io-index" 3798 | checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" 3799 | 3800 | [[package]] 3801 | name = "ulid" 3802 | version = "1.2.1" 3803 | source = "registry+https://github.com/rust-lang/crates.io-index" 3804 | checksum = "470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe" 3805 | dependencies = [ 3806 | "rand", 3807 | "web-time", 3808 | ] 3809 | 3810 | [[package]] 3811 | name = "unicode-bidi" 3812 | version = "0.3.18" 3813 | source = "registry+https://github.com/rust-lang/crates.io-index" 3814 | checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" 3815 | 3816 | [[package]] 3817 | name = "unicode-ident" 3818 | version = "1.0.18" 3819 | source = "registry+https://github.com/rust-lang/crates.io-index" 3820 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 3821 | 3822 | [[package]] 3823 | name = "unicode-normalization" 3824 | version = "0.1.24" 3825 | source = "registry+https://github.com/rust-lang/crates.io-index" 3826 | checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" 3827 | dependencies = [ 3828 | "tinyvec", 3829 | ] 3830 | 3831 | [[package]] 3832 | name = "unicode-properties" 3833 | version = "0.1.3" 3834 | source = "registry+https://github.com/rust-lang/crates.io-index" 3835 | checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" 3836 | 3837 | [[package]] 3838 | name = "unicode-segmentation" 3839 | version = "1.12.0" 3840 | source = "registry+https://github.com/rust-lang/crates.io-index" 3841 | checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 3842 | 3843 | [[package]] 3844 | name = "untrusted" 3845 | version = "0.9.0" 3846 | source = "registry+https://github.com/rust-lang/crates.io-index" 3847 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 3848 | 3849 | [[package]] 3850 | name = "ureq" 3851 | version = "2.12.1" 3852 | source = "registry+https://github.com/rust-lang/crates.io-index" 3853 | checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" 3854 | dependencies = [ 3855 | "base64 0.22.1", 3856 | "flate2", 3857 | "log", 3858 | "once_cell", 3859 | "rustls 0.23.25", 3860 | "rustls-pki-types", 3861 | "socks", 3862 | "url", 3863 | "webpki-roots", 3864 | ] 3865 | 3866 | [[package]] 3867 | name = "url" 3868 | version = "2.5.4" 3869 | source = "registry+https://github.com/rust-lang/crates.io-index" 3870 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 3871 | dependencies = [ 3872 | "form_urlencoded", 3873 | "idna", 3874 | "percent-encoding", 3875 | ] 3876 | 3877 | [[package]] 3878 | name = "utf-8" 3879 | version = "0.7.6" 3880 | source = "registry+https://github.com/rust-lang/crates.io-index" 3881 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 3882 | 3883 | [[package]] 3884 | name = "utf16_iter" 3885 | version = "1.0.5" 3886 | source = "registry+https://github.com/rust-lang/crates.io-index" 3887 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 3888 | 3889 | [[package]] 3890 | name = "utf8_iter" 3891 | version = "1.0.4" 3892 | source = "registry+https://github.com/rust-lang/crates.io-index" 3893 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 3894 | 3895 | [[package]] 3896 | name = "utf8parse" 3897 | version = "0.2.2" 3898 | source = "registry+https://github.com/rust-lang/crates.io-index" 3899 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 3900 | 3901 | [[package]] 3902 | name = "uuid" 3903 | version = "1.16.0" 3904 | source = "registry+https://github.com/rust-lang/crates.io-index" 3905 | checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" 3906 | 3907 | [[package]] 3908 | name = "vcpkg" 3909 | version = "0.2.15" 3910 | source = "registry+https://github.com/rust-lang/crates.io-index" 3911 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 3912 | 3913 | [[package]] 3914 | name = "version_check" 3915 | version = "0.9.5" 3916 | source = "registry+https://github.com/rust-lang/crates.io-index" 3917 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 3918 | 3919 | [[package]] 3920 | name = "vsimd" 3921 | version = "0.8.0" 3922 | source = "registry+https://github.com/rust-lang/crates.io-index" 3923 | checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" 3924 | 3925 | [[package]] 3926 | name = "want" 3927 | version = "0.3.1" 3928 | source = "registry+https://github.com/rust-lang/crates.io-index" 3929 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 3930 | dependencies = [ 3931 | "try-lock", 3932 | ] 3933 | 3934 | [[package]] 3935 | name = "wasi" 3936 | version = "0.11.0+wasi-snapshot-preview1" 3937 | source = "registry+https://github.com/rust-lang/crates.io-index" 3938 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 3939 | 3940 | [[package]] 3941 | name = "wasi" 3942 | version = "0.14.2+wasi-0.2.4" 3943 | source = "registry+https://github.com/rust-lang/crates.io-index" 3944 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 3945 | dependencies = [ 3946 | "wit-bindgen-rt", 3947 | ] 3948 | 3949 | [[package]] 3950 | name = "wasm-bindgen" 3951 | version = "0.2.100" 3952 | source = "registry+https://github.com/rust-lang/crates.io-index" 3953 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 3954 | dependencies = [ 3955 | "cfg-if", 3956 | "once_cell", 3957 | "rustversion", 3958 | "wasm-bindgen-macro", 3959 | ] 3960 | 3961 | [[package]] 3962 | name = "wasm-bindgen-backend" 3963 | version = "0.2.100" 3964 | source = "registry+https://github.com/rust-lang/crates.io-index" 3965 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 3966 | dependencies = [ 3967 | "bumpalo", 3968 | "log", 3969 | "proc-macro2", 3970 | "quote", 3971 | "syn", 3972 | "wasm-bindgen-shared", 3973 | ] 3974 | 3975 | [[package]] 3976 | name = "wasm-bindgen-futures" 3977 | version = "0.4.50" 3978 | source = "registry+https://github.com/rust-lang/crates.io-index" 3979 | checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" 3980 | dependencies = [ 3981 | "cfg-if", 3982 | "js-sys", 3983 | "once_cell", 3984 | "wasm-bindgen", 3985 | "web-sys", 3986 | ] 3987 | 3988 | [[package]] 3989 | name = "wasm-bindgen-macro" 3990 | version = "0.2.100" 3991 | source = "registry+https://github.com/rust-lang/crates.io-index" 3992 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 3993 | dependencies = [ 3994 | "quote", 3995 | "wasm-bindgen-macro-support", 3996 | ] 3997 | 3998 | [[package]] 3999 | name = "wasm-bindgen-macro-support" 4000 | version = "0.2.100" 4001 | source = "registry+https://github.com/rust-lang/crates.io-index" 4002 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 4003 | dependencies = [ 4004 | "proc-macro2", 4005 | "quote", 4006 | "syn", 4007 | "wasm-bindgen-backend", 4008 | "wasm-bindgen-shared", 4009 | ] 4010 | 4011 | [[package]] 4012 | name = "wasm-bindgen-shared" 4013 | version = "0.2.100" 4014 | source = "registry+https://github.com/rust-lang/crates.io-index" 4015 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 4016 | dependencies = [ 4017 | "unicode-ident", 4018 | ] 4019 | 4020 | [[package]] 4021 | name = "web-sys" 4022 | version = "0.3.77" 4023 | source = "registry+https://github.com/rust-lang/crates.io-index" 4024 | checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" 4025 | dependencies = [ 4026 | "js-sys", 4027 | "wasm-bindgen", 4028 | ] 4029 | 4030 | [[package]] 4031 | name = "web-time" 4032 | version = "1.1.0" 4033 | source = "registry+https://github.com/rust-lang/crates.io-index" 4034 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 4035 | dependencies = [ 4036 | "js-sys", 4037 | "wasm-bindgen", 4038 | ] 4039 | 4040 | [[package]] 4041 | name = "webpki-roots" 4042 | version = "0.26.8" 4043 | source = "registry+https://github.com/rust-lang/crates.io-index" 4044 | checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" 4045 | dependencies = [ 4046 | "rustls-pki-types", 4047 | ] 4048 | 4049 | [[package]] 4050 | name = "weezl" 4051 | version = "0.1.8" 4052 | source = "registry+https://github.com/rust-lang/crates.io-index" 4053 | checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" 4054 | 4055 | [[package]] 4056 | name = "which" 4057 | version = "4.4.2" 4058 | source = "registry+https://github.com/rust-lang/crates.io-index" 4059 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 4060 | dependencies = [ 4061 | "either", 4062 | "home", 4063 | "once_cell", 4064 | "rustix 0.38.44", 4065 | ] 4066 | 4067 | [[package]] 4068 | name = "which" 4069 | version = "7.0.2" 4070 | source = "registry+https://github.com/rust-lang/crates.io-index" 4071 | checksum = "2774c861e1f072b3aadc02f8ba886c26ad6321567ecc294c935434cad06f1283" 4072 | dependencies = [ 4073 | "either", 4074 | "env_home", 4075 | "rustix 0.38.44", 4076 | "winsafe", 4077 | ] 4078 | 4079 | [[package]] 4080 | name = "winapi" 4081 | version = "0.3.9" 4082 | source = "registry+https://github.com/rust-lang/crates.io-index" 4083 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 4084 | dependencies = [ 4085 | "winapi-i686-pc-windows-gnu", 4086 | "winapi-x86_64-pc-windows-gnu", 4087 | ] 4088 | 4089 | [[package]] 4090 | name = "winapi-i686-pc-windows-gnu" 4091 | version = "0.4.0" 4092 | source = "registry+https://github.com/rust-lang/crates.io-index" 4093 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 4094 | 4095 | [[package]] 4096 | name = "winapi-x86_64-pc-windows-gnu" 4097 | version = "0.4.0" 4098 | source = "registry+https://github.com/rust-lang/crates.io-index" 4099 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 4100 | 4101 | [[package]] 4102 | name = "windows-core" 4103 | version = "0.52.0" 4104 | source = "registry+https://github.com/rust-lang/crates.io-index" 4105 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 4106 | dependencies = [ 4107 | "windows-targets 0.52.6", 4108 | ] 4109 | 4110 | [[package]] 4111 | name = "windows-link" 4112 | version = "0.1.1" 4113 | source = "registry+https://github.com/rust-lang/crates.io-index" 4114 | checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" 4115 | 4116 | [[package]] 4117 | name = "windows-registry" 4118 | version = "0.4.0" 4119 | source = "registry+https://github.com/rust-lang/crates.io-index" 4120 | checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" 4121 | dependencies = [ 4122 | "windows-result", 4123 | "windows-strings", 4124 | "windows-targets 0.53.0", 4125 | ] 4126 | 4127 | [[package]] 4128 | name = "windows-result" 4129 | version = "0.3.2" 4130 | source = "registry+https://github.com/rust-lang/crates.io-index" 4131 | checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" 4132 | dependencies = [ 4133 | "windows-link", 4134 | ] 4135 | 4136 | [[package]] 4137 | name = "windows-strings" 4138 | version = "0.3.1" 4139 | source = "registry+https://github.com/rust-lang/crates.io-index" 4140 | checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" 4141 | dependencies = [ 4142 | "windows-link", 4143 | ] 4144 | 4145 | [[package]] 4146 | name = "windows-sys" 4147 | version = "0.52.0" 4148 | source = "registry+https://github.com/rust-lang/crates.io-index" 4149 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 4150 | dependencies = [ 4151 | "windows-targets 0.52.6", 4152 | ] 4153 | 4154 | [[package]] 4155 | name = "windows-sys" 4156 | version = "0.59.0" 4157 | source = "registry+https://github.com/rust-lang/crates.io-index" 4158 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 4159 | dependencies = [ 4160 | "windows-targets 0.52.6", 4161 | ] 4162 | 4163 | [[package]] 4164 | name = "windows-targets" 4165 | version = "0.52.6" 4166 | source = "registry+https://github.com/rust-lang/crates.io-index" 4167 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 4168 | dependencies = [ 4169 | "windows_aarch64_gnullvm 0.52.6", 4170 | "windows_aarch64_msvc 0.52.6", 4171 | "windows_i686_gnu 0.52.6", 4172 | "windows_i686_gnullvm 0.52.6", 4173 | "windows_i686_msvc 0.52.6", 4174 | "windows_x86_64_gnu 0.52.6", 4175 | "windows_x86_64_gnullvm 0.52.6", 4176 | "windows_x86_64_msvc 0.52.6", 4177 | ] 4178 | 4179 | [[package]] 4180 | name = "windows-targets" 4181 | version = "0.53.0" 4182 | source = "registry+https://github.com/rust-lang/crates.io-index" 4183 | checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" 4184 | dependencies = [ 4185 | "windows_aarch64_gnullvm 0.53.0", 4186 | "windows_aarch64_msvc 0.53.0", 4187 | "windows_i686_gnu 0.53.0", 4188 | "windows_i686_gnullvm 0.53.0", 4189 | "windows_i686_msvc 0.53.0", 4190 | "windows_x86_64_gnu 0.53.0", 4191 | "windows_x86_64_gnullvm 0.53.0", 4192 | "windows_x86_64_msvc 0.53.0", 4193 | ] 4194 | 4195 | [[package]] 4196 | name = "windows_aarch64_gnullvm" 4197 | version = "0.52.6" 4198 | source = "registry+https://github.com/rust-lang/crates.io-index" 4199 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 4200 | 4201 | [[package]] 4202 | name = "windows_aarch64_gnullvm" 4203 | version = "0.53.0" 4204 | source = "registry+https://github.com/rust-lang/crates.io-index" 4205 | checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" 4206 | 4207 | [[package]] 4208 | name = "windows_aarch64_msvc" 4209 | version = "0.52.6" 4210 | source = "registry+https://github.com/rust-lang/crates.io-index" 4211 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 4212 | 4213 | [[package]] 4214 | name = "windows_aarch64_msvc" 4215 | version = "0.53.0" 4216 | source = "registry+https://github.com/rust-lang/crates.io-index" 4217 | checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" 4218 | 4219 | [[package]] 4220 | name = "windows_i686_gnu" 4221 | version = "0.52.6" 4222 | source = "registry+https://github.com/rust-lang/crates.io-index" 4223 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 4224 | 4225 | [[package]] 4226 | name = "windows_i686_gnu" 4227 | version = "0.53.0" 4228 | source = "registry+https://github.com/rust-lang/crates.io-index" 4229 | checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" 4230 | 4231 | [[package]] 4232 | name = "windows_i686_gnullvm" 4233 | version = "0.52.6" 4234 | source = "registry+https://github.com/rust-lang/crates.io-index" 4235 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 4236 | 4237 | [[package]] 4238 | name = "windows_i686_gnullvm" 4239 | version = "0.53.0" 4240 | source = "registry+https://github.com/rust-lang/crates.io-index" 4241 | checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" 4242 | 4243 | [[package]] 4244 | name = "windows_i686_msvc" 4245 | version = "0.52.6" 4246 | source = "registry+https://github.com/rust-lang/crates.io-index" 4247 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 4248 | 4249 | [[package]] 4250 | name = "windows_i686_msvc" 4251 | version = "0.53.0" 4252 | source = "registry+https://github.com/rust-lang/crates.io-index" 4253 | checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" 4254 | 4255 | [[package]] 4256 | name = "windows_x86_64_gnu" 4257 | version = "0.52.6" 4258 | source = "registry+https://github.com/rust-lang/crates.io-index" 4259 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 4260 | 4261 | [[package]] 4262 | name = "windows_x86_64_gnu" 4263 | version = "0.53.0" 4264 | source = "registry+https://github.com/rust-lang/crates.io-index" 4265 | checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" 4266 | 4267 | [[package]] 4268 | name = "windows_x86_64_gnullvm" 4269 | version = "0.52.6" 4270 | source = "registry+https://github.com/rust-lang/crates.io-index" 4271 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 4272 | 4273 | [[package]] 4274 | name = "windows_x86_64_gnullvm" 4275 | version = "0.53.0" 4276 | source = "registry+https://github.com/rust-lang/crates.io-index" 4277 | checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" 4278 | 4279 | [[package]] 4280 | name = "windows_x86_64_msvc" 4281 | version = "0.52.6" 4282 | source = "registry+https://github.com/rust-lang/crates.io-index" 4283 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 4284 | 4285 | [[package]] 4286 | name = "windows_x86_64_msvc" 4287 | version = "0.53.0" 4288 | source = "registry+https://github.com/rust-lang/crates.io-index" 4289 | checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" 4290 | 4291 | [[package]] 4292 | name = "winnow" 4293 | version = "0.7.4" 4294 | source = "registry+https://github.com/rust-lang/crates.io-index" 4295 | checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" 4296 | dependencies = [ 4297 | "memchr", 4298 | ] 4299 | 4300 | [[package]] 4301 | name = "winreg" 4302 | version = "0.55.0" 4303 | source = "registry+https://github.com/rust-lang/crates.io-index" 4304 | checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" 4305 | dependencies = [ 4306 | "cfg-if", 4307 | "windows-sys 0.59.0", 4308 | ] 4309 | 4310 | [[package]] 4311 | name = "winsafe" 4312 | version = "0.0.19" 4313 | source = "registry+https://github.com/rust-lang/crates.io-index" 4314 | checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" 4315 | 4316 | [[package]] 4317 | name = "wit-bindgen-rt" 4318 | version = "0.39.0" 4319 | source = "registry+https://github.com/rust-lang/crates.io-index" 4320 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 4321 | dependencies = [ 4322 | "bitflags", 4323 | ] 4324 | 4325 | [[package]] 4326 | name = "write16" 4327 | version = "1.0.0" 4328 | source = "registry+https://github.com/rust-lang/crates.io-index" 4329 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 4330 | 4331 | [[package]] 4332 | name = "writeable" 4333 | version = "0.5.5" 4334 | source = "registry+https://github.com/rust-lang/crates.io-index" 4335 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 4336 | 4337 | [[package]] 4338 | name = "xattr" 4339 | version = "1.5.0" 4340 | source = "registry+https://github.com/rust-lang/crates.io-index" 4341 | checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" 4342 | dependencies = [ 4343 | "libc", 4344 | "rustix 1.0.3", 4345 | ] 4346 | 4347 | [[package]] 4348 | name = "xmlparser" 4349 | version = "0.13.6" 4350 | source = "registry+https://github.com/rust-lang/crates.io-index" 4351 | checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" 4352 | 4353 | [[package]] 4354 | name = "yaml-rust2" 4355 | version = "0.10.0" 4356 | source = "registry+https://github.com/rust-lang/crates.io-index" 4357 | checksum = "232bdb534d65520716bef0bbb205ff8f2db72d807b19c0bc3020853b92a0cd4b" 4358 | dependencies = [ 4359 | "arraydeque", 4360 | "encoding_rs", 4361 | "hashlink", 4362 | ] 4363 | 4364 | [[package]] 4365 | name = "yoke" 4366 | version = "0.7.5" 4367 | source = "registry+https://github.com/rust-lang/crates.io-index" 4368 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 4369 | dependencies = [ 4370 | "serde", 4371 | "stable_deref_trait", 4372 | "yoke-derive", 4373 | "zerofrom", 4374 | ] 4375 | 4376 | [[package]] 4377 | name = "yoke-derive" 4378 | version = "0.7.5" 4379 | source = "registry+https://github.com/rust-lang/crates.io-index" 4380 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 4381 | dependencies = [ 4382 | "proc-macro2", 4383 | "quote", 4384 | "syn", 4385 | "synstructure", 4386 | ] 4387 | 4388 | [[package]] 4389 | name = "zerocopy" 4390 | version = "0.8.24" 4391 | source = "registry+https://github.com/rust-lang/crates.io-index" 4392 | checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" 4393 | dependencies = [ 4394 | "zerocopy-derive", 4395 | ] 4396 | 4397 | [[package]] 4398 | name = "zerocopy-derive" 4399 | version = "0.8.24" 4400 | source = "registry+https://github.com/rust-lang/crates.io-index" 4401 | checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" 4402 | dependencies = [ 4403 | "proc-macro2", 4404 | "quote", 4405 | "syn", 4406 | ] 4407 | 4408 | [[package]] 4409 | name = "zerofrom" 4410 | version = "0.1.6" 4411 | source = "registry+https://github.com/rust-lang/crates.io-index" 4412 | checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 4413 | dependencies = [ 4414 | "zerofrom-derive", 4415 | ] 4416 | 4417 | [[package]] 4418 | name = "zerofrom-derive" 4419 | version = "0.1.6" 4420 | source = "registry+https://github.com/rust-lang/crates.io-index" 4421 | checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 4422 | dependencies = [ 4423 | "proc-macro2", 4424 | "quote", 4425 | "syn", 4426 | "synstructure", 4427 | ] 4428 | 4429 | [[package]] 4430 | name = "zeroize" 4431 | version = "1.8.1" 4432 | source = "registry+https://github.com/rust-lang/crates.io-index" 4433 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 4434 | 4435 | [[package]] 4436 | name = "zerovec" 4437 | version = "0.10.4" 4438 | source = "registry+https://github.com/rust-lang/crates.io-index" 4439 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 4440 | dependencies = [ 4441 | "yoke", 4442 | "zerofrom", 4443 | "zerovec-derive", 4444 | ] 4445 | 4446 | [[package]] 4447 | name = "zerovec-derive" 4448 | version = "0.10.3" 4449 | source = "registry+https://github.com/rust-lang/crates.io-index" 4450 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 4451 | dependencies = [ 4452 | "proc-macro2", 4453 | "quote", 4454 | "syn", 4455 | ] 4456 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pdf-rendering-srv" 3 | version = "0.1.3" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | tokio = { version = "1.44.1", features = ["macros", "rt-multi-thread", "rt", "full"] } 10 | prost = "0.13.5" 11 | headless_chrome = "1.0.17" 12 | tonic = "0.13.0" 13 | prost-types = "0.13.5" 14 | tokio-stream = "0.1.17" 15 | tiny_http = "0.12.0" 16 | tonic-reflection = "0.13.0" 17 | tonic-health = "0.13.0" 18 | anyhow = "1.0.97" 19 | log = "0.4.27" 20 | env_logger = "0.11.7" 21 | config = "0.15.11" 22 | aws-sdk-s3 = "1.79.0" 23 | aws-sdk-config = "1.65.0" 24 | aws-smithy-runtime-api = "1.7.4" 25 | lopdf = "0.36.0" 26 | serde_json = "1.0.140" 27 | serde = { version = "1.0.219", features = ["derive"] } 28 | prost-wkt-types = "0.6.0" 29 | ulid = "1.2.1" 30 | 31 | [build-dependencies] 32 | tonic-build = "0.13.0" 33 | reqwest = { version = "0.12.15", features = ["blocking", "json"] } 34 | flate2 = "1.1.0" 35 | tar = "0.4.44" 36 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM lukemathwalker/cargo-chef:0.1.71-rust-1.85.1-alpine3.21 AS planner 2 | WORKDIR /app 3 | COPY . . 4 | RUN cargo chef prepare --recipe-path recipe.json 5 | 6 | 7 | FROM rust:1.85.1-alpine3.21 AS build 8 | 9 | RUN rustup target add x86_64-unknown-linux-musl 10 | RUN apk add --no-cache build-base pkgconfig dbus-dev "libressl-dev<4.1.0" protoc protobuf-dev 11 | 12 | WORKDIR /app 13 | 14 | RUN cargo install cargo-chef 15 | 16 | COPY --from=planner /app/recipe.json recipe.json 17 | RUN cargo chef cook --release --target x86_64-unknown-linux-musl --recipe-path recipe.json 18 | 19 | COPY . . 20 | RUN cargo build --target x86_64-unknown-linux-musl --release 21 | 22 | RUN strip /app/target/x86_64-unknown-linux-musl/release/pdf-rendering-srv 23 | 24 | 25 | FROM alpine:3.21 26 | 27 | RUN apk --update --upgrade --no-cache add fontconfig font-noto font-noto-emoji font-liberation \ 28 | && fc-cache -f \ 29 | && fc-list | sort 30 | 31 | # Don't install M$ fonts because of license issues 32 | # RUN apk --update add fontconfig msttcorefonts-installer \ 33 | # && update-ms-fonts \ 34 | # && fc-cache -f 35 | 36 | RUN apk add --no-cache chromium 37 | 38 | WORKDIR /app 39 | 40 | COPY --from=build /app/target/x86_64-unknown-linux-musl/release/pdf-rendering-srv /app/pdf-rendering-srv 41 | COPY ./cfg /app/cfg 42 | 43 | ENV NODE_ENV=production 44 | 45 | EXPOSE 50051 46 | 47 | CMD ["/app/pdf-rendering-srv"] 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) n-fuse GmbH and other contributors. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = PDF Rendering Service 2 | 3 | https://github.com/restorecommerce/pdf-rendering-srv/actions/workflows/build.yaml[image:https://img.shields.io/github/actions/workflow/status/restorecommerce/pdf-rendering-srv/build.yaml?style=flat-square[Build Status]] 4 | 5 | A microservice for PDF rendering from URLs. 6 | 7 | Please consult the documentation for using it: 8 | 9 | - *link:https://docs.restorecommerce.io/pdf-rendering-srv/index.html[Usage]* 10 | - *link:https://docs.restorecommerce.io/architecture/index.html[Restorecommerce Architecture]* 11 | 12 | Part of link:https://github.com/restorecommerce[Restorecommerce]. 13 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - ~~Authentication/ authorization (+ subject propagation)~~ 2 | - ~~Let service directly upload to a pre defined S3 endpoint (provide bucket, key, meta data in the request)~~ 3 | - ~~Combine PDFs~~ 4 | - Embed attachments like XML data 5 | - PDF/A support 6 | - Proxy support for downloads 7 | - Content caching 8 | - ~~Add docs also explaining how to add fonts~~ 9 | - ~~Info endpoint that provides chrome version~~ 10 | - ~~Modify PDF meta data~~ 11 | - Emit Kafka event on successful render/ upload 12 | - ~~Batch rendering of multiple documents~~ 13 | - ~~Add logging~~ 14 | - Store objects via Ostorage service instead of S3 directly 15 | - return the actual URL instead of n/a when the object is stored 16 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use flate2::read::GzDecoder; 2 | use std::env; 3 | use std::fs; 4 | use std::path::{Path, PathBuf}; 5 | use tar::Archive; 6 | 7 | // npm view @restorecommerce/protos dist.tarball 8 | const PROTO_URL: &str = "https://registry.npmjs.org/@restorecommerce/protos/-/protos-6.8.0.tgz"; 9 | 10 | fn main() -> Result<(), Box> { 11 | let out_dir = env::var_os("OUT_DIR").unwrap(); 12 | let dest_path = Path::new(&out_dir).join("protos"); 13 | let relative_path = dest_path.strip_prefix(env::current_dir()?)?; 14 | 15 | let resp = reqwest::blocking::get(PROTO_URL).expect("request failed"); 16 | let tar = GzDecoder::new(resp); 17 | let mut archive = Archive::new(tar); 18 | archive.unpack(relative_path)?; 19 | 20 | let proto_path = Path::new(&relative_path).join("package/io/restorecommerce/"); 21 | fs::copy( 22 | Path::new(&env::current_dir()?).join("pdf_rendering.proto"), 23 | Path::new(&proto_path).join("pdf_rendering.proto").clone(), 24 | )?; 25 | 26 | tonic_build::configure() 27 | .build_server(true) 28 | .build_client(false) 29 | .compile_well_known_types(true) 30 | .extern_path( 31 | ".google.protobuf.BytesValue", 32 | "::prost::alloc::vec::Vec", 33 | ) 34 | .extern_path( 35 | ".google.protobuf.StringValue", 36 | "::prost::alloc::string::String", 37 | ) 38 | .extern_path(".google.protobuf", "::prost_wkt_types") 39 | .type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]") 40 | .file_descriptor_set_path(Path::new(&out_dir).join("proto_fd.bin")) 41 | .compile_protos( 42 | &[Path::new(&proto_path).join("pdf_rendering.proto").clone()], 43 | &[Path::new(&relative_path).join("package/")], 44 | )?; 45 | 46 | let paths: Vec = fs::read_dir(proto_path.clone()) 47 | .expect("") 48 | .filter(|p| { 49 | p.as_ref() 50 | .unwrap() 51 | .file_name() 52 | .to_str() 53 | .unwrap() 54 | .to_string() 55 | .contains(".proto") 56 | }) 57 | .filter(|p| { 58 | !p.as_ref() 59 | .unwrap() 60 | .file_name() 61 | .to_str() 62 | .unwrap() 63 | .to_string() 64 | .eq("pdf_rendering.proto") 65 | }) 66 | .map(|p| p.unwrap().path()) 67 | .collect(); 68 | 69 | tonic_build::configure() 70 | .build_server(false) 71 | .build_client(true) 72 | .compile_well_known_types(true) 73 | .extern_path( 74 | ".google.protobuf.BytesValue", 75 | "::prost::alloc::vec::Vec", 76 | ) 77 | .extern_path( 78 | ".google.protobuf.StringValue", 79 | "::prost::alloc::string::String", 80 | ) 81 | .extern_path(".google.protobuf", "::prost_wkt_types") 82 | .type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]") 83 | .compile_protos(&paths, &[Path::new(&relative_path).join("package/")])?; 84 | 85 | Ok(()) 86 | } 87 | -------------------------------------------------------------------------------- /buildImage.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SERVICE_NAME="pdf-rendering-srv" 4 | 5 | DOCKER_BUILDKIT=1 docker build \ 6 | --tag restorecommerce/$SERVICE_NAME \ 7 | -f ./Dockerfile \ 8 | --cache-from restorecommerce/$SERVICE_NAME \ 9 | . 10 | -------------------------------------------------------------------------------- /cfg/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "logger": { 3 | "console": { 4 | "level": "info" 5 | } 6 | }, 7 | 8 | "server": { 9 | "host": "0.0.0.0", 10 | "port": 50062, 11 | "message_size_limit": 128000000 12 | }, 13 | 14 | "s3": { 15 | "client": { 16 | "region": "eu-central-1", 17 | "endpoint": "http://127.0.0.1:8000", 18 | "access_key": "accessKey1", 19 | "secret_key": "verySecretKey1", 20 | "s3_force_path_style": true 21 | } 22 | }, 23 | 24 | "serviceNames": { 25 | "ostorage": "io-restorecommerce-ostorage-srv", 26 | "reflection": "io-restorecommerce-ostorage-reflection", 27 | "cis": "io-restorecommerce-ostorage-cis", 28 | "health": "grpc-health-v1" 29 | }, 30 | 31 | "client": { 32 | "user": { 33 | "address": "http://localhost:50051" 34 | } 35 | }, 36 | 37 | "authorization": { 38 | "urns": { 39 | "entity": "urn:restorecommerce:acs:names:model:entity", 40 | "user": "urn:restorecommerce:acs:model:user.User", 41 | "model": "urn:restorecommerce:acs:model", 42 | "role": "urn:restorecommerce:acs:names:role", 43 | "roleScopingEntity": "urn:restorecommerce:acs:names:roleScopingEntity", 44 | "roleScopingInstance": "urn:restorecommerce:acs:names:roleScopingInstance", 45 | "unauthenticated_user": "urn:restorecommerce:acs:names:unauthenticated-user", 46 | "property": "urn:restorecommerce:acs:names:model:property", 47 | "ownerIndicatoryEntity": "urn:restorecommerce:acs:names:ownerIndicatoryEntity", 48 | "ownerInstance": "urn:restorecommerce:acs:names:ownerInstance", 49 | "orgScope": "urn:restorecommerce:acs:model:organization.Organization", 50 | "subjectID": "urn:oasis:names:tc:xacml:1.0:subject:subject-id", 51 | "resourceID": "urn:oasis:names:tc:xacml:1.0:resource:resource-id", 52 | "actionID": "urn:oasis:names:tc:xacml:1.0:action:action-id", 53 | "action": "urn:restorecommerce:acs:names:action", 54 | "operation": "urn:restorecommerce:acs:names:operation", 55 | "execute": "urn:restorecommerce:acs:names:action:execute", 56 | "permitOverrides": "urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-overrides", 57 | "denyOverrides": "urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:deny-overrides", 58 | "create": "urn:restorecommerce:acs:names:action:create", 59 | "read": "urn:restorecommerce:acs:names:action:read", 60 | "modify": "urn:restorecommerce:acs:names:action:modify", 61 | "delete": "urn:restorecommerce:acs:names:action:delete", 62 | "organization": "urn:restorecommerce:acs:model:organization.Organization", 63 | "aclIndicatoryEntity": "urn:restorecommerce:acs:names:aclIndicatoryEntity", 64 | "aclInstance": "urn:restorecommerce:acs:names:aclInstance", 65 | "skipACL": "urn:restorecommerce:acs:names:skipACL", 66 | "maskedProperty": "urn:restorecommerce:acs:names:obligation:maskedProperty" 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /cfg/config_development.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /cfg/config_production.json: -------------------------------------------------------------------------------- 1 | { 2 | "server": { 3 | "port": 50051 4 | }, 5 | 6 | "s3": { 7 | "client": { 8 | "endpoint": "http://cloudserver:8000" 9 | } 10 | }, 11 | 12 | "client": { 13 | "user": { 14 | "address": "http://identity-srv:50051" 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /docs/antora.yml: -------------------------------------------------------------------------------- 1 | name: pdf-rendering-srv 2 | title: PDF Rendering Service 3 | version: master 4 | nav: 5 | - modules/ROOT/nav.adoc 6 | -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/fonts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/restorecommerce/pdf-rendering-srv/537594189a790e2ce234aa14f5c55ea85f502991/docs/modules/ROOT/assets/images/fonts.png -------------------------------------------------------------------------------- /docs/modules/ROOT/nav.adoc: -------------------------------------------------------------------------------- 1 | // INDEX 2 | * xref:index.adoc[PDF Rendering Service] 3 | 4 | // FEATURES 5 | * xref:index.adoc#features[Features] 6 | 7 | // EXAMPLE 8 | * xref:index.adoc#example[Example] 9 | 10 | // USAGE 11 | * xref:index.adoc#usage[Usage] 12 | ** xref:index.adoc#usage_running_as_container[Running as Container] 13 | ** xref:index.adoc#usage_from_url[From URL] 14 | ** xref:index.adoc#usage_from_html[From HTML] 15 | 16 | // CUSTOMIZATION 17 | * xref:index.adoc#customization[Customization] 18 | ** xref:index.adoc#customization_install_additional_fonts[Installing Extra Fonts] 19 | 20 | // CONFIGURATION 21 | * xref:index.adoc#configuration[Configuration] 22 | 23 | // API 24 | * xref:index.adoc#api[API] 25 | ** xref:index.adoc#api_render[Render] 26 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = PDF Rendering Service 2 | 3 | A microservice for rendering PDFs from HTML using the Chromium browser. 4 | 5 | [#features] 6 | == Features 7 | 8 | * Good for any kind of content like receipts, invoices, reports. 9 | * gRPC interface including health checks. 10 | * Batch rendering. 11 | * Return or upload render results to an S3 endpoint. 12 | * Uses link:https://www.chromium.org/[Chromium] to render PDF. 13 | * Supports various fonts out of the box and adding custom fonts. 14 | 15 | [#example] 16 | == Example 17 | 18 | [source,html] 19 | ---- 20 | 21 | 22 | 23 | 24 |

This is a paragraph - Liberation.

25 |

This is a paragraph - Liberation Sans.

26 |

This is a paragraph - Noto Serif.

27 |

This is a paragraph - Noto Sans.

28 |

This is a paragraph - Arial (without font being installed).

29 |

This is a paragraph - Comic Sans MS (without font being installed).

30 |

This is a paragraph - Times New Roman (without font being installed).

31 | 32 | 33 | 34 | ---- 35 | 36 | renders like this in PDF: 37 | image:https://github.com/restorecommerce/pdf-rendering-srv/blob/master/docs/modules/ROOT/assets/images/fonts.png[fonts.png]. 38 | 39 | [#usage] 40 | == Usage 41 | 42 | [#usage_running_as_container] 43 | === Running as Container 44 | 45 | [source,sh] 46 | ---- 47 | docker run -d -p 50051:50051 --name pdf-rendering-srv ghcr.io/restorecommerce/pdf-rendering-srv 48 | ---- 49 | 50 | [#example_calls] 51 | === Example calls 52 | 53 | These examples use the link:https://github.com/fullstorydev/grpcurl[grpcurl] CLI tool to make gRPC calls. 54 | 55 | [#example_call_from_url] 56 | ==== From URL 57 | 58 | Produces a PDF file called `out.pdf` 59 | 60 | [source,sh] 61 | ---- 62 | grpcurl -plaintext -d '{ 63 | "individual": { 64 | "data": [ 65 | { 66 | "data": { 67 | "source": { 68 | "url": "https://en.wikipedia.org/wiki/WebKit" 69 | } 70 | } 71 | } 72 | ] 73 | } 74 | }' 127.0.0.1:50051 io.restorecommerce.pdf_rendering.PdfRenderingService.Render | jq -r '.individual.RenderingResponse[0].payload.pdf.data' | base64 -d > out.pdf 75 | ---- 76 | 77 | [#example_call_from_html] 78 | ==== From HTML 79 | 80 | Produces a PDF file called `out.pdf` 81 | 82 | [source,sh] 83 | ---- 84 | grpcurl -plaintext -d '{ 85 | "individual": { 86 | "data": [ 87 | { 88 | "data": { 89 | "source": { 90 | "html": "Hello World" 91 | } 92 | } 93 | } 94 | ] 95 | } 96 | }' 127.0.0.1:50051 io.restorecommerce.pdf_rendering.PdfRenderingService.Render | jq -r '.individual.RenderingResponse[0].payload.pdf.data' | base64 -d > out.pdf 97 | ---- 98 | 99 | [#example_call_combine] 100 | ==== Combine Multiple PDFs 101 | 102 | Produces a PDF file called `combined.pdf` 103 | 104 | [source,sh] 105 | ---- 106 | grpcurl -plaintext -d '{ 107 | "combined": { 108 | "data": [ 109 | { 110 | "source": { 111 | "url": "https://en.wikipedia.org/wiki/WebKit" 112 | } 113 | }, 114 | { 115 | "source": { 116 | "html": "Hello World" 117 | } 118 | } 119 | ] 120 | } 121 | }' 127.0.0.1:50051 io.restorecommerce.pdf_rendering.PdfRenderingService.Render | jq -r '.combined.payload.pdf.data' | base64 -d > combined.pdf 122 | ---- 123 | 124 | [#example_s3] 125 | ==== Upload directly to S3 126 | 127 | Produces a PDF file and uploads it to the `pdf` bucket at the `sample.pdf` key. 128 | 129 | [source,sh] 130 | ---- 131 | grpcurl -plaintext -d '{ 132 | "individual": { 133 | "data": [ 134 | { 135 | "data": { 136 | "source": { 137 | "html": "Hello World" 138 | } 139 | }, 140 | "output": { 141 | "metaData": { 142 | "title": "Replacement Title", 143 | "creator": "Replacement Creator", 144 | "producer": "Replacement Producer" 145 | }, 146 | "uploadOptions": { 147 | "bucket": "pdf", 148 | "key": "sample.pdf" 149 | } 150 | } 151 | } 152 | ] 153 | } 154 | }' 127.0.0.1:50051 io.restorecommerce.pdf_rendering.PdfRenderingService.Render | jq 155 | ---- 156 | 157 | [#customization] 158 | == Customization 159 | 160 | [#customization_install_additional_fonts] 161 | === Installing Additional Fonts 162 | 163 | See the Dockerfile how fonts are installed in Alpine Linux. 164 | 165 | [#configuration] 166 | == Configuration 167 | 168 | All configuration options and their defaults are available in `./cfg/config.json`. 169 | 170 | [#api] 171 | == API 172 | 173 | This microservice exposes the following gRPC endpoints: 174 | 175 | [#api_info] 176 | === Info 177 | 178 | Return data about the used chromium instance. 179 | 180 | `io.restorecommerce.pdf_rendering.PdfRenderingService.Info` 181 | 182 | [#api_render] 183 | === Render 184 | 185 | Render provided request into a PDF. 186 | 187 | `io.restorecommerce.pdf_rendering.PdfRenderingService.Render` 188 | 189 | [width="100%",cols="20%,16%,20%,44%",options="header",] 190 | |========================================================================================================================== 191 | |Field |Type |Label |Description 192 | |individual |`io.restorecommerce.pdf_rendering.IndividualRequest` |optional |Individual render request 193 | |combined |`io.restorecommerce.pdf_rendering.CombinedRequest` |optional |Combined render request 194 | |subject |`io.restorecommerce.auth.Subject` |optional |Subject details 195 | |========================================================================================================================== 196 | 197 | For details of the meaning of these options check the link:https://pptr.dev/api/puppeteer.pdfoptions[PDFOptions interface] of Puppeteer. 198 | 199 | -------------------------------------------------------------------------------- /lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -ex 4 | 5 | cargo +nightly fmt 6 | cargo +nightly clippy -------------------------------------------------------------------------------- /pdf_rendering.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package io.restorecommerce.pdf_rendering; 4 | 5 | import "google/protobuf/any.proto"; 6 | import "google/protobuf/empty.proto"; 7 | import "io/restorecommerce/auth.proto"; 8 | import "io/restorecommerce/status.proto"; 9 | 10 | // Service 11 | 12 | service PdfRenderingService { 13 | rpc Render(RenderRequest) returns (RenderingResponse); 14 | rpc Info(google.protobuf.Empty) returns (InfoResponse); 15 | } 16 | 17 | // Requests 18 | 19 | message RenderRequest { 20 | oneof type { 21 | IndividualRequest individual = 1; 22 | CombinedRequest combined = 2; 23 | } 24 | optional io.restorecommerce.auth.Subject subject = 3; 25 | } 26 | 27 | message IndividualRequest { 28 | message IndividualRequestData { 29 | RenderData data = 1; 30 | optional OutputOptions output = 2; 31 | } 32 | 33 | repeated IndividualRequestData data = 1; 34 | } 35 | 36 | message CombinedRequest { 37 | repeated RenderData data = 1; 38 | optional OutputOptions output = 2; 39 | } 40 | 41 | message RenderData { 42 | RenderSource source = 1; 43 | optional RenderOptions options = 2; 44 | } 45 | 46 | message OutputOptions { 47 | optional bool generate_pdfa = 1; 48 | optional MetaData meta_data = 2; 49 | optional UploadOptions upload_options = 3; 50 | } 51 | 52 | message RenderOptions { 53 | oneof header_template { 54 | string header_url = 1; 55 | string header_html = 2; 56 | } 57 | oneof footer_template { 58 | string footer_url = 3; 59 | string footer_html = 4; 60 | } 61 | optional int64 wait_after_load_time = 5; 62 | optional PuppeteerOptions puppeteer_options = 6; 63 | } 64 | 65 | message RenderSource { 66 | oneof content { 67 | string url = 1; 68 | string html = 2; 69 | } 70 | } 71 | 72 | message UploadOptions { 73 | optional string bucket = 1; 74 | optional string key = 2; 75 | optional string content_disposition = 3; 76 | } 77 | 78 | message MetaData { 79 | optional string title = 1; 80 | optional string creator = 2; 81 | optional string producer = 3; 82 | } 83 | 84 | // Responses 85 | 86 | message RenderingResponse { 87 | oneof response { 88 | IndividualResponse individual = 1; 89 | ResponsePayloadWithStatus combined = 2; 90 | } 91 | optional io.restorecommerce.status.OperationStatus operation_status = 3; 92 | } 93 | 94 | message IndividualResponse { 95 | repeated ResponsePayloadWithStatus RenderingResponse = 1; 96 | } 97 | 98 | message ResponsePayloadWithStatus { 99 | optional ResponsePayload payload = 1; 100 | optional io.restorecommerce.status.Status status = 3; 101 | } 102 | 103 | message ResponsePayload { 104 | oneof response { 105 | ResponsePDF pdf = 1; 106 | ResponseS3Upload upload_result = 2; 107 | } 108 | } 109 | 110 | message ResponsePDF { 111 | bytes data = 1; 112 | } 113 | 114 | message ResponseS3Upload { 115 | string url = 1; 116 | int32 length = 2; 117 | } 118 | 119 | // Info 120 | 121 | message InfoResponse { 122 | message ChromeVersion { 123 | string protocol_version = 1; 124 | string product = 2; 125 | string revision = 3; 126 | string user_agent = 4; 127 | string js_version = 5; 128 | } 129 | 130 | ChromeVersion chrome = 1; 131 | } 132 | 133 | // Puppeteer 134 | 135 | message PuppeteerOptions { 136 | optional PDFOptions pdf_options = 1; 137 | } 138 | 139 | message PDFOptions { 140 | enum PaperFormat { 141 | A0 = 0; 142 | A1 = 1; 143 | A2 = 2; 144 | A3 = 3; 145 | A4 = 4; 146 | A5 = 5; 147 | A6 = 6; 148 | A7 = 7; 149 | LETTER = 8; 150 | LEGAL = 9; 151 | TABLOID = 10; 152 | } 153 | 154 | optional bool landscape = 1; 155 | optional bool display_header_footer = 2; 156 | optional bool print_background = 3; 157 | optional PaperFormat format = 4; 158 | optional float scale = 5; 159 | optional float paper_width = 6; 160 | optional float paper_height = 7; 161 | optional float margin_top = 8; 162 | optional float margin_bottom = 9; 163 | optional float margin_left = 10; 164 | optional float margin_right = 11; 165 | optional string page_ranges = 12; 166 | optional bool ignore_invalid_page_ranges = 13; 167 | optional string header_template = 14; 168 | optional string footer_template = 15; 169 | optional bool prefer_css_page_size = 16; 170 | } 171 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use config::{Case, Config, File}; 2 | use env_logger::WriteStyle; 3 | use log::info; 4 | use std::str::FromStr; 5 | use std::{env, error::Error, net::ToSocketAddrs}; 6 | use tokio::sync::mpsc; 7 | 8 | use tonic::codegen::InterceptedService; 9 | use tonic::{transport::Server, Request, Status}; 10 | use tonic_health::ServingStatus; 11 | 12 | use crate::proto::pdf_rendering::pdf_rendering_service_server::PdfRenderingServiceServer; 13 | use crate::renderer::start_renderer; 14 | use crate::server::PDFServer; 15 | use crate::types::{IDExtension, InternalRequest}; 16 | 17 | mod pdf_utils; 18 | mod proto; 19 | mod renderer; 20 | mod s3; 21 | mod server; 22 | mod types; 23 | 24 | #[tokio::main] 25 | async fn main() -> Result<(), Box> { 26 | let config = load_config(); 27 | 28 | let level = log::LevelFilter::from_str( 29 | config 30 | .get_string("logger.console.level") 31 | .unwrap_or("info".to_string()) 32 | .as_str(), 33 | ); 34 | 35 | env_logger::builder() 36 | .filter_level(level.expect("invalid level")) 37 | .write_style(WriteStyle::Always) 38 | .init(); 39 | 40 | let metrics = tokio::runtime::Handle::current().metrics(); 41 | info!("worker count: {}", metrics.num_workers()); 42 | 43 | let reflection_service = tonic_reflection::server::Builder::configure() 44 | .register_encoded_file_descriptor_set(proto::pdf_rendering::FILE_DESCRIPTOR_SET) 45 | .build_v1() 46 | .unwrap(); 47 | 48 | let (health_reporter, health_service) = tonic_health::server::health_reporter(); 49 | 50 | health_reporter 51 | .set_serving::>() 52 | .await; 53 | 54 | health_reporter 55 | .set_service_status("readiness", ServingStatus::Serving) 56 | .await; 57 | 58 | let (tx, rx) = mpsc::channel::(32); 59 | 60 | let pdf_server = PDFServer { 61 | config: config.clone(), 62 | renderer: tx, 63 | }; 64 | 65 | start_renderer(rx).await?; 66 | 67 | let pdf_service = 68 | InterceptedService::new( 69 | PdfRenderingServiceServer::new(pdf_server) 70 | .max_decoding_message_size( 71 | config.get_int("server.message_size_limit").unwrap() as usize 72 | ) 73 | .max_encoding_message_size( 74 | config.get_int("server.message_size_limit").unwrap() as usize 75 | ), 76 | logging, 77 | ); 78 | 79 | let server = Server::builder() 80 | .add_service(health_service) 81 | .add_service(reflection_service) 82 | .add_service(pdf_service) 83 | .serve( 84 | (format!( 85 | "{}:{}", 86 | config.get_string("server.host").unwrap(), 87 | config.get_int("server.port").unwrap() 88 | )) 89 | .to_socket_addrs() 90 | .unwrap() 91 | .next() 92 | .unwrap(), 93 | ); 94 | 95 | info!( 96 | "Serving gRPC on port {}.", 97 | config.get_int("server.port").unwrap() 98 | ); 99 | 100 | server.await?; 101 | 102 | Ok(()) 103 | } 104 | 105 | fn logging(mut req: Request<()>) -> Result, Status> { 106 | let id = ulid::Ulid::new(); 107 | 108 | req.extensions_mut().insert(IDExtension { id }); 109 | 110 | info!("[{}] Received request: {:?}", id, req); 111 | Ok(req) 112 | } 113 | 114 | fn load_config() -> Config { 115 | let run_mode = env::var("NODE_ENV").unwrap_or_else(|_| "development".into()); 116 | 117 | println!("Running in mode: {}", run_mode); 118 | 119 | Config::builder() 120 | .add_source(File::with_name("cfg/config")) 121 | .add_source(File::with_name(&format!("cfg/config_{}", run_mode))) 122 | .add_source(config::Environment::with_convert_case(Case::Lower).separator("__")) 123 | .build() 124 | .unwrap() 125 | } 126 | -------------------------------------------------------------------------------- /src/pdf_utils.rs: -------------------------------------------------------------------------------- 1 | use log::error; 2 | use std::collections::BTreeMap; 3 | use std::io::{Cursor, Write}; 4 | 5 | use crate::proto::pdf_rendering::MetaData; 6 | use lopdf::Dictionary as LoDictionary; 7 | use lopdf::Object::*; 8 | use lopdf::StringFormat::Literal; 9 | use lopdf::{Bookmark, Document, Object, ObjectId}; 10 | 11 | pub fn merge_pdfs(documents: Vec) -> std::io::Result> { 12 | // Define a starting max_id (will be used as start index for object_ids) 13 | let mut max_id = 1; 14 | let mut pagenum = 1; 15 | // Collect all Documents Objects grouped by a map 16 | let mut documents_pages = BTreeMap::new(); 17 | let mut documents_objects = BTreeMap::new(); 18 | let mut document = Document::with_version("1.5"); 19 | 20 | for mut doc in documents { 21 | let mut first = false; 22 | doc.renumber_objects_with(max_id); 23 | 24 | max_id = doc.max_id + 1; 25 | 26 | documents_pages.extend( 27 | doc.get_pages() 28 | .into_values() 29 | .map(|object_id| { 30 | if !first { 31 | let bookmark = Bookmark::new( 32 | format!("Page_{}", pagenum), 33 | [0.0, 0.0, 1.0], 34 | 0, 35 | object_id, 36 | ); 37 | document.add_bookmark(bookmark, None); 38 | first = true; 39 | pagenum += 1; 40 | } 41 | 42 | (object_id, doc.get_object(object_id).unwrap().to_owned()) 43 | }) 44 | .collect::>(), 45 | ); 46 | documents_objects.extend(doc.objects); 47 | } 48 | 49 | // Catalog and Pages are mandatory 50 | let mut catalog_object: Option<(ObjectId, Object)> = None; 51 | let mut pages_object: Option<(ObjectId, Object)> = None; 52 | 53 | // Process all objects except "Page" type 54 | for (object_id, object) in documents_objects.iter() { 55 | // We have to ignore "Page" (as are processed later), "Outlines" and "Outline" objects 56 | // All other objects should be collected and inserted into the main Document 57 | match object.type_name().unwrap_or("".as_bytes()) { 58 | b"Catalog" => { 59 | // Collect a first "Catalog" object and use it for the future "Pages" 60 | catalog_object = Some(( 61 | if let Some((id, _)) = catalog_object { 62 | id 63 | } else { 64 | *object_id 65 | }, 66 | object.clone(), 67 | )); 68 | } 69 | b"Pages" => { 70 | // Collect and update a first "Pages" object and use it for the future "Catalog" 71 | // We have also to merge all dictionaries of the old and the new "Pages" object 72 | if let Ok(dictionary) = object.as_dict() { 73 | let mut dictionary = dictionary.clone(); 74 | if let Some((_, ref object)) = pages_object { 75 | if let Ok(old_dictionary) = object.as_dict() { 76 | dictionary.extend(old_dictionary); 77 | } 78 | } 79 | 80 | pages_object = Some(( 81 | if let Some((id, _)) = pages_object { 82 | id 83 | } else { 84 | *object_id 85 | }, 86 | Dictionary(dictionary), 87 | )); 88 | } 89 | } 90 | b"Page" => {} // Ignored, processed later and separately 91 | b"Outlines" => {} // Ignored, not supported yet 92 | b"Outline" => {} // Ignored, not supported yet 93 | _ => { 94 | document.objects.insert(*object_id, object.clone()); 95 | } 96 | } 97 | } 98 | 99 | // If no "Pages" object found abort 100 | if pages_object.is_none() { 101 | error!("Pages root not found."); 102 | 103 | return Ok(vec![]); 104 | } 105 | 106 | // Iterate over all "Page" objects and collect into the parent "Pages" created before 107 | for (object_id, object) in documents_pages.iter() { 108 | if let Ok(dictionary) = object.as_dict() { 109 | let mut dictionary = dictionary.clone(); 110 | dictionary.set("Parent", pages_object.as_ref().unwrap().0); 111 | 112 | document.objects.insert(*object_id, Dictionary(dictionary)); 113 | } 114 | } 115 | 116 | // If no "Catalog" found abort 117 | if catalog_object.is_none() { 118 | error!("Catalog root not found."); 119 | 120 | return Ok(vec![]); 121 | } 122 | 123 | let catalog_object = catalog_object.unwrap(); 124 | let pages_object = pages_object.unwrap(); 125 | 126 | // Build a new "Pages" with updated fields 127 | if let Ok(dictionary) = pages_object.1.as_dict() { 128 | let mut dictionary = dictionary.clone(); 129 | 130 | // Set new pages count 131 | dictionary.set("Count", documents_pages.len() as u32); 132 | 133 | // Set new "Kids" list (collected from documents pages) for "Pages" 134 | dictionary.set( 135 | "Kids", 136 | documents_pages 137 | .into_keys() 138 | .map(Reference) 139 | .collect::>(), 140 | ); 141 | 142 | document 143 | .objects 144 | .insert(pages_object.0, Dictionary(dictionary)); 145 | } 146 | 147 | // Build a new "Catalog" with updated fields 148 | if let Ok(dictionary) = catalog_object.1.as_dict() { 149 | let mut dictionary = dictionary.clone(); 150 | dictionary.set("Pages", pages_object.0); 151 | dictionary.remove(b"Outlines"); // Outlines not supported in merged PDFs 152 | 153 | document 154 | .objects 155 | .insert(catalog_object.0, Dictionary(dictionary)); 156 | } 157 | 158 | document.trailer.set("Root", catalog_object.0); 159 | 160 | // Update the max internal ID as wasn't updated before due to direct objects insertion 161 | document.max_id = document.objects.len() as u32; 162 | 163 | // Reorder all new Document objects 164 | document.renumber_objects(); 165 | 166 | //Set any Bookmarks to the First child if they are not set to a page 167 | document.adjust_zero_pages(); 168 | 169 | //Set all bookmarks to the PDF Object tree then set the Outlines to the Bookmark content map. 170 | if let Some(n) = document.build_outline() { 171 | if let Ok(Dictionary(ref mut dict)) = document.get_object_mut(catalog_object.0) { 172 | dict.set("Outlines", Reference(n)); 173 | } 174 | } 175 | 176 | document.compress(); 177 | 178 | let out_buf = Vec::new(); 179 | let mut memory_cursor = Cursor::new(out_buf.clone()); 180 | 181 | document 182 | .save_to(&mut memory_cursor) 183 | .expect("failed saving pdf"); 184 | 185 | memory_cursor.flush().expect("failed flushing"); 186 | 187 | Ok(memory_cursor.get_ref().to_vec()) 188 | } 189 | 190 | pub fn add_pdf_metadata(file: Vec, meta: Option) -> std::io::Result> { 191 | match meta { 192 | None => Ok(file), 193 | Some(m) => { 194 | let mut document = Document::load_mem(&file).expect("failed parsing pdf"); 195 | 196 | let mut meta_list = Vec::new(); 197 | 198 | if m.title.is_some() { 199 | meta_list.push(("Title", String(m.title.unwrap().into(), Literal))); 200 | } 201 | 202 | if m.creator.is_some() { 203 | meta_list.push(("Creator", String(m.creator.unwrap().into(), Literal))); 204 | } 205 | 206 | if m.producer.is_some() { 207 | meta_list.push(("Producer", String(m.producer.unwrap().into(), Literal))); 208 | } 209 | 210 | document.set_object((1, 0), LoDictionary::from_iter(meta_list.clone())); 211 | 212 | document.compress(); 213 | 214 | let out_buf = Vec::new(); 215 | let mut memory_cursor = Cursor::new(out_buf.clone()); 216 | 217 | document 218 | .save_to(&mut memory_cursor) 219 | .expect("failed saving PDF"); 220 | 221 | memory_cursor.flush().expect("failed flushing"); 222 | 223 | Ok(memory_cursor.get_ref().to_vec()) 224 | } 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /src/proto.rs: -------------------------------------------------------------------------------- 1 | pub mod attribute { 2 | tonic::include_proto!("io.restorecommerce.attribute"); 3 | } 4 | pub mod status { 5 | tonic::include_proto!("io.restorecommerce.status"); 6 | } 7 | pub mod auth { 8 | tonic::include_proto!("io.restorecommerce.auth"); 9 | } 10 | pub mod meta { 11 | tonic::include_proto!("io.restorecommerce.meta"); 12 | } 13 | pub mod user { 14 | tonic::include_proto!("io.restorecommerce.user"); 15 | } 16 | pub mod image { 17 | tonic::include_proto!("io.restorecommerce.image"); 18 | } 19 | pub mod role { 20 | tonic::include_proto!("io.restorecommerce.role"); 21 | } 22 | pub mod resourcebase { 23 | tonic::include_proto!("io.restorecommerce.resourcebase"); 24 | } 25 | pub mod filter { 26 | tonic::include_proto!("io.restorecommerce.filter"); 27 | } 28 | 29 | pub mod pdf_rendering { 30 | tonic::include_proto!("io.restorecommerce.pdf_rendering"); 31 | 32 | pub(crate) const FILE_DESCRIPTOR_SET: &[u8] = tonic::include_file_descriptor_set!("proto_fd"); 33 | } 34 | -------------------------------------------------------------------------------- /src/renderer.rs: -------------------------------------------------------------------------------- 1 | use crate::proto::pdf_rendering::pdf_options::PaperFormat; 2 | use crate::proto::pdf_rendering::render_source::Content; 3 | use crate::proto::pdf_rendering::{RenderData, RenderOptions}; 4 | use crate::types::{InternalRequest, RendererResponse}; 5 | use anyhow::{anyhow, Result}; 6 | use headless_chrome::browser::default_executable; 7 | use headless_chrome::types::PrintToPdfOptions; 8 | use headless_chrome::{Browser, LaunchOptionsBuilder, Tab}; 9 | use std::error::Error; 10 | use std::io; 11 | use std::sync::Arc; 12 | use std::time::Duration; 13 | use tokio::sync::mpsc; 14 | use tokio::sync::mpsc::Receiver; 15 | 16 | impl PaperFormat { 17 | pub fn width(&self) -> f32 { 18 | match self { 19 | PaperFormat::A0 => 33.1, 20 | PaperFormat::A1 => 23.4, 21 | PaperFormat::A2 => 16.5, 22 | PaperFormat::A3 => 11.7, 23 | PaperFormat::A4 => 8.27, 24 | PaperFormat::A5 => 5.83, 25 | PaperFormat::A6 => 4.13, 26 | PaperFormat::A7 => 2.91, 27 | PaperFormat::Letter => 8.5, 28 | PaperFormat::Legal => 8.5, 29 | PaperFormat::Tabloid => 11.0, 30 | } 31 | } 32 | 33 | pub fn height(&self) -> f32 { 34 | match self { 35 | PaperFormat::A0 => 46.8, 36 | PaperFormat::A1 => 33.1, 37 | PaperFormat::A2 => 23.4, 38 | PaperFormat::A3 => 16.5, 39 | PaperFormat::A4 => 11.69, 40 | PaperFormat::A5 => 8.27, 41 | PaperFormat::A6 => 5.83, 42 | PaperFormat::A7 => 4.13, 43 | PaperFormat::Letter => 11.0, 44 | PaperFormat::Legal => 14.0, 45 | PaperFormat::Tabloid => 17.0, 46 | } 47 | } 48 | } 49 | 50 | pub fn content_to_pdf( 51 | tab: Arc, 52 | content: Content, 53 | options: Option, 54 | ) -> Result, Box> { 55 | let mut landscape = None; 56 | let mut display_header_footer = None; 57 | let mut print_background = Some(true); 58 | let mut format = Some(PaperFormat::A4); 59 | let mut scale = None; 60 | let mut paper_width = None; 61 | let mut paper_height = None; 62 | let mut margin_top = Some(0.0); 63 | let mut margin_bottom = Some(0.0); 64 | let mut margin_left = Some(0.0); 65 | let mut margin_right = Some(0.0); 66 | let mut page_ranges = None; 67 | let mut ignore_invalid_page_ranges = None; 68 | let mut header_template = None; 69 | let mut footer_template = None; 70 | let mut prefer_css_page_size = Some(true); 71 | 72 | match options { 73 | None => {} 74 | Some(opt) => match opt.puppeteer_options { 75 | None => {} 76 | Some(puppeteer) => match puppeteer.pdf_options { 77 | None => {} 78 | Some(pdf) => { 79 | paper_width = pdf.paper_width.or(paper_width); 80 | paper_height = pdf.paper_height.or(paper_height); 81 | 82 | landscape = pdf.landscape.or(landscape); 83 | display_header_footer = pdf.display_header_footer.or(display_header_footer); 84 | print_background = pdf.print_background.or(print_background); 85 | format = pdf 86 | .format 87 | .map(|t| PaperFormat::try_from(t).unwrap()) 88 | .or(format); 89 | scale = pdf.scale.or(scale); 90 | paper_width = pdf.paper_width.or(paper_width); 91 | paper_height = pdf.paper_height.or(paper_height); 92 | margin_top = pdf.margin_top.or(margin_top); 93 | margin_bottom = pdf.margin_bottom.or(margin_bottom); 94 | margin_left = pdf.margin_left.or(margin_left); 95 | margin_right = pdf.margin_right.or(margin_right); 96 | page_ranges = pdf.page_ranges.or(page_ranges); 97 | ignore_invalid_page_ranges = pdf 98 | .ignore_invalid_page_ranges 99 | .or(ignore_invalid_page_ranges); 100 | header_template = pdf.header_template.or(header_template); 101 | footer_template = pdf.footer_template.or(footer_template); 102 | prefer_css_page_size = pdf.prefer_css_page_size.or(prefer_css_page_size); 103 | } 104 | }, 105 | }, 106 | } 107 | 108 | paper_width = paper_width.or(Some(format.unwrap().width())); 109 | paper_height = paper_height.or(Some(format.unwrap().height())); 110 | 111 | let pdf_options = PrintToPdfOptions { 112 | paper_width: paper_width.map(|t| t as f64), 113 | paper_height: paper_height.map(|t| t as f64), 114 | margin_top: margin_top.map(|t| t as f64), 115 | margin_right: margin_right.map(|t| t as f64), 116 | margin_bottom: margin_bottom.map(|t| t as f64), 117 | margin_left: margin_left.map(|t| t as f64), 118 | scale: scale.map(|t| t as f64), 119 | landscape, 120 | prefer_css_page_size, 121 | print_background, 122 | page_ranges, 123 | ignore_invalid_page_ranges, 124 | header_template, 125 | display_header_footer, 126 | footer_template, 127 | ..Default::default() 128 | }; 129 | 130 | let pdf = match content { 131 | Content::Url(url) => tab 132 | .navigate_to(url.as_str())? 133 | .wait_until_navigated()? 134 | .print_to_pdf(Some(pdf_options))?, 135 | Content::Html(data) => { 136 | let server = Arc::new(tiny_http::Server::http("127.0.0.1:0").unwrap()); 137 | 138 | let response = tiny_http::Response::new( 139 | 200.into(), 140 | vec![ 141 | tiny_http::Header::from_bytes(&b"Content-Type"[..], &b"text/html"[..]).unwrap(), 142 | ], 143 | io::Cursor::new(data.clone()), 144 | Some(data.clone().len()), 145 | None, 146 | ); 147 | 148 | let srv = server.clone(); 149 | std::thread::spawn(move || { 150 | let request = match srv.recv() { 151 | Ok(rq) => rq, 152 | Err(e) => { 153 | panic!("error: {}", e); 154 | } 155 | }; 156 | 157 | let _ = request.respond(response); 158 | 159 | drop(srv) 160 | }); 161 | 162 | tab.navigate_to( 163 | format!( 164 | "http://127.0.0.1:{}", 165 | server.server_addr().to_ip().unwrap().port() 166 | ) 167 | .as_str(), 168 | )? 169 | .wait_until_navigated()? 170 | .print_to_pdf(Some(pdf_options))? 171 | } 172 | }; 173 | 174 | tab.close(true)?; 175 | 176 | Ok(pdf) 177 | } 178 | 179 | pub async fn start_renderer(mut rx: Receiver) -> Result<(), Box> { 180 | let options = LaunchOptionsBuilder::default() 181 | .path(Some(default_executable().map_err(|e| anyhow!(e))?)) 182 | .sandbox(false) 183 | .idle_browser_timeout(Duration::MAX) 184 | .build() 185 | .unwrap(); 186 | 187 | tokio::spawn(async move { 188 | let browser = Arc::new(Browser::new(options).expect("failed instantiating browser")); 189 | 190 | while let Some(cmd) = rx.recv().await { 191 | handle_cmd(browser.clone(), cmd); 192 | } 193 | }); 194 | 195 | Ok(()) 196 | } 197 | 198 | pub fn handle_cmd(browser: Arc, cmd: InternalRequest) { 199 | tokio::spawn(async move { 200 | let (tx, mut rx) = mpsc::channel::(32); 201 | 202 | let data = cmd.data; 203 | for (i, req) in data.iter().enumerate() { 204 | let tab = browser.new_tab().expect("failed opening new browser tab"); 205 | handle_req(tab, req, tx.clone(), i); 206 | } 207 | 208 | let mut rendered = Vec::with_capacity(data.clone().len()); 209 | 210 | for _ in data.clone().iter() { 211 | rendered.push(rx.recv().await.unwrap()); 212 | } 213 | 214 | rendered.sort_by_key(|r| r.order); 215 | 216 | for out in rendered { 217 | let _ = cmd.response.send(out.resp).await; 218 | } 219 | }); 220 | } 221 | 222 | pub fn handle_req( 223 | tab: Arc, 224 | req: &RenderData, 225 | tx: mpsc::Sender, 226 | order: usize, 227 | ) { 228 | let req2 = req.clone(); 229 | tokio::spawn(async move { 230 | let content = req2 231 | .clone() 232 | .source 233 | .expect("no source") 234 | .content 235 | .expect("no content"); 236 | let options = req2.clone().options; 237 | let out = content_to_pdf(tab, content, options.clone()); 238 | let _ = tx.clone().send(RendererResponse { resp: out, order }).await; 239 | }); 240 | } 241 | -------------------------------------------------------------------------------- /src/s3.rs: -------------------------------------------------------------------------------- 1 | use crate::proto::attribute::Attribute; 2 | use crate::proto::auth::Subject; 3 | use crate::proto::meta; 4 | use crate::proto::pdf_rendering::UploadOptions; 5 | use crate::proto::user::user_service_client::UserServiceClient; 6 | use crate::proto::user::FindByTokenRequest; 7 | use aws_sdk_s3::config::Credentials; 8 | use aws_sdk_s3::error::SdkError; 9 | use aws_sdk_s3::operation::put_object::{PutObjectError, PutObjectOutput}; 10 | use aws_sdk_s3::primitives::ByteStream; 11 | use aws_smithy_runtime_api::client::orchestrator::HttpResponse; 12 | use config::Config; 13 | use serde::Serialize; 14 | use serde_json::json; 15 | use std::time::SystemTime; 16 | 17 | pub async fn upload_to_s3( 18 | config: Config, 19 | upload_opt: UploadOptions, 20 | data: Vec, 21 | subject: Option, 22 | ) -> Result> { 23 | let endpoint = config.get_string("s3.client.endpoint").unwrap(); 24 | let region = config.get_string("s3.client.region").unwrap(); 25 | let access_key = config.get_string("s3.client.access_key").unwrap(); 26 | let secret_key = config.get_string("s3.client.secret_key").unwrap(); 27 | 28 | let s3_config = aws_sdk_s3::Config::builder() 29 | .behavior_version_latest() 30 | .endpoint_url(endpoint) 31 | .region(aws_sdk_config::config::Region::new(region)) 32 | .credentials_provider(Credentials::new( 33 | access_key, secret_key, None, None, "Static", 34 | )) 35 | .force_path_style( 36 | config 37 | .get_bool("s3.client.s3_force_path_style") 38 | .unwrap_or(false), 39 | ) 40 | .build(); 41 | 42 | let client = aws_sdk_s3::Client::from_conf(s3_config); 43 | 44 | let bucket_name = upload_opt.bucket.unwrap(); 45 | let key = upload_opt.key.unwrap(); 46 | let meta = create_metadata(config.clone(), subject.clone()); 47 | let mut subject_value = "{}".to_owned(); 48 | 49 | if subject.clone().is_some() && subject.clone().unwrap().token.is_some() { 50 | let mut ids_client = 51 | UserServiceClient::connect(config.get_string("client.user.address").unwrap()) 52 | .await 53 | .unwrap(); 54 | 55 | let response = ids_client 56 | .find_by_token(tonic::Request::new(FindByTokenRequest { 57 | token: subject.clone().unwrap().token, 58 | })) 59 | .await 60 | .unwrap(); 61 | 62 | match response.get_ref().clone().payload { 63 | None => {} 64 | Some(user) => { 65 | subject_value = json!({ 66 | "id": user.id.unwrap() 67 | }) 68 | .to_string(); 69 | } 70 | } 71 | } 72 | 73 | client 74 | .put_object() 75 | .bucket(bucket_name.clone()) 76 | .key(key.clone()) 77 | .body(ByteStream::from(data.clone())) 78 | .content_type("application/pdf") 79 | .set_content_disposition(upload_opt.content_disposition) 80 | .metadata("Data", "{}") 81 | .metadata("Key", key.clone()) 82 | .metadata( 83 | "Meta", 84 | serde_json::to_string(&meta).expect("failed json serialization"), 85 | ) 86 | .metadata("Subject", subject_value) 87 | .send() 88 | .await 89 | } 90 | 91 | #[derive(Debug, Default, Serialize)] 92 | pub struct Resource { 93 | id: String, 94 | key: String, 95 | bucket: String, 96 | meta: meta::Meta, 97 | } 98 | 99 | fn create_metadata(config: Config, subject: Option) -> meta::Meta { 100 | let mut out = meta::Meta::default(); 101 | 102 | let now: prost_wkt_types::Timestamp = SystemTime::now().into(); 103 | out.created = Some(now); 104 | out.modified = Some(now); 105 | 106 | out.created_by = subject.clone().and_then(|s| s.id); 107 | out.modified_by = subject.clone().and_then(|s| s.id); 108 | 109 | match subject.clone() { 110 | None => {} 111 | Some(s) => match s.scope { 112 | None => {} 113 | Some(target_scope) => out.owners.push(Attribute { 114 | id: Some( 115 | config 116 | .get_string("authorization.urns.ownerIndicatoryEntity") 117 | .unwrap(), 118 | ), 119 | value: Some( 120 | config 121 | .get_string("authorization.urns.organization") 122 | .unwrap(), 123 | ), 124 | attributes: vec![Attribute { 125 | id: Some( 126 | config 127 | .get_string("authorization.urns.ownerInstance") 128 | .unwrap(), 129 | ), 130 | value: Some(target_scope), 131 | attributes: Vec::new(), 132 | }], 133 | }), 134 | }, 135 | } 136 | 137 | out 138 | } 139 | -------------------------------------------------------------------------------- /src/server.rs: -------------------------------------------------------------------------------- 1 | use crate::pdf_utils::{add_pdf_metadata, merge_pdfs}; 2 | use crate::proto::auth::Subject; 3 | use crate::proto::pdf_rendering::info_response::ChromeVersion; 4 | use crate::proto::pdf_rendering::pdf_rendering_service_server::PdfRenderingService; 5 | use crate::proto::pdf_rendering::render_request::Type; 6 | use crate::proto::pdf_rendering::{ 7 | rendering_response, response_payload, CombinedRequest, IndividualRequest, IndividualResponse, 8 | InfoResponse, OutputOptions, RenderRequest, RenderingResponse, ResponsePayload, 9 | ResponsePayloadWithStatus, ResponsePdf, ResponseS3Upload, 10 | }; 11 | use crate::proto::status; 12 | use crate::proto::status::OperationStatus; 13 | use crate::s3::upload_to_s3; 14 | use crate::types::{IDExtension, InternalRequest, InternalResponse}; 15 | use config::Config; 16 | use log::{debug, error, info}; 17 | use lopdf::Document; 18 | use prost_wkt_types::Empty; 19 | use tokio::sync::mpsc; 20 | use tonic::{Request, Response, Status}; 21 | 22 | pub struct PDFServer { 23 | pub config: Config, 24 | pub renderer: mpsc::Sender, 25 | } 26 | 27 | #[tonic::async_trait] 28 | impl PdfRenderingService for PDFServer { 29 | async fn render( 30 | &self, 31 | request: Request, 32 | ) -> Result, Status> { 33 | let (tx, mut rx) = mpsc::channel::(32); 34 | 35 | let id = request.extensions().get::().unwrap(); 36 | 37 | debug!("[{}] Rendering request: {:?}", id.id, request.get_ref()); 38 | 39 | let data = match request.get_ref().clone().r#type.unwrap() { 40 | Type::Individual(req) => req.data.iter().map(|x| x.clone().data.unwrap()).collect(), 41 | Type::Combined(req) => req.data, 42 | }; 43 | 44 | match self 45 | .renderer 46 | .send(InternalRequest { 47 | response: tx, 48 | data: data.clone(), 49 | }) 50 | .await 51 | { 52 | Ok(_) => {} 53 | Err(err) => { 54 | error!("error sending rendering request: {}", err); 55 | } 56 | } 57 | 58 | let mut rendered = Vec::with_capacity(data.len()); 59 | 60 | for _ in data.iter() { 61 | rendered.push(rx.recv().await); 62 | } 63 | 64 | info!("[{}] Rendering success", id.id); 65 | 66 | let output = match request.get_ref().clone().r#type.unwrap() { 67 | Type::Individual(req) => Ok(Self::individual_response( 68 | req, 69 | self.config.clone(), 70 | rendered, 71 | request.get_ref().clone().subject, 72 | ) 73 | .await), 74 | Type::Combined(req) => Ok(Self::combined_response( 75 | req, 76 | self.config.clone(), 77 | rendered, 78 | request.get_ref().clone().subject, 79 | ) 80 | .await), 81 | }; 82 | 83 | return output; 84 | } 85 | 86 | async fn info(&self, _: Request) -> Result, Status> { 87 | let version = headless_chrome::Browser::default() 88 | .expect("failed opening browser") 89 | .get_version() 90 | .expect("failed fetching version"); 91 | Ok(Response::new(InfoResponse { 92 | chrome: Some(ChromeVersion { 93 | js_version: version.js_version, 94 | product: version.product, 95 | protocol_version: version.protocol_version, 96 | revision: version.revision, 97 | user_agent: version.user_agent, 98 | }), 99 | })) 100 | } 101 | } 102 | 103 | impl PDFServer { 104 | async fn individual_response( 105 | req: IndividualRequest, 106 | config: Config, 107 | rendered: Vec>, 108 | subject: Option, 109 | ) -> Response { 110 | let mut out = Vec::with_capacity(rendered.len()); 111 | 112 | for (i, opt) in rendered.iter().enumerate() { 113 | match opt { 114 | None => { 115 | out.push(ResponsePayloadWithStatus { 116 | status: Some(status::Status { 117 | id: None, 118 | code: Some(500), 119 | message: Some("unknown error".to_string()), 120 | }), 121 | payload: None, 122 | }); 123 | } 124 | Some(response) => match response { 125 | Err(err) => { 126 | out.push(ResponsePayloadWithStatus { 127 | status: Some(status::Status { 128 | id: None, 129 | code: Some(400), 130 | message: Some(format!("rendering failed: {}", err)), 131 | }), 132 | payload: None, 133 | }); 134 | } 135 | Ok(data) => { 136 | let output = req.data[i].output.clone(); 137 | 138 | let mut out_data = data.clone(); 139 | if output.is_some() { 140 | out_data = add_pdf_metadata( 141 | out_data.clone(), 142 | output.clone().unwrap().meta_data, 143 | ) 144 | .expect("failed adding meta"); 145 | } 146 | 147 | out.push( 148 | Self::construct_response( 149 | config.clone(), 150 | out_data.clone(), 151 | output, 152 | subject.clone(), 153 | ) 154 | .await, 155 | ) 156 | } 157 | }, 158 | } 159 | } 160 | 161 | Response::new(RenderingResponse { 162 | operation_status: Some(OperationStatus { 163 | code: Some(200), 164 | message: Some("success".to_string()), 165 | }), 166 | response: Some(rendering_response::Response::Individual( 167 | IndividualResponse { 168 | rendering_response: out, 169 | }, 170 | )), 171 | }) 172 | } 173 | 174 | async fn combined_response( 175 | req: CombinedRequest, 176 | config: Config, 177 | rendered: Vec>, 178 | subject: Option, 179 | ) -> Response { 180 | let mut merged = merge_pdfs( 181 | rendered 182 | .iter() 183 | .map(|x| match x { 184 | None => { 185 | panic!("missing pdf") 186 | } 187 | Some(r) => match r { 188 | Err(err) => { 189 | panic!("missing pdf: {}", err) 190 | } 191 | Ok(response) => Document::load_mem(response).expect("failed parsing PDF"), 192 | }, 193 | }) 194 | .collect(), 195 | ) 196 | .expect("render failed"); 197 | 198 | if req.output.is_some() { 199 | merged = add_pdf_metadata(merged, req.output.clone().unwrap().meta_data) 200 | .expect("failed adding meta"); 201 | } 202 | 203 | Response::new(RenderingResponse { 204 | operation_status: Some(OperationStatus { 205 | code: Some(200), 206 | message: Some("success".to_string()), 207 | }), 208 | response: Some(rendering_response::Response::Combined( 209 | Self::construct_response( 210 | config.clone(), 211 | merged.clone(), 212 | req.output.clone(), 213 | subject, 214 | ) 215 | .await, 216 | )), 217 | }) 218 | } 219 | 220 | async fn construct_response( 221 | config: Config, 222 | data: Vec, 223 | output: Option, 224 | subject: Option, 225 | ) -> ResponsePayloadWithStatus { 226 | if output.clone().is_some() && output.clone().unwrap().upload_options.is_some() { 227 | match upload_to_s3( 228 | config.clone(), 229 | output.unwrap().upload_options.unwrap(), 230 | data.clone(), 231 | subject, 232 | ) 233 | .await 234 | { 235 | Ok(_) => ResponsePayloadWithStatus { 236 | status: Some(status::Status { 237 | id: None, 238 | code: Some(200), 239 | message: Some("success".to_string()), 240 | }), 241 | payload: Some(ResponsePayload { 242 | response: Some(response_payload::Response::UploadResult( 243 | ResponseS3Upload { 244 | length: data.len() as i32, 245 | url: "n/a".to_string(), 246 | }, 247 | )), 248 | }), 249 | }, 250 | Err(err) => ResponsePayloadWithStatus { 251 | status: Some(status::Status { 252 | id: None, 253 | code: Some(400), 254 | message: Some(format!("render failed: {}", err)), 255 | }), 256 | payload: None, 257 | }, 258 | } 259 | } else { 260 | ResponsePayloadWithStatus { 261 | status: Some(status::Status { 262 | id: None, 263 | code: Some(200), 264 | message: Some("success".to_string()), 265 | }), 266 | payload: Some(ResponsePayload { 267 | response: Some(response_payload::Response::Pdf(ResponsePdf { 268 | data: data.clone(), 269 | })), 270 | }), 271 | } 272 | } 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /src/types.rs: -------------------------------------------------------------------------------- 1 | use crate::proto::pdf_rendering::RenderData; 2 | use std::error::Error; 3 | use tokio::sync::mpsc; 4 | 5 | pub struct InternalRequest { 6 | pub data: Vec, 7 | pub response: mpsc::Sender, 8 | } 9 | 10 | pub type InternalResponse = anyhow::Result, Box>; 11 | 12 | pub struct RendererResponse { 13 | pub resp: InternalResponse, 14 | pub order: usize, 15 | } 16 | 17 | #[derive(Copy, Clone)] 18 | pub struct IDExtension { 19 | pub id: ulid::Ulid, 20 | } 21 | --------------------------------------------------------------------------------