Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ea561f635a | |||
| 1f180a2e53 | |||
| 6b29c6f069 | |||
| 781231e414 | |||
| bb422fdd8d |
@@ -80,6 +80,7 @@ of the notes even if it tried to.
|
|||||||
| `ALLOW_ADVANCED` | `true` | Allow custom configuration. If set to `false` all notes will be one view only. |
|
| `ALLOW_ADVANCED` | `true` | Allow custom configuration. If set to `false` all notes will be one view only. |
|
||||||
| `ALLOW_FILES` | `true` | Allow uploading files. If set to `false`, users will only be allowed to create text notes. |
|
| `ALLOW_FILES` | `true` | Allow uploading files. If set to `false`, users will only be allowed to create text notes. |
|
||||||
| `ID_LENGTH` | `32` | Set the size of the note `id` in bytes. By default this is `32` bytes. This is useful for reducing link size. _This setting does not affect encryption strength_. |
|
| `ID_LENGTH` | `32` | Set the size of the note `id` in bytes. By default this is `32` bytes. This is useful for reducing link size. _This setting does not affect encryption strength_. |
|
||||||
|
| `REDIS_PREFIX` | `""` | Optional prefix for all Redis keys. Useful when sharing a Redis instance with other apps via ACL namespaces. |
|
||||||
| `VERBOSITY` | `warn` | Verbosity level for the backend. [Possible values](https://docs.rs/env_logger/latest/env_logger/#enabling-logging) are: `error`, `warn`, `info`, `debug`, `trace` |
|
| `VERBOSITY` | `warn` | Verbosity level for the backend. [Possible values](https://docs.rs/env_logger/latest/env_logger/#enabling-logging) are: `error`, `warn`, `info`, `debug`, `trace` |
|
||||||
| `THEME_IMAGE` | `""` | Custom image for replacing the logo. Must be publicly reachable |
|
| `THEME_IMAGE` | `""` | Custom image for replacing the logo. Must be publicly reachable |
|
||||||
| `THEME_TEXT` | `""` | Custom text for replacing the description below the logo |
|
| `THEME_TEXT` | `""` | Custom text for replacing the description below the logo |
|
||||||
@@ -89,6 +90,7 @@ of the notes even if it tried to.
|
|||||||
| `THEME_HOME_LINK` | `true` | Show the `/home` link in the footer. Defaults to `true`. |
|
| `THEME_HOME_LINK` | `true` | Show the `/home` link in the footer. Defaults to `true`. |
|
||||||
| `IMPRINT_URL` | `""` | Custom url for an Imprint hosted somewhere else. Must be publicly reachable. Takes precedence above `IMPRINT_HTML`. |
|
| `IMPRINT_URL` | `""` | Custom url for an Imprint hosted somewhere else. Must be publicly reachable. Takes precedence above `IMPRINT_HTML`. |
|
||||||
| `IMPRINT_HTML` | `""` | Alternative to `IMPRINT_URL`, this can be used to specify the HTML code to show on `/imprint`. Only `IMPRINT_HTML` or `IMPRINT_URL` should be specified, not both. |
|
| `IMPRINT_HTML` | `""` | Alternative to `IMPRINT_URL`, this can be used to specify the HTML code to show on `/imprint`. Only `IMPRINT_HTML` or `IMPRINT_URL` should be specified, not both. |
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
> ℹ️ `https` is required otherwise browsers will not support the cryptographic functions.
|
> ℹ️ `https` is required otherwise browsers will not support the cryptographic functions.
|
||||||
@@ -102,7 +104,7 @@ Docker is the easiest way. There is the [official image here](https://hub.docker
|
|||||||
```yaml
|
```yaml
|
||||||
# docker-compose.yml
|
# docker-compose.yml
|
||||||
|
|
||||||
version: '3.8'
|
version: "3.8"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
"redis",
|
"redis",
|
||||||
"ring",
|
"ring",
|
||||||
|
"rmp-serde",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
@@ -1004,6 +1005,25 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rmp"
|
||||||
|
version = "0.8.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rmp-serde"
|
||||||
|
version = "1.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
|
||||||
|
dependencies = [
|
||||||
|
"rmp",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
|
|||||||
@@ -25,3 +25,4 @@ ring = "0.17"
|
|||||||
bs62 = "0.1"
|
bs62 = "0.1"
|
||||||
byte-unit = "4"
|
byte-unit = "4"
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
|
rmp-serde = "1.3.1"
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ pub static ref ID_LENGTH: u32 = std::env::var("ID_LENGTH")
|
|||||||
.unwrap_or("32".to_string())
|
.unwrap_or("32".to_string())
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
pub static ref REDIS_PREFIX: String = std::env::var("REDIS_PREFIX")
|
||||||
|
.unwrap_or("".to_string())
|
||||||
|
.parse()
|
||||||
|
.unwrap();
|
||||||
pub static ref ALLOW_FILES: bool = std::env::var("ALLOW_FILES")
|
pub static ref ALLOW_FILES: bool = std::env::var("ALLOW_FILES")
|
||||||
.unwrap_or("true".to_string())
|
.unwrap_or("true".to_string())
|
||||||
.parse()
|
.parse()
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ mod csp;
|
|||||||
mod health;
|
mod health;
|
||||||
mod lock;
|
mod lock;
|
||||||
mod note;
|
mod note;
|
||||||
|
mod note_v2;
|
||||||
mod status;
|
mod status;
|
||||||
mod store;
|
mod store;
|
||||||
|
|
||||||
@@ -42,7 +43,8 @@ async fn main() {
|
|||||||
let notes_routes = Router::new()
|
let notes_routes = Router::new()
|
||||||
.route("/", post(note::create))
|
.route("/", post(note::create))
|
||||||
.route("/{id}", delete(note::delete))
|
.route("/{id}", delete(note::delete))
|
||||||
.route("/{id}", get(note::preview));
|
.route("/{id}", get(note::preview))
|
||||||
|
.route("/v2/", post(note_v2::create));
|
||||||
let health_routes = Router::new().route("/live", get(health::report_health));
|
let health_routes = Router::new().route("/live", get(health::report_health));
|
||||||
let status_routes = Router::new().route("/status", get(status::get_status));
|
let status_routes = Router::new().route("/status", get(status::get_status));
|
||||||
let api_routes = Router::new()
|
let api_routes = Router::new()
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
mod model;
|
||||||
|
mod routes;
|
||||||
|
|
||||||
|
pub use model::*;
|
||||||
|
pub use routes::*;
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
use bs62;
|
||||||
|
use ring::rand::SecureRandom;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct NoteV2Metadata {
|
||||||
|
pub views: Option<u32>,
|
||||||
|
pub expiration: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct NoteV2 {
|
||||||
|
pub metadata: NoteV2Metadata,
|
||||||
|
pub public: String,
|
||||||
|
pub content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct NoteInfoV2 {
|
||||||
|
pub public: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct NotePublicV2 {
|
||||||
|
pub public: String,
|
||||||
|
pub content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_id_v2() -> String {
|
||||||
|
let mut result = "".to_owned();
|
||||||
|
let mut id: [u8; 1] = [0; 1];
|
||||||
|
let sr = ring::rand::SystemRandom::new();
|
||||||
|
|
||||||
|
for _ in 0..*config::ID_LENGTH {
|
||||||
|
let _ = sr.fill(&mut id);
|
||||||
|
result.push_str(&bs62::encode_data(&id));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
use axum::{
|
||||||
|
Json,
|
||||||
|
body::Bytes,
|
||||||
|
extract::Path,
|
||||||
|
http::StatusCode,
|
||||||
|
response::{IntoResponse, Response},
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::{sync::Arc, time::SystemTime};
|
||||||
|
|
||||||
|
use crate::note_v2::{NoteV2, generate_id_v2};
|
||||||
|
use crate::store;
|
||||||
|
use crate::{config, lock::SharedState};
|
||||||
|
|
||||||
|
use super::NotePublicV2;
|
||||||
|
|
||||||
|
pub fn now() -> u32 {
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[derive(Deserialize)]
|
||||||
|
// pub struct OneNoteParams {
|
||||||
|
// id: String,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub async fn preview(Path(OneNoteParams { id }): Path<OneNoteParams>) -> Response {
|
||||||
|
// let note = store::get(&id);
|
||||||
|
|
||||||
|
// match note {
|
||||||
|
// Ok(Some(n)) => (StatusCode::OK, Json(NoteInfoV2 { meta: n.meta })).into_response(),
|
||||||
|
// Ok(None) => (StatusCode::NOT_FOUND).into_response(),
|
||||||
|
// Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response(),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct CreateResponse {
|
||||||
|
id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create(body: Bytes) -> Response {
|
||||||
|
let id = generate_id_v2();
|
||||||
|
println!("{}", body.len());
|
||||||
|
(StatusCode::OK, Json(CreateResponse { id })).into_response()
|
||||||
|
// match store::set(&id.clone(), &n.clone()) {
|
||||||
|
// Ok(_) => (StatusCode::OK, Json(CreateResponse { id })).into_response(),
|
||||||
|
// Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response(),
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub async fn delete(
|
||||||
|
// Path(OneNoteParams { id }): Path<OneNoteParams>,
|
||||||
|
// state: axum::extract::State<SharedState>,
|
||||||
|
// ) -> Response {
|
||||||
|
// let mut locks_map = state.locks.lock().await;
|
||||||
|
// let lock = locks_map
|
||||||
|
// .entry(id.clone())
|
||||||
|
// .or_insert_with(|| Arc::new(Mutex::new(())))
|
||||||
|
// .clone();
|
||||||
|
// drop(locks_map);
|
||||||
|
// let _guard = lock.lock().await;
|
||||||
|
|
||||||
|
// let note = store::get(&id);
|
||||||
|
// match note {
|
||||||
|
// Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()).into_response(),
|
||||||
|
// Ok(None) => (StatusCode::NOT_FOUND).into_response(),
|
||||||
|
// Ok(Some(note)) => {
|
||||||
|
// let mut changed = note.clone();
|
||||||
|
// if changed.views == None && changed.expiration == None {
|
||||||
|
// return (StatusCode::BAD_REQUEST).into_response();
|
||||||
|
// }
|
||||||
|
// match changed.views {
|
||||||
|
// Some(v) => {
|
||||||
|
// changed.views = Some(v - 1);
|
||||||
|
// let id = id.clone();
|
||||||
|
// if v <= 1 {
|
||||||
|
// match store::del(&id) {
|
||||||
|
// Err(e) => {
|
||||||
|
// return (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
|
||||||
|
// .into_response();
|
||||||
|
// }
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// match store::set(&id, &changed.clone()) {
|
||||||
|
// Err(e) => {
|
||||||
|
// return (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
|
||||||
|
// .into_response();
|
||||||
|
// }
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let n = now();
|
||||||
|
// match changed.expiration {
|
||||||
|
// Some(e) => {
|
||||||
|
// if e < n {
|
||||||
|
// match store::del(&id.clone()) {
|
||||||
|
// Ok(_) => return (StatusCode::BAD_REQUEST).into_response(),
|
||||||
|
// Err(e) => {
|
||||||
|
// return (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
|
||||||
|
// .into_response();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// StatusCode::OK,
|
||||||
|
// Json(NotePublicV2 {
|
||||||
|
// content: changed.contents,
|
||||||
|
// public: changed.meta,
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
// .into_response();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
use redis;
|
use redis;
|
||||||
use redis::Commands;
|
use redis::Commands;
|
||||||
|
|
||||||
|
use crate::config;
|
||||||
use crate::note::now;
|
use crate::note::now;
|
||||||
use crate::note::Note;
|
use crate::note::Note;
|
||||||
|
|
||||||
@@ -11,6 +12,10 @@ lazy_static! {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn prefixed(id: &String) -> String {
|
||||||
|
format!("{}{}", config::REDIS_PREFIX.as_str(), id)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_connection() -> Result<redis::Connection, &'static str> {
|
fn get_connection() -> Result<redis::Connection, &'static str> {
|
||||||
let client =
|
let client =
|
||||||
redis::Client::open(REDIS_CLIENT.to_string()).map_err(|_| "Unable to connect to redis")?;
|
redis::Client::open(REDIS_CLIENT.to_string()).map_err(|_| "Unable to connect to redis")?;
|
||||||
@@ -28,15 +33,16 @@ pub fn can_reach_redis() -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(id: &String, note: &Note) -> Result<(), &'static str> {
|
pub fn set(id: &String, note: &Note) -> Result<(), &'static str> {
|
||||||
|
let key = prefixed(id);
|
||||||
let serialized = serde_json::to_string(¬e.clone()).unwrap();
|
let serialized = serde_json::to_string(¬e.clone()).unwrap();
|
||||||
let mut conn = get_connection()?;
|
let mut conn = get_connection()?;
|
||||||
|
|
||||||
conn.set::<_, _, ()>(id, serialized)
|
conn.set::<_, _, ()>(key.as_str(), serialized)
|
||||||
.map_err(|_| "Unable to set note in redis")?;
|
.map_err(|_| "Unable to set note in redis")?;
|
||||||
match note.expiration {
|
match note.expiration {
|
||||||
Some(e) => {
|
Some(e) => {
|
||||||
let seconds = e - now();
|
let seconds = e - now();
|
||||||
conn.expire::<_, ()>(id, seconds as i64)
|
conn.expire::<_, ()>(key.as_str(), seconds as i64)
|
||||||
.map_err(|_| "Unable to set expiration on note")?
|
.map_err(|_| "Unable to set expiration on note")?
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
@@ -45,8 +51,9 @@ pub fn set(id: &String, note: &Note) -> Result<(), &'static str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(id: &String) -> Result<Option<Note>, &'static str> {
|
pub fn get(id: &String) -> Result<Option<Note>, &'static str> {
|
||||||
|
let key = prefixed(id);
|
||||||
let mut conn = get_connection()?;
|
let mut conn = get_connection()?;
|
||||||
let value: Option<String> = conn.get(id).map_err(|_| "Could not load note in redis")?;
|
let value: Option<String> = conn.get(key.as_str()).map_err(|_| "Could not load note in redis")?;
|
||||||
match value {
|
match value {
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
@@ -57,7 +64,8 @@ pub fn get(id: &String) -> Result<Option<Note>, &'static str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn del(id: &String) -> Result<(), &'static str> {
|
pub fn del(id: &String) -> Result<(), &'static str> {
|
||||||
|
let key = prefixed(id);
|
||||||
let mut conn = get_connection()?;
|
let mut conn = get_connection()?;
|
||||||
conn.del::<_, ()>(id).map_err(|_| "Unable to delete note in redis")?;
|
conn.del::<_, ()>(key.as_str()).map_err(|_| "Unable to delete note in redis")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "@cryptgeon/shared",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
".": "./src/index.ts"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@msgpack/msgpack": "^3.1.3",
|
||||||
|
"@noble/ciphers": "^2.2.0",
|
||||||
|
"@noble/hashes": "^2.2.0",
|
||||||
|
"ky": "^2.0.2",
|
||||||
|
"zod": "^4.4.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tsconfig/strictest": "catalog:",
|
||||||
|
"@vitest/browser-playwright": "catalog:",
|
||||||
|
"typescript": "catalog:",
|
||||||
|
"vitest": "catalog:"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test:browser": "vitest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
@@ -0,0 +1,38 @@
|
|||||||
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||||
|
|
||||||
|
exports[`encryption > stable derive key 1`] = `
|
||||||
|
Uint8Array [
|
||||||
|
107,
|
||||||
|
115,
|
||||||
|
150,
|
||||||
|
59,
|
||||||
|
243,
|
||||||
|
162,
|
||||||
|
229,
|
||||||
|
9,
|
||||||
|
221,
|
||||||
|
235,
|
||||||
|
124,
|
||||||
|
184,
|
||||||
|
124,
|
||||||
|
51,
|
||||||
|
96,
|
||||||
|
32,
|
||||||
|
183,
|
||||||
|
240,
|
||||||
|
114,
|
||||||
|
43,
|
||||||
|
221,
|
||||||
|
208,
|
||||||
|
248,
|
||||||
|
142,
|
||||||
|
16,
|
||||||
|
45,
|
||||||
|
163,
|
||||||
|
137,
|
||||||
|
102,
|
||||||
|
240,
|
||||||
|
245,
|
||||||
|
198,
|
||||||
|
]
|
||||||
|
`;
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { upload } from "./actions";
|
||||||
|
import { deriveKey } from "./encryption";
|
||||||
|
|
||||||
|
describe("actions", () => {
|
||||||
|
describe("upload", () => {
|
||||||
|
it("upload", async () => {
|
||||||
|
const key = deriveKey("abc");
|
||||||
|
await expect(
|
||||||
|
upload({ public: "foo", metadata: { views: 1 }, files: [] }, key),
|
||||||
|
).resolves.toBe({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { encode } from "@msgpack/msgpack";
|
||||||
|
import { encrypt } from "./encryption";
|
||||||
|
import { ClientNote, ServerNote } from "./types";
|
||||||
|
import ky from "ky";
|
||||||
|
import z from "zod";
|
||||||
|
|
||||||
|
const client = ky.extend({ baseUrl: "http://localhost:8000/api" });
|
||||||
|
|
||||||
|
export async function upload(
|
||||||
|
note: ClientNote,
|
||||||
|
key: Uint8Array,
|
||||||
|
): Promise<string> {
|
||||||
|
const data = encode(note.files);
|
||||||
|
const encrypted = encrypt(data, key);
|
||||||
|
const serverNote: ServerNote = {
|
||||||
|
metadata: structuredClone(note.metadata),
|
||||||
|
public: "",
|
||||||
|
data: encrypted,
|
||||||
|
};
|
||||||
|
const payload = encode(serverNote);
|
||||||
|
const response = await client
|
||||||
|
.post("/notes/v2", {
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/msgpack",
|
||||||
|
},
|
||||||
|
body: new Blob([payload]).stream(),
|
||||||
|
})
|
||||||
|
.json(
|
||||||
|
z.object({
|
||||||
|
id: z.string().nonempty(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
console.info("created note", response);
|
||||||
|
throw new Error("not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
export function view(noteId: string): Promise<ClientNote> {
|
||||||
|
throw new Error("not implemented");
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import {
|
||||||
|
decrypt,
|
||||||
|
deriveKey,
|
||||||
|
encrypt,
|
||||||
|
generateKey,
|
||||||
|
utf8ToBytes,
|
||||||
|
} from "./encryption";
|
||||||
|
|
||||||
|
describe("encryption", () => {
|
||||||
|
it("chacha20 custom key", () => {
|
||||||
|
const password = "abc";
|
||||||
|
const payload = utf8ToBytes("libero iste qui");
|
||||||
|
|
||||||
|
const key = deriveKey(password);
|
||||||
|
const encrypted = encrypt(payload, key);
|
||||||
|
const decrypted = decrypt(encrypted, key);
|
||||||
|
expect(decrypted).toEqual(payload);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("chacha20 auto key", () => {
|
||||||
|
const payload = utf8ToBytes(
|
||||||
|
"Earum id inventore debitis rerum minima necessitatibus consequuntur.",
|
||||||
|
);
|
||||||
|
const key = generateKey();
|
||||||
|
const encrypted = encrypt(payload, key);
|
||||||
|
const decrypted = decrypt(encrypted, key);
|
||||||
|
expect(decrypted).toEqual(payload);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("stable derive key", () => {
|
||||||
|
const password = "alias laboriosam porro";
|
||||||
|
expect(deriveKey(password)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("derived key has same length as generated", () => {
|
||||||
|
const derived = deriveKey("ipsam esse asperiores");
|
||||||
|
const generated = generateKey();
|
||||||
|
|
||||||
|
expect(derived.length).toEqual(generated.length);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { xchacha20poly1305 } from "@noble/ciphers/chacha.js";
|
||||||
|
import {
|
||||||
|
managedNonce,
|
||||||
|
randomBytes,
|
||||||
|
utf8ToBytes,
|
||||||
|
} from "@noble/ciphers/utils.js";
|
||||||
|
import { scrypt } from "@noble/hashes/scrypt.js";
|
||||||
|
|
||||||
|
export { bytesToUtf8, utf8ToBytes } from "@noble/ciphers/utils.js";
|
||||||
|
|
||||||
|
const APP_SPECIFIC_SECRET = "758ac0b9d5f04efca13f57909d3d0fc0";
|
||||||
|
const SECURITY_LEVEL = 2 ** 15;
|
||||||
|
const KEY_SIZE = 32;
|
||||||
|
|
||||||
|
export function deriveKey(password: string) {
|
||||||
|
const key = scrypt(password, APP_SPECIFIC_SECRET, {
|
||||||
|
N: SECURITY_LEVEL,
|
||||||
|
r: 8,
|
||||||
|
p: 1,
|
||||||
|
dkLen: KEY_SIZE,
|
||||||
|
});
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateKey(): Uint8Array {
|
||||||
|
return randomBytes(KEY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function encrypt(payload: Uint8Array, key: Uint8Array): Uint8Array {
|
||||||
|
const chacha = managedNonce(xchacha20poly1305)(key);
|
||||||
|
const data = payload instanceof Uint8Array ? payload : utf8ToBytes(payload);
|
||||||
|
const ciphertext = chacha.encrypt(data);
|
||||||
|
return ciphertext;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decrypt(ciphertext: Uint8Array, key: Uint8Array): Uint8Array {
|
||||||
|
const chacha = managedNonce(xchacha20poly1305)(key);
|
||||||
|
const decrypted = chacha.decrypt(ciphertext, key);
|
||||||
|
return decrypted;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * as encryption from "./encryption";
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* `metadata` is public, and NOT encrypted
|
||||||
|
*/
|
||||||
|
export type NoteMetadata = {
|
||||||
|
expiration?: number;
|
||||||
|
views?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ClientNote = {
|
||||||
|
metadata: NoteMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public information
|
||||||
|
*/
|
||||||
|
public: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `files` are encrypted
|
||||||
|
*/
|
||||||
|
files: {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
content: Uint8Array;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ServerNote = {
|
||||||
|
metadata: NoteMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publicly available information
|
||||||
|
*/
|
||||||
|
public: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypted binary blob
|
||||||
|
*/
|
||||||
|
data: Uint8Array;
|
||||||
|
};
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"extends": ["@tsconfig/strictest"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { defineConfig } from "vitest/config";
|
||||||
|
import { playwright } from "@vitest/browser-playwright";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
projects: [
|
||||||
|
{ test: { name: "node", environment: "node" } },
|
||||||
|
{
|
||||||
|
test: {
|
||||||
|
name: "Browser",
|
||||||
|
browser: {
|
||||||
|
enabled: true,
|
||||||
|
provider: playwright(),
|
||||||
|
headless: true,
|
||||||
|
// https://vitest.dev/config/browser/playwright
|
||||||
|
instances: [
|
||||||
|
{ browser: "chromium" },
|
||||||
|
{ browser: "firefox" },
|
||||||
|
{ browser: "webkit" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -4,6 +4,21 @@ settings:
|
|||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
catalogs:
|
||||||
|
default:
|
||||||
|
'@tsconfig/strictest':
|
||||||
|
specifier: ^2.0.8
|
||||||
|
version: 2.0.8
|
||||||
|
'@vitest/browser-playwright':
|
||||||
|
specifier: ^4.1.7
|
||||||
|
version: 4.1.7
|
||||||
|
typescript:
|
||||||
|
specifier: ^6.0.3
|
||||||
|
version: 6.0.3
|
||||||
|
vitest:
|
||||||
|
specifier: ^4.1.7
|
||||||
|
version: 4.1.7
|
||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
@@ -120,6 +135,37 @@ importers:
|
|||||||
specifier: ^8.0.14
|
specifier: ^8.0.14
|
||||||
version: 8.0.14(@types/node@24.12.4)(esbuild@0.27.7)
|
version: 8.0.14(@types/node@24.12.4)(esbuild@0.27.7)
|
||||||
|
|
||||||
|
packages/shared:
|
||||||
|
dependencies:
|
||||||
|
'@msgpack/msgpack':
|
||||||
|
specifier: ^3.1.3
|
||||||
|
version: 3.1.3
|
||||||
|
'@noble/ciphers':
|
||||||
|
specifier: ^2.2.0
|
||||||
|
version: 2.2.0
|
||||||
|
'@noble/hashes':
|
||||||
|
specifier: ^2.2.0
|
||||||
|
version: 2.2.0
|
||||||
|
ky:
|
||||||
|
specifier: ^2.0.2
|
||||||
|
version: 2.0.2
|
||||||
|
zod:
|
||||||
|
specifier: ^4.4.3
|
||||||
|
version: 4.4.3
|
||||||
|
devDependencies:
|
||||||
|
'@tsconfig/strictest':
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 2.0.8
|
||||||
|
'@vitest/browser-playwright':
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 4.1.7(playwright@1.60.0)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))(vitest@4.1.7)
|
||||||
|
typescript:
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 6.0.3
|
||||||
|
vitest:
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 4.1.7(@types/node@24.12.4)(@vitest/browser-playwright@4.1.7)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
'@ampproject/remapping@2.3.0':
|
'@ampproject/remapping@2.3.0':
|
||||||
@@ -193,6 +239,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==}
|
resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@blazediff/core@1.9.1':
|
||||||
|
resolution: {integrity: sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA==}
|
||||||
|
|
||||||
'@commander-js/extra-typings@12.1.0':
|
'@commander-js/extra-typings@12.1.0':
|
||||||
resolution: {integrity: sha512-wf/lwQvWAA0goIghcb91dQYpkLBcyhOhQNqG/VgWhnKzgt+UOMvra7EX/2fv70arm5RW+PUHoQHHDa6/p77Eqg==}
|
resolution: {integrity: sha512-wf/lwQvWAA0goIghcb91dQYpkLBcyhOhQNqG/VgWhnKzgt+UOMvra7EX/2fv70arm5RW+PUHoQHHDa6/p77Eqg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -437,12 +486,24 @@ packages:
|
|||||||
resolution: {integrity: sha512-p5KAAp6qe16lVYyh+pgvgY7FvnlJ44ICa/jNLMB442F1BsTfaITa4zX1EhwWGqc0NDRxjBvNZPF0Hw6Rc2EClg==}
|
resolution: {integrity: sha512-p5KAAp6qe16lVYyh+pgvgY7FvnlJ44ICa/jNLMB442F1BsTfaITa4zX1EhwWGqc0NDRxjBvNZPF0Hw6Rc2EClg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
'@msgpack/msgpack@3.1.3':
|
||||||
|
resolution: {integrity: sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA==}
|
||||||
|
engines: {node: '>= 18'}
|
||||||
|
|
||||||
'@napi-rs/wasm-runtime@1.1.4':
|
'@napi-rs/wasm-runtime@1.1.4':
|
||||||
resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==}
|
resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@emnapi/core': ^1.7.1
|
'@emnapi/core': ^1.7.1
|
||||||
'@emnapi/runtime': ^1.7.1
|
'@emnapi/runtime': ^1.7.1
|
||||||
|
|
||||||
|
'@noble/ciphers@2.2.0':
|
||||||
|
resolution: {integrity: sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA==}
|
||||||
|
engines: {node: '>= 20.19.0'}
|
||||||
|
|
||||||
|
'@noble/hashes@2.2.0':
|
||||||
|
resolution: {integrity: sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==}
|
||||||
|
engines: {node: '>= 20.19.0'}
|
||||||
|
|
||||||
'@npmcli/agent@4.0.2':
|
'@npmcli/agent@4.0.2':
|
||||||
resolution: {integrity: sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==}
|
resolution: {integrity: sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==}
|
||||||
engines: {node: ^20.17.0 || >=22.9.0}
|
engines: {node: ^20.17.0 || >=22.9.0}
|
||||||
@@ -779,6 +840,9 @@ packages:
|
|||||||
svelte: ^5.46.4
|
svelte: ^5.46.4
|
||||||
vite: ^8.0.0-beta.7 || ^8.0.0
|
vite: ^8.0.0-beta.7 || ^8.0.0
|
||||||
|
|
||||||
|
'@tsconfig/strictest@2.0.8':
|
||||||
|
resolution: {integrity: sha512-XnQ7vNz5HRN0r88GYf1J9JJjqtZPiHt2woGJOo2dYqyHGGcd6OLGqSlBB6p1j9mpzja6Oe5BoPqWmeDx6X9rLw==}
|
||||||
|
|
||||||
'@tufjs/canonical-json@2.0.0':
|
'@tufjs/canonical-json@2.0.0':
|
||||||
resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==}
|
resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==}
|
||||||
engines: {node: ^16.14.0 || >=18.0.0}
|
engines: {node: ^16.14.0 || >=18.0.0}
|
||||||
@@ -790,12 +854,21 @@ packages:
|
|||||||
'@tybys/wasm-util@0.10.2':
|
'@tybys/wasm-util@0.10.2':
|
||||||
resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==}
|
resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==}
|
||||||
|
|
||||||
|
'@types/chai@5.2.3':
|
||||||
|
resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
|
||||||
|
|
||||||
'@types/cookie@0.6.0':
|
'@types/cookie@0.6.0':
|
||||||
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
||||||
|
|
||||||
|
'@types/deep-eql@4.0.2':
|
||||||
|
resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
|
||||||
|
|
||||||
'@types/estree@1.0.6':
|
'@types/estree@1.0.6':
|
||||||
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
|
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
|
||||||
|
|
||||||
|
'@types/estree@1.0.9':
|
||||||
|
resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
|
||||||
|
|
||||||
'@types/inquirer@9.0.9':
|
'@types/inquirer@9.0.9':
|
||||||
resolution: {integrity: sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==}
|
resolution: {integrity: sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==}
|
||||||
|
|
||||||
@@ -818,6 +891,46 @@ packages:
|
|||||||
'@types/trusted-types@2.0.7':
|
'@types/trusted-types@2.0.7':
|
||||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||||
|
|
||||||
|
'@vitest/browser-playwright@4.1.7':
|
||||||
|
resolution: {integrity: sha512-OlTlJej7YN6VwV7zJJoNeaCsctF+JXpzpZ4oBHUbrQFfIq+0KW2f07rprCLh9N/zRIZ0v4Mchn1QDDmWMUhPKw==}
|
||||||
|
peerDependencies:
|
||||||
|
playwright: '*'
|
||||||
|
vitest: 4.1.7
|
||||||
|
|
||||||
|
'@vitest/browser@4.1.7':
|
||||||
|
resolution: {integrity: sha512-N2JFGfXoEGVAut+kHeru9dD4BUMq/q5xDvBARNl0tUsly3m5KglLOu8VO/6MkDfOlgxXTycojkt6gBKsuyR+IQ==}
|
||||||
|
peerDependencies:
|
||||||
|
vitest: 4.1.7
|
||||||
|
|
||||||
|
'@vitest/expect@4.1.7':
|
||||||
|
resolution: {integrity: sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==}
|
||||||
|
|
||||||
|
'@vitest/mocker@4.1.7':
|
||||||
|
resolution: {integrity: sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==}
|
||||||
|
peerDependencies:
|
||||||
|
msw: ^2.4.9
|
||||||
|
vite: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
msw:
|
||||||
|
optional: true
|
||||||
|
vite:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@vitest/pretty-format@4.1.7':
|
||||||
|
resolution: {integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==}
|
||||||
|
|
||||||
|
'@vitest/runner@4.1.7':
|
||||||
|
resolution: {integrity: sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==}
|
||||||
|
|
||||||
|
'@vitest/snapshot@4.1.7':
|
||||||
|
resolution: {integrity: sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==}
|
||||||
|
|
||||||
|
'@vitest/spy@4.1.7':
|
||||||
|
resolution: {integrity: sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==}
|
||||||
|
|
||||||
|
'@vitest/utils@4.1.7':
|
||||||
|
resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==}
|
||||||
|
|
||||||
'@zerodevx/svelte-toast@0.9.6':
|
'@zerodevx/svelte-toast@0.9.6':
|
||||||
resolution: {integrity: sha512-nHlTrCjverlPK9yukK6fqbG3e/R+f10ldrc4nJHOe2qNDScuPTuYVSFEk2dDDtzWAwTN5pmdEXgA3M2RbT8jiw==}
|
resolution: {integrity: sha512-nHlTrCjverlPK9yukK6fqbG3e/R+f10ldrc4nJHOe2qNDScuPTuYVSFEk2dDDtzWAwTN5pmdEXgA3M2RbT8jiw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -895,6 +1008,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==}
|
resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
assertion-error@2.0.1:
|
||||||
|
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
available-typed-arrays@1.0.7:
|
available-typed-arrays@1.0.7:
|
||||||
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -964,6 +1081,10 @@ packages:
|
|||||||
caniuse-lite@1.0.30001701:
|
caniuse-lite@1.0.30001701:
|
||||||
resolution: {integrity: sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==}
|
resolution: {integrity: sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==}
|
||||||
|
|
||||||
|
chai@6.2.2:
|
||||||
|
resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
chalk@2.4.2:
|
chalk@2.4.2:
|
||||||
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
|
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -1131,6 +1252,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
es-module-lexer@2.1.0:
|
||||||
|
resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==}
|
||||||
|
|
||||||
es-set-tostringtag@2.0.3:
|
es-set-tostringtag@2.0.3:
|
||||||
resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
|
resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -1163,6 +1287,13 @@ packages:
|
|||||||
'@typescript-eslint/types':
|
'@typescript-eslint/types':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
estree-walker@3.0.3:
|
||||||
|
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
|
||||||
|
|
||||||
|
expect-type@1.3.0:
|
||||||
|
resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
|
||||||
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
||||||
exponential-backoff@3.1.3:
|
exponential-backoff@3.1.3:
|
||||||
resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==}
|
resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==}
|
||||||
|
|
||||||
@@ -1488,6 +1619,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
|
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
ky@2.0.2:
|
||||||
|
resolution: {integrity: sha512-/GmXpo9F9W+f8n4Ivr2iH+7h7wL7jLbLKWkMlpflcCRb6kGjBfTlASEXaZ9qUgNTn4VgS0P2pwxxzQ4EM6Ulgg==}
|
||||||
|
engines: {node: '>=22'}
|
||||||
|
|
||||||
license-checker-rseidelsohn@5.0.1:
|
license-checker-rseidelsohn@5.0.1:
|
||||||
resolution: {integrity: sha512-9X+ikKxt9Hy3zOrOZzW1dXL4St5akoYjLt63Am9JZVzU6aTdN+xfDvqySpnJT+gF/h5RmtMk2waW6TDNNCKbqQ==}
|
resolution: {integrity: sha512-9X+ikKxt9Hy3zOrOZzW1dXL4St5akoYjLt63Am9JZVzU6aTdN+xfDvqySpnJT+gF/h5RmtMk2waW6TDNNCKbqQ==}
|
||||||
engines: {node: '>=24', npm: '>=11'}
|
engines: {node: '>=24', npm: '>=11'}
|
||||||
@@ -1889,6 +2024,10 @@ packages:
|
|||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
pngjs@7.0.0:
|
||||||
|
resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==}
|
||||||
|
engines: {node: '>=14.19.0'}
|
||||||
|
|
||||||
possible-typed-array-names@1.0.0:
|
possible-typed-array-names@1.0.0:
|
||||||
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
|
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -2069,6 +2208,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
|
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
siginfo@2.0.0:
|
||||||
|
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
|
||||||
|
|
||||||
signal-exit@3.0.7:
|
signal-exit@3.0.7:
|
||||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||||
|
|
||||||
@@ -2084,6 +2226,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==}
|
resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
sirv@3.0.2:
|
||||||
|
resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
smart-buffer@4.2.0:
|
smart-buffer@4.2.0:
|
||||||
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
|
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
|
||||||
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
|
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
|
||||||
@@ -2132,6 +2278,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==}
|
resolution: {integrity: sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==}
|
||||||
engines: {node: ^20.17.0 || >=22.9.0}
|
engines: {node: ^20.17.0 || >=22.9.0}
|
||||||
|
|
||||||
|
stackback@0.0.2:
|
||||||
|
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
|
||||||
|
|
||||||
|
std-env@4.1.0:
|
||||||
|
resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==}
|
||||||
|
|
||||||
string-width@4.2.3:
|
string-width@4.2.3:
|
||||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -2216,13 +2368,24 @@ packages:
|
|||||||
thenify@3.3.1:
|
thenify@3.3.1:
|
||||||
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
||||||
|
|
||||||
|
tinybench@2.9.0:
|
||||||
|
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
|
||||||
|
|
||||||
tinyexec@0.3.2:
|
tinyexec@0.3.2:
|
||||||
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
|
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
|
||||||
|
|
||||||
|
tinyexec@1.2.2:
|
||||||
|
resolution: {integrity: sha512-M/Q0B2cp4K7kynaT/vnED1j8TlLY+Pp7C6Wl2bl/7u/F0mUVwdyOpwomQb8JpYLitHUssAJRmLZdMCGsrx7i+g==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
tinyglobby@0.2.16:
|
tinyglobby@0.2.16:
|
||||||
resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
|
resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
||||||
|
tinyrainbow@3.1.0:
|
||||||
|
resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
|
||||||
totalist@3.0.1:
|
totalist@3.0.1:
|
||||||
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@@ -2387,6 +2550,47 @@ packages:
|
|||||||
vite:
|
vite:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
vitest@4.1.7:
|
||||||
|
resolution: {integrity: sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==}
|
||||||
|
engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
'@edge-runtime/vm': '*'
|
||||||
|
'@opentelemetry/api': ^1.9.0
|
||||||
|
'@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
|
||||||
|
'@vitest/browser-playwright': 4.1.7
|
||||||
|
'@vitest/browser-preview': 4.1.7
|
||||||
|
'@vitest/browser-webdriverio': 4.1.7
|
||||||
|
'@vitest/coverage-istanbul': 4.1.7
|
||||||
|
'@vitest/coverage-v8': 4.1.7
|
||||||
|
'@vitest/ui': 4.1.7
|
||||||
|
happy-dom: '*'
|
||||||
|
jsdom: '*'
|
||||||
|
vite: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@edge-runtime/vm':
|
||||||
|
optional: true
|
||||||
|
'@opentelemetry/api':
|
||||||
|
optional: true
|
||||||
|
'@types/node':
|
||||||
|
optional: true
|
||||||
|
'@vitest/browser-playwright':
|
||||||
|
optional: true
|
||||||
|
'@vitest/browser-preview':
|
||||||
|
optional: true
|
||||||
|
'@vitest/browser-webdriverio':
|
||||||
|
optional: true
|
||||||
|
'@vitest/coverage-istanbul':
|
||||||
|
optional: true
|
||||||
|
'@vitest/coverage-v8':
|
||||||
|
optional: true
|
||||||
|
'@vitest/ui':
|
||||||
|
optional: true
|
||||||
|
happy-dom:
|
||||||
|
optional: true
|
||||||
|
jsdom:
|
||||||
|
optional: true
|
||||||
|
|
||||||
walk-up-path@4.0.0:
|
walk-up-path@4.0.0:
|
||||||
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
|
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
|
||||||
engines: {node: 20 || >=22}
|
engines: {node: 20 || >=22}
|
||||||
@@ -2415,6 +2619,11 @@ packages:
|
|||||||
engines: {node: ^20.17.0 || >=22.9.0}
|
engines: {node: ^20.17.0 || >=22.9.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
why-is-node-running@2.3.0:
|
||||||
|
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
wrap-ansi@6.2.0:
|
wrap-ansi@6.2.0:
|
||||||
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -2434,6 +2643,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==}
|
resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==}
|
||||||
engines: {node: ^20.17.0 || >=22.9.0}
|
engines: {node: ^20.17.0 || >=22.9.0}
|
||||||
|
|
||||||
|
ws@8.21.0:
|
||||||
|
resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
bufferutil: ^4.0.1
|
||||||
|
utf-8-validate: '>=5.0.2'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
bufferutil:
|
||||||
|
optional: true
|
||||||
|
utf-8-validate:
|
||||||
|
optional: true
|
||||||
|
|
||||||
yallist@3.1.1:
|
yallist@3.1.1:
|
||||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||||
|
|
||||||
@@ -2451,6 +2672,9 @@ packages:
|
|||||||
zimmerframe@1.1.2:
|
zimmerframe@1.1.2:
|
||||||
resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
|
resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
|
||||||
|
|
||||||
|
zod@4.4.3:
|
||||||
|
resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@ampproject/remapping@2.3.0':
|
'@ampproject/remapping@2.3.0':
|
||||||
@@ -2558,6 +2782,8 @@ snapshots:
|
|||||||
'@babel/helper-string-parser': 7.25.9
|
'@babel/helper-string-parser': 7.25.9
|
||||||
'@babel/helper-validator-identifier': 7.25.9
|
'@babel/helper-validator-identifier': 7.25.9
|
||||||
|
|
||||||
|
'@blazediff/core@1.9.1': {}
|
||||||
|
|
||||||
'@commander-js/extra-typings@12.1.0(commander@12.1.0)':
|
'@commander-js/extra-typings@12.1.0(commander@12.1.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
commander: 12.1.0
|
commander: 12.1.0
|
||||||
@@ -2736,6 +2962,8 @@ snapshots:
|
|||||||
|
|
||||||
'@lokalise/node-api@13.2.1': {}
|
'@lokalise/node-api@13.2.1': {}
|
||||||
|
|
||||||
|
'@msgpack/msgpack@3.1.3': {}
|
||||||
|
|
||||||
'@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
|
'@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emnapi/core': 1.10.0
|
'@emnapi/core': 1.10.0
|
||||||
@@ -2743,6 +2971,10 @@ snapshots:
|
|||||||
'@tybys/wasm-util': 0.10.2
|
'@tybys/wasm-util': 0.10.2
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@noble/ciphers@2.2.0': {}
|
||||||
|
|
||||||
|
'@noble/hashes@2.2.0': {}
|
||||||
|
|
||||||
'@npmcli/agent@4.0.2':
|
'@npmcli/agent@4.0.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 7.1.4
|
agent-base: 7.1.4
|
||||||
@@ -3055,6 +3287,8 @@ snapshots:
|
|||||||
vite: 8.0.14(@types/node@24.12.4)(esbuild@0.27.7)
|
vite: 8.0.14(@types/node@24.12.4)(esbuild@0.27.7)
|
||||||
vitefu: 1.1.3(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))
|
vitefu: 1.1.3(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))
|
||||||
|
|
||||||
|
'@tsconfig/strictest@2.0.8': {}
|
||||||
|
|
||||||
'@tufjs/canonical-json@2.0.0': {}
|
'@tufjs/canonical-json@2.0.0': {}
|
||||||
|
|
||||||
'@tufjs/models@4.1.0':
|
'@tufjs/models@4.1.0':
|
||||||
@@ -3067,10 +3301,19 @@ snapshots:
|
|||||||
tslib: 2.8.1
|
tslib: 2.8.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@types/chai@5.2.3':
|
||||||
|
dependencies:
|
||||||
|
'@types/deep-eql': 4.0.2
|
||||||
|
assertion-error: 2.0.1
|
||||||
|
|
||||||
'@types/cookie@0.6.0': {}
|
'@types/cookie@0.6.0': {}
|
||||||
|
|
||||||
|
'@types/deep-eql@4.0.2': {}
|
||||||
|
|
||||||
'@types/estree@1.0.6': {}
|
'@types/estree@1.0.6': {}
|
||||||
|
|
||||||
|
'@types/estree@1.0.9': {}
|
||||||
|
|
||||||
'@types/inquirer@9.0.9':
|
'@types/inquirer@9.0.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/through': 0.0.33
|
'@types/through': 0.0.33
|
||||||
@@ -3098,6 +3341,77 @@ snapshots:
|
|||||||
|
|
||||||
'@types/trusted-types@2.0.7': {}
|
'@types/trusted-types@2.0.7': {}
|
||||||
|
|
||||||
|
'@vitest/browser-playwright@4.1.7(playwright@1.60.0)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))(vitest@4.1.7)':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/browser': 4.1.7(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))(vitest@4.1.7)
|
||||||
|
'@vitest/mocker': 4.1.7(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))
|
||||||
|
playwright: 1.60.0
|
||||||
|
tinyrainbow: 3.1.0
|
||||||
|
vitest: 4.1.7(@types/node@24.12.4)(@vitest/browser-playwright@4.1.7)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- msw
|
||||||
|
- utf-8-validate
|
||||||
|
- vite
|
||||||
|
|
||||||
|
'@vitest/browser@4.1.7(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))(vitest@4.1.7)':
|
||||||
|
dependencies:
|
||||||
|
'@blazediff/core': 1.9.1
|
||||||
|
'@vitest/mocker': 4.1.7(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))
|
||||||
|
'@vitest/utils': 4.1.7
|
||||||
|
magic-string: 0.30.21
|
||||||
|
pngjs: 7.0.0
|
||||||
|
sirv: 3.0.2
|
||||||
|
tinyrainbow: 3.1.0
|
||||||
|
vitest: 4.1.7(@types/node@24.12.4)(@vitest/browser-playwright@4.1.7)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))
|
||||||
|
ws: 8.21.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- msw
|
||||||
|
- utf-8-validate
|
||||||
|
- vite
|
||||||
|
|
||||||
|
'@vitest/expect@4.1.7':
|
||||||
|
dependencies:
|
||||||
|
'@standard-schema/spec': 1.1.0
|
||||||
|
'@types/chai': 5.2.3
|
||||||
|
'@vitest/spy': 4.1.7
|
||||||
|
'@vitest/utils': 4.1.7
|
||||||
|
chai: 6.2.2
|
||||||
|
tinyrainbow: 3.1.0
|
||||||
|
|
||||||
|
'@vitest/mocker@4.1.7(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/spy': 4.1.7
|
||||||
|
estree-walker: 3.0.3
|
||||||
|
magic-string: 0.30.21
|
||||||
|
optionalDependencies:
|
||||||
|
vite: 8.0.14(@types/node@24.12.4)(esbuild@0.27.7)
|
||||||
|
|
||||||
|
'@vitest/pretty-format@4.1.7':
|
||||||
|
dependencies:
|
||||||
|
tinyrainbow: 3.1.0
|
||||||
|
|
||||||
|
'@vitest/runner@4.1.7':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/utils': 4.1.7
|
||||||
|
pathe: 2.0.3
|
||||||
|
|
||||||
|
'@vitest/snapshot@4.1.7':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/pretty-format': 4.1.7
|
||||||
|
'@vitest/utils': 4.1.7
|
||||||
|
magic-string: 0.30.21
|
||||||
|
pathe: 2.0.3
|
||||||
|
|
||||||
|
'@vitest/spy@4.1.7': {}
|
||||||
|
|
||||||
|
'@vitest/utils@4.1.7':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/pretty-format': 4.1.7
|
||||||
|
convert-source-map: 2.0.0
|
||||||
|
tinyrainbow: 3.1.0
|
||||||
|
|
||||||
'@zerodevx/svelte-toast@0.9.6(svelte@5.55.9)':
|
'@zerodevx/svelte-toast@0.9.6(svelte@5.55.9)':
|
||||||
dependencies:
|
dependencies:
|
||||||
svelte: 5.55.9
|
svelte: 5.55.9
|
||||||
@@ -3156,6 +3470,8 @@ snapshots:
|
|||||||
is-array-buffer: 3.0.4
|
is-array-buffer: 3.0.4
|
||||||
is-shared-array-buffer: 1.0.3
|
is-shared-array-buffer: 1.0.3
|
||||||
|
|
||||||
|
assertion-error@2.0.1: {}
|
||||||
|
|
||||||
available-typed-arrays@1.0.7:
|
available-typed-arrays@1.0.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
possible-typed-array-names: 1.0.0
|
possible-typed-array-names: 1.0.0
|
||||||
@@ -3243,6 +3559,8 @@ snapshots:
|
|||||||
|
|
||||||
caniuse-lite@1.0.30001701: {}
|
caniuse-lite@1.0.30001701: {}
|
||||||
|
|
||||||
|
chai@6.2.2: {}
|
||||||
|
|
||||||
chalk@2.4.2:
|
chalk@2.4.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-styles: 3.2.1
|
ansi-styles: 3.2.1
|
||||||
@@ -3414,6 +3732,8 @@ snapshots:
|
|||||||
|
|
||||||
es-errors@1.3.0: {}
|
es-errors@1.3.0: {}
|
||||||
|
|
||||||
|
es-module-lexer@2.1.0: {}
|
||||||
|
|
||||||
es-set-tostringtag@2.0.3:
|
es-set-tostringtag@2.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
get-intrinsic: 1.2.4
|
get-intrinsic: 1.2.4
|
||||||
@@ -3465,6 +3785,12 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/sourcemap-codec': 1.5.0
|
'@jridgewell/sourcemap-codec': 1.5.0
|
||||||
|
|
||||||
|
estree-walker@3.0.3:
|
||||||
|
dependencies:
|
||||||
|
'@types/estree': 1.0.9
|
||||||
|
|
||||||
|
expect-type@1.3.0: {}
|
||||||
|
|
||||||
exponential-backoff@3.1.3: {}
|
exponential-backoff@3.1.3: {}
|
||||||
|
|
||||||
fdir@6.4.3(picomatch@4.0.4):
|
fdir@6.4.3(picomatch@4.0.4):
|
||||||
@@ -3477,7 +3803,7 @@ snapshots:
|
|||||||
|
|
||||||
fix-dts-default-cjs-exports@1.0.1:
|
fix-dts-default-cjs-exports@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.21
|
||||||
mlly: 1.8.2
|
mlly: 1.8.2
|
||||||
rollup: 4.34.8
|
rollup: 4.34.8
|
||||||
|
|
||||||
@@ -3709,7 +4035,7 @@ snapshots:
|
|||||||
|
|
||||||
is-reference@3.0.3:
|
is-reference@3.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': 1.0.6
|
'@types/estree': 1.0.9
|
||||||
|
|
||||||
is-regex@1.1.4:
|
is-regex@1.1.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3776,6 +4102,8 @@ snapshots:
|
|||||||
|
|
||||||
kleur@4.1.5: {}
|
kleur@4.1.5: {}
|
||||||
|
|
||||||
|
ky@2.0.2: {}
|
||||||
|
|
||||||
license-checker-rseidelsohn@5.0.1:
|
license-checker-rseidelsohn@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@npmcli/arborist': 9.6.0
|
'@npmcli/arborist': 9.6.0
|
||||||
@@ -4190,6 +4518,8 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.2
|
||||||
|
|
||||||
|
pngjs@7.0.0: {}
|
||||||
|
|
||||||
possible-typed-array-names@1.0.0: {}
|
possible-typed-array-names@1.0.0: {}
|
||||||
|
|
||||||
postcss-load-config@6.0.1(postcss@8.5.15):
|
postcss-load-config@6.0.1(postcss@8.5.15):
|
||||||
@@ -4389,6 +4719,8 @@ snapshots:
|
|||||||
get-intrinsic: 1.2.4
|
get-intrinsic: 1.2.4
|
||||||
object-inspect: 1.13.1
|
object-inspect: 1.13.1
|
||||||
|
|
||||||
|
siginfo@2.0.0: {}
|
||||||
|
|
||||||
signal-exit@3.0.7: {}
|
signal-exit@3.0.7: {}
|
||||||
|
|
||||||
signal-exit@4.1.0: {}
|
signal-exit@4.1.0: {}
|
||||||
@@ -4410,6 +4742,12 @@ snapshots:
|
|||||||
mrmime: 2.0.1
|
mrmime: 2.0.1
|
||||||
totalist: 3.0.1
|
totalist: 3.0.1
|
||||||
|
|
||||||
|
sirv@3.0.2:
|
||||||
|
dependencies:
|
||||||
|
'@polka/url': 1.0.0-next.28
|
||||||
|
mrmime: 2.0.1
|
||||||
|
totalist: 3.0.1
|
||||||
|
|
||||||
smart-buffer@4.2.0: {}
|
smart-buffer@4.2.0: {}
|
||||||
|
|
||||||
socks-proxy-agent@8.0.5:
|
socks-proxy-agent@8.0.5:
|
||||||
@@ -4466,6 +4804,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
minipass: 7.1.3
|
minipass: 7.1.3
|
||||||
|
|
||||||
|
stackback@0.0.2: {}
|
||||||
|
|
||||||
|
std-env@4.1.0: {}
|
||||||
|
|
||||||
string-width@4.2.3:
|
string-width@4.2.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
emoji-regex: 8.0.0
|
emoji-regex: 8.0.0
|
||||||
@@ -4599,13 +4941,19 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
any-promise: 1.3.0
|
any-promise: 1.3.0
|
||||||
|
|
||||||
|
tinybench@2.9.0: {}
|
||||||
|
|
||||||
tinyexec@0.3.2: {}
|
tinyexec@0.3.2: {}
|
||||||
|
|
||||||
|
tinyexec@1.2.2: {}
|
||||||
|
|
||||||
tinyglobby@0.2.16:
|
tinyglobby@0.2.16:
|
||||||
dependencies:
|
dependencies:
|
||||||
fdir: 6.5.0(picomatch@4.0.4)
|
fdir: 6.5.0(picomatch@4.0.4)
|
||||||
picomatch: 4.0.4
|
picomatch: 4.0.4
|
||||||
|
|
||||||
|
tinyrainbow@3.1.0: {}
|
||||||
|
|
||||||
totalist@3.0.1: {}
|
totalist@3.0.1: {}
|
||||||
|
|
||||||
tree-kill@1.2.2: {}
|
tree-kill@1.2.2: {}
|
||||||
@@ -4742,6 +5090,34 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 8.0.14(@types/node@24.12.4)(esbuild@0.27.7)
|
vite: 8.0.14(@types/node@24.12.4)(esbuild@0.27.7)
|
||||||
|
|
||||||
|
vitest@4.1.7(@types/node@24.12.4)(@vitest/browser-playwright@4.1.7)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7)):
|
||||||
|
dependencies:
|
||||||
|
'@vitest/expect': 4.1.7
|
||||||
|
'@vitest/mocker': 4.1.7(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))
|
||||||
|
'@vitest/pretty-format': 4.1.7
|
||||||
|
'@vitest/runner': 4.1.7
|
||||||
|
'@vitest/snapshot': 4.1.7
|
||||||
|
'@vitest/spy': 4.1.7
|
||||||
|
'@vitest/utils': 4.1.7
|
||||||
|
es-module-lexer: 2.1.0
|
||||||
|
expect-type: 1.3.0
|
||||||
|
magic-string: 0.30.21
|
||||||
|
obug: 2.1.1
|
||||||
|
pathe: 2.0.3
|
||||||
|
picomatch: 4.0.4
|
||||||
|
std-env: 4.1.0
|
||||||
|
tinybench: 2.9.0
|
||||||
|
tinyexec: 1.2.2
|
||||||
|
tinyglobby: 0.2.16
|
||||||
|
tinyrainbow: 3.1.0
|
||||||
|
vite: 8.0.14(@types/node@24.12.4)(esbuild@0.27.7)
|
||||||
|
why-is-node-running: 2.3.0
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/node': 24.12.4
|
||||||
|
'@vitest/browser-playwright': 4.1.7(playwright@1.60.0)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.27.7))(vitest@4.1.7)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- msw
|
||||||
|
|
||||||
walk-up-path@4.0.0: {}
|
walk-up-path@4.0.0: {}
|
||||||
|
|
||||||
wcwidth@1.0.1:
|
wcwidth@1.0.1:
|
||||||
@@ -4776,6 +5152,11 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
isexe: 4.0.0
|
isexe: 4.0.0
|
||||||
|
|
||||||
|
why-is-node-running@2.3.0:
|
||||||
|
dependencies:
|
||||||
|
siginfo: 2.0.0
|
||||||
|
stackback: 0.0.2
|
||||||
|
|
||||||
wrap-ansi@6.2.0:
|
wrap-ansi@6.2.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-styles: 4.3.0
|
ansi-styles: 4.3.0
|
||||||
@@ -4800,6 +5181,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
signal-exit: 4.1.0
|
signal-exit: 4.1.0
|
||||||
|
|
||||||
|
ws@8.21.0: {}
|
||||||
|
|
||||||
yallist@3.1.1: {}
|
yallist@3.1.1: {}
|
||||||
|
|
||||||
yallist@4.0.0: {}
|
yallist@4.0.0: {}
|
||||||
@@ -4809,3 +5192,5 @@ snapshots:
|
|||||||
yoctocolors-cjs@2.1.2: {}
|
yoctocolors-cjs@2.1.2: {}
|
||||||
|
|
||||||
zimmerframe@1.1.2: {}
|
zimmerframe@1.1.2: {}
|
||||||
|
|
||||||
|
zod@4.4.3: {}
|
||||||
|
|||||||
@@ -5,3 +5,9 @@ allowBuilds:
|
|||||||
esbuild: true
|
esbuild: true
|
||||||
|
|
||||||
minimumReleaseAge: 10080 # One week
|
minimumReleaseAge: 10080 # One week
|
||||||
|
|
||||||
|
catalog:
|
||||||
|
"@tsconfig/strictest": "^2.0.8"
|
||||||
|
"typescript": "^6.0.3"
|
||||||
|
"vitest": "^4.1.7"
|
||||||
|
"@vitest/browser-playwright": "^4.1.7"
|
||||||
|
|||||||