trifid-api 0.3.0-alpha1 and some work on a tfweb rewrite #6
|
@ -35,10 +35,14 @@
|
|||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"bits-ui": "^0.11.8",
|
||||
"clsx": "^2.0.0",
|
||||
"formsnap": "^0.4.1",
|
||||
"lucide-svelte": "^0.298.0",
|
||||
"mode-watcher": "^0.1.2",
|
||||
"sveltekit-superforms": "^1.12.0",
|
||||
"tailwind-merge": "^2.1.0",
|
||||
"tailwind-variants": "^0.1.19"
|
||||
"tailwind-variants": "^0.1.19",
|
||||
"zod": "^3.22.4"
|
||||
}
|
||||
}
|
|
@ -5,21 +5,33 @@ settings:
|
|||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
bits-ui:
|
||||
specifier: ^0.11.8
|
||||
version: 0.11.8(svelte@4.2.8)
|
||||
clsx:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
formsnap:
|
||||
specifier: ^0.4.1
|
||||
version: 0.4.1(svelte@4.2.8)(sveltekit-superforms@1.12.0)(zod@3.22.4)
|
||||
lucide-svelte:
|
||||
specifier: ^0.298.0
|
||||
version: 0.298.0(svelte@4.2.8)
|
||||
mode-watcher:
|
||||
specifier: ^0.1.2
|
||||
version: 0.1.2(svelte@4.2.8)
|
||||
sveltekit-superforms:
|
||||
specifier: ^1.12.0
|
||||
version: 1.12.0(@sveltejs/kit@2.0.1)(svelte@4.2.8)(zod@3.22.4)
|
||||
tailwind-merge:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
tailwind-variants:
|
||||
specifier: ^0.1.19
|
||||
version: 0.1.19(tailwindcss@3.3.6)
|
||||
zod:
|
||||
specifier: ^3.22.4
|
||||
version: 3.22.4
|
||||
|
||||
devDependencies:
|
||||
'@sveltejs/adapter-auto':
|
||||
|
@ -114,7 +126,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-arm@0.19.9:
|
||||
|
@ -123,7 +134,6 @@ packages:
|
|||
cpu: [arm]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-x64@0.19.9:
|
||||
|
@ -132,7 +142,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-arm64@0.19.9:
|
||||
|
@ -141,7 +150,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-x64@0.19.9:
|
||||
|
@ -150,7 +158,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-arm64@0.19.9:
|
||||
|
@ -159,7 +166,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-x64@0.19.9:
|
||||
|
@ -168,7 +174,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm64@0.19.9:
|
||||
|
@ -177,7 +182,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm@0.19.9:
|
||||
|
@ -186,7 +190,6 @@ packages:
|
|||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ia32@0.19.9:
|
||||
|
@ -195,7 +198,6 @@ packages:
|
|||
cpu: [ia32]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-loong64@0.19.9:
|
||||
|
@ -204,7 +206,6 @@ packages:
|
|||
cpu: [loong64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-mips64el@0.19.9:
|
||||
|
@ -213,7 +214,6 @@ packages:
|
|||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ppc64@0.19.9:
|
||||
|
@ -222,7 +222,6 @@ packages:
|
|||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-riscv64@0.19.9:
|
||||
|
@ -231,7 +230,6 @@ packages:
|
|||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-s390x@0.19.9:
|
||||
|
@ -240,7 +238,6 @@ packages:
|
|||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-x64@0.19.9:
|
||||
|
@ -249,7 +246,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/netbsd-x64@0.19.9:
|
||||
|
@ -258,7 +254,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/openbsd-x64@0.19.9:
|
||||
|
@ -267,7 +262,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/sunos-x64@0.19.9:
|
||||
|
@ -276,7 +270,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [sunos]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-arm64@0.19.9:
|
||||
|
@ -285,7 +278,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-ia32@0.19.9:
|
||||
|
@ -294,7 +286,6 @@ packages:
|
|||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-x64@0.19.9:
|
||||
|
@ -303,7 +294,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@eslint-community/eslint-utils@4.4.0(eslint@8.56.0):
|
||||
|
@ -343,6 +333,23 @@ packages:
|
|||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/@floating-ui/core@1.5.2:
|
||||
resolution: {integrity: sha512-Ii3MrfY/GAIN3OhXNzpCKaLxHQfJF9qvwq/kEJYdqDxeIHa01K8sldugal6TmeeXl+WMvhv9cnVzUTaFFJF09A==}
|
||||
dependencies:
|
||||
'@floating-ui/utils': 0.1.6
|
||||
dev: false
|
||||
|
||||
/@floating-ui/dom@1.5.3:
|
||||
resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==}
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.5.2
|
||||
'@floating-ui/utils': 0.1.6
|
||||
dev: false
|
||||
|
||||
/@floating-ui/utils@0.1.6:
|
||||
resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==}
|
||||
dev: false
|
||||
|
||||
/@humanwhocodes/config-array@0.11.13:
|
||||
resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
|
@ -363,6 +370,12 @@ packages:
|
|||
resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==}
|
||||
dev: true
|
||||
|
||||
/@internationalized/date@3.5.0:
|
||||
resolution: {integrity: sha512-nw0Q+oRkizBWMioseI8+2TeUPEyopJVz5YxoYVzR0W1v+2YytiYah7s/ot35F149q/xAg4F1gT/6eTd+tsUpFQ==}
|
||||
dependencies:
|
||||
'@swc/helpers': 0.5.3
|
||||
dev: false
|
||||
|
||||
/@jridgewell/gen-mapping@0.3.3:
|
||||
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
@ -388,6 +401,20 @@ packages:
|
|||
'@jridgewell/resolve-uri': 3.1.1
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
|
||||
/@melt-ui/svelte@0.65.2(svelte@4.2.8):
|
||||
resolution: {integrity: sha512-BpsSl9Bjp1++8U3+LaDOFUoX/PFQ9N7QWFhlFdUEZduhrbVyU70v9A459SKrQ+esFSjvh1AvqJYkMAUJXJlAmQ==}
|
||||
peerDependencies:
|
||||
svelte: '>=3 <5'
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.5.2
|
||||
'@floating-ui/dom': 1.5.3
|
||||
'@internationalized/date': 3.5.0
|
||||
dequal: 2.0.3
|
||||
focus-trap: 7.5.4
|
||||
nanoid: 4.0.2
|
||||
svelte: 4.2.8
|
||||
dev: false
|
||||
|
||||
/@nodelib/fs.scandir@2.1.5:
|
||||
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
|
||||
engines: {node: '>= 8'}
|
||||
|
@ -408,14 +435,12 @@ packages:
|
|||
|
||||
/@polka/url@1.0.0-next.24:
|
||||
resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==}
|
||||
dev: true
|
||||
|
||||
/@rollup/rollup-android-arm-eabi@4.9.0:
|
||||
resolution: {integrity: sha512-+1ge/xmaJpm1KVBuIH38Z94zj9fBD+hp+/5WLaHgyY8XLq1ibxk/zj6dTXaqM2cAbYKq8jYlhHd6k05If1W5xA==}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-android-arm64@4.9.0:
|
||||
|
@ -423,7 +448,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-darwin-arm64@4.9.0:
|
||||
|
@ -431,7 +455,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-darwin-x64@4.9.0:
|
||||
|
@ -439,7 +462,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-linux-arm-gnueabihf@4.9.0:
|
||||
|
@ -447,7 +469,6 @@ packages:
|
|||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-linux-arm64-gnu@4.9.0:
|
||||
|
@ -455,7 +476,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-linux-arm64-musl@4.9.0:
|
||||
|
@ -463,7 +483,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-linux-riscv64-gnu@4.9.0:
|
||||
|
@ -471,7 +490,6 @@ packages:
|
|||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-linux-x64-gnu@4.9.0:
|
||||
|
@ -479,7 +497,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-linux-x64-musl@4.9.0:
|
||||
|
@ -487,7 +504,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-win32-arm64-msvc@4.9.0:
|
||||
|
@ -495,7 +511,6 @@ packages:
|
|||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-win32-ia32-msvc@4.9.0:
|
||||
|
@ -503,7 +518,6 @@ packages:
|
|||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@rollup/rollup-win32-x64-msvc@4.9.0:
|
||||
|
@ -511,7 +525,6 @@ packages:
|
|||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@sveltejs/adapter-auto@3.0.0(@sveltejs/kit@2.0.1):
|
||||
|
@ -547,7 +560,6 @@ packages:
|
|||
svelte: 4.2.8
|
||||
tiny-glob: 0.2.9
|
||||
vite: 5.0.10
|
||||
dev: true
|
||||
|
||||
/@sveltejs/vite-plugin-svelte-inspector@2.0.0(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@4.2.8)(vite@5.0.10):
|
||||
resolution: {integrity: sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==}
|
||||
|
@ -563,7 +575,6 @@ packages:
|
|||
vite: 5.0.10
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@sveltejs/vite-plugin-svelte@3.0.1(svelte@4.2.8)(vite@5.0.10):
|
||||
resolution: {integrity: sha512-CGURX6Ps+TkOovK6xV+Y2rn8JKa8ZPUHPZ/NKgCxAmgBrXReavzFl8aOSCj3kQ1xqT7yGJj53hjcV/gqwDAaWA==}
|
||||
|
@ -583,11 +594,15 @@ packages:
|
|||
vitefu: 0.2.5(vite@5.0.10)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@swc/helpers@0.5.3:
|
||||
resolution: {integrity: sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==}
|
||||
dependencies:
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/@types/cookie@0.6.0:
|
||||
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
||||
dev: true
|
||||
|
||||
/@types/estree@1.0.5:
|
||||
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
|
||||
|
@ -828,6 +843,17 @@ packages:
|
|||
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
/bits-ui@0.11.8(svelte@4.2.8):
|
||||
resolution: {integrity: sha512-T3YaT88OJguBoUU/MSncf41fiIc+5/ka8Au2LUDo0nSECex+LFY40+hKWLJc5tRT56avkyHsI7x9daA2r9eS/g==}
|
||||
peerDependencies:
|
||||
svelte: ^4.0.0
|
||||
dependencies:
|
||||
'@internationalized/date': 3.5.0
|
||||
'@melt-ui/svelte': 0.65.2(svelte@4.2.8)
|
||||
nanoid: 5.0.4
|
||||
svelte: 4.2.8
|
||||
dev: false
|
||||
|
||||
/brace-expansion@1.1.11:
|
||||
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
||||
dependencies:
|
||||
|
@ -925,7 +951,6 @@ packages:
|
|||
/cookie@0.6.0:
|
||||
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: true
|
||||
|
||||
/cross-spawn@7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
|
@ -958,7 +983,6 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
dev: true
|
||||
|
||||
/deep-is@0.1.4:
|
||||
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
||||
|
@ -967,7 +991,6 @@ packages:
|
|||
/deepmerge@4.3.1:
|
||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/dequal@2.0.3:
|
||||
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
|
||||
|
@ -980,7 +1003,6 @@ packages:
|
|||
|
||||
/devalue@4.3.2:
|
||||
resolution: {integrity: sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==}
|
||||
dev: true
|
||||
|
||||
/didyoumean@1.2.2:
|
||||
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
|
||||
|
@ -1038,7 +1060,6 @@ packages:
|
|||
'@esbuild/win32-arm64': 0.19.9
|
||||
'@esbuild/win32-ia32': 0.19.9
|
||||
'@esbuild/win32-x64': 0.19.9
|
||||
dev: true
|
||||
|
||||
/escalade@3.1.1:
|
||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||
|
@ -1159,7 +1180,6 @@ packages:
|
|||
|
||||
/esm-env@1.0.0:
|
||||
resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==}
|
||||
dev: true
|
||||
|
||||
/espree@9.6.1:
|
||||
resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
|
||||
|
@ -1260,6 +1280,24 @@ packages:
|
|||
resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
|
||||
dev: true
|
||||
|
||||
/focus-trap@7.5.4:
|
||||
resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==}
|
||||
dependencies:
|
||||
tabbable: 6.2.0
|
||||
dev: false
|
||||
|
||||
/formsnap@0.4.1(svelte@4.2.8)(sveltekit-superforms@1.12.0)(zod@3.22.4):
|
||||
resolution: {integrity: sha512-hUOaDKb+KoBi4PamJRnxRqIQW3msp2BKPqohoqjHUuBb+vgBrhoaz0WYEFkXG4bzVQS3JngG55m/zX5ciZTyeA==}
|
||||
peerDependencies:
|
||||
svelte: ^4.0.0
|
||||
sveltekit-superforms: ^1.7.1
|
||||
zod: ^3.22.2
|
||||
dependencies:
|
||||
svelte: 4.2.8
|
||||
sveltekit-superforms: 1.12.0(@sveltejs/kit@2.0.1)(svelte@4.2.8)(zod@3.22.4)
|
||||
zod: 3.22.4
|
||||
dev: false
|
||||
|
||||
/fraction.js@4.3.7:
|
||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||
dev: true
|
||||
|
@ -1319,7 +1357,6 @@ packages:
|
|||
|
||||
/globalyzer@0.1.0:
|
||||
resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==}
|
||||
dev: true
|
||||
|
||||
/globby@11.1.0:
|
||||
resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
|
||||
|
@ -1335,7 +1372,6 @@ packages:
|
|||
|
||||
/globrex@0.1.2:
|
||||
resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
|
||||
dev: true
|
||||
|
||||
/graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
@ -1458,7 +1494,6 @@ packages:
|
|||
/kleur@4.1.5:
|
||||
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/known-css-properties@0.29.0:
|
||||
resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==}
|
||||
|
@ -1571,16 +1606,13 @@ packages:
|
|||
/mri@1.2.0:
|
||||
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/mrmime@1.0.1:
|
||||
resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/ms@2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
dev: true
|
||||
|
||||
/mz@2.7.0:
|
||||
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
|
||||
|
@ -1594,6 +1626,18 @@ packages:
|
|||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
/nanoid@4.0.2:
|
||||
resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==}
|
||||
engines: {node: ^14 || ^16 || >=18}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/nanoid@5.0.4:
|
||||
resolution: {integrity: sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==}
|
||||
engines: {node: ^18 || >=20}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/natural-compare@1.4.0:
|
||||
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
|
||||
dev: true
|
||||
|
@ -1963,7 +2007,6 @@ packages:
|
|||
'@rollup/rollup-win32-ia32-msvc': 4.9.0
|
||||
'@rollup/rollup-win32-x64-msvc': 4.9.0
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/run-parallel@1.2.0:
|
||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||
|
@ -1975,7 +2018,6 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
mri: 1.2.0
|
||||
dev: true
|
||||
|
||||
/sander@0.5.1:
|
||||
resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==}
|
||||
|
@ -1996,7 +2038,6 @@ packages:
|
|||
|
||||
/set-cookie-parser@2.6.0:
|
||||
resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==}
|
||||
dev: true
|
||||
|
||||
/shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
|
@ -2017,7 +2058,6 @@ packages:
|
|||
'@polka/url': 1.0.0-next.24
|
||||
mrmime: 1.0.1
|
||||
totalist: 3.0.1
|
||||
dev: true
|
||||
|
||||
/slash@3.0.0:
|
||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||
|
@ -2132,7 +2172,6 @@ packages:
|
|||
svelte: ^3.19.0 || ^4.0.0
|
||||
dependencies:
|
||||
svelte: 4.2.8
|
||||
dev: true
|
||||
|
||||
/svelte-preprocess@5.1.2(postcss-load-config@5.0.2)(postcss@8.4.32)(svelte@4.2.8)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-XF0aliMAcYnP4hLETvB6HRAMnaL09ASYT1Z2I1Gwu0nz6xbdg/dSgAEthtFZJA4AKrNhFDFdmUDO+H9d/6xg5g==}
|
||||
|
@ -2201,6 +2240,22 @@ packages:
|
|||
magic-string: 0.30.5
|
||||
periscopic: 3.1.0
|
||||
|
||||
/sveltekit-superforms@1.12.0(@sveltejs/kit@2.0.1)(svelte@4.2.8)(zod@3.22.4):
|
||||
resolution: {integrity: sha512-yer9YKhfWsKsDIxXahFLuGuUel32gyi96qIdxTVFAOWXZM9ZaMEP7+FL2cMYRDg6Xqlrh5SQ9oQdkVYeLNG0eA==}
|
||||
peerDependencies:
|
||||
'@sveltejs/kit': 1.x || 2.x
|
||||
svelte: 3.x || 4.x
|
||||
zod: 3.x
|
||||
dependencies:
|
||||
'@sveltejs/kit': 2.0.1(@sveltejs/vite-plugin-svelte@3.0.1)(svelte@4.2.8)(vite@5.0.10)
|
||||
svelte: 4.2.8
|
||||
zod: 3.22.4
|
||||
dev: false
|
||||
|
||||
/tabbable@6.2.0:
|
||||
resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
|
||||
dev: false
|
||||
|
||||
/tailwind-merge@1.14.0:
|
||||
resolution: {integrity: sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==}
|
||||
dev: false
|
||||
|
@ -2271,7 +2326,6 @@ packages:
|
|||
dependencies:
|
||||
globalyzer: 0.1.0
|
||||
globrex: 0.1.2
|
||||
dev: true
|
||||
|
||||
/to-regex-range@5.0.1:
|
||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||
|
@ -2282,7 +2336,6 @@ packages:
|
|||
/totalist@3.0.1:
|
||||
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/ts-api-utils@1.0.3(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
|
||||
|
@ -2298,7 +2351,6 @@ packages:
|
|||
|
||||
/tslib@2.6.2:
|
||||
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||
dev: true
|
||||
|
||||
/type-check@0.4.0:
|
||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||
|
@ -2371,7 +2423,6 @@ packages:
|
|||
rollup: 4.9.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/vitefu@0.2.5(vite@5.0.10):
|
||||
resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==}
|
||||
|
@ -2382,7 +2433,6 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
vite: 5.0.10
|
||||
dev: true
|
||||
|
||||
/which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
|
@ -2412,3 +2462,7 @@ packages:
|
|||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/zod@3.22.4:
|
||||
resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
|
||||
dev: false
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<script lang="ts">
|
||||
import { Button as ButtonPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils";
|
||||
import { buttonVariants, type Props, type Events } from ".";
|
||||
|
||||
type $$Props = Props;
|
||||
type $$Events = Events;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let variant: $$Props["variant"] = "default";
|
||||
export let size: $$Props["size"] = "default";
|
||||
export let builders: $$Props["builders"] = [];
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<ButtonPrimitive.Root
|
||||
{builders}
|
||||
class={cn(buttonVariants({ variant, size, className }))}
|
||||
type="button"
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
>
|
||||
<slot />
|
||||
</ButtonPrimitive.Root>
|
|
@ -0,0 +1,51 @@
|
|||
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",
|
||||
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"
|
||||
},
|
||||
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"
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default"
|
||||
}
|
||||
});
|
||||
|
||||
type Variant = VariantProps<typeof buttonVariants>["variant"];
|
||||
type Size = VariantProps<typeof buttonVariants>["size"];
|
||||
|
||||
type Props = ButtonPrimitive.Props & {
|
||||
variant?: Variant;
|
||||
size?: Size;
|
||||
};
|
||||
|
||||
type Events = ButtonPrimitive.Events;
|
||||
|
||||
export {
|
||||
Root,
|
||||
type Props,
|
||||
type Events,
|
||||
//
|
||||
Root as Button,
|
||||
type Props as ButtonProps,
|
||||
type Events as ButtonEvents,
|
||||
buttonVariants
|
||||
};
|
|
@ -0,0 +1,34 @@
|
|||
<script lang="ts">
|
||||
import { Checkbox as CheckboxPrimitive } from "bits-ui";
|
||||
import { Check, Minus } from "lucide-svelte";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = CheckboxPrimitive.Props;
|
||||
type $$Events = CheckboxPrimitive.Events;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let checked: $$Props["checked"] = false;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<CheckboxPrimitive.Root
|
||||
class={cn(
|
||||
"box-content peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
|
||||
className
|
||||
)}
|
||||
bind:checked
|
||||
{...$$restProps}
|
||||
on:click
|
||||
>
|
||||
<CheckboxPrimitive.Indicator
|
||||
class={cn("flex items-center justify-center text-current h-4 w-4")}
|
||||
let:isChecked
|
||||
let:isIndeterminate
|
||||
>
|
||||
{#if isChecked}
|
||||
<Check class="h-3.5 w-3.5" />
|
||||
{:else if isIndeterminate}
|
||||
<Minus class="h-3.5 w-3.5" />
|
||||
{/if}
|
||||
</CheckboxPrimitive.Indicator>
|
||||
</CheckboxPrimitive.Root>
|
|
@ -0,0 +1,6 @@
|
|||
import Root from "./checkbox.svelte";
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Checkbox
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
<script lang="ts">
|
||||
import * as Button from "$lib/components/ui/button";
|
||||
type $$Props = Button.Props;
|
||||
type $$Events = Button.Events;
|
||||
</script>
|
||||
|
||||
<Button.Root type="submit" {...$$restProps} on:click on:keydown>
|
||||
<slot />
|
||||
</Button.Root>
|
|
@ -0,0 +1,26 @@
|
|||
<script lang="ts">
|
||||
import { getFormField } from "formsnap";
|
||||
import type { Checkbox as CheckboxPrimitive } from "bits-ui";
|
||||
import { Checkbox } from "$lib/components/ui/checkbox";
|
||||
type $$Props = CheckboxPrimitive.Props;
|
||||
type $$Events = CheckboxPrimitive.Events;
|
||||
|
||||
export let onCheckedChange: $$Props["onCheckedChange"] = undefined;
|
||||
|
||||
const { name, setValue, attrStore, value } = getFormField();
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { name: nameAttr, value: valueAttr, ...rest } = $attrStore;
|
||||
</script>
|
||||
|
||||
<Checkbox
|
||||
{...rest}
|
||||
checked={typeof $value === "boolean" ? $value : false}
|
||||
onCheckedChange={(v) => {
|
||||
onCheckedChange?.(v);
|
||||
setValue(v);
|
||||
}}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
/>
|
||||
<input hidden {name} value={$value} />
|
|
@ -0,0 +1,16 @@
|
|||
<script lang="ts">
|
||||
import { Form as FormPrimitive } from "formsnap";
|
||||
import { cn } from "$lib/utils";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLSpanElement>;
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<FormPrimitive.Description
|
||||
class={cn("text-sm text-muted-foreground", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</FormPrimitive.Description>
|
|
@ -0,0 +1,28 @@
|
|||
<script lang="ts">
|
||||
import { getFormField } from "formsnap";
|
||||
import type { HTMLInputAttributes } from "svelte/elements";
|
||||
import { Input, type InputEvents } from "$lib/components/ui/input";
|
||||
|
||||
type $$Props = HTMLInputAttributes;
|
||||
type $$Events = InputEvents;
|
||||
|
||||
const { attrStore, value } = getFormField();
|
||||
</script>
|
||||
|
||||
<Input
|
||||
{...$attrStore}
|
||||
bind:value={$value}
|
||||
{...$$restProps}
|
||||
on:blur
|
||||
on:change
|
||||
on:click
|
||||
on:focus
|
||||
on:keydown
|
||||
on:keypress
|
||||
on:keyup
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
on:paste
|
||||
on:input
|
||||
/>
|
|
@ -0,0 +1,12 @@
|
|||
<script lang="ts">
|
||||
import { cn } from "$lib/utils";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div class={cn("space-y-2", className)} {...$$restProps}>
|
||||
<slot />
|
||||
</div>
|
|
@ -0,0 +1,21 @@
|
|||
<script lang="ts">
|
||||
import type { Label as LabelPrimitive } from "bits-ui";
|
||||
import { getFormField } from "formsnap";
|
||||
import { cn } from "$lib/utils";
|
||||
import { Label } from "$lib/components/ui/label";
|
||||
|
||||
type $$Props = LabelPrimitive.Props;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
|
||||
const { errors, ids } = getFormField();
|
||||
</script>
|
||||
|
||||
<Label
|
||||
for={$ids.input}
|
||||
class={cn($errors && "text-destructive", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</Label>
|
|
@ -0,0 +1,26 @@
|
|||
<script lang="ts">
|
||||
import { Form as FormPrimitive } from "formsnap";
|
||||
import { buttonVariants } from "$lib/components/ui/button";
|
||||
import { cn } from "$lib/utils";
|
||||
import { ChevronDown } from "lucide-svelte";
|
||||
import type { HTMLSelectAttributes } from "svelte/elements";
|
||||
|
||||
type $$Props = HTMLSelectAttributes;
|
||||
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div class="relative">
|
||||
<FormPrimitive.Select
|
||||
class={cn(
|
||||
buttonVariants({ variant: "outline" }),
|
||||
"appearance-none bg-transparent font-normal",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</FormPrimitive.Select>
|
||||
<ChevronDown class="absolute right-3 top-2.5 h-4 w-4 opacity-50" />
|
||||
</div>
|
|
@ -0,0 +1,22 @@
|
|||
<script lang="ts">
|
||||
import { getFormField } from "formsnap";
|
||||
import type { RadioGroup as RadioGroupPrimitive } from "bits-ui";
|
||||
import * as RadioGroup from "$lib/components/ui/radio-group";
|
||||
|
||||
type $$Props = RadioGroupPrimitive.Props;
|
||||
const { attrStore, setValue, name, value } = getFormField();
|
||||
|
||||
export let onValueChange: $$Props["onValueChange"] = undefined;
|
||||
</script>
|
||||
|
||||
<RadioGroup.Root
|
||||
{...$attrStore}
|
||||
onValueChange={(v) => {
|
||||
onValueChange?.(v);
|
||||
setValue(v);
|
||||
}}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
<input hidden {name} value={$value} />
|
||||
</RadioGroup.Root>
|
|
@ -0,0 +1,23 @@
|
|||
<script lang="ts">
|
||||
import * as Select from "$lib/components/ui/select";
|
||||
import type { Select as SelectPrimitive } from "bits-ui";
|
||||
import { getFormField } from "formsnap";
|
||||
|
||||
type $$Props = SelectPrimitive.TriggerProps & {
|
||||
placeholder?: string;
|
||||
};
|
||||
type $$Events = SelectPrimitive.TriggerEvents;
|
||||
const { attrStore } = getFormField();
|
||||
export let placeholder = "";
|
||||
</script>
|
||||
|
||||
<Select.Trigger
|
||||
{...$$restProps}
|
||||
{...$attrStore}
|
||||
on:click
|
||||
on:keydown
|
||||
type="button"
|
||||
>
|
||||
<Select.Value {placeholder} />
|
||||
<slot />
|
||||
</Select.Trigger>
|
|
@ -0,0 +1,20 @@
|
|||
<script lang="ts">
|
||||
import * as Select from "$lib/components/ui/select";
|
||||
import { getFormField } from "formsnap";
|
||||
import type { Select as SelectPrimitive } from "bits-ui";
|
||||
|
||||
type $$Props = SelectPrimitive.Props<unknown>;
|
||||
const { setValue, name, value } = getFormField();
|
||||
export let onSelectedChange: $$Props["onSelectedChange"] = undefined;
|
||||
</script>
|
||||
|
||||
<Select.Root
|
||||
onSelectedChange={(v) => {
|
||||
onSelectedChange?.(v);
|
||||
setValue(v ? v.value : undefined);
|
||||
}}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
<input hidden {name} value={$value} />
|
||||
</Select.Root>
|
|
@ -0,0 +1,24 @@
|
|||
<script lang="ts">
|
||||
import { getFormField } from "formsnap";
|
||||
import type { Switch as SwitchPrimitive } from "bits-ui";
|
||||
import { Switch } from "$lib/components/ui/switch";
|
||||
type $$Props = SwitchPrimitive.Props;
|
||||
type $$Events = SwitchPrimitive.Events;
|
||||
|
||||
export let onCheckedChange: $$Props["onCheckedChange"] = undefined;
|
||||
|
||||
const { name, setValue, attrStore, value } = getFormField();
|
||||
</script>
|
||||
|
||||
<Switch
|
||||
{...$attrStore}
|
||||
checked={typeof $value === "boolean" ? $value : false}
|
||||
onCheckedChange={(v) => {
|
||||
onCheckedChange?.(v);
|
||||
setValue(v);
|
||||
}}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
/>
|
||||
<input hidden {name} value={$value} />
|
|
@ -0,0 +1,32 @@
|
|||
<script lang="ts">
|
||||
import { getFormField } from "formsnap";
|
||||
import type { HTMLTextareaAttributes } from "svelte/elements";
|
||||
import type { TextareaGetFormField } from ".";
|
||||
import {
|
||||
Textarea,
|
||||
type TextareaEvents
|
||||
} from "$lib/components/ui/textarea";
|
||||
|
||||
type $$Props = HTMLTextareaAttributes;
|
||||
type $$Events = TextareaEvents;
|
||||
|
||||
const { attrStore, value } = getFormField() as TextareaGetFormField;
|
||||
</script>
|
||||
|
||||
<Textarea
|
||||
{...$attrStore}
|
||||
bind:value={$value}
|
||||
{...$$restProps}
|
||||
on:blur
|
||||
on:change
|
||||
on:click
|
||||
on:focus
|
||||
on:keydown
|
||||
on:keypress
|
||||
on:keyup
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
on:paste
|
||||
on:input
|
||||
/>
|
|
@ -0,0 +1,14 @@
|
|||
<script lang="ts">
|
||||
import { Form as FormPrimitive } from "formsnap";
|
||||
import { cn } from "$lib/utils";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLParagraphElement>;
|
||||
let className: string | undefined | null = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<FormPrimitive.Validation
|
||||
class={cn("text-sm font-medium text-destructive", className)}
|
||||
{...$$restProps}
|
||||
/>
|
|
@ -0,0 +1,85 @@
|
|||
import { Form as FormPrimitive, getFormField } from "formsnap";
|
||||
import * as RadioGroupComp from "$lib/components/ui/radio-group";
|
||||
import * as SelectComp from "$lib/components/ui/select";
|
||||
import type { Writable } from "svelte/store";
|
||||
import Item from "./form-item.svelte";
|
||||
import Input from "./form-input.svelte";
|
||||
import Textarea from "./form-textarea.svelte";
|
||||
import Description from "./form-description.svelte";
|
||||
import Label from "./form-label.svelte";
|
||||
import Validation from "./form-validation.svelte";
|
||||
import Checkbox from "./form-checkbox.svelte";
|
||||
import Switch from "./form-switch.svelte";
|
||||
import NativeSelect from "./form-native-select.svelte";
|
||||
import RadioGroup from "./form-radio-group.svelte";
|
||||
import Select from "./form-select.svelte";
|
||||
import SelectTrigger from "./form-select-trigger.svelte";
|
||||
import Button from "./form-button.svelte";
|
||||
|
||||
const Root = FormPrimitive.Root;
|
||||
const Field = FormPrimitive.Field;
|
||||
const Control = FormPrimitive.Control;
|
||||
const RadioItem = RadioGroupComp.Item;
|
||||
const NativeRadio = FormPrimitive.Radio;
|
||||
const SelectContent = SelectComp.Content;
|
||||
const SelectLabel = SelectComp.Label;
|
||||
const SelectGroup = SelectComp.Group;
|
||||
const SelectItem = SelectComp.Item;
|
||||
const SelectSeparator = SelectComp.Separator;
|
||||
|
||||
export type TextareaGetFormField = Omit<
|
||||
ReturnType<typeof getFormField>,
|
||||
"value"
|
||||
> & {
|
||||
value: Writable<string>;
|
||||
};
|
||||
|
||||
export {
|
||||
Root,
|
||||
Field,
|
||||
Control,
|
||||
Item,
|
||||
Input,
|
||||
Label,
|
||||
Button,
|
||||
Switch,
|
||||
Select,
|
||||
Checkbox,
|
||||
Textarea,
|
||||
Validation,
|
||||
RadioGroup,
|
||||
RadioItem,
|
||||
Description,
|
||||
SelectContent,
|
||||
SelectLabel,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
SelectSeparator,
|
||||
SelectTrigger,
|
||||
NativeSelect,
|
||||
NativeRadio,
|
||||
//
|
||||
Root as Form,
|
||||
Field as FormField,
|
||||
Control as FormControl,
|
||||
Item as FormItem,
|
||||
Input as FormInput,
|
||||
Textarea as FormTextarea,
|
||||
Description as FormDescription,
|
||||
Label as FormLabel,
|
||||
Validation as FormValidation,
|
||||
NativeSelect as FormNativeSelect,
|
||||
NativeRadio as FormNativeRadio,
|
||||
Checkbox as FormCheckbox,
|
||||
Switch as FormSwitch,
|
||||
RadioGroup as FormRadioGroup,
|
||||
RadioItem as FormRadioItem,
|
||||
Select as FormSelect,
|
||||
SelectContent as FormSelectContent,
|
||||
SelectLabel as FormSelectLabel,
|
||||
SelectGroup as FormSelectGroup,
|
||||
SelectItem as FormSelectItem,
|
||||
SelectSeparator as FormSelectSeparator,
|
||||
SelectTrigger as FormSelectTrigger,
|
||||
Button as FormButton
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
import Root from "./input.svelte";
|
||||
|
||||
type FormInputEvent<T extends Event = Event> = T & {
|
||||
currentTarget: EventTarget & HTMLInputElement;
|
||||
};
|
||||
export type InputEvents = {
|
||||
blur: FormInputEvent<FocusEvent>;
|
||||
change: FormInputEvent<Event>;
|
||||
click: FormInputEvent<MouseEvent>;
|
||||
focus: FormInputEvent<FocusEvent>;
|
||||
keydown: FormInputEvent<KeyboardEvent>;
|
||||
keypress: FormInputEvent<KeyboardEvent>;
|
||||
keyup: FormInputEvent<KeyboardEvent>;
|
||||
mouseover: FormInputEvent<MouseEvent>;
|
||||
mouseenter: FormInputEvent<MouseEvent>;
|
||||
mouseleave: FormInputEvent<MouseEvent>;
|
||||
paste: FormInputEvent<ClipboardEvent>;
|
||||
input: FormInputEvent<InputEvent>;
|
||||
};
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Input
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLInputAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils";
|
||||
import type { InputEvents } from ".";
|
||||
|
||||
type $$Props = HTMLInputAttributes;
|
||||
type $$Events = InputEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let value: $$Props["value"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<input
|
||||
class={cn(
|
||||
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-foreground file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
bind:value
|
||||
on:blur
|
||||
on:change
|
||||
on:click
|
||||
on:focus
|
||||
on:keydown
|
||||
on:keypress
|
||||
on:keyup
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
on:paste
|
||||
on:input
|
||||
{...$$restProps}
|
||||
/>
|
|
@ -0,0 +1,7 @@
|
|||
import Root from "./label.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Label
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
<script lang="ts">
|
||||
import { Label as LabelPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = LabelPrimitive.Props;
|
||||
type $$Events = LabelPrimitive.Events;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<LabelPrimitive.Root
|
||||
class={cn(
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:mousedown
|
||||
>
|
||||
<slot />
|
||||
</LabelPrimitive.Root>
|
|
@ -0,0 +1,15 @@
|
|||
import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
|
||||
|
||||
import Root from "./radio-group.svelte";
|
||||
import Item from "./radio-group-item.svelte";
|
||||
const Input = RadioGroupPrimitive.Input;
|
||||
|
||||
export {
|
||||
Root,
|
||||
Input,
|
||||
Item,
|
||||
//
|
||||
Root as RadioGroup,
|
||||
Input as RadioGroupInput,
|
||||
Item as RadioGroupItem
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
<script lang="ts">
|
||||
import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
|
||||
import { Circle } from "lucide-svelte";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = RadioGroupPrimitive.ItemProps;
|
||||
type $$Events = RadioGroupPrimitive.ItemEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let value: $$Props["value"];
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<RadioGroupPrimitive.Item
|
||||
{value}
|
||||
class={cn(
|
||||
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
>
|
||||
<div class="flex items-center justify-center">
|
||||
<RadioGroupPrimitive.ItemIndicator>
|
||||
<Circle class="h-2.5 w-2.5 fill-current text-current" />
|
||||
</RadioGroupPrimitive.ItemIndicator>
|
||||
</div>
|
||||
</RadioGroupPrimitive.Item>
|
|
@ -0,0 +1,18 @@
|
|||
<script lang="ts">
|
||||
import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = RadioGroupPrimitive.Props;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let value: $$Props["value"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<RadioGroupPrimitive.Root
|
||||
bind:value
|
||||
class={cn("grid gap-2", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</RadioGroupPrimitive.Root>
|
|
@ -0,0 +1,34 @@
|
|||
import { Select as SelectPrimitive } from "bits-ui";
|
||||
|
||||
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 Root = SelectPrimitive.Root;
|
||||
const Group = SelectPrimitive.Group;
|
||||
const Input = SelectPrimitive.Input;
|
||||
const Value = SelectPrimitive.Value;
|
||||
|
||||
export {
|
||||
Root,
|
||||
Group,
|
||||
Input,
|
||||
Label,
|
||||
Item,
|
||||
Value,
|
||||
Content,
|
||||
Trigger,
|
||||
Separator,
|
||||
//
|
||||
Root as Select,
|
||||
Group as SelectGroup,
|
||||
Input as SelectInput,
|
||||
Label as SelectLabel,
|
||||
Item as SelectItem,
|
||||
Value as SelectValue,
|
||||
Content as SelectContent,
|
||||
Trigger as SelectTrigger,
|
||||
Separator as SelectSeparator
|
||||
};
|
|
@ -0,0 +1,39 @@
|
|||
<script lang="ts">
|
||||
import { Select as SelectPrimitive } from "bits-ui";
|
||||
import { cn, flyAndScale } from "$lib/utils";
|
||||
import { scale } from "svelte/transition";
|
||||
|
||||
type $$Props = SelectPrimitive.ContentProps;
|
||||
type $$Events = SelectPrimitive.ContentEvents;
|
||||
|
||||
export let sideOffset: $$Props["sideOffset"] = 4;
|
||||
export let inTransition: $$Props["inTransition"] = flyAndScale;
|
||||
export let inTransitionConfig: $$Props["inTransitionConfig"] = undefined;
|
||||
export let outTransition: $$Props["outTransition"] = scale;
|
||||
export let outTransitionConfig: $$Props["outTransitionConfig"] = {
|
||||
start: 0.95,
|
||||
opacity: 0,
|
||||
duration: 50
|
||||
};
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<SelectPrimitive.Content
|
||||
{inTransition}
|
||||
{inTransitionConfig}
|
||||
{outTransition}
|
||||
{outTransitionConfig}
|
||||
{sideOffset}
|
||||
class={cn(
|
||||
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md outline-none",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:keydown
|
||||
>
|
||||
<div class="w-full p-1">
|
||||
<slot />
|
||||
</div>
|
||||
</SelectPrimitive.Content>
|
|
@ -0,0 +1,38 @@
|
|||
<script lang="ts">
|
||||
import { cn } from "$lib/utils";
|
||||
import { Select as SelectPrimitive } from "bits-ui";
|
||||
import { Check } from "lucide-svelte";
|
||||
|
||||
type $$Props = SelectPrimitive.ItemProps;
|
||||
type $$Events = SelectPrimitive.ItemEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let value: $$Props["value"];
|
||||
export let label: $$Props["label"] = undefined;
|
||||
export let disabled: $$Props["disabled"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<SelectPrimitive.Item
|
||||
{value}
|
||||
{disabled}
|
||||
{label}
|
||||
class={cn(
|
||||
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
on:click
|
||||
on:keydown
|
||||
on:focusin
|
||||
on:focusout
|
||||
on:pointerleave
|
||||
on:pointermove
|
||||
>
|
||||
<span class="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<SelectPrimitive.ItemIndicator>
|
||||
<Check class="h-4 w-4" />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
</span>
|
||||
<slot />
|
||||
</SelectPrimitive.Item>
|
|
@ -0,0 +1,16 @@
|
|||
<script lang="ts">
|
||||
import { Select as SelectPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = SelectPrimitive.LabelProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<SelectPrimitive.Label
|
||||
class={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</SelectPrimitive.Label>
|
|
@ -0,0 +1,14 @@
|
|||
<script lang="ts">
|
||||
import { Select as SelectPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = SelectPrimitive.SeparatorProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<SelectPrimitive.Separator
|
||||
class={cn("-mx-1 my-1 h-px bg-muted", className)}
|
||||
{...$$restProps}
|
||||
/>
|
|
@ -0,0 +1,27 @@
|
|||
<script lang="ts">
|
||||
import { Select as SelectPrimitive } from "bits-ui";
|
||||
import { ChevronDown } from "lucide-svelte";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = SelectPrimitive.TriggerProps;
|
||||
type $$Events = SelectPrimitive.TriggerEvents;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<SelectPrimitive.Trigger
|
||||
class={cn(
|
||||
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
let:builder
|
||||
on:click
|
||||
on:keydown
|
||||
>
|
||||
<slot {builder} />
|
||||
<div>
|
||||
<ChevronDown class="h-4 w-4 opacity-50" />
|
||||
</div>
|
||||
</SelectPrimitive.Trigger>
|
|
@ -0,0 +1,7 @@
|
|||
import Root from "./switch.svelte";
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Switch
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
<script lang="ts">
|
||||
import { Switch as SwitchPrimitive } from "bits-ui";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = SwitchPrimitive.Props;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let checked: $$Props["checked"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<SwitchPrimitive.Root
|
||||
bind:checked
|
||||
class={cn(
|
||||
"peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<SwitchPrimitive.Thumb
|
||||
class={cn(
|
||||
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
|
||||
)}
|
||||
/>
|
||||
</SwitchPrimitive.Root>
|
|
@ -0,0 +1,28 @@
|
|||
import Root from "./textarea.svelte";
|
||||
|
||||
type FormTextareaEvent<T extends Event = Event> = T & {
|
||||
currentTarget: EventTarget & HTMLTextAreaElement;
|
||||
};
|
||||
|
||||
type TextareaEvents = {
|
||||
blur: FormTextareaEvent<FocusEvent>;
|
||||
change: FormTextareaEvent<Event>;
|
||||
click: FormTextareaEvent<MouseEvent>;
|
||||
focus: FormTextareaEvent<FocusEvent>;
|
||||
keydown: FormTextareaEvent<KeyboardEvent>;
|
||||
keypress: FormTextareaEvent<KeyboardEvent>;
|
||||
keyup: FormTextareaEvent<KeyboardEvent>;
|
||||
mouseover: FormTextareaEvent<MouseEvent>;
|
||||
mouseenter: FormTextareaEvent<MouseEvent>;
|
||||
mouseleave: FormTextareaEvent<MouseEvent>;
|
||||
paste: FormTextareaEvent<ClipboardEvent>;
|
||||
input: FormTextareaEvent<InputEvent>;
|
||||
};
|
||||
|
||||
export {
|
||||
Root,
|
||||
//
|
||||
Root as Textarea,
|
||||
type TextareaEvents,
|
||||
type FormTextareaEvent
|
||||
};
|
|
@ -0,0 +1,31 @@
|
|||
<script lang="ts">
|
||||
import type { HTMLTextareaAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = HTMLTextareaAttributes;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let value: $$Props["value"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<textarea
|
||||
class={cn(
|
||||
"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
bind:value
|
||||
on:blur
|
||||
on:change
|
||||
on:click
|
||||
on:focus
|
||||
on:keydown
|
||||
on:keypress
|
||||
on:keyup
|
||||
on:mouseover
|
||||
on:mouseenter
|
||||
on:mouseleave
|
||||
on:paste
|
||||
on:input
|
||||
{...$$restProps}
|
||||
/>
|
|
@ -1,33 +1,139 @@
|
|||
<script lang="ts">
|
||||
import { env } from "$env/dynamic/public";
|
||||
import { env } from '$env/dynamic/public';
|
||||
import { CheckCircle, XCircle } from 'lucide-svelte';
|
||||
|
||||
let public_base_url_set = Object.keys(env).includes("PUBLIC_BASE_URL");
|
||||
const public_base_url_set = Object.keys(env).includes('PUBLIC_BASE_URL');
|
||||
const public_session_token_expiry_time_set = Object.keys(env).includes('PUBLIC_SESSION_TOKEN_EXPIRY_TIME');
|
||||
const public_auth_token_expiry_time_set = Object.keys(env).includes('PUBLIC_AUTH_TOKEN_EXPIRY_TIME');
|
||||
|
||||
const config_ok = public_base_url_set && public_auth_token_expiry_time_set && public_session_token_expiry_time_set;
|
||||
</script>
|
||||
|
||||
<div class="w-screen h-screen p-4">
|
||||
<h1 class="scroll-m-20 text-3xl font-extrabold tracking-tight lg:text-4xl">
|
||||
Welcome to Trifid!
|
||||
</h1>
|
||||
{#if public_base_url_set}
|
||||
{#if config_ok}
|
||||
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||
If you're seeing this page, Trifid's web interface is <b
|
||||
class="font-medium text-green-400 underline underline-offset-4">correctly configured</b> and ready to
|
||||
class="font-medium text-green-400 underline underline-offset-4">correctly configured</b> and ready to
|
||||
go! Perhaps you meant to visit the <a class="font-medium text-primary underline underline-offset-4"
|
||||
href="/dashboard">dashboard</a>, or read the <a
|
||||
class="font-medium text-primary underline underline-offset-4"
|
||||
href="https://trifid.e3t.cc">documentation</a>.
|
||||
class="font-medium text-primary underline underline-offset-4"
|
||||
href="https://trifid.e3t.cc">documentation</a>.
|
||||
</p>
|
||||
{:else}
|
||||
<p class="leading-7 [&:not(:first-child)]:mt-6">
|
||||
If you're seeing this page, Trifid's web interface is installed and running, but <b
|
||||
class="font-medium text-yellow-400 underline underline-offset-4">not correctly configured.</b> The <code
|
||||
class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">PUBLIC_BASE_URL</code>
|
||||
environment variable is not set. Set this variable to the publicly accessible base URL of your trifid-api
|
||||
instance, and restart the web interface. Reload this page once you are done. Consult the <a
|
||||
class="font-medium text-primary underline underline-offset-4"
|
||||
href="https://trifid.e3t.cc">documentation</a> for more information.
|
||||
class="font-medium text-yellow-400 underline underline-offset-4">not correctly configured.</b> One or more
|
||||
environment variables are not set. See the table below for what variables need to be updated. Reload this
|
||||
page once you are done. Consult the <a
|
||||
class="font-medium text-primary underline underline-offset-4"
|
||||
href="https://trifid.e3t.cc">documentation</a> for more information.
|
||||
</p>
|
||||
{/if}
|
||||
<div class="my-6 w-full overflow-y-auto">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="m-0 border-t p-0">
|
||||
<th
|
||||
class="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||
>
|
||||
Environment Variable
|
||||
</th>
|
||||
<th
|
||||
class="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||
>
|
||||
Set?
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="m-0 border-t p-0">
|
||||
<td
|
||||
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||
>
|
||||
<code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">
|
||||
PUBLIC_BASE_URL
|
||||
</code>
|
||||
</td>
|
||||
<td
|
||||
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||
>
|
||||
{#if public_base_url_set}
|
||||
<span class="text-green-500"><CheckCircle /></span>
|
||||
{:else}
|
||||
<span>
|
||||
<span class="text-red-500 align-middle display-inline-block">
|
||||
<XCircle />
|
||||
</span>
|
||||
<span class="text-red-500 align-middle display-inline-block">
|
||||
Set <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">PUBLIC_BASE_URL</code> to the publicly accessible root URL of your API server.
|
||||
</span>
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="m-0 border-t p-0">
|
||||
<td
|
||||
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||
>
|
||||
<code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">
|
||||
PUBLIC_SESSION_TOKEN_EXPIRY_TIME
|
||||
</code>
|
||||
</td>
|
||||
<td
|
||||
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||
>
|
||||
{#if public_session_token_expiry_time_set}
|
||||
<span class="text-green-500"><CheckCircle /></span>
|
||||
{:else}
|
||||
<span>
|
||||
<span class="text-red-500 align-middle display-inline-block">
|
||||
<XCircle />
|
||||
</span>
|
||||
<span class="text-red-500 align-middle display-inline-block">
|
||||
Set <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">PUBLIC_SESSION_TOKEN_EXPIRY_TIME</code> to the same value you set in <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">tokens.session_token_expiry_seconds</code> in your trifid-api config.
|
||||
</span>
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="m-0 border-t p-0">
|
||||
<td
|
||||
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||
>
|
||||
<code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">
|
||||
PUBLIC_AUTH_TOKEN_EXPIRY_TIME
|
||||
</code>
|
||||
</td>
|
||||
<td
|
||||
class="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right"
|
||||
>
|
||||
{#if public_auth_token_expiry_time_set}
|
||||
<span class="text-green-500"><CheckCircle /></span>
|
||||
{:else}
|
||||
<span>
|
||||
<span class="text-red-500 align-middle display-inline-block">
|
||||
<XCircle />
|
||||
</span>
|
||||
<span class="text-red-500 align-middle display-inline-block">
|
||||
Set <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">PUBLIC_AUTH_TOKEN_EXPIRY_TIME</code> to the same value you set in <code class="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">tokens.auth_token_expiry_seconds</code> in your trifid-api config.
|
||||
</span>
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<style lang="postcss">
|
||||
:global(.lucide) {
|
||||
display: inline-block !important;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,16 @@
|
|||
import { redirect } from "@sveltejs/kit";
|
||||
import { env } from "$env/dynamic/public";
|
||||
|
||||
export function load({ cookies, fetch }) {
|
||||
const session = cookies.get("tfsession");
|
||||
if (session === undefined) {
|
||||
redirect(301, "/login");
|
||||
}
|
||||
|
||||
const mfa = cookies.get("tfmfa");
|
||||
if (mfa === undefined) {
|
||||
redirect(301, "/mfa");
|
||||
}
|
||||
|
||||
fetch(`${env.PUBLIC_BASE_URL}/`)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
<slot></slot>
|
|
@ -0,0 +1,61 @@
|
|||
import { redirect, fail } from "@sveltejs/kit";
|
||||
import type { PageServerLoad, Actions } from "./$types";
|
||||
import { superValidate, setError } from "sveltekit-superforms/server";
|
||||
import { formSchema } from "./schema";
|
||||
import { env } from "$env/dynamic/public";
|
||||
|
||||
export const load: PageServerLoad = async ({cookies}) => {
|
||||
const session = cookies.get("tfsession");
|
||||
const mfa = cookies.get("tfmfa");
|
||||
if (session !== undefined) {
|
||||
if (mfa === undefined) {
|
||||
redirect(301, "/mfa");
|
||||
} else {
|
||||
redirect(301, "/login");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
form: await superValidate(formSchema)
|
||||
};
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
default: async (event) => {
|
||||
const form = await superValidate(event, formSchema);
|
||||
if (!form.valid) {
|
||||
return fail(400, {form});
|
||||
}
|
||||
|
||||
let resp;
|
||||
|
||||
try {
|
||||
resp = await fetch(`${env.PUBLIC_BASE_URL}/v1/auth/magic-link`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: form.data.username
|
||||
})
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setError(form, 'username', `Error contacting the API: ${e}`);
|
||||
return fail(500, { form });
|
||||
}
|
||||
|
||||
if (!resp.ok) {
|
||||
let resp2 = await resp.json();
|
||||
|
||||
if (resp2.errors[0].code === "ERR_INVALID_EMAIL") {
|
||||
return setError(form, 'username', 'User does not exist');
|
||||
} else {
|
||||
setError(form, 'username', `Server returned error response: ${resp2.errors[0].code} ${resp2.errors[0].message}`);
|
||||
return fail(resp.code, { form });
|
||||
}
|
||||
}
|
||||
|
||||
redirect(301, "/login/sent");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<script lang="ts">
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import * as Form from '$lib/components/ui/form';
|
||||
import type { PageData } from './$types';
|
||||
import { formSchema, type FormSchema } from './schema';
|
||||
import type { SuperValidated } from 'sveltekit-superforms';
|
||||
|
||||
export let data;
|
||||
</script>
|
||||
|
||||
<div class="h-screen flex flex-col p-6 space-y-4 items-center justify-center">
|
||||
<Card.Root class="w-[20em] justify-center content-center pt-5">
|
||||
<Card.Header class="space-y-2 pb-0 pt-0">
|
||||
<Card.Title>Login via email</Card.Title>
|
||||
<Card.Description>Enter your email address, and we'll send you a link to log in.</Card.Description>
|
||||
</Card.Header>
|
||||
<Card.Content class="mt-2">
|
||||
<Form.Root method="POST" form={data.form} schema={formSchema} let:config>
|
||||
<Form.Field {config} name="username">
|
||||
<Form.Item>
|
||||
<Form.Label>Email</Form.Label>
|
||||
<Form.Input placeholder="john.doe@yourdomain.com" />
|
||||
<Form.Description>The email your Trifid account is associated with.</Form.Description>
|
||||
<Form.Validation />
|
||||
</Form.Item>
|
||||
</Form.Field>
|
||||
<Form.Button class="mt-2">Login</Form.Button>
|
||||
</Form.Root>
|
||||
</Card.Content>
|
||||
<Card.Footer>
|
||||
<span class="text-xs text-foreground/70">Don't have an account? <a
|
||||
class="font-medium text-primary underline underline-offset-4" href="/signup">Create one!</a></span>
|
||||
</Card.Footer>
|
||||
</Card.Root>
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export const formSchema = z.object({
|
||||
username: z.string().email()
|
||||
});
|
||||
|
||||
export type FormSchema = typeof formSchema;
|
|
@ -0,0 +1,16 @@
|
|||
<script lang="ts">
|
||||
import * as Card from "$lib/components/ui/card";
|
||||
</script>
|
||||
|
||||
<div class="h-screen flex flex-col p-6 space-y-4 items-center justify-center">
|
||||
<Card.Root class="w-[20em] justify-center content-center pt-5">
|
||||
<Card.Header class="space-y-2 pb-0 pt-0">
|
||||
<Card.Title>Check your inbox</Card.Title>
|
||||
<Card.Description>We sent you an email to finish logging in. Click the link in the email to complete the login process.</Card.Description>
|
||||
</Card.Header>
|
||||
<Card.Content class="mt-2">
|
||||
<span class="text-xs text-foreground/70">Didn't get an email? <a
|
||||
class="font-medium text-primary underline underline-offset-4" href="/login">Try again</a></span>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
</div>
|
|
@ -0,0 +1,61 @@
|
|||
import { redirect, fail } from "@sveltejs/kit";
|
||||
import type { PageServerLoad, Actions } from "./$types";
|
||||
import { superValidate, setError } from "sveltekit-superforms/server";
|
||||
import { formSchema } from "./schema";
|
||||
import { env } from "$env/dynamic/public";
|
||||
|
||||
export const load: PageServerLoad = async ({cookies}) => {
|
||||
const session = cookies.get("tfsession");
|
||||
const mfa = cookies.get("tfmfa");
|
||||
if (session !== undefined) {
|
||||
if (mfa === undefined) {
|
||||
redirect(301, "/mfa");
|
||||
} else {
|
||||
redirect(301, "/login");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
form: await superValidate(formSchema)
|
||||
};
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
default: async (event) => {
|
||||
const form = await superValidate(event, formSchema);
|
||||
if (!form.valid) {
|
||||
return fail(400, {form});
|
||||
}
|
||||
|
||||
let resp;
|
||||
|
||||
try {
|
||||
resp = await fetch(`${env.PUBLIC_BASE_URL}/v1/signup`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: form.data.username
|
||||
})
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setError(form, 'username', `Error contacting the API: ${e}`);
|
||||
return fail(500, { form });
|
||||
}
|
||||
|
||||
if (!resp.ok) {
|
||||
let resp2 = await resp.json();
|
||||
|
||||
if (resp2.errors[0].code === "ERR_INVALID_EMAIL") {
|
||||
return setError(form, 'username', 'User does not exist');
|
||||
} else {
|
||||
setError(form, 'username', `Server returned error response: ${resp2.errors[0].code} ${resp2.errors[0].message}`);
|
||||
return fail(resp.code, { form });
|
||||
}
|
||||
}
|
||||
|
||||
redirect(301, "/signup/sent");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<script lang="ts">
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import * as Form from '$lib/components/ui/form';
|
||||
import type { PageData } from './$types';
|
||||
import { formSchema, type FormSchema } from './schema';
|
||||
import type { SuperValidated } from 'sveltekit-superforms';
|
||||
|
||||
export let data;
|
||||
</script>
|
||||
|
||||
<div class="h-screen flex flex-col p-6 space-y-4 items-center justify-center">
|
||||
<Card.Root class="w-[20em] justify-center content-center pt-5">
|
||||
<Card.Header class="space-y-2 pb-0 pt-0">
|
||||
<Card.Title>Sign up with email</Card.Title>
|
||||
<Card.Description>Enter your email address, and we'll send you a link to finish creating your account.</Card.Description>
|
||||
</Card.Header>
|
||||
<Card.Content class="mt-2">
|
||||
<Form.Root method="POST" form={data.form} schema={formSchema} let:config>
|
||||
<Form.Field {config} name="username">
|
||||
<Form.Item>
|
||||
<Form.Label>Email</Form.Label>
|
||||
<Form.Input placeholder="john.doe@yourdomain.com" />
|
||||
<Form.Description>The email to create your Trifid account with.</Form.Description>
|
||||
<Form.Validation />
|
||||
</Form.Item>
|
||||
</Form.Field>
|
||||
<Form.Button class="mt-2">Login</Form.Button>
|
||||
</Form.Root>
|
||||
</Card.Content>
|
||||
<Card.Footer>
|
||||
<span class="text-xs text-foreground/70">Already have an account? <a
|
||||
class="font-medium text-primary underline underline-offset-4" href="/login">Log in!</a></span>
|
||||
</Card.Footer>
|
||||
</Card.Root>
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export const formSchema = z.object({
|
||||
username: z.string().email()
|
||||
});
|
||||
|
||||
export type FormSchema = typeof formSchema;
|
|
@ -0,0 +1,16 @@
|
|||
<script lang="ts">
|
||||
import * as Card from "$lib/components/ui/card";
|
||||
</script>
|
||||
|
||||
<div class="h-screen flex flex-col p-6 space-y-4 items-center justify-center">
|
||||
<Card.Root class="w-[20em] justify-center content-center pt-5">
|
||||
<Card.Header class="space-y-2 pb-0 pt-0">
|
||||
<Card.Title>Check your inbox</Card.Title>
|
||||
<Card.Description>We sent you an email to finish signup. Click the link in the email to complete the registration process.</Card.Description>
|
||||
</Card.Header>
|
||||
<Card.Content class="mt-2">
|
||||
<span class="text-xs text-foreground/70">Didn't get an email? <a
|
||||
class="font-medium text-primary underline underline-offset-4" href="/signup">Try again</a></span>
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
</div>
|
|
@ -6,7 +6,7 @@
|
|||
# [server] contains options for the HTTP server used to serve the API.
|
||||
[server]
|
||||
# (Required) What IP and port to bind the HTTP listener to.
|
||||
bind = { ip = "127.0.0.1", port = 8080 }
|
||||
bind = { ip = "::", port = 8080 }
|
||||
# How many worker threads to start. The higher the number, the more resources trifid-api will use while idle, but
|
||||
# the more parallel requests it can handle.
|
||||
# Optional. Defaults to the number of physical CPUs in the system.
|
||||
|
@ -49,4 +49,4 @@ auth_token_expiry_seconds = 86400 # 24 hours
|
|||
# (Required) (VERY IMPORTANT!) The per-instance encryption key used to encrypt sensitive data in the database.
|
||||
# It is INCREDIBLY IMPORTANT that you change this value! It should be a 32-byte/256-bit hex-encoded randomly generated
|
||||
# key.
|
||||
data_encryption_key = "dd5aa62f0fd9b7fb4ff65567493f889557212f3a8e9587a79268161f9ae070a6"
|
||||
data_encryption_key = "dd5aa62f0fd9b7fb4ff65567493f889557212f3a8e9587a79268161f9ae070a6"
|
||||
|
|
|
@ -66,7 +66,7 @@ pub fn create_signing_ca(
|
|||
.map_err(|e| CryptographyError::PemSerializeError(e))?;
|
||||
|
||||
let cert_value =
|
||||
serde_json::to_value(cert).map_err(|e| CryptographyError::JsonSerializeError(e))?;
|
||||
serde_json::to_value(&cert).map_err(|e| CryptographyError::JsonSerializeError(e))?;
|
||||
|
||||
let lockbox_key = XChaCha20Poly1305::new_from_slice(
|
||||
&hex::decode(&config.tokens.data_encryption_key)
|
||||
|
@ -112,7 +112,7 @@ pub fn sign_cert_with_ca(
|
|||
.map_err(|_| CryptographyError::InvalidKeyLength)?;
|
||||
|
||||
let salt_u24: [u8; 24] = ca
|
||||
.salt
|
||||
.salt.clone()
|
||||
.try_into()
|
||||
.map_err(|_| CryptographyError::InvalidSaltLength)?;
|
||||
|
||||
|
|
Loading…
Reference in New Issue