From bb40079bd68b3588733bfe0096177c9c95d3f0af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:30:10 +0330 Subject: [PATCH 01/31] chore(deps): bump clap from 4.4.3 to 4.4.4 (#3) Bumps [clap](https://github.com/clap-rs/clap) from 4.4.3 to 4.4.4. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/v4.4.3...v4.4.4) --- updated-dependencies: - dependency-name: clap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d4c3fb..9549839 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -290,9 +290,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.3" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6" +checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" dependencies = [ "clap_builder", "clap_derive", @@ -300,9 +300,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" dependencies = [ "anstream", "anstyle", diff --git a/Cargo.toml b/Cargo.toml index af63208..2f8ba0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ log = "0.4.20" env_logger = "0.10.0" serde_json = "1.0.107" futures = "0.3.28" -clap = { version = "4.4.3", features = ["derive"] } +clap = { version = "4.4.4", features = ["derive"] } serenity = { version = "0.11.6", default-features = false, features = ["rustls_backend", "model"] } rocksdb = { version = "0.21.0", default-features = false, features = ["lz4"] } html2md = "0.2.14" From 6e89b6f799dca0a4ab7ce2bf7d720962dbb6b493 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 07:31:07 +0330 Subject: [PATCH 02/31] chore: add `package.json` for LilNouns bots project This commit introduces a package.json file for the lilnouns-bots project. This file is essential as it holds various metadata relevant to the project such as its dependencies and scripts. It is essential for Node.js projects and it's being introduced to support the development and deployment phases. The file is marked as private to prevent accidental publication on npm. The wrangler module version 3.8.0 is added under devDependencies to help managing and publishing cloudflare workers. --- package.json | 12 + pnpm-lock.yaml | 964 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 976 insertions(+) create mode 100644 package.json create mode 100644 pnpm-lock.yaml diff --git a/package.json b/package.json new file mode 100644 index 0000000..9e1f6bb --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "lilnouns-bots", + "version": "1.0.0-alpha.6", + "private": true, + "scripts": { + "deploy": "wrangler deploy", + "dev": "wrangler dev --local" + }, + "devDependencies": { + "wrangler": "3.8.0" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..411955b --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,964 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +devDependencies: + wrangler: + specifier: 3.8.0 + version: 3.8.0 + +packages: + + /@cloudflare/kv-asset-handler@0.2.0: + resolution: { integrity: sha512-MVbXLbTcAotOPUj0pAMhVtJ+3/kFkwJqc5qNOleOZTv6QkZZABDMS21dSrSlVswEHwrpWC03e4fWytjqKvuE2A== } + dependencies: + mime: 3.0.0 + dev: true + + /@cloudflare/workerd-darwin-64@1.20230904.0: + resolution: { integrity: sha512-/GDlmxAFbDtrQwP4zOXFbqOfaPvkDxdsCoEa+KEBcAl5uR98+7WW5/b8naBHX+t26uS7p4bLlImM8J5F1ienRQ== } + engines: { node: '>=16' } + cpu: [ x64 ] + os: [ darwin ] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/workerd-darwin-arm64@1.20230904.0: + resolution: { integrity: sha512-x8WXNc2xnDqr5y1iirnNdyx8GZY3rL5xiF7ebK3mKQeB+jFjkhO71yuPTkDCzUWtOvw1Wfd4jbwy4wxacMX4mQ== } + engines: { node: '>=16' } + cpu: [ arm64 ] + os: [ darwin ] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/workerd-linux-64@1.20230904.0: + resolution: { integrity: sha512-V58xyMS3oDpKO8Dpdh0r0BXm99OzoGgvWe9ufttVraj/1NTMGELwb6i9ySb8k3F1J9m/sO26+TV7pQc/bGC1VQ== } + engines: { node: '>=16' } + cpu: [ x64 ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/workerd-linux-arm64@1.20230904.0: + resolution: { integrity: sha512-VrDaW+pjb5IAKEnNWtEaFiG377kXKmk5Fu0Era4W+jKzPON2BW/qRb/4LNHXQ4yxg/2HLm7RiUTn7JZtt1qO6A== } + engines: { node: '>=16' } + cpu: [ arm64 ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@cloudflare/workerd-windows-64@1.20230904.0: + resolution: { integrity: sha512-/R/dE8uy+8J2YeXfDhI8/Bg7YUirdbbjH5/l/Vv00ZRE0lC3nPLcYeyBXSwXIQ6/Xht3gN+lksLQgKd0ZWRd+Q== } + engines: { node: '>=16' } + cpu: [ x64 ] + os: [ win32 ] + requiresBuild: true + dev: true + optional: true + + /@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19): + resolution: { integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw== } + peerDependencies: + esbuild: '*' + dependencies: + esbuild: 0.17.19 + dev: true + + /@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19): + resolution: { integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA== } + peerDependencies: + esbuild: '*' + dependencies: + esbuild: 0.17.19 + escape-string-regexp: 4.0.0 + rollup-plugin-node-polyfills: 0.2.1 + dev: true + + /@esbuild/android-arm64@0.17.19: + resolution: { integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== } + engines: { node: '>=12' } + cpu: [ arm64 ] + os: [ android ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.17.19: + resolution: { integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== } + engines: { node: '>=12' } + cpu: [ arm ] + os: [ android ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.17.19: + resolution: { integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== } + engines: { node: '>=12' } + cpu: [ x64 ] + os: [ android ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.17.19: + resolution: { integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== } + engines: { node: '>=12' } + cpu: [ arm64 ] + os: [ darwin ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.17.19: + resolution: { integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== } + engines: { node: '>=12' } + cpu: [ x64 ] + os: [ darwin ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.17.19: + resolution: { integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== } + engines: { node: '>=12' } + cpu: [ arm64 ] + os: [ freebsd ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.17.19: + resolution: { integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== } + engines: { node: '>=12' } + cpu: [ x64 ] + os: [ freebsd ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.17.19: + resolution: { integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== } + engines: { node: '>=12' } + cpu: [ arm64 ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.17.19: + resolution: { integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== } + engines: { node: '>=12' } + cpu: [ arm ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.17.19: + resolution: { integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== } + engines: { node: '>=12' } + cpu: [ ia32 ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.17.19: + resolution: { integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== } + engines: { node: '>=12' } + cpu: [ loong64 ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.17.19: + resolution: { integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== } + engines: { node: '>=12' } + cpu: [ mips64el ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.17.19: + resolution: { integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== } + engines: { node: '>=12' } + cpu: [ ppc64 ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.17.19: + resolution: { integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== } + engines: { node: '>=12' } + cpu: [ riscv64 ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.17.19: + resolution: { integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== } + engines: { node: '>=12' } + cpu: [ s390x ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.17.19: + resolution: { integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== } + engines: { node: '>=12' } + cpu: [ x64 ] + os: [ linux ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.17.19: + resolution: { integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== } + engines: { node: '>=12' } + cpu: [ x64 ] + os: [ netbsd ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.17.19: + resolution: { integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== } + engines: { node: '>=12' } + cpu: [ x64 ] + os: [ openbsd ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.17.19: + resolution: { integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== } + engines: { node: '>=12' } + cpu: [ x64 ] + os: [ sunos ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.17.19: + resolution: { integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== } + engines: { node: '>=12' } + cpu: [ arm64 ] + os: [ win32 ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.17.19: + resolution: { integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== } + engines: { node: '>=12' } + cpu: [ ia32 ] + os: [ win32 ] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.17.19: + resolution: { integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== } + engines: { node: '>=12' } + cpu: [ x64 ] + os: [ win32 ] + requiresBuild: true + dev: true + optional: true + + /acorn-walk@8.2.0: + resolution: { integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== } + engines: { node: '>=0.4.0' } + dev: true + + /acorn@8.10.0: + resolution: { integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== } + engines: { node: '>=0.4.0' } + hasBin: true + dev: true + + /anymatch@3.1.3: + resolution: { integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== } + engines: { node: '>= 8' } + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /as-table@1.0.55: + resolution: { integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ== } + dependencies: + printable-characters: 1.0.42 + dev: true + + /base64-js@1.5.1: + resolution: { integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== } + dev: true + + /better-sqlite3@8.4.0: + resolution: { integrity: sha512-NmsNW1CQvqMszu/CFAJ3pLct6NEFlNfuGM6vw72KHkjOD1UDnL96XNN1BMQc1hiHo8vE2GbOWQYIpZ+YM5wrZw== } + requiresBuild: true + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.1 + dev: true + + /binary-extensions@2.2.0: + resolution: { integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== } + engines: { node: '>=8' } + dev: true + + /bindings@1.5.0: + resolution: { integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== } + dependencies: + file-uri-to-path: 1.0.0 + dev: true + + /bl@4.1.0: + resolution: { integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== } + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /blake3-wasm@2.1.5: + resolution: { integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g== } + dev: true + + /braces@3.0.2: + resolution: { integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== } + engines: { node: '>=8' } + dependencies: + fill-range: 7.0.1 + dev: true + + /buffer-from@1.1.2: + resolution: { integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== } + dev: true + + /buffer@5.7.1: + resolution: { integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== } + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /busboy@1.6.0: + resolution: { integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== } + engines: { node: '>=10.16.0' } + dependencies: + streamsearch: 1.1.0 + dev: true + + /capnp-ts@0.7.0: + resolution: { integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g== } + dependencies: + debug: 4.3.4 + tslib: 2.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /chokidar@3.5.3: + resolution: { integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== } + engines: { node: '>= 8.10.0' } + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /chownr@1.1.4: + resolution: { integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== } + dev: true + + /cookie@0.5.0: + resolution: { integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== } + engines: { node: '>= 0.6' } + dev: true + + /data-uri-to-buffer@2.0.2: + resolution: { integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA== } + dev: true + + /debug@4.3.4: + resolution: { integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== } + engines: { node: '>=6.0' } + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /decompress-response@6.0.0: + resolution: { integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== } + engines: { node: '>=10' } + dependencies: + mimic-response: 3.1.0 + dev: true + + /deep-extend@0.6.0: + resolution: { integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== } + engines: { node: '>=4.0.0' } + dev: true + + /detect-libc@2.0.1: + resolution: { integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== } + engines: { node: '>=8' } + dev: true + + /end-of-stream@1.4.4: + resolution: { integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== } + dependencies: + once: 1.4.0 + dev: true + + /esbuild@0.17.19: + resolution: { integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== } + engines: { node: '>=12' } + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + dev: true + + /escape-string-regexp@4.0.0: + resolution: { integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== } + engines: { node: '>=10' } + dev: true + + /estree-walker@0.6.1: + resolution: { integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== } + dev: true + + /exit-hook@2.2.1: + resolution: { integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw== } + engines: { node: '>=6' } + dev: true + + /expand-template@2.0.3: + resolution: { integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== } + engines: { node: '>=6' } + dev: true + + /file-uri-to-path@1.0.0: + resolution: { integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== } + dev: true + + /fill-range@7.0.1: + resolution: { integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== } + engines: { node: '>=8' } + dependencies: + to-regex-range: 5.0.1 + dev: true + + /fs-constants@1.0.0: + resolution: { integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== } + dev: true + + /fsevents@2.3.2: + resolution: { integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [ darwin ] + requiresBuild: true + dev: true + optional: true + + /get-source@2.0.12: + resolution: { integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w== } + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + dev: true + + /github-from-package@0.0.0: + resolution: { integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== } + dev: true + + /glob-parent@5.1.2: + resolution: { integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== } + engines: { node: '>= 6' } + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-to-regexp@0.4.1: + resolution: { integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== } + dev: true + + /http-cache-semantics@4.1.1: + resolution: { integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== } + dev: true + + /ieee754@1.2.1: + resolution: { integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== } + dev: true + + /inherits@2.0.4: + resolution: { integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== } + dev: true + + /ini@1.3.8: + resolution: { integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== } + dev: true + + /is-binary-path@2.1.0: + resolution: { integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== } + engines: { node: '>=8' } + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-extglob@2.1.1: + resolution: { integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== } + engines: { node: '>=0.10.0' } + dev: true + + /is-glob@4.0.3: + resolution: { integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== } + engines: { node: '>=0.10.0' } + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-number@7.0.0: + resolution: { integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== } + engines: { node: '>=0.12.0' } + dev: true + + /kleur@4.1.5: + resolution: { integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== } + engines: { node: '>=6' } + dev: true + + /lru-cache@6.0.0: + resolution: { integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== } + engines: { node: '>=10' } + dependencies: + yallist: 4.0.0 + dev: true + + /magic-string@0.25.9: + resolution: { integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== } + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /mime@3.0.0: + resolution: { integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== } + engines: { node: '>=10.0.0' } + hasBin: true + dev: true + + /mimic-response@3.1.0: + resolution: { integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== } + engines: { node: '>=10' } + dev: true + + /miniflare@3.20230904.0: + resolution: { integrity: sha512-+OWQqEk8hV7vZaPCoj5dk1lZr4YUy56OiyNZ45/3ITYf+ZxgQOBPWhQhpw1jCahkRKGPa9Aykz01sc+GhPZYDA== } + engines: { node: '>=16.13' } + dependencies: + acorn: 8.10.0 + acorn-walk: 8.2.0 + better-sqlite3: 8.4.0 + capnp-ts: 0.7.0 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + http-cache-semantics: 4.1.1 + kleur: 4.1.5 + source-map-support: 0.5.21 + stoppable: 1.1.0 + undici: 5.23.0 + workerd: 1.20230904.0 + ws: 8.13.0 + youch: 3.2.3 + zod: 3.21.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /minimist@1.2.8: + resolution: { integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== } + dev: true + + /mkdirp-classic@0.5.3: + resolution: { integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== } + dev: true + + /ms@2.1.2: + resolution: { integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== } + dev: true + + /mustache@4.2.0: + resolution: { integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== } + hasBin: true + dev: true + + /nanoid@3.3.6: + resolution: { integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + dev: true + + /napi-build-utils@1.0.2: + resolution: { integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== } + dev: true + + /node-abi@3.45.0: + resolution: { integrity: sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ== } + engines: { node: '>=10' } + dependencies: + semver: 7.5.4 + dev: true + + /node-forge@1.3.1: + resolution: { integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== } + engines: { node: '>= 6.13.0' } + dev: true + + /normalize-path@3.0.0: + resolution: { integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== } + engines: { node: '>=0.10.0' } + dev: true + + /once@1.4.0: + resolution: { integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== } + dependencies: + wrappy: 1.0.2 + dev: true + + /path-to-regexp@6.2.1: + resolution: { integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== } + dev: true + + /picomatch@2.3.1: + resolution: { integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== } + engines: { node: '>=8.6' } + dev: true + + /prebuild-install@7.1.1: + resolution: { integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== } + engines: { node: '>=10' } + hasBin: true + dependencies: + detect-libc: 2.0.1 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.45.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + dev: true + + /printable-characters@1.0.42: + resolution: { integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ== } + dev: true + + /pump@3.0.0: + resolution: { integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== } + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /rc@1.2.8: + resolution: { integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== } + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + dev: true + + /readable-stream@3.6.2: + resolution: { integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== } + engines: { node: '>= 6' } + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readdirp@3.6.0: + resolution: { integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== } + engines: { node: '>=8.10.0' } + dependencies: + picomatch: 2.3.1 + dev: true + + /rollup-plugin-inject@3.0.2: + resolution: { integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w== } + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + dev: true + + /rollup-plugin-node-polyfills@0.2.1: + resolution: { integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA== } + dependencies: + rollup-plugin-inject: 3.0.2 + dev: true + + /rollup-pluginutils@2.8.2: + resolution: { integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== } + dependencies: + estree-walker: 0.6.1 + dev: true + + /safe-buffer@5.2.1: + resolution: { integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== } + dev: true + + /selfsigned@2.1.1: + resolution: { integrity: sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== } + engines: { node: '>=10' } + dependencies: + node-forge: 1.3.1 + dev: true + + /semver@7.5.4: + resolution: { integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== } + engines: { node: '>=10' } + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /simple-concat@1.0.1: + resolution: { integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== } + dev: true + + /simple-get@4.0.1: + resolution: { integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== } + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + dev: true + + /source-map-support@0.5.21: + resolution: { integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== } + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: { integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== } + engines: { node: '>=0.10.0' } + dev: true + + /source-map@0.7.4: + resolution: { integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== } + engines: { node: '>= 8' } + dev: true + + /sourcemap-codec@1.4.8: + resolution: { integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== } + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: true + + /stacktracey@2.1.8: + resolution: { integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw== } + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + dev: true + + /stoppable@1.1.0: + resolution: { integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== } + engines: { node: '>=4', npm: '>=6' } + dev: true + + /streamsearch@1.1.0: + resolution: { integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== } + engines: { node: '>=10.0.0' } + dev: true + + /string_decoder@1.3.0: + resolution: { integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== } + dependencies: + safe-buffer: 5.2.1 + dev: true + + /strip-json-comments@2.0.1: + resolution: { integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== } + engines: { node: '>=0.10.0' } + dev: true + + /tar-fs@2.1.1: + resolution: { integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== } + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: true + + /tar-stream@2.2.0: + resolution: { integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== } + engines: { node: '>=6' } + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /to-regex-range@5.0.1: + resolution: { integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== } + engines: { node: '>=8.0' } + dependencies: + is-number: 7.0.0 + dev: true + + /tslib@2.6.1: + resolution: { integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== } + dev: true + + /tunnel-agent@0.6.0: + resolution: { integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== } + dependencies: + safe-buffer: 5.2.1 + dev: true + + /undici@5.23.0: + resolution: { integrity: sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg== } + engines: { node: '>=14.0' } + dependencies: + busboy: 1.6.0 + dev: true + + /util-deprecate@1.0.2: + resolution: { integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== } + dev: true + + /workerd@1.20230904.0: + resolution: { integrity: sha512-t9znszH0rQGK4mJGvF9L3nN0qKEaObAGx0JkywFtAwH8OkSn+YfQbHNZE+YsJ4qa1hOz1DCNEk08UDFRBaYq4g== } + engines: { node: '>=16' } + hasBin: true + requiresBuild: true + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20230904.0 + '@cloudflare/workerd-darwin-arm64': 1.20230904.0 + '@cloudflare/workerd-linux-64': 1.20230904.0 + '@cloudflare/workerd-linux-arm64': 1.20230904.0 + '@cloudflare/workerd-windows-64': 1.20230904.0 + dev: true + + /wrangler@3.8.0: + resolution: { integrity: sha512-sTdD+6fMEpM9ROxv+gcyxgTKpnf7tB5ftRV5+wupsdljWkow5C00UCWU/IWSOUfuitAGAj1PWATjKfrRp9Bk9w== } + engines: { node: '>=16.13.0' } + hasBin: true + dependencies: + '@cloudflare/kv-asset-handler': 0.2.0 + '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) + '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) + blake3-wasm: 2.1.5 + chokidar: 3.5.3 + esbuild: 0.17.19 + miniflare: 3.20230904.0 + nanoid: 3.3.6 + path-to-regexp: 6.2.1 + selfsigned: 2.1.1 + source-map: 0.7.4 + xxhash-wasm: 1.0.2 + optionalDependencies: + fsevents: 2.3.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /wrappy@1.0.2: + resolution: { integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== } + dev: true + + /ws@8.13.0: + resolution: { integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== } + engines: { node: '>=10.0.0' } + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /xxhash-wasm@1.0.2: + resolution: { integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A== } + dev: true + + /yallist@4.0.0: + resolution: { integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== } + dev: true + + /youch@3.2.3: + resolution: { integrity: sha512-ZBcWz/uzZaQVdCvfV4uk616Bbpf2ee+F/AvuKDR5EwX/Y4v06xWdtMluqTD7+KlZdM93lLm9gMZYo0sKBS0pgw== } + dependencies: + cookie: 0.5.0 + mustache: 4.2.0 + stacktracey: 2.1.8 + dev: true + + /zod@3.21.4: + resolution: { integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw== } + dev: true From f327b59e9deeaee660b945d8a6ffa066dd68d553 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 07:31:28 +0330 Subject: [PATCH 03/31] chore: add `wrangler.toml` configuration for deployment This commit introduces the Wrangler configuration file `wrangler.toml` for the project "lilnouns-bots". This change is necessary to enable the Cloudflare deployment. It specifies the name, entry point, compatibility date, and build command for the Worker script. --- wrangler.toml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 wrangler.toml diff --git a/wrangler.toml b/wrangler.toml new file mode 100644 index 0000000..621a38f --- /dev/null +++ b/wrangler.toml @@ -0,0 +1,6 @@ +name = "lilnouns-bots" +main = "build/worker/shim.mjs" +compatibility_date = "2023-03-22" + +[build] +command = "cargo install -q worker-build && worker-build --release" From 47653f33cd6d8f73728e2bd936c10d3b0649e181 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 07:32:36 +0330 Subject: [PATCH 04/31] chore: add `wasm-pack` and additional dependencies in `Cargo.toml` Added wasm-pack configuration and necessary dependencies to enhance the packaging of rust code to WebAssembly. This change was made due to https://github.com/rustwasm/wasm-pack/issues/1247. Additionally, included 'worker' as a new dependency and adjusted the release profile to optimize for size and performance. --- Cargo.toml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 2f8ba0b..93d268d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,13 @@ include = ["*.graphql"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +# https://github.com/rustwasm/wasm-pack/issues/1247 +[package.metadata.wasm-pack.profile.release] +wasm-opt = false + +[lib] +crate-type = ["cdylib"] + [dependencies] graphql_client = { version = "0.13.0", features = ["reqwest"] } serde = { version = "1.0.188", features = ["derive"] } @@ -22,3 +29,8 @@ serenity = { version = "0.11.6", default-features = false, features = ["rustls_b rocksdb = { version = "0.21.0", default-features = false, features = ["lz4"] } html2md = "0.2.14" chrono = "0.4.31" +worker = "0.0.18" +[profile.release] +lto = true +strip = true +codegen-units = 1 From 8a46ef1655b8df3dff4958443ed77db1910c5d62 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 07:33:46 +0330 Subject: [PATCH 05/31] chore: add `node_modules` to `.gitignore` This change is incorporated to ensure we are not tracking or commiting the node_modules folder. This is an important change in order to reduce the clutter and size of our repository as this folder can potentially contain thousands of npm packages which are not necessary to be in our version control. --- .gitignore | 1 + Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 65f5692..8ade55a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /tmp /report.* +/node_modules diff --git a/Cargo.toml b/Cargo.toml index 93d268d..0a78af8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ rocksdb = { version = "0.21.0", default-features = false, features = ["lz4"] } html2md = "0.2.14" chrono = "0.4.31" worker = "0.0.18" + [profile.release] lto = true strip = true From 3c177be03c4032bb4da7b3a807cc981c436f9672 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 07:56:04 +0330 Subject: [PATCH 06/31] chore: update `package.json` for deployment and development This commit removes the specific versioning and name from package.json file as well as changes the "dev" script. This simplification was made to streamline the workflow and avoid redundancy. Now, "wrangler dev" will execute without the local flag, making it more universal. --- package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index 9e1f6bb..8419224 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,8 @@ { - "name": "lilnouns-bots", - "version": "1.0.0-alpha.6", "private": true, "scripts": { "deploy": "wrangler deploy", - "dev": "wrangler dev --local" + "dev": "wrangler dev" }, "devDependencies": { "wrangler": "3.8.0" From f7c2ac0c09fafa9c4c2c099af0f78d415177a244 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 08:30:43 +0330 Subject: [PATCH 07/31] chore: add `wasm32` target to Cargo configuration A new target, "wasm32-unknown-unknown", has been added to the .cargo/config.toml file to enable WebAssembly compilation. This is instrumental in compiling Rust to WebAssembly. --- .cargo/config.toml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..f4e8c00 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[build] +target = "wasm32-unknown-unknown" From 5167625e6b2dff7cf2d1d8ee4ecd9625aeade55c Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 08:34:23 +0330 Subject: [PATCH 08/31] chore(deps): add `getrandom` dependency A new dependency, getrandom, has been added to the Cargo.toml file. This is required for generating random numbers, especially relevant for cryptographic functionalities. The version being used is 0.2.10 with js feature enabled. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 0a78af8..5f23094 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ rocksdb = { version = "0.21.0", default-features = false, features = ["lz4"] } html2md = "0.2.14" chrono = "0.4.31" worker = "0.0.18" +getrandom = { version = "0.2.10", features = ["js"] } [profile.release] lto = true From f86024fcd2f1640a22a01508a8bd9a14c9ba6fe9 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 12:19:01 +0330 Subject: [PATCH 09/31] chore(deps): remove `rocksdb` dependency RocksDB dependency was removed from the 'Cargo.toml' because it was not being used in the project, which will reduce build time and the binary size. --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5f23094..76ab3fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,6 @@ serde_json = "1.0.107" futures = "0.3.28" clap = { version = "4.4.4", features = ["derive"] } serenity = { version = "0.11.6", default-features = false, features = ["rustls_backend", "model"] } -rocksdb = { version = "0.21.0", default-features = false, features = ["lz4"] } html2md = "0.2.14" chrono = "0.4.31" worker = "0.0.18" From d58d2e5dbecfeb9ecb377947d47c35c3ae8a4295 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 13:46:19 +0330 Subject: [PATCH 10/31] chore: update and rearrange dependencies The dependencies in the Cargo.toml file have been reorganized in alphabetical order for improved readability and maintenance. The 'getrandom' library was added to the list to support random number generation in JavaScript environments, enhancing app feature capabilities within these contexts." --- Cargo.toml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 76ab3fe..5faaa58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,22 +14,20 @@ wasm-opt = false crate-type = ["cdylib"] [dependencies] -graphql_client = { version = "0.13.0", features = ["reqwest"] } -serde = { version = "1.0.188", features = ["derive"] } -reqwest = "0.11.20" -tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] } anyhow = "1.0.75" -lazy_static = "1.4.0" -log = "0.4.20" +chrono = "0.4.31" env_logger = "0.10.0" -serde_json = "1.0.107" futures = "0.3.28" -clap = { version = "4.4.4", features = ["derive"] } -serenity = { version = "0.11.6", default-features = false, features = ["rustls_backend", "model"] } +getrandom = { version = "0.2.10", features = ["js"] } +graphql_client = { version = "0.13.0", features = ["reqwest"] } html2md = "0.2.14" -chrono = "0.4.31" +lazy_static = "1.4.0" +log = "0.4.20" +reqwest = "0.11.20" +serde = { version = "1.0.188", features = ["derive"] } +serde_json = "1.0.107" +tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] } worker = "0.0.18" -getrandom = { version = "0.2.10", features = ["js"] } [profile.release] lto = true From 28f4d7484e3335e1e9ddf4cde9e68bb3a04a58bb Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 15:36:09 +0330 Subject: [PATCH 11/31] chore(deps): remove `tokio` dependency The 'tokio' crate was removed from the package manifest file, Cargo.toml, as it was no longer being used in the project. This reduction of unused dependency will potentially aid in improving the compilation speed and reducing the project size. --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5faaa58..e92bff7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,6 @@ log = "0.4.20" reqwest = "0.11.20" serde = { version = "1.0.188", features = ["derive"] } serde_json = "1.0.107" -tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread"] } worker = "0.0.18" [profile.release] From 6adcd3a60781d73ff541af286251d47da954743b Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 15:38:32 +0330 Subject: [PATCH 12/31] chore(deps): remove `lazy_static` dependency The 'lazy_static' dependency was removed from the Cargo.toml file as it's no longer being used in the project, hence cleaning up and optimizing the dependency list. --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e92bff7..0461099 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,6 @@ futures = "0.3.28" getrandom = { version = "0.2.10", features = ["js"] } graphql_client = { version = "0.13.0", features = ["reqwest"] } html2md = "0.2.14" -lazy_static = "1.4.0" log = "0.4.20" reqwest = "0.11.20" serde = { version = "1.0.188", features = ["derive"] } From 680b16c6dea0915b14bfcb7b5bcd2376f95ec808 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 23:47:21 +0330 Subject: [PATCH 13/31] refactor: remove caching system from project The cache.rs and associated cacher.rs files directly related to it in the 'prop_house' and 'prop_lot' directories were removed. The decision to remove the caching system from the project was made because it was found to be an unnecessary optimization. Caching is typically used for performance optimization to speed up software apps by storing data in memory that can be re-used. However, upon reviewing the needs of our application, we determined that our application's data needs were simple enough that we did not require a caching system and this would by extension reduce code complexity. --- src/cache.rs | 79 ---------------------------------------- src/prop_house/cacher.rs | 77 --------------------------------------- src/prop_lot/cacher.rs | 79 ---------------------------------------- 3 files changed, 235 deletions(-) delete mode 100644 src/cache.rs delete mode 100644 src/prop_house/cacher.rs delete mode 100644 src/prop_lot/cacher.rs diff --git a/src/cache.rs b/src/cache.rs deleted file mode 100644 index d4505c3..0000000 --- a/src/cache.rs +++ /dev/null @@ -1,79 +0,0 @@ -use std::fmt::Debug; -use std::sync::{Arc, Mutex}; - -use anyhow::{anyhow, Result}; -use lazy_static::lazy_static; -use serde::de::DeserializeOwned; -use serde::Serialize; - -use rocksdb::{Options, WriteBatch, DB}; - -lazy_static! { - pub static ref CACHE: Cache = { - let path = "./tmp/cache"; - let mut opts = Options::default(); - opts.create_if_missing(true); - let db = DB::open(&opts, path).unwrap_or_else(|_| panic!("Could not open storage")); - Cache { - storage: Arc::new(Mutex::new(db)), - } - }; -} - -pub struct Cache { - storage: Arc>, -} - -impl Cache { - pub fn get(&self, key: &K) -> Result> - where - K: Serialize + Debug, - V: DeserializeOwned, - { - let storage = self.storage.lock().unwrap(); - let key_bytes = serde_json::to_vec(&key)?; - - match storage.get(key_bytes) { - Ok(Some(value_bytes)) => { - let value: V = serde_json::from_slice(&value_bytes)?; - Ok(Some(value)) - } - Ok(None) => Ok(None), - Err(err) => Err(anyhow!("Failed to get key {:?} from cache: {:?}", key, err)), - } - } - - pub fn set(&self, key: K, value: V) -> Result<()> - where - K: Serialize + Debug, - V: Serialize, - { - let storage = self.storage.lock().unwrap(); - let key_bytes = serde_json::to_vec(&key)?; - let value_bytes = serde_json::to_vec(&value)?; - - storage.put(key_bytes, value_bytes)?; - - Ok(()) - } - - pub fn set_batch(&self, items: Vec<(K, V)>) -> Result<()> - where - K: Serialize + Debug, - V: Serialize, - { - let storage = self.storage.lock().unwrap(); - let mut batch = WriteBatch::default(); - - for (key, value) in items { - let key_bytes = serde_json::to_vec(&key)?; - let value_bytes = serde_json::to_vec(&value)?; - - batch.put(key_bytes, value_bytes); - } - - storage.write(batch)?; - - Ok(()) - } -} diff --git a/src/prop_house/cacher.rs b/src/prop_house/cacher.rs deleted file mode 100644 index dc9a719..0000000 --- a/src/prop_house/cacher.rs +++ /dev/null @@ -1,77 +0,0 @@ -use anyhow::Result; - -use crate::cache; -use crate::prop_house::fetcher::{Auction, Proposal, Vote}; - -const AUCTION_CACHE_KEY_PREFIX: &str = "PROP_HOUSE_AUCTION_"; -const PROPOSAL_CACHE_KEY_PREFIX: &str = "PROP_HOUSE_PROPOSAL_"; -const VOTE_CACHE_KEY_PREFIX: &str = "PROP_HOUSE_VOTE_"; - -fn auction_cache_key(id: isize) -> String { - format!("{}{}", AUCTION_CACHE_KEY_PREFIX, id) -} - -fn proposal_cache_key(id: isize) -> String { - format!("{}{}", PROPOSAL_CACHE_KEY_PREFIX, id) -} - -fn vote_cache_key(id: isize) -> String { - format!("{}{}", VOTE_CACHE_KEY_PREFIX, id) -} - -pub(crate) fn set_auction_cache(auction: &Auction) -> Result<()> { - let cache = &cache::CACHE; - cache.set(auction_cache_key(auction.id), auction) -} - -pub(crate) fn set_auctions_cache(auctions: &[Auction]) -> Result<()> { - let cache = &cache::CACHE; - let items: Vec<_> = auctions - .iter() - .map(|auction| (auction_cache_key(auction.id), auction)) - .collect(); - cache.set_batch(items) -} - -pub(crate) fn get_auction_cache(id: isize) -> Result> { - let cache = &cache::CACHE; - cache.get::(&auction_cache_key(id)) -} - -pub(crate) fn set_proposal_cache(proposal: &Proposal) -> Result<()> { - let cache = &cache::CACHE; - cache.set(proposal_cache_key(proposal.id), proposal) -} - -pub(crate) fn set_proposals_cache(proposals: &[Proposal]) -> Result<()> { - let cache = &cache::CACHE; - let items: Vec<_> = proposals - .iter() - .map(|proposal| (proposal_cache_key(proposal.id), proposal)) - .collect(); - cache.set_batch(items) -} - -pub(crate) fn get_proposal_cache(id: isize) -> Result> { - let cache = &cache::CACHE; - cache.get::(&proposal_cache_key(id)) -} - -pub(crate) fn set_vote_cache(vote: &Vote) -> Result<()> { - let cache = &cache::CACHE; - cache.set(vote_cache_key(vote.id), vote) -} - -pub(crate) fn set_votes_cache(votes: &[Vote]) -> Result<()> { - let cache = &cache::CACHE; - let items: Vec<_> = votes - .iter() - .map(|vote| (vote_cache_key(vote.id), vote)) - .collect(); - cache.set_batch(items) -} - -pub(crate) fn get_vote_cache(id: isize) -> Result> { - let cache = &cache::CACHE; - cache.get::(&vote_cache_key(id)) -} diff --git a/src/prop_lot/cacher.rs b/src/prop_lot/cacher.rs deleted file mode 100644 index 9ff421d..0000000 --- a/src/prop_lot/cacher.rs +++ /dev/null @@ -1,79 +0,0 @@ -use anyhow::Result; - -use crate::cache; -use crate::prop_lot::fetcher::{Comment, Idea, Vote}; - -const IDEA_CACHE_KEY_PREFIX: &str = "PROP_LOT_IDEA_"; - -const VOTE_CACHE_KEY_PREFIX: &str = "PROP_LOT_VOTE_"; - -const COMMENT_CACHE_KEY_PREFIX: &str = "PROP_LOT_COMMENT_"; - -fn idea_cache_key(id: isize) -> String { - format!("{}{}", IDEA_CACHE_KEY_PREFIX, id) -} - -fn vote_cache_key(id: isize) -> String { - format!("{}{}", VOTE_CACHE_KEY_PREFIX, id) -} - -fn comment_cache_key(id: isize) -> String { - format!("{}{}", COMMENT_CACHE_KEY_PREFIX, id) -} - -pub(crate) fn set_idea_cache(idea: &Idea) -> Result<()> { - let cache = &cache::CACHE; - cache.set(idea_cache_key(idea.id), idea) -} - -pub(crate) fn set_ideas_cache(ideas: &[Idea]) -> Result<()> { - let cache = &cache::CACHE; - let items: Vec<_> = ideas - .iter() - .map(|idea| (idea_cache_key(idea.id), idea)) - .collect(); - cache.set_batch(items) -} - -pub(crate) fn get_idea_cache(id: isize) -> Result> { - let cache = &cache::CACHE; - cache.get::(&idea_cache_key(id)) -} - -pub(crate) fn set_vote_cache(vote: &Vote) -> Result<()> { - let cache = &cache::CACHE; - cache.set(vote_cache_key(vote.id), vote) -} - -pub(crate) fn set_votes_cache(votes: &[Vote]) -> Result<()> { - let cache = &cache::CACHE; - let items: Vec<_> = votes - .iter() - .map(|vote| (vote_cache_key(vote.id), vote)) - .collect(); - cache.set_batch(items) -} - -pub(crate) fn get_vote_cache(id: isize) -> Result> { - let cache = &cache::CACHE; - cache.get::(&vote_cache_key(id)) -} - -pub(crate) fn set_comment_cache(comment: &Comment) -> Result<()> { - let cache = &cache::CACHE; - cache.set(comment_cache_key(comment.id), comment) -} - -pub(crate) fn set_comments_cache(comments: &[Comment]) -> Result<()> { - let cache = &cache::CACHE; - let items: Vec<_> = comments - .iter() - .map(|comment| (comment_cache_key(comment.id), comment)) - .collect(); - cache.set_batch(items) -} - -pub(crate) fn get_comment_cache(id: isize) -> Result> { - let cache = &cache::CACHE; - cache.get::(&comment_cache_key(id)) -} From db710fd299cdbae63f4fc1633d55deb9bb5a7bc7 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Tue, 19 Sep 2023 23:48:11 +0330 Subject: [PATCH 14/31] chore: update `dev` script in `package.json` Modified the "dev" script in package.json to include "--test-scheduled" flag. This addition allows us to simulate and test scheduled tasks during development, making sure they run properly before deployment. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8419224..bf0f0ea 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "private": true, "scripts": { "deploy": "wrangler deploy", - "dev": "wrangler dev" + "dev": "wrangler dev --test-scheduled" }, "devDependencies": { "wrangler": "3.8.0" From c9185ac5a21cfff84490f676c8a8e37cab440a5d Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 07:07:36 +0330 Subject: [PATCH 15/31] chore: add `.wrangler` to `.gitignore` Added .wrangler directory to .gitignore to prevent it from being tracked. The .wrangler directory contains build artifacts that are not meant to be version controlled. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8ade55a..7b46c1d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /tmp /report.* /node_modules +/.wrangler From 8bb677aaf06f3d3c2e262299f0ed1613f4981e07 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 07:13:04 +0330 Subject: [PATCH 16/31] chore(deps): add `worker_logger` dependency to `Cargo.toml` A new 'worker_logger' dependency has been added to the Rust project to handle logging services. The version of 'worker_logger' used here is 0.2.0 and the feature 'color' has been activated to introduce colored logs for ease of visual navigation through logs. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 0461099..527d6b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ reqwest = "0.11.20" serde = { version = "1.0.188", features = ["derive"] } serde_json = "1.0.107" worker = "0.0.18" +worker_logger = { version = "0.2.0", features = ["color"] } [profile.release] lto = true From bb25140686307a3ad2552287eecf7a10f011c96d Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 07:13:37 +0330 Subject: [PATCH 17/31] chore(deps): add `cfg-if` dependency to `Cargo.toml` The cfg-if crate is added as a new dependency in the project. This library gives us a readable and ergonomic way to have conditional compilation in the codebase. It is essential for handling platform-specific code in a convenient and efficient manner. --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 527d6b2..f9a7fe8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ crate-type = ["cdylib"] [dependencies] anyhow = "1.0.75" +cfg-if = "1.0.0" chrono = "0.4.31" env_logger = "0.10.0" futures = "0.3.28" From c9c3d0fff736f9e47d1cd6679f4e1997409dc405 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 07:14:35 +0330 Subject: [PATCH 18/31] chore(deps): add `console_error_panic_hook` as optional dependency Included console_error_panic_hook into `Cargo.toml` file as an optional feature and a dependency. This was done to improve error messages in WebAssembly by using console_error_panic_hook which provides better visibility on error traces. This change doesn't affect the default behaviour and is optional. --- Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index f9a7fe8..1129b7c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,9 @@ wasm-opt = false [lib] crate-type = ["cdylib"] +[features] +default = ["console_error_panic_hook"] + [dependencies] anyhow = "1.0.75" cfg-if = "1.0.0" @@ -28,6 +31,7 @@ serde = { version = "1.0.188", features = ["derive"] } serde_json = "1.0.107" worker = "0.0.18" worker_logger = { version = "0.2.0", features = ["color"] } +console_error_panic_hook = { version = "0.1.7", optional = true } [profile.release] lto = true From 819d025178a78622974624dc6932b696fd47602d Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 07:24:06 +0330 Subject: [PATCH 19/31] refactor: update fetcher functions to use worker env The fetcher functions in both prop_house and prop_lot modules have been refactored to use worker::Env instead of std::env. This change simplifies the handling of environment variables and reduces dependencies. It also removes several lines of repetitive code and unifies the way environment variables are accessed across the modules, therefore improving the readability and maintainability of the code. The dependency on std::time::Duration was removed as it was no longer required. --- src/prop_house/fetcher.rs | 48 ++++++++++++++++++++++----------------- src/prop_lot/fetcher.rs | 23 ++++++++++--------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/src/prop_house/fetcher.rs b/src/prop_house/fetcher.rs index 8e3a535..c7a65ba 100644 --- a/src/prop_house/fetcher.rs +++ b/src/prop_house/fetcher.rs @@ -1,11 +1,9 @@ -use std::env; -use std::time::Duration; - use graphql_client::reqwest::post_graphql; use graphql_client::GraphQLQuery; use log::error; use reqwest::Client; use serde::{Deserialize, Serialize}; +use worker::Env; #[derive(GraphQLQuery)] #[graphql( @@ -62,16 +60,18 @@ pub(crate) struct Vote { } async fn fetch( + env: &Env, variables: ::Variables, ) -> Option<::ResponseData> { - let url = env::var("PROP_HOUSE_GRAPHQL_URL") + let url = env + .var("PROP_HOUSE_GRAPHQL_URL") .map_err(|_| { error!("PROP_HOUSE_GRAPHQL_URL is not set in env"); }) - .ok()?; + .ok()? + .to_string(); let client = Client::builder() - .timeout(Duration::from_secs(30)) .build() .map_err(|e| { error!("Failed to create client: {}", e); @@ -87,18 +87,20 @@ async fn fetch( .and_then(|response| response.data) } -pub(crate) async fn fetch_auctions() -> Option> { - let community_id = env::var("PROP_HOUSE_COMMUNITY_ID") +pub(crate) async fn fetch_auctions(env: &Env) -> Option> { + let community_id = env + .var("PROP_HOUSE_COMMUNITY_ID") .map_err(|_| { - error!("PROP_HOUSE_GRAPHQL_URL is not set in env"); + error!("PROP_HOUSE_COMMUNITY_ID is not set in env"); }) - .ok()?; + .ok()? + .to_string(); let variables = auction_query::Variables { id: community_id.parse().unwrap(), }; - let response = fetch::(variables).await?; + let response = fetch::(env, variables).await?; let auctions = response .community @@ -114,18 +116,20 @@ pub(crate) async fn fetch_auctions() -> Option> { Some(auctions) } -pub(crate) async fn fetch_proposals() -> Option> { - let community_id = env::var("PROP_HOUSE_COMMUNITY_ID") +pub(crate) async fn fetch_proposals(env: &Env) -> Option> { + let community_id = env + .var("PROP_HOUSE_COMMUNITY_ID") .map_err(|_| { - error!("PROP_HOUSE_GRAPHQL_URL is not set in env"); + error!("PROP_HOUSE_COMMUNITY_ID is not set in env"); }) - .ok()?; + .ok()? + .to_string(); let variables = proposal_query::Variables { id: community_id.parse().unwrap(), }; - let response = fetch::(variables).await?; + let response = fetch::(env, variables).await?; let proposals = response .community @@ -144,18 +148,20 @@ pub(crate) async fn fetch_proposals() -> Option> { Some(proposals) } -pub(crate) async fn fetch_votes() -> Option> { - let community_id = env::var("PROP_HOUSE_COMMUNITY_ID") +pub(crate) async fn fetch_votes(env: &Env) -> Option> { + let community_id = env + .var("PROP_HOUSE_COMMUNITY_ID") .map_err(|_| { - error!("PROP_HOUSE_GRAPHQL_URL is not set in env"); + error!("PROP_HOUSE_COMMUNITY_ID is not set in env"); }) - .ok()?; + .ok()? + .to_string(); let variables = vote_query::Variables { id: community_id.parse().unwrap(), }; - let response = fetch::(variables).await?; + let response = fetch::(env, variables).await?; let votes = response .community diff --git a/src/prop_lot/fetcher.rs b/src/prop_lot/fetcher.rs index 26b8f0c..ac8f3ee 100644 --- a/src/prop_lot/fetcher.rs +++ b/src/prop_lot/fetcher.rs @@ -1,12 +1,11 @@ use std::convert::TryInto; -use std::env; -use std::time::Duration; use graphql_client::reqwest::post_graphql; use graphql_client::GraphQLQuery; use log::error; use reqwest::Client; use serde::{Deserialize, Serialize}; +use worker::Env; #[derive(GraphQLQuery)] #[graphql( @@ -63,16 +62,18 @@ pub(crate) struct Comment { } async fn fetch( + env: &Env, variables: ::Variables, ) -> Option<::ResponseData> { - let url = env::var("PROP_LOT_GRAPHQL_URL") + let url = env + .var("PROP_LOT_GRAPHQL_URL") .map_err(|_| { error!("PROP_LOT_GRAPHQL_URL is not set in env"); }) - .ok()?; + .ok()? + .to_string(); let client = Client::builder() - .timeout(Duration::from_secs(30)) .build() .map_err(|e| { error!("Failed to create client: {}", e); @@ -88,7 +89,7 @@ async fn fetch( .and_then(|response| response.data) } -pub(crate) async fn fetch_ideas() -> Option> { +pub(crate) async fn fetch_ideas(env: &Env) -> Option> { let variables = idea_query::Variables { options: idea_query::IdeaInputOptions { idea_id: None, @@ -96,7 +97,7 @@ pub(crate) async fn fetch_ideas() -> Option> { }, }; - let response = fetch::(variables).await?; + let response = fetch::(env, variables).await?; let ideas = response .ideas @@ -113,7 +114,7 @@ pub(crate) async fn fetch_ideas() -> Option> { Some(ideas) } -pub(crate) async fn fetch_votes() -> Option> { +pub(crate) async fn fetch_votes(env: &Env) -> Option> { let variables = vote_query::Variables { options: vote_query::IdeaInputOptions { idea_id: None, @@ -121,7 +122,7 @@ pub(crate) async fn fetch_votes() -> Option> { }, }; - let response = fetch::(variables).await?; + let response = fetch::(env, variables).await?; let votes = response .ideas @@ -141,7 +142,7 @@ pub(crate) async fn fetch_votes() -> Option> { Some(votes) } -pub(crate) async fn fetch_comments() -> Option> { +pub(crate) async fn fetch_comments(env: &Env) -> Option> { let variables = comment_query::Variables { options: comment_query::IdeaInputOptions { idea_id: None, @@ -149,7 +150,7 @@ pub(crate) async fn fetch_comments() -> Option> { }, }; - let response = fetch::(variables).await?; + let response = fetch::(env, variables).await?; let comments = response .ideas From 24ee03c4761ede1e830127c101ded973fdad0479 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 08:39:31 +0330 Subject: [PATCH 20/31] refactor: update fetcher to use GraphQLFetcher struct This commit refactors the fetching code in both `fetcher.rs` files under the `src/prop_house` and `src/prop_lot` directories. The code is refactored into a new structure `GraphQLFetcher` that performs fetching and handles environment variables more efficiently. This refactoring simplifies the fetcher logic and makes the code more readable and maintainable. The `fetch_auctions`, `fetch_proposals`, `fetch_votes`, `fetch_ideas`, and `fetch_comments` methods now belong to the `GraphQLFetcher` struct, and just use its method `fetch`, passing in only the necessary variables. --- src/prop_house/fetcher.rs | 220 ++++++++++++++++++-------------------- src/prop_lot/fetcher.rs | 214 ++++++++++++++++++------------------ 2 files changed, 213 insertions(+), 221 deletions(-) diff --git a/src/prop_house/fetcher.rs b/src/prop_house/fetcher.rs index c7a65ba..6568f2c 100644 --- a/src/prop_house/fetcher.rs +++ b/src/prop_house/fetcher.rs @@ -3,7 +3,7 @@ use graphql_client::GraphQLQuery; use log::error; use reqwest::Client; use serde::{Deserialize, Serialize}; -use worker::Env; +use worker::{Env, Result}; #[derive(GraphQLQuery)] #[graphql( @@ -59,124 +59,112 @@ pub(crate) struct Vote { pub(crate) direction: isize, } -async fn fetch( - env: &Env, - variables: ::Variables, -) -> Option<::ResponseData> { - let url = env - .var("PROP_HOUSE_GRAPHQL_URL") - .map_err(|_| { - error!("PROP_HOUSE_GRAPHQL_URL is not set in env"); - }) - .ok()? - .to_string(); - - let client = Client::builder() - .build() - .map_err(|e| { - error!("Failed to create client: {}", e); - }) - .ok()?; - - post_graphql::(&client, url, variables) - .await - .map_err(|e| { - error!("Failed to execute GraphQL request: {}", e); - }) - .ok() - .and_then(|response| response.data) +pub struct GraphQLFetcher<'a> { + _env: &'a Env, + url: String, + community_id: String, } -pub(crate) async fn fetch_auctions(env: &Env) -> Option> { - let community_id = env - .var("PROP_HOUSE_COMMUNITY_ID") - .map_err(|_| { - error!("PROP_HOUSE_COMMUNITY_ID is not set in env"); - }) - .ok()? - .to_string(); - - let variables = auction_query::Variables { - id: community_id.parse().unwrap(), - }; - - let response = fetch::(env, variables).await?; - - let auctions = response - .community - .auctions - .iter() - .map(|auction| Auction { - id: auction.id.try_into().unwrap(), - title: auction.title.clone(), - description: html2md::parse_html(&auction.description), - }) - .collect(); +impl<'a> GraphQLFetcher<'a> { + pub fn new(env: &'a Env) -> Result> { + let url = env.var("PROP_HOUSE_GRAPHQL_URL")?.to_string(); - Some(auctions) -} + let community_id = env.var("PROP_HOUSE_COMMUNITY_ID")?.to_string(); -pub(crate) async fn fetch_proposals(env: &Env) -> Option> { - let community_id = env - .var("PROP_HOUSE_COMMUNITY_ID") - .map_err(|_| { - error!("PROP_HOUSE_COMMUNITY_ID is not set in env"); + Ok(GraphQLFetcher { + _env: env, + url, + community_id, }) - .ok()? - .to_string(); - - let variables = proposal_query::Variables { - id: community_id.parse().unwrap(), - }; - - let response = fetch::(env, variables).await?; - - let proposals = response - .community - .auctions - .iter() - .flat_map(|auction| &auction.proposals) - .map(|proposal| Proposal { - id: proposal.id.try_into().unwrap(), - title: proposal.title.clone(), - tldr: proposal.tldr.clone(), - address: proposal.address.clone(), - auction_id: proposal.auction.id.try_into().unwrap(), - }) - .collect(); - - Some(proposals) -} - -pub(crate) async fn fetch_votes(env: &Env) -> Option> { - let community_id = env - .var("PROP_HOUSE_COMMUNITY_ID") - .map_err(|_| { - error!("PROP_HOUSE_COMMUNITY_ID is not set in env"); - }) - .ok()? - .to_string(); - - let variables = vote_query::Variables { - id: community_id.parse().unwrap(), - }; - - let response = fetch::(env, variables).await?; - - let votes = response - .community - .auctions - .iter() - .flat_map(|auction| &auction.proposals) - .flat_map(|proposal| &proposal.votes) - .map(|vote| Vote { - id: vote.id.try_into().unwrap(), - address: vote.address.clone(), - auction_id: vote.auction_id.try_into().unwrap(), - proposal_id: vote.proposal_id.try_into().unwrap(), - direction: vote.direction.try_into().unwrap(), - }) - .collect(); - - Some(votes) + } + + async fn fetch( + &self, + variables: ::Variables, + ) -> Option<::ResponseData> { + let client = Client::builder() + .build() + .map_err(|e| { + error!("Failed to create client: {}", e); + }) + .ok()?; + + post_graphql::(&client, &self.url, variables) + .await + .map_err(|e| { + error!("Failed to execute GraphQL request: {}", e); + }) + .ok() + .and_then(|response| response.data) + } + + pub(crate) async fn fetch_auctions(&self) -> Option> { + let variables = auction_query::Variables { + id: self.community_id.parse().unwrap(), + }; + + let response = self.fetch::(variables).await?; + + let auctions = response + .community + .auctions + .iter() + .map(|auction| Auction { + id: auction.id.try_into().unwrap(), + title: auction.title.clone(), + description: html2md::parse_html(&auction.description), + }) + .collect(); + + Some(auctions) + } + + pub(crate) async fn fetch_proposals(&self) -> Option> { + let variables = proposal_query::Variables { + id: self.community_id.parse().unwrap(), + }; + + let response = self.fetch::(variables).await?; + + let proposals = response + .community + .auctions + .iter() + .flat_map(|auction| &auction.proposals) + .map(|proposal| Proposal { + id: proposal.id.try_into().unwrap(), + title: proposal.title.clone(), + tldr: proposal.tldr.clone(), + address: proposal.address.clone(), + auction_id: proposal.auction.id.try_into().unwrap(), + }) + .collect(); + + Some(proposals) + } + + pub(crate) async fn fetch_votes(&self) -> Option> { + let variables = vote_query::Variables { + id: self.community_id.parse().unwrap(), + }; + + let response = self.fetch::(variables).await?; + + let votes = response + .community + .auctions + .iter() + .flat_map(|auction| &auction.proposals) + .flat_map(|proposal| &proposal.votes) + .map(|vote| Vote { + id: vote.id.try_into().unwrap(), + address: vote.address.clone(), + auction_id: vote.auction_id.try_into().unwrap(), + proposal_id: vote.proposal_id.try_into().unwrap(), + direction: vote.direction.try_into().unwrap(), + }) + .collect(); + + Some(votes) + } } diff --git a/src/prop_lot/fetcher.rs b/src/prop_lot/fetcher.rs index ac8f3ee..3efa582 100644 --- a/src/prop_lot/fetcher.rs +++ b/src/prop_lot/fetcher.rs @@ -5,7 +5,7 @@ use graphql_client::GraphQLQuery; use log::error; use reqwest::Client; use serde::{Deserialize, Serialize}; -use worker::Env; +use worker::{Env, Result}; #[derive(GraphQLQuery)] #[graphql( @@ -61,110 +61,114 @@ pub(crate) struct Comment { pub(crate) body: String, } -async fn fetch( - env: &Env, - variables: ::Variables, -) -> Option<::ResponseData> { - let url = env - .var("PROP_LOT_GRAPHQL_URL") - .map_err(|_| { - error!("PROP_LOT_GRAPHQL_URL is not set in env"); - }) - .ok()? - .to_string(); - - let client = Client::builder() - .build() - .map_err(|e| { - error!("Failed to create client: {}", e); - }) - .ok()?; - - post_graphql::(&client, url, variables) - .await - .map_err(|e| { - error!("Failed to execute GraphQL request: {}", e); - }) - .ok() - .and_then(|response| response.data) +pub struct GraphQLFetcher<'a> { + _env: &'a Env, + url: String, } -pub(crate) async fn fetch_ideas(env: &Env) -> Option> { - let variables = idea_query::Variables { - options: idea_query::IdeaInputOptions { - idea_id: None, - sort: Some(idea_query::SORT_TYPE::OLDEST), - }, - }; - - let response = fetch::(env, variables).await?; - - let ideas = response - .ideas - .as_ref()? - .iter() - .map(|idea| Idea { - id: idea.id.try_into().unwrap(), - title: idea.title.clone(), - tldr: idea.tldr.clone(), - creator_id: idea.creator_id.clone(), - }) - .collect(); - - Some(ideas) -} - -pub(crate) async fn fetch_votes(env: &Env) -> Option> { - let variables = vote_query::Variables { - options: vote_query::IdeaInputOptions { - idea_id: None, - sort: Some(vote_query::SORT_TYPE::LATEST), - }, - }; - - let response = fetch::(env, variables).await?; - - let votes = response - .ideas - .as_ref()? - .iter() - .flat_map(|idea| idea.votes.iter()) - .flat_map(|vote| vote.iter()) - .map(|vote| Vote { - id: vote.id.try_into().unwrap(), - voter_id: vote.voter_id.clone(), - idea_id: vote.idea_id.try_into().unwrap(), - direction: vote.direction.try_into().unwrap(), - voter_weight: vote.voter_weight.try_into().unwrap(), - }) - .collect(); - - Some(votes) -} - -pub(crate) async fn fetch_comments(env: &Env) -> Option> { - let variables = comment_query::Variables { - options: comment_query::IdeaInputOptions { - idea_id: None, - sort: Some(comment_query::SORT_TYPE::LATEST), - }, - }; - - let response = fetch::(env, variables).await?; - - let comments = response - .ideas - .as_ref()? - .iter() - .flat_map(|idea| idea.comments.iter()) - .flat_map(|comment| comment.iter()) - .map(|comment| Comment { - id: comment.id.try_into().unwrap(), - idea_id: comment.id.try_into().unwrap(), - author_id: comment.author_id.clone(), - body: comment.body.clone(), - }) - .collect(); - - Some(comments) +impl<'a> GraphQLFetcher<'a> { + pub fn new(env: &'a Env) -> Result> { + let url = env.var("PROP_LOT_GRAPHQL_URL")?.to_string(); + + Ok(GraphQLFetcher { _env: env, url }) + } + async fn fetch( + &self, + variables: ::Variables, + ) -> Option<::ResponseData> { + let client = Client::builder() + .build() + .map_err(|e| { + error!("Failed to create client: {}", e); + }) + .ok()?; + + post_graphql::(&client, &self.url, variables) + .await + .map_err(|e| { + error!("Failed to execute GraphQL request: {}", e); + }) + .ok() + .and_then(|response| response.data) + } + + pub(crate) async fn fetch_ideas(&self) -> Option> { + let variables = idea_query::Variables { + options: idea_query::IdeaInputOptions { + idea_id: None, + sort: Some(idea_query::SORT_TYPE::OLDEST), + }, + }; + + let response = self.fetch::(variables).await?; + + let ideas = response + .ideas + .as_ref()? + .iter() + .map(|idea| Idea { + id: idea.id.try_into().unwrap(), + title: idea.title.clone(), + tldr: idea.tldr.clone(), + creator_id: idea.creator_id.clone(), + }) + .collect(); + + Some(ideas) + } + + pub(crate) async fn fetch_votes(&self) -> Option> { + let variables = vote_query::Variables { + options: vote_query::IdeaInputOptions { + idea_id: None, + sort: Some(vote_query::SORT_TYPE::LATEST), + }, + }; + + let response = self.fetch::(variables).await?; + + let votes = response + .ideas + .as_ref()? + .iter() + .flat_map(|idea| idea.votes.iter()) + .flat_map(|vote| vote.iter()) + .map(|vote| Vote { + id: vote.id.try_into().unwrap(), + voter_id: vote.voter_id.clone(), + idea_id: vote.idea_id.try_into().unwrap(), + direction: vote.direction.try_into().unwrap(), + voter_weight: vote.voter_weight.try_into().unwrap(), + }) + .collect(); + + Some(votes) + } + + pub(crate) async fn fetch_comments(&self) -> Option> { + let variables = comment_query::Variables { + options: comment_query::IdeaInputOptions { + idea_id: None, + sort: Some(comment_query::SORT_TYPE::LATEST), + }, + }; + + let response = self.fetch::(variables).await?; + + let comments = response + .ideas + .as_ref()? + .iter() + .flat_map(|idea| idea.comments.iter()) + .flat_map(|comment| comment.iter()) + .map(|comment| Comment { + id: comment.id.try_into().unwrap(), + idea_id: comment.id.try_into().unwrap(), + author_id: comment.author_id.clone(), + body: comment.body.clone(), + }) + .collect(); + + Some(comments) + } } From 8cbc3c1b2f5eb4cd5b983f4d0a50c06f9d32c533 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 13:32:31 +0330 Subject: [PATCH 21/31] refactor: add caching functionality to enhance performance A new struct 'Cache' was introduced in the crate 'cache.rs' which acts as a key-value (KV) store. It abstracts the functionalities of a KV store with methods for putting and getting data. The data is serialized and deserialized using the serde library. This cache layer will boost the performance by reducing the need for direct database calls. --- src/cache.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/cache.rs diff --git a/src/cache.rs b/src/cache.rs new file mode 100644 index 0000000..700cecb --- /dev/null +++ b/src/cache.rs @@ -0,0 +1,37 @@ +use log::error; +use serde::de::DeserializeOwned; +use serde::ser::Serialize; +use worker::kv::KvError; +use worker::Env; + +pub struct Cache<'a> { + store_name: String, + env: &'a Env, +} + +impl<'a> Cache<'a> { + pub fn new(store_name: String, env: &'a Env) -> Self { + Self { store_name, env } + } + + pub fn from(env: &'a Env) -> Self { + let store_name = env.var("KV_STORE_NAME").unwrap().to_string(); + + Self::new(store_name, env) + } + + pub async fn put(&self, key: &str, value: &T) { + let kv = self.env.kv(&self.store_name).unwrap(); + if let Ok(put) = kv.put(key, value) { + if let Err(pe) = put.execute().await { + error!("Failed updating KV: {}", pe) + } + } + } + + pub async fn get(&self, key: &str) -> Result, KvError> { + let kv = self.env.kv(&self.store_name).unwrap(); + + kv.get(key).json::().await + } +} From 8a699054d66d0778e9531fbe131dc7e9cc80e6aa Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 14:28:24 +0330 Subject: [PATCH 22/31] refactor: move code into `lib.rs` for modularity and error handling Moved the logic from main.rs to lib.rs for better code organization and easy maintenance. The setup and start processes for "prop_lot" and "prop_house" have been modified to check the cache before execution. This change enhances efficiency and provides better control over error handling. --- src/lib.rs | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 54 ---------------------------------- 2 files changed, 84 insertions(+), 54 deletions(-) create mode 100644 src/lib.rs delete mode 100644 src/main.rs diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..b1f70f8 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,84 @@ +use cfg_if::cfg_if; +use log::{error, info, Level}; +use worker::{event, Date, Env, Request, Response, Result, ScheduleContext, ScheduledEvent}; + +use prop_house::fetcher::GraphQLFetcher as PropHouseGraphQLFetcher; +use prop_house::handler::DiscordHandler as PropHouseDiscordHandler; +use prop_lot::fetcher::GraphQLFetcher as PropLotGraphQLFetcher; +use prop_lot::handler::DiscordHandler as PropLotDiscordHandler; + +use crate::cache::Cache; + +mod cache; +mod prop_house; +mod prop_lot; + +cfg_if! { + // https://github.com/rustwasm/console_error_panic_hook#readme + if #[cfg(feature = "console_error_panic_hook")] { + pub use console_error_panic_hook::set_once as set_panic_hook; + } else { + #[inline] + pub fn set_panic_hook() {} + } +} + +#[event(scheduled)] +async fn cron(_event: ScheduledEvent, env: Env, _ctx: ScheduleContext) { + worker_logger::init_with_level(&Level::Debug); + set_panic_hook(); + + let cache = Cache::from(&env); + + let prop_lot_key = "PROP_LOT_SETUP"; + let prop_lot_fetcher = PropLotGraphQLFetcher::new(&env).unwrap(); + let prop_lot_handler = PropLotDiscordHandler::new(&env).unwrap(); + + let prop_house_key = "PROP_HOUSE_SETUP"; + let prop_house_fetcher = PropHouseGraphQLFetcher::new(&env).unwrap(); + let prop_house_handler = PropHouseDiscordHandler::new(&env).unwrap(); + + if cache.get::(prop_lot_key).await.ok().is_none() { + if let Err(e) = prop_lot::setup(&cache, &prop_lot_fetcher).await { + error!("Failed to setup prop_lot: {}", e); + } else { + // On successful setup, set the key in the cache. + let now: String = chrono::Utc::now().to_string(); + cache.put(prop_lot_key, &now).await; + } + } + + if let Err(e) = prop_lot::start(&cache, &prop_lot_fetcher, &prop_lot_handler).await { + error!("Failed to start prop_lot: {}", e); + } + + if cache.get::(prop_house_key).await.ok().is_none() { + if let Err(e) = prop_house::setup(&cache, &prop_house_fetcher).await { + error!("Failed to setup prop_house: {}", e); + } else { + // On successful setup, set the key in the cache. + let now = chrono::Utc::now().to_string(); + cache.put(prop_house_key, &now).await; + } + } + + if let Err(e) = prop_house::start(&cache, &prop_house_fetcher, &prop_house_handler).await { + error!("Failed to start prop_house: {}", e); + } +} + +#[event(fetch)] +pub async fn main(req: Request, _env: Env, _ctx: worker::Context) -> Result { + worker_logger::init_with_level(&Level::Debug); + set_panic_hook(); + + info!( + "{} - [{}], located at: {:?}, within: {}", + Date::now().to_string(), + req.path(), + req.cf().coordinates().unwrap_or_default(), + req.cf().region().unwrap_or_else(|| "unknown region".into()) + ); + + Response::error("Bad Request", 400) +} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index f74f2e5..0000000 --- a/src/main.rs +++ /dev/null @@ -1,54 +0,0 @@ -use clap::{Parser, Subcommand}; -use env_logger::Env; -use log::{info, warn}; - -mod cache; -mod prop_house; -mod prop_lot; - -#[derive(Parser)] -#[command(author, version, about, long_about = None)] -struct Cli { - #[command(subcommand)] - command: Option, -} - -#[derive(Subcommand)] -enum Commands { - /// Runs setups - Setup { - /// Forces the setup - #[arg(short, long)] - force: bool, - }, - /// Starts the program - Start, -} - -#[tokio::main] -async fn main() { - let env = Env::default() - .filter_or("BOT_LOG_LEVEL", "trace") - .write_style_or("BOT_LOG_STYLE", "always"); - - env_logger::init_from_env(env); - - let cli = Cli::parse(); - - match &cli.command { - Some(Commands::Setup { force }) => { - if *force { - info!("Running setup..."); - prop_lot::setup().await; - prop_house::setup().await; - } else { - warn!("Setup not forced, not running..."); - } - } - Some(Commands::Start) => { - prop_lot::start().await; - prop_house::start().await; - } - None => {} - } -} From 3fa7aba7cb027f8dce559ea28b02be53625d65af Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 15:24:02 +0330 Subject: [PATCH 23/31] refactor: update caching and fetching mechanism Changed the setup and start functions in both prop_house and prop_lot modules. Instead of separate cache and fetch functions for each data type (auctions, proposals, votes, ideas, comments), created general fetch and cache functions, simplifying the code and reducing redundancy. This makes the system more maintainable by adhering to the DRY (Don't Repeat Yourself) principle. The methods now also return a Result, thus improving error handling. --- src/prop_house/mod.rs | 110 +++++++++++++++++++++++++----------------- src/prop_lot/mod.rs | 104 ++++++++++++++++++++++----------------- 2 files changed, 128 insertions(+), 86 deletions(-) diff --git a/src/prop_house/mod.rs b/src/prop_house/mod.rs index c18eff0..b947ca1 100644 --- a/src/prop_house/mod.rs +++ b/src/prop_house/mod.rs @@ -1,73 +1,97 @@ use log::{error, info}; +use worker::Result; -use fetcher::fetch_auctions; +use fetcher::{Auction, GraphQLFetcher, Proposal, Vote}; +use handler::DiscordHandler; -use crate::prop_house::cacher::{ - get_auction_cache, get_proposal_cache, get_vote_cache, set_auctions_cache, set_proposals_cache, - set_votes_cache, -}; -use crate::prop_house::fetcher::{fetch_proposals, fetch_votes}; -use crate::prop_house::handler::DiscordHandler; +use crate::cache::Cache; -mod cacher; -mod fetcher; -mod handler; +pub mod fetcher; +pub mod handler; -pub async fn setup() { - if let Some(auctions) = fetch_auctions().await { - set_auctions_cache(&auctions).unwrap(); +pub async fn setup(cache: &Cache<'_>, fetcher: &GraphQLFetcher<'_>) -> Result<()> { + if let Some(auctions) = fetcher.fetch_auctions().await { + for auction in auctions { + cache + .put( + &format!("{}{}", "PROP_HOUSE_AUCTION_", auction.id), + &auction, + ) + .await; + } } - if let Some(proposals) = fetch_proposals().await { - set_proposals_cache(&proposals).unwrap(); + if let Some(proposals) = fetcher.fetch_proposals().await { + for proposal in proposals { + cache + .put( + &format!("{}{}", "PROP_HOUSE_PROPOSAL_", proposal.id), + &proposal, + ) + .await; + } } - if let Some(votes) = fetch_votes().await { - set_votes_cache(&votes).unwrap(); + if let Some(votes) = fetcher.fetch_votes().await { + for vote in votes { + cache + .put(&format!("{}{}", "PROP_HOUSE_VOTE_", vote.id), &vote) + .await; + } } -} -pub async fn start() { - let handler = DiscordHandler::new() - .await - .expect("Could not create a new DiscordHandler"); + Ok(()) +} - if let Some(auctions) = fetch_auctions().await { +pub async fn start( + cache: &Cache<'_>, + fetcher: &GraphQLFetcher<'_>, + handler: &DiscordHandler<'_>, +) -> Result<()> { + if let Some(auctions) = fetcher.fetch_auctions().await { for auction in auctions { - if let Ok(cached_auction) = get_auction_cache(auction.id) { - if cached_auction.is_none() { - info!("Handle a new auction... ({:?})", auction.id); - if let Err(err) = handler.handle_new_auction(&auction).await { - error!("Failed to handle new auction: {:?}", err); - } + let cached_auction: Option = cache + .get(&format!("{}{}", "PROP_HOUSE_AUCTION_", auction.id)) + .await?; + + if cached_auction.is_none() { + info!("Handle a new auction... ({:?})", auction.id); + if let Err(err) = handler.handle_new_auction(&auction).await { + error!("Failed to handle new auction: {:?}", err); } } } } - if let Some(proposals) = fetch_proposals().await { + if let Some(proposals) = fetcher.fetch_proposals().await { for proposal in proposals { - if let Ok(cached_proposal) = get_proposal_cache(proposal.id) { - if cached_proposal.is_none() { - info!("Handle a new proposal... ({:?})", proposal.id); - if let Err(err) = handler.handle_new_proposal(&proposal).await { - error!("Failed to handle new proposal: {:?}", err); - } + let cached_proposal: Option = cache + .get(&format!("{}{}", "PROP_HOUSE_PROPOSAL_", proposal.id)) + .await?; + + if cached_proposal.is_none() { + info!("Handle a new proposal... ({:?})", proposal.id); + if let Err(err) = handler.handle_new_proposal(&proposal).await { + error!("Failed to handle new proposal: {:?}", err); } } } } - if let Some(votes) = fetch_votes().await { + if let Some(votes) = fetcher.fetch_votes().await { for vote in votes { - if let Ok(cached_vote) = get_vote_cache(vote.id) { - if cached_vote.is_none() { - info!("Handle a new vote... ({:?})", vote.id); - if let Err(err) = handler.handle_new_vote(&vote).await { - error!("Failed to handle new vote: {:?}", err); - } + let cached_vote: Option = cache + .get(&format!("{}{}", "PROP_HOUSE_VOTE_", vote.id)) + .await?; + + if cached_vote.is_none() { + info!("Handle a new vote... ({:?})", vote.id); + if let Err(err) = handler.handle_new_vote(&vote).await { + error!("Failed to handle new vote: {:?}", err); } } } } + + Ok(()) } diff --git a/src/prop_lot/mod.rs b/src/prop_lot/mod.rs index 20b8e3c..c7c6728 100644 --- a/src/prop_lot/mod.rs +++ b/src/prop_lot/mod.rs @@ -1,73 +1,91 @@ use log::{error, info}; +use worker::Result; -use fetcher::fetch_ideas; +use fetcher::{Comment, GraphQLFetcher, Idea, Vote}; +use handler::DiscordHandler; -use crate::prop_lot::cacher::{ - get_comment_cache, get_idea_cache, get_vote_cache, set_comments_cache, set_ideas_cache, - set_votes_cache, -}; -use crate::prop_lot::fetcher::{fetch_comments, fetch_votes}; -use crate::prop_lot::handler::DiscordHandler; +use crate::cache::Cache; -mod cacher; -mod fetcher; -mod handler; +pub mod fetcher; +pub mod handler; -pub async fn setup() { - if let Some(ideas) = fetch_ideas().await { - set_ideas_cache(&ideas).unwrap(); +pub async fn setup(cache: &Cache<'_>, fetcher: &GraphQLFetcher<'_>) -> Result<()> { + if let Some(ideas) = fetcher.fetch_ideas().await { + for idea in ideas { + cache + .put(&format!("{}{}", "PROP_LOT_IDEA_", idea.id), &idea) + .await; + } } - if let Some(votes) = fetch_votes().await { - set_votes_cache(&votes).unwrap(); + if let Some(votes) = fetcher.fetch_votes().await { + for vote in votes { + cache + .put(&format!("{}{}", "PROP_LOT_VOTE_", vote.id), &vote) + .await; + } } - if let Some(comments) = fetch_comments().await { - set_comments_cache(&comments).unwrap(); + if let Some(comments) = fetcher.fetch_comments().await { + for comment in comments { + cache + .put(&format!("{}{}", "PROP_LOT_COMMENT_", comment.id), &comment) + .await; + } } -} -pub async fn start() { - let handler = DiscordHandler::new() - .await - .expect("Could not create a new DiscordHandler"); + Ok(()) +} - if let Some(ideas) = fetch_ideas().await { +pub async fn start( + cache: &Cache<'_>, + fetcher: &GraphQLFetcher<'_>, + handler: &DiscordHandler<'_>, +) -> Result<()> { + if let Some(ideas) = fetcher.fetch_ideas().await { for idea in &ideas { - if let Ok(cached_idea) = get_idea_cache(idea.id) { - if cached_idea.is_none() { - info!("Handle a new idea... ({:?})", idea.id); - if let Err(err) = handler.handle_new_idea(idea).await { - error!("Failed to handle new idea: {:?}", err); - } + let cached_idea: Option = cache + .get(&format!("{}{}", "PROP_LOT_IDEA_", idea.id)) + .await?; + + if cached_idea.is_none() { + info!("Handle a new idea... ({:?})", idea.id); + if let Err(err) = handler.handle_new_idea(idea).await { + error!("Failed to handle new idea: {:?}", err); } } } } - if let Some(votes) = fetch_votes().await { + if let Some(votes) = fetcher.fetch_votes().await { for vote in &votes { - if let Ok(cached_vote) = get_vote_cache(vote.id) { - if cached_vote.is_none() { - info!("Handle a new vote... ({:?})", vote.id); - if let Err(err) = handler.handle_new_vote(vote).await { - error!("Failed to handle new vote: {:?}", err); - } + let cached_vote: Option = cache + .get(&format!("{}{}", "PROP_LOT_VOTE_", vote.id)) + .await?; + + if cached_vote.is_none() { + info!("Handle a new vote... ({:?})", vote.id); + if let Err(err) = handler.handle_new_vote(vote).await { + error!("Failed to handle new vote: {:?}", err); } } } } - if let Some(comments) = fetch_comments().await { + if let Some(comments) = fetcher.fetch_comments().await { for comment in &comments { - if let Ok(cached_comment) = get_comment_cache(comment.id) { - if cached_comment.is_none() { - info!("Handle a new comment... ({:?})", comment.id); - if let Err(err) = handler.handle_new_comment(comment).await { - error!("Failed to handle new comment: {:?}", err); - } + let cached_comment: Option = cache + .get(&format!("{}{}", "PROP_LOT_COMMENT_", comment.id)) + .await?; + + if cached_comment.is_none() { + info!("Handle a new comment... ({:?})", comment.id); + if let Err(err) = handler.handle_new_comment(comment).await { + error!("Failed to handle new comment: {:?}", err); } } } } + + Ok(()) } From 4fd918dec31904413cae9cb38839fa165fb31884 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 15:26:46 +0330 Subject: [PATCH 24/31] refactor: update the `pnpm-lock.yaml` and `Cargo.lock` files --- Cargo.lock | 920 ++++++++++++------------------------------------- pnpm-lock.yaml | 56 +-- 2 files changed, 254 insertions(+), 722 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9549839..53a299d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,54 +41,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anstream" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" - -[[package]] -name = "anstyle-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" -dependencies = [ - "anstyle", - "windows-sys", -] - [[package]] name = "anyhow" version = "1.0.75" @@ -112,22 +64,6 @@ dependencies = [ "syn 2.0.32", ] -[[package]] -name = "async-tungstenite" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb" -dependencies = [ - "futures-io", - "futures-util", - "log", - "pin-project-lite", - "tokio", - "tokio-rustls 0.23.4", - "tungstenite", - "webpki-roots 0.22.6", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -149,39 +85,12 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" -[[package]] -name = "bindgen" -version = "0.65.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.32", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -194,15 +103,6 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - [[package]] name = "bumpalo" version = "3.13.0" @@ -221,24 +121,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "cc" version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ - "jobserver", "libc", ] @@ -248,15 +136,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -278,62 +157,38 @@ dependencies = [ ] [[package]] -name = "clang-sys" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "4.4.4" +name = "chrono-tz" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "f1369bc6b9e9a7dfdae2055f6ec151fe9c554a9d23d357c0237cee2e25eaabb7" dependencies = [ - "clap_builder", - "clap_derive", + "chrono", + "chrono-tz-build", + "phf 0.11.2", ] [[package]] -name = "clap_builder" -version = "4.4.4" +name = "chrono-tz-build" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "e2f5ebdc942f57ed96d560a6d1a459bae5851102a25d5bf89dc04ae453e31ecf" dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", + "parse-zoneinfo", + "phf 0.11.2", + "phf_codegen 0.11.2", ] [[package]] -name = "clap_derive" -version = "4.4.2" +name = "colored" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.32", + "is-terminal", + "lazy_static", + "windows-sys", ] -[[package]] -name = "clap_lex" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - [[package]] name = "combine" version = "3.8.1" @@ -357,6 +212,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -373,44 +238,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "cpufeatures" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" -dependencies = [ - "libc", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "deranged" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" -dependencies = [ - "serde", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - [[package]] name = "either" version = "1.9.0" @@ -595,16 +422,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - [[package]] name = "getrandom" version = "0.2.10" @@ -612,8 +429,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -622,12 +441,6 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - [[package]] name = "graphql-introspection-query" version = "0.2.0" @@ -816,20 +629,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls 0.21.7", - "tokio", - "tokio-rustls 0.24.1", -] - [[package]] name = "hyper-tls" version = "0.5.0" @@ -929,20 +728,11 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" -[[package]] -name = "jobserver" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] - [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" dependencies = [ "wasm-bindgen", ] @@ -953,73 +743,31 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "librocksdb-sys" -version = "0.11.0+8.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" -dependencies = [ - "bindgen", - "bzip2-sys", - "cc", - "glob", - "libc", - "libz-sys", - "lz4-sys", -] - -[[package]] -name = "libz-sys" -version = "1.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - [[package]] name = "lilnouns-bots" version = "1.0.0-alpha.7" dependencies = [ "anyhow", + "cfg-if", "chrono", - "clap", + "console_error_panic_hook", "env_logger", "futures", + "getrandom", "graphql_client", "html2md", - "lazy_static", "log", "reqwest", - "rocksdb", "serde", "serde_json", - "serenity", - "tokio", + "worker", + "worker_logger", ] [[package]] @@ -1044,16 +792,6 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "lz4-sys" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "mac" version = "0.1.1" @@ -1067,8 +805,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" dependencies = [ "log", - "phf", - "phf_codegen", + "phf 0.10.1", + "phf_codegen 0.10.0", "string_cache", "string_cache_codegen", "tendril", @@ -1086,6 +824,12 @@ dependencies = [ "xml5ever", ] +[[package]] +name = "matchit" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9376a4f0340565ad675d11fc1419227faf5f60cd7ac9cb2e7185a471f30af833" + [[package]] name = "memchr" version = "2.6.3" @@ -1098,22 +842,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1158,16 +886,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "num-traits" version = "0.2.16" @@ -1177,16 +895,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" version = "0.32.1" @@ -1246,15 +954,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "ordered-float" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" -dependencies = [ - "num-traits", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -1279,10 +978,13 @@ dependencies = [ ] [[package]] -name = "peeking_take_while" -version = "0.1.2" +name = "parse-zoneinfo" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] [[package]] name = "percent-encoding" @@ -1296,7 +998,16 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_shared", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared 0.11.2", ] [[package]] @@ -1305,8 +1016,18 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", ] [[package]] @@ -1315,7 +1036,17 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ - "phf_shared", + "phf_shared 0.10.0", + "rand", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", "rand", ] @@ -1329,17 +1060,46 @@ dependencies = [ ] [[package]] -name = "pin-project-lite" -version = "0.2.13" +name = "phf_shared" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] [[package]] -name = "pin-utils" -version = "0.1.0" +name = "pin-project" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - +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.32", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.27" @@ -1358,16 +1118,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -[[package]] -name = "prettyplease" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" -dependencies = [ - "proc-macro2", - "syn 2.0.32", -] - [[package]] name = "proc-macro2" version = "1.0.66" @@ -1460,7 +1210,7 @@ version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.4", + "base64", "bytes", "encoding_rs", "futures-core", @@ -1469,73 +1219,34 @@ dependencies = [ "http", "http-body", "hyper", - "hyper-rustls", "hyper-tls", "ipnet", "js-sys", "log", "mime", - "mime_guess", "native-tls", "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.7", - "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "tokio", "tokio-native-tls", - "tokio-rustls 0.24.1", - "tokio-util", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", "web-sys", - "webpki-roots 0.25.2", "winreg", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "rocksdb" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" -dependencies = [ - "libc", - "librocksdb-sys", -] - [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustix" version = "0.38.13" @@ -1549,49 +1260,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "rustls" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" -dependencies = [ - "log", - "ring", - "sct", - "webpki", -] - -[[package]] -name = "rustls" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" -dependencies = [ - "base64 0.21.4", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "ryu" version = "1.0.15" @@ -1622,16 +1290,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "security-framework" version = "2.9.2" @@ -1665,13 +1323,14 @@ dependencies = [ ] [[package]] -name = "serde-value" -version = "0.7.0" +name = "serde-wasm-bindgen" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" dependencies = [ - "ordered-float", + "js-sys", "serde", + "wasm-bindgen", ] [[package]] @@ -1708,49 +1367,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serenity" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d007dc45584ecc47e791f2a9a7cf17bf98ac386728106f111159c846d624be3f" -dependencies = [ - "async-trait", - "async-tungstenite", - "base64 0.13.1", - "bitflags 1.3.2", - "bytes", - "cfg-if", - "futures", - "mime", - "mime_guess", - "percent-encoding", - "reqwest", - "serde", - "serde-value", - "serde_json", - "time", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "sha-1" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - [[package]] name = "siphasher" version = "0.3.11" @@ -1792,12 +1408,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "string_cache" version = "0.8.7" @@ -1807,7 +1417,7 @@ dependencies = [ "new_debug_unreachable", "once_cell", "parking_lot", - "phf_shared", + "phf_shared 0.10.0", "precomputed-hash", "serde", ] @@ -1818,18 +1428,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.10.0", + "phf_shared 0.10.0", "proc-macro2", "quote", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "syn" version = "1.0.109" @@ -1905,34 +1509,6 @@ dependencies = [ "syn 2.0.32", ] -[[package]] -name = "time" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" -dependencies = [ - "deranged", - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" - -[[package]] -name = "time-macros" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" -dependencies = [ - "time-core", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -1958,24 +1534,11 @@ dependencies = [ "bytes", "libc", "mio", - "num_cpus", "pin-project-lite", "socket2 0.5.4", - "tokio-macros", "windows-sys", ] -[[package]] -name = "tokio-macros" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] - [[package]] name = "tokio-native-tls" version = "0.3.1" @@ -1986,27 +1549,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" -dependencies = [ - "rustls 0.20.9", - "tokio", - "webpki", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.7", - "tokio", -] - [[package]] name = "tokio-util" version = "0.7.8" @@ -2034,23 +1576,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", - "log", "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.32", -] - [[package]] name = "tracing-core" version = "0.1.31" @@ -2066,42 +1595,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "tungstenite" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" -dependencies = [ - "base64 0.13.1", - "byteorder", - "bytes", - "http", - "httparse", - "log", - "rand", - "rustls 0.20.9", - "sha-1", - "thiserror", - "url", - "utf-8", - "webpki", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.13" @@ -2132,12 +1625,6 @@ dependencies = [ "void", ] -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "url" version = "2.4.1" @@ -2147,7 +1634,6 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] [[package]] @@ -2156,24 +1642,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "void" version = "1.0.2" @@ -2207,9 +1681,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2217,9 +1691,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" dependencies = [ "bumpalo", "log", @@ -2232,9 +1706,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" dependencies = [ "cfg-if", "js-sys", @@ -2244,9 +1718,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2254,9 +1728,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", @@ -2267,9 +1741,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" [[package]] name = "wasm-streams" @@ -2286,39 +1760,14 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] - -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - [[package]] name = "winapi" version = "0.3.9" @@ -2435,6 +1884,89 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "worker" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd7ad167392bdd707a963356f3478844019c74fc89f6af0dfc656914b30af24" +dependencies = [ + "async-trait", + "chrono", + "chrono-tz", + "futures-channel", + "futures-util", + "http", + "js-sys", + "matchit", + "pin-project", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tokio", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "worker-kv", + "worker-macros", + "worker-sys", +] + +[[package]] +name = "worker-kv" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d4b9fe1a87b7aef252fceb4f30bf6303036a5de329c81ccad9be9c35d1fdbc7" +dependencies = [ + "js-sys", + "serde", + "serde-wasm-bindgen", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "worker-macros" +version = "0.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306c6b6fc316ce129de9cc393dc614b244afb37d43d8ae7a4dccf45d6f8a5ff5" +dependencies = [ + "async-trait", + "proc-macro2", + "quote", + "syn 2.0.32", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-macro-support", + "worker-sys", +] + +[[package]] +name = "worker-sys" +version = "0.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5db3bd0e45980dbcefe567c978b4930e4526e864cd9e70482252a60229ddd7" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "worker_logger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3feaee8b9d44f53f5d8100158d30b254539ad4327d545e00de7ad9a2b2f43431" +dependencies = [ + "colored", + "log", + "worker", +] + [[package]] name = "xml5ever" version = "0.17.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 411955b..29f39d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -307,8 +307,8 @@ packages: resolution: { integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== } dev: true - /better-sqlite3@8.4.0: - resolution: { integrity: sha512-NmsNW1CQvqMszu/CFAJ3pLct6NEFlNfuGM6vw72KHkjOD1UDnL96XNN1BMQc1hiHo8vE2GbOWQYIpZ+YM5wrZw== } + /better-sqlite3@8.6.0: + resolution: { integrity: sha512-jwAudeiTMTSyby+/SfbHDebShbmC2MCH8mU2+DXi0WJfv13ypEJm47cd3kljmy/H130CazEvkf2Li//ewcMJ1g== } requiresBuild: true dependencies: bindings: 1.5.0 @@ -367,7 +367,7 @@ packages: resolution: { integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g== } dependencies: debug: 4.3.4 - tslib: 2.6.1 + tslib: 2.6.2 transitivePeerDependencies: - supports-color dev: true @@ -384,7 +384,7 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /chownr@1.1.4: @@ -424,8 +424,8 @@ packages: engines: { node: '>=4.0.0' } dev: true - /detect-libc@2.0.1: - resolution: { integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== } + /detect-libc@2.0.2: + resolution: { integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== } engines: { node: '>=8' } dev: true @@ -499,8 +499,8 @@ packages: resolution: { integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== } dev: true - /fsevents@2.3.2: - resolution: { integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== } + /fsevents@2.3.3: + resolution: { integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== } engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [ darwin ] requiresBuild: true @@ -604,7 +604,7 @@ packages: dependencies: acorn: 8.10.0 acorn-walk: 8.2.0 - better-sqlite3: 8.4.0 + better-sqlite3: 8.6.0 capnp-ts: 0.7.0 exit-hook: 2.2.1 glob-to-regexp: 0.4.1 @@ -612,11 +612,11 @@ packages: kleur: 4.1.5 source-map-support: 0.5.21 stoppable: 1.1.0 - undici: 5.23.0 + undici: 5.24.0 workerd: 1.20230904.0 - ws: 8.13.0 - youch: 3.2.3 - zod: 3.21.4 + ws: 8.14.2 + youch: 3.3.1 + zod: 3.22.2 transitivePeerDependencies: - bufferutil - supports-color @@ -650,8 +650,8 @@ packages: resolution: { integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== } dev: true - /node-abi@3.45.0: - resolution: { integrity: sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ== } + /node-abi@3.47.0: + resolution: { integrity: sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A== } engines: { node: '>=10' } dependencies: semver: 7.5.4 @@ -687,13 +687,13 @@ packages: engines: { node: '>=10' } hasBin: true dependencies: - detect-libc: 2.0.1 + detect-libc: 2.0.2 expand-template: 2.0.3 github-from-package: 0.0.0 minimist: 1.2.8 mkdirp-classic: 0.5.3 napi-build-utils: 1.0.2 - node-abi: 3.45.0 + node-abi: 3.47.0 pump: 3.0.0 rc: 1.2.8 simple-get: 4.0.1 @@ -867,8 +867,8 @@ packages: is-number: 7.0.0 dev: true - /tslib@2.6.1: - resolution: { integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== } + /tslib@2.6.2: + resolution: { integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== } dev: true /tunnel-agent@0.6.0: @@ -877,8 +877,8 @@ packages: safe-buffer: 5.2.1 dev: true - /undici@5.23.0: - resolution: { integrity: sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg== } + /undici@5.24.0: + resolution: { integrity: sha512-OKlckxBjFl0oXxcj9FU6oB8fDAaiRUq+D8jrFWGmOfI/gIyjk/IeS75LMzgYKUaeHzLUcYvf9bbJGSrUwTfwwQ== } engines: { node: '>=14.0' } dependencies: busboy: 1.6.0 @@ -919,7 +919,7 @@ packages: source-map: 0.7.4 xxhash-wasm: 1.0.2 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 transitivePeerDependencies: - bufferutil - supports-color @@ -930,8 +930,8 @@ packages: resolution: { integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== } dev: true - /ws@8.13.0: - resolution: { integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== } + /ws@8.14.2: + resolution: { integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== } engines: { node: '>=10.0.0' } peerDependencies: bufferutil: ^4.0.1 @@ -951,14 +951,14 @@ packages: resolution: { integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== } dev: true - /youch@3.2.3: - resolution: { integrity: sha512-ZBcWz/uzZaQVdCvfV4uk616Bbpf2ee+F/AvuKDR5EwX/Y4v06xWdtMluqTD7+KlZdM93lLm9gMZYo0sKBS0pgw== } + /youch@3.3.1: + resolution: { integrity: sha512-Rg9ioi+AkKyje2Hk4qILSVvayaFW98KTsOJ4aIkjDf97LZX5WJVIHZmFLnM4ThcVofHo/fbbwtYajfBPHFOVtg== } dependencies: cookie: 0.5.0 mustache: 4.2.0 stacktracey: 2.1.8 dev: true - /zod@3.21.4: - resolution: { integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw== } + /zod@3.22.2: + resolution: { integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg== } dev: true From 96d7127e5197771094b25e2174fc639ab7e88b35 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Wed, 20 Sep 2023 23:54:41 +0330 Subject: [PATCH 25/31] fix: replace incorrect field mapping in Prop House comment model Corrected the field mapping for `idea_id` in the `Comment` struct within `fetcher.rs`. Previously, the `idea_id` was incorrectly being populated with the `comment id`. This change ensures that the `idea_id` correctly maps from the `comment.idea_id`. --- src/prop_lot/fetcher.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prop_lot/fetcher.rs b/src/prop_lot/fetcher.rs index 3efa582..29e8fec 100644 --- a/src/prop_lot/fetcher.rs +++ b/src/prop_lot/fetcher.rs @@ -163,7 +163,7 @@ impl<'a> GraphQLFetcher<'a> { .flat_map(|comment| comment.iter()) .map(|comment| Comment { id: comment.id.try_into().unwrap(), - idea_id: comment.id.try_into().unwrap(), + idea_id: comment.idea_id.try_into().unwrap(), author_id: comment.author_id.clone(), body: comment.body.clone(), }) From 0b6424a9f8640d8dcf743d6475d7b3c49117c555 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Thu, 21 Sep 2023 00:28:22 +0330 Subject: [PATCH 26/31] refactor: update DiscordHandler to use a custom in-memory cache system In this commit, the previous Serenity-based webhook system and Cacher system have been replaced with a more general reqwest Client and custom Cache in 'src/prop_lot/handler.rs' and 'src/prop_house/handler.rs'. Now, we are using the Client and Cache system which is present in 'worker'. This refactoring brings consistency in the usage of resources available in the worker environment, and simplifies the dependency tree by eliminating the need for modules that were only used for executing the Discord webhooks and caching. The organization level webhook URL is fetched from the environment variables to initialize the DiscordHandler. Error handling for unsuccessful webhook requests has been improved, and unsuccessful cache retrievals are logged as errors but do not interrupt the process. The in-memory caching system noticeably impacts the run time performance. --- src/prop_house/handler.rs | 197 ++++++++++++++++------------------- src/prop_lot/handler.rs | 212 +++++++++++++++++++++----------------- 2 files changed, 210 insertions(+), 199 deletions(-) diff --git a/src/prop_house/handler.rs b/src/prop_house/handler.rs index 048532c..bd01abc 100644 --- a/src/prop_house/handler.rs +++ b/src/prop_house/handler.rs @@ -1,146 +1,131 @@ -use std::env; - -use anyhow::{Context, Result}; use chrono::Local; -use serenity::http::Http; -use serenity::json::Value; -use serenity::model::channel::Embed; -use serenity::model::webhook::Webhook; - -use crate::prop_house::cacher::{ - get_auction_cache, get_proposal_cache, set_auction_cache, set_proposal_cache, set_vote_cache, -}; +use log::error; +use reqwest::{header, Client}; +use serde_json::{json, Value}; +use worker::{Env, Result}; + +use crate::cache::Cache; use crate::prop_house::fetcher::{Auction, Proposal, Vote}; -pub struct DiscordHandler { +pub struct DiscordHandler<'a> { base_url: String, - http: Http, - webhook: Webhook, + webhook_url: String, + cache: Cache<'a>, + client: Client, } -impl DiscordHandler { - pub async fn new() -> Result { - let base_url = - env::var("PROP_HOUSE_BASE_URL").context("PROP_HOUSE_BASE_URL is not set in env")?; +impl<'a> DiscordHandler<'a> { + pub fn new(env: &'a Env) -> Result> { + let base_url = env.var("PROP_HOUSE_BASE_URL")?.to_string(); + let webhook_url = env.var("PROP_HOUSE_DISCORD_WEBHOOK_URL")?.to_string(); - let webhook_url = env::var("PROP_HOUSE_DISCORD_WEBHOOK_URL") - .context("PROP_HOUSE_DISCORD_WEBHOOK_URL is not set in env")?; + let cache = Cache::from(env); + let client = Client::new(); - let http = Http::new(""); - let webhook = Webhook::from_url(&http, webhook_url.as_str()) - .await - .context("Failed to create webhook from URL")?; - - Ok(Self { + Ok(DiscordHandler { base_url, - http, - webhook, + webhook_url, + cache, + client, }) } - async fn execute_webhook(&self, message: Value) -> Result<()> { - self.webhook - .execute(&self.http, false, |w| w.embeds(vec![message])) + async fn execute_webhook(&self, embed: Value) -> Result<()> { + let msg_json = json!({"embeds": [embed]}); + + self.client + .post(&self.webhook_url) + .header(header::CONTENT_TYPE, "application/json") + .body(msg_json.to_string()) + .send() .await - .context("Failed to execute webhook")?; + .map_err(|e| worker::Error::from(format!("Failed to execute webhook: {}", e)))?; Ok(()) } pub(crate) async fn handle_new_auction(&self, auction: &Auction) -> Result<()> { - let message = Embed::fake(|e| { - e.title("New Prop House Round") - .url(format!( - "{}/{}", - self.base_url, - auction.title.replace(' ', "-").to_lowercase() - )) - .description(format!( - "A new Prop House round has been created: {}", - auction.title - )) - .footer(|f| f.text(format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")))) - .colour(0x8A2CE2) + let date = Local::now().format("%m/%d/%Y %I:%M %p"); + let embed = json!({ + "title": "New Prop House Round", + "description": format!("A new Prop House round has been created: {}", auction.title), + "url": format!("{}/{}", self.base_url, auction.title.replace(' ', "-").to_lowercase()), + "color": 0x8A2CE2, + "footer": {"text": format!("{}", date)} }); - self.execute_webhook(message).await?; + self.execute_webhook(embed).await?; - set_auction_cache(auction)?; + self.cache + .put(&format!("{}{}", "PROP_HOUSE_AUCTION_", auction.id), auction) + .await; Ok(()) } pub(crate) async fn handle_new_proposal(&self, proposal: &Proposal) -> Result<()> { - let auction = get_auction_cache(proposal.auction_id)? - .ok_or_else(|| anyhow::anyhow!("No auction found for id {}", proposal.auction_id))?; - - let message = Embed::fake(|e| { - e.author(|a| { - a.name(format!( - "{}...{}", - &proposal.address[0..4], - &proposal.address[38..42] - )) - .url(format!("https://etherscan.io/address/{}", proposal.address)) - }) - .title("New Prop House Proposal") - .url(format!( - "{}/{}/{}", - self.base_url, - auction.title.replace(' ', "-").to_lowercase(), - proposal.id - )) - .description(format!( - "A new Prop House proposal has been created: {}", - proposal.title - )) - .footer(|f| f.text(format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")))) - .colour(0x8A2CE2) + let auction = self + .cache + .get::(&format!("{}{}", "PROP_HOUSE_AUCTION_", proposal.auction_id)) + .await? + .unwrap(); + + let embed = json!({ + "title": "New Prop House Proposal", + "description": format!("A new Prop House proposal has been created: {}", proposal.title), + "url": format!("{}/{}/{}", self.base_url, auction.title.replace(' ', "-").to_lowercase(), proposal.id), + "color": 0x8A2CE2, + "footer": {"text": format!("{}", Local::now().format("%m/%d/%Y %I:%M %p"))}, + "author": { + "name": format!("{}...{}", &proposal.address[0..4], &proposal.address[38..42]), + "url": format!("https://etherscan.io/address/{}", proposal.address) + } }); - self.execute_webhook(message).await?; + self.execute_webhook(embed).await?; - set_proposal_cache(proposal)?; + self.cache + .put( + &format!("{}{}", "PROP_HOUSE_PROPOSAL_", proposal.id), + proposal, + ) + .await; Ok(()) } pub(crate) async fn handle_new_vote(&self, vote: &Vote) -> Result<()> { - let proposal = get_proposal_cache(vote.proposal_id)? - .ok_or_else(|| anyhow::anyhow!("No proposal found for id {}", vote.proposal_id))?; - - let message = Embed::fake(|e| { - e.author(|a| { - a.name(format!( - "{}...{}", - &vote.address[0..4], - &vote.address[38..42] - )) - .url(format!("https://etherscan.io/address/{}", vote.address)) - }) - .title("New Prop House Proposal Vote") - .url(format!( - "{}/{}/{}", - self.base_url, - proposal.title.replace(' ', "-").to_lowercase(), - proposal.id - )) - .description(format!( - "{} has voted {} Proposal ({})", - format!("{}...{}", &vote.address[0..4], &vote.address[38..42]), - match vote.direction { - 1 => "for", - _ => "against", - }, - proposal.title - )) - .footer(|f| f.text(format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")))) - .colour(0x8A2CE2) + let proposal = match self + .cache + .get::(&format!("{}{}", "PROP_HOUSE_PROPOSAL_", vote.proposal_id)) + .await? + { + Some(i) => i, + None => { + error!("Proposal not found for id: {}", vote.proposal_id); + return Ok(()); + } + }; + + let embed = json!({ + "title": "New Prop House Proposal Vote", + "description": format!("{} has voted {} Proposal", + format!("{}...{}", &vote.address[0..4], &vote.address[38..42]), + match vote.direction {1 => "for", _ => "against"}), + "url": format!("{}/{}/{}", self.base_url, proposal.title.replace(' ', "-").to_lowercase(), proposal.id), + "color": 0x8A2CE2, + "footer": {"text": format!("{}", Local::now().format("%m/%d/%Y %I:%M %p"))}, + "author": { + "name": format!("{}...{}", &vote.address[0..4], &vote.address[38..42]), + "url": format!("https://etherscan.io/address/{}", vote.address) + } }); - self.execute_webhook(message).await?; + self.execute_webhook(embed).await?; - set_vote_cache(vote)?; + self.cache + .put(&format!("{}{}", "PROP_HOUSE_VOTE_", vote.id), vote) + .await; Ok(()) } diff --git a/src/prop_lot/handler.rs b/src/prop_lot/handler.rs index d23b800..78f791c 100644 --- a/src/prop_lot/handler.rs +++ b/src/prop_lot/handler.rs @@ -1,132 +1,142 @@ -use std::env; - -use anyhow::{Context, Result}; use chrono::Local; -use serenity::json::Value; -use serenity::{ - http::Http, - model::{channel::Embed, webhook::Webhook}, -}; +use log::error; +use reqwest::{header, Client}; +use serde_json::{json, Value}; +use worker::{Env, Result}; -use crate::prop_lot::cacher::{get_idea_cache, set_comment_cache, set_idea_cache, set_vote_cache}; +use crate::cache::Cache; use crate::prop_lot::fetcher::{Comment, Idea, Vote}; -pub struct DiscordHandler { +pub struct DiscordHandler<'a> { base_url: String, - http: Http, - webhook: Webhook, + webhook_url: String, + cache: Cache<'a>, + client: Client, } -impl DiscordHandler { - pub async fn new() -> Result { - let base_url = - env::var("PROP_LOT_BASE_URL").context("PROP_LOT_BASE_URL is not set in env")?; - - let webhook_url = env::var("PROP_LOT_DISCORD_WEBHOOK_URL") - .context("PROP_LOT_DISCORD_WEBHOOK_URL is not set in env")?; +impl<'a> DiscordHandler<'a> { + pub fn new(env: &'a Env) -> Result> { + let base_url = env.var("PROP_LOT_BASE_URL")?.to_string(); + let webhook_url = env.var("PROP_LOT_DISCORD_WEBHOOK_URL")?.to_string(); - let http = Http::new(""); - let webhook = Webhook::from_url(&http, webhook_url.as_str()) - .await - .context("Failed to create webhook from URL")?; + let cache = Cache::from(env); + let client = Client::new(); - Ok(Self { + Ok(DiscordHandler { base_url, - http, - webhook, + webhook_url, + cache, + client, }) } - async fn execute_webhook(&self, message: Value) -> Result<()> { - self.webhook - .execute(&self.http, false, |w| w.embeds(vec![message])) + async fn execute_webhook(&self, embed: Value) -> Result<()> { + let msg_json = json!({"embeds": [embed]}); + + self.client + .post(&self.webhook_url) + .header(header::CONTENT_TYPE, "application/json") + .body(msg_json.to_string()) + .send() .await - .context("Failed to execute webhook")?; + .map_err(|e| worker::Error::from(format!("Failed to execute webhook: {}", e)))?; Ok(()) } pub(crate) async fn handle_new_idea(&self, idea: &Idea) -> Result<()> { - let message = Embed::fake(|e| { - e.author(|a| { - a.name(format!( + let date = Local::now().format("%m/%d/%Y %I:%M %p"); + let embed = json!({ + "title": "New Prop Lot Proposal", + "description": format!( + "A new Prop Lot proposal has been created: {}", + idea.title + ), + "url": format!("{}/idea/{}", self.base_url, idea.id), + "color": 0xFFB911, + "footer": { + "text": format!("{}", date) + }, + "author": { + "name": format!( "{}...{}", &idea.creator_id[0..4], &idea.creator_id[38..42] - )) - .url(format!("https://etherscan.io/address/{}", idea.creator_id)) - }) - .title("New Prop Lot Proposal") - .url(format!("{}/idea/{}", self.base_url, idea.id)) - .description(format!( - "A new Prop Lot proposal has been created: {}", - idea.title - )) - .footer(|f| f.text(format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")))) - .colour(0xFFB911) + ), + "url": format!("{}/idea/{}", self.base_url, idea.id) + } }); - self.execute_webhook(message).await?; + self.execute_webhook(embed).await?; - set_idea_cache(idea)?; + self.cache + .put(&format!("{}{}", "PROP_LOT_IDEA_", idea.id), idea) + .await; Ok(()) } pub(crate) async fn handle_new_vote(&self, vote: &Vote) -> Result<()> { - let idea = get_idea_cache(vote.idea_id)? - .ok_or_else(|| anyhow::anyhow!("No idea found for id {}", vote.idea_id))?; - - let message = Embed::fake(|e| { - e.author(|a| { - a.name(format!( - "{}...{}", - &vote.voter_id[0..4], - &vote.voter_id[38..42] - )) - .url(format!("https://etherscan.io/address/{}", vote.voter_id)) - }) - .title("New Prop Lot Proposal Vote") - .url(format!("{}/idea/{}", self.base_url, idea.id)) - .description(format!( + let idea = match self + .cache + .get::(&format!("{}{}", "PROP_LOT_IDEA_", vote.idea_id)) + .await? + { + Some(i) => i, + None => { + error!("Idea not found for id: {}", vote.idea_id); + return Ok(()); + } + }; + + let embed = json!({ + "title": "New Prop Lot Proposal Vote", + "description": format!( "{} has voted {} Proposal ({})", format!("{}...{}", &vote.voter_id[0..4], &vote.voter_id[38..42]), - match vote.direction { - 1 => "for", - _ => "against", - }, + match vote.direction {1 => "for",_ => "against",}, idea.title - )) - .footer(|f| f.text(format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")))) - .colour(0x8A2CE2) + ), + "url": format!("{}/idea/{}", self.base_url, idea.id), + "color": 0xFFB911, + "footer": { + "text": format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")) + }, + "author": { + "name": format!( + "{}...{}", + &vote.voter_id[0..4], + &vote.voter_id[38..42] + ), + "url": format!("https://etherscan.io/address/{}", vote.voter_id) + } }); - self.execute_webhook(message).await?; + self.execute_webhook(embed).await?; - set_vote_cache(vote)?; + self.cache + .put(&format!("{}{}", "PROP_LOT_VOTE_", vote.id), vote) + .await; Ok(()) } pub(crate) async fn handle_new_comment(&self, comment: &Comment) -> Result<()> { - let idea = get_idea_cache(comment.idea_id)? - .ok_or_else(|| anyhow::anyhow!("No idea found for id {}", comment.idea_id))?; - - let message = Embed::fake(|e| { - e.author(|a| { - a.name(format!( - "{}...{}", - &comment.author_id[0..4], - &comment.author_id[38..42] - )) - .url(format!( - "https://etherscan.io/address/{}", - comment.author_id - )) - }) - .title("New Prop Lot Proposal Comment") - .url(format!("{}/idea/{}", self.base_url, idea.id)) - .description(format!( + let idea = match self + .cache + .get::(&format!("{}{}", "PROP_LOT_IDEA_", comment.idea_id)) + .await? + { + Some(i) => i, + None => { + error!("Idea not found for id: {}", comment.idea_id); + return Ok(()); + } + }; + + let embed = json!({ + "title": "New Prop Lot Proposal Comment", + "description": format!( "{} has commented on Proposal ({})", format!( "{}...{}", @@ -134,14 +144,30 @@ impl DiscordHandler { &comment.author_id[38..42] ), idea.title - )) - .footer(|f| f.text(format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")))) - .colour(0x8A2CE2) + ), + "url": format!("{}/idea/{}", self.base_url, idea.id), + "color": 0xFFB911, + "footer": { + "text": format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")) + }, + "author": { + "name": format!( + "{}...{}", + &comment.author_id[0..4], + &comment.author_id[38..42] + ), + "url": format!( + "https://etherscan.io/address/{}", + comment.author_id + ) + } }); - self.execute_webhook(message).await?; + self.execute_webhook(embed).await?; - set_comment_cache(comment)?; + self.cache + .put(&format!("{}{}", "PROP_LOT_COMMENT_", comment.id), comment) + .await; Ok(()) } From de13066f47dd9aa1341a8983f1a5832d64e2acb2 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Thu, 21 Sep 2023 07:45:53 +0330 Subject: [PATCH 27/31] refactor: update formatting and date variable in prop handlers Code for formatting URLs and date is refactored to make it more readable and efficient. The date variable is created once, to calculate current date and time, and reused in the footers rather than being recalculated multiple times. Besides, the format calls for URLs are modulated to improve code legibility. This refactoring doesn't affect existing functionality but clarifies the code structure and improves time efficiency. --- src/prop_house/handler.rs | 78 ++++++++++++++++++++++++++++++++------- src/prop_lot/handler.rs | 49 +++++++++++++++++++----- 2 files changed, 104 insertions(+), 23 deletions(-) diff --git a/src/prop_house/handler.rs b/src/prop_house/handler.rs index bd01abc..d194d75 100644 --- a/src/prop_house/handler.rs +++ b/src/prop_house/handler.rs @@ -46,12 +46,18 @@ impl<'a> DiscordHandler<'a> { pub(crate) async fn handle_new_auction(&self, auction: &Auction) -> Result<()> { let date = Local::now().format("%m/%d/%Y %I:%M %p"); + let embed = json!({ "title": "New Prop House Round", - "description": format!("A new Prop House round has been created: {}", auction.title), + "description": format!( + "A new Prop House round has been created: {}", + auction.title + ), "url": format!("{}/{}", self.base_url, auction.title.replace(' ', "-").to_lowercase()), "color": 0x8A2CE2, - "footer": {"text": format!("{}", date)} + "footer": { + "text": format!("{}", date) + } }); self.execute_webhook(embed).await?; @@ -64,6 +70,8 @@ impl<'a> DiscordHandler<'a> { } pub(crate) async fn handle_new_proposal(&self, proposal: &Proposal) -> Result<()> { + let date = Local::now().format("%m/%d/%Y %I:%M %p"); + let auction = self .cache .get::(&format!("{}{}", "PROP_HOUSE_AUCTION_", proposal.auction_id)) @@ -72,13 +80,30 @@ impl<'a> DiscordHandler<'a> { let embed = json!({ "title": "New Prop House Proposal", - "description": format!("A new Prop House proposal has been created: {}", proposal.title), - "url": format!("{}/{}/{}", self.base_url, auction.title.replace(' ', "-").to_lowercase(), proposal.id), + "description": format!( + "A new Prop House proposal has been created: {}", + proposal.title + ), + "url": format!( + "{}/{}/{}", + self.base_url, + auction.title.replace(' ', "-").to_lowercase(), + proposal.id + ), "color": 0x8A2CE2, - "footer": {"text": format!("{}", Local::now().format("%m/%d/%Y %I:%M %p"))}, + "footer": { + "text": format!("{}", date) + }, "author": { - "name": format!("{}...{}", &proposal.address[0..4], &proposal.address[38..42]), - "url": format!("https://etherscan.io/address/{}", proposal.address) + "name": format!( + "{}...{}", + &proposal.address[0..4], + &proposal.address[38..42] + ), + "url": format!( + "https://etherscan.io/address/{}", + proposal.address + ) } }); @@ -95,6 +120,8 @@ impl<'a> DiscordHandler<'a> { } pub(crate) async fn handle_new_vote(&self, vote: &Vote) -> Result<()> { + let date = Local::now().format("%m/%d/%Y %I:%M %p"); + let proposal = match self .cache .get::(&format!("{}{}", "PROP_HOUSE_PROPOSAL_", vote.proposal_id)) @@ -109,15 +136,38 @@ impl<'a> DiscordHandler<'a> { let embed = json!({ "title": "New Prop House Proposal Vote", - "description": format!("{} has voted {} Proposal", - format!("{}...{}", &vote.address[0..4], &vote.address[38..42]), - match vote.direction {1 => "for", _ => "against"}), - "url": format!("{}/{}/{}", self.base_url, proposal.title.replace(' ', "-").to_lowercase(), proposal.id), + "description": format!( + "{} has voted {} Proposal", + format!( + "{}...{}", + &vote.address[0..4], + &vote.address[38..42] + ), + match vote.direction { + 1 => "for", + _ => "against" + } + ), + "url": format!( + "{}/{}/{}", + self.base_url, + proposal.title.replace(' ', "-").to_lowercase(), + proposal.id + ), "color": 0x8A2CE2, - "footer": {"text": format!("{}", Local::now().format("%m/%d/%Y %I:%M %p"))}, + "footer": { + "text": format!("{}", date) + }, "author": { - "name": format!("{}...{}", &vote.address[0..4], &vote.address[38..42]), - "url": format!("https://etherscan.io/address/{}", vote.address) + "name": format!( + "{}...{}", + &vote.address[0..4], + &vote.address[38..42] + ), + "url": format!( + "https://etherscan.io/address/{}", + vote.address + ) } }); diff --git a/src/prop_lot/handler.rs b/src/prop_lot/handler.rs index 78f791c..62d1d5b 100644 --- a/src/prop_lot/handler.rs +++ b/src/prop_lot/handler.rs @@ -46,13 +46,18 @@ impl<'a> DiscordHandler<'a> { pub(crate) async fn handle_new_idea(&self, idea: &Idea) -> Result<()> { let date = Local::now().format("%m/%d/%Y %I:%M %p"); + let embed = json!({ "title": "New Prop Lot Proposal", "description": format!( "A new Prop Lot proposal has been created: {}", idea.title ), - "url": format!("{}/idea/{}", self.base_url, idea.id), + "url": format!( + "{}/idea/{}", + self.base_url, + idea.id + ), "color": 0xFFB911, "footer": { "text": format!("{}", date) @@ -63,7 +68,11 @@ impl<'a> DiscordHandler<'a> { &idea.creator_id[0..4], &idea.creator_id[38..42] ), - "url": format!("{}/idea/{}", self.base_url, idea.id) + "url": format!( + "{}/idea/{}", + self.base_url, + idea.id + ) } }); @@ -77,6 +86,8 @@ impl<'a> DiscordHandler<'a> { } pub(crate) async fn handle_new_vote(&self, vote: &Vote) -> Result<()> { + let date = Local::now().format("%m/%d/%Y %I:%M %p"); + let idea = match self .cache .get::(&format!("{}{}", "PROP_LOT_IDEA_", vote.idea_id)) @@ -93,14 +104,25 @@ impl<'a> DiscordHandler<'a> { "title": "New Prop Lot Proposal Vote", "description": format!( "{} has voted {} Proposal ({})", - format!("{}...{}", &vote.voter_id[0..4], &vote.voter_id[38..42]), - match vote.direction {1 => "for",_ => "against",}, + format!( + "{}...{}", + &vote.voter_id[0..4], + &vote.voter_id[38..42] + ), + match vote.direction { + 1 => "for", + _ => "against", + }, idea.title ), - "url": format!("{}/idea/{}", self.base_url, idea.id), + "url": format!( + "{}/idea/{}", + self.base_url, + idea.id + ), "color": 0xFFB911, "footer": { - "text": format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")) + "text": format!("{}", date) }, "author": { "name": format!( @@ -108,7 +130,10 @@ impl<'a> DiscordHandler<'a> { &vote.voter_id[0..4], &vote.voter_id[38..42] ), - "url": format!("https://etherscan.io/address/{}", vote.voter_id) + "url": format!( + "https://etherscan.io/address/{}", + vote.voter_id + ) } }); @@ -122,6 +147,8 @@ impl<'a> DiscordHandler<'a> { } pub(crate) async fn handle_new_comment(&self, comment: &Comment) -> Result<()> { + let date = Local::now().format("%m/%d/%Y %I:%M %p"); + let idea = match self .cache .get::(&format!("{}{}", "PROP_LOT_IDEA_", comment.idea_id)) @@ -145,10 +172,14 @@ impl<'a> DiscordHandler<'a> { ), idea.title ), - "url": format!("{}/idea/{}", self.base_url, idea.id), + "url": format!( + "{}/idea/{}", + self.base_url, + idea.id + ), "color": 0xFFB911, "footer": { - "text": format!("{}", Local::now().format("%m/%d/%Y %I:%M %p")) + "text": format!("{}", date) }, "author": { "name": format!( From 03708847f98607442c35fed6fc5f01ef33526b79 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Thu, 21 Sep 2023 08:09:20 +0330 Subject: [PATCH 28/31] ci: update build process in GitHub Actions workflow Modified the .github/workflows/build.yml file to enhance the CI/CD pipeline. The build process now installs the stable toolchain, checks for errors, installs 'worker-build', then builds using 'worker-build'. This aims to streamline the build process and improve error checking in the build steps. --- .github/workflows/build.yml | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b2d4394..be8516b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,13 +59,28 @@ jobs: target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - # This compiles the application. - - name: Build the application and export it - run: cargo build --verbose + - name: Install stable toolchain + uses: actions-rs/toolchain@v1.0.6 + with: + toolchain: stable + target: wasm32-unknown-unknown + override: true + + - name: Check for errors + uses: actions-rs/cargo@v1.0.1 + with: + command: check - # Runs unit tests for the application using Jest. - - name: Execute tests using Cargo - run: cargo test --verbose + - name: Install worker-build + uses: actions-rs/cargo@v1.0.1 + with: + command: install + args: worker-build + + - name: Build by worker-build + uses: actions-rs/cargo@v1.0.1 + with: + command: worker-build release: name: Create Release From 5174e9fb531cb8c2335a25108f9b11fb5f0c9729 Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Thu, 21 Sep 2023 08:10:28 +0330 Subject: [PATCH 29/31] chore(release): prepare for version 1.0.0-alpha.8 --- CHANGELOG.md | 33 ++++++++++++++++++++++++++++++++- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8cf526..d598eee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,38 @@ All notable changes to this project will be documented in this file. -## [unreleased] +## [1.0.0-alpha.8] - 2023-09-21 + +### Bug Fixes + +- Replace incorrect field mapping in Prop House comment model + +### Refactor + +- Remove caching system from project +- Update fetcher functions to use worker env +- Update fetcher to use GraphQLFetcher struct +- Add caching functionality to enhance performance +- Move code into `lib.rs` for modularity and error handling +- Update caching and fetching mechanism +- Update the `pnpm-lock.yaml` and `Cargo.lock` files +- Update DiscordHandler to use a custom in-memory cache system +- Update formatting and date variable in prop handlers + +### Miscellaneous Tasks + +- Add `package.json` for LilNouns bots project +- Add `wrangler.toml` configuration for deployment +- Add `wasm-pack` and additional dependencies in `Cargo.toml` +- Add `node_modules` to `.gitignore` +- Update `package.json` for deployment and development +- Add `wasm32` target to Cargo configuration +- Update and rearrange dependencies +- Update `dev` script in `package.json` +- Add `.wrangler` to `.gitignore` +- Update build process in GitHub Actions workflow + +## [1.0.0-alpha.7] - 2023-09-19 ### Refactor diff --git a/Cargo.lock b/Cargo.lock index 53a299d..e46506c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -751,7 +751,7 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "lilnouns-bots" -version = "1.0.0-alpha.7" +version = "1.0.0-alpha.8" dependencies = [ "anyhow", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index 1129b7c..81c7f6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lilnouns-bots" -version = "1.0.0-alpha.7" +version = "1.0.0-alpha.8" edition = "2021" include = ["*.graphql"] From dcb835750201d4587cca76b197b1e4a9f204ab2e Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Thu, 21 Sep 2023 08:14:12 +0330 Subject: [PATCH 30/31] ci: update build command in GitHub Actions workflow Instead of using actions-rs/cargo to run the command worker-build, the GitHub Actions workflow is now updated to directly run the command. This simplification enhances the efficiency of the build process. --- .github/workflows/build.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index be8516b..b96e368 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,9 +78,7 @@ jobs: args: worker-build - name: Build by worker-build - uses: actions-rs/cargo@v1.0.1 - with: - command: worker-build + run: worker-build release: name: Create Release From da434f839d608122246be442e194a13a5d97261f Mon Sep 17 00:00:00 2001 From: Milad Nekofar Date: Thu, 21 Sep 2023 08:48:01 +0330 Subject: [PATCH 31/31] ci: add deployment workflow for GitHub Actions This commit introduces a new GitHub Actions workflow, deploy.yml, for automating deployment to Workers whenever a release is pre-released or released. The workflow includes steps for fetching sources, caching cargo dependencies, installing the stable toolchain and worker-build, building with worker-build, and deploying to Workers. The concurrency setting ensures only one workflow runs at any given time per branch to prevent conflicts. --- .github/workflows/deploy.yml | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/deploy.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..e72bb94 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,58 @@ +name: Deploy & Publish +on: + release: + types: [ prereleased, released ] + +jobs: + + # Prepare and publish + deploy: + name: Deploy to Workers + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + + # Check out current repository + - name: Fetch Sources + uses: actions/checkout@v3.6.0 + with: + ref: ${{ github.event.release.tag_name }} + + # Cache dependencies to speed up builds + - name: Cache cargo dependencies + uses: actions/cache@v3.3.2 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1.0.6 + with: + toolchain: stable + target: wasm32-unknown-unknown + override: true + + - name: Install worker-build + uses: actions-rs/cargo@v1.0.1 + with: + command: install + args: worker-build + + - name: Build by worker-build + run: worker-build + + - name: Deploy to Workers + uses: cloudflare/wrangler-action@v3.1.0 + with: + apiToken: ${{ secrets.CF_API_TOKEN }} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true