From 7354c73fe00232e27c3a584133f83e175335ca7b Mon Sep 17 00:00:00 2001 From: kirinnee Date: Tue, 31 Dec 2024 14:45:46 +0800 Subject: [PATCH 1/2] fix: landing page for mobile --- .envrc | 2 +- .infisical.json | 5 + Taskfile.yaml | 5 +- atomi_release.yaml | 26 +- bun.lockb | Bin 218836 -> 219235 bytes flake.lock | 601 ++++++++++++++++-- flake.nix | 10 +- nix/packages.nix | 21 +- package.json | 1 + playwright.config.ts | 6 +- scripts/local/secrets.sh | 18 + src/app.d.ts | 4 +- src/config/client/index.ts | 12 +- src/config/client/lapras.config.ts | 2 +- src/config/client/pichu.config.ts | 2 +- src/config/client/pikachu.config.ts | 2 +- src/config/client/raichu.config.ts | 2 +- src/config/server/index.ts | 12 +- src/config/server/lapras.config.ts | 4 +- src/config/server/pichu.config.ts | 4 +- src/config/server/pikachu.config.ts | 4 +- src/config/server/raichu.config.ts | 4 +- src/config/shared/config.ts | 2 +- src/config/shared/index.ts | 12 +- src/config/shared/lapras.config.ts | 20 +- src/config/shared/pichu.config.ts | 20 +- src/config/shared/pikachu.config.ts | 20 +- src/config/shared/raichu.config.ts | 20 +- src/errors/error_info.ts | 55 +- src/errors/error_utility.ts | 20 +- src/errors/problem_details.ts | 2 +- src/errors/v1/aggregate_error.ts | 2 +- src/errors/v1/local_exception_error.ts | 2 +- src/errors/v1/local_string_error.ts | 2 +- src/errors/v1/local_unknown_error.ts | 2 +- src/errors/v1/unauthenticated.ts | 2 +- src/errors/v1/unauthorized.ts | 2 +- src/hooks.server.ts | 22 +- src/lib/api/core/Api.ts | 417 +++++------- src/lib/api/core/http-client.ts | 108 +--- .../components/custom/account/account.svelte | 7 +- src/lib/components/custom/account/index.ts | 2 +- src/lib/components/custom/main-nav/index.ts | 2 +- src/lib/components/custom/main-nav/nav.svelte | 10 +- src/lib/components/ui/accordion/index.ts | 8 +- src/lib/components/ui/alert-dialog/index.ts | 20 +- src/lib/components/ui/avatar/index.ts | 6 +- src/lib/components/ui/badge/index.ts | 21 +- src/lib/components/ui/button/index.ts | 38 +- src/lib/components/ui/card/index.ts | 14 +- src/lib/components/ui/dialog/index.ts | 16 +- src/lib/components/ui/dropdown-menu/index.ts | 22 +- src/lib/components/ui/input/index.ts | 2 +- src/lib/components/ui/label/index.ts | 2 +- src/lib/components/ui/light-switch/index.ts | 2 +- .../ui/light-switch/light-switch.ts | 49 +- .../ui/light-switch/local-storage-store.ts | 27 +- src/lib/components/ui/select/index.ts | 14 +- src/lib/components/ui/table/index.ts | 16 +- src/lib/components/ui/tabs/index.ts | 8 +- src/lib/components/ui/tooltip/index.ts | 4 +- src/lib/core/error.ts | 16 +- src/lib/core/option.ts | 124 ++-- src/lib/core/result.ts | 148 ++--- src/lib/design/animations.ts | 34 +- src/lib/design/index.ts | 2 +- src/lib/design/lottie/loading.json | 54 +- src/lib/design/lottie/searching.json | 15 +- src/lib/utility.ts | 67 +- src/lib/utils.ts | 24 +- src/routes/+layout.server.ts | 36 +- src/routes/+layout.svelte | 6 +- src/routes/+page.svelte | 14 +- src/routes/api/v1/error_info/+server.ts | 6 +- .../api/v1/error_info/[slug]/+server.ts | 15 +- .../plugins/[user_id]/[plugin_id]/+page.ts | 16 +- .../[user_id]/[processor_id]/+page.ts | 16 +- .../[user_id]/[template_id]/+page.ts | 16 +- src/routes/tokens/+page.ts | 23 +- src/store.ts | 39 +- svelte.config.js | 6 +- tailwind.config.js | 54 +- tests/test.ts | 10 +- vite.config.ts | 6 +- 84 files changed, 1374 insertions(+), 1140 deletions(-) create mode 100644 .infisical.json create mode 100755 scripts/local/secrets.sh diff --git a/.envrc b/.envrc index 813c5aa..6fa0050 100755 --- a/.envrc +++ b/.envrc @@ -1,3 +1,3 @@ -nix_direnv_watch_file "./nix/env.nix" "./nix/fmt.nix" "./nix/packages.nix" "./nix/shells.nix" "./nix/pre-commit.nix" "./flake.nix" "./parse.nix" +watch_file "./nix/env.nix" "./nix/fmt.nix" "./nix/packages.nix" "./nix/shells.nix" "./nix/pre-commit.nix" "./flake.nix" "./parse.nix" use flake pls setup diff --git a/.infisical.json b/.infisical.json new file mode 100644 index 0000000..7818071 --- /dev/null +++ b/.infisical.json @@ -0,0 +1,5 @@ +{ + "workspaceId": "18cef1a6-813c-407a-8e21-2e052adf1802", + "defaultEnvironment": "lapras", + "gitBranchToEnvironmentMapping": null +} diff --git a/Taskfile.yaml b/Taskfile.yaml index a3550e4..a025436 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -1,4 +1,4 @@ -version: "3" +version: '3' vars: API: http://127.0.0.1:9001 @@ -14,6 +14,7 @@ tasks: desc: Setups cmds: - bun i + - ./scripts/local/secrets.sh add: desc: Add Component @@ -48,6 +49,6 @@ tasks: sdk-gen: desc: Generate SDK from Swagger env: - API_URL: "{{.API}}" + API_URL: '{{.API}}' cmds: - ./scripts/local/sdk_gen.sh v1 diff --git a/atomi_release.yaml b/atomi_release.yaml index 6e65f1f..539c059 100644 --- a/atomi_release.yaml +++ b/atomi_release.yaml @@ -22,40 +22,40 @@ specialScopes: release: false plugins: - - module: "@semantic-release/changelog" + - module: '@semantic-release/changelog' config: changelogFile: Changelog.md - - module: "@semantic-release/git" + - module: '@semantic-release/git' config: message: "release: ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" assets: - Changelog.md - CommitConventions.md - - module: "@semantic-release/github" + - module: '@semantic-release/github' # Angular Conventional Commit Example: https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#-commit-message-guidelines types: - type: dep section: ⬆️ Dependencies ⬆️ - desc: "Update dependencies from upstream" + desc: 'Update dependencies from upstream' scopes: default: desc: Update dependencies release: minor - type: build - desc: "Changes that affect the build system or external dependencies (example scopes: nix)" + desc: 'Changes that affect the build system or external dependencies (example scopes: nix)' scopes: default: desc: Fixes in nix release: false - type: config - desc: "Changes to the configuration files (example scopes: nix, ci)" + desc: 'Changes to the configuration files (example scopes: nix, ci)' scopes: default: desc: Update configuration files release: false - type: ci - desc: "Changes to our CI configuration files and scripts (example scopes: github_workflow, github_action)" + desc: 'Changes to our CI configuration files and scripts (example scopes: github_workflow, github_action)' scopes: default: desc: Update CI configuration @@ -73,7 +73,7 @@ types: vae: verb: add application: , - example: "feat: new withdraw api for rapid" + example: 'feat: new withdraw api for rapid' scopes: default: desc: Release a new features @@ -84,7 +84,7 @@ types: vae: verb: fix application: <title> - example: "fix: deposit api for rapid" + example: 'fix: deposit api for rapid' scopes: default: desc: Generic fixes @@ -95,7 +95,7 @@ types: vae: verb: improve application: <title> - example: "perf: alpaca api callback speed increase" + example: 'perf: alpaca api callback speed increase' scopes: default: desc: Generic improvement statement @@ -105,7 +105,7 @@ types: vae: verb: refactor application: <scope>, <title> - example: "refactor: make withdrawal code more reusable" + example: 'refactor: make withdrawal code more reusable' scopes: default: desc: Refactor existing feature @@ -115,7 +115,7 @@ types: vae: verb: style application: <title> - example: "style: add missing semi colon" + example: 'style: add missing semi colon' scopes: default: desc: Generic improvement statement @@ -126,7 +126,7 @@ types: vae: verb: test application: <scope>, <title> - example: "test: update test for deposit api" + example: 'test: update test for deposit api' scopes: default: desc: Made changes to test diff --git a/bun.lockb b/bun.lockb index 05964baabc64e18e8f52e34595a969ac0d08887f..ce15816297ecc029573498dc2d629381fd89dec2 100755 GIT binary patch delta 38306 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 delta 37909 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 BB}4!K diff --git a/flake.lock b/flake.lock index 7d761a4..afb4866 100644 --- a/flake.lock +++ b/flake.lock @@ -1,33 +1,111 @@ { "nodes": { "atomipkgs": { + "inputs": { + "dev-atomi": "dev-atomi", + "dev-atomi_classic": "dev-atomi_classic_3", + "dev-npkgs": "dev-npkgs_3", + "dev-npkgs-unstable-05-Jun-2024": "dev-npkgs-unstable-05-Jun-2024", + "dev-npkgs-unstable-05-Oct-2022": "dev-npkgs-unstable-05-Oct-2022_3", + "dev-npkgs-unstable-07-Feb-2024": "dev-npkgs-unstable-07-Feb-2024_3", + "dev-npkgs-unstable-11-Dec-2022": "dev-npkgs-unstable-11-Dec-2022_3", + "fenix": "fenix_3", + "flake-utils": "flake-utils_6", + "npkgs": "npkgs_3", + "npkgs-unstable": "npkgs-unstable_3" + }, + "locked": { + "lastModified": 1727535459, + "narHash": "sha256-4NhQ5cX5MNaQTLShhwroD+vAbNO6/8KLh7Is7IXhHfY=", + "owner": "kirinnee", + "repo": "test-nix-repo", + "rev": "6e28f6405ca3f2ecd75d494a2911e7e5f368c8b5", + "type": "github" + }, + "original": { + "owner": "kirinnee", + "ref": "v28.0.0", + "repo": "test-nix-repo", + "type": "github" + } + }, + "dev-atomi": { + "inputs": { + "dev-atomi": "dev-atomi_2", + "dev-atomi_classic": "dev-atomi_classic_2", + "dev-npkgs": "dev-npkgs_2", + "dev-npkgs-unstable-05-Oct-2022": "dev-npkgs-unstable-05-Oct-2022_2", + "dev-npkgs-unstable-07-Feb-2024": "dev-npkgs-unstable-07-Feb-2024_2", + "dev-npkgs-unstable-11-Dec-2022": "dev-npkgs-unstable-11-Dec-2022_2", + "fenix": "fenix_2", + "flake-utils": "flake-utils_4", + "npkgs": "npkgs_2", + "npkgs-unstable": "npkgs-unstable_2" + }, + "locked": { + "lastModified": 1707362469, + "narHash": "sha256-rRk9DPJv0xdQrraAbYtP1yivcH5Mz4HhheWKroj/HTc=", + "owner": "kirinnee", + "repo": "test-nix-repo", + "rev": "6ff86a09a767d3e0d20994213e43de507c8a8c37", + "type": "github" + }, + "original": { + "owner": "kirinnee", + "ref": "v23.0.1", + "repo": "test-nix-repo", + "type": "github" + } + }, + "dev-atomi_2": { "inputs": { "dev-atomi_classic": "dev-atomi_classic", "dev-npkgs": "dev-npkgs", "dev-npkgs-unstable-05-Oct-2022": "dev-npkgs-unstable-05-Oct-2022", + "dev-npkgs-unstable-07-Feb-2024": "dev-npkgs-unstable-07-Feb-2024", "dev-npkgs-unstable-11-Dec-2022": "dev-npkgs-unstable-11-Dec-2022", - "dev-npkgs-unstable-20-Sep-2023": "dev-npkgs-unstable-20-Sep-2023", "fenix": "fenix", "flake-utils": "flake-utils_2", "npkgs": "npkgs", "npkgs-unstable": "npkgs-unstable" }, "locked": { - "lastModified": 1698112078, - "narHash": "sha256-vgzVsDzf/FesFmSc6n6c6J//Yf1GkkqsKVbnEfiOko8=", + "lastModified": 1707319132, + "narHash": "sha256-L5ekxE6MeA7URMF9M4Gdal5a5fSKAzCGyXGSepI8ozA=", + "owner": "kirinnee", + "repo": "test-nix-repo", + "rev": "099b7e7850d00d0e376aade2b9ad62683e6440a5", + "type": "github" + }, + "original": { + "owner": "kirinnee", + "ref": "v23.0.0", + "repo": "test-nix-repo", + "type": "github" + } + }, + "dev-atomi_classic": { + "inputs": { + "flake-utils": "flake-utils", + "pkgs": "pkgs", + "pkgs_25_Jul_2021": "pkgs_25_Jul_2021" + }, + "locked": { + "lastModified": 1689236000, + "narHash": "sha256-MEqyIPlD4ueJji6FtfDs8qqZifM9hyYH1svBs3oxrrc=", "owner": "kirinnee", "repo": "test-nix-repo", - "rev": "e9b9c21cf824aa6fa9b4cfeb067d22f60722cd17", + "rev": "2d9d80544d2e81ff736fa23345ad0a9cc5a6c8ab", "type": "github" }, "original": { "owner": "kirinnee", - "ref": "v22.1.0", + "ref": "classic", "repo": "test-nix-repo", "type": "github" } }, - "atomipkgs_classic": { + "dev-atomi_classic_2": { "inputs": { "flake-utils": "flake-utils_3", "pkgs": "pkgs_2", @@ -48,11 +126,11 @@ "type": "github" } }, - "dev-atomi_classic": { + "dev-atomi_classic_3": { "inputs": { - "flake-utils": "flake-utils", - "pkgs": "pkgs", - "pkgs_25_Jul_2021": "pkgs_25_Jul_2021" + "flake-utils": "flake-utils_5", + "pkgs": "pkgs_3", + "pkgs_25_Jul_2021": "pkgs_25_Jul_2021_3" }, "locked": { "lastModified": 1689236000, @@ -71,11 +149,11 @@ }, "dev-npkgs": { "locked": { - "lastModified": 1689048911, - "narHash": "sha256-pODI2CkjWbSLo5nPMZoLtkRNJU/Nr3VSITXZqqmNtIk=", + "lastModified": 1704290814, + "narHash": "sha256-LWvKHp7kGxk/GEtlrGYV68qIvPHkU9iToomNFGagixU=", "owner": "nixos", "repo": "nixpkgs", - "rev": "8163a64662b43848802092d52015ef60777d6129", + "rev": "70bdadeb94ffc8806c0570eb5c2695ad29f0e421", "type": "github" }, "original": { @@ -85,6 +163,21 @@ "type": "github" } }, + "dev-npkgs-unstable-05-Jun-2024": { + "locked": { + "lastModified": 1717196966, + "narHash": "sha256-yZKhxVIKd2lsbOqYd5iDoUIwsRZFqE87smE2Vzf6Ck0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "57610d2f8f0937f39dbd72251e9614b1561942d8", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "57610d2f8f0937f39dbd72251e9614b1561942d8", + "type": "indirect" + } + }, "dev-npkgs-unstable-05-Oct-2022": { "locked": { "lastModified": 1664847737, @@ -100,6 +193,81 @@ "type": "indirect" } }, + "dev-npkgs-unstable-05-Oct-2022_2": { + "locked": { + "lastModified": 1664847737, + "narHash": "sha256-Wxl0CtRH3Vo8+qEZ/PbCcx+9D8wEEi56tJPmROum2ss=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "de80d1d04ee691279e1302a1128c082bbda3ab01", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "de80d1d04ee691279e1302a1128c082bbda3ab01", + "type": "indirect" + } + }, + "dev-npkgs-unstable-05-Oct-2022_3": { + "locked": { + "lastModified": 1664847737, + "narHash": "sha256-Wxl0CtRH3Vo8+qEZ/PbCcx+9D8wEEi56tJPmROum2ss=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "de80d1d04ee691279e1302a1128c082bbda3ab01", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "de80d1d04ee691279e1302a1128c082bbda3ab01", + "type": "indirect" + } + }, + "dev-npkgs-unstable-07-Feb-2024": { + "locked": { + "lastModified": 1707092692, + "narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", + "type": "indirect" + } + }, + "dev-npkgs-unstable-07-Feb-2024_2": { + "locked": { + "lastModified": 1707092692, + "narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", + "type": "indirect" + } + }, + "dev-npkgs-unstable-07-Feb-2024_3": { + "locked": { + "lastModified": 1707092692, + "narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", + "type": "indirect" + } + }, "dev-npkgs-unstable-11-Dec-2022": { "locked": { "lastModified": 1670681895, @@ -115,26 +283,111 @@ "type": "indirect" } }, - "dev-npkgs-unstable-20-Sep-2023": { + "dev-npkgs-unstable-11-Dec-2022_2": { + "locked": { + "lastModified": 1670681895, + "narHash": "sha256-kZH9DSU36W4fn1z81a/24JCGkU517TcY50VE0RFJ9k4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f82f0ec1b70b2879c3f3d9a1015a05c73a90a17c", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "f82f0ec1b70b2879c3f3d9a1015a05c73a90a17c", + "type": "indirect" + } + }, + "dev-npkgs-unstable-11-Dec-2022_3": { "locked": { - "lastModified": 1694959747, - "narHash": "sha256-CXQ2MuledDVlVM5dLC4pB41cFlBWxRw4tCBsFrq3cRk=", + "lastModified": 1670681895, + "narHash": "sha256-kZH9DSU36W4fn1z81a/24JCGkU517TcY50VE0RFJ9k4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "970a59bd19eff3752ce552935687100c46e820a5", + "rev": "f82f0ec1b70b2879c3f3d9a1015a05c73a90a17c", "type": "github" }, "original": { "id": "nixpkgs", - "rev": "970a59bd19eff3752ce552935687100c46e820a5", + "rev": "f82f0ec1b70b2879c3f3d9a1015a05c73a90a17c", "type": "indirect" } }, + "dev-npkgs_2": { + "locked": { + "lastModified": 1704290814, + "narHash": "sha256-LWvKHp7kGxk/GEtlrGYV68qIvPHkU9iToomNFGagixU=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "70bdadeb94ffc8806c0570eb5c2695ad29f0e421", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "dev-npkgs_3": { + "locked": { + "lastModified": 1689048911, + "narHash": "sha256-pODI2CkjWbSLo5nPMZoLtkRNJU/Nr3VSITXZqqmNtIk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8163a64662b43848802092d52015ef60777d6129", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, "fenix": { "inputs": { "nixpkgs": "nixpkgs", "rust-analyzer-src": "rust-analyzer-src" }, + "locked": { + "lastModified": 1706941198, + "narHash": "sha256-t6/qloMYdknVJ9a3QzjylQIZnQfgefJ5kMim50B7dwA=", + "owner": "nix-community", + "repo": "fenix", + "rev": "28dbd8b43ea328ee708f7da538c63e03d5ed93c8", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "fenix_2": { + "inputs": { + "nixpkgs": "nixpkgs_2", + "rust-analyzer-src": "rust-analyzer-src_2" + }, + "locked": { + "lastModified": 1706941198, + "narHash": "sha256-t6/qloMYdknVJ9a3QzjylQIZnQfgefJ5kMim50B7dwA=", + "owner": "nix-community", + "repo": "fenix", + "rev": "28dbd8b43ea328ee708f7da538c63e03d5ed93c8", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, + "fenix_3": { + "inputs": { + "nixpkgs": "nixpkgs_3", + "rust-analyzer-src": "rust-analyzer-src_3" + }, "locked": { "lastModified": 1695363721, "narHash": "sha256-+VRVzXpWdSsZPcR2Cg9Q5LKhUQDVvoQFfH4V8iKNAkU=", @@ -188,11 +441,11 @@ "systems": "systems_2" }, "locked": { - "lastModified": 1689068808, - "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", "owner": "numtide", "repo": "flake-utils", - "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", "type": "github" }, "original": { @@ -223,6 +476,60 @@ "inputs": { "systems": "systems_4" }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "inputs": { + "systems": "systems_5" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_6": { + "inputs": { + "systems": "systems_6" + }, + "locked": { + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_7": { + "inputs": { + "systems": "systems_7" + }, "locked": { "lastModified": 1694529238, "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", @@ -237,9 +544,9 @@ "type": "github" } }, - "flake-utils_5": { + "flake-utils_8": { "inputs": { - "systems": "systems_5" + "systems": "systems_8" }, "locked": { "lastModified": 1685518550, @@ -278,11 +585,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1695145219, - "narHash": "sha256-Eoe9IHbvmo5wEDeJXKFOpKUwxYJIOxKUesounVccNYk=", + "lastModified": 1706732774, + "narHash": "sha256-hqJlyJk4MRpcItGYMF+3uHe8HvxNETWvlGtLuVpqLU0=", "owner": "nixos", "repo": "nixpkgs", - "rev": "5ba549eafcf3e33405e5f66decd1a72356632b96", + "rev": "b8b232ae7b8b144397fdb12d20f592e5e7c1a64d", "type": "github" }, "original": { @@ -307,6 +614,21 @@ "type": "indirect" } }, + "nixpkgs-2411": { + "locked": { + "lastModified": 1735531152, + "narHash": "sha256-As8I+ebItDKtboWgDXYZSIjGlKeqiLBvjxsQHUmAf1Q=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "3ffbbdbac0566a0977da3d2657b89cbcfe9a173b", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-24.11", + "type": "indirect" + } + }, "nixpkgs-oct-21-23": { "locked": { "lastModified": 1697723726, @@ -339,6 +661,38 @@ } }, "nixpkgs_2": { + "locked": { + "lastModified": 1706732774, + "narHash": "sha256-hqJlyJk4MRpcItGYMF+3uHe8HvxNETWvlGtLuVpqLU0=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "b8b232ae7b8b144397fdb12d20f592e5e7c1a64d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1695145219, + "narHash": "sha256-Eoe9IHbvmo5wEDeJXKFOpKUwxYJIOxKUesounVccNYk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "5ba549eafcf3e33405e5f66decd1a72356632b96", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { "locked": { "lastModified": 1694343207, "narHash": "sha256-jWi7OwFxU5Owi4k2JmiL1sa/OuBCQtpaAesuj5LXC8w=", @@ -353,7 +707,7 @@ "type": "indirect" } }, - "nixpkgs_3": { + "nixpkgs_5": { "locked": { "lastModified": 1689261696, "narHash": "sha256-LzfUtFs9MQRvIoQ3MfgSuipBVMXslMPH/vZ+nM40LkA=", @@ -369,7 +723,7 @@ "type": "github" } }, - "nixpkgs_4": { + "nixpkgs_6": { "locked": { "lastModified": 1695644571, "narHash": "sha256-asS9dCCdlt1lPq0DLwkVBbVoEKuEuz+Zi3DG7pR/RxA=", @@ -387,11 +741,11 @@ }, "npkgs": { "locked": { - "lastModified": 1689048911, - "narHash": "sha256-pODI2CkjWbSLo5nPMZoLtkRNJU/Nr3VSITXZqqmNtIk=", + "lastModified": 1704290814, + "narHash": "sha256-LWvKHp7kGxk/GEtlrGYV68qIvPHkU9iToomNFGagixU=", "owner": "nixos", "repo": "nixpkgs", - "rev": "8163a64662b43848802092d52015ef60777d6129", + "rev": "70bdadeb94ffc8806c0570eb5c2695ad29f0e421", "type": "github" }, "original": { @@ -402,6 +756,38 @@ } }, "npkgs-unstable": { + "locked": { + "lastModified": 1707092692, + "narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "npkgs-unstable_2": { + "locked": { + "lastModified": 1707092692, + "narHash": "sha256-ZbHsm+mGk/izkWtT4xwwqz38fdlwu7nUUKXTOmm4SyE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "faf912b086576fd1a15fca610166c98d47bc667e", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "npkgs-unstable_3": { "locked": { "lastModified": 1689008574, "narHash": "sha256-VFMgyHDiqsGDkRg73alv6OdHJAqhybryWHv77bSCGIw=", @@ -417,6 +803,38 @@ "type": "github" } }, + "npkgs_2": { + "locked": { + "lastModified": 1704290814, + "narHash": "sha256-LWvKHp7kGxk/GEtlrGYV68qIvPHkU9iToomNFGagixU=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "70bdadeb94ffc8806c0570eb5c2695ad29f0e421", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "npkgs_3": { + "locked": { + "lastModified": 1689048911, + "narHash": "sha256-pODI2CkjWbSLo5nPMZoLtkRNJU/Nr3VSITXZqqmNtIk=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8163a64662b43848802092d52015ef60777d6129", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, "pkgs": { "locked": { "lastModified": 1643805626, @@ -477,12 +895,42 @@ "type": "indirect" } }, + "pkgs_25_Jul_2021_3": { + "locked": { + "lastModified": 1627107260, + "narHash": "sha256-CwvSwz3kvpp7uEFyOj2Dq6bdtY6P2N0Bzd7ZVgsIICw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "537678cb1ead06fca831077c3b193566cbc3f406", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "537678cb1ead06fca831077c3b193566cbc3f406", + "type": "indirect" + } + }, + "pkgs_3": { + "locked": { + "lastModified": 1643805626, + "narHash": "sha256-AXLDVMG+UaAGsGSpOtQHPIKB+IZ0KSd9WS77aanGzgc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "554d2d8aa25b6e583575459c297ec23750adb6cb", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "rev": "554d2d8aa25b6e583575459c297ec23750adb6cb", + "type": "indirect" + } + }, "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat", - "flake-utils": "flake-utils_5", + "flake-utils": "flake-utils_8", "gitignore": "gitignore", - "nixpkgs": "nixpkgs_3", + "nixpkgs": "nixpkgs_5", "nixpkgs-stable": "nixpkgs-stable" }, "locked": { @@ -502,16 +950,50 @@ "root": { "inputs": { "atomipkgs": "atomipkgs", - "atomipkgs_classic": "atomipkgs_classic", - "flake-utils": "flake-utils_4", - "nixpkgs": "nixpkgs_2", + "flake-utils": "flake-utils_7", + "nixpkgs": "nixpkgs_4", "nixpkgs-2305": "nixpkgs-2305", + "nixpkgs-2411": "nixpkgs-2411", "nixpkgs-oct-21-23": "nixpkgs-oct-21-23", "pre-commit-hooks": "pre-commit-hooks", "treefmt-nix": "treefmt-nix" } }, "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1706875368, + "narHash": "sha256-KOBXxNurIU2lEmO6lR2A5El32X9x8ITt25McxKZ/Ew0=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "8f6a72871ec87ed53cfe43a09fb284168a284e7e", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "rust-analyzer-src_2": { + "flake": false, + "locked": { + "lastModified": 1706875368, + "narHash": "sha256-KOBXxNurIU2lEmO6lR2A5El32X9x8ITt25McxKZ/Ew0=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "8f6a72871ec87ed53cfe43a09fb284168a284e7e", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, + "rust-analyzer-src_3": { "flake": false, "locked": { "lastModified": 1695220688, @@ -603,9 +1085,54 @@ "type": "github" } }, + "systems_6": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_7": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_8": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "treefmt-nix": { "inputs": { - "nixpkgs": "nixpkgs_4" + "nixpkgs": "nixpkgs_6" }, "locked": { "lastModified": 1697388351, diff --git a/flake.nix b/flake.nix index 05623a1..660efbe 100644 --- a/flake.nix +++ b/flake.nix @@ -8,9 +8,9 @@ # registry nixpkgs.url = "nixpkgs/78058d810644f5ed276804ce7ea9e82d92bee293"; nixpkgs-2305.url = "nixpkgs/nixos-23.05"; + nixpkgs-2411.url = "nixpkgs/nixos-24.11"; nixpkgs-oct-21-23.url = "nixpkgs/7c9cc5a6e5d38010801741ac830a3f8fd667a7a0"; - atomipkgs.url = "github:kirinnee/test-nix-repo/v22.1.0"; - atomipkgs_classic.url = "github:kirinnee/test-nix-repo/classic"; + atomipkgs.url = "github:kirinnee/test-nix-repo/v28.0.0"; }; outputs = @@ -23,9 +23,9 @@ # registries , atomipkgs - , atomipkgs_classic , nixpkgs , nixpkgs-2305 + , nixpkgs-2411 , nixpkgs-oct-21-23 } @inputs: @@ -35,9 +35,9 @@ let pkgs = nixpkgs.legacyPackages.${system}; pkgs-2305 = nixpkgs-2305.legacyPackages.${system}; + pkgs-2411 = nixpkgs-2411.legacyPackages.${system}; pkgs-oct-21-23 = nixpkgs-oct-21-23.legacyPackages.${system}; atomi = atomipkgs.packages.${system}; - atomi_classic = atomipkgs_classic.packages.${system}; pre-commit-lib = pre-commit-hooks.lib.${system}; in with rec { @@ -49,7 +49,7 @@ }; packages = import ./nix/packages.nix { - inherit pkgs pkgs-2305 atomi atomi_classic pkgs-oct-21-23; + inherit pkgs pkgs-2305 pkgs-2411 atomi pkgs-oct-21-23; }; env = import ./nix/env.nix { inherit pkgs packages; diff --git a/nix/packages.nix b/nix/packages.nix index 64f10ff..d4af28b 100644 --- a/nix/packages.nix +++ b/nix/packages.nix @@ -1,22 +1,16 @@ -{ pkgs, pkgs-2305, atomi, atomi_classic, pkgs-oct-21-23 }: +{ pkgs, pkgs-2305, pkgs-2411, atomi, pkgs-oct-21-23 }: let all = { - atomipkgs_classic = ( - with atomi_classic; - { - inherit - sg; - } - ); + atomipkgs = ( with atomi; { inherit - infisical mirrord typescript_json_schema swagger_typescript_api + sg pls; } ); @@ -24,6 +18,13 @@ let with pkgs-2305; { } ); + nix-2411 = ( + with pkgs-2411; + { + inherit + infisical; + } + ); oct-21-23 = ( with pkgs-oct-21-23; { @@ -52,6 +53,6 @@ let in with all; nix-2305 // +nix-2411 // atomipkgs // -atomipkgs_classic // oct-21-23 diff --git a/package.json b/package.json index 170b6f1..16434d0 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@auth/core": "^0.17.0", "@auth/sveltekit": "0.3.7", "bits-ui": "^0.6.3", + "caniuse-lite": "", "clsx": "^2.0.0", "jwt-decode": "^3.1.2", "lottie-web": "^5.12.2", diff --git a/playwright.config.ts b/playwright.config.ts index 92e6d08..b59a0e4 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,11 +1,11 @@ -import type { PlaywrightTestConfig } from "@playwright/test"; +import type { PlaywrightTestConfig } from '@playwright/test'; const config: PlaywrightTestConfig = { webServer: { - command: "npm run build && npm run preview", + command: 'npm run build && npm run preview', port: 4173, }, - testDir: "tests", + testDir: 'tests', testMatch: /(.+\.)?(test|spec)\.[jt]s/, }; diff --git a/scripts/local/secrets.sh b/scripts/local/secrets.sh new file mode 100755 index 0000000..5f3051a --- /dev/null +++ b/scripts/local/secrets.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -eou pipefail + +echo "🔏 Setting up secrets for local development..." +set +e +(infisical secrets) &>/dev/null +ec="$?" +set -e + +if [ "$ec" != '0' ]; then + infisical login +fi + +echo "🔄 Syncing secrets..." +infisical export --format dotenv >.env +echo "PUBLIC_LANDSCAPE=lapras" >>.env +echo "🔑 Secrets set up!" diff --git a/src/app.d.ts b/src/app.d.ts index 123856d..2c72ef2 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -15,7 +15,7 @@ interface Tokens { id_token?: string; } -declare module "@auth/core/types" { +declare module '@auth/core/types' { interface Session { access_token?: string; scopes?: string[]; @@ -24,7 +24,7 @@ declare module "@auth/core/types" { } } -declare module "@auth/core/jwt" { +declare module '@auth/core/jwt' { interface JWT { scopes: string[]; roles: string[]; diff --git a/src/config/client/index.ts b/src/config/client/index.ts index 505a8a3..f97e626 100644 --- a/src/config/client/index.ts +++ b/src/config/client/index.ts @@ -1,9 +1,9 @@ -import { PUBLIC_LANDSCAPE } from "$env/static/public"; -import type { IClientConfig } from "./config"; -import lapras from "./lapras.config"; -import pichu from "./pichu.config"; -import pikachu from "./pikachu.config"; -import raichu from "./raichu.config"; +import { PUBLIC_LANDSCAPE } from '$env/static/public'; +import type { IClientConfig } from './config'; +import lapras from './lapras.config'; +import pichu from './pichu.config'; +import pikachu from './pikachu.config'; +import raichu from './raichu.config'; const reg: { [s: string]: IClientConfig } = { lapras, diff --git a/src/config/client/lapras.config.ts b/src/config/client/lapras.config.ts index a02fc50..dad4cea 100644 --- a/src/config/client/lapras.config.ts +++ b/src/config/client/lapras.config.ts @@ -1,4 +1,4 @@ -import type { IClientConfig } from "./config"; +import type { IClientConfig } from './config'; const config: IClientConfig = {}; diff --git a/src/config/client/pichu.config.ts b/src/config/client/pichu.config.ts index a02fc50..dad4cea 100644 --- a/src/config/client/pichu.config.ts +++ b/src/config/client/pichu.config.ts @@ -1,4 +1,4 @@ -import type { IClientConfig } from "./config"; +import type { IClientConfig } from './config'; const config: IClientConfig = {}; diff --git a/src/config/client/pikachu.config.ts b/src/config/client/pikachu.config.ts index a02fc50..dad4cea 100644 --- a/src/config/client/pikachu.config.ts +++ b/src/config/client/pikachu.config.ts @@ -1,4 +1,4 @@ -import type { IClientConfig } from "./config"; +import type { IClientConfig } from './config'; const config: IClientConfig = {}; diff --git a/src/config/client/raichu.config.ts b/src/config/client/raichu.config.ts index a02fc50..dad4cea 100644 --- a/src/config/client/raichu.config.ts +++ b/src/config/client/raichu.config.ts @@ -1,4 +1,4 @@ -import type { IClientConfig } from "./config"; +import type { IClientConfig } from './config'; const config: IClientConfig = {}; diff --git a/src/config/server/index.ts b/src/config/server/index.ts index b8c6151..50005c3 100644 --- a/src/config/server/index.ts +++ b/src/config/server/index.ts @@ -1,9 +1,9 @@ -import { PUBLIC_LANDSCAPE } from "$env/static/public"; -import type { IServerConfig } from "./config"; -import lapras from "./lapras.config"; -import pichu from "./pichu.config"; -import pikachu from "./pikachu.config"; -import raichu from "./raichu.config"; +import { PUBLIC_LANDSCAPE } from '$env/static/public'; +import type { IServerConfig } from './config'; +import lapras from './lapras.config'; +import pichu from './pichu.config'; +import pikachu from './pikachu.config'; +import raichu from './raichu.config'; const reg: { [s: string]: IServerConfig } = { lapras, diff --git a/src/config/server/lapras.config.ts b/src/config/server/lapras.config.ts index f5e89de..a2ab865 100644 --- a/src/config/server/lapras.config.ts +++ b/src/config/server/lapras.config.ts @@ -1,5 +1,5 @@ -import type { IServerConfig } from "./config"; -import { DESCOPE_ID, DESCOPE_SECRET, AUTH_SECRET } from "$env/static/private"; +import type { IServerConfig } from './config'; +import { DESCOPE_ID, DESCOPE_SECRET, AUTH_SECRET } from '$env/static/private'; const config: IServerConfig = { auth: { diff --git a/src/config/server/pichu.config.ts b/src/config/server/pichu.config.ts index f5e89de..a2ab865 100644 --- a/src/config/server/pichu.config.ts +++ b/src/config/server/pichu.config.ts @@ -1,5 +1,5 @@ -import type { IServerConfig } from "./config"; -import { DESCOPE_ID, DESCOPE_SECRET, AUTH_SECRET } from "$env/static/private"; +import type { IServerConfig } from './config'; +import { DESCOPE_ID, DESCOPE_SECRET, AUTH_SECRET } from '$env/static/private'; const config: IServerConfig = { auth: { diff --git a/src/config/server/pikachu.config.ts b/src/config/server/pikachu.config.ts index f5e89de..a2ab865 100644 --- a/src/config/server/pikachu.config.ts +++ b/src/config/server/pikachu.config.ts @@ -1,5 +1,5 @@ -import type { IServerConfig } from "./config"; -import { DESCOPE_ID, DESCOPE_SECRET, AUTH_SECRET } from "$env/static/private"; +import type { IServerConfig } from './config'; +import { DESCOPE_ID, DESCOPE_SECRET, AUTH_SECRET } from '$env/static/private'; const config: IServerConfig = { auth: { diff --git a/src/config/server/raichu.config.ts b/src/config/server/raichu.config.ts index f5e89de..a2ab865 100644 --- a/src/config/server/raichu.config.ts +++ b/src/config/server/raichu.config.ts @@ -1,5 +1,5 @@ -import type { IServerConfig } from "./config"; -import { DESCOPE_ID, DESCOPE_SECRET, AUTH_SECRET } from "$env/static/private"; +import type { IServerConfig } from './config'; +import { DESCOPE_ID, DESCOPE_SECRET, AUTH_SECRET } from '$env/static/private'; const config: IServerConfig = { auth: { diff --git a/src/config/shared/config.ts b/src/config/shared/config.ts index 89fe11a..b10a230 100644 --- a/src/config/shared/config.ts +++ b/src/config/shared/config.ts @@ -8,7 +8,7 @@ interface ISharedConfig { }; errorPortal: { enabled: boolean; - scheme: "http" | "https"; + scheme: 'http' | 'https'; host: string; }; api: { diff --git a/src/config/shared/index.ts b/src/config/shared/index.ts index 4b32cac..f639d59 100644 --- a/src/config/shared/index.ts +++ b/src/config/shared/index.ts @@ -1,9 +1,9 @@ -import { PUBLIC_LANDSCAPE } from "$env/static/public"; -import type { ISharedConfig } from "./config"; -import lapras from "./lapras.config"; -import pichu from "./pichu.config"; -import pikachu from "./pikachu.config"; -import raichu from "./raichu.config"; +import { PUBLIC_LANDSCAPE } from '$env/static/public'; +import type { ISharedConfig } from './config'; +import lapras from './lapras.config'; +import pichu from './pichu.config'; +import pikachu from './pikachu.config'; +import raichu from './raichu.config'; const reg: { [s: string]: ISharedConfig } = { lapras, diff --git a/src/config/shared/lapras.config.ts b/src/config/shared/lapras.config.ts index 5228413..f0d32a4 100644 --- a/src/config/shared/lapras.config.ts +++ b/src/config/shared/lapras.config.ts @@ -1,21 +1,21 @@ -import type { ISharedConfig } from "./config"; +import type { ISharedConfig } from './config'; const config: ISharedConfig = { app: { - landscape: "lapras", - platform: "sulfone", - service: "argon", - module: "webapp", - version: "1.0.0", + landscape: 'lapras', + platform: 'sulfone', + service: 'argon', + module: 'webapp', + version: '1.0.0', }, errorPortal: { enabled: true, - host: "localhost:3000", - scheme: "http", + host: 'localhost:3000', + scheme: 'http', }, api: { - domain: "127.0.0.1:9001", - scheme: "http", + domain: '127.0.0.1:9001', + scheme: 'http', }, }; diff --git a/src/config/shared/pichu.config.ts b/src/config/shared/pichu.config.ts index be271f0..2eb4b81 100644 --- a/src/config/shared/pichu.config.ts +++ b/src/config/shared/pichu.config.ts @@ -1,21 +1,21 @@ -import type { ISharedConfig } from "./config"; +import type { ISharedConfig } from './config'; const config: ISharedConfig = { app: { - landscape: "pichu", - platform: "sulfone", - service: "argon", - module: "webapp", - version: "1.0.0", + landscape: 'pichu', + platform: 'sulfone', + service: 'argon', + module: 'webapp', + version: '1.0.0', }, errorPortal: { enabled: true, - host: "error-portal.pages.dev", - scheme: "https", + host: 'error-portal.pages.dev', + scheme: 'https', }, api: { - domain: "api.zinc.sulfone.pichu.cluster.atomi.cloud", - scheme: "https", + domain: 'api.zinc.sulfone.pichu.cluster.atomi.cloud', + scheme: 'https', }, }; diff --git a/src/config/shared/pikachu.config.ts b/src/config/shared/pikachu.config.ts index 2a99d6b..7241a78 100644 --- a/src/config/shared/pikachu.config.ts +++ b/src/config/shared/pikachu.config.ts @@ -1,21 +1,21 @@ -import type { ISharedConfig } from "./config"; +import type { ISharedConfig } from './config'; const config: ISharedConfig = { app: { - landscape: "pikachu", - platform: "sulfone", - service: "argon", - module: "webapp", - version: "1.0.0", + landscape: 'pikachu', + platform: 'sulfone', + service: 'argon', + module: 'webapp', + version: '1.0.0', }, errorPortal: { enabled: true, - host: "error-portal.pages.dev", - scheme: "https", + host: 'error-portal.pages.dev', + scheme: 'https', }, api: { - domain: "api.zinc.sulfone.pikachu.cluster.atomi.cloud", - scheme: "https", + domain: 'api.zinc.sulfone.pikachu.cluster.atomi.cloud', + scheme: 'https', }, }; diff --git a/src/config/shared/raichu.config.ts b/src/config/shared/raichu.config.ts index 2d77139..2d8bcf6 100644 --- a/src/config/shared/raichu.config.ts +++ b/src/config/shared/raichu.config.ts @@ -1,21 +1,21 @@ -import type { ISharedConfig } from "./config"; +import type { ISharedConfig } from './config'; const config: ISharedConfig = { app: { - landscape: "raichu", - platform: "sulfone", - service: "argon", - module: "webapp", - version: "1.0.0", + landscape: 'raichu', + platform: 'sulfone', + service: 'argon', + module: 'webapp', + version: '1.0.0', }, errorPortal: { enabled: true, - host: "error-portal.pages.dev", - scheme: "https", + host: 'error-portal.pages.dev', + scheme: 'https', }, api: { - domain: "api.zinc.sulfone.raichu.cluster.atomi.cloud", - scheme: "https", + domain: 'api.zinc.sulfone.raichu.cluster.atomi.cloud', + scheme: 'https', }, }; diff --git a/src/errors/error_info.ts b/src/errors/error_info.ts index c1bb95a..f1cee13 100644 --- a/src/errors/error_info.ts +++ b/src/errors/error_info.ts @@ -1,10 +1,10 @@ -import { Unauthenticated } from "./v1/unauthenticated"; -import type { Problem } from "./problem"; -import { LocalExceptionError } from "./v1/local_exception_error"; -import { LocalStringError } from "./v1/local_string_error"; -import { LocalUnknownError } from "./v1/local_unknown_error"; -import { Unauthorized } from "./v1/unauthorized"; -import { AggregatedError } from "./v1/aggregate_error"; +import { Unauthenticated } from './v1/unauthenticated'; +import type { Problem } from './problem'; +import { LocalExceptionError } from './v1/local_exception_error'; +import { LocalStringError } from './v1/local_string_error'; +import { LocalUnknownError } from './v1/local_unknown_error'; +import { Unauthorized } from './v1/unauthorized'; +import { AggregatedError } from './v1/aggregate_error'; interface ErrorInfoResp { id: string; @@ -27,16 +27,13 @@ interface ErrorRegistryEntry { type: ProblemConstructor; } -const problems: Map<ProblemConstructor, ErrorRegistryEntry> = new Map< - ProblemConstructor, - ErrorRegistryEntry ->([ +const problems: Map<ProblemConstructor, ErrorRegistryEntry> = new Map<ProblemConstructor, ErrorRegistryEntry>([ [ AggregatedError, { - id: "email_not_verified", - title: "Email Not Verified", - version: "v1", + id: 'email_not_verified', + title: 'Email Not Verified', + version: 'v1', schema: {}, status: 403, type: AggregatedError, @@ -45,9 +42,9 @@ const problems: Map<ProblemConstructor, ErrorRegistryEntry> = new Map< [ LocalExceptionError, { - id: "local_exception_error", - title: "Client Error", - version: "v1", + id: 'local_exception_error', + title: 'Client Error', + version: 'v1', schema: {}, status: 400, type: LocalExceptionError, @@ -56,9 +53,9 @@ const problems: Map<ProblemConstructor, ErrorRegistryEntry> = new Map< [ LocalStringError, { - id: "local_string_error", - title: "Client Error", - version: "v1", + id: 'local_string_error', + title: 'Client Error', + version: 'v1', schema: {}, status: 400, type: LocalStringError, @@ -67,9 +64,9 @@ const problems: Map<ProblemConstructor, ErrorRegistryEntry> = new Map< [ LocalUnknownError, { - id: "local_unknown_error", - title: "Unknown Error", - version: "v1", + id: 'local_unknown_error', + title: 'Unknown Error', + version: 'v1', schema: {}, status: 400, type: LocalUnknownError, @@ -78,9 +75,9 @@ const problems: Map<ProblemConstructor, ErrorRegistryEntry> = new Map< [ Unauthenticated, { - id: "unauthenticated", - title: "Not Authenticated", - version: "v1", + id: 'unauthenticated', + title: 'Not Authenticated', + version: 'v1', schema: {}, status: 401, type: Unauthenticated, @@ -89,9 +86,9 @@ const problems: Map<ProblemConstructor, ErrorRegistryEntry> = new Map< [ Unauthorized, { - id: "unauthorized", - title: "Unauthorized", - version: "v1", + id: 'unauthorized', + title: 'Unauthorized', + version: 'v1', schema: {}, status: 403, type: Unauthorized, diff --git a/src/errors/error_utility.ts b/src/errors/error_utility.ts index 308e69c..5d7ec98 100644 --- a/src/errors/error_utility.ts +++ b/src/errors/error_utility.ts @@ -1,8 +1,8 @@ -import { config } from "../config/shared"; -import type { ProblemDetails } from "./problem_details"; -import type { ProblemConstructor } from "./error_info"; -import { problems } from "./error_info"; -import type { Problem } from "./problem"; +import { config } from '../config/shared'; +import type { ProblemDetails } from './problem_details'; +import type { ProblemConstructor } from './error_info'; +import { problems } from './error_info'; +import type { Problem } from './problem'; const ep = config.errorPortal; const ap = config.app; @@ -11,11 +11,11 @@ function toDetail<T extends Problem>(problem: T): ProblemDetails { const errorInfo = problems.get(problem.constructor as ProblemConstructor); if (errorInfo == null) { return { - detail: "Error parsed not registered", - title: "Error occurred when parsing Error", + detail: 'Error parsed not registered', + title: 'Error occurred when parsing Error', status: 500, - traceId: "local", - type: "none", + traceId: 'local', + type: 'none', data: { original: problem, }, @@ -28,7 +28,7 @@ function toDetail<T extends Problem>(problem: T): ProblemDetails { detail: problem.detail, title: errorInfo.title, status: errorInfo.status, - traceId: "local", + traceId: 'local', type: `${ep.scheme}://${ep.host}/docs/${ap.landscape}/${ap.platform}/${ap.service}/${ap.module}/${errorInfo.version}/${errorInfo.id}`, data: p, }; diff --git a/src/errors/problem_details.ts b/src/errors/problem_details.ts index 7605792..d1949fb 100644 --- a/src/errors/problem_details.ts +++ b/src/errors/problem_details.ts @@ -1,4 +1,4 @@ -import type { Problem } from "./problem"; +import type { Problem } from './problem'; interface ProblemDetails { type: string; diff --git a/src/errors/v1/aggregate_error.ts b/src/errors/v1/aggregate_error.ts index 8777450..477d5c2 100644 --- a/src/errors/v1/aggregate_error.ts +++ b/src/errors/v1/aggregate_error.ts @@ -1,4 +1,4 @@ -import { Problem } from "../problem"; +import { Problem } from '../problem'; /** * Unauthenticated diff --git a/src/errors/v1/local_exception_error.ts b/src/errors/v1/local_exception_error.ts index 1bfa470..3c57314 100644 --- a/src/errors/v1/local_exception_error.ts +++ b/src/errors/v1/local_exception_error.ts @@ -1,4 +1,4 @@ -import { Problem } from "../problem"; +import { Problem } from '../problem'; class LocalExceptionError extends Problem { constructor(detail: string, error: Error) { diff --git a/src/errors/v1/local_string_error.ts b/src/errors/v1/local_string_error.ts index f22798b..64c7f05 100644 --- a/src/errors/v1/local_string_error.ts +++ b/src/errors/v1/local_string_error.ts @@ -1,4 +1,4 @@ -import { Problem } from "../problem"; +import { Problem } from '../problem'; class LocalStringError extends Problem { constructor(detail: string, error: string) { diff --git a/src/errors/v1/local_unknown_error.ts b/src/errors/v1/local_unknown_error.ts index 50dc04f..69456a8 100644 --- a/src/errors/v1/local_unknown_error.ts +++ b/src/errors/v1/local_unknown_error.ts @@ -1,4 +1,4 @@ -import { Problem } from "../problem"; +import { Problem } from '../problem'; class LocalUnknownError extends Problem { constructor(detail: string, error: unknown) { diff --git a/src/errors/v1/unauthenticated.ts b/src/errors/v1/unauthenticated.ts index 0ee3e6a..5227802 100644 --- a/src/errors/v1/unauthenticated.ts +++ b/src/errors/v1/unauthenticated.ts @@ -1,4 +1,4 @@ -import { Problem } from "../problem"; +import { Problem } from '../problem'; /** * Unauthenticated diff --git a/src/errors/v1/unauthorized.ts b/src/errors/v1/unauthorized.ts index c1fdd78..b1378dc 100644 --- a/src/errors/v1/unauthorized.ts +++ b/src/errors/v1/unauthorized.ts @@ -1,4 +1,4 @@ -import { Problem } from "../problem"; +import { Problem } from '../problem'; /** * Unauthenticated diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 9360bf3..3dc47d6 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,8 +1,8 @@ -import { SvelteKitAuth } from "@auth/sveltekit"; -import jwt_decode from "jwt-decode"; -import { config } from "./config/server"; -import type { JWT } from "@auth/core/jwt"; -import type { Session } from "@auth/core/types"; +import { SvelteKitAuth } from '@auth/sveltekit'; +import jwt_decode from 'jwt-decode'; +import { config } from './config/server'; +import type { JWT } from '@auth/core/jwt'; +import type { Session } from '@auth/core/types'; function expired(token?: string, now?: Date): boolean { if (now == null) now = new Date(); @@ -14,16 +14,16 @@ function expired(token?: string, now?: Date): boolean { export const handle = SvelteKitAuth({ providers: [ { - id: "descope", - name: "Descope", - type: "oidc", + id: 'descope', + name: 'Descope', + type: 'oidc', issuer: `https://api.descope.com/${config.auth.clientId}`, wellKnown: `https://api.descope.com/${config.auth.clientId}/.well-known/openid-configuration`, - authorization: { params: { scope: "openid email profile" } }, + authorization: { params: { scope: 'openid email profile' } }, clientId: config.auth.clientId, clientSecret: config.auth.clientSecret, // eslint-disable-next-line @typescript-eslint/no-explicit-any - checks: ["pkce", "state"] as any, + checks: ['pkce', 'state'] as any, }, ], callbacks: { @@ -58,7 +58,7 @@ export const handle = SvelteKitAuth({ } const now = new Date(); - if (!expired(tkn.raw?.access_token ?? "", now)) return token; + if (!expired(tkn.raw?.access_token ?? '', now)) return token; // eslint-disable-next-line @typescript-eslint/no-unused-vars const { raw, ...t } = token; diff --git a/src/lib/api/core/Api.ts b/src/lib/api/core/Api.ts index 0f1eec9..328b7bb 100644 --- a/src/lib/api/core/Api.ts +++ b/src/lib/api/core/Api.ts @@ -48,12 +48,10 @@ import type { UserExistResp, UserPrincipalResp, UserResp, -} from "./data-contracts"; -import { ContentType, HttpClient, type RequestParams } from "./http-client"; +} from './data-contracts'; +import { ContentType, HttpClient, type RequestParams } from './http-client'; -export class Api< - SecurityDataType = unknown, -> extends HttpClient<SecurityDataType> { +export class Api<SecurityDataType = unknown> extends HttpClient<SecurityDataType> { /** * No description * @@ -76,10 +74,10 @@ export class Api< ) => this.request<PluginPrincipalResp[], any>({ path: `/api/v${version}/Plugin`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -90,17 +88,12 @@ export class Api< * @request GET:/api/v{version}/Plugin/id/{userId}/{pluginId} * @secure */ - vPluginIdDetail = ( - userId: string, - pluginId: string, - version: string, - params: RequestParams = {}, - ) => + vPluginIdDetail = (userId: string, pluginId: string, version: string, params: RequestParams = {}) => this.request<PluginResp, any>({ path: `/api/v${version}/Plugin/id/${userId}/${pluginId}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -120,11 +113,11 @@ export class Api< ) => this.request<PluginPrincipalResp, any>({ path: `/api/v${version}/Plugin/id/${userId}/${pluginId}`, - method: "PUT", + method: 'PUT', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -135,17 +128,12 @@ export class Api< * @request DELETE:/api/v{version}/Plugin/id/{userId}/{pluginId} * @secure */ - vPluginIdDelete = ( - userId: string, - pluginId: string, - version: string, - params: RequestParams = {}, - ) => + vPluginIdDelete = (userId: string, pluginId: string, version: string, params: RequestParams = {}) => this.request<Unit, any>({ path: `/api/v${version}/Plugin/id/${userId}/${pluginId}`, - method: "DELETE", + method: 'DELETE', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -156,17 +144,12 @@ export class Api< * @request GET:/api/v{version}/Plugin/slug/{username}/{name} * @secure */ - vPluginSlugDetail = ( - username: string, - name: string, - version: string, - params: RequestParams = {}, - ) => + vPluginSlugDetail = (username: string, name: string, version: string, params: RequestParams = {}) => this.request<PluginResp, any>({ path: `/api/v${version}/Plugin/slug/${username}/${name}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -177,19 +160,14 @@ export class Api< * @request POST:/api/v{version}/Plugin/id/{userId} * @secure */ - vPluginIdCreate = ( - userId: string, - version: string, - data: CreatePluginReq, - params: RequestParams = {}, - ) => + vPluginIdCreate = (userId: string, version: string, data: CreatePluginReq, params: RequestParams = {}) => this.request<PluginPrincipalResp, any>({ path: `/api/v${version}/Plugin/id/${userId}`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -210,9 +188,9 @@ export class Api< ) => this.request<Unit, any>({ path: `/api/v${version}/Plugin/slug/${username}/${pluginName}/like/${likerId}/${like}`, - method: "POST", + method: 'POST', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -238,10 +216,10 @@ export class Api< ) => this.request<PluginVersionPrincipalResp[], any>({ path: `/api/v${version}/Plugin/slug/${username}/${pluginName}/versions`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -261,11 +239,11 @@ export class Api< ) => this.request<PluginVersionPrincipalResp, any>({ path: `/api/v${version}/Plugin/slug/${username}/${pluginName}/versions`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -291,10 +269,10 @@ export class Api< ) => this.request<PluginVersionPrincipalResp[], any>({ path: `/api/v${version}/Plugin/id/${userId}/${pluginId}/versions`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -314,11 +292,11 @@ export class Api< ) => this.request<PluginVersionPrincipalResp, any>({ path: `/api/v${version}/Plugin/id/${userId}/${pluginId}/versions`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -343,10 +321,10 @@ export class Api< ) => this.request<PluginVersionResp, any>({ path: `/api/v${version}/Plugin/slug/${username}/${pluginName}/versions/${ver}`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -368,10 +346,10 @@ export class Api< ) => this.request<PluginVersionResp, any>({ path: `/api/v${version}/Plugin/slug/${username}/${pluginName}/versions/latest`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -393,9 +371,9 @@ export class Api< ) => this.request<PluginVersionResp, any>({ path: `/api/v${version}/Plugin/id/${userId}/${pluginId}/versions/${ver}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -416,11 +394,11 @@ export class Api< ) => this.request<PluginVersionPrincipalResp, any>({ path: `/api/v${version}/Plugin/id/${userId}/${pluginId}/versions/${ver}`, - method: "PUT", + method: 'PUT', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -431,19 +409,14 @@ export class Api< * @request POST:/api/v{version}/Plugin/push/{username} * @secure */ - vPluginPushCreate = ( - username: string, - version: string, - data: PushPluginReq, - params: RequestParams = {}, - ) => + vPluginPushCreate = (username: string, version: string, data: PushPluginReq, params: RequestParams = {}) => this.request<PluginVersionPrincipalResp, any>({ path: `/api/v${version}/Plugin/push/${username}`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -468,10 +441,10 @@ export class Api< ) => this.request<ProcessorPrincipalResp[], any>({ path: `/api/v${version}/Processor`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -482,17 +455,12 @@ export class Api< * @request GET:/api/v{version}/Processor/id/{userId}/{processorId} * @secure */ - vProcessorIdDetail = ( - userId: string, - processorId: string, - version: string, - params: RequestParams = {}, - ) => + vProcessorIdDetail = (userId: string, processorId: string, version: string, params: RequestParams = {}) => this.request<ProcessorResp, any>({ path: `/api/v${version}/Processor/id/${userId}/${processorId}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -512,11 +480,11 @@ export class Api< ) => this.request<ProcessorPrincipalResp, any>({ path: `/api/v${version}/Processor/id/${userId}/${processorId}`, - method: "PUT", + method: 'PUT', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -527,17 +495,12 @@ export class Api< * @request DELETE:/api/v{version}/Processor/id/{userId}/{processorId} * @secure */ - vProcessorIdDelete = ( - userId: string, - processorId: string, - version: string, - params: RequestParams = {}, - ) => + vProcessorIdDelete = (userId: string, processorId: string, version: string, params: RequestParams = {}) => this.request<Unit, any>({ path: `/api/v${version}/Processor/id/${userId}/${processorId}`, - method: "DELETE", + method: 'DELETE', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -548,17 +511,12 @@ export class Api< * @request GET:/api/v{version}/Processor/slug/{username}/{name} * @secure */ - vProcessorSlugDetail = ( - username: string, - name: string, - version: string, - params: RequestParams = {}, - ) => + vProcessorSlugDetail = (username: string, name: string, version: string, params: RequestParams = {}) => this.request<ProcessorResp, any>({ path: `/api/v${version}/Processor/slug/${username}/${name}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -569,19 +527,14 @@ export class Api< * @request POST:/api/v{version}/Processor/id/{userId} * @secure */ - vProcessorIdCreate = ( - userId: string, - version: string, - data: CreateProcessorReq, - params: RequestParams = {}, - ) => + vProcessorIdCreate = (userId: string, version: string, data: CreateProcessorReq, params: RequestParams = {}) => this.request<ProcessorPrincipalResp, any>({ path: `/api/v${version}/Processor/id/${userId}`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -602,9 +555,9 @@ export class Api< ) => this.request<Unit, any>({ path: `/api/v${version}/Processor/slug/${username}/${processorName}/like/${likerId}/${like}`, - method: "POST", + method: 'POST', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -630,10 +583,10 @@ export class Api< ) => this.request<ProcessorVersionPrincipalResp[], any>({ path: `/api/v${version}/Processor/slug/${username}/${processorName}/versions`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -653,11 +606,11 @@ export class Api< ) => this.request<ProcessorVersionPrincipalResp, any>({ path: `/api/v${version}/Processor/slug/${username}/${processorName}/versions`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -683,10 +636,10 @@ export class Api< ) => this.request<ProcessorVersionPrincipalResp[], any>({ path: `/api/v${version}/Processor/id/${userId}/${processorId}/versions`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -706,11 +659,11 @@ export class Api< ) => this.request<ProcessorVersionPrincipalResp, any>({ path: `/api/v${version}/Processor/id/${userId}/${processorId}/versions`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -735,10 +688,10 @@ export class Api< ) => this.request<ProcessorVersionResp, any>({ path: `/api/v${version}/Processor/slug/${username}/${processorName}/versions/${ver}`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -760,10 +713,10 @@ export class Api< ) => this.request<ProcessorVersionResp, any>({ path: `/api/v${version}/Processor/slug/${username}/${processorName}/versions/latest`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -785,9 +738,9 @@ export class Api< ) => this.request<ProcessorVersionResp, any>({ path: `/api/v${version}/Processor/id/${userId}/${processorId}/versions/${ver}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -808,11 +761,11 @@ export class Api< ) => this.request<ProcessorVersionPrincipalResp, any>({ path: `/api/v${version}/Processor/id/${userId}/${processorId}/versions/${ver}`, - method: "PUT", + method: 'PUT', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -823,19 +776,14 @@ export class Api< * @request POST:/api/v{version}/Processor/push/{username} * @secure */ - vProcessorPushCreate = ( - username: string, - version: string, - data: PushProcessorReq, - params: RequestParams = {}, - ) => + vProcessorPushCreate = (username: string, version: string, data: PushProcessorReq, params: RequestParams = {}) => this.request<ProcessorVersionPrincipalResp, any>({ path: `/api/v${version}/Processor/push/${username}`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -860,10 +808,10 @@ export class Api< ) => this.request<TemplatePrincipalResp[], any>({ path: `/api/v${version}/Template`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -874,17 +822,12 @@ export class Api< * @request GET:/api/v{version}/Template/id/{userId}/{templateId} * @secure */ - vTemplateIdDetail = ( - userId: string, - templateId: string, - version: string, - params: RequestParams = {}, - ) => + vTemplateIdDetail = (userId: string, templateId: string, version: string, params: RequestParams = {}) => this.request<TemplateResp, any>({ path: `/api/v${version}/Template/id/${userId}/${templateId}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -904,11 +847,11 @@ export class Api< ) => this.request<TemplatePrincipalResp, any>({ path: `/api/v${version}/Template/id/${userId}/${templateId}`, - method: "PUT", + method: 'PUT', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -919,17 +862,12 @@ export class Api< * @request DELETE:/api/v{version}/Template/id/{userId}/{templateId} * @secure */ - vTemplateIdDelete = ( - userId: string, - templateId: string, - version: string, - params: RequestParams = {}, - ) => + vTemplateIdDelete = (userId: string, templateId: string, version: string, params: RequestParams = {}) => this.request<Unit, any>({ path: `/api/v${version}/Template/id/${userId}/${templateId}`, - method: "DELETE", + method: 'DELETE', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -940,17 +878,12 @@ export class Api< * @request GET:/api/v{version}/Template/slug/{username}/{name} * @secure */ - vTemplateSlugDetail = ( - username: string, - name: string, - version: string, - params: RequestParams = {}, - ) => + vTemplateSlugDetail = (username: string, name: string, version: string, params: RequestParams = {}) => this.request<TemplateResp, any>({ path: `/api/v${version}/Template/slug/${username}/${name}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -961,19 +894,14 @@ export class Api< * @request POST:/api/v{version}/Template/id/{userId} * @secure */ - vTemplateIdCreate = ( - userId: string, - version: string, - data: CreateTemplateReq, - params: RequestParams = {}, - ) => + vTemplateIdCreate = (userId: string, version: string, data: CreateTemplateReq, params: RequestParams = {}) => this.request<TemplatePrincipalResp, any>({ path: `/api/v${version}/Template/id/${userId}`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -994,9 +922,9 @@ export class Api< ) => this.request<Unit, any>({ path: `/api/v${version}/Template/slug/${username}/${templateName}/like/${likerId}/${like}`, - method: "POST", + method: 'POST', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1022,10 +950,10 @@ export class Api< ) => this.request<TemplateVersionPrincipalResp[], any>({ path: `/api/v${version}/Template/slug/${username}/${templateName}/versions`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1045,11 +973,11 @@ export class Api< ) => this.request<TemplateVersionPrincipalResp, any>({ path: `/api/v${version}/Template/slug/${username}/${templateName}/versions`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -1075,10 +1003,10 @@ export class Api< ) => this.request<TemplateVersionPrincipalResp[], any>({ path: `/api/v${version}/Template/id/${userId}/${templateId}/versions`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1098,11 +1026,11 @@ export class Api< ) => this.request<TemplateVersionPrincipalResp, any>({ path: `/api/v${version}/Template/id/${userId}/${templateId}/versions`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -1127,10 +1055,10 @@ export class Api< ) => this.request<TemplateVersionResp, any>({ path: `/api/v${version}/Template/slug/${username}/${templateName}/versions/${ver}`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1152,10 +1080,10 @@ export class Api< ) => this.request<TemplateVersionResp, any>({ path: `/api/v${version}/Template/slug/${username}/${templateName}/versions/latest`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1177,9 +1105,9 @@ export class Api< ) => this.request<TemplateVersionResp, any>({ path: `/api/v${version}/Template/id/${userId}/${templateId}/versions/${ver}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1200,11 +1128,11 @@ export class Api< ) => this.request<TemplateVersionPrincipalResp, any>({ path: `/api/v${version}/Template/id/${userId}/${templateId}/versions/${ver}`, - method: "PUT", + method: 'PUT', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -1215,19 +1143,14 @@ export class Api< * @request POST:/api/v{version}/Template/push/{username} * @secure */ - vTemplatePushCreate = ( - username: string, - version: string, - data: PushTemplateReq, - params: RequestParams = {}, - ) => + vTemplatePushCreate = (username: string, version: string, data: PushTemplateReq, params: RequestParams = {}) => this.request<TemplateVersionPrincipalResp, any>({ path: `/api/v${version}/Template/push/${username}`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -1252,10 +1175,10 @@ export class Api< ) => this.request<UserPrincipalResp[], any>({ path: `/api/v${version}/User`, - method: "GET", + method: 'GET', query: query, secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1266,18 +1189,14 @@ export class Api< * @request POST:/api/v{version}/User * @secure */ - vUserCreate = ( - version: string, - data: CreateUserReq, - params: RequestParams = {}, - ) => + vUserCreate = (version: string, data: CreateUserReq, params: RequestParams = {}) => this.request<UserPrincipalResp, any>({ path: `/api/v${version}/User`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -1291,9 +1210,9 @@ export class Api< vUserMeDetail = (version: string, params: RequestParams = {}) => this.request<string, any>({ path: `/api/v${version}/User/Me`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1309,9 +1228,9 @@ export class Api< vUserDetail2 = (id: string, version: string, params: RequestParams = {}) => this.request<UserResp, any>({ path: `/api/v${version}/User/${id}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1322,19 +1241,14 @@ export class Api< * @request PUT:/api/v{version}/User/{id} * @secure */ - vUserUpdate = ( - id: string, - version: string, - data: UpdateUserReq, - params: RequestParams = {}, - ) => + vUserUpdate = (id: string, version: string, data: UpdateUserReq, params: RequestParams = {}) => this.request<UserPrincipalResp, any>({ path: `/api/v${version}/User/${id}`, - method: "PUT", + method: 'PUT', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -1348,7 +1262,7 @@ export class Api< vUserDelete = (id: string, version: string, params: RequestParams = {}) => this.request<void, any>({ path: `/api/v${version}/User/${id}`, - method: "DELETE", + method: 'DELETE', secure: true, ...params, }); @@ -1360,16 +1274,12 @@ export class Api< * @request GET:/api/v{version}/User/username/{username} * @secure */ - vUserUsernameDetail = ( - username: string, - version: string, - params: RequestParams = {}, - ) => + vUserUsernameDetail = (username: string, version: string, params: RequestParams = {}) => this.request<UserResp, any>({ path: `/api/v${version}/User/username/${username}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1380,16 +1290,12 @@ export class Api< * @request GET:/api/v{version}/User/exist/{username} * @secure */ - vUserExistDetail = ( - username: string, - version: string, - params: RequestParams = {}, - ) => + vUserExistDetail = (username: string, version: string, params: RequestParams = {}) => this.request<UserExistResp, any>({ path: `/api/v${version}/User/exist/${username}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1400,16 +1306,12 @@ export class Api< * @request GET:/api/v{version}/User/{userId}/tokens * @secure */ - vUserTokensDetail = ( - userId: string, - version: string, - params: RequestParams = {}, - ) => + vUserTokensDetail = (userId: string, version: string, params: RequestParams = {}) => this.request<TokenPrincipalResp[], any>({ path: `/api/v${version}/User/${userId}/tokens`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1420,19 +1322,14 @@ export class Api< * @request POST:/api/v{version}/User/{userId}/tokens * @secure */ - vUserTokensCreate = ( - userId: string, - version: string, - data: CreateTokenReq, - params: RequestParams = {}, - ) => + vUserTokensCreate = (userId: string, version: string, data: CreateTokenReq, params: RequestParams = {}) => this.request<TokenOTPrincipalResp, any>({ path: `/api/v${version}/User/${userId}/tokens`, - method: "POST", + method: 'POST', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -1452,11 +1349,11 @@ export class Api< ) => this.request<TokenPrincipalResp, any>({ path: `/api/v${version}/User/${userId}/tokens/${tokenId}`, - method: "PUT", + method: 'PUT', body: data, secure: true, type: ContentType.Json, - format: "json", + format: 'json', ...params, }); /** @@ -1467,15 +1364,10 @@ export class Api< * @request DELETE:/api/v{version}/User/{userId}/tokens/{tokenId} * @secure */ - vUserTokensDelete = ( - userId: string, - tokenId: string, - version: string, - params: RequestParams = {}, - ) => + vUserTokensDelete = (userId: string, tokenId: string, version: string, params: RequestParams = {}) => this.request<void, any>({ path: `/api/v${version}/User/${userId}/tokens/${tokenId}`, - method: "DELETE", + method: 'DELETE', secure: true, ...params, }); @@ -1487,15 +1379,10 @@ export class Api< * @request POST:/api/v{version}/User/{userId}/tokens/{tokenId}/revoke * @secure */ - vUserTokensRevokeCreate = ( - userId: string, - tokenId: string, - version: string, - params: RequestParams = {}, - ) => + vUserTokensRevokeCreate = (userId: string, tokenId: string, version: string, params: RequestParams = {}) => this.request<void, any>({ path: `/api/v${version}/User/${userId}/tokens/${tokenId}/revoke`, - method: "POST", + method: 'POST', secure: true, ...params, }); @@ -1510,9 +1397,9 @@ export class Api< vErrorInfoDetail = (version: string, params: RequestParams = {}) => this.request<string[], any>({ path: `/api/v${version}/error-info`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); /** @@ -1525,16 +1412,12 @@ export class Api< * @duplicate * @secure */ - vErrorInfoDetail2 = ( - id: string, - version: string, - params: RequestParams = {}, - ) => + vErrorInfoDetail2 = (id: string, version: string, params: RequestParams = {}) => this.request<ErrorInfo, any>({ path: `/api/v${version}/error-info/${id}`, - method: "GET", + method: 'GET', secure: true, - format: "json", + format: 'json', ...params, }); } diff --git a/src/lib/api/core/http-client.ts b/src/lib/api/core/http-client.ts index 8818b65..04d988a 100644 --- a/src/lib/api/core/http-client.ts +++ b/src/lib/api/core/http-client.ts @@ -10,9 +10,9 @@ */ export type QueryParamsType = Record<string | number, any>; -export type ResponseFormat = keyof Omit<Body, "body" | "bodyUsed">; +export type ResponseFormat = keyof Omit<Body, 'body' | 'bodyUsed'>; -export interface FullRequestParams extends Omit<RequestInit, "body"> { +export interface FullRequestParams extends Omit<RequestInit, 'body'> { /** set parameter to `true` for call `securityWorker` for this request */ secure?: boolean; /** request path */ @@ -31,22 +31,16 @@ export interface FullRequestParams extends Omit<RequestInit, "body"> { cancelToken?: CancelToken; } -export type RequestParams = Omit< - FullRequestParams, - "body" | "method" | "query" | "path" ->; +export type RequestParams = Omit<FullRequestParams, 'body' | 'method' | 'query' | 'path'>; export interface ApiConfig<SecurityDataType = unknown> { baseUrl?: string; - baseApiParams?: Omit<RequestParams, "baseUrl" | "cancelToken" | "signal">; - securityWorker?: ( - securityData: SecurityDataType | null, - ) => Promise<RequestParams | void> | RequestParams | void; + baseApiParams?: Omit<RequestParams, 'baseUrl' | 'cancelToken' | 'signal'>; + securityWorker?: (securityData: SecurityDataType | null) => Promise<RequestParams | void> | RequestParams | void; customFetch?: typeof fetch; } -export interface HttpResponse<D extends unknown, E extends unknown = unknown> - extends Response { +export interface HttpResponse<D extends unknown, E extends unknown = unknown> extends Response { data: D; error: E; } @@ -54,19 +48,18 @@ export interface HttpResponse<D extends unknown, E extends unknown = unknown> type CancelToken = Symbol | string | number; export enum ContentType { - Json = "application/json", - FormData = "multipart/form-data", - UrlEncoded = "application/x-www-form-urlencoded", - Text = "text/plain", + Json = 'application/json', + FormData = 'multipart/form-data', + UrlEncoded = 'application/x-www-form-urlencoded', + Text = 'text/plain', } export class HttpClient<SecurityDataType = unknown> { - public baseUrl: string = ""; + public baseUrl: string = ''; private securityData: SecurityDataType | null = null; - private securityWorker?: ApiConfig<SecurityDataType>["securityWorker"]; + private securityWorker?: ApiConfig<SecurityDataType>['securityWorker']; private abortControllers = new Map<CancelToken, AbortController>(); - private customFetch = (...fetchParams: Parameters<typeof fetch>) => - fetch(...fetchParams); + private customFetch = (...fetchParams: Parameters<typeof fetch>) => fetch(...fetchParams); private baseApiParams: RequestParams = {}; @@ -80,9 +73,7 @@ export class HttpClient<SecurityDataType = unknown> { protected encodeQueryParam(key: string, value: any) { const encodedKey = encodeURIComponent(key); - return `${encodedKey}=${encodeURIComponent( - typeof value === "number" ? value : `${value}`, - )}`; + return `${encodedKey}=${encodeURIComponent(typeof value === 'number' ? value : `${value}`)}`; } protected addQueryParam(query: QueryParamsType, key: string) { @@ -91,37 +82,26 @@ export class HttpClient<SecurityDataType = unknown> { protected addArrayQueryParam(query: QueryParamsType, key: string) { const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + return value.map((v: any) => this.encodeQueryParam(key, v)).join('&'); } protected toQueryString(rawQuery?: QueryParamsType): string { const query = rawQuery || {}; - const keys = Object.keys(query).filter( - (key) => "undefined" !== typeof query[key], - ); + const keys = Object.keys(query).filter(key => 'undefined' !== typeof query[key]); return keys - .map((key) => - Array.isArray(query[key]) - ? this.addArrayQueryParam(query, key) - : this.addQueryParam(query, key), - ) - .join("&"); + .map(key => (Array.isArray(query[key]) ? this.addArrayQueryParam(query, key) : this.addQueryParam(query, key))) + .join('&'); } protected addQueryParams(rawQuery?: QueryParamsType): string { const queryString = this.toQueryString(rawQuery); - return queryString ? `?${queryString}` : ""; + return queryString ? `?${queryString}` : ''; } private contentFormatters: Record<ContentType, (input: any) => any> = { [ContentType.Json]: (input: any) => - input !== null && (typeof input === "object" || typeof input === "string") - ? JSON.stringify(input) - : input, - [ContentType.Text]: (input: any) => - input !== null && typeof input !== "string" - ? JSON.stringify(input) - : input, + input !== null && (typeof input === 'object' || typeof input === 'string') ? JSON.stringify(input) : input, + [ContentType.Text]: (input: any) => (input !== null && typeof input !== 'string' ? JSON.stringify(input) : input), [ContentType.FormData]: (input: any) => Object.keys(input || {}).reduce((formData, key) => { const property = input[key]; @@ -129,7 +109,7 @@ export class HttpClient<SecurityDataType = unknown> { key, property instanceof Blob ? property - : typeof property === "object" && property !== null + : typeof property === 'object' && property !== null ? JSON.stringify(property) : `${property}`, ); @@ -138,10 +118,7 @@ export class HttpClient<SecurityDataType = unknown> { [ContentType.UrlEncoded]: (input: any) => this.toQueryString(input), }; - protected mergeRequestParams( - params1: RequestParams, - params2?: RequestParams, - ): RequestParams { + protected mergeRequestParams(params1: RequestParams, params2?: RequestParams): RequestParams { return { ...this.baseApiParams, ...params1, @@ -154,9 +131,7 @@ export class HttpClient<SecurityDataType = unknown> { }; } - protected createAbortSignal = ( - cancelToken: CancelToken, - ): AbortSignal | undefined => { + protected createAbortSignal = (cancelToken: CancelToken): AbortSignal | undefined => { if (this.abortControllers.has(cancelToken)) { const abortController = this.abortControllers.get(cancelToken); if (abortController) { @@ -191,7 +166,7 @@ export class HttpClient<SecurityDataType = unknown> { ...params }: FullRequestParams): Promise<HttpResponse<T, E>> => { const secureParams = - ((typeof secure === "boolean" ? secure : this.baseApiParams.secure) && + ((typeof secure === 'boolean' ? secure : this.baseApiParams.secure) && this.securityWorker && (await this.securityWorker(this.securityData))) || {}; @@ -200,28 +175,15 @@ export class HttpClient<SecurityDataType = unknown> { const payloadFormatter = this.contentFormatters[type || ContentType.Json]; const responseFormat = format || requestParams.format; - return this.customFetch( - `${baseUrl || this.baseUrl || ""}${path}${ - queryString ? `?${queryString}` : "" - }`, - { - ...requestParams, - headers: { - ...(requestParams.headers || {}), - ...(type && type !== ContentType.FormData - ? { "Content-Type": type } - : {}), - }, - signal: - (cancelToken - ? this.createAbortSignal(cancelToken) - : requestParams.signal) || null, - body: - typeof body === "undefined" || body === null - ? null - : payloadFormatter(body), + return this.customFetch(`${baseUrl || this.baseUrl || ''}${path}${queryString ? `?${queryString}` : ''}`, { + ...requestParams, + headers: { + ...(requestParams.headers || {}), + ...(type && type !== ContentType.FormData ? { 'Content-Type': type } : {}), }, - ).then(async (response) => { + signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null, + body: typeof body === 'undefined' || body === null ? null : payloadFormatter(body), + }).then(async response => { const r = response as HttpResponse<T, E>; r.data = null as unknown as T; r.error = null as unknown as E; @@ -229,7 +191,7 @@ export class HttpClient<SecurityDataType = unknown> { const data = !responseFormat ? r : await response[responseFormat]() - .then((data) => { + .then(data => { if (r.ok) { r.data = data; } else { @@ -237,7 +199,7 @@ export class HttpClient<SecurityDataType = unknown> { } return r; }) - .catch((e) => { + .catch(e => { r.error = e; return r; }); diff --git a/src/lib/components/custom/account/account.svelte b/src/lib/components/custom/account/account.svelte index 4ef3830..32b66c2 100644 --- a/src/lib/components/custom/account/account.svelte +++ b/src/lib/components/custom/account/account.svelte @@ -4,6 +4,7 @@ import {page} from "$app/stores"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu"; import * as Avatar from "$lib/components/ui/avatar"; + import {LogInIcon} from "lucide-svelte"; </script> {#if $page.data.session} @@ -49,5 +50,9 @@ </DropdownMenu.Content> </DropdownMenu.Root> {:else} - <Button on:click={() => signIn('descope')}>Sign in</Button> + <Button class="hidden md:block" on:click={() => signIn('descope')}>Sign in</Button> + <button class="block md:hidden" on:click={() => signIn('descope')}> + <LogInIcon class="w-5 h-5 dark:text-white text-black"/> + </button> + {/if} diff --git a/src/lib/components/custom/account/index.ts b/src/lib/components/custom/account/index.ts index 28b275d..de65c0f 100644 --- a/src/lib/components/custom/account/index.ts +++ b/src/lib/components/custom/account/index.ts @@ -1 +1 @@ -export { default as Account } from "./account.svelte"; +export { default as Account } from './account.svelte'; diff --git a/src/lib/components/custom/main-nav/index.ts b/src/lib/components/custom/main-nav/index.ts index 33a594b..3a975bf 100644 --- a/src/lib/components/custom/main-nav/index.ts +++ b/src/lib/components/custom/main-nav/index.ts @@ -1 +1 @@ -export { default as MainNav } from "./nav.svelte"; +export { default as MainNav } from './nav.svelte'; diff --git a/src/lib/components/custom/main-nav/nav.svelte b/src/lib/components/custom/main-nav/nav.svelte index cf8112e..027945b 100644 --- a/src/lib/components/custom/main-nav/nav.svelte +++ b/src/lib/components/custom/main-nav/nav.svelte @@ -4,19 +4,17 @@ export {className as class}; </script> -<nav class={cn("flex items-center space-x-4 lg:space-x-6", className)}> - - +<nav class={cn("flex items-center space-x-2 md:space-x-4 lg:space-x-6", className)}> <a href="/registry" - class="text-sm font-medium text-muted-foreground transition-colors hover:text-primary" + class="text-xs md:text-sm font-medium text-muted-foreground transition-colors hover:text-primary" > Registry </a> <a href="https://docs.cyanprint.dev" - class="text-sm font-medium text-muted-foreground transition-colors hover:text-primary" + class="text-xs md:text-sm font-medium text-muted-foreground transition-colors hover:text-primary" > - Documentation + Docs </a> </nav> diff --git a/src/lib/components/ui/accordion/index.ts b/src/lib/components/ui/accordion/index.ts index aecd801..1c437a0 100644 --- a/src/lib/components/ui/accordion/index.ts +++ b/src/lib/components/ui/accordion/index.ts @@ -1,7 +1,7 @@ -import { Accordion as AccordionPrimitive } from "bits-ui"; -import Content from "./accordion-content.svelte"; -import Item from "./accordion-item.svelte"; -import Trigger from "./accordion-trigger.svelte"; +import { Accordion as AccordionPrimitive } from 'bits-ui'; +import Content from './accordion-content.svelte'; +import Item from './accordion-item.svelte'; +import Trigger from './accordion-trigger.svelte'; const Root = AccordionPrimitive.Root; export { diff --git a/src/lib/components/ui/alert-dialog/index.ts b/src/lib/components/ui/alert-dialog/index.ts index ca755e6..691ac92 100644 --- a/src/lib/components/ui/alert-dialog/index.ts +++ b/src/lib/components/ui/alert-dialog/index.ts @@ -1,17 +1,17 @@ -import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; +import { AlertDialog as AlertDialogPrimitive } from 'bits-ui'; const Root = AlertDialogPrimitive.Root; const Trigger = AlertDialogPrimitive.Trigger; -import Title from "./alert-dialog-title.svelte"; -import Action from "./alert-dialog-action.svelte"; -import Cancel from "./alert-dialog-cancel.svelte"; -import Portal from "./alert-dialog-portal.svelte"; -import Footer from "./alert-dialog-footer.svelte"; -import Header from "./alert-dialog-header.svelte"; -import Overlay from "./alert-dialog-overlay.svelte"; -import Content from "./alert-dialog-content.svelte"; -import Description from "./alert-dialog-description.svelte"; +import Title from './alert-dialog-title.svelte'; +import Action from './alert-dialog-action.svelte'; +import Cancel from './alert-dialog-cancel.svelte'; +import Portal from './alert-dialog-portal.svelte'; +import Footer from './alert-dialog-footer.svelte'; +import Header from './alert-dialog-header.svelte'; +import Overlay from './alert-dialog-overlay.svelte'; +import Content from './alert-dialog-content.svelte'; +import Description from './alert-dialog-description.svelte'; export { Root, diff --git a/src/lib/components/ui/avatar/index.ts b/src/lib/components/ui/avatar/index.ts index 71f5b20..591ea32 100644 --- a/src/lib/components/ui/avatar/index.ts +++ b/src/lib/components/ui/avatar/index.ts @@ -1,6 +1,6 @@ -import Root from "./avatar.svelte"; -import Image from "./avatar-image.svelte"; -import Fallback from "./avatar-fallback.svelte"; +import Root from './avatar.svelte'; +import Image from './avatar-image.svelte'; +import Fallback from './avatar-fallback.svelte'; export { Root, diff --git a/src/lib/components/ui/badge/index.ts b/src/lib/components/ui/badge/index.ts index f6d6c23..720a9b3 100644 --- a/src/lib/components/ui/badge/index.ts +++ b/src/lib/components/ui/badge/index.ts @@ -1,22 +1,19 @@ -import { tv, type VariantProps } from "tailwind-variants"; -export { default as Badge } from "./badge.svelte"; +import { tv, type VariantProps } from 'tailwind-variants'; +export { default as Badge } from './badge.svelte'; export const badgeVariants = tv({ - base: "inline-flex items-center border rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none select-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + base: 'inline-flex items-center border rounded-full px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none select-none focus:ring-2 focus:ring-ring focus:ring-offset-2', variants: { variant: { - default: - "bg-primary hover:bg-primary/80 border-transparent text-primary-foreground", - secondary: - "bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground", - destructive: - "bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground", - outline: "text-foreground", + default: 'bg-primary hover:bg-primary/80 border-transparent text-primary-foreground', + secondary: 'bg-secondary hover:bg-secondary/80 border-transparent text-secondary-foreground', + destructive: 'bg-destructive hover:bg-destructive/80 border-transparent text-destructive-foreground', + outline: 'text-foreground', }, }, defaultVariants: { - variant: "default", + variant: 'default', }, }); -export type Variant = VariantProps<typeof badgeVariants>["variant"]; +export type Variant = VariantProps<typeof badgeVariants>['variant']; diff --git a/src/lib/components/ui/button/index.ts b/src/lib/components/ui/button/index.ts index 5ab68c4..82a3929 100644 --- a/src/lib/components/ui/button/index.ts +++ b/src/lib/components/ui/button/index.ts @@ -1,35 +1,33 @@ -import Root from "./button.svelte"; -import { tv, type VariantProps } from "tailwind-variants"; -import type { Button as ButtonPrimitive } from "bits-ui"; +import Root from './button.svelte'; +import { tv, type VariantProps } from 'tailwind-variants'; +import type { Button as ButtonPrimitive } from 'bits-ui'; const buttonVariants = tv({ - base: "inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + base: 'inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', variants: { variant: { - default: "bg-primary text-primary-foreground hover:bg-primary/90", - destructive: - "bg-destructive text-destructive-foreground hover:bg-destructive/90", - outline: - "border border-input bg-background hover:bg-accent hover:text-accent-foreground", - secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: "hover:bg-accent hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", + default: 'bg-primary text-primary-foreground hover:bg-primary/90', + destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90', + outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground', + secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80', + ghost: 'hover:bg-accent hover:text-accent-foreground', + link: 'text-primary underline-offset-4 hover:underline', }, size: { - default: "h-10 px-4 py-2", - sm: "h-9 rounded-md px-3", - lg: "h-11 rounded-md px-8", - icon: "h-10 w-10", + default: 'h-10 px-4 py-2', + sm: 'h-9 rounded-md px-3', + lg: 'h-11 rounded-md px-8', + icon: 'h-10 w-10', }, }, defaultVariants: { - variant: "default", - size: "default", + variant: 'default', + size: 'default', }, }); -type Variant = VariantProps<typeof buttonVariants>["variant"]; -type Size = VariantProps<typeof buttonVariants>["size"]; +type Variant = VariantProps<typeof buttonVariants>['variant']; +type Size = VariantProps<typeof buttonVariants>['size']; type Props = ButtonPrimitive.Props & { variant?: Variant; diff --git a/src/lib/components/ui/card/index.ts b/src/lib/components/ui/card/index.ts index b7f88bb..1432839 100644 --- a/src/lib/components/ui/card/index.ts +++ b/src/lib/components/ui/card/index.ts @@ -1,9 +1,9 @@ -import Root from "./card.svelte"; -import Content from "./card-content.svelte"; -import Description from "./card-description.svelte"; -import Footer from "./card-footer.svelte"; -import Header from "./card-header.svelte"; -import Title from "./card-title.svelte"; +import Root from './card.svelte'; +import Content from './card-content.svelte'; +import Description from './card-description.svelte'; +import Footer from './card-footer.svelte'; +import Header from './card-header.svelte'; +import Title from './card-title.svelte'; export { Root, @@ -21,4 +21,4 @@ export { Title as CardTitle, }; -export type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6"; +export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; diff --git a/src/lib/components/ui/dialog/index.ts b/src/lib/components/ui/dialog/index.ts index e91d032..7a9f7c7 100644 --- a/src/lib/components/ui/dialog/index.ts +++ b/src/lib/components/ui/dialog/index.ts @@ -1,15 +1,15 @@ -import { Dialog as DialogPrimitive } from "bits-ui"; +import { Dialog as DialogPrimitive } from 'bits-ui'; const Root = DialogPrimitive.Root; const Trigger = DialogPrimitive.Trigger; -import Title from "./dialog-title.svelte"; -import Portal from "./dialog-portal.svelte"; -import Footer from "./dialog-footer.svelte"; -import Header from "./dialog-header.svelte"; -import Overlay from "./dialog-overlay.svelte"; -import Content from "./dialog-content.svelte"; -import Description from "./dialog-description.svelte"; +import Title from './dialog-title.svelte'; +import Portal from './dialog-portal.svelte'; +import Footer from './dialog-footer.svelte'; +import Header from './dialog-header.svelte'; +import Overlay from './dialog-overlay.svelte'; +import Content from './dialog-content.svelte'; +import Description from './dialog-description.svelte'; export { Root, diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts index fedb817..22001e4 100644 --- a/src/lib/components/ui/dropdown-menu/index.ts +++ b/src/lib/components/ui/dropdown-menu/index.ts @@ -1,14 +1,14 @@ -import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; -import Item from "./dropdown-menu-item.svelte"; -import Label from "./dropdown-menu-label.svelte"; -import Content from "./dropdown-menu-content.svelte"; -import Shortcut from "./dropdown-menu-shortcut.svelte"; -import RadioItem from "./dropdown-menu-radio-item.svelte"; -import Separator from "./dropdown-menu-separator.svelte"; -import RadioGroup from "./dropdown-menu-radio-group.svelte"; -import SubContent from "./dropdown-menu-sub-content.svelte"; -import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; -import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; +import Item from './dropdown-menu-item.svelte'; +import Label from './dropdown-menu-label.svelte'; +import Content from './dropdown-menu-content.svelte'; +import Shortcut from './dropdown-menu-shortcut.svelte'; +import RadioItem from './dropdown-menu-radio-item.svelte'; +import Separator from './dropdown-menu-separator.svelte'; +import RadioGroup from './dropdown-menu-radio-group.svelte'; +import SubContent from './dropdown-menu-sub-content.svelte'; +import SubTrigger from './dropdown-menu-sub-trigger.svelte'; +import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; const Sub = DropdownMenuPrimitive.Sub; const Root = DropdownMenuPrimitive.Root; diff --git a/src/lib/components/ui/input/index.ts b/src/lib/components/ui/input/index.ts index f42e750..72d9cde 100644 --- a/src/lib/components/ui/input/index.ts +++ b/src/lib/components/ui/input/index.ts @@ -1,4 +1,4 @@ -import Root from "./input.svelte"; +import Root from './input.svelte'; type FormInputEvent<T extends Event = Event> = T & { currentTarget: EventTarget & HTMLInputElement; diff --git a/src/lib/components/ui/label/index.ts b/src/lib/components/ui/label/index.ts index b0b23ce..36fb393 100644 --- a/src/lib/components/ui/label/index.ts +++ b/src/lib/components/ui/label/index.ts @@ -1,4 +1,4 @@ -import Root from "./label.svelte"; +import Root from './label.svelte'; export { Root, diff --git a/src/lib/components/ui/light-switch/index.ts b/src/lib/components/ui/light-switch/index.ts index d839f8c..beaca5a 100644 --- a/src/lib/components/ui/light-switch/index.ts +++ b/src/lib/components/ui/light-switch/index.ts @@ -1 +1 @@ -export { default as LightSwitch } from "./light-switch.svelte"; +export { default as LightSwitch } from './light-switch.svelte'; diff --git a/src/lib/components/ui/light-switch/light-switch.ts b/src/lib/components/ui/light-switch/light-switch.ts index d91fa2f..c71a330 100644 --- a/src/lib/components/ui/light-switch/light-switch.ts +++ b/src/lib/components/ui/light-switch/light-switch.ts @@ -2,30 +2,25 @@ // Lightswitch Service -import { get } from "svelte/store"; +import { get } from 'svelte/store'; // DO NOT replace this ⬇ import, it has to be imported directly -import { localStorageStore } from "./local-storage-store"; +import { localStorageStore } from './local-storage-store'; // Stores --- // TRUE: light, FALSE: dark /** Store: OS Preference Mode */ -export const modeOsPrefers = localStorageStore<boolean>("modeOsPrefers", false); +export const modeOsPrefers = localStorageStore<boolean>('modeOsPrefers', false); /** Store: User Preference Mode */ -export const modeUserPrefers = localStorageStore<boolean | undefined>( - "modeUserPrefers", - undefined, -); +export const modeUserPrefers = localStorageStore<boolean | undefined>('modeUserPrefers', undefined); /** Store: Current Mode State */ -export const modeCurrent = localStorageStore<boolean>("modeCurrent", false); +export const modeCurrent = localStorageStore<boolean>('modeCurrent', false); // Get --- /** Get the OS Preference for light/dark mode */ export function getModeOsPrefers(): boolean { - const prefersLightMode = window.matchMedia( - "(prefers-color-scheme: light)", - ).matches; + const prefersLightMode = window.matchMedia('(prefers-color-scheme: light)').matches; modeOsPrefers.set(prefersLightMode); return prefersLightMode; } @@ -54,9 +49,7 @@ export function setModeUserPrefers(value: boolean): void { export function setModeCurrent(value: boolean) { const elemHtmlClasses = document.documentElement.classList; const classDark = `dark`; - value === true - ? elemHtmlClasses.remove(classDark) - : elemHtmlClasses.add(classDark); + value === true ? elemHtmlClasses.remove(classDark) : elemHtmlClasses.add(classDark); modeCurrent.set(value); } @@ -68,22 +61,16 @@ export function setInitialClassState() { const htmlElClasses = htmlEl.classList; // Conditions - const condLocalStorageUserPrefs = - localStorage.getItem("modeUserPrefers") === "false"; - const condLocalStorageUserPrefsExists = !("modeUserPrefers" in localStorage); - const condMatchMedia = window.matchMedia( - "(prefers-color-scheme: dark)", - ).matches; + const condLocalStorageUserPrefs = localStorage.getItem('modeUserPrefers') === 'false'; + const condLocalStorageUserPrefsExists = !('modeUserPrefers' in localStorage); + const condMatchMedia = window.matchMedia('(prefers-color-scheme: dark)').matches; // Add/remove `.dark` class to HTML element - if ( - condLocalStorageUserPrefs || - (condLocalStorageUserPrefsExists && condMatchMedia) - ) { - htmlElClasses.add("dark"); - htmlEl.style.colorScheme = "dark"; + if (condLocalStorageUserPrefs || (condLocalStorageUserPrefsExists && condMatchMedia)) { + htmlElClasses.add('dark'); + htmlEl.style.colorScheme = 'dark'; } else { - htmlElClasses.remove("dark"); - htmlEl.style.colorScheme = "light"; + htmlElClasses.remove('dark'); + htmlEl.style.colorScheme = 'light'; } } @@ -91,7 +78,7 @@ export function setInitialClassState() { /** Automatically set the visible light/dark, updates on change. */ export function autoModeWatcher(): void { - const mql = window.matchMedia("(prefers-color-scheme: light)"); + const mql = window.matchMedia('(prefers-color-scheme: light)'); function setMode(value: boolean) { const htmlEl = document.documentElement; const htmlElClasses = htmlEl.classList; @@ -99,10 +86,10 @@ export function autoModeWatcher(): void { if (value === true) { htmlElClasses.remove(classDark); - htmlEl.style.colorScheme = "light"; + htmlEl.style.colorScheme = 'light'; } else { htmlElClasses.add(classDark); - htmlEl.style.colorScheme = "dark"; + htmlEl.style.colorScheme = 'dark'; } } setMode(mql.matches); diff --git a/src/lib/components/ui/light-switch/local-storage-store.ts b/src/lib/components/ui/light-switch/local-storage-store.ts index 740f0a9..35dddcc 100644 --- a/src/lib/components/ui/light-switch/local-storage-store.ts +++ b/src/lib/components/ui/light-switch/local-storage-store.ts @@ -1,9 +1,9 @@ // Source: https://github.com/joshnuss/svelte-local-storage-store // https://github.com/joshnuss/svelte-local-storage-store/blob/master/index.ts // Represents version v0.4.0 (2023-01-18) -import type { Writable } from "svelte/store"; -import { BROWSER } from "esm-env"; -import { get, writable as internal } from "svelte/store"; +import type { Writable } from 'svelte/store'; +import { BROWSER } from 'esm-env'; +import { get, writable as internal } from 'svelte/store'; declare type Updater<T> = (value: T) => T; declare type StoreDict<T> = { [key: string]: Writable<T> }; @@ -16,7 +16,7 @@ interface Serializer<T> { stringify(object: T): string; } -type StorageType = "local" | "session"; +type StorageType = 'local' | 'session'; interface Options<T> { serializer?: Serializer<T>; @@ -24,16 +24,12 @@ interface Options<T> { } function getStorage(type: StorageType) { - return type === "local" ? localStorage : sessionStorage; + return type === 'local' ? localStorage : sessionStorage; } -export function localStorageStore<T>( - key: string, - initialValue: T, - options?: Options<T>, -): Writable<T> { +export function localStorageStore<T>(key: string, initialValue: T, options?: Options<T>): Writable<T> { const serializer = options?.serializer ?? JSON; - const storageType = options?.storage ?? "local"; + const storageType = options?.storage ?? 'local'; function updateStorage(key: string, value: T) { if (!BROWSER) return; @@ -42,7 +38,7 @@ export function localStorageStore<T>( } if (!stores[key]) { - const store = internal(initialValue, (set) => { + const store = internal(initialValue, set => { const json = BROWSER ? getStorage(storageType).getItem(key) : null; if (json) { @@ -51,13 +47,12 @@ export function localStorageStore<T>( if (BROWSER) { const handleStorage = (event: StorageEvent) => { - if (event.key === key) - set(event.newValue ? serializer.parse(event.newValue) : null); + if (event.key === key) set(event.newValue ? serializer.parse(event.newValue) : null); }; - window.addEventListener("storage", handleStorage); + window.addEventListener('storage', handleStorage); - return () => window.removeEventListener("storage", handleStorage); + return () => window.removeEventListener('storage', handleStorage); } }); diff --git a/src/lib/components/ui/select/index.ts b/src/lib/components/ui/select/index.ts index a6a9b56..d27bc48 100644 --- a/src/lib/components/ui/select/index.ts +++ b/src/lib/components/ui/select/index.ts @@ -1,11 +1,11 @@ -import { Select as SelectPrimitive } from "bits-ui"; +import { Select as SelectPrimitive } from 'bits-ui'; -import Root from "./select.svelte"; -import Label from "./select-label.svelte"; -import Item from "./select-item.svelte"; -import Content from "./select-content.svelte"; -import Trigger from "./select-trigger.svelte"; -import Separator from "./select-separator.svelte"; +import Root from './select.svelte'; +import Label from './select-label.svelte'; +import Item from './select-item.svelte'; +import Content from './select-content.svelte'; +import Trigger from './select-trigger.svelte'; +import Separator from './select-separator.svelte'; const Group = SelectPrimitive.Group; const Input = SelectPrimitive.Input; diff --git a/src/lib/components/ui/table/index.ts b/src/lib/components/ui/table/index.ts index 3fe1e39..7e48545 100644 --- a/src/lib/components/ui/table/index.ts +++ b/src/lib/components/ui/table/index.ts @@ -1,11 +1,11 @@ -import Root from "./table.svelte"; -import Body from "./table-body.svelte"; -import Caption from "./table-caption.svelte"; -import Cell from "./table-cell.svelte"; -import Footer from "./table-footer.svelte"; -import Head from "./table-head.svelte"; -import Header from "./table-header.svelte"; -import Row from "./table-row.svelte"; +import Root from './table.svelte'; +import Body from './table-body.svelte'; +import Caption from './table-caption.svelte'; +import Cell from './table-cell.svelte'; +import Footer from './table-footer.svelte'; +import Head from './table-head.svelte'; +import Header from './table-header.svelte'; +import Row from './table-row.svelte'; export { Root, diff --git a/src/lib/components/ui/tabs/index.ts b/src/lib/components/ui/tabs/index.ts index 088decc..e57b2e2 100644 --- a/src/lib/components/ui/tabs/index.ts +++ b/src/lib/components/ui/tabs/index.ts @@ -1,7 +1,7 @@ -import { Tabs as TabsPrimitive } from "bits-ui"; -import Content from "./tabs-content.svelte"; -import List from "./tabs-list.svelte"; -import Trigger from "./tabs-trigger.svelte"; +import { Tabs as TabsPrimitive } from 'bits-ui'; +import Content from './tabs-content.svelte'; +import List from './tabs-list.svelte'; +import Trigger from './tabs-trigger.svelte'; const Root = TabsPrimitive.Root; diff --git a/src/lib/components/ui/tooltip/index.ts b/src/lib/components/ui/tooltip/index.ts index 21bee51..7e883a8 100644 --- a/src/lib/components/ui/tooltip/index.ts +++ b/src/lib/components/ui/tooltip/index.ts @@ -1,5 +1,5 @@ -import { Tooltip as TooltipPrimitive } from "bits-ui"; -import Content from "./tooltip-content.svelte"; +import { Tooltip as TooltipPrimitive } from 'bits-ui'; +import Content from './tooltip-content.svelte'; const Root = TooltipPrimitive.Root; const Trigger = TooltipPrimitive.Trigger; diff --git a/src/lib/core/error.ts b/src/lib/core/error.ts index 61663b7..76d7aa2 100644 --- a/src/lib/core/error.ts +++ b/src/lib/core/error.ts @@ -1,22 +1,16 @@ class UnwrapError extends Error { - type: - | "Expected Ok got Error" - | "Expected Err got Ok" - | "Expected Some got None"; - monadType: "result" | "option"; + type: 'Expected Ok got Error' | 'Expected Err got Ok' | 'Expected Some got None'; + monadType: 'result' | 'option'; constructor( message: string, - monadType: "result" | "option", - type: - | "Expected Ok got Error" - | "Expected Err got Ok" - | "Expected Some got None", + monadType: 'result' | 'option', + type: 'Expected Ok got Error' | 'Expected Err got Ok' | 'Expected Some got None', ) { super(message); this.type = type; this.monadType = monadType; - this.name = "UnwrapError"; + this.name = 'UnwrapError'; } } diff --git a/src/lib/core/option.ts b/src/lib/core/option.ts index eb1dcb0..def2346 100644 --- a/src/lib/core/option.ts +++ b/src/lib/core/option.ts @@ -1,6 +1,6 @@ -import type { Result } from "./result.js"; -import { KResult } from "./result.js"; -import { UnwrapError } from "./error.js"; +import type { Result } from './result.js'; +import { KResult } from './result.js'; +import { UnwrapError } from './error.js'; interface Match<T, U> { // Map the Some value to a standard type @@ -11,19 +11,11 @@ interface Match<T, U> { interface ResultMatch<T, U, E> { some: ((val: T) => Result<U, E>) | ((val: T) => Promise<Result<U, E>>); - none: - | (() => Result<U, E>) - | (() => Promise<Result<U, E>>) - | Result<U, E> - | Promise<Result<U, E>>; + none: (() => Result<U, E>) | (() => Promise<Result<U, E>>) | Result<U, E> | Promise<Result<U, E>>; } type OptionSome<T extends Option<unknown>[]> = { - [K in keyof T]: K extends number - ? T[K] extends Option<infer U> - ? U - : never - : never; + [K in keyof T]: K extends number ? (T[K] extends Option<infer U> ? U : never) : never; }; class Opt { @@ -49,18 +41,18 @@ class Opt { const closure = async (): Promise<Option<OptionSome<T>>> => { const some: OptionSome<T> = [] as OptionSome<T>; let none = 0; - const r = i.map(async (e) => { + const r = i.map(async e => { const isSome = await e.isSome(); if (isSome) { const ok = await e.unwrap(); - return ["some", ok]; + return ['some', ok]; } else { - return ["none", null]; + return ['none', null]; } }); const a = await Promise.all(r); for (const [t, v] of a) { - if (t === "some") { + if (t === 'some') { some.push(v); } else { none++; @@ -88,9 +80,9 @@ class Opt { const isSome = await r.isSome(); if (isSome) { const ok = await r.unwrap(); - return Promise.resolve(["some", ok]); + return Promise.resolve(['some', ok]); } - return Promise.resolve(["none", null]); + return Promise.resolve(['none', null]); })(), ); } @@ -145,9 +137,7 @@ interface Option<T> { * @param fn - mapper function that returns on Option. Can be async or sync. * @returns {Option<U>} Mapped Option */ - andThen<U>( - fn: ((v: T) => Option<U>) | ((v: T) => Promise<Option<U>>), - ): Option<U>; + andThen<U>(fn: ((v: T) => Option<U>) | ((v: T) => Promise<Option<U>>)): Option<U>; // Removes the Option type and return the underlying value. // Throws an error if None was inside. @@ -214,15 +204,13 @@ interface Option<T> { native(): Promise<T | null>; } -type ISome<T> = ["some", T]; -type INone = ["none", null]; +type ISome<T> = ['some', T]; +type INone = ['none', null]; class KOption<T> implements Option<T> { value: Promise<ISome<T> | INone>; - constructor( - value: Promise<ISome<T>> | Promise<INone> | Promise<ISome<T> | INone>, - ) { + constructor(value: Promise<ISome<T>> | Promise<INone> | Promise<ISome<T> | INone>) { this.value = Promise.resolve(value); } @@ -231,22 +219,20 @@ class KOption<T> implements Option<T> { return v; } - andThen<U>( - fn: ((v: T) => Option<U>) | ((v: T) => Promise<Option<U>>), - ): Option<U> { + andThen<U>(fn: ((v: T) => Option<U>) | ((v: T) => Promise<Option<U>>)): Option<U> { return new KOption<U>( (async () => { const [type, value] = await this.value; - if (type === "none") { + if (type === 'none') { return [type, value] as INone; } else { const mapped = await fn(value); const isSome = await mapped.isSome(); if (isSome) { const v = await mapped.unwrap(); - return ["some", v] as ISome<U>; + return ['some', v] as ISome<U>; } else { - return ["none", null] as INone; + return ['none', null] as INone; } } })(), @@ -257,11 +243,11 @@ class KOption<T> implements Option<T> { return new KResult<O, T>( (async () => { const [t, v] = await this.value; - if (t === "none") { + if (t === 'none') { const s = await ok; - return ["ok", s]; + return ['ok', s]; } else { - return ["err", v]; + return ['err', v]; } })(), ); @@ -271,51 +257,49 @@ class KOption<T> implements Option<T> { return new KResult<T, E>( (async () => { const [t, v] = await this.value; - if (t === "none") { + if (t === 'none') { const s = await err; - return ["err", s]; + return ['err', s]; } else { - return ["ok", v]; + return ['ok', v]; } })(), ); } asResult<O, E>(fn: ResultMatch<T, O, E>): Result<O, E> { - return new KResult<number, E>(Promise.resolve(["ok", 0])).andThen( - async (): Promise<Result<O, E>> => { - const [t, v] = await this.value; - return await (async () => { - if (t === "none") { - if (typeof fn.none === "function") { - const f = fn.none; - return Promise.resolve(f()); - } else { - return Promise.resolve(fn.none); - } + return new KResult<number, E>(Promise.resolve(['ok', 0])).andThen(async (): Promise<Result<O, E>> => { + const [t, v] = await this.value; + return await (async () => { + if (t === 'none') { + if (typeof fn.none === 'function') { + const f = fn.none; + return Promise.resolve(f()); } else { - return fn.some(v); + return Promise.resolve(fn.none); } - })(); - }, - ); + } else { + return fn.some(v); + } + })(); + }); } async isNone(): Promise<boolean> { const [t] = await this.value; - return t === "none"; + return t === 'none'; } async isSome(): Promise<boolean> { const [t] = await this.value; - return t === "some"; + return t === 'some'; } map<U>(fn: ((val: T) => U) | ((val: T) => Promise<U>)): Option<U> { return new KOption<U>( (async () => { const [t, v] = await this.value; - if (t === "none") { + if (t === 'none') { return [t, v]; } else { const fv = await fn(v); @@ -327,10 +311,10 @@ class KOption<T> implements Option<T> { async match<U>(fn: Match<T, U>): Promise<U> { const [t, v] = await this.value; - if (t === "some") { + if (t === 'some') { return Promise.resolve(fn.some(v)); } else { - if (typeof fn.none === "function") { + if (typeof fn.none === 'function') { const f = fn.none as (() => U) | (() => Promise<U>); return Promise.resolve(f()); } else { @@ -343,7 +327,7 @@ class KOption<T> implements Option<T> { return new KOption( (async () => { const [t, v] = await this.value; - if (t === "none") { + if (t === 'none') { return [t, v]; } else { await sideEffect(v); @@ -355,25 +339,19 @@ class KOption<T> implements Option<T> { async unwrap(): Promise<T> { const [t, v] = await this.value; - if (t === "some") { + if (t === 'some') { return v; } else { - throw new UnwrapError( - "Failed to unwrap", - "option", - "Expected Some got None", - ); + throw new UnwrapError('Failed to unwrap', 'option', 'Expected Some got None'); } } - async unwrapOr( - def: Promise<T> | (() => T) | (() => Promise<T>) | T, - ): Promise<T> { + async unwrapOr(def: Promise<T> | (() => T) | (() => Promise<T>) | T): Promise<T> { const [t, v] = await this.value; - if (t === "some") { + if (t === 'some') { return v; } else { - if (typeof def === "function") { + if (typeof def === 'function') { const f = def as (() => T) | (() => Promise<T>); return Promise.resolve(f()); } else { @@ -384,11 +362,11 @@ class KOption<T> implements Option<T> { } function Some<T>(v: T): Option<T> { - return new KOption(Promise.resolve(["some", v])); + return new KOption(Promise.resolve(['some', v])); } function None<T>(): Option<T> { - return new KOption<T>(Promise.resolve(["none", null])); + return new KOption<T>(Promise.resolve(['none', null])); } export { KOption, Some, None, Opt }; diff --git a/src/lib/core/result.ts b/src/lib/core/result.ts index 73b586d..8566968 100644 --- a/src/lib/core/result.ts +++ b/src/lib/core/result.ts @@ -1,6 +1,6 @@ -import { UnwrapError } from "./error"; -import type { INone, ISome, Option } from "./option"; -import { KOption } from "./option"; +import { UnwrapError } from './error'; +import type { INone, ISome, Option } from './option'; +import { KOption } from './option'; // Creates a new instance of `Result` as the `err` variant. /** @@ -12,7 +12,7 @@ function Err<T, X>(error: X | Promise<X>): Result<T, X> { return new KResult<T, X>( (async () => { const err = await error; - return ["err", err]; + return ['err', err]; })(), ); } @@ -27,7 +27,7 @@ function Ok<T, X = never>(val: T | Promise<T>): Result<T, X> { return new KResult<T, X>( (async () => { const v = await val; - return ["ok", v]; + return ['ok', v]; })(), ); } @@ -37,18 +37,10 @@ interface Match<T, E, U> { err: ((val: E) => Promise<U>) | ((val: E) => U); } -type ResultErr<T extends Result<unknown, unknown>[]> = T extends Array< - Result<unknown, infer E> -> - ? E[] - : never; +type ResultErr<T extends Result<unknown, unknown>[]> = T extends Array<Result<unknown, infer E>> ? E[] : never; type ResultOk<T extends Result<unknown, unknown>[]> = { - [K in keyof T]: K extends number - ? T[K] extends Result<infer U, unknown> - ? U - : never - : never; + [K in keyof T]: K extends number ? (T[K] extends Result<infer U, unknown> ? U : never) : never; }; class Res { @@ -58,10 +50,8 @@ class Res { * @param a - serialized format of the result * @return {Result<T,E>} - new instance of `Result` by deserializing the serial format */ - static fromSerial<T, E>( - a: (["ok", T] | ["err", E]) | Promise<["ok", T] | ["err", E]>, - ): Result<T, E> { - const p = Promise.resolve(a) satisfies Promise<["ok", T] | ["err", E]>; + static fromSerial<T, E>(a: (['ok', T] | ['err', E]) | Promise<['ok', T] | ['err', E]>): Result<T, E> { + const p = Promise.resolve(a) satisfies Promise<['ok', T] | ['err', E]>; return new KResult<T, E>(p); } @@ -78,10 +68,10 @@ class Res { const isOk = await r.isOk(); if (isOk) { const ok = await r.unwrap(); - return Promise.resolve(["ok", ok]); + return Promise.resolve(['ok', ok]); } else { const err = await r.unwrapErr(); - return Promise.resolve(["err", err]); + return Promise.resolve(['err', err]); } })(), ); @@ -102,25 +92,23 @@ class Res { * @template * @param i - list of results */ - static all<T extends Result<unknown, unknown>[]>( - ...i: [...T] - ): Result<ResultOk<T>, ResultErr<T>> { + static all<T extends Result<unknown, unknown>[]>(...i: [...T]): Result<ResultOk<T>, ResultErr<T>> { const closure = async (): Promise<Result<ResultOk<T>, ResultErr<T>>> => { const ok: ResultOk<T> = [] as unknown as ResultOk<T>; const err: ResultErr<T> = [] as unknown as ResultErr<T>; - const r = i.map(async (e) => { + const r = i.map(async e => { const isOk = await e.isOk(); if (isOk) { const okR = await e.unwrap(); - return ["ok", okR] as ["ok", ResultOk<T>[number]]; + return ['ok', okR] as ['ok', ResultOk<T>[number]]; } else { const errR = await e.unwrapErr(); - return ["err", errR] as ["err", ResultErr<T>[number]]; + return ['err', errR] as ['err', ResultErr<T>[number]]; } }); const a = await Promise.all(r); for (const [t, v] of a) { - if (t === "ok") { + if (t === 'ok') { ok.push(v); } else { err.push(v); @@ -162,9 +150,7 @@ interface Result<T, E> { * @param i - default value to be returned if the variant of the Result is "err". It can be the default value, promised value, or function that returns the default value or async function that returns the default value * @returns {Promise<T>} - promise of the unwrapped value */ - unwrapOr( - i: T | Promise<T> | ((err: E) => Promise<T>) | ((err: E) => T), - ): Promise<T>; + unwrapOr(i: T | Promise<T> | ((err: E) => Promise<T>) | ((err: E) => T)): Promise<T>; // returns a Promise of the error value of the Result if its variant is "err". If its variant is "ok", it throws an error /** @@ -202,7 +188,7 @@ interface Result<T, E> { * @template T, E * @returns {Promise<Promise<['err', E] | ['ok', T]>>} - promise of the native serializable format of the result type */ - serial(): Promise<["err", E] | ["ok", T]>; + serial(): Promise<['err', E] | ['ok', T]>; // method that takes in a function fn with ok and err cases. It applies the corresponding case based on the variant of the Result and returns the result of that case as a Promise. /** @@ -220,9 +206,7 @@ interface Result<T, E> { * @param fn - function that maps the ok value of the Result to a new Result. fn can be async. * @returns {Result<U,E>} - new Result that was mapped from the original Result */ - andThen<U>( - fn: ((val: T) => Result<U, E>) | ((val: T) => Promise<Result<U, E>>), - ): Result<U, E>; + andThen<U>(fn: ((val: T) => Result<U, E>) | ((val: T) => Promise<Result<U, E>>)): Result<U, E>; // Runs the function passed in but does not capture the return value. // Accepts both sync and async functions. @@ -264,36 +248,26 @@ interface Result<T, E> { } class KResult<T, X> implements Result<T, X> { - value: - | Promise<["ok", T]> - | Promise<["err", X]> - | Promise<["err", X] | ["ok", T]>; - - constructor( - value: - | Promise<["ok", T]> - | Promise<["err", X]> - | Promise<["err", X] | ["ok", T]>, - ) { + value: Promise<['ok', T]> | Promise<['err', X]> | Promise<['err', X] | ['ok', T]>; + + constructor(value: Promise<['ok', T]> | Promise<['err', X]> | Promise<['err', X] | ['ok', T]>) { this.value = value; } - andThen<U>( - fn: ((val: T) => Result<U, X>) | ((val: T) => Promise<Result<U, X>>), - ): Result<U, X> { + andThen<U>(fn: ((val: T) => Result<U, X>) | ((val: T) => Promise<Result<U, X>>)): Result<U, X> { const wrapped = async () => { const [type, val] = await this.value; - if (type === "err") { - return [type, val] as ["err", X]; + if (type === 'err') { + return [type, val] as ['err', X]; } else { const mapped = await fn(val); const mType = await mapped.isOk(); if (mType) { const okVal = await Promise.resolve(mapped.unwrap()); - return ["ok", okVal] as ["ok", U]; + return ['ok', okVal] as ['ok', U]; } else { const errVal = await Promise.resolve(mapped.unwrapErr()); - return ["err", errVal] as ["err", X]; + return ['err', errVal] as ['err', X]; } } }; @@ -302,43 +276,39 @@ class KResult<T, X> implements Result<T, X> { async isOk(): Promise<boolean> { const [type] = await this.value; - return type === "ok"; + return type === 'ok'; } async isErr(): Promise<boolean> { const [type] = await this.value; - return type === "err"; + return type === 'err'; } async unwrap(): Promise<T> | never { const [type, val] = await this.value; - if (type === "ok") { + if (type === 'ok') { return val; } - throw new UnwrapError( - "Failed to unwrap", - "result", - "Expected Ok got Error", - ); + throw new UnwrapError('Failed to unwrap', 'result', 'Expected Ok got Error'); } async unwrapErr(): Promise<X> | never { const [type, val] = await this.value; - if (type === "err") { + if (type === 'err') { return val; } - throw new UnwrapError("Failed to unwrap", "result", "Expected Err got Ok"); + throw new UnwrapError('Failed to unwrap', 'result', 'Expected Err got Ok'); } map<Y>(mapper: ((a: T) => Promise<Y>) | ((a: T) => Y)): Result<Y, X> { return new KResult<Y, X>( (async () => { const [type, val] = await this.value; - if (type === "ok") { + if (type === 'ok') { const mapped: Y = await mapper(val); - return ["ok", mapped] as ["ok", Y]; + return ['ok', mapped] as ['ok', Y]; } else { - return ["err", val] as ["err", X]; + return ['err', val] as ['err', X]; } })(), ); @@ -348,11 +318,11 @@ class KResult<T, X> implements Result<T, X> { return new KResult<T, Y>( (async () => { const [type, val] = await this.value; - if (type === "err") { + if (type === 'err') { const err = await mapper(val); - return ["err", err] as ["err", Y]; + return ['err', err] as ['err', Y]; } else { - return [type, val] as ["ok", T]; + return [type, val] as ['ok', T]; } })(), ); @@ -365,21 +335,19 @@ class KResult<T, X> implements Result<T, X> { async match<U>(fn: Match<T, X, U>): Promise<U> { const [type, val] = await this.value; - if (type === "ok") { + if (type === 'ok') { return Promise.resolve(fn.ok(val)); } else { return Promise.resolve(fn.err(val)); } } - async unwrapOr( - i: Promise<T> | ((err: X) => Promise<T>) | ((err: X) => T) | T, - ): Promise<T> { + async unwrapOr(i: Promise<T> | ((err: X) => Promise<T>) | ((err: X) => T) | T): Promise<T> { const [type, val] = await this.value; - if (type === "ok") { + if (type === 'ok') { return val; } else { - if (typeof i === "function") { + if (typeof i === 'function') { const f = i as ((err: X) => Promise<T>) | ((err: X) => T); return f(val); } else { @@ -391,10 +359,10 @@ class KResult<T, X> implements Result<T, X> { err(): Option<X> { const closure = async (): Promise<ISome<X> | INone> => { const [t, v] = await this.value; - if (t === "err") { - return ["some", v] as ["some", X]; + if (t === 'err') { + return ['some', v] as ['some', X]; } else { - return ["none", null] as ["none", null]; + return ['none', null] as ['none', null]; } }; return new KOption<X>(closure()); @@ -412,22 +380,22 @@ class KResult<T, X> implements Result<T, X> { ): Result<T, Error> { const closure = async () => { const [t, v] = await this.value; - if (t === "err") { + if (t === 'err') { const err = await mapper(v); - return [t, err] as ["err", Error]; + return [t, err] as ['err', Error]; } else { try { await sideEffect(v); } catch (e) { if (e instanceof Error) { - return ["err", e] as ["err", Error]; - } else if (typeof e === "string") { - return ["err", new Error(e)] as ["err", Error]; + return ['err', e] as ['err', Error]; + } else if (typeof e === 'string') { + return ['err', new Error(e)] as ['err', Error]; } else { - return ["err", new Error(JSON.stringify(e))] as ["err", Error]; + return ['err', new Error(JSON.stringify(e))] as ['err', Error]; } } - return [t, v] as ["ok", T]; + return [t, v] as ['ok', T]; } }; return new KResult<T, Error>(closure()); @@ -436,10 +404,10 @@ class KResult<T, X> implements Result<T, X> { ok(): Option<T> { const closure = async (): Promise<ISome<T> | INone> => { const [t, v] = await this.value; - if (t === "ok") { - return ["some", v] as ["some", T]; + if (t === 'ok') { + return ['some', v] as ['some', T]; } else { - return ["none", null] as ["none", null]; + return ['none', null] as ['none', null]; } }; return new KOption<T>(closure()); @@ -449,7 +417,7 @@ class KResult<T, X> implements Result<T, X> { return new KResult<T, X>( (async () => { const [t, v] = await this.value; - if (t === "err") { + if (t === 'err') { return [t, v]; } else { await sideEffect(v); @@ -459,7 +427,7 @@ class KResult<T, X> implements Result<T, X> { ); } - async serial(): Promise<["err", X] | ["ok", T]> { + async serial(): Promise<['err', X] | ['ok', T]> { const r = await this.value; return r; } diff --git a/src/lib/design/animations.ts b/src/lib/design/animations.ts index aa819db..bfe3846 100644 --- a/src/lib/design/animations.ts +++ b/src/lib/design/animations.ts @@ -1,20 +1,20 @@ -import corgi from "./lottie/corgi.json"; -import cat from "./lottie/cat.json"; -import astronaut from "./lottie/astronaout.json"; -import dogNewsPaper from "./lottie/dogNewsPaper.json"; -import chemical from "./lottie/chemical.json"; -import coffee from "./lottie/coffee.json"; -import cow from "./lottie/cow.json"; -import dogSmell from "./lottie/dogSmell.json"; -import dogSwimming from "./lottie/dogSwimming.json"; -import emptybox from "./lottie/emptybox.json"; -import icecream from "./lottie/icecream.json"; -import laptop from "./lottie/laptop.json"; -import loading from "./lottie/loading.json"; -import lochness from "./lottie/lochness.json"; -import puzzle from "./lottie/puzzle.json"; -import tissue from "./lottie/tissue.json"; -import search from "./lottie/searching.json"; +import corgi from './lottie/corgi.json'; +import cat from './lottie/cat.json'; +import astronaut from './lottie/astronaout.json'; +import dogNewsPaper from './lottie/dogNewsPaper.json'; +import chemical from './lottie/chemical.json'; +import coffee from './lottie/coffee.json'; +import cow from './lottie/cow.json'; +import dogSmell from './lottie/dogSmell.json'; +import dogSwimming from './lottie/dogSwimming.json'; +import emptybox from './lottie/emptybox.json'; +import icecream from './lottie/icecream.json'; +import laptop from './lottie/laptop.json'; +import loading from './lottie/loading.json'; +import lochness from './lottie/lochness.json'; +import puzzle from './lottie/puzzle.json'; +import tissue from './lottie/tissue.json'; +import search from './lottie/searching.json'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const animations: Record<string, any> = { diff --git a/src/lib/design/index.ts b/src/lib/design/index.ts index 4ced1d3..c1373b6 100644 --- a/src/lib/design/index.ts +++ b/src/lib/design/index.ts @@ -1 +1 @@ -export { animations } from "./animations"; +export { animations } from './animations'; diff --git a/src/lib/design/lottie/loading.json b/src/lib/design/lottie/loading.json index fe61609..7ed0746 100644 --- a/src/lib/design/lottie/loading.json +++ b/src/lib/design/lottie/loading.json @@ -65,10 +65,7 @@ "ty": "fl", "c": { "a": 0, - "k": [ - 0.10196078431372549, 0.3411764705882353, 0.24705882352941178, - 1 - ], + "k": [0.10196078431372549, 0.3411764705882353, 0.24705882352941178, 1], "ix": 4 }, "o": { "a": 0, "k": 100, "ix": 5 }, @@ -177,9 +174,7 @@ "ty": "fl", "c": { "a": 0, - "k": [ - 0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1 - ], + "k": [0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1], "ix": 4 }, "o": { "a": 0, "k": 100, "ix": 5 }, @@ -288,9 +283,7 @@ "ty": "fl", "c": { "a": 0, - "k": [ - 0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1 - ], + "k": [0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1], "ix": 4 }, "o": { "a": 0, "k": 100, "ix": 5 }, @@ -420,10 +413,7 @@ "ty": "st", "c": { "a": 0, - "k": [ - 0.10196078431372549, 0.3411764705882353, 0.24705882352941178, - 1 - ], + "k": [0.10196078431372549, 0.3411764705882353, 0.24705882352941178, 1], "ix": 3 }, "o": { "a": 0, "k": 100, "ix": 4 }, @@ -582,10 +572,7 @@ "ty": "st", "c": { "a": 0, - "k": [ - 0.10196078431372549, 0.3411764705882353, 0.24705882352941178, - 1 - ], + "k": [0.10196078431372549, 0.3411764705882353, 0.24705882352941178, 1], "ix": 3 }, "o": { "a": 0, "k": 100, "ix": 4 }, @@ -715,10 +702,7 @@ "ty": "fl", "c": { "a": 0, - "k": [ - 0.10196078431372549, 0.3411764705882353, 0.24705882352941178, - 1 - ], + "k": [0.10196078431372549, 0.3411764705882353, 0.24705882352941178, 1], "ix": 4 }, "o": { "a": 0, "k": 100, "ix": 5 }, @@ -856,10 +840,7 @@ "ty": "fl", "c": { "a": 0, - "k": [ - 0.10196078431372549, 0.3411764705882353, 0.24705882352941178, - 1 - ], + "k": [0.10196078431372549, 0.3411764705882353, 0.24705882352941178, 1], "ix": 4 }, "o": { "a": 0, "k": 100, "ix": 5 }, @@ -1030,10 +1011,7 @@ "ty": "st", "c": { "a": 0, - "k": [ - 0.10196078431372549, 0.3411764705882353, 0.24705882352941178, - 1 - ], + "k": [0.10196078431372549, 0.3411764705882353, 0.24705882352941178, 1], "ix": 3 }, "o": { "a": 0, "k": 100, "ix": 4 }, @@ -1163,9 +1141,7 @@ "ty": "fl", "c": { "a": 0, - "k": [ - 0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1 - ], + "k": [0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1], "ix": 4 }, "o": { "a": 0, "k": 100, "ix": 5 }, @@ -1341,9 +1317,7 @@ "ty": "fl", "c": { "a": 0, - "k": [ - 0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1 - ], + "k": [0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1], "ix": 4 }, "o": { "a": 0, "k": 100, "ix": 5 }, @@ -1516,9 +1490,7 @@ "ty": "st", "c": { "a": 0, - "k": [ - 0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1 - ], + "k": [0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1], "ix": 3 }, "o": { "a": 0, "k": 100, "ix": 4 }, @@ -1669,9 +1641,7 @@ "ty": "st", "c": { "a": 0, - "k": [ - 0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1 - ], + "k": [0.9764705882352941, 0.7372549019607844, 0.3764705882352941, 1], "ix": 3 }, "o": { "a": 0, "k": 100, "ix": 4 }, diff --git a/src/lib/design/lottie/searching.json b/src/lib/design/lottie/searching.json index 745efb2..da28b29 100644 --- a/src/lib/design/lottie/searching.json +++ b/src/lib/design/lottie/searching.json @@ -893,10 +893,7 @@ "ty": "fl", "c": { "a": 0, - "k": [ - 0.27450980392156865, 0.34901960784313724, 0.6431372549019608, - 1 - ], + "k": [0.27450980392156865, 0.34901960784313724, 0.6431372549019608, 1], "ix": 4 }, "o": { "a": 0, "k": 100, "ix": 5 }, @@ -960,10 +957,7 @@ "ty": "st", "c": { "a": 0, - "k": [ - 0.27450980392156865, 0.34901960784313724, 0.6431372549019608, - 1 - ], + "k": [0.27450980392156865, 0.34901960784313724, 0.6431372549019608, 1], "ix": 3 }, "o": { "a": 0, "k": 100, "ix": 4 }, @@ -1012,10 +1006,7 @@ "ty": "st", "c": { "a": 0, - "k": [ - 0.27450980392156865, 0.34901960784313724, 0.6431372549019608, - 1 - ], + "k": [0.27450980392156865, 0.34901960784313724, 0.6431372549019608, 1], "ix": 3 }, "o": { "a": 0, "k": 100, "ix": 4 }, diff --git a/src/lib/utility.ts b/src/lib/utility.ts index e878d39..2a31286 100644 --- a/src/lib/utility.ts +++ b/src/lib/utility.ts @@ -1,47 +1,39 @@ -import { LocalStringError } from "../errors/v1/local_string_error"; -import { LocalExceptionError } from "../errors/v1/local_exception_error"; -import { LocalUnknownError } from "../errors/v1/local_unknown_error"; -import type { Problem } from "../errors/problem"; -import type { HttpResponse } from "$lib/api/core/http-client"; -import type { Result } from "$lib/core/result"; -import { Err, Ok, Res } from "$lib/core/result"; -import type { ProblemDetails } from "../errors/problem_details"; -import { toDetail } from "../errors/error_utility"; -import { Unauthenticated } from "../errors/v1/unauthenticated"; -import { Unauthorized } from "../errors/v1/unauthorized"; -import jwt_decode from "jwt-decode"; +import { LocalStringError } from '../errors/v1/local_string_error'; +import { LocalExceptionError } from '../errors/v1/local_exception_error'; +import { LocalUnknownError } from '../errors/v1/local_unknown_error'; +import type { Problem } from '../errors/problem'; +import type { HttpResponse } from '$lib/api/core/http-client'; +import type { Result } from '$lib/core/result'; +import { Err, Ok, Res } from '$lib/core/result'; +import type { ProblemDetails } from '../errors/problem_details'; +import { toDetail } from '../errors/error_utility'; +import { Unauthenticated } from '../errors/v1/unauthenticated'; +import { Unauthorized } from '../errors/v1/unauthorized'; +import jwt_decode from 'jwt-decode'; const isResponse = <T>(value: unknown): value is HttpResponse<T> => { - return ( - typeof value === "object" && - value !== null && - "error" in value && - "ok" in value && - "data" in value - ); + return typeof value === 'object' && value !== null && 'error' in value && 'ok' in value && 'data' in value; }; const isProblem = (value: unknown): value is Problem => { - return typeof value === "object" && value !== null && "detail" in value; + return typeof value === 'object' && value !== null && 'detail' in value; }; const isProblemDetail = (value: unknown): value is ProblemDetails => { return ( - typeof value === "object" && + typeof value === 'object' && value !== null && - "detail" in value && - "status" in value && - "title" in value && - "type" in value + 'detail' in value && + 'status' in value && + 'title' in value && + 'type' in value ); }; function pathMatch(pathParts: string[], pattern: string[]) { return ( pathParts.length === pattern.length && - pathParts.every( - (part, index) => pattern[index] === "*" || pattern[index] === part, - ) + pathParts.every((part, index) => pattern[index] === '*' || pattern[index] === part) ); } @@ -75,19 +67,15 @@ async function parseErrorResponse<T>( if (!isProblemDetail(r.error) && (r.status === 401 || r.status === 403)) { return toDetail( r.status === 401 - ? new Unauthenticated("You need to be logged in to view this page.") - : new Unauthorized( - "You do not have permission to view this page.", - [], - [], - ), + ? new Unauthenticated('You need to be logged in to view this page.') + : new Unauthorized('You do not have permission to view this page.', [], []), ); } if (r.error == null) { - const t = (await r.text()) ?? "No body found"; - return toDetail(new LocalStringError("Unknown client error", t)); + const t = (await r.text()) ?? 'No body found'; + return toDetail(new LocalStringError('Unknown client error', t)); } - return parseErrorToDetail("Unknown client error", r.error); + return parseErrorToDetail('Unknown client error', r.error); } function parseErrorToDetail(detail: string, error: unknown): ProblemDetails { @@ -99,7 +87,7 @@ function parseError(detail: string, error: unknown): Problem { console.error(error); if (error instanceof Error) { return new LocalExceptionError(detail, error); - } else if (typeof error === "string") { + } else if (typeof error === 'string') { return new LocalStringError(detail, error); } else if (isProblem(error)) { return error; @@ -119,8 +107,7 @@ function unique<T>(value: T, index: number, array: T[]): boolean { return array.indexOf(value) === index; } -const __ = (i: number) => - new Promise((resolve) => setTimeout(resolve, i * 1000)); +const __ = (i: number) => new Promise(resolve => setTimeout(resolve, i * 1000)); function compare(a?: string | null, b?: string | null): boolean { if (a == null || b == null) return false; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 5e50069..660b839 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,7 +1,7 @@ -import { type ClassValue, clsx } from "clsx"; -import { twMerge } from "tailwind-merge"; -import { cubicOut } from "svelte/easing"; -import type { TransitionConfig } from "svelte/transition"; +import { type ClassValue, clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; +import { cubicOut } from 'svelte/easing'; +import type { TransitionConfig } from 'svelte/transition'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); @@ -19,13 +19,9 @@ export const flyAndScale = ( params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }, ): TransitionConfig => { const style = getComputedStyle(node); - const transform = style.transform === "none" ? "" : style.transform; + const transform = style.transform === 'none' ? '' : style.transform; - const scaleConversion = ( - valueA: number, - scaleA: [number, number], - scaleB: [number, number], - ) => { + const scaleConversion = (valueA: number, scaleA: [number, number], scaleB: [number, number]) => { const [minA, maxA] = scaleA; const [minB, maxB] = scaleB; @@ -35,19 +31,17 @@ export const flyAndScale = ( return valueB; }; - const styleToString = ( - style: Record<string, number | string | undefined>, - ): string => { + const styleToString = (style: Record<string, number | string | undefined>): string => { return Object.keys(style).reduce((str, key) => { if (style[key] === undefined) return str; return str + `${key}:${style[key]};`; - }, ""); + }, ''); }; return { duration: params.duration ?? 200, delay: 0, - css: (t) => { + css: t => { const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]); const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]); const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]); diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index cd0eaab..46d97fc 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -1,22 +1,19 @@ -import type { LayoutServerLoad } from "./$types"; -import type { Session } from "@auth/core/types"; -import { NewApi } from "../store"; -import { expired, toResult } from "$lib/utility"; -import jwtDecode from "jwt-decode"; -import type { JWT } from "@auth/core/jwt"; -import { redirect } from "@sveltejs/kit"; -import { config } from "../config/server"; +import type { LayoutServerLoad } from './$types'; +import type { Session } from '@auth/core/types'; +import { NewApi } from '../store'; +import { expired, toResult } from '$lib/utility'; +import jwtDecode from 'jwt-decode'; +import type { JWT } from '@auth/core/jwt'; +import { redirect } from '@sveltejs/kit'; +import { config } from '../config/server'; export const load: LayoutServerLoad = async ({ locals, route }) => { const session: Session | null = await locals.getSession(); console.log(config); - const signIn = - session?.user != null && - (session.access_token == null || expired(session.access_token, new Date())); - if (route.id === "/register" && session?.user == null) - throw redirect(307, "/"); + const signIn = session?.user != null && (session.access_token == null || expired(session.access_token, new Date())); + if (route.id === '/register' && session?.user == null) throw redirect(307, '/'); if (session?.user == null || signIn) return { session, auth: { signIn } }; @@ -26,18 +23,15 @@ export const load: LayoutServerLoad = async ({ locals, route }) => { // if (config.app.landscape !== "lapras") c.fetch = fetch; const api = NewApi(c); - const s = (jwtDecode(session.access_token!) as JWT).sub ?? ""; + const s = (jwtDecode(session.access_token!) as JWT).sub ?? ''; - const user = toResult( - () => api.vUserDetail2(s, "1"), - `Failed to fetch user ${s}`, - ); + const user = toResult(() => api.vUserDetail2(s, '1'), `Failed to fetch user ${s}`); const ok = await user.isOk(); - if (route.id === "/register") { + if (route.id === '/register') { if (ok) { - throw redirect(307, "/"); + throw redirect(307, '/'); } else { return { session, auth: { signIn } }; } @@ -49,7 +43,7 @@ export const load: LayoutServerLoad = async ({ locals, route }) => { auth: { signIn }, }; } else { - throw redirect(307, "/register"); + throw redirect(307, '/register'); } } }; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index d65d6a9..9c9e275 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -18,15 +18,15 @@ <!-- eslint-disable-next-line svelte/no-at-html-tags --> {@html `<\u{73}cript nonce="%sveltekit.nonce%">(${setInitialClassState.toString()})();</script>`} </svelte:head> -<div class="relative flex min-h-screen flex-col" id="page"> +<div class="flex min-h-screen flex-col" id="page"> <div class="border-b border-b-muted"> - <div class="flex h-16 items-center justify-between px-4 w-11/12 max-w-[1200px] mx-auto"> + <div class="flex h-16 items-center justify-between gap-2 md:gap-4 px-4 max-w-[1200px] mx-auto"> <a href="/" class="flex items-center space-x-2"> <img src={cyanprint} alt="CyanPrint" class="h-12 w-12"/> <span class="hidden text-foreground sm:inline-block ">CyanPrint</span> </a> <MainNav/> - <div class="flex items-center space-x-4 lg:space-x-6"> + <div class="flex items-center md:space-x-2 lg:space-x-6"> <LightSwitch/> <Account/> </div> diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 0e1f2b2..60097d4 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -39,8 +39,8 @@ </script> <Page notFoundMessage="Main page cannot be found"> - <div class="max-w-[1200px] w-5/6 mx-auto"> - <div class="relative text-center text-6xl md:text-9xl flex flex-col justify-center "> + <div class="max-w-[1200px] w-full mx-auto"> + <div class="relative text-center text-4xl md:text-9xl flex flex-col items-center justify-center "> <div class="w-full h-full absolute font-semibold transition-all duration-500 bg-[radial-gradient(ellipse_at_center,_var(--tw-gradient-stops))] @@ -49,12 +49,12 @@ </div> <div class="flex items-center mt-8 md:mt-28 mb-8 w-full font-semibold"> - <div class="mx-auto relative p-2 md:p-4 dark:bg-gradient-to-br bg-gradient-to-tr {textg} inline-block text-transparent bg-clip-text"> + <div class="mx-auto relative p-2 md:p-4 dark:bg-gradient-to-br bg-gradient-to-tr {textg} inline-block text-transparent bg-clip-text"> Next Generation Templating Engine </div> </div> - <div class="relative space-y-2 space-x-0 md:space-y-0 md:space-x-4 my-8 flex flex-col md:flex-row w-full max-w-[1200px] justify-between text-foreground"> - <button class="flex w-1/3 flex-col gap-y-4 items-center justify-center rounded-t-lg md:rounded-lg p-8 cursor-pointer bg-black/5 + <div class="relative items-center space-y-4 space-x-0 md:space-y-0 md:space-x-4 my-8 flex flex-col md:flex-row w-full max-w-[1200px] justify-between text-foreground"> + <button class="flex w-11/12 md:w-1/3 flex-col gap-y-4 items-center justify-center rounded-t-lg md:rounded-lg p-8 cursor-pointer bg-black/5 dark:bg-white/5 backdrop-blur transition hover:scale-[1.02]" on:mouseenter={() => hover="a"} on:mouseleave={() => hover="main"}> <div class="text-2xl font-light">Templates</div> <div class="text-lg text-muted-foreground text-center">Quickly scaffold production-ready projects by answer a few questions</div> @@ -62,7 +62,7 @@ CREATE </Button> </button> - <button class="flex w-1/3 flex-col gap-y-4 items-center justify-center md:rounded-lg p-8 cursor-pointer bg-black/5 dark:bg-white/5 backdrop-blur transition hover:scale-[1.02]" on:mouseenter={() => hover="b"} on:mouseleave={() => hover="main"}> + <button class="flex w-11/12 md:w-1/3 flex-col gap-y-4 items-center justify-center md:rounded-lg p-8 cursor-pointer bg-black/5 dark:bg-white/5 backdrop-blur transition hover:scale-[1.02]" on:mouseenter={() => hover="b"} on:mouseleave={() => hover="main"}> <div class="text-2xl font-light">Processors</div> <div class="text-lg text-muted-foreground text-center"> Create language agnostic rules to generate more powerful templates @@ -71,7 +71,7 @@ CREATE </Button> </button> - <button class="flex w-1/3 flex-col gap-y-4 items-center justify-center rounded-b-lg md:rounded-lg p-8 cursor-pointer bg-black/5 dark:bg-white/5 backdrop-blur transition rounded-lg hover:scale-[1.02]" on:mouseenter={() => hover="c"} on:mouseleave={() => hover="main"}> + <button class="flex w-11/12 md:w-1/3 flex-col gap-y-4 items-center justify-center rounded-b-lg md:rounded-lg p-8 cursor-pointer bg-black/5 dark:bg-white/5 backdrop-blur transition rounded-lg hover:scale-[1.02]" on:mouseenter={() => hover="c"} on:mouseleave={() => hover="main"}> <div class="text-2xl font-light">Plugins</div> <div class="text-lg text-muted-foreground text-center"> Extend capabilities of templates in any language diff --git a/src/routes/api/v1/error_info/+server.ts b/src/routes/api/v1/error_info/+server.ts index e70cd96..d710db9 100644 --- a/src/routes/api/v1/error_info/+server.ts +++ b/src/routes/api/v1/error_info/+server.ts @@ -1,6 +1,6 @@ -import { json } from "@sveltejs/kit"; -import { problems } from "../../../../errors/error_info"; +import { json } from '@sveltejs/kit'; +import { problems } from '../../../../errors/error_info'; export function GET() { - return json([...problems.values()].map((x) => x.id)); + return json([...problems.values()].map(x => x.id)); } diff --git a/src/routes/api/v1/error_info/[slug]/+server.ts b/src/routes/api/v1/error_info/[slug]/+server.ts index 4d443af..6937c4a 100644 --- a/src/routes/api/v1/error_info/[slug]/+server.ts +++ b/src/routes/api/v1/error_info/[slug]/+server.ts @@ -1,14 +1,13 @@ -import type { RequestHandler } from "@sveltejs/kit"; -import { error, json } from "@sveltejs/kit"; -import type { ErrorInfoResp } from "../../../../../errors/error_info"; -import { problems } from "../../../../../errors/error_info"; -import schemas from "./schema.json"; +import type { RequestHandler } from '@sveltejs/kit'; +import { error, json } from '@sveltejs/kit'; +import type { ErrorInfoResp } from '../../../../../errors/error_info'; +import { problems } from '../../../../../errors/error_info'; +import schemas from './schema.json'; export const GET = (async ({ params }) => { if (params.slug == null) throw error(404, `Error '${params.slug}' not found`); - const problem = [...problems.values()].find((x) => x.id === params.slug); - if (problem == undefined) - throw error(404, `Error '${params.slug}' not found`); + const problem = [...problems.values()].find(x => x.id === params.slug); + if (problem == undefined) throw error(404, `Error '${params.slug}' not found`); // get relative // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/src/routes/plugins/[user_id]/[plugin_id]/+page.ts b/src/routes/plugins/[user_id]/[plugin_id]/+page.ts index fa8f5af..704fd7a 100644 --- a/src/routes/plugins/[user_id]/[plugin_id]/+page.ts +++ b/src/routes/plugins/[user_id]/[plugin_id]/+page.ts @@ -1,22 +1,22 @@ -import type { ProblemDetails } from "../../../../errors/problem_details"; -import type { PluginResp } from "$lib/api/core/data-contracts"; -import { NewApi } from "../../../../store"; -import type { PageLoad } from "./$types"; -import { toResult } from "$lib/utility"; +import type { ProblemDetails } from '../../../../errors/problem_details'; +import type { PluginResp } from '$lib/api/core/data-contracts'; +import { NewApi } from '../../../../store'; +import type { PageLoad } from './$types'; +import { toResult } from '$lib/utility'; export const load = (async ({ params, fetch, parent, }): Promise<{ - result: ["err", ProblemDetails] | ["ok", PluginResp]; + result: ['err', ProblemDetails] | ['ok', PluginResp]; }> => { const data = await parent(); const api = NewApi({ data, fetch }); const r = await toResult( - () => api.vPluginIdDetail(params.user_id, params.plugin_id, "1"), - "Fail to get plugin", + () => api.vPluginIdDetail(params.user_id, params.plugin_id, '1'), + 'Fail to get plugin', ).serial(); return { result: r, diff --git a/src/routes/processors/[user_id]/[processor_id]/+page.ts b/src/routes/processors/[user_id]/[processor_id]/+page.ts index 23d4ab9..153062c 100644 --- a/src/routes/processors/[user_id]/[processor_id]/+page.ts +++ b/src/routes/processors/[user_id]/[processor_id]/+page.ts @@ -1,22 +1,22 @@ -import type { ProblemDetails } from "../../../../errors/problem_details"; -import type { ProcessorResp } from "$lib/api/core/data-contracts"; -import { NewApi } from "../../../../store"; -import type { PageLoad } from "./$types"; -import { toResult } from "$lib/utility"; +import type { ProblemDetails } from '../../../../errors/problem_details'; +import type { ProcessorResp } from '$lib/api/core/data-contracts'; +import { NewApi } from '../../../../store'; +import type { PageLoad } from './$types'; +import { toResult } from '$lib/utility'; export const load = (async ({ params, fetch, parent, }): Promise<{ - result: ["err", ProblemDetails] | ["ok", ProcessorResp]; + result: ['err', ProblemDetails] | ['ok', ProcessorResp]; }> => { const data = await parent(); const api = NewApi({ data, fetch }); const r = await toResult( - () => api.vProcessorIdDetail(params.user_id, params.processor_id, "1"), - "Fail to get processor", + () => api.vProcessorIdDetail(params.user_id, params.processor_id, '1'), + 'Fail to get processor', ).serial(); return { result: r, diff --git a/src/routes/templates/[user_id]/[template_id]/+page.ts b/src/routes/templates/[user_id]/[template_id]/+page.ts index f370755..fd7cdc5 100644 --- a/src/routes/templates/[user_id]/[template_id]/+page.ts +++ b/src/routes/templates/[user_id]/[template_id]/+page.ts @@ -1,22 +1,22 @@ -import type { ProblemDetails } from "../../../../errors/problem_details"; -import type { TemplateResp } from "$lib/api/core/data-contracts"; -import { NewApi } from "../../../../store"; -import type { PageLoad } from "./$types"; -import { toResult } from "$lib/utility"; +import type { ProblemDetails } from '../../../../errors/problem_details'; +import type { TemplateResp } from '$lib/api/core/data-contracts'; +import { NewApi } from '../../../../store'; +import type { PageLoad } from './$types'; +import { toResult } from '$lib/utility'; export const load = (async ({ params, fetch, parent, }): Promise<{ - result: ["err", ProblemDetails] | ["ok", TemplateResp]; + result: ['err', ProblemDetails] | ['ok', TemplateResp]; }> => { const data = await parent(); const api = NewApi({ data, fetch }); const r = await toResult( - () => api.vTemplateIdDetail(params.user_id, params.template_id, "1"), - "Fail to get template", + () => api.vTemplateIdDetail(params.user_id, params.template_id, '1'), + 'Fail to get template', ).serial(); return { result: r, diff --git a/src/routes/tokens/+page.ts b/src/routes/tokens/+page.ts index 94e9701..07dea2e 100644 --- a/src/routes/tokens/+page.ts +++ b/src/routes/tokens/+page.ts @@ -1,24 +1,21 @@ -import type { UserResp } from "$lib/api/core/data-contracts"; -import type { PageLoad } from "./$types"; -import { toResult } from "$lib/utility"; -import type { ProblemDetails } from "../../errors/problem_details"; -import { NewApi } from "../../store"; -import jwtDecode from "jwt-decode"; -import type { JWT } from "@auth/core/jwt"; +import type { UserResp } from '$lib/api/core/data-contracts'; +import type { PageLoad } from './$types'; +import { toResult } from '$lib/utility'; +import type { ProblemDetails } from '../../errors/problem_details'; +import { NewApi } from '../../store'; +import jwtDecode from 'jwt-decode'; +import type { JWT } from '@auth/core/jwt'; export const load = (async ({ fetch, parent, }): Promise<{ - result: ["err", ProblemDetails] | ["ok", UserResp]; + result: ['err', ProblemDetails] | ['ok', UserResp]; }> => { const data = await parent(); const api = NewApi({ data, fetch }); - const s = (jwtDecode(data.session?.access_token ?? "") as JWT).sub ?? ""; - const r = await toResult( - () => api.vUserDetail2(s, "1"), - "Fail to get user", - ).serial(); + const s = (jwtDecode(data.session?.access_token ?? '') as JWT).sub ?? ''; + const r = await toResult(() => api.vUserDetail2(s, '1'), 'Fail to get user').serial(); return { result: r, }; diff --git a/src/store.ts b/src/store.ts index 9146bda..bab55d0 100644 --- a/src/store.ts +++ b/src/store.ts @@ -1,13 +1,13 @@ -import type { ApiConfig } from "$lib/api/core/http-client"; -import { Api } from "$lib/api/core/Api"; -import type { Writable } from "svelte/store"; -import { get, writable } from "svelte/store"; -import { config } from "./config/shared"; -import { page } from "$app/stores"; -import type { Session } from "@auth/core/types"; -import { expired } from "$lib/utility"; -import { signIn } from "@auth/sveltekit/client"; -import type { ProblemDetails } from "./errors/problem_details"; +import type { ApiConfig } from '$lib/api/core/http-client'; +import { Api } from '$lib/api/core/Api'; +import type { Writable } from 'svelte/store'; +import { get, writable } from 'svelte/store'; +import { config } from './config/shared'; +import { page } from '$app/stores'; +import type { Session } from '@auth/core/types'; +import { expired } from '$lib/utility'; +import { signIn } from '@auth/sveltekit/client'; +import type { ProblemDetails } from './errors/problem_details'; export const problem: Writable<ProblemDetails | null> = writable(null); @@ -19,11 +19,7 @@ export function NewApi({ data, fetch }: { data?: any; fetch?: any }): Api { baseUrl: `${config.api.scheme}://${config.api.domain}`, securityWorker: async () => { const s = data?.session; - if ( - s && - s?.access_token != null && - !expired(s.access_token, new Date()) - ) { + if (s && s?.access_token != null && !expired(s.access_token, new Date())) { return { headers: { Authorization: `Bearer ${s.access_token}`, @@ -44,17 +40,10 @@ export const api = writable( baseUrl: `${config.api.scheme}://${config.api.domain}`, securityWorker: async () => { const s = get(page).data.session as Session; - if ( - s != null && - (s.access_token == null || expired(s.access_token, new Date())) - ) { - await signIn("descope"); + if (s != null && (s.access_token == null || expired(s.access_token, new Date()))) { + await signIn('descope'); } - if ( - s && - s?.access_token != null && - !expired(s.access_token, new Date()) - ) { + if (s && s?.access_token != null && !expired(s.access_token, new Date())) { return { headers: { Authorization: `Bearer ${s.access_token}`, diff --git a/svelte.config.js b/svelte.config.js index ef10914..dda2030 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,5 +1,5 @@ -import adapter from "@sveltejs/adapter-auto"; -import { vitePreprocess } from "@sveltejs/kit/vite"; +import adapter from '@sveltejs/adapter-auto'; +import { vitePreprocess } from '@sveltejs/kit/vite'; /** @type {import('@sveltejs/kit').Config} */ const config = { @@ -13,7 +13,7 @@ const config = { // See https://kit.svelte.dev/docs/adapters for more information about adapters. adapter: adapter(), alias: { - $lib: "./src/lib", + $lib: './src/lib', }, }, }; diff --git a/tailwind.config.js b/tailwind.config.js index 41bdd0c..360470b 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,57 +1,57 @@ -import { fontFamily } from "tailwindcss/defaultTheme"; +import { fontFamily } from 'tailwindcss/defaultTheme'; /** @type {import('tailwindcss').Config} */ const config = { - darkMode: ["class"], - content: ["./src/**/*.{html,js,svelte,ts}"], + darkMode: ['class'], + content: ['./src/**/*.{html,js,svelte,ts}'], theme: { container: { center: true, - padding: "2rem", + padding: '2rem', screens: { - "2xl": "1400px", + '2xl': '1400px', }, }, extend: { colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", + border: 'hsl(var(--border))', + input: 'hsl(var(--input))', + ring: 'hsl(var(--ring))', + background: 'hsl(var(--background))', + foreground: 'hsl(var(--foreground))', primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", + DEFAULT: 'hsl(var(--primary))', + foreground: 'hsl(var(--primary-foreground))', }, secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", + DEFAULT: 'hsl(var(--secondary))', + foreground: 'hsl(var(--secondary-foreground))', }, destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", + DEFAULT: 'hsl(var(--destructive))', + foreground: 'hsl(var(--destructive-foreground))', }, muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", + DEFAULT: 'hsl(var(--muted))', + foreground: 'hsl(var(--muted-foreground))', }, accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", + DEFAULT: 'hsl(var(--accent))', + foreground: 'hsl(var(--accent-foreground))', }, popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", + DEFAULT: 'hsl(var(--popover))', + foreground: 'hsl(var(--popover-foreground))', }, card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", + DEFAULT: 'hsl(var(--card))', + foreground: 'hsl(var(--card-foreground))', }, }, borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)', }, fontFamily: { sans: [...fontFamily.sans], diff --git a/tests/test.ts b/tests/test.ts index 42175e9..589fab7 100644 --- a/tests/test.ts +++ b/tests/test.ts @@ -1,8 +1,6 @@ -import { expect, test } from "@playwright/test"; +import { expect, test } from '@playwright/test'; -test("index page has expected h1", async ({ page }) => { - await page.goto("/"); - await expect( - page.getByRole("heading", { name: "Welcome to SvelteKit" }), - ).toBeVisible(); +test('index page has expected h1', async ({ page }) => { + await page.goto('/'); + await expect(page.getByRole('heading', { name: 'Welcome to SvelteKit' })).toBeVisible(); }); diff --git a/vite.config.ts b/vite.config.ts index 49c9e7c..5edbb38 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,9 +1,9 @@ -import { sveltekit } from "@sveltejs/kit/vite"; -import { defineConfig } from "vitest/config"; +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vitest/config'; export default defineConfig({ plugins: [sveltekit()], test: { - include: ["src/**/*.{test,spec}.{js,ts}"], + include: ['src/**/*.{test,spec}.{js,ts}'], }, }); From 320f0cfdd50933a9a7ec1b16ad4fc5980d6bcf24 Mon Sep 17 00:00:00 2001 From: kirinnee <kirinnee97@gmail.com> Date: Tue, 31 Dec 2024 15:09:54 +0800 Subject: [PATCH 2/2] fix: formatting --- .prettierrc.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .prettierrc.yaml diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 0000000..a455290 --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,8 @@ +tabWidth: 2 +semi: true +singleQuote: true +bracketSpacing: true +trailingComma: all +arrowParens: avoid +printWidth: 120 +singleAttributePerLine: false