diff --git a/.forgejo/workflows/build+release.yml b/.forgejo/workflows/build+release.yml new file mode 100644 index 0000000..c473e32 --- /dev/null +++ b/.forgejo/workflows/build+release.yml @@ -0,0 +1,91 @@ +name: 'Build and Release Binary File' +author: 'Neshura' + +on: + push: + tags: + - '[0-9]+.[0-9]+.[0-9]+' + - '[0-9]+.[0-9]+.[0-9]+rc[0-9]+' +jobs: + test: + runs-on: docker + steps: + - + name: Checking Out Repository Code + uses: https://code.forgejo.org/actions/checkout@v3 + - + name: Placeholder + run: echo Placeholder Job + - + name: Check if Version in Cargo.toml matches Tag + run: | + VERSION=$(cat Cargo.toml | grep -E "(^|\|)version =" | cut -f2- -d= | tr -d \" | tr -d " ") + if test $VERSION != "${{ github.ref_name }}"; then + echo "Expected Version is: '${{ github.ref_name }}' actual Version is: '$VERSION'"; + exit 1 + else + echo "Version is: '$VERSION'"; + fi + + build: + needs: test + if: success() + runs-on: docker + container: rust:latest + steps: + - + name: Installing Node + run: apt update && apt install -y nodejs + - + name: Checking Out Repository Code + uses: https://code.forgejo.org/actions/checkout@v3 + - + name: Preparing Environment + run: | + echo DATABASE_URL=${{ secrets.DATABASE_URL }} >> .env + echo MACHINE_GROUP_ID=${{ vars.MACHINE_GROUP_ID }} >> .env + echo UPTIME_KUMA_URL= >> .env + - + name: Compiling To Linux Target + run: | + cargo build -r + mv target/release/chellaris-rust-api chellaris-rust-api-linux-amd64 + - + name: Uploading Build Artifact + uses: actions/upload-artifact@v3 + with: + name: chellaris-rust-api-linux-amd64 + path: chellaris-rust-api-linux-amd64 + if-no-files-found: error + + upload-release: + needs: build + if: success() + runs-on: docker + steps: + - + name: Downloading All Build Artifacts + uses: actions/download-artifact@v3 + - + name: Rearrange Artifact Paths + run: | + mkdir release + mv chellaris-rust-api-linux-amd64/chellaris-rust-api-linux-amd64 release/chellaris-rust-api-linux-amd64 + - + name: Upload Artifacts As Generic Packages + run: | + echo 'curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \ + --upload-file release/chellaris-rust-api-linux-amd64 \ + https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/generic/${{ github.event.repository.name }}/${{ github.ref_name }}/chellaris-rust-api-linux-amd64' + curl -v --user ${{ secrets.FORGEJO_USERNAME }}:${{ secrets.FORGEJO_TOKEN }} \ + --upload-file release/chellaris-rust-api-linux-amd64 \ + https://forgejo.neshweb.net/api/packages/${{ secrets.FORGEJO_USERNAME }}/generic/${{ github.event.repository.name }}/${{ github.ref_name }}/chellaris-rust-api-linux-amd64 + - + name: Release New Version + uses: actions/forgejo-release@v1 + with: + direction: upload + url: https://forgejo.neshweb.net + release-dir: release + token: ${{ secrets.FORGEJO_TOKEN }} + tag: ${{ github.ref_name }} diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml new file mode 100644 index 0000000..637f42a --- /dev/null +++ b/.forgejo/workflows/test.yml @@ -0,0 +1,16 @@ +name: 'Run Tests on Code' +author: 'Neshura' + +on: + push: + tags-ignore: + - '**' + branches: + - '**' +jobs: + run-tests: + runs-on: docker + steps: + - + name: Placeholder + run: echo Placeholder Job \ No newline at end of file diff --git a/.gitignore b/.gitignore index ecdc5b9..14602bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /target +/.vscode +/.idea config.toml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 20c400c..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,68 +0,0 @@ -image: 3.10.8-slim-buster - -variables: - PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/linux/$CI_COMMIT_TAG/" - -.deploy: - rules: - # Regex magic copied from Neshura/page-test, only deploys on x.y.z or higher (x.y) Tags - - if: $CI_COMMIT_TAG =~ /^((([\d])+\.){1,2}[\d]+)\s*$/ && $CI_COMMIT_TAG - -stages: - - build - - upload - - release - -## Docker steps - -build: - image: rust:latest - stage: build - - variables: - IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_BRANCH - CACHING: - script: - - echo "Compiling the code..." - - cargo build -r - - echo "Compile complete." - after_script: - - echo JOB_ID=$CI_JOB_ID >> job.env - - mkdir ./artifacts - - cp /builds/Neshura/chellaris-rust-api/target/release/chellaris-rust-api ./artifacts/ - artifacts: - paths: - - ./artifacts/ - reports: - dotenv: job.env - rules: - - !reference [.deploy, rules] - -upload: - needs: - - job: build - artifacts: true - image: curlimages/curl:latest - stage: upload - script: - - | - curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file artifacts/chellaris-rust-api "${PACKAGE_REGISTRY_URL}/chellaris-rust-api" - rules: - - !reference [.deploy, rules] - - -Tag Release: - stage: release - image: registry.gitlab.com/gitlab-org/release-cli:latest - rules: - - !reference [.deploy, rules] - script: - - apk add curl - - echo "running Release Job, attaching Artifact from Job $JOB_ID" - release: - tag_name: '$CI_COMMIT_TAG' - description: '$CI_COMMIT_TAG' - assets: - links: - - name: "chellaris-rust-api" - url: "${PACKAGE_REGISTRY_URL}/chellaris-rust-api" diff --git a/Cargo.lock b/Cargo.lock index 93c78fa..ca617a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,17 +21,17 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2079246596c18b4a33e274ae10c0e50613f4d32a4198e09c7b93771013fed74" +checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9" dependencies = [ "actix-codec", "actix-rt", "actix-service", "actix-utils", - "ahash 0.8.3", + "ahash", "base64", - "bitflags 1.3.2", + "bitflags 2.4.0", "brotli", "bytes", "bytestring", @@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.3.1" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3cb42f9566ab176e1ef0b8b3a896529062b4efc6be0123046095914c4c1c96" +checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" dependencies = [ "actix-codec", "actix-http", @@ -145,7 +145,7 @@ dependencies = [ "actix-service", "actix-utils", "actix-web-codegen", - "ahash 0.7.6", + "ahash", "bytes", "bytestring", "cfg-if", @@ -154,7 +154,6 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "http", "itoa", "language-tags", "log", @@ -166,8 +165,8 @@ dependencies = [ "serde_json", "serde_urlencoded", "smallvec", - "socket2 0.4.9", - "time 0.3.27", + "socket2 0.5.5", + "time", "url", ] @@ -200,25 +199,15 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "ahash" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -275,6 +264,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-write-file" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" +dependencies = [ + "nix", + "rand", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -398,37 +397,39 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chellaris-rust-api" -version = "0.1.0" +version = "1.2.4" dependencies = [ "actix-web", "chrono", "ctrlc", - "dotenv", - "dotenv_codegen", + "dotenvy", + "dotenvy_macro", "env_logger", + "rand", + "reqwest", "schemars", "serde", "serde_json", "sqlx", "tokio", "toml", + "url", "utoipa", "utoipa-swagger-ui", ] [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets", ] [[package]] @@ -450,10 +451,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.27", + "time", "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -524,9 +535,9 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" +checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" dependencies = [ "nix", "windows-sys", @@ -594,41 +605,24 @@ dependencies = [ "winapi", ] -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "dotenv_codegen" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56966279c10e4f8ee8c22123a15ed74e7c8150b658b26c619c53f4a56eb4a8aa" -dependencies = [ - "dotenv_codegen_implementation", - "proc-macro-hack", -] - -[[package]] -name = "dotenv_codegen_implementation" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e737a3522cd45f6adc19b644ce43ef53e1e9045f2d2de425c1f468abd4cf33" -dependencies = [ - "dotenv", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "dotenvy" version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "dotenvy_macro" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0235d912a8c749f4e0c9f18ca253b4c28cfefc1d2518096016d6e3230b6424" +dependencies = [ + "dotenvy", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "dyn-clone" version = "1.0.13" @@ -655,9 +649,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ "humantime", "is-terminal", @@ -728,13 +722,12 @@ dependencies = [ [[package]] name = "flume" -version = "0.10.14" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ "futures-core", "futures-sink", - "pin-project", "spin 0.9.8", ] @@ -745,10 +738,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "form_urlencoded" -version = "1.2.0" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -843,7 +851,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -883,7 +891,7 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" dependencies = [ - "ahash 0.8.3", + "ahash", "allocator-api2", ] @@ -955,6 +963,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.8.0" @@ -973,6 +992,43 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.57" @@ -998,9 +1054,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1027,6 +1083,12 @@ dependencies = [ "serde", ] +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + [[package]] name = "is-terminal" version = "0.4.9" @@ -1088,9 +1150,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libm" @@ -1100,9 +1162,9 @@ checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "libsqlite3-sys" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" dependencies = [ "cc", "pkg-config", @@ -1197,26 +1259,43 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys", ] [[package]] -name = "nix" -version = "0.26.2" +name = "native-tls" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ - "bitflags 1.3.2", + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.4.0", "cfg-if", "libc", - "static_assertions", ] [[package]] @@ -1302,6 +1381,50 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl" +version = "0.10.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +dependencies = [ + "bitflags 2.4.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1342,29 +1465,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" - -[[package]] -name = "pin-project" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.29", -] +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" @@ -1435,12 +1538,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.66" @@ -1547,6 +1644,44 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + [[package]] name = "rsa" version = "0.9.2" @@ -1571,9 +1706,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "6.8.1" +version = "8.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" +checksum = "810294a8a4a0853d4118e3b94bb079905f2107c7fe979d8f0faae98765eb6378" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -1582,23 +1717,23 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "6.8.1" +version = "8.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" +checksum = "bfc144a1273124a67b8c1d7cd19f5695d1878b31569c0512f6086f0f4676604e" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", "shellexpand", - "syn 2.0.29", + "syn 2.0.32", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "7.8.1" +version = "8.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" +checksum = "816ccd4875431253d6bb54b804bcff4369cbde9bae33defde25fdf6c2ef91d40" dependencies = [ "sha2", "walkdir", @@ -1648,10 +1783,19 @@ dependencies = [ ] [[package]] -name = "schemars" -version = "0.8.12" +name = "schannel" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -1661,9 +1805,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -1677,6 +1821,29 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.18" @@ -1685,22 +1852,22 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.185" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.185" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc59dfdcbad1437773485e0367fea4b090a2e0a16d9ffc46af47764536a298ec" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -1716,9 +1883,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1727,9 +1894,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" dependencies = [ "serde", ] @@ -1770,9 +1937,9 @@ dependencies = [ [[package]] name = "shellexpand" -version = "2.1.2" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" dependencies = [ "dirs", ] @@ -1823,9 +1990,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys", @@ -1869,9 +2036,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e58421b6bc416714d5115a2ca953718f6c621a51b68e4f4922aea5a4391a721" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" dependencies = [ "sqlx-core", "sqlx-macros", @@ -1882,11 +2049,11 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4cef4251aabbae751a3710927945901ee1d97ee96d757f6880ebb9a79bfd53" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" dependencies = [ - "ahash 0.8.3", + "ahash", "atoi", "byteorder", "bytes", @@ -1922,9 +2089,9 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "208e3165167afd7f3881b16c1ef3f2af69fa75980897aac8874a0696516d12c2" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" dependencies = [ "proc-macro2", "quote", @@ -1935,10 +2102,11 @@ dependencies = [ [[package]] name = "sqlx-macros-core" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a4a8336d278c62231d87f24e8a7a74898156e34c1c18942857be2acb29c7dfc" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" dependencies = [ + "atomic-write-file", "dotenvy", "either", "heck", @@ -1961,9 +2129,9 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca69bf415b93b60b80dc8fda3cb4ef52b2336614d8da2de5456cc942a110482" +checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" dependencies = [ "atoi", "base64", @@ -2003,9 +2171,9 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0db2df1b8731c3651e204629dd55e52adbae0462fa1bdcbed56a2302c18181e" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" dependencies = [ "atoi", "base64", @@ -2042,9 +2210,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2" +checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" dependencies = [ "atoi", "flume", @@ -2060,14 +2228,9 @@ dependencies = [ "sqlx-core", "tracing", "url", + "urlencoding", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "stringprep" version = "0.1.3" @@ -2097,15 +2260,36 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.29" +version = "2.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" version = "3.8.0" @@ -2145,18 +2329,7 @@ checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", -] - -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", + "syn 2.0.32", ] [[package]] @@ -2204,21 +2377,44 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ "backtrace", "bytes", "libc", "mio", + "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.3", + "socket2 0.5.5", + "tokio-macros", "windows-sys", ] +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.14" @@ -2246,9 +2442,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", @@ -2258,18 +2454,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap 2.0.0", "serde", @@ -2278,6 +2474,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.37" @@ -2299,7 +2501,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] @@ -2311,6 +2513,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + [[package]] name = "typenum" version = "1.16.0" @@ -2361,9 +2569,9 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "url" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -2371,10 +2579,16 @@ dependencies = [ ] [[package]] -name = "utoipa" -version = "3.5.0" +name = "urlencoding" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82b1bc5417102a73e8464c686eef947bdfb99fcdfc0a4f228e81afa9526470a" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utoipa" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ff05e3bac2c9428f57ade702667753ca3f5cf085e2011fe697de5bfd49aa72d" dependencies = [ "indexmap 2.0.0", "serde", @@ -2384,22 +2598,22 @@ dependencies = [ [[package]] name = "utoipa-gen" -version = "3.5.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d96dcd6fc96f3df9b3280ef480770af1b7c5d14bc55192baa9b067976d920c" +checksum = "5f0b6f4667edd64be0e820d6631a60433a269710b6ee89ac39525b872b76d61d" dependencies = [ "proc-macro-error", "proc-macro2", "quote", "regex", - "syn 2.0.29", + "syn 2.0.32", ] [[package]] name = "utoipa-swagger-ui" -version = "3.1.5" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84614caa239fb25b2bb373a52859ffd94605ceb256eeb1d63436325cf81e3653" +checksum = "f839caa8e09dddc3ff1c3112a91ef7da0601075ba5025d9f33ae99c4cb9b6e51" dependencies = [ "actix-web", "mime_guess", @@ -2434,10 +2648,13 @@ dependencies = [ ] [[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +name = "want" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] [[package]] name = "wasi" @@ -2466,10 +2683,22 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.87" @@ -2488,7 +2717,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.32", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2499,6 +2728,16 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "whoami" version = "1.4.1" @@ -2620,6 +2859,36 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys", +] + +[[package]] +name = "zerocopy" +version = "0.7.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "zeroize" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index 4d071ee..f901372 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,25 @@ [package] name = "chellaris-rust-api" -version = "0.1.0" +version = "1.2.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -actix-web = "4.3.1" -chrono = "0.4.26" -ctrlc = "3.4.0" -dotenv = "0.15.0" -dotenv_codegen = "0.15.0" -env_logger = "0.10.0" -schemars = "0.8.10" -serde = { version = "1.0.185", features = ["derive"] } -serde_json = "1.0.105" -sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio"] } -tokio = { version = "1.32.0", features = ["rt"] } -toml = "0.7.6" -utoipa = { version = "3.5.0", features = ["actix_extras", "non_strict_integers"] } -utoipa-swagger-ui = { version = "3.1.5", features = ["actix-web"] } +actix-web = "4.4.0" +chrono = "0.4.31" +ctrlc = "3.4.1" +dotenvy = "0.15.7" +dotenvy_macro = "0.15.7" +env_logger = "0.10.1" +reqwest = "0.11.22" +schemars = "0.8.16" +serde = { version = "1.0.193", features = ["derive"] } +serde_json = "1.0.108" +sqlx = { version = "0.7.3", features = ["postgres", "runtime-tokio"] } +tokio = { version = "1.35.0", features = ["rt", "rt-multi-thread", "macros", "time"] } +toml = "0.8.8" +utoipa = { version = "4.1.0", features = ["actix_extras", "non_strict_integers"] } +utoipa-swagger-ui = { version = "5.0.0", features = ["actix-web"] } +rand = "0.8.5" +url = "2.5.0" diff --git a/package.json b/package.json deleted file mode 100644 index 2bb8783..0000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "sqlx": "^4.3.2" - } -} diff --git a/src/db/mod.rs b/src/db/mod.rs index 7c8e632..0f2302c 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,5 +1 @@ -use std::error::Error; - -use sqlx::{Postgres, postgres::PgConnectOptions, PgPool, Pool}; - pub(crate) mod schemas; \ No newline at end of file diff --git a/src/db/schemas.rs b/src/db/schemas.rs index 88525ad..9604b78 100644 --- a/src/db/schemas.rs +++ b/src/db/schemas.rs @@ -33,7 +33,7 @@ pub struct GameGroup { pub struct Ethic { pub id: i32, pub name: String, - pub machine_ethic: bool, + pub gestalt_ethic: bool, } #[derive(Serialize, ToSchema, Debug, FromRow)] @@ -42,10 +42,15 @@ pub struct Empire { pub group_id: i32, pub game_id: i32, pub name: String, - pub discord_user: Option<String>, pub gestalt: bool, pub portrait_id: i32, pub portrait_group_id: i32, + pub backstory: String, + pub goals: String, + pub interactions: String, + pub available: bool, + pub approval_status: Option<bool>, + pub users_id: i32, } #[derive(Serialize, ToSchema, Debug, FromRow)] @@ -55,3 +60,15 @@ pub struct EmpireEthic { pub ethics_id: i32, pub fanatic: bool, } + +#[derive(Serialize, ToSchema, Debug, FromRow)] +pub struct User { + pub id: i32, + pub token: String, + pub discord_id: Option<String>, + pub picture_url: Option<String>, + pub game_permissions: bool, + pub empire_permissions: bool, + pub data_permissions: bool, + pub user_permissions: bool, +} diff --git a/src/main.rs b/src/main.rs index d8da6f8..6a3a574 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,24 @@ #[macro_use] -extern crate dotenv_codegen; -extern crate dotenv; +extern crate dotenvy_macro; +extern crate dotenvy; -use dotenv::dotenv; +use dotenvy::dotenv; use tokio::time::sleep; -use std::{env, error::Error, fs, net::Ipv4Addr, net::Ipv6Addr, thread, time::Duration, sync::{Mutex, Arc, atomic::{AtomicBool, Ordering}}}; +use std::{env, fs, net::Ipv4Addr, net::Ipv6Addr, time::Duration, sync::{Arc, atomic::{AtomicBool, Ordering}}}; +use std::process::abort; use chrono::Local; -use actix_web::{middleware::Logger, web, App, HttpServer, Result}; +use actix_web::{middleware::Logger, web, App, HttpServer}; use serde::{Deserialize, Serialize}; use sqlx::{PgPool, Pool, Postgres, Connection}; +use tokio::signal::unix::SignalKind; use utoipa::{OpenApi, openapi::security::{SecurityScheme, ApiKey, ApiKeyValue}, Modify}; use utoipa_swagger_ui::{Config, SwaggerUi, Url}; mod db; +mod v1; mod v2; mod v3; @@ -25,21 +28,33 @@ macro_rules! api_base { }; } +macro_rules! api_base_1 { + () => { + "/api/v1" + }; +} + macro_rules! api_base_2 { () => { - "/api/v2" + "/api/v2-l" }; } macro_rules! api_base_3 { () => { - "/api/v3" + "/api/v3-l" }; } #[derive(Serialize, Deserialize, Debug, Clone)] pub(crate) struct ConfigToml { auth: AuthenticationTokens, + port: PortConfig, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub(crate) struct PortConfig { + default: u16, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -53,11 +68,8 @@ pub struct AppState { auth_tokens: AuthenticationTokens, } -async fn postgres_watchdog(pool: PgPool, is_alive: Arc<AtomicBool>, shutdown: Arc<AtomicBool>) { - loop { - if shutdown.load(Ordering::Relaxed) { - break; - } +async fn postgres_watchdog(pool: PgPool, shutdown: Arc<AtomicBool>) { + while !shutdown.load(Ordering::Relaxed) { let start = Local::now(); let mut conn = match pool.acquire().await { @@ -70,27 +82,32 @@ async fn postgres_watchdog(pool: PgPool, is_alive: Arc<AtomicBool>, shutdown: Ar Err(_) => {println!("Error pinging Server"); break;}, }; - let passed = (Local::now() - start).to_std().expect(&format!("Unable to get Time Difference for '{}' and '{}'", start, Local::now())); + let url = dotenvy::var("UPTIME_KUMA_URL").unwrap_or("".to_string()); + if url != "" { + match reqwest::get( + url, + ).await { + Ok(_) => {} + Err(err) => println!("{}", err), + }; + } + else { + println!("No Uptime Kuma URL provided!"); + } - sleep(Duration::from_secs(15) - passed).await; + while Local::now() - start < chrono::Duration::seconds(15) { + sleep(Duration::from_millis(100)).await; + } } - is_alive.store(false, Ordering::Relaxed); } #[actix_web::main] -async fn main() -> Result<()> { +async fn main() { env_logger::init(); dotenv().ok(); let shutdown: Arc<AtomicBool> = Arc::new(AtomicBool::new(false)); - let shutdown_clone = Arc::clone(&shutdown); - ctrlc::set_handler(move || { - eprintln!("Ctrl-C received"); - shutdown_clone.store(true, Ordering::Relaxed) - }) - .expect("Error setting Ctrl-C handler"); - let toml_str = fs::read_to_string("config.toml").expect("Failed to read config.toml"); let config: ConfigToml = toml::from_str(&toml_str).expect("Failed to parse config.toml"); @@ -148,7 +165,9 @@ async fn main() -> Result<()> { v3::get_empire, v3::create_empire, v3::edit_empire, - v3::delete_empire + v3::delete_empire, + v3::get_ethics, + v3::get_phenotypes ), components(schemas( v3::schemas::AuthReturn, @@ -165,15 +184,17 @@ async fn main() -> Result<()> { v3::schemas::DeleteEmpireParams, v3::schemas::FullViewData, v3::schemas::Ethic, + v3::schemas::ChellarisEthics, v3::schemas::EmpireEthic, v3::schemas::EmpireEthicLegacy, v3::schemas::ChellarisGameLegacy, v3::schemas::ChellarisGameFlat, v3::schemas::ChellarisGame, - v3::schemas::Species, + v3::schemas::Phenotype, + v3::schemas::ChellarisPhenotypes, v3::schemas::ChellarisGameGroupLegacy, v3::schemas::ChellarisGroupFlat, - v3::schemas::Portrait, + v3::schemas::Species, v3::schemas::ChellarisEmpireLegacy, v3::schemas::ChellarisEmpireFlat, v3::schemas::ChellarisEmpire @@ -182,27 +203,64 @@ async fn main() -> Result<()> { )] struct ApiDocV3; - let openapi_urls = vec![ - Url::new("v2", concat!(api_base_2!(), "/openapi.json")), - Url::new("v3", concat!(api_base_3!(), "/openapi.json")), - ]; + #[derive(OpenApi)] + #[openapi( + paths( + v1::get_user, + v1::create_user, + v1::update_user, + v1::delete_user + ), + components(schemas( + v1::schemas::GetUserParams, + v1::schemas::UpdateUserParams, + v1::schemas::DeleteUserParams, + v1::schemas::User + )) + )] + struct ApiDocV1; - let is_alive: Arc<AtomicBool> = Arc::new(AtomicBool::new(true)); + let openapi_urls = vec![ + Url::new("v1", concat!(api_base!(), "-docs/openapi1.json")), + Url::new("v2-L", concat!(api_base!(), "-docs/openapi2l.json")), + Url::new("v3-L", concat!(api_base!(), "-docs/openapi3l.json")), + ]; loop { let db_auth_tokens = config.auth.clone(); let pool = PgPool::connect(dotenv!("DATABASE_URL")).await.unwrap(); + let pool_copy = pool.clone(); + let shutdown_clone = shutdown.clone(); let swagger_config = Config::new(openapi_urls.clone()); - let mut openapi_v2 = ApiDocV2::openapi(); - openapi_v2.info.title = "Chellaris Rust API".to_string(); - - let mut openapi_v3 = ApiDocV3::openapi(); - openapi_v3.info.title = "Chellaris Rust API".to_string(); + let mut openapi_v1 = ApiDocV1::openapi(); + openapi_v1.info.title = "Chellaris Rust API v1".to_string(); - let server = HttpServer::new(move || { + let mut openapi_v2_l = ApiDocV2::openapi(); + openapi_v2_l.info.title = "Legacy Chellaris Rust API v2".to_string(); + + let mut openapi_v3_l = ApiDocV3::openapi(); + openapi_v3_l.info.title = "Legacy Chellaris Rust API v3".to_string(); + + println!("Serving API on: "); + println!(" -> http://[{}]:{}", Ipv6Addr::UNSPECIFIED, 8080); + println!(" -> http://{}:{}", Ipv4Addr::UNSPECIFIED, 8080); + + let watchdog_thread = tokio::spawn(async move { postgres_watchdog(pool_copy, shutdown_clone).await }); + tokio::spawn(async move { + actix_web::rt::signal::unix::signal(SignalKind::terminate()).unwrap().recv().await; + println!("SIGTERM received, killing Server"); + abort() + }); + tokio::spawn(async move { + actix_web::rt::signal::unix::signal(SignalKind::interrupt()).unwrap().recv().await; + println!("SIGINT received, killing Server"); + abort() + }); + + let _ = HttpServer::new(move || { App::new() .app_data(web::Data::new(AppState { db: pool.clone(), auth_tokens: db_auth_tokens.clone() })) .wrap(Logger::default()) @@ -229,56 +287,43 @@ async fn main() -> Result<()> { .service(v3::create_empire) .service(v3::edit_empire) .service(v3::delete_empire) + .service(v3::get_ethics) + .service(v3::get_phenotypes) + // API v1 Endpoints + .service(v1::get_user) + .service(v1::create_user) + .service(v1::update_user) + .service(v1::delete_user) // Swagger UI .service( SwaggerUi::new(concat!(api_base!(), "/swagger/{_:.*}")) .urls(vec![ ( - Url::new("v2", concat!(api_base_2!(), "/openapi.json")), - openapi_v2.clone(), + Url::new("v1", concat!(api_base!(), "-docs/openapi1.json")), + openapi_v1.clone(), ), ( - Url::new("v3", concat!(api_base_3!(), "/openapi.json")), - openapi_v3.clone(), + Url::new("v2-l", concat!(api_base!(), "-docs/openapi2l.json")), + openapi_v2_l.clone(), + ), + ( + Url::new("v3-l", concat!(api_base!(), "-docs/openapi3l.json")), + openapi_v3_l.clone(), ), ]) .config(swagger_config.clone()), ) }) - .bind((Ipv6Addr::UNSPECIFIED, 8080)).expect("Port or IP already occupied") - .run(); + .bind((Ipv6Addr::UNSPECIFIED, config.port.default)).expect("Port or IP already occupied") + .run() + .await; - let server_thread = tokio::spawn(async { - println!("Awaiting server"); - let _ = server.await; - println!("Stopped awaiting server"); - }); + watchdog_thread.abort(); - println!("Started Serving API on: "); - println!(" -> http://[{}]:{}", Ipv6Addr::UNSPECIFIED, 8080); - println!(" -> http://{}:{}", Ipv4Addr::UNSPECIFIED, 8080); + sleep(Duration::from_secs(10)).await; - let is_alive_clone = Arc::clone(&is_alive); - let shutdown_clone = Arc::clone(&shutdown); - let _ = tokio::spawn(async move { postgres_watchdog(pool_copy, is_alive_clone, shutdown_clone).await }); - - //watchdog_thread.await; + println!("Service crashed due to unexpected Error, restarting thread after wait..."); - while is_alive.load(Ordering::Relaxed) { - let thread = tokio::spawn(async { - sleep(Duration::from_millis(100)); - }); - - let _ = thread.await; - } - - if shutdown.load(Ordering::Relaxed) { - break; - } - - eprintln!("Connection died, restarting Server"); - server_thread.abort(); + sleep(Duration::from_secs(10)).await; } - - Ok(()) } diff --git a/src/v1/mod.rs b/src/v1/mod.rs new file mode 100644 index 0000000..4c0fb1b --- /dev/null +++ b/src/v1/mod.rs @@ -0,0 +1,369 @@ +use crate::{db, AppState}; +use actix_web::{delete, get, post, put, web, HttpRequest, HttpResponse, Responder}; +use std::collections::HashMap; +use std::ops::Deref; +use rand::distributions::Alphanumeric; +use rand::{Rng, thread_rng}; +use sqlx::QueryBuilder; + +pub(crate) mod schemas; + +fn get_auth_header(req: &HttpRequest) -> Option<&str> { + req.headers().get("x-api-key")?.to_str().ok() +} + +async fn verify_user_auth(data: &web::Data<AppState>, auth_token: &str, user_token: &str, table: schemas::TablePermission, permissions_only: bool) -> bool { + let user: db::schemas::User = match sqlx::query_as!( + db::schemas::User, + "SELECT * FROM public.users WHERE token = $1", + auth_token + ) + .fetch_one(&data.db) + .await + { + Ok(data) => data, + Err(_) => return false, + }; + + if user.token == user_token && !permissions_only { + return true; + } + else { + match table { + schemas::TablePermission::Game => { + return user.data_permissions; + }, + schemas::TablePermission::Empire => { + return user.empire_permissions; + }, + schemas::TablePermission::Data => { + return user.data_permissions; + }, + schemas::TablePermission::User => { + return user.user_permissions; + }, + } + } +} + +// User Endpoints +#[utoipa::path( + request_body = GetUserParams, + responses( + (status = 200, description = "OK", body = User), + (status = 403, description = "Unauthorized"), + (status = 500, description = "Internal Server Error") + ), + security( + ("api_key" = []) + ), +)] +#[post("/api/v1/user")] +pub(crate) async fn get_user( + data: web::Data<AppState>, + params: web::Json<schemas::GetUserParams>, + req: HttpRequest, +) -> impl Responder { + let auth_header = get_auth_header(&req); + let params = params.into_inner(); + + let auth_token: String; + + match auth_header { + Some(token) => auth_token = token.to_string(), + None => return HttpResponse::Unauthorized().finish(), + }; + + let auth = verify_user_auth(&data, &auth_token, ¶ms.user_token, schemas::TablePermission::User, false).await; + + if auth { + let user: db::schemas::User = match sqlx::query_as!( + db::schemas::User, + "SELECT * FROM public.users WHERE token = $1", + params.user_token + ) + .fetch_one(&data.db) + .await + { + Ok(data) => data, + Err(_) => return HttpResponse::InternalServerError().finish(), + }; + + let mut user_permissions: HashMap<String, bool> = HashMap::new(); + + user_permissions.insert("game_permissions".to_string(), user.game_permissions); + user_permissions.insert("empire_permissions".to_string(), user.empire_permissions); + user_permissions.insert("data_permissions".to_string(), user.data_permissions); + user_permissions.insert("user_permissions".to_string(), user.user_permissions); + + let return_data = schemas::User { + user_token: user.token, + discord_handle: user.discord_id, + profile_picture: user.picture_url, + permissions: user_permissions + }; + + return HttpResponse::Ok().json(return_data); + } + else { + return HttpResponse::Unauthorized().finish(); + } +} + +#[utoipa::path( + responses( + (status = 200, description = "OK", body = User), + (status = 500, description = "Internal Server Error") + ), +)] +#[post("/api/v1/user/create")] +pub(crate) async fn create_user( + data: web::Data<AppState>, +) -> impl Responder { + let user: db::schemas::User; + + let mut rng = thread_rng(); + + let user_tokens = match sqlx::query_scalar!( + "SELECT token FROM public.users" + ) + .fetch_all(&data.db) + .await + { + Ok(data) => data, + Err(_) => return HttpResponse::InternalServerError().finish(), + }; + + let new_token: String; + + loop { + let mut chars: String = (0..6).map(|_| rng.sample(Alphanumeric) as char).collect(); + chars = chars.to_uppercase(); + if !user_tokens.contains(&chars) { + new_token = chars; + break; + } + else { + println!("looping"); + } + } + + user = match sqlx::query_as!( + db::schemas::User, + "INSERT INTO public.users(token, game_permissions, empire_permissions, data_permissions, user_permissions) VALUES ($1, $2, $3, $4, $5) RETURNING * ", + new_token, + false, + false, + false, + false + + ) + .fetch_one(&data.db) + .await + { + Ok(data) => data, + Err(_) => return HttpResponse::InternalServerError().finish(), + }; + + return HttpResponse::Ok().json(user) +} + +#[utoipa::path( + request_body = UpdateUserParams, + responses( + (status = 200, description = "OK"), + (status = 403, description = "Unauthorized"), + (status = 500, description = "Internal Server Error") + ), + security( + ("api_key" = []) + ), +)] +#[put("/api/v1/user")] +pub(crate) async fn update_user( + data: web::Data<AppState>, + params: web::Json<schemas::UpdateUserParams>, + req: HttpRequest, +) -> impl Responder { + let auth_header = get_auth_header(&req); + let params = params.into_inner(); + + let auth_token: String; + + match auth_header { + Some(token) => auth_token = token.to_string(), + None => return HttpResponse::Unauthorized().finish(), + }; + + let mut user_permissions: HashMap<String, bool> = HashMap::new(); + match params.permissions { + Some(data) => {user_permissions = data.clone()}, + None => {}, + } + + let mut elevated_auth = false; + if user_permissions.len() != 0 { + if user_permissions["game_permissions"] || user_permissions["empire_permissions"] || user_permissions["data_permissions"] || user_permissions["user_permissions"] { + elevated_auth = true; + } + } + + let auth = verify_user_auth(&data, &auth_token, ¶ms.user_token, schemas::TablePermission::User, elevated_auth).await; + + // SQL Queries + // TODO: Optimize by utilizing some SQL magic, for now this has to do + if auth { + let user: db::schemas::User; + + let mut user_query = QueryBuilder::<sqlx::Postgres>::new("UPDATE public.users SET "); + let mut user_query_separated = user_query.separated(", "); + let mut any_param_present = false; + + if let Some(discord_handle) = params.discord_handle { + user_query_separated.push(" discord_id = ").push_bind_unseparated(discord_handle); + any_param_present = true; + } + + if let Some(profile_picture) = params.profile_picture { + user_query_separated.push(" picture_url = "); + match any_param_present { + true => user_query_separated.push_bind(profile_picture), + false => user_query_separated.push_bind_unseparated(profile_picture) + }; + any_param_present = true; + } + + if user_permissions.len() != 0 { + for (entry, value) in user_permissions.iter() { + match entry.deref() { + "game_permissions" => { + user_query_separated.push( " game_permissions = "); + match any_param_present { + true => user_query_separated.push_bind(value), + false => user_query_separated.push_bind_unseparated(value) + }; + any_param_present = true; + }, + "empire_permissions" => { + user_query_separated.push( " empire_permissions = "); + match any_param_present { + true => user_query_separated.push_bind(value), + false => user_query_separated.push_bind_unseparated(value) + }; + any_param_present = true; + }, + "data_permissions" => { + user_query_separated.push( " data_permissions = "); + match any_param_present { + true => user_query_separated.push_bind(value), + false => user_query_separated.push_bind_unseparated(value) + }; + any_param_present = true; + }, + "user_permissions" => { + user_query_separated.push( " user_permissions = "); + match any_param_present { + true => user_query_separated.push_bind(value), + false => user_query_separated.push_bind_unseparated(value) + }; + any_param_present = true; + }, + _ => {} + } + } + } + + if any_param_present { + user_query_separated.push_unseparated(" WHERE token = ").push_bind_unseparated(params.user_token); + user_query_separated.push_unseparated(" RETURNING *"); + + user = match user_query + .build_query_as::<db::schemas::User>() + .fetch_one(&data.db) + .await + { + Ok(data) => data, + Err(_) => return HttpResponse::InternalServerError().finish(), + }; + } else { + user = match sqlx::query_as!( + db::schemas::User, + "SELECT * FROM public.users WHERE token = $1", + params.user_token + ) + .fetch_one(&data.db) + .await + { + Ok(data) => data, + Err(_) => return HttpResponse::InternalServerError().finish(), + }; + } + + let mut user_permissions: HashMap<String, bool> = HashMap::new(); + user_permissions.insert("game_permissions".to_string(), user.game_permissions); + user_permissions.insert("empire_permissions".to_string(), user.empire_permissions); + user_permissions.insert("data_permissions".to_string(), user.data_permissions); + user_permissions.insert("user_permissions".to_string(), user.user_permissions); + + let return_data = schemas::User { + user_token: user.token, + discord_handle: user.discord_id, + profile_picture: user.picture_url, + permissions: user_permissions + }; + return HttpResponse::Ok().json(return_data); + } else { + return HttpResponse::Unauthorized().finish(); + } +} + +#[utoipa::path( + request_body = DeleteUserParams, + responses( + (status = 200, description = "OK"), + (status = 403, description = "Unauthorized"), + (status = 500, description = "Internal Server Error") + ), + security( + ("api_key" = []) + ), +)] +#[delete("/api/v1/user")] +pub(crate) async fn delete_user( + data: web::Data<AppState>, + params: web::Query<schemas::DeleteUserParams>, + req: HttpRequest, +) -> impl Responder { + let auth_header = get_auth_header(&req); + let params = params.into_inner(); + + let auth_token: String; + + match auth_header { + Some(token) => auth_token = token.to_string(), + None => return HttpResponse::Unauthorized().finish(), + }; + + let auth = verify_user_auth(&data, &auth_token, ¶ms.user_token, schemas::TablePermission::User, false).await; + + // SQL Queries + // TODO: Optimize by utilizing some SQL magic, for now this has to do + if auth { + match sqlx::query!( + "DELETE FROM public.users WHERE token = $1", + params.user_token + ) + .execute(&data.db) + .await + { + Ok(_) => {} + Err(_) => { + return HttpResponse::InternalServerError().finish(); + } + }; + + return HttpResponse::Ok().into(); + } else { + return HttpResponse::Unauthorized().finish(); + } +} diff --git a/src/v1/schemas.rs b/src/v1/schemas.rs new file mode 100644 index 0000000..81c23c3 --- /dev/null +++ b/src/v1/schemas.rs @@ -0,0 +1,64 @@ +use std::collections::HashMap; +use serde::{Deserialize, Serialize}; +use utoipa::{IntoParams, ToSchema}; + +// DB Permission Enums + +pub enum TablePermission { + Game, + Empire, + Data, + User +} + +// User Structs + +#[derive(Serialize, ToSchema, Debug)] +pub struct User { + #[schema(example = "abcdef")] + pub user_token: String, + #[schema(example = "discorduser")] + pub discord_handle: Option<String>, + #[schema(example = "/assets/avatars/124677612.png")] + pub profile_picture: Option<String>, + #[schema(example = "\ + {\ + [\"game_permissions\"]: true, + [\"empire_permissions\"]: true, + [\"data_permissions\"]: false, + [\"user_permissions\"]: false, + }\ + ")] + pub permissions: HashMap<String, bool>, +} + +#[derive(Serialize, Deserialize, ToSchema, Debug)] +pub struct GetUserParams { + #[schema(example = "abcdef")] + pub user_token: String, +} + +#[derive(Serialize, Deserialize, ToSchema, Debug)] +pub struct UpdateUserParams { + #[schema(example = "abcdef")] + pub user_token: String, + #[schema(example = "discorduser")] + pub discord_handle: Option<String>, + #[schema(example = "/assets/avatars/124677612.png")] + pub profile_picture: Option<String>, + #[schema(example = "\ + {\ + [\"game_permissions\"]: true, + [\"empire_permissions\"]: true, + [\"data_permissions\"]: false, + [\"user_permissions\"]: false, + }\ + ")] + pub permissions: Option<HashMap<String, bool>>, +} + +#[derive(Serialize, Deserialize, ToSchema, Debug)] +pub struct DeleteUserParams { + #[schema(example = "abcdef")] + pub user_token: String, +} \ No newline at end of file diff --git a/src/v2/mod.rs b/src/v2/mod.rs index 9f37731..1f1f07a 100644 --- a/src/v2/mod.rs +++ b/src/v2/mod.rs @@ -78,7 +78,7 @@ pub(crate) async fn empires( if let Some(auth_token) = params.token.clone() { if auth_token == data.auth_tokens.admin || auth_token == data.auth_tokens.moderator { - new_data.discord_user = entry.discord_user.clone(); + new_data.discord_user = Some("deprecated".to_string()); } } @@ -112,7 +112,7 @@ pub(crate) async fn ethics( db_data.iter().for_each(|entry| { let new_data = schemas::Ethic { id: entry.id, - machine_ethic: entry.machine_ethic, + gestalt_ethic: entry.gestalt_ethic, name: entry.name.clone() }; diff --git a/src/v2/schemas.rs b/src/v2/schemas.rs index e575885..69897e0 100644 --- a/src/v2/schemas.rs +++ b/src/v2/schemas.rs @@ -38,7 +38,7 @@ pub struct GameGroup { pub struct Ethic { pub id: i32, pub name: String, - pub machine_ethic: bool, + pub gestalt_ethic: bool, } #[derive(Serialize, ToSchema, Debug, FromRow)] diff --git a/src/v3/mod.rs b/src/v3/mod.rs index 980e772..f1c414c 100644 --- a/src/v3/mod.rs +++ b/src/v3/mod.rs @@ -5,12 +5,11 @@ use actix_web::{ web::{self, Json}, HttpRequest, HttpResponse, Responder, }; -use sqlx::{Execute, QueryBuilder}; +use sqlx::QueryBuilder; -use crate::{ - db::{self, schemas::EmpireEthic}, - AppState, -}; +use dotenvy; + +use crate::{db, AppState}; pub(crate) mod schemas; @@ -32,7 +31,7 @@ fn verify_auth(token: Option<&str>, data: &AppState) -> schemas::AuthReturn { return auth_return; } -fn get_auth_header<'a>(req: &'a HttpRequest) -> Option<&'a str> { +fn get_auth_header(req: &HttpRequest) -> Option<&str> { req.headers().get("x-api-key")?.to_str().ok() } @@ -110,37 +109,37 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder let mut parsed_data: schemas::FullViewData = schemas::FullViewData { games: HashMap::new(), ethics: HashMap::new(), - species: HashMap::new(), + phenotypes: HashMap::new(), }; // Data processing // Species Vector db_portrait_groups.iter().for_each(|species| { - let new_data = schemas::Species { + let new_data = schemas::Phenotype { id: species.id, display: species.name.clone(), - portraits: HashMap::new(), + species: HashMap::new(), }; parsed_data - .species + .phenotypes .entry(species.id) .and_modify(|d| *d = new_data.clone()) .or_insert(new_data); }); db_portraits.iter().for_each(|portrait| { - let new_data = schemas::Portrait { + let new_data = schemas::Species { id: portrait.id, hires: portrait.hires.clone(), - lores: Some(portrait.lores.clone()), + lores: portrait.lores.clone(), }; parsed_data - .species + .phenotypes .get_mut(&portrait.group_id) .unwrap() - .portraits + .species .entry(portrait.id) .and_modify(|d| *d = new_data.clone()) .or_insert(new_data); @@ -182,10 +181,10 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder let new_data = schemas::ChellarisEmpireLegacy { id: empire.id, gestalt: empire.gestalt, - machine: false, + machine: empire.portrait_group_id.to_string() == dotenvy::var("MACHINE_GROUP_ID").unwrap_or("12".to_string()), group: empire.group_id, - empire_portrait: empire.portrait_id, - empire_portrait_group: empire.portrait_group_id, + portrait_id: empire.portrait_id, + portrait_group_id: empire.portrait_group_id, discord_user: None, ethics: HashMap::new(), }; @@ -205,7 +204,7 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder let new_data = schemas::Ethic { id: ethic.id, display: ethic.name.clone(), - machine: ethic.machine_ethic, + gestalt: ethic.gestalt_ethic, }; parsed_data @@ -220,13 +219,13 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder let id = empire_ethic.empire_id; let new_data = schemas::EmpireEthicLegacy { - id: empire_ethic.ethics_id, + ethic_id: empire_ethic.ethics_id, display: parsed_data.ethics[&empire_ethic.ethics_id].display.clone(), - machine: parsed_data.ethics[&empire_ethic.ethics_id].machine, + gestalt: parsed_data.ethics[&empire_ethic.ethics_id].gestalt, fanatic: empire_ethic.fanatic, }; - if new_data.machine { + if new_data.gestalt { parsed_data .games .get_mut(&game_id) @@ -234,7 +233,7 @@ pub(crate) async fn full_view_data(data: web::Data<AppState>) -> impl Responder .empires .get_mut(&id) .unwrap() - .machine = true; + .gestalt = true; } parsed_data @@ -368,7 +367,7 @@ pub(crate) async fn get_game_data( "[REDACTED]".to_string() }, discord_user: if user_auth.moderator || user_auth.admin { - empire.discord_user.clone() + Some("deprecated".to_string()) } else { None }, @@ -808,7 +807,8 @@ pub(crate) async fn get_empire( group: db_empire.group_id, game: db_empire.game_id, name: db_empire.name, - discord_user: db_empire.discord_user, + discord_user: Some("deprecated".to_string()), + machine: db_empire.portrait_group_id.to_string() == dotenvy::var("MACHINE_GROUP_ID").unwrap_or("12".to_string()), gestalt: db_empire.gestalt, portrait_id: db_empire.portrait_id, portrait_group_id: db_empire.portrait_group_id, @@ -941,7 +941,8 @@ pub(crate) async fn create_empire( group: db_empire.group_id, game: db_empire.game_id, name: db_empire.name, - discord_user: db_empire.discord_user, + discord_user: Some("deprecated".to_string()), + machine: db_empire.portrait_group_id.to_string() == dotenvy::var("MACHINE_GROUP_ID").unwrap_or("12".to_string()), gestalt: db_empire.gestalt, portrait_id: db_empire.portrait_id, portrait_group_id: db_empire.portrait_group_id, @@ -987,12 +988,10 @@ pub(crate) async fn edit_empire( let mut db_empire_query = QueryBuilder::<sqlx::Postgres>::new("UPDATE public.empires SET "); let mut db_empire_separated = db_empire_query.separated(", "); - if let Some(new_game) = params.game_id { - any_param_present = true; - db_empire_separated - .push(" game_id = ") - .push_bind_unseparated(new_game); - } + // More often than not does nothing but is required to ensure data is handled properly + db_empire_separated + .push(" game_id = ") + .push_bind_unseparated(params.game_id); if let Some(new_group) = params.group_id { any_param_present = true; @@ -1038,6 +1037,12 @@ pub(crate) async fn edit_empire( .push(" discord_user = ") .push_bind_unseparated(new_discord_user); } + else { + any_param_present = true; + let val: Option<String> = None; + db_empire_separated + .push(" discord_user = ").push_bind_unseparated(val); + } } let db_empire: db::schemas::Empire; @@ -1046,9 +1051,6 @@ pub(crate) async fn edit_empire( db_empire_separated .push_unseparated(" WHERE id = ") .push_bind_unseparated(params.empire_id); - db_empire_separated - .push_unseparated(" AND group_id = ") - .push_bind_unseparated(params.group_id); db_empire_separated .push_unseparated(" AND game_id = ") .push_bind_unseparated(params.game_id); @@ -1071,9 +1073,6 @@ pub(crate) async fn edit_empire( db_empire_separated .push_unseparated(" WHERE id = ") .push_bind_unseparated(params.empire_id); - db_empire_separated - .push_unseparated(" AND group_id = ") - .push_bind_unseparated(params.group_id); db_empire_separated .push_unseparated(" AND game_id = ") .push_bind_unseparated(params.game_id); @@ -1175,7 +1174,8 @@ pub(crate) async fn edit_empire( group: db_empire.group_id, game: db_empire.game_id, name: db_empire.name, - discord_user: db_empire.discord_user, + discord_user: Some("deprecated".to_string()), + machine: db_empire.portrait_group_id.to_string() == dotenvy::var("MACHINE_GROUP_ID").unwrap_or("12".to_string()), gestalt: db_empire.gestalt, portrait_id: db_empire.portrait_id, portrait_group_id: db_empire.portrait_group_id, @@ -1235,9 +1235,110 @@ pub(crate) async fn delete_empire( } } -// Data Manipulation Endpoints +// Ethics Endpoints +// Data Manipulation Admin Only -// Admin -// Add/Update/Remove Portrait -// Add/Update/Remove Species -// Add/Update/Remove Ethics +#[utoipa::path( + responses( + (status = 200, description = "OK", body = ChellarisEthics), + ), +)] +#[get("/api/v3/ethics")] +pub(crate) async fn get_ethics(data: web::Data<AppState>) -> impl Responder { + // SQL Queries + // TODO: Optimize by utilizing some SQL magic, for now this has to do + let mut db_ethics: HashMap<i32, schemas::Ethic> = HashMap::new(); + + let mut db_ethic_query = QueryBuilder::<sqlx::Postgres>::new("SELECT * FROM public.ethics"); + + match db_ethic_query + .build_query_as::<db::schemas::Ethic>() + .fetch_all(&data.db) + .await + { + Ok(data) => { + for ethic in data { + db_ethics.insert( + ethic.id, + schemas::Ethic { + id: ethic.id, + gestalt: ethic.gestalt_ethic, + display: ethic.name, + }, + ); + } + } + Err(e) => return HttpResponse::UnprocessableEntity().body(format!("{:#?}", e.to_string())), + }; + + // Empire Ethic Creation + let parsed_data: schemas::ChellarisEthics = schemas::ChellarisEthics { ethics: db_ethics }; + + return HttpResponse::Ok().json(parsed_data); +} + +// Species & Portrait Endpoints +// Data Manipulation Admin Only + +#[utoipa::path( + responses( + (status = 200, description = "OK", body = ChellarisPhenotypes), + ), +)] +#[get("/api/v3/phenotypes")] +pub(crate) async fn get_phenotypes(data: web::Data<AppState>) -> impl Responder { + // SQL Queries + // TODO: Optimize by utilizing some SQL magic, for now this has to do + let mut db_phenotypes: HashMap<i32, schemas::Phenotype> = HashMap::new(); + + let mut db_phenotype_query = QueryBuilder::<sqlx::Postgres>::new("SELECT * FROM public.portrait_groups"); + + match db_phenotype_query + .build_query_as::<db::schemas::PortraitGroup>() + .fetch_all(&data.db) + .await + { + Ok(data) => { + for phenotype in data { + db_phenotypes.insert( + phenotype.id, + schemas::Phenotype { + id: phenotype.id, + display: phenotype.name, + species: HashMap::new(), + }, + ); + } + } + Err(e) => return HttpResponse::UnprocessableEntity().body(format!("{:#?}", e.to_string())), + }; + + let mut db_species_query = QueryBuilder::<sqlx::Postgres>::new("SELECT * FROM public.portraits"); + + match db_species_query + .build_query_as::<db::schemas::Portrait>() + .fetch_all(&data.db) + .await + { + Ok(data) => { + for species in data { + if let Some(phenotype) = db_phenotypes.get_mut(&species.group_id) { + phenotype.species.insert( + species.id, + schemas::Species { + id: species.id, + hires: species.hires, + lores: species.lores + } + ); + } + } + } + Err(e) => return HttpResponse::UnprocessableEntity().body(format!("{:#?}", e.to_string())), + }; + + // Empire Ethic Creation + let parsed_data: schemas::ChellarisPhenotypes = schemas::ChellarisPhenotypes { phenotypes: db_phenotypes }; + + return HttpResponse::Ok().json(parsed_data); +} diff --git a/src/v3/schemas.rs b/src/v3/schemas.rs index 2a25b96..709a7b2 100644 --- a/src/v3/schemas.rs +++ b/src/v3/schemas.rs @@ -43,7 +43,7 @@ pub struct DeleteGameParam { pub struct FullViewData { pub games: HashMap<i32, ChellarisGameLegacy>, pub ethics: HashMap<i32, Ethic>, - pub species: HashMap<i32, Species>, + pub phenotypes: HashMap<i32, Phenotype>, } #[derive(Serialize, ToSchema, Debug, Clone)] @@ -147,7 +147,7 @@ pub struct UpdateEmpireParams { #[schema(example = 1)] pub empire_id: i32, #[schema(example = 1)] - pub game_id: Option<i32>, + pub game_id: i32, #[schema(example = 1)] pub group_id: Option<i32>, #[schema(example = "Example Empire")] @@ -195,6 +195,7 @@ pub struct ChellarisEmpire { pub game: i32, pub name: String, pub discord_user: Option<String>, + pub machine: bool, pub gestalt: bool, pub portrait_id: i32, pub portrait_group_id: i32, @@ -207,17 +208,19 @@ pub struct ChellarisEmpireLegacy { pub group: i32, pub gestalt: bool, pub machine: bool, - pub empire_portrait: i32, - pub empire_portrait_group: i32, + pub portrait_id: i32, + pub portrait_group_id: i32, pub discord_user: Option<String>, pub ethics: HashMap<i32, EmpireEthicLegacy>, } +// Ethics Structs + #[derive(Serialize, ToSchema, Debug, Clone)] pub struct Ethic { pub id: i32, pub display: String, - pub machine: bool, + pub gestalt: bool, } #[derive(Serialize, Deserialize, ToSchema, Debug, Clone)] @@ -230,23 +233,35 @@ pub struct EmpireEthic { #[derive(Serialize, ToSchema, Debug, Clone)] pub struct EmpireEthicLegacy { + pub ethic_id: i32, + pub display: String, + pub gestalt: bool, + pub fanatic: bool, +} + +#[derive(Serialize, ToSchema, Debug, Clone)] +pub struct ChellarisEthics { + pub ethics: HashMap<i32, Ethic>, +} + +// Species Structs + +#[derive(Serialize, ToSchema, Debug, Clone)] +pub struct Phenotype { pub id: i32, pub display: String, - pub machine: bool, - pub fanatic: bool, + pub species: HashMap<i32, Species>, +} + +#[derive(Serialize, ToSchema, Debug, Clone)] +pub struct ChellarisPhenotypes { + pub phenotypes: HashMap<i32, Phenotype> } #[derive(Serialize, ToSchema, Debug, Clone)] pub struct Species { - pub id: i32, - pub display: String, - pub portraits: HashMap<i32, Portrait>, -} - -#[derive(Serialize, ToSchema, Debug, Clone)] -pub struct Portrait { pub id: i32, pub hires: String, - pub lores: Option<String>, + pub lores: String, } diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index a2e0510..0000000 --- a/yarn.lock +++ /dev/null @@ -1,314 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -ajv@^6.1.1: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -async@^2.0.1: - version "2.6.4" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" - -bignumber.js@9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" - integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== - -bson@~1.0.4: - version "1.0.9" - resolved "https://registry.yarnpkg.com/bson/-/bson-1.0.9.tgz#12319f8323b1254739b7c6bef8d3e89ae05a2f57" - integrity sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg== - -buffer-shims@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - integrity sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -debug@*: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@^2.2.0: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -double-ended-queue@^2.1.0-0: - version "2.1.0-0" - resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" - integrity sha512-+BNfZ+deCo8hMNpDqDnvT+c0XpJ5cUa6mqYq89bho2Ifze4URTqRkcwR399hWoTrTkbZ/XJYDgP6rc7pRgffEQ== - -es6-promise@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.2.1.tgz#ec56233868032909207170c39448e24449dd1fc4" - integrity sha512-oj4jOSXvWglTsc3wrw86iom3LDPOx1nbipQk+jaG3dy+sMRM6ReSgVr/VlmBuF6lXUrflN9DCcQHeSbAwGUl4g== - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -lodash@^4.17.14, lodash@^4.17.4: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -mongo-sql@^2.7.5: - version "2.7.8" - resolved "https://registry.yarnpkg.com/mongo-sql/-/mongo-sql-2.7.8.tgz#f50184aaadc1be530db69e301ba35b01afd402d9" - integrity sha512-fJ4Tsn/G5QimXPRyoT0tnDhYdrPa/UJZY6FCJ4e9CYZgYH84w1qQrlednrpqgD9qK0oXtrLv78j1V+I5Yt/a6A== - -mongodb-core@2.1.20: - version "2.1.20" - resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.20.tgz#fece8dd76b59ee7d7f2d313b65322c160492d8f1" - integrity sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ== - dependencies: - bson "~1.0.4" - require_optional "~1.0.0" - -mongodb@^2.1.18: - version "2.2.36" - resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.36.tgz#1c573680b2849fb0f47acbba3dc5fa228de975f5" - integrity sha512-P2SBLQ8Z0PVx71ngoXwo12+FiSfbNfGOClAao03/bant5DgLNkOPAck5IaJcEk4gKlQhDEURzfR3xuBG1/B+IA== - dependencies: - es6-promise "3.2.1" - mongodb-core "2.1.20" - readable-stream "2.2.7" - -monk-middleware-cast-ids@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/monk-middleware-cast-ids/-/monk-middleware-cast-ids-0.2.1.tgz#40c40e5a6cb33ccedc289220943275ee8861c529" - integrity sha512-Hp9gwjXo+inSPhXUlsV1u3DyZh2cXT3Osij/1gSNCJQCgacAF1lfmnTj6bKmlf1Et4dvLhwUL0PquxdZRIofkA== - -monk-middleware-fields@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/monk-middleware-fields/-/monk-middleware-fields-0.2.0.tgz#ff637af35f5948879ccb2be15a91360911bea6c1" - integrity sha512-pp+k0JeBX+HkIKnCisrtsW/QM2WGkOVG1Bd1qKLSanuBCf1l5khpdHrEullfko0HO6tCjCJMp//MsR16gd5tAw== - -monk-middleware-handle-callback@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/monk-middleware-handle-callback/-/monk-middleware-handle-callback-0.2.2.tgz#47de6cc1248726c72a2be0c81bc4e68310c32146" - integrity sha512-5hBynb7asZ2uw9XVze7C3XH0zXT51yFDvYydk/5HnWWzh2NLglDSiKDcX0yLKPHzFgiq+5Z4Laq5fFVnFsmm8w== - -monk-middleware-options@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/monk-middleware-options/-/monk-middleware-options-0.2.1.tgz#58dae1c518d46636ebdff506fadfc773bb442886" - integrity sha512-ypE0wGC8n5ARvOq2tlERr1uyu1edckeDRkheQLaXPRm9LoW7kr9P7xMGEjW2vmBh7IxnkpONVc7555X8x+34hQ== - -monk-middleware-query@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/monk-middleware-query/-/monk-middleware-query-0.2.0.tgz#a926c677d4a5620c62151b0a56d0c0c151675874" - integrity sha512-BApd5HBiczJl1eVy65c9/NBVLtygBePFxuoHgar/LeMWCjWP9odSJk3vsnbxTnsOT1CMJ+hFysbaosLzDsxvtA== - -monk-middleware-wait-for-connection@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/monk-middleware-wait-for-connection/-/monk-middleware-wait-for-connection-0.2.0.tgz#312958d30e588b57d09754dd7c97b4843316835a" - integrity sha512-jSTz73B/+pGTTvhu5Ym8xsG6+QqaWab53UXnXdNNlTijTdLvcHABCLJXudQiJxob5N1Mzr5EOSx5ziwn2sihPQ== - -monk@^6.0.5: - version "6.0.6" - resolved "https://registry.yarnpkg.com/monk/-/monk-6.0.6.tgz#2ff1cd57f001bba0fea73d1eea3952a7d35450c5" - integrity sha512-bSuADQGwIxBcRzCzQaMoGmiGl30Dr+0iB1FQAQb3VwWwAKbtpDN2wkVHCjthzw/jXhPHWxTQFUtlSt/nSagojQ== - dependencies: - debug "*" - mongodb "^2.1.18" - monk-middleware-cast-ids "^0.2.1" - monk-middleware-fields "^0.2.0" - monk-middleware-handle-callback "^0.2.0" - monk-middleware-options "^0.2.1" - monk-middleware-query "^0.2.0" - monk-middleware-wait-for-connection "^0.2.0" - object-assign "^4.1.1" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -mysql@^2.11.1: - version "2.18.1" - resolved "https://registry.yarnpkg.com/mysql/-/mysql-2.18.1.tgz#2254143855c5a8c73825e4522baf2ea021766717" - integrity sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig== - dependencies: - bignumber.js "9.0.0" - readable-stream "2.3.7" - safe-buffer "5.1.2" - sqlstring "2.3.1" - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - integrity sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -readable-stream@2.2.7: - version "2.2.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.7.tgz#07057acbe2467b22042d36f98c5ad507054e95b1" - integrity sha512-a6ibcfWFhgihuTw/chl+u3fB5ykBZFmnvpyZHebY0MCQE4vvYcsCLpCeaQ1BkH7HdJYavNSqF0WDLeo4IPHQaQ== - dependencies: - buffer-shims "~1.0.0" - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~1.0.0" - util-deprecate "~1.0.1" - -readable-stream@2.3.7: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -redis-commands@^1.2.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89" - integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ== - -redis-parser@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b" - integrity sha512-9Hdw19gwXFBJdN8ENUoNVJFRyMDFrE/ZBClPicKYDPwNPJ4ST1TedAHYNSiGKElwh2vrmRGMoJYbVdJd+WQXIw== - -redis@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/redis/-/redis-2.8.0.tgz#202288e3f58c49f6079d97af7a10e1303ae14b02" - integrity sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A== - dependencies: - double-ended-queue "^2.1.0-0" - redis-commands "^1.2.0" - redis-parser "^2.6.0" - -require_optional@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e" - integrity sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g== - dependencies: - resolve-from "^2.0.0" - semver "^5.1.0" - -resolve-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" - integrity sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ== - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -semver@^5.1.0: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -sqlstring@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.1.tgz#475393ff9e91479aea62dcaf0ca3d14983a7fb40" - integrity sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ== - -sqlx@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/sqlx/-/sqlx-4.3.2.tgz#e00e9c01543e776639b3622beee0b51f2e005b76" - integrity sha512-cKXn3T0fDhnX69F7556K0weGUYaBsmmtcIjTlj9OPQNxR56Lvil89pk5WntRR+h4IFFkrmKDg0yzl0YVsSDgbQ== - dependencies: - ajv "^6.1.1" - async "^2.0.1" - debug "^2.2.0" - lodash "^4.17.4" - mongo-sql "^2.7.5" - monk "^6.0.5" - mysql "^2.11.1" - redis "^2.8.0" - -string_decoder@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" - integrity sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ== - dependencies: - safe-buffer "~5.1.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==