From 1e52ddc88c9553699d5b0e06dc848f35a0946356 Mon Sep 17 00:00:00 2001 From: Leafd Date: Sun, 5 Oct 2025 00:10:10 -0600 Subject: [PATCH] chore(ci): add linters (#22) * chore(ci): add linters * chore: apply linter fixes * chore(ci): add cache layer * chore(ci): change lint flavour * chore: apply linter fixes * chore(cI): fix linter errors * chore * chore(ci): add renovate * chore(ci): add renovate workflow * chore( * chore(ci): enable git lfs --------- Co-authored-by: leafdbot[bot] <192038741+leafdbot[bot]@users.noreply.github.com> --- .github/renovate-ci.json5 | 23 ++++ .github/workflows/lint.yaml | 119 ++++++++++++++++ .github/workflows/release.yaml | 1 + .github/workflows/renovate.yaml | 51 +++++++ .gitignore | 2 + .trivyignore | 6 + src-tauri/Cargo.lock | 233 ++++++++++++++++++-------------- src/api.ts | 163 +++++++++++----------- src/composables/useTheme.ts | 2 +- src/main.ts | 8 +- src/vite-env.d.ts | 8 +- 11 files changed, 421 insertions(+), 195 deletions(-) create mode 100644 .github/renovate-ci.json5 create mode 100644 .github/workflows/lint.yaml create mode 100644 .github/workflows/renovate.yaml create mode 100644 .trivyignore diff --git a/.github/renovate-ci.json5 b/.github/renovate-ci.json5 new file mode 100644 index 0000000..79750e5 --- /dev/null +++ b/.github/renovate-ci.json5 @@ -0,0 +1,23 @@ +{ + "extends": [":enableRenovate", ":semanticCommits", ":enablePreCommit"], + "platform": "github", + "username": "leafdbot[bot]", + "repositories": ["hackclub/hackatime-desktop"], + "onboarding": false, + "requireConfig": "optional", + "gitAuthor": "leafdbot[bot] <192038741+leafdbot[bot]@users.noreply.github.com>", + "timezone": "UTC", + "dependencyDashboard": true, + "stabilityDays": 1, + "platformCommit": true, + "prCreation": "not-pending", + "commitBody": "Signed-off-by: leafdbot[bot] <192038741+leafdbot[bot]@users.noreply.github.com>", + "suppressNotifications": ["prIgnoreNotification"], + "rebaseWhen": "conflicted", + "git-submodules": {"enabled": true}, + "packageRules": [ + {"matchUpdateTypes": ["major"], "addLabels": ["dependency/major"]}, + {"matchUpdateTypes": ["minor"], "addLabels": ["dependency/minor"]}, + {"matchUpdateTypes": ["patch"], "addLabels": ["dependency/patch"]} + ] +} \ No newline at end of file diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..1458c7c --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,119 @@ +--- +name: leafdlint + +on: + pull_request: + branches: [main, develop] + push: + branches: [main, develop] + +permissions: + contents: write + pull-requests: write + issues: write + +jobs: + lint: + name: LINTEEER + runs-on: blacksmith-4vcpu-ubuntu-2404 + if: github.event.action != 'closed' + env: + APPLY_FIXES: all + APPLY_FIXES_EVENT: all + APPLY_FIXES_MODE: commit + outputs: + changes_detected: ${{ steps.autocommit.outputs.changes_detected }} + commit_hash: ${{ steps.autocommit.outputs.commit_hash }} + + steps: + - name: Generate GitHub App Token + uses: actions/create-github-app-token@v1 + id: generate-token + with: + app-id: ${{ secrets.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Checkout Code + uses: actions/checkout@v4 + with: + token: ${{ steps.generate-token.outputs.token }} + fetch-depth: 0 + ref: ${{ github.head_ref || github.ref }} + lfs: true + + - name: Run MegaLinter + uses: oxsecurity/megalinter/flavors/rust@v8.8.0 + env: + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} + DEFAULT_BRANCH: main + VALIDATE_ALL_CODEBASE: true + ENABLE: RUST,JAVASCRIPT,TYPESCRIPT,JSON,YAML,MARKDOWN,REPOSITORY + ENABLE_LINTERS: RUST_CLIPPY,RUST_RUSTFMT,VUE_ESLINT_PLUGIN_VUE,REPOSITORY_GIT_DIFF,REPOSITORY_SECRETLINT,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,YAML_PRETTIER,YAML_YAMLLINT + DISABLE: COPYPASTE,SPELL + DISABLE_LINTERS: REPOSITORY_CHECKOV,REPOSITORY_GITLEAKS + SECURITY_LINTERS_ENABLED: true + + # Rust linter configuration + RUST_PRE_COMMANDS: "[{\"cwd\": \"workspace\", \"command\": \"apk add --no-cache pkgconfig gtk+3.0-dev webkit2gtk-4.1-dev openssl-dev\"}]" + RUST_CLIPPY_ARGUMENTS: -- --manifest-path src-tauri/Cargo.toml + RUST_RUSTFMT_ARGUMENTS: --edition 2024 + + # Other linter arguments + REPOSITORY_TRIVY_ARGUMENTS: --scanners vuln,misconfig --severity HIGH,CRITICAL --exit-code 1 + JSON_PRETTIER_FILTER_REGEX_EXCLUDE: ".release-please-manifest.json" + MARKDOWN_FILTER_REGEX_EXCLUDE: "CHANGELOG.md" + + # File filtering + FILTER_REGEX_INCLUDE: (src-tauri/.*\.rs|src/.*\.(js|ts|tsx|jsx|json|yaml|yml|toml|md)) + FILTER_REGEX_EXCLUDE: (target/|src-tauri/target/|node_modules/|dist/|build/) + + # Apply fixes configuration + APPLY_FIXES: all + APPLY_FIXES_EVENT: all + APPLY_FIXES_MODE: commit + + # Reporter settings + FILEIO_REPORTER: false + FLAVOR_SUGGESTIONS: false + SHOW_ELAPSED_TIME: true + PRINT_ALPACA: false + PRINT_ALL_FILES: false + + - name: Archive Linter Reports + if: always() + uses: actions/upload-artifact@v4 + with: + name: megalinter-reports + path: | + megalinter-reports/ + mega-linter.log + retention-days: 30 + + - name: Add Reports to Gitignore + if: success() || failure() + run: | + touch .gitignore + grep -qxF 'megalinter-reports/' .gitignore || echo 'megalinter-reports/' >> .gitignore + grep -qxF 'mega-linter.log' .gitignore || echo 'mega-linter.log' >> .gitignore + + - name: Prepare Git for Commit + if: success() || failure() + run: | + git config --global --add safe.directory "$GITHUB_WORKSPACE" + sudo chown -Rc $UID .git/ || true + + - name: Commit and Push Linter Fixes + id: autocommit + if: success() || failure() + uses: stefanzweifel/git-auto-commit-action@v5 + with: + branch: ${{ github.head_ref || github.ref_name }} + commit_user_name: ${{ vars.BOT_NAME }} + commit_user_email: ${{ vars.BOT_EMAIL }} + commit_author: ${{ vars.BOT_NAME }} <${{ vars.BOT_EMAIL }}> + commit_message: "chore: apply linter fixes" + skip_dirty_check: false + skip_fetch: false + skip_checkout: false + env: + GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3e67041..87b2e72 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,3 +1,4 @@ +--- name: Release 'on': workflow_dispatch: null diff --git a/.github/workflows/renovate.yaml b/.github/workflows/renovate.yaml new file mode 100644 index 0000000..3d36600 --- /dev/null +++ b/.github/workflows/renovate.yaml @@ -0,0 +1,51 @@ +--- +name: Renovate + +"on": + push: + branches: [main] + pull_request: + types: [edited] + issues: + types: [edited] + workflow_dispatch: + inputs: + # checkov:skip=CKV_GHA_7:The build output is unaffected by these inputs + dryRun: + description: "Dry-Run" + default: "true" + required: false + logLevel: + description: "Log-Level" + default: "debug" + required: false + +env: + LOG_LEVEL: info + DRY_RUN: false + +jobs: + renovate: + name: Renovate + runs-on: blacksmith-2vcpu-ubuntu-2404 + steps: + - name: Generate Token + uses: tibdex/github-app-token@v2 + id: generate-token + with: + app_id: ${{ secrets.APP_ID }} + private_key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Checkout + uses: actions/checkout@v4 + with: + token: ${{ steps.generate-token.outputs.token }} + fetch-depth: 1 + - name: Override default config from dispatch variables + run: | + echo "DRY_RUN=${{ github.event.inputs.dryRun || env.DRY_RUN }}" >> "${GITHUB_ENV}" + echo "LOG_LEVEL=${{ github.event.inputs.logLevel || env.LOG_LEVEL }}" >> "${GITHUB_ENV}" + - name: Run Renovate + uses: renovatebot/github-action@v41.0.3 + with: + configurationFile: .github/renovate-ci.json5 + token: "x-access-token:${{ steps.generate-token.outputs.token }}" diff --git a/.gitignore b/.gitignore index a547bf3..d44d2d0 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ dist-ssr *.njsproj *.sln *.sw? +megalinter-reports/ +mega-linter.log diff --git a/.trivyignore b/.trivyignore new file mode 100644 index 0000000..915c22f --- /dev/null +++ b/.trivyignore @@ -0,0 +1,6 @@ +# Trivy ignore file +# Suppress known issues that cannot be easily fixed + +# More info on : https://github.com/tauri-apps/tauri/issues/12048 +GHSA-wrw7-89jp-8q8g + diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index e6c819f..d6bf625 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -314,11 +314,11 @@ dependencies = [ [[package]] name = "block2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "objc2 0.6.2", + "objc2 0.6.3", ] [[package]] @@ -363,9 +363,9 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "byteorder" @@ -451,9 +451,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.39" +version = "1.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" dependencies = [ "find-msvc-tools", "shlex", @@ -899,7 +899,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ "bitflags 2.9.4", - "objc2 0.6.2", + "objc2 0.6.3", ] [[package]] @@ -1150,9 +1150,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" [[package]] name = "flate2" @@ -2364,11 +2364,10 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] @@ -2489,10 +2488,10 @@ dependencies = [ "dpi", "gtk", "keyboard-types", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-app-kit", "objc2-core-foundation", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "once_cell", "png", "serde", @@ -2665,9 +2664,9 @@ dependencies = [ [[package]] name = "objc2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" dependencies = [ "objc2-encode", "objc2-exception-helper", @@ -2675,77 +2674,104 @@ dependencies = [ [[package]] name = "objc2-app-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.9.4", - "block2 0.6.1", + "block2 0.6.2", "libc", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-cloud-kit", "objc2-core-data", "objc2-core-foundation", "objc2-core-graphics", "objc2-core-image", - "objc2-foundation 0.3.1", - "objc2-quartz-core 0.3.1", + "objc2-core-text", + "objc2-core-video", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", ] [[package]] name = "objc2-cloud-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17614fdcd9b411e6ff1117dfb1d0150f908ba83a7df81b1f118005fe0a8ea15d" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-foundation 0.3.1", + "objc2 0.6.3", + "objc2-foundation 0.3.2", ] [[package]] name = "objc2-core-data" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291fbbf7d29287518e8686417cf7239c74700fd4b607623140a7d4a3c834329d" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" dependencies = [ "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-foundation 0.3.1", + "objc2 0.6.3", + "objc2-foundation 0.3.2", ] [[package]] name = "objc2-core-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.9.4", "dispatch2", - "objc2 0.6.2", + "objc2 0.6.3", ] [[package]] name = "objc2-core-graphics" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ "bitflags 2.9.4", "dispatch2", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-core-foundation", "objc2-io-surface", ] [[package]] name = "objc2-core-image" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b3dc0cc4386b6ccf21c157591b34a7f44c8e75b064f85502901ab2188c007e" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" dependencies = [ - "objc2 0.6.2", - "objc2-foundation 0.3.1", + "objc2 0.6.3", + "objc2-foundation 0.3.2", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.3", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", ] [[package]] @@ -2777,35 +2803,35 @@ dependencies = [ [[package]] name = "objc2-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.9.4", - "block2 0.6.1", + "block2 0.6.2", "libc", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-core-foundation", ] [[package]] name = "objc2-io-surface" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ "bitflags 2.9.4", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-core-foundation", ] [[package]] name = "objc2-javascript-core" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9052cb1bb50a4c161d934befcf879526fb87ae9a68858f241e693ca46225cf5a" +checksum = "2a1e6550c4caed348956ce3370c9ffeca70bb1dbed4fa96112e7c6170e074586" dependencies = [ - "objc2 0.6.2", + "objc2 0.6.3", "objc2-core-foundation", ] @@ -2823,14 +2849,14 @@ dependencies = [ [[package]] name = "objc2-osa-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26bb88504b5a050dbba515d2414607bf5e57dd56b107bc5f0351197a3e7bdc5d" +checksum = "f112d1746737b0da274ef79a23aac283376f335f4095a083a267a082f21db0c0" dependencies = [ "bitflags 2.9.4", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-app-kit", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", ] [[package]] @@ -2848,50 +2874,50 @@ dependencies = [ [[package]] name = "objc2-quartz-core" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ffb6a0cd5f182dc964334388560b12a57f7b74b3e2dec5e2722aa2dfb2ccd5" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-foundation 0.3.1", + "objc2 0.6.3", + "objc2-foundation 0.3.2", ] [[package]] name = "objc2-security" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1f8e0ef3ab66b08c42644dcb34dba6ec0a574bbd8adbb8bdbdc7a2779731a44" +checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a" dependencies = [ "bitflags 2.9.4", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-core-foundation", ] [[package]] name = "objc2-ui-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b1312ad7bc8a0e92adae17aa10f90aae1fb618832f9b993b022b591027daed" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ "bitflags 2.9.4", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-core-foundation", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", ] [[package]] name = "objc2-web-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91672909de8b1ce1c2252e95bbee8c1649c9ad9d14b9248b3d7b4c47903c47ad" +checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" dependencies = [ "bitflags 2.9.4", - "block2 0.6.1", - "objc2 0.6.2", + "block2 0.6.2", + "objc2 0.6.3", "objc2-app-kit", "objc2-core-foundation", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "objc2-javascript-core", "objc2-security", ] @@ -2999,8 +3025,8 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b" dependencies = [ - "objc2 0.6.2", - "objc2-foundation 0.3.1", + "objc2 0.6.3", + "objc2-foundation 0.3.2", "objc2-osa-kit", "serde", "serde_json", @@ -3040,9 +3066,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -3050,15 +3076,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.0", ] [[package]] @@ -3601,9 +3627,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags 2.9.4", ] @@ -4118,9 +4144,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.1" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" +checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5" dependencies = [ "base64 0.22.1", "chrono", @@ -4129,8 +4155,7 @@ dependencies = [ "indexmap 2.11.4", "schemars 0.9.0", "schemars 1.0.4", - "serde", - "serde_derive", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -4138,9 +4163,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.1" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" +checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27" dependencies = [ "darling", "proc-macro2", @@ -4705,7 +4730,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "959469667dbcea91e5485fc48ba7dd6023face91bb0f1a14681a70f99847c3f7" dependencies = [ "bitflags 2.9.4", - "block2 0.6.1", + "block2 0.6.2", "core-foundation 0.10.1", "core-graphics", "crossbeam-channel", @@ -4722,9 +4747,9 @@ dependencies = [ "ndk", "ndk-context", "ndk-sys", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-app-kit", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "once_cell", "parking_lot", "raw-window-handle", @@ -4788,9 +4813,9 @@ dependencies = [ "log", "mime", "muda", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-app-kit", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "objc2-ui-kit", "objc2-web-kit", "percent-encoding", @@ -4928,7 +4953,7 @@ dependencies = [ "dunce", "glob", "objc2-app-kit", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "open", "schemars 0.8.22", "serde", @@ -4994,7 +5019,7 @@ dependencies = [ "gtk", "http 1.3.1", "jni", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-ui-kit", "objc2-web-kit", "raw-window-handle", @@ -5018,9 +5043,9 @@ dependencies = [ "http 1.3.1", "jni", "log", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-app-kit", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "once_cell", "percent-encoding", "raw-window-handle", @@ -5470,11 +5495,11 @@ dependencies = [ "dirs", "libappindicator", "muda", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-app-kit", "objc2-core-foundation", "objc2-core-graphics", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "once_cell", "png", "serde", @@ -5496,9 +5521,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "uds_windows" @@ -5997,10 +6022,10 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" dependencies = [ - "objc2 0.6.2", + "objc2 0.6.3", "objc2-app-kit", "objc2-core-foundation", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "raw-window-handle", "windows-sys 0.59.0", "windows-version", @@ -6528,7 +6553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31f0e9642a0d061f6236c54ccae64c2722a7879ad4ec7dff59bd376d446d8e90" dependencies = [ "base64 0.22.1", - "block2 0.6.1", + "block2 0.6.2", "cookie", "crossbeam-channel", "dirs", @@ -6543,10 +6568,10 @@ dependencies = [ "kuchikiki", "libc", "ndk", - "objc2 0.6.2", + "objc2 0.6.3", "objc2-app-kit", "objc2-core-foundation", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "objc2-ui-kit", "objc2-web-kit", "once_cell", diff --git a/src/api.ts b/src/api.ts index ee1088c..0868570 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,179 +1,178 @@ -import { invoke } from "@tauri-apps/api/core"; +import { invoke } from '@tauri-apps/api/core' interface ApiConfig { - base_url: string; + base_url: string } interface AuthState { - is_authenticated: boolean; - access_token: string | null; - user_info: Record | null; + is_authenticated: boolean + access_token: string | null + user_info: Record | null } export class KubeTimeApi { - private baseUrl: string = "https://hackatime.hackclub.com"; - private accessToken: string | null = null; - private latestPresenceCache: { data: any | null; fetchedAt: number } = { data: null, fetchedAt: 0 }; + private baseUrl: string = 'https://hackatime.hackclub.com' + private accessToken: string | null = null + private latestPresenceCache: { data: any | null, fetchedAt: number } = { data: null, fetchedAt: 0 } - async initialize() { + async initialize () { try { - const config: ApiConfig = await invoke("get_api_config"); + const config: ApiConfig = await invoke('get_api_config') if (config.base_url && config.base_url.trim()) { - this.baseUrl = config.base_url; + this.baseUrl = config.base_url } - - const authState: AuthState = await invoke("get_auth_state"); - this.accessToken = authState.access_token; + + const authState: AuthState = await invoke('get_auth_state') + this.accessToken = authState.access_token } catch (error) { - console.error("Failed to initialize API:", error); + console.error('Failed to initialize API:', error) if (!this.baseUrl || !this.baseUrl.trim()) { - this.baseUrl = "https://hackatime.hackclub.com"; + this.baseUrl = 'https://hackatime.hackclub.com' } } } - async getCurrentUser() { + async getCurrentUser () { if (!this.accessToken) { - throw new Error("Not authenticated"); + throw new Error('Not authenticated') } try { const response = await fetch(`${this.baseUrl}/api/v1/authenticated/me`, { headers: { - 'Authorization': `Bearer ${this.accessToken}`, - 'Content-Type': 'application/json', - }, - }); + Authorization: `Bearer ${this.accessToken}`, + 'Content-Type': 'application/json' + } + }) if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error(`HTTP error! status: ${response.status}`) } - return await response.json(); + return await response.json() } catch (error) { - console.error("Failed to fetch current user:", error); - throw error; + console.error('Failed to fetch current user:', error) + throw error } } - async getHours(startDate?: string, endDate?: string) { + async getHours (startDate?: string, endDate?: string) { if (!this.accessToken) { - throw new Error("Not authenticated"); + throw new Error('Not authenticated') } try { - const params = new URLSearchParams(); - if (startDate) params.append('start_date', startDate); - if (endDate) params.append('end_date', endDate); - - const url = `${this.baseUrl}/api/v1/authenticated/hours${params.toString() ? `?${params.toString()}` : ''}`; - + const params = new URLSearchParams() + if (startDate) params.append('start_date', startDate) + if (endDate) params.append('end_date', endDate) + + const url = `${this.baseUrl}/api/v1/authenticated/hours${params.toString() ? `?${params.toString()}` : ''}` + const response = await fetch(url, { headers: { - 'Authorization': `Bearer ${this.accessToken}`, - 'Content-Type': 'application/json', - }, - }); + Authorization: `Bearer ${this.accessToken}`, + 'Content-Type': 'application/json' + } + }) if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error(`HTTP error! status: ${response.status}`) } - return await response.json(); + return await response.json() } catch (error) { - console.error("Failed to fetch hours:", error); - throw error; + console.error('Failed to fetch hours:', error) + throw error } } - async getWeeklyHours() { - const endDate = new Date(); - const startDate = new Date(); - startDate.setDate(endDate.getDate() - 7); + async getWeeklyHours () { + const endDate = new Date() + const startDate = new Date() + startDate.setDate(endDate.getDate() - 7) - const formatDate = (date: Date) => date.toISOString().split('T')[0]; - - return this.getHours(formatDate(startDate), formatDate(endDate)); + const formatDate = (date: Date) => date.toISOString().split('T')[0] + + return await this.getHours(formatDate(startDate), formatDate(endDate)) } - async getStreak() { + async getStreak () { if (!this.accessToken) { - throw new Error("Not authenticated"); + throw new Error('Not authenticated') } try { const response = await fetch(`${this.baseUrl}/api/v1/authenticated/streak`, { headers: { - 'Authorization': `Bearer ${this.accessToken}`, - 'Content-Type': 'application/json', - }, - }); + Authorization: `Bearer ${this.accessToken}`, + 'Content-Type': 'application/json' + } + }) if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error(`HTTP error! status: ${response.status}`) } - return await response.json(); + return await response.json() } catch (error) { - console.error("Failed to fetch streak:", error); - throw error; + console.error('Failed to fetch streak:', error) + throw error } } - async getStats() { + async getStats () { if (!this.accessToken) { - throw new Error("Not authenticated"); + throw new Error('Not authenticated') } try { const [hoursData, streakData] = await Promise.all([ this.getWeeklyHours(), this.getStreak() - ]); + ]) return { ...hoursData, current_streak: streakData.current_streak, longest_streak: streakData.longest_streak - }; + } } catch (error) { - console.error("Failed to fetch stats:", error); - throw error; + console.error('Failed to fetch stats:', error) + throw error } } - - async getCurrentPresence() { + async getCurrentPresence () { if (!this.accessToken) { - throw new Error("Not authenticated"); + throw new Error('Not authenticated') } try { // Return cached result if fetched within last 60s - const now = Date.now(); + const now = Date.now() if (now - this.latestPresenceCache.fetchedAt < 60_000 && this.latestPresenceCache.data !== null) { - return this.latestPresenceCache.data; + return this.latestPresenceCache.data } - + const response = await fetch(`${this.baseUrl}/api/v1/authenticated/heartbeats/latest`, { headers: { - 'Authorization': `Bearer ${this.accessToken}`, - 'Content-Type': 'application/json', - }, - }); + Authorization: `Bearer ${this.accessToken}`, + 'Content-Type': 'application/json' + } + }) if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error(`HTTP error! status: ${response.status}`) } - const json = await response.json(); - this.latestPresenceCache = { data: json, fetchedAt: Date.now() }; - return json; + const json = await response.json() + this.latestPresenceCache = { data: json, fetchedAt: Date.now() } + return json } catch (error) { - console.error("Failed to fetch current presence:", error); - throw error; + console.error('Failed to fetch current presence:', error) + throw error } } } -export const api = new KubeTimeApi(); +export const api = new KubeTimeApi() diff --git a/src/composables/useTheme.ts b/src/composables/useTheme.ts index ac4fa65..8b80eb2 100644 --- a/src/composables/useTheme.ts +++ b/src/composables/useTheme.ts @@ -4,7 +4,7 @@ export type Theme = 'dark' | 'light' const currentTheme = ref('dark') -export function useTheme() { +export function useTheme () { const setTheme = (theme: Theme) => { currentTheme.value = theme document.documentElement.className = theme diff --git a/src/main.ts b/src/main.ts index de275e7..fe5bae3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ -import { createApp } from "vue"; -import App from "./App.vue"; -import "./style.css"; +import { createApp } from 'vue' +import App from './App.vue' +import './style.css' -createApp(App).mount("#app"); +createApp(App).mount('#app') diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index fc81239..323c78a 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1,7 +1,7 @@ /// -declare module "*.vue" { - import type { DefineComponent } from "vue"; - const component: DefineComponent<{}, {}, any>; - export default component; +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component }