From 211e31a00834667d7907656cf73233a40dc76ddb Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Mon, 13 Sep 2021 17:18:33 +0200 Subject: [PATCH 01/22] Wrote first draft of sections database scheme --- .../2021-09-13-143540_sections/down.sql | 7 +++ migrations/2021-09-13-143540_sections/up.sql | 56 +++++++++++++++++++ src/schema.rs | 28 +++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 migrations/2021-09-13-143540_sections/down.sql create mode 100644 migrations/2021-09-13-143540_sections/up.sql diff --git a/migrations/2021-09-13-143540_sections/down.sql b/migrations/2021-09-13-143540_sections/down.sql new file mode 100644 index 0000000..7af43ff --- /dev/null +++ b/migrations/2021-09-13-143540_sections/down.sql @@ -0,0 +1,7 @@ +-- This file should undo anything in `up.sql` +drop trigger insert_enforce_post_titles on posts; +drop trigger update_enforce_post_titles on posts; +drop function enforce_post_titles; + +drop table posts cascade; +drop table sections cascade; diff --git a/migrations/2021-09-13-143540_sections/up.sql b/migrations/2021-09-13-143540_sections/up.sql new file mode 100644 index 0000000..0c5ca76 --- /dev/null +++ b/migrations/2021-09-13-143540_sections/up.sql @@ -0,0 +1,56 @@ +-- Your SQL goes here +create table sections ( + id uuid DEFAULT gen_random_uuid() PRIMARY KEY, + + -- Title of the section + title varchar(255) UNIQUE NOT NULL, + -- Optional description of the section + description text, + -- Wether to show the section in the default list on the homepage + is_default boolean NOT NULL DEFAULT false, + -- Wether the posts should contain titles or not + has_titles boolean NOT NULL DEFAULT true +); + +create table posts ( + id uuid DEFAULT gen_random_uuid() PRIMARY KEY, + + section_id uuid NOT NULL REFERENCES sections(id) ON DELETE CASCADE, + -- Title of the post + -- Wether this is NULL or not is enforced using the enforce_post_titles trigger + title varchar(255), + -- Post date, defaults to today + publish_date date NOT NULL DEFAULT now(), + -- Content of the post + content text NOT NULL +); + +create function enforce_post_titles() returns trigger as $enforce_post_titles$ + begin + -- Check for a wrongfully null title + if new.title is null and exists ( + select 1 from sections where id = new.section_id and has_titles + ) then + raise exception 'Expected a post title, but got null.'; + end if; + + if new.title is not null and exists ( + select 1 from sections where id = new.section_id and not has_titles + ) then + raise exception 'Expected an empty post title, but got a value.'; + end if; + + return new; + end; +$enforce_post_titles$ language plpgsql; + +create trigger insert_enforce_post_titles + before insert on posts + for each row + execute function enforce_post_titles(); + +create trigger update_enforce_post_titles + before update of title on posts + for each row + when (old.title is distinct from new.title) + execute function enforce_post_titles(); diff --git a/src/schema.rs b/src/schema.rs index e3854e3..a38f572 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -1,3 +1,13 @@ +table! { + posts (id) { + id -> Uuid, + section_id -> Uuid, + title -> Nullable, + publish_date -> Date, + content -> Text, + } +} + table! { refresh_tokens (token) { token -> Bytea, @@ -7,6 +17,16 @@ table! { } } +table! { + sections (id) { + id -> Uuid, + title -> Varchar, + description -> Nullable, + is_default -> Bool, + has_titles -> Bool, + } +} + table! { users (id) { id -> Uuid, @@ -17,6 +37,12 @@ table! { } } +joinable!(posts -> sections (section_id)); joinable!(refresh_tokens -> users (user_id)); -allow_tables_to_appear_in_same_query!(refresh_tokens, users,); +allow_tables_to_appear_in_same_query!( + posts, + refresh_tokens, + sections, + users, +); From 8534090f0f923f48749f2c1bd263bdb5671cb613 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Mon, 13 Sep 2021 17:35:06 +0200 Subject: [PATCH 02/22] Wrote some database boilerplate --- src/db/mod.rs | 3 +++ src/db/posts.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/db/sections.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/db/tokens.rs | 4 ++-- 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 src/db/posts.rs create mode 100644 src/db/sections.rs diff --git a/src/db/mod.rs b/src/db/mod.rs index 9c831dd..19cb419 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,5 +1,8 @@ pub mod tokens; pub mod users; +pub mod sections; +pub mod posts; pub use tokens::{NewRefreshToken, RefreshToken}; pub use users::{NewUser, User}; +pub use sections::{Section, NewSection}; diff --git a/src/db/posts.rs b/src/db/posts.rs new file mode 100644 index 0000000..0493405 --- /dev/null +++ b/src/db/posts.rs @@ -0,0 +1,44 @@ +use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; +use uuid::Uuid; +use chrono::NaiveDate; + +use crate::{ + errors::{RbError, RbResult}, + schema::{posts, posts::dsl::*}, +}; + +#[derive(Queryable)] +pub struct Post +{ + pub id: Uuid, + pub section_id: Uuid, + pub title: Option, + pub publish_date: NaiveDate, + pub content: String, +} + +#[derive(Insertable)] +#[table_name = "posts"] +pub struct NewPost +{ + pub section_id: Uuid, + pub title: Option, + pub publish_date: NaiveDate, +} + +pub fn all(conn: &PgConnection) -> RbResult> +{ + posts.load::(conn).map_err(|_| RbError::DbError("Couldn't get all posts.")) +} + +pub fn create(conn: &PgConnection, new_post: &NewPost) -> RbResult<()> +{ + insert_into(posts) + .values(new_post) + .execute(conn) + .map_err(|_| RbError::DbError("Couldn't insert post."))?; + + // TODO check for conflict? + + Ok(()) +} diff --git a/src/db/sections.rs b/src/db/sections.rs new file mode 100644 index 0000000..cff2736 --- /dev/null +++ b/src/db/sections.rs @@ -0,0 +1,44 @@ +use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; +use uuid::Uuid; + +use crate::{ + errors::{RbError, RbResult}, + schema::{sections, sections::dsl::*}, +}; + +#[derive(Queryable)] +pub struct Section +{ + pub id: Uuid, + pub title: String, + pub description: Option, + pub is_default: bool, + pub has_titles: bool, +} + +#[derive(Insertable)] +#[table_name = "sections"] +pub struct NewSection +{ + title: String, + description: Option, + is_default: bool, + has_titles: bool, +} + +pub fn all(conn: &PgConnection) -> RbResult> +{ + sections.load::
(conn).map_err(|_| RbError::DbError("Couldn't get all sections")) +} + +pub fn create(conn: &PgConnection, new_section: &NewSection) -> RbResult<()> +{ + insert_into(sections) + .values(new_section) + .execute(conn) + .map_err(|_| RbError::DbError("Couldn't insert section."))?; + + // TODO check for conflict? + + Ok(()) +} diff --git a/src/db/tokens.rs b/src/db/tokens.rs index 8940721..97dd02d 100644 --- a/src/db/tokens.rs +++ b/src/db/tokens.rs @@ -36,7 +36,7 @@ pub fn create(conn: &PgConnection, new_refresh_token: &NewRefreshToken) -> RbRes insert_into(refresh_tokens) .values(new_refresh_token) .execute(conn) - .map_err(|_| RbError::Custom("Couldn't insert refresh token."))?; + .map_err(|_| RbError::DbError("Couldn't insert refresh token."))?; // TODO check for conflict? @@ -53,7 +53,7 @@ pub fn find_with_user( .inner_join(crate::schema::users::dsl::users) .filter(token.eq(token_val)) .first::<(RefreshToken, super::users::User)>(conn) - .map_err(|_| RbError::Custom("Couldn't get refresh token & user.")) + .map_err(|_| RbError::DbError("Couldn't get refresh token & user.")) .ok() } From 3e7612a9a8b278a21a561295464aae31f30e5202 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Mon, 13 Sep 2021 22:15:38 +0200 Subject: [PATCH 03/22] Added create section endpoint --- Rb.yaml | 21 +++++++++++++++++++++ rustfmt.toml | 2 +- src/db/mod.rs | 6 +++--- src/db/posts.rs | 6 ++++-- src/db/sections.rs | 12 ++++++++---- src/errors.rs | 2 +- src/guards.rs | 18 ++++++++---------- src/main.rs | 2 ++ src/schema.rs | 7 +------ src/sections.rs | 16 ++++++++++++++++ tests/admin.py | 13 ++++++++++--- 11 files changed, 75 insertions(+), 30 deletions(-) create mode 100644 src/sections.rs diff --git a/Rb.yaml b/Rb.yaml index c944758..29a37f8 100644 --- a/Rb.yaml +++ b/Rb.yaml @@ -21,3 +21,24 @@ debug: databases: postgres_rb: url: "postgres://rb:rb@localhost:5432/rb" + +# This config is just used for testing, you should change it when deploying +release: + keep_alive: 5 + read_timeout: 5 + write_timeout: 5 + log_level: "normal" + limits: + forms: 32768 + + admin_user: "admin" + admin_pass: "password" + jwt: + key: "secret" + refresh_token_size: 64 + # Just 5 seconds for debugging + refresh_token_expire: 60 + + databases: + postgres_rb: + url: "postgres://rb:rb@localhost:5432/rb" diff --git a/rustfmt.toml b/rustfmt.toml index 5e52857..8e8627b 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -36,7 +36,7 @@ license_template_path = "" make_backup = false match_arm_blocks = true match_arm_leading_pipes = "Never" -match_block_trailing_comma = false +match_block_trailing_comma = true max_width = 100 merge_derives = true newline_style = "Auto" diff --git a/src/db/mod.rs b/src/db/mod.rs index 19cb419..d1dcdcf 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,8 +1,8 @@ +pub mod posts; +pub mod sections; pub mod tokens; pub mod users; -pub mod sections; -pub mod posts; +pub use sections::{NewSection, Section}; pub use tokens::{NewRefreshToken, RefreshToken}; pub use users::{NewUser, User}; -pub use sections::{Section, NewSection}; diff --git a/src/db/posts.rs b/src/db/posts.rs index 0493405..8014f3f 100644 --- a/src/db/posts.rs +++ b/src/db/posts.rs @@ -1,6 +1,6 @@ +use chrono::NaiveDate; use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; use uuid::Uuid; -use chrono::NaiveDate; use crate::{ errors::{RbError, RbResult}, @@ -28,7 +28,9 @@ pub struct NewPost pub fn all(conn: &PgConnection) -> RbResult> { - posts.load::(conn).map_err(|_| RbError::DbError("Couldn't get all posts.")) + posts + .load::(conn) + .map_err(|_| RbError::DbError("Couldn't get all posts.")) } pub fn create(conn: &PgConnection, new_post: &NewPost) -> RbResult<()> diff --git a/src/db/sections.rs b/src/db/sections.rs index cff2736..19721fb 100644 --- a/src/db/sections.rs +++ b/src/db/sections.rs @@ -1,4 +1,5 @@ use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; +use serde::Deserialize; use uuid::Uuid; use crate::{ @@ -16,19 +17,22 @@ pub struct Section pub has_titles: bool, } -#[derive(Insertable)] +#[derive(Deserialize, Insertable)] #[table_name = "sections"] +// #[serde(rename_all = "camelCase")] pub struct NewSection { title: String, description: Option, - is_default: bool, - has_titles: bool, + is_default: Option, + has_titles: Option, } pub fn all(conn: &PgConnection) -> RbResult> { - sections.load::
(conn).map_err(|_| RbError::DbError("Couldn't get all sections")) + sections + .load::
(conn) + .map_err(|_| RbError::DbError("Couldn't get all sections")) } pub fn create(conn: &PgConnection, new_section: &NewSection) -> RbResult<()> diff --git a/src/errors.rs b/src/errors.rs index bb7856a..1f9aff3 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -61,7 +61,7 @@ impl RbError RbError::AuthInvalidRefreshToken => "This refresh token is not valid.", RbError::AuthDuplicateRefreshToken => { "This refresh token has already been used. The user has been blocked." - } + }, RbError::AuthMissingHeader => "Missing Authorization header.", RbError::UMDuplicateUser => "This user already exists.", diff --git a/src/guards.rs b/src/guards.rs index 7b40bdd..3510163 100644 --- a/src/guards.rs +++ b/src/guards.rs @@ -10,7 +10,7 @@ use sha2::Sha256; use crate::{auth::jwt::Claims, errors::RbError, RbConfig}; -/// Extracts a "Authorization: Bearer" string from the headers. +/// Extracts an "Authorization: Bearer" string from the headers. pub struct Bearer<'a>(&'a str); #[rocket::async_trait] @@ -22,7 +22,7 @@ impl<'r> FromRequest<'r> for Bearer<'r> { // If the header isn't present, just forward to the next route let header = match req.headers().get_one("Authorization") { - None => return Outcome::Failure((Status::BadRequest, Self::Error::AuthMissingHeader)), + None => return Outcome::Forward(()), Some(val) => val, }; @@ -31,12 +31,10 @@ impl<'r> FromRequest<'r> for Bearer<'r> } // Extract the jwt token from the header - let auth_string = match header.get(7..) { - Some(s) => s, - None => return Outcome::Failure((Status::Unauthorized, Self::Error::AuthUnauthorized)), - }; - - Outcome::Success(Self(auth_string)) + match header.get(7..) { + Some(s) => Outcome::Success(Self(s)), + None => Outcome::Failure((Status::Unauthorized, Self::Error::AuthUnauthorized)), + } } } @@ -63,14 +61,14 @@ impl<'r> FromRequest<'r> for Jwt Status::InternalServerError, Self::Error::Custom("Failed to do Hmac thing."), )) - } + }, }; // Verify token using key let claims: Claims = match bearer.verify_with_key(&key) { Ok(claims) => claims, Err(_) => { return Outcome::Failure((Status::Unauthorized, Self::Error::AuthUnauthorized)) - } + }, }; Outcome::Success(Self(claims)) diff --git a/src/main.rs b/src/main.rs index 2819e79..adb2f26 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ pub mod db; pub mod errors; pub mod guards; pub(crate) mod schema; +pub mod sections; #[global_allocator] static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; @@ -111,4 +112,5 @@ fn rocket() -> _ "/api/admin", routes![admin::get_users, admin::create_user, admin::get_user_info], ) + .mount("/api/sections", routes![sections::create_section]) } diff --git a/src/schema.rs b/src/schema.rs index a38f572..45b9813 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -40,9 +40,4 @@ table! { joinable!(posts -> sections (section_id)); joinable!(refresh_tokens -> users (user_id)); -allow_tables_to_appear_in_same_query!( - posts, - refresh_tokens, - sections, - users, -); +allow_tables_to_appear_in_same_query!(posts, refresh_tokens, sections, users,); diff --git a/src/sections.rs b/src/sections.rs new file mode 100644 index 0000000..c5e2f27 --- /dev/null +++ b/src/sections.rs @@ -0,0 +1,16 @@ +use rocket::serde::json::Json; + +use crate::{db, errors::RbResult, guards::Admin, RbDbConn}; + +/// Create a new section. +#[post("/", data = "")] +pub async fn create_section( + _admin: Admin, + conn: RbDbConn, + new_section: Json, +) -> RbResult<()> +{ + Ok(conn + .run(move |c| db::sections::create(c, &new_section.into_inner())) + .await?) +} diff --git a/tests/admin.py b/tests/admin.py index 19a1c5b..069c2dd 100644 --- a/tests/admin.py +++ b/tests/admin.py @@ -2,7 +2,7 @@ import requests class RbClient: - def __init__(self, username, password, base_url = "http://localhost:8000/api"): + def __init__(self, username = "admin", password = "password", base_url = "http://localhost:8000/api"): self.username = username self.password = password self.base_url = base_url @@ -17,6 +17,7 @@ class RbClient: }) if r.status_code != 200: + print(r.text) raise Exception("Couldn't login") res = r.json() @@ -56,9 +57,15 @@ class RbClient: def get(self, url, *args, **kwargs): return self._request("GET", f"{self.base_url}{url}", *args, **kwargs) + def post(self, url, *args, **kwargs): + return self._request("POST", f"{self.base_url}{url}", *args, **kwargs) + if __name__ == "__main__": - client = RbClient("admin", "password") + client = RbClient() - print(client.get("/admin/users").json()) + # print(client.get("/admin/users").json()) + client.post("/sections", json={ + "title": "this is a title" + }) From 6d83c1803609b76a270596f330c50956f3723bb3 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Wed, 15 Sep 2021 11:36:40 +0200 Subject: [PATCH 04/22] Documented entire db section --- src/db/mod.rs | 3 +++ src/db/posts.rs | 16 ++++++++++++++++ src/db/sections.rs | 15 +++++++++++++++ src/db/tokens.rs | 32 +++++++++++++++++++++++++++++++ src/db/users.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++++ src/sections.rs | 10 +++++++++- 6 files changed, 122 insertions(+), 1 deletion(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index d1dcdcf..35e4995 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,3 +1,6 @@ +//! The db module contains all Diesel-related logic. This is to prevent the various Diesel imports +//! from poluting other modules' namespaces. + pub mod posts; pub mod sections; pub mod tokens; diff --git a/src/db/posts.rs b/src/db/posts.rs index 8014f3f..2486c08 100644 --- a/src/db/posts.rs +++ b/src/db/posts.rs @@ -1,3 +1,5 @@ +//! Handles all posts-related database operations. + use chrono::NaiveDate; use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; use uuid::Uuid; @@ -7,6 +9,7 @@ use crate::{ schema::{posts, posts::dsl::*}, }; +/// Represents a post contained within the database. #[derive(Queryable)] pub struct Post { @@ -17,6 +20,7 @@ pub struct Post pub content: String, } +/// Represents a new post to be added to the database. #[derive(Insertable)] #[table_name = "posts"] pub struct NewPost @@ -26,6 +30,12 @@ pub struct NewPost pub publish_date: NaiveDate, } +/// Returns all posts in the database; should be used with care as this method could quickly return +/// a large amount of data. +/// +/// # Arguments +/// +/// * `conn` - a reference to a database connection pub fn all(conn: &PgConnection) -> RbResult> { posts @@ -33,6 +43,12 @@ pub fn all(conn: &PgConnection) -> RbResult> .map_err(|_| RbError::DbError("Couldn't get all posts.")) } +/// Insert a new post into the database. +/// +/// # Arguments +/// +/// * `conn` - reference to a database connection +/// * `new_post` - the new post object to insert pub fn create(conn: &PgConnection, new_post: &NewPost) -> RbResult<()> { insert_into(posts) diff --git a/src/db/sections.rs b/src/db/sections.rs index 19721fb..ca8956b 100644 --- a/src/db/sections.rs +++ b/src/db/sections.rs @@ -1,3 +1,5 @@ +//! Handles all section-related database operations. + use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; use serde::Deserialize; use uuid::Uuid; @@ -7,6 +9,7 @@ use crate::{ schema::{sections, sections::dsl::*}, }; +/// Represents a section contained in the database. #[derive(Queryable)] pub struct Section { @@ -17,6 +20,7 @@ pub struct Section pub has_titles: bool, } +/// A new section to be added into the database. #[derive(Deserialize, Insertable)] #[table_name = "sections"] // #[serde(rename_all = "camelCase")] @@ -28,6 +32,11 @@ pub struct NewSection has_titles: Option, } +/// Returns all sections in the database. +/// +/// # Arguments +/// +/// * `conn` - reference to a database connection pub fn all(conn: &PgConnection) -> RbResult> { sections @@ -35,6 +44,12 @@ pub fn all(conn: &PgConnection) -> RbResult> .map_err(|_| RbError::DbError("Couldn't get all sections")) } +/// Inserts a new section into the database. +/// +/// # Arguments +/// +/// * `conn` - reference to a database connection +/// * `new_section` - the new section to be added pub fn create(conn: &PgConnection, new_section: &NewSection) -> RbResult<()> { insert_into(sections) diff --git a/src/db/tokens.rs b/src/db/tokens.rs index 97dd02d..cbb8898 100644 --- a/src/db/tokens.rs +++ b/src/db/tokens.rs @@ -1,3 +1,5 @@ +//! Handles refresh token-related database operations. + use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; use uuid::Uuid; @@ -6,6 +8,7 @@ use crate::{ schema::{refresh_tokens, refresh_tokens::dsl::*}, }; +/// A refresh token as stored in the database #[derive(Queryable)] pub struct RefreshToken { @@ -15,6 +18,7 @@ pub struct RefreshToken pub last_used_at: Option, } +/// A new refresh token to be added into the database #[derive(Insertable)] #[table_name = "refresh_tokens"] pub struct NewRefreshToken @@ -24,6 +28,12 @@ pub struct NewRefreshToken pub expires_at: chrono::NaiveDateTime, } +// TODO add pagination as this could grow very quickly +/// Returns all refresh tokens contained in the database. +/// +/// # Arguments +/// +/// * `conn` - database connection to use pub fn all(conn: &PgConnection) -> RbResult> { refresh_tokens @@ -31,6 +41,12 @@ pub fn all(conn: &PgConnection) -> RbResult> .map_err(|_| RbError::DbError("Couldn't get all refresh tokens.")) } +/// Insert a new refresh token into the database. +/// +/// # Arguments +/// +/// * `conn` - database connection to use +/// * `new_refresh_token` - token to insert pub fn create(conn: &PgConnection, new_refresh_token: &NewRefreshToken) -> RbResult<()> { insert_into(refresh_tokens) @@ -43,6 +59,12 @@ pub fn create(conn: &PgConnection, new_refresh_token: &NewRefreshToken) -> RbRes Ok(()) } +/// Returns the token & user data associated with the given refresh token value. +/// +/// # Arguments +/// +/// * `conn` - database connection to use +/// * `token_val` - token value to search for pub fn find_with_user( conn: &PgConnection, token_val: &[u8], @@ -57,6 +79,16 @@ pub fn find_with_user( .ok() } +/// Updates a token's `last_used_at` column value. +/// +/// # Arguments +/// +/// * `conn` - database connection to use +/// * `token_` - value of the refresh token to update +/// * `last_used_at_` - date value to update column with +/// +/// **NOTE**: argument names use trailing underscores as to not conflict with Diesel's imported dsl +/// names. pub fn update_last_used_at( conn: &PgConnection, token_: &[u8], diff --git a/src/db/users.rs b/src/db/users.rs index efc74db..37ef9c2 100644 --- a/src/db/users.rs +++ b/src/db/users.rs @@ -1,3 +1,5 @@ +//! Handles user-related database operations. + use diesel::{prelude::*, AsChangeset, Insertable, Queryable}; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -7,6 +9,7 @@ use crate::{ schema::{users, users::dsl::*}, }; +/// A user as stored in the database. #[derive(Queryable, Serialize)] pub struct User { @@ -18,6 +21,7 @@ pub struct User pub admin: bool, } +/// A new user to add to the database. #[derive(Insertable, AsChangeset, Deserialize)] #[table_name = "users"] pub struct NewUser @@ -27,6 +31,11 @@ pub struct NewUser pub admin: bool, } +/// Returns all users in the database. +/// +/// # Arguments +/// +/// * `conn` - database connection to use pub fn all(conn: &PgConnection) -> RbResult> { users @@ -34,11 +43,23 @@ pub fn all(conn: &PgConnection) -> RbResult> .map_err(|_| RbError::DbError("Couldn't get all users.")) } +/// Find a user with a given ID. +/// +/// # Arguments +/// +/// * `conn` - database connection to use +/// * `user_id` - ID to search for pub fn find(conn: &PgConnection, user_id: Uuid) -> Option { users.find(user_id).first::(conn).ok() } +/// Find a user with a given username. +/// +/// # Arguments +/// +/// * `conn` - database connection to use +/// * `username_` - username to search for pub fn find_by_username(conn: &PgConnection, username_: &str) -> RbResult { Ok(users @@ -47,6 +68,12 @@ pub fn find_by_username(conn: &PgConnection, username_: &str) -> RbResult .map_err(|_| RbError::DbError("Couldn't find users by username."))?) } +/// Insert a new user into the database +/// +/// # Arguments +/// +/// * `conn` - database connection to use +/// * `new_user` - user to insert pub fn create(conn: &PgConnection, new_user: &NewUser) -> RbResult<()> { let count = diesel::insert_into(users) @@ -61,6 +88,12 @@ pub fn create(conn: &PgConnection, new_user: &NewUser) -> RbResult<()> Ok(()) } +/// Either create a new user or update an existing one on conflict. +/// +/// # Arguments +/// +/// * `conn` - database connection to use +/// * `new_user` - user to insert/update pub fn create_or_update(conn: &PgConnection, new_user: &NewUser) -> RbResult<()> { diesel::insert_into(users) @@ -74,6 +107,12 @@ pub fn create_or_update(conn: &PgConnection, new_user: &NewUser) -> RbResult<()> Ok(()) } +/// Delete the user with the given ID. +/// +/// # Arguments +/// +/// `conn` - database connection to use +/// `user_id` - ID of user to delete pub fn delete(conn: &PgConnection, user_id: Uuid) -> RbResult<()> { diesel::delete(users.filter(id.eq(user_id))) @@ -83,6 +122,14 @@ pub fn delete(conn: &PgConnection, user_id: Uuid) -> RbResult<()> Ok(()) } +/// Block a user given an ID. +/// In practice, this means updating the user's entry so that the `blocked` column is set to +/// `true`. +/// +/// # Arguments +/// +/// `conn` - database connection to use +/// `user_id` - ID of user to block pub fn block(conn: &PgConnection, user_id: Uuid) -> RbResult<()> { diesel::update(users.filter(id.eq(user_id))) diff --git a/src/sections.rs b/src/sections.rs index c5e2f27..e4def24 100644 --- a/src/sections.rs +++ b/src/sections.rs @@ -1,8 +1,16 @@ +//! This module handles management of site sections (aka blogs). + use rocket::serde::json::Json; use crate::{db, errors::RbResult, guards::Admin, RbDbConn}; -/// Create a new section. +/// Route for creating a new section. +/// +/// # Arguments +/// +/// * `_admin` - guard ensuring user is admin +/// * `conn` - guard providing a connection to the database +/// * `new_section` - Json-encoded NewSection object #[post("/", data = "")] pub async fn create_section( _admin: Admin, From 548dd0d022da69667111d3c89be2fe1c3348ada0 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Thu, 23 Sep 2021 15:30:39 +0200 Subject: [PATCH 05/22] Tried to add MirageJS but failed --- src/db/posts.rs | 4 - src/db/sections.rs | 2 +- web/package.json | 4 +- web/src/components/MirageTest.svelte | 19 + web/src/components/SvelteCounter.svelte | 2 +- web/src/layouts/index.astro | 4 + web/src/pages/index.astro | 23 + web/yarn.lock | 996 +++++++++++++++--------- 8 files changed, 681 insertions(+), 373 deletions(-) create mode 100644 web/src/components/MirageTest.svelte diff --git a/src/db/posts.rs b/src/db/posts.rs index 2486c08..163902e 100644 --- a/src/db/posts.rs +++ b/src/db/posts.rs @@ -1,5 +1,3 @@ -//! Handles all posts-related database operations. - use chrono::NaiveDate; use diesel::{insert_into, prelude::*, Insertable, PgConnection, Queryable}; use uuid::Uuid; @@ -9,7 +7,6 @@ use crate::{ schema::{posts, posts::dsl::*}, }; -/// Represents a post contained within the database. #[derive(Queryable)] pub struct Post { @@ -20,7 +17,6 @@ pub struct Post pub content: String, } -/// Represents a new post to be added to the database. #[derive(Insertable)] #[table_name = "posts"] pub struct NewPost diff --git a/src/db/sections.rs b/src/db/sections.rs index ca8956b..b429c85 100644 --- a/src/db/sections.rs +++ b/src/db/sections.rs @@ -23,7 +23,7 @@ pub struct Section /// A new section to be added into the database. #[derive(Deserialize, Insertable)] #[table_name = "sections"] -// #[serde(rename_all = "camelCase")] +#[serde(rename_all = "camelCase")] pub struct NewSection { title: String, diff --git a/web/package.json b/web/package.json index 6dfbfa6..b1070aa 100644 --- a/web/package.json +++ b/web/package.json @@ -7,7 +7,9 @@ "build": "astro build" }, "devDependencies": { + "@astrojs/renderer-svelte": "^0.1.1", "astro": "0.19.0-next.2", - "@astrojs/renderer-svelte": "^0.1.1" + "miragejs": "^0.1.41", + "typescript": "^4.4.3" } } diff --git a/web/src/components/MirageTest.svelte b/web/src/components/MirageTest.svelte new file mode 100644 index 0000000..ac3676b --- /dev/null +++ b/web/src/components/MirageTest.svelte @@ -0,0 +1,19 @@ + + + diff --git a/web/src/components/SvelteCounter.svelte b/web/src/components/SvelteCounter.svelte index f493c25..ea6cf52 100644 --- a/web/src/components/SvelteCounter.svelte +++ b/web/src/components/SvelteCounter.svelte @@ -1,4 +1,4 @@ - + + diff --git a/web2/package.json b/web2/package.json new file mode 100644 index 0000000..4a7220b --- /dev/null +++ b/web2/package.json @@ -0,0 +1,18 @@ +{ + "name": "rusty-bever", + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vue-tsc --noEmit && vite build", + "serve": "vite preview" + }, + "dependencies": { + "vue": "^3.2.16" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^1.9.3", + "typescript": "^4.4.3", + "vite": "^2.6.4", + "vue-tsc": "^0.3.0" + } +} \ No newline at end of file diff --git a/web2/public/favicon.ico b/web2/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..df36fcfb72584e00488330b560ebcf34a41c64c2 GIT binary patch literal 4286 zcmds*O-Phc6o&64GDVCEQHxsW(p4>LW*W<827=Unuo8sGpRux(DN@jWP-e29Wl%wj zY84_aq9}^Am9-cWTD5GGEo#+5Fi2wX_P*bo+xO!)p*7B;iKlbFd(U~_d(U?#hLj56 zPhFkj-|A6~Qk#@g^#D^U0XT1cu=c-vu1+SElX9NR;kzAUV(q0|dl0|%h|dI$%VICy zJnu2^L*Te9JrJMGh%-P79CL0}dq92RGU6gI{v2~|)p}sG5x0U*z<8U;Ij*hB9z?ei z@g6Xq-pDoPl=MANPiR7%172VA%r)kevtV-_5H*QJKFmd;8yA$98zCxBZYXTNZ#QFk2(TX0;Y2dt&WitL#$96|gJY=3xX zpCoi|YNzgO3R`f@IiEeSmKrPSf#h#Qd<$%Ej^RIeeYfsxhPMOG`S`Pz8q``=511zm zAm)MX5AV^5xIWPyEu7u>qYs?pn$I4nL9J!=K=SGlKLXpE<5x+2cDTXq?brj?n6sp= zphe9;_JHf40^9~}9i08r{XM$7HB!`{Ys~TK0kx<}ZQng`UPvH*11|q7&l9?@FQz;8 zx!=3<4seY*%=OlbCbcae?5^V_}*K>Uo6ZWV8mTyE^B=DKy7-sdLYkR5Z?paTgK-zyIkKjIcpyO z{+uIt&YSa_$QnN_@t~L014dyK(fOOo+W*MIxbA6Ndgr=Y!f#Tokqv}n<7-9qfHkc3 z=>a|HWqcX8fzQCT=dqVbogRq!-S>H%yA{1w#2Pn;=e>JiEj7Hl;zdt-2f+j2%DeVD zsW0Ab)ZK@0cIW%W7z}H{&~yGhn~D;aiP4=;m-HCo`BEI+Kd6 z={Xwx{TKxD#iCLfl2vQGDitKtN>z|-AdCN|$jTFDg0m3O`WLD4_s#$S literal 0 HcmV?d00001 diff --git a/web2/src/App.vue b/web2/src/App.vue new file mode 100644 index 0000000..df4e2d7 --- /dev/null +++ b/web2/src/App.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/web2/src/assets/logo.png b/web2/src/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d2503fc2a44b5053b0837ebea6e87a2d339a43 GIT binary patch literal 6849 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 +import { ref } from 'vue' + +defineProps<{ msg: string }>() + +const count = ref(0) + + + + + diff --git a/web2/src/env.d.ts b/web2/src/env.d.ts new file mode 100644 index 0000000..d27eb5a --- /dev/null +++ b/web2/src/env.d.ts @@ -0,0 +1,8 @@ +/// + +declare module '*.vue' { + import { DefineComponent } from 'vue' + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/web2/src/main.ts b/web2/src/main.ts new file mode 100644 index 0000000..01433bc --- /dev/null +++ b/web2/src/main.ts @@ -0,0 +1,4 @@ +import { createApp } from 'vue' +import App from './App.vue' + +createApp(App).mount('#app') diff --git a/web2/tsconfig.json b/web2/tsconfig.json new file mode 100644 index 0000000..8617c8a --- /dev/null +++ b/web2/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "esnext", + "useDefineForClassFields": true, + "module": "esnext", + "moduleResolution": "node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "lib": ["esnext", "dom"] + }, + "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"] +} diff --git a/web2/vite.config.ts b/web2/vite.config.ts new file mode 100644 index 0000000..315212d --- /dev/null +++ b/web2/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()] +}) diff --git a/web2/yarn.lock b/web2/yarn.lock new file mode 100644 index 0000000..25336fa --- /dev/null +++ b/web2/yarn.lock @@ -0,0 +1,887 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/helper-validator-identifier@^7.14.9": + version "7.15.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" + integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== + +"@babel/parser@^7.15.0", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6": + version "7.15.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016" + integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA== + +"@babel/types@^7.6.1", "@babel/types@^7.9.6": + version "7.15.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" + integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== + dependencies: + "@babel/helper-validator-identifier" "^7.14.9" + to-fast-properties "^2.0.0" + +"@emmetio/abbreviation@^2.2.2": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@emmetio/abbreviation/-/abbreviation-2.2.2.tgz#746762fd9e7a8c2ea604f580c62e3cfe250e6989" + integrity sha512-TtE/dBnkTCct8+LntkqVrwqQao6EnPAs1YN3cUgxOxTaBlesBCY37ROUAVZrRlG64GNnVShdl/b70RfAI3w5lw== + dependencies: + "@emmetio/scanner" "^1.0.0" + +"@emmetio/css-abbreviation@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@emmetio/css-abbreviation/-/css-abbreviation-2.1.4.tgz#90362e8a1122ce3b76f6c3157907d30182f53f54" + integrity sha512-qk9L60Y+uRtM5CPbB0y+QNl/1XKE09mSO+AhhSauIfr2YOx/ta3NJw2d8RtCFxgzHeRqFRr8jgyzThbu+MZ4Uw== + dependencies: + "@emmetio/scanner" "^1.0.0" + +"@emmetio/scanner@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@emmetio/scanner/-/scanner-1.0.0.tgz#065b2af6233fe7474d44823e3deb89724af42b5f" + integrity sha512-8HqW8EVqjnCmWXVpqAOZf+EGESdkR27odcMMMGefgKXtar00SoYNSryGv//TELI4T3QFsECo78p+0lmalk/CFA== + +"@vitejs/plugin-vue@^1.9.3": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-1.9.3.tgz#93d61893ce6c723d0209af0483ec8b91a2cd811f" + integrity sha512-yW6H/q+4Mc2PcVjSOelcsMrg/k15DnMUz8jyCFsI04emc3aLwo4AoofUfGnjHUkgirrDxSJLVqQVGhonQ3yykA== + +"@volar/code-gen@^0.27.24": + version "0.27.24" + resolved "https://registry.yarnpkg.com/@volar/code-gen/-/code-gen-0.27.24.tgz#ccdbe858951c1ee4e0c3979232d52412dc46756a" + integrity sha512-s4j/QqOZUW03PeD6LmVYI00Q1C3CfJEOePDOQwDvCTUov4lFk0iSBtFyYhjlLyQ1pdtV1+TDTErkj2aMQtc4PA== + dependencies: + "@volar/shared" "^0.27.24" + "@volar/source-map" "^0.27.24" + +"@volar/html2pug@^0.27.13": + version "0.27.13" + resolved "https://registry.yarnpkg.com/@volar/html2pug/-/html2pug-0.27.13.tgz#48dfa73ecf1ef1955a02a046d0c88845950fac85" + integrity sha512-3NYgNA5F3PDsKbbpOrVdGy2S7ZYmZIbFmbp1A/27DDzjj/uIC9Pj7HXVvbYOzi8HcOxUPt0BMrh4TVzBUaCFww== + dependencies: + domelementtype "^2.2.0" + domhandler "^4.2.0" + htmlparser2 "^6.1.0" + pug "^3.0.2" + +"@volar/shared@^0.27.24": + version "0.27.24" + resolved "https://registry.yarnpkg.com/@volar/shared/-/shared-0.27.24.tgz#a33457ec8ac0b0d367ed54c9e21913a5f8c2d6c2" + integrity sha512-Mi8a4GQaiorfb+o4EqOXDZm9E/uBJXgScFgF+NhtcMBOUKHNMKQyLI7YRGumtyJTTdaX7nSDJjGGTkv23tcOtQ== + dependencies: + upath "^2.0.1" + vscode-jsonrpc "^8.0.0-next.2" + vscode-uri "^3.0.2" + +"@volar/source-map@^0.27.24": + version "0.27.24" + resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-0.27.24.tgz#60f2e070c169be82cbf7ffa296a30c2823c5205f" + integrity sha512-2I5a7cXqekZ66D6lHep7ttJgvVVtPEBUIe1hnpcGbnXWNA2ya6f6jKNNyTmrXQyfkh32IEuaUd4kocR+3AKMag== + dependencies: + "@volar/shared" "^0.27.24" + +"@volar/transforms@^0.27.24": + version "0.27.24" + resolved "https://registry.yarnpkg.com/@volar/transforms/-/transforms-0.27.24.tgz#68ebc53dca2e36884e247c0866ec3d24ed815784" + integrity sha512-sOHi1ZSapFlxn7yPl4MO5TXd9aWC0BVq2CgXAJ2EESb+ddh2uJbGQgLLNocX+MDh419cUuuFT2QAJpuWHhJcng== + dependencies: + "@volar/shared" "^0.27.24" + vscode-languageserver "^8.0.0-next.2" + +"@vscode/emmet-helper@^2.7.0": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@vscode/emmet-helper/-/emmet-helper-2.7.0.tgz#3db485f6a650196ff8bbd38ba1b9e468ec8d22f8" + integrity sha512-LL7MoKNLUQASacQROO7hBdx5IAxsEnA0UdJFd9xXyf3sBQgz8NE3QEfo3IezE7uin8W2fkG2+EXMst3oqK6+KQ== + dependencies: + emmet "^2.3.0" + jsonc-parser "^2.3.0" + vscode-languageserver-textdocument "^1.0.1" + vscode-languageserver-types "^3.15.1" + vscode-nls "^5.0.0" + vscode-uri "^2.1.2" + +"@vue/compiler-core@3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.19.tgz#b537dd377ce51fdb64e9b30ebfbff7cd70a64cb9" + integrity sha512-8dOPX0YOtaXol0Zf2cfLQ4NU/yHYl2H7DCKsLEZ7gdvPK6ZSEwGLJ7IdghhY2YEshEpC5RB9QKdC5I07z8Dtjg== + dependencies: + "@babel/parser" "^7.15.0" + "@vue/shared" "3.2.19" + estree-walker "^2.0.2" + source-map "^0.6.1" + +"@vue/compiler-dom@3.2.19", "@vue/compiler-dom@^3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.19.tgz#0607bc90de6af55fde73b09b3c4d0bf8cb597ed8" + integrity sha512-WzQoE8rfkFjPtIioc7SSgTsnz9g2oG61DU8KHnzPrRS7fW/lji6H2uCYJfp4Z6kZE8GjnHc1Ljwl3/gxDes0cw== + dependencies: + "@vue/compiler-core" "3.2.19" + "@vue/shared" "3.2.19" + +"@vue/compiler-sfc@3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.19.tgz#d412195a98ebd49b84602f171719294a1d9549be" + integrity sha512-pLlbgkO1UHTO02MSpa/sFOXUwIDxSMiKZ1ozE5n71CY4DM+YmI+G3gT/ZHZ46WBId7f3VTF/D8pGwMygcQbrQA== + dependencies: + "@babel/parser" "^7.15.0" + "@vue/compiler-core" "3.2.19" + "@vue/compiler-dom" "3.2.19" + "@vue/compiler-ssr" "3.2.19" + "@vue/ref-transform" "3.2.19" + "@vue/shared" "3.2.19" + estree-walker "^2.0.2" + magic-string "^0.25.7" + postcss "^8.1.10" + source-map "^0.6.1" + +"@vue/compiler-ssr@3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.19.tgz#3e91ecf70f8f961c5f63eacd2139bcdab9a7a07c" + integrity sha512-oLon0Cn3O7WEYzzmzZavGoqXH+199LT+smdjBT3Uf3UX4HwDNuBFCmvL0TsqV9SQnIgKvBRbQ7lhbpnd4lqM3w== + dependencies: + "@vue/compiler-dom" "3.2.19" + "@vue/shared" "3.2.19" + +"@vue/reactivity@3.2.19", "@vue/reactivity@^3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.19.tgz#fc6e0f0106f295226835cfed5ff5f84d927bea65" + integrity sha512-FtachoYs2SnyrWup5UikP54xDX6ZJ1s5VgHcJp4rkGoutU3Ry61jhs+nCX7J64zjX992Mh9gGUC0LqTs8q9vCA== + dependencies: + "@vue/shared" "3.2.19" + +"@vue/ref-transform@3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/ref-transform/-/ref-transform-3.2.19.tgz#cf0f986486bb26838fbd09749e927bab19745600" + integrity sha512-03wwUnoIAeKti5IGGx6Vk/HEBJ+zUcm5wrUM3+PQsGf7IYnXTbeIfHHpx4HeSeWhnLAjqZjADQwW8uA4rBmVbg== + dependencies: + "@babel/parser" "^7.15.0" + "@vue/compiler-core" "3.2.19" + "@vue/shared" "3.2.19" + estree-walker "^2.0.2" + magic-string "^0.25.7" + +"@vue/runtime-core@3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.19.tgz#807715b7f4728abb84fa4a8efdbe37d8ddb4c6d3" + integrity sha512-qArZSWKxWsgKfxk9BelZ32nY0MZ31CAW2kUUyVJyxh4cTfHaXGbjiQB5JgsvKc49ROMNffv9t3/qjasQqAH+RQ== + dependencies: + "@vue/reactivity" "3.2.19" + "@vue/shared" "3.2.19" + +"@vue/runtime-dom@3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.19.tgz#7e8bf645754703e360fa132e4be9113edf2377bb" + integrity sha512-hIRboxXwafeHhbZEkZYNV0MiJXPNf4fP0X6hM2TJb0vssz8BKhD9cF92BkRgZztTQevecbhk0gu4uAPJ3dxL9A== + dependencies: + "@vue/runtime-core" "3.2.19" + "@vue/shared" "3.2.19" + csstype "^2.6.8" + +"@vue/server-renderer@3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.19.tgz#870bcec9f7cdaee0c2187a169b6e636ab4362fb1" + integrity sha512-A9FNT7fgQJXItwdzWREntAgWKVtKYuXHBKGev/H4+ByTu8vB7gQXGcim01QxaJshdNg4dYuH2tEBZXCNCNx+/w== + dependencies: + "@vue/compiler-ssr" "3.2.19" + "@vue/shared" "3.2.19" + +"@vue/shared@3.2.19", "@vue/shared@^3.2.19": + version "3.2.19" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.19.tgz#111ec3da18337d86274446984c49925b1b2b2dd7" + integrity sha512-Knqhx7WieLdVgwCAZgTVrDCXZ50uItuecLh9JdLC8O+a5ayaSyIQYveUK3hCRNC7ws5zalHmZwfdLMGaS8r4Ew== + +acorn@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +assert-never@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" + integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== + +babel-walk@3.0.0-canary-5: + version "3.0.0-canary-5" + resolved "https://registry.yarnpkg.com/babel-walk/-/babel-walk-3.0.0-canary-5.tgz#f66ecd7298357aee44955f235a6ef54219104b11" + integrity sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw== + dependencies: + "@babel/types" "^7.9.6" + +call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +character-parser@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" + integrity sha1-x84o821LzZdE5f/CxfzeHHMmH8A= + dependencies: + is-regex "^1.0.3" + +constantinople@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151" + integrity sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw== + dependencies: + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.1" + +csstype@^2.6.8: + version "2.6.18" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.18.tgz#980a8b53085f34af313410af064f2bd241784218" + integrity sha512-RSU6Hyeg14am3Ah4VZEmeX8H7kLwEEirXe6aU2IPfKNvhXwTflK5HQRDNI0ypQXoqmm+QPyG2IaPuQE5zMwSIQ== + +doctypes@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" + integrity sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk= + +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domhandler@^4.0.0, domhandler@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f" + integrity sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.5.2: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +emmet@^2.3.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/emmet/-/emmet-2.3.4.tgz#5ba0d7a5569a68c7697dfa890c772e4f3179d123" + integrity sha512-3IqSwmO+N2ZGeuhDyhV/TIOJFUbkChi53bcasSNRE7Yd+4eorbbYz4e53TpMECt38NtYkZNupQCZRlwdAYA42A== + dependencies: + "@emmetio/abbreviation" "^2.2.2" + "@emmetio/css-abbreviation" "^2.1.4" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +esbuild-android-arm64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.4.tgz#5178a20d2b7aba741a31c19609f9e67b346996b9" + integrity sha512-elDJt+jNyoHFId0/dKsuVYUPke3EcquIyUwzJCH17a3ERglN3A9aMBI5zbz+xNZ+FbaDNdpn0RaJHCFLbZX+fA== + +esbuild-darwin-64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.4.tgz#7a3e66c8e1271b650541b25eed65c84f3564a69d" + integrity sha512-zJQGyHRAdZUXlRzbN7W+7ykmEiGC+bq3Gc4GxKYjjWTgDRSEly98ym+vRNkDjXwXYD3gGzSwvH35+MiHAtWvLA== + +esbuild-darwin-arm64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.4.tgz#793feca6032b2a57ef291eb9b2d33768d60a49d6" + integrity sha512-r8oYvAtqSGq8HNTZCAx4TdLE7jZiGhX9ooGi5AQAey37MA6XNaP8ZNlw9OCpcgpx3ryU2WctXwIqPzkHO7a8dg== + +esbuild-freebsd-64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.4.tgz#294aec3c2cf4b41fb6900212fc9c33dd8fbbb4a2" + integrity sha512-u9DRGkn09EN8+lCh6z7FKle7awi17PJRBuAKdRNgSo5ZrH/3m+mYaJK2PR2URHMpAfXiwJX341z231tSdVe3Yw== + +esbuild-freebsd-arm64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.4.tgz#09fe66c751c12f9b976976b1d83f3de594cb2787" + integrity sha512-q3B2k68Uf6gfjATjcK16DqxvjqRQkHL8aPoOfj4op+lSqegdXvBacB1d8jw8PxbWJ8JHpdTLdAVUYU80kotQXA== + +esbuild-linux-32@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.4.tgz#a9f0793d7bcc9cef4f4ffa4398c525877fba5839" + integrity sha512-UUYJPHSiKAO8KoN3Ls/iZtgDLZvK5HarES96aolDPWZnq9FLx4dIHM/x2z4Rxv9IYqQ/DxlPoE2Co1UPBIYYeA== + +esbuild-linux-64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.4.tgz#c0d0b4c9d62e3bbf8bdf2cece37403aa6d60fc2e" + integrity sha512-+RnohAKiiUW4UHLGRkNR1AnENW1gCuDWuygEtd4jxTNPIoeC7lbXGor7rtgjj9AdUzFgOEvAXyNNX01kJ8NueQ== + +esbuild-linux-arm64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.4.tgz#1292d97bfa64a08d12728f8a7837bf92776c779b" + integrity sha512-+A188cAdd6QuSRxMIwRrWLjgphQA0LDAQ/ECVlrPVJwnx+1i64NjDZivoqPYLOTkSPIKntiWwMhhf0U5/RrPHQ== + +esbuild-linux-arm@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.4.tgz#186cd9b8885ac132b9953a4a0afe668168debd10" + integrity sha512-BH5gKve4jglS7UPSsfwHSX79I5agC/lm4eKoRUEyo8lwQs89frQSRp2Xup+6SFQnxt3md5EsKcd2Dbkqeb3gPA== + +esbuild-linux-mips64le@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.4.tgz#42049bf72bc586817b4a51cc9e32148d13e5e807" + integrity sha512-0xkwtPaUkG5xMTFGaQPe1AadSe5QAiQuD4Gix1O9k5Xo/U8xGIkw9UFUTvfEUeu71vFb6ZgsIacfP1NLoFjWNw== + +esbuild-linux-ppc64le@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.4.tgz#adf1ce2ef2302757c4383887da6ac4dd25be9d4f" + integrity sha512-E1+oJPP7A+j23GPo3CEpBhGwG1bni4B8IbTA3/3rvzjURwUMZdcN3Fhrz24rnjzdLSHmULtOE4VsbT42h1Om4Q== + +esbuild-openbsd-64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.4.tgz#1c8122101898c52a20c8786935cf3eb7a19b83b4" + integrity sha512-xEkI1o5HYxDzbv9jSox0EsDxpwraG09SRiKKv0W8pH6O3bt+zPSlnoK7+I7Q69tkvONkpIq5n2o+c55uq0X7cw== + +esbuild-sunos-64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.4.tgz#4ec95faa14a60f295fe485bebffefff408739337" + integrity sha512-bjXUMcODMnB6hQicLBBmmnBl7OMDyVpFahKvHGXJfDChIi5udiIRKCmFUFIRn+AUAKVlfrofRKdyPC7kBsbvGQ== + +esbuild-windows-32@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.4.tgz#3182c380487b797b04d0ec2c80c2945666869080" + integrity sha512-z4CH07pfyVY0XF98TCsGmLxKCl0kyvshKDbdpTekW9f2d+dJqn5mmoUyWhpSVJ0SfYWJg86FoD9nMbbaMVyGdg== + +esbuild-windows-64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.4.tgz#b9e995f92d81f433a04f33611e603e82f9232e69" + integrity sha512-uVL11vORRPjocGLYam67rwFLd0LvkrHEs+JG+1oJN4UD9MQmNGZPa4gBHo6hDpF+kqRJ9kXgQSeDqUyRy0tj/Q== + +esbuild-windows-arm64@0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.4.tgz#fb239532f07b764d158f4cc787178ef4c6fadb5c" + integrity sha512-vA6GLvptgftRcDcWngD5cMlL4f4LbL8JjU2UMT9yJ0MT5ra6hdZNFWnOeOoEtY4GtJ6OjZ0i+81sTqhAB0fMkg== + +esbuild@^0.13.2: + version "0.13.4" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.13.4.tgz#ce2deb56c4fb360938311cbfc67f8e467bb6841b" + integrity sha512-wMA5eUwpavTBiNl+It6j8OQuKVh69l6z4DKDLzoTIqC+gChnPpcmqdA8WNHptUHRnfyML+mKEQPlW7Mybj8gHg== + optionalDependencies: + esbuild-android-arm64 "0.13.4" + esbuild-darwin-64 "0.13.4" + esbuild-darwin-arm64 "0.13.4" + esbuild-freebsd-64 "0.13.4" + esbuild-freebsd-arm64 "0.13.4" + esbuild-linux-32 "0.13.4" + esbuild-linux-64 "0.13.4" + esbuild-linux-arm "0.13.4" + esbuild-linux-arm64 "0.13.4" + esbuild-linux-mips64le "0.13.4" + esbuild-linux-ppc64le "0.13.4" + esbuild-openbsd-64 "0.13.4" + esbuild-sunos-64 "0.13.4" + esbuild-windows-32 "0.13.4" + esbuild-windows-64 "0.13.4" + esbuild-windows-arm64 "0.13.4" + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +is-core-module@^2.2.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" + integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== + dependencies: + has "^1.0.3" + +is-expression@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" + integrity sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A== + dependencies: + acorn "^7.1.1" + object-assign "^4.1.1" + +is-promise@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + +is-regex@^1.0.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +js-stringify@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" + integrity sha1-Fzb939lyTyijaCrcYjCufk6Weds= + +jsonc-parser@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.1.tgz#59549150b133f2efacca48fe9ce1ec0659af2342" + integrity sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg== + +jsonc-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== + +jstransformer@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" + integrity sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM= + dependencies: + is-promise "^2.0.0" + promise "^7.0.1" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +magic-string@^0.25.7: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== + dependencies: + sourcemap-codec "^1.4.4" + +nanoid@^3.1.28: + version "3.1.29" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.29.tgz#214fb2d7a33e1a5bef4757b779dfaeb6a4e5aeb4" + integrity sha512-dW2pUSGZ8ZnCFIlBIA31SV8huOGCHb6OwzVCc7A69rb/a+SgPBwfmLvK5TKQ3INPbRkcI8a/Owo0XbiTNH19wg== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + +postcss@^8.1.10, postcss@^8.3.8: + version "8.3.9" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.9.tgz#98754caa06c4ee9eb59cc48bd073bb6bd3437c31" + integrity sha512-f/ZFyAKh9Dnqytx5X62jgjhhzttjZS7hMsohcI7HEI5tjELX/HxCy3EFhsRxyzGvrzFF+82XPvCS8T9TFleVJw== + dependencies: + nanoid "^3.1.28" + picocolors "^0.2.1" + source-map-js "^0.6.2" + +promise@^7.0.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +pug-attrs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41" + integrity sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA== + dependencies: + constantinople "^4.0.1" + js-stringify "^1.0.2" + pug-runtime "^3.0.0" + +pug-code-gen@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-3.0.2.tgz#ad190f4943133bf186b60b80de483100e132e2ce" + integrity sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg== + dependencies: + constantinople "^4.0.1" + doctypes "^1.1.0" + js-stringify "^1.0.2" + pug-attrs "^3.0.0" + pug-error "^2.0.0" + pug-runtime "^3.0.0" + void-elements "^3.1.0" + with "^7.0.0" + +pug-error@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-2.0.0.tgz#5c62173cb09c34de2a2ce04f17b8adfec74d8ca5" + integrity sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ== + +pug-filters@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-4.0.0.tgz#d3e49af5ba8472e9b7a66d980e707ce9d2cc9b5e" + integrity sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A== + dependencies: + constantinople "^4.0.1" + jstransformer "1.0.0" + pug-error "^2.0.0" + pug-walk "^2.0.0" + resolve "^1.15.1" + +pug-lexer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-5.0.1.tgz#ae44628c5bef9b190b665683b288ca9024b8b0d5" + integrity sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w== + dependencies: + character-parser "^2.2.0" + is-expression "^4.0.0" + pug-error "^2.0.0" + +pug-linker@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-4.0.0.tgz#12cbc0594fc5a3e06b9fc59e6f93c146962a7708" + integrity sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw== + dependencies: + pug-error "^2.0.0" + pug-walk "^2.0.0" + +pug-load@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-3.0.0.tgz#9fd9cda52202b08adb11d25681fb9f34bd41b662" + integrity sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ== + dependencies: + object-assign "^4.1.1" + pug-walk "^2.0.0" + +pug-parser@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-6.0.0.tgz#a8fdc035863a95b2c1dc5ebf4ecf80b4e76a1260" + integrity sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw== + dependencies: + pug-error "^2.0.0" + token-stream "1.0.0" + +pug-runtime@^3.0.0, pug-runtime@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-3.0.1.tgz#f636976204723f35a8c5f6fad6acda2a191b83d7" + integrity sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg== + +pug-strip-comments@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz#f94b07fd6b495523330f490a7f554b4ff876303e" + integrity sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ== + dependencies: + pug-error "^2.0.0" + +pug-walk@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-2.0.0.tgz#417aabc29232bb4499b5b5069a2b2d2a24d5f5fe" + integrity sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ== + +pug@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pug/-/pug-3.0.2.tgz#f35c7107343454e43bc27ae0ff76c731b78ea535" + integrity sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw== + dependencies: + pug-code-gen "^3.0.2" + pug-filters "^4.0.0" + pug-lexer "^5.0.1" + pug-linker "^4.0.0" + pug-load "^3.0.0" + pug-parser "^6.0.0" + pug-runtime "^3.0.1" + pug-strip-comments "^2.0.0" + +request-light@^0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.4.tgz#497a98c6d8ae49536417a5e2d7f383b934f3e38c" + integrity sha512-t3566CMweOFlUk7Y1DJMu5OrtpoZEb6aSTsLQVT3wtrIEJ5NhcY9G/Oqxvjllzl4a15zXfFlcr9q40LbLVQJqw== + +resolve@^1.15.1, resolve@^1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +rollup@^2.57.0: + version "2.58.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.58.0.tgz#a643983365e7bf7f5b7c62a8331b983b7c4c67fb" + integrity sha512-NOXpusKnaRpbS7ZVSzcEXqxcLDOagN6iFS8p45RkoiMqPHDLwJm758UF05KlMoCRbLBTZsPOIa887gZJ1AiXvw== + optionalDependencies: + fsevents "~2.3.2" + +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + +source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +token-stream@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4" + integrity sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ= + +typescript@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324" + integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA== + +upath@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" + integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== + +vite@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/vite/-/vite-2.6.4.tgz#b932735f1ecdf69256ce6eaae0d41a7b15d77599" + integrity sha512-zNGZgjKGprdLKJ1g1taAvNt51JbGAdrAUU9hpLzgtlks+cXBxTZUsEAGEtLbF3UvlYOVAPXS8r9E9gxYAv6z+A== + dependencies: + esbuild "^0.13.2" + postcss "^8.3.8" + resolve "^1.20.0" + rollup "^2.57.0" + optionalDependencies: + fsevents "~2.3.2" + +void-elements@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= + +vscode-css-languageservice@^5.1.4: + version "5.1.7" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-5.1.7.tgz#ebbf803b03fde539bd683588cd2da6c4a61b90e2" + integrity sha512-h4oafcZaGFe2VtbNIlkZDmLEP0GQha3E5Ct2YMH4p/p9xYC8yWDNQ5CD+VF3UnSijKPSKmA+oc4cKjhJBowGKw== + dependencies: + vscode-languageserver-textdocument "^1.0.1" + vscode-languageserver-types "^3.16.0" + vscode-nls "^5.0.0" + vscode-uri "^3.0.2" + +vscode-html-languageservice@^4.0.7: + version "4.1.0" + resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-4.1.0.tgz#e1662f1ff3b623b910c54d3f4a2aad8f397e53d7" + integrity sha512-QQrEKfpfbeglD8Jcai4fQDQ7vOJrN6LyiOs47Y6qAxnhve+ervw1kP2UCt9ohHe/6teNWJDYTGxLDgs5iAvitw== + dependencies: + vscode-languageserver-textdocument "^1.0.1" + vscode-languageserver-types "^3.16.0" + vscode-nls "^5.0.0" + vscode-uri "^3.0.2" + +vscode-json-languageservice@^4.1.7: + version "4.1.8" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.1.8.tgz#397a39238d496e3e08a544a8b93df2cd13347d0c" + integrity sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg== + dependencies: + jsonc-parser "^3.0.0" + vscode-languageserver-textdocument "^1.0.1" + vscode-languageserver-types "^3.16.0" + vscode-nls "^5.0.0" + vscode-uri "^3.0.2" + +vscode-jsonrpc@8.0.0-next.2, vscode-jsonrpc@^8.0.0-next.2: + version "8.0.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.0-next.2.tgz#285fc294be586e4768acd67e5a42efc738a5cac0" + integrity sha512-gxUyTBAjmwGkiHW/UaRScre2s4i98P8M7gnc3VB4DrVQUm3vQ0idi2cN9nbkfcjATx+uEt8C22j+MLN/8UzsJA== + +vscode-languageserver-protocol@3.17.0-next.8: + version "3.17.0-next.8" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.8.tgz#ef2eb7423b474cccd11384239de24488e7fe818c" + integrity sha512-P89vSuJ+FA5JzFmcOoZN13Ig1yd6LsiPOig0O5m5BSGuO/rplQegCd9J0wKpaTy7trf/SYHRoypnbUBdzy14sg== + dependencies: + vscode-jsonrpc "8.0.0-next.2" + vscode-languageserver-types "3.17.0-next.3" + +vscode-languageserver-textdocument@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz#178168e87efad6171b372add1dea34f53e5d330f" + integrity sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA== + +vscode-languageserver-types@3.17.0-next.3: + version "3.17.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.3.tgz#e1f4311e08ea3193e81126154b6a342fc1c3dba3" + integrity sha512-VQcXnhKYxUW6OiRMhG++SzmZYMJwusXknJGd+FfdOnS1yHAo734OHyR0e2eEHDlv0/oWc8RZPgx/VKSKyondVg== + +vscode-languageserver-types@^3.15.1, vscode-languageserver-types@^3.16.0: + version "3.16.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247" + integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA== + +vscode-languageserver@^8.0.0-next.2: + version "8.0.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.0-next.2.tgz#3a3daf79ff10350ea9cec5c73b5302901a955117" + integrity sha512-7qCEXTeGZKkI8BGvlKh0JPXTY7BaWoiwQYKCcGaUgnMs34wt6F/yaKcxoC3XIouBBVyRxiI6Ml/JdztM3XYEaA== + dependencies: + vscode-languageserver-protocol "3.17.0-next.8" + +vscode-nls@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840" + integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA== + +vscode-pug-languageservice@^0.27.24: + version "0.27.24" + resolved "https://registry.yarnpkg.com/vscode-pug-languageservice/-/vscode-pug-languageservice-0.27.24.tgz#fa805c4d3e33dee3681e660a0767136738e68370" + integrity sha512-GSvsFB+rPhAD7cBlEKCVNNsFGIaOnp/0zyLw3WpYbXY24vJZafXu1kHvtYaaQXJRnIhqp5EI5p+EqpdI3hTBnw== + dependencies: + "@volar/code-gen" "^0.27.24" + "@volar/shared" "^0.27.24" + "@volar/source-map" "^0.27.24" + "@volar/transforms" "^0.27.24" + pug-lexer "^5.0.1" + pug-parser "^6.0.0" + vscode-languageserver "^8.0.0-next.2" + +vscode-typescript-languageservice@^0.27.25: + version "0.27.25" + resolved "https://registry.yarnpkg.com/vscode-typescript-languageservice/-/vscode-typescript-languageservice-0.27.25.tgz#acd211723b600108c25515388b75d55ce15bb056" + integrity sha512-nxpJI9MnF2rn5rKL/032Qrsq3T9DgM3slK5fwZp3suNdo90JG2zFTs3Ola8n62k7+KWu4A775obxyb4wLIW6Gw== + dependencies: + "@volar/shared" "^0.27.24" + semver "^7.3.5" + upath "^2.0.1" + vscode-languageserver "^8.0.0-next.2" + vscode-languageserver-textdocument "^1.0.1" + +vscode-uri@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c" + integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A== + +vscode-uri@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.2.tgz#ecfd1d066cb8ef4c3a208decdbab9a8c23d055d0" + integrity sha512-jkjy6pjU1fxUvI51P+gCsxg1u2n8LSt0W6KrCNQceaziKzff74GoWmjVG46KieVzybO1sttPQmYfrwSHey7GUA== + +vscode-vue-languageservice@^0.27.0: + version "0.27.30" + resolved "https://registry.yarnpkg.com/vscode-vue-languageservice/-/vscode-vue-languageservice-0.27.30.tgz#1f32b0203dd233582f74a457428519a6318f039e" + integrity sha512-nPnUNCMqqHfxcCPLyLWvmgbNCgos3SwvPcl/CzAnMbqcjLtNZppsdI7bKX3EEj0Jbg6SGLQ9NanIvZaMI1bsUA== + dependencies: + "@volar/code-gen" "^0.27.24" + "@volar/html2pug" "^0.27.13" + "@volar/shared" "^0.27.24" + "@volar/source-map" "^0.27.24" + "@volar/transforms" "^0.27.24" + "@vscode/emmet-helper" "^2.7.0" + "@vue/compiler-dom" "^3.2.19" + "@vue/reactivity" "^3.2.19" + "@vue/shared" "^3.2.19" + request-light "^0.5.4" + upath "^2.0.1" + vscode-css-languageservice "^5.1.4" + vscode-html-languageservice "^4.0.7" + vscode-json-languageservice "^4.1.7" + vscode-languageserver "^8.0.0-next.2" + vscode-languageserver-textdocument "^1.0.1" + vscode-pug-languageservice "^0.27.24" + vscode-typescript-languageservice "^0.27.25" + +vue-tsc@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/vue-tsc/-/vue-tsc-0.3.0.tgz#3b3872bf4f1d2e4409b57adbd826032e253db406" + integrity sha512-zaDRZBxwRIz1XjhNP92FqugG71st6BUMnA2EwPeXrAyzbEYVRz6TezNFceYl3QYqqN8CtaxbqUhaQEDj/ntoCA== + dependencies: + vscode-vue-languageservice "^0.27.0" + +vue@^3.2.16: + version "3.2.19" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.19.tgz#da2c80a6a0271c7097fee9e31692adfd9d569c8f" + integrity sha512-6KAMdIfAtlK+qohTIUE4urwAv4A3YRuo8uAbByApUmiB0CziGAAPs6qVugN6oHPia8YIafHB/37K0O6KZ7sGmA== + dependencies: + "@vue/compiler-dom" "3.2.19" + "@vue/compiler-sfc" "3.2.19" + "@vue/runtime-dom" "3.2.19" + "@vue/server-renderer" "3.2.19" + "@vue/shared" "3.2.19" + +with@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" + integrity sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w== + dependencies: + "@babel/parser" "^7.9.6" + "@babel/types" "^7.9.6" + assert-never "^1.2.1" + babel-walk "3.0.0-canary-5" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== From 061a9d9bc68161dd38026cfddf31fd27a4b19ac4 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sat, 9 Oct 2021 22:01:52 +0200 Subject: [PATCH 12/22] Some more stuff --- migrations/2021-09-13-143540_sections/up.sql | 2 + web2/package.json | 4 +- web2/src/components/HelloWorld.vue | 13 + web2/src/main.ts | 5 + web2/src/server.d.ts | 1 + web2/src/server.js | 27 + web2/yarn-error.log | 1121 ++++++++++++++++++ web2/yarn.lock | 180 +++ 8 files changed, 1352 insertions(+), 1 deletion(-) create mode 100644 web2/src/server.d.ts create mode 100644 web2/src/server.js create mode 100644 web2/yarn-error.log diff --git a/migrations/2021-09-13-143540_sections/up.sql b/migrations/2021-09-13-143540_sections/up.sql index 0c5ca76..64b80cb 100644 --- a/migrations/2021-09-13-143540_sections/up.sql +++ b/migrations/2021-09-13-143540_sections/up.sql @@ -4,6 +4,8 @@ create table sections ( -- Title of the section title varchar(255) UNIQUE NOT NULL, + -- Name to use when routing (this just makes for prettier URLs) + shortname varchar(32) UNIQUE NOT NULL, -- Optional description of the section description text, -- Wether to show the section in the default list on the homepage diff --git a/web2/package.json b/web2/package.json index 4a7220b..64c0d5b 100644 --- a/web2/package.json +++ b/web2/package.json @@ -10,9 +10,11 @@ "vue": "^3.2.16" }, "devDependencies": { + "@types/node": "^16.10.3", "@vitejs/plugin-vue": "^1.9.3", + "miragejs": "^0.1.42", "typescript": "^4.4.3", "vite": "^2.6.4", "vue-tsc": "^0.3.0" } -} \ No newline at end of file +} diff --git a/web2/src/components/HelloWorld.vue b/web2/src/components/HelloWorld.vue index 2d61249..2af73ad 100644 --- a/web2/src/components/HelloWorld.vue +++ b/web2/src/components/HelloWorld.vue @@ -4,11 +4,24 @@ import { ref } from 'vue' defineProps<{ msg: string }>() const count = ref(0) +let test = ref("yeet") + +fetch("/api/users").then( + res => { + if (!res.ok) return Promise.reject() + + return res.json() + } +).then( + json => test.value = json +)