Skip to content

Commit

Permalink
Feat: add editPost and fromJson (#17)
Browse files Browse the repository at this point in the history
* Add editPost and fromJson

* Add validation to fromJson and tests

* Bump version

* Fix test
  • Loading branch information
SHAcollision authored Feb 6, 2025
1 parent 1ff90d6 commit 114eb08
Show file tree
Hide file tree
Showing 14 changed files with 292 additions and 130 deletions.
2 changes: 1 addition & 1 deletion pkg/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "pubky-app-specs",
"type": "module",
"description": "Pubky.app Data Model Specifications",
"version": "0.3.0-rc1",
"version": "0.3.0-rc6",
"license": "MIT",
"collaborators": [
"SHAcollision"
Expand Down
24 changes: 16 additions & 8 deletions src/models/blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use serde::{Deserialize, Serialize};

#[cfg(target_arch = "wasm32")]
use crate::traits::ToJson;
use crate::traits::Json;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;

Expand All @@ -31,10 +31,14 @@ impl PubkyAppBlob {
#[cfg(target_arch = "wasm32")]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
impl PubkyAppBlob {
/// Serialize to JSON for WASM.
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = fromJson))]
pub fn from_json(js_value: &JsValue) -> Result<Self, String> {
Self::import_json(js_value)
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toJson))]
pub fn json(&self) -> Result<JsValue, JsValue> {
self.to_json()
pub fn to_json(&self) -> Result<JsValue, String> {
self.export_json()
}

/// Getter for the blob data as a `Uint8Array`.
Expand All @@ -45,7 +49,7 @@ impl PubkyAppBlob {
}

#[cfg(target_arch = "wasm32")]
impl ToJson for PubkyAppBlob {}
impl Json for PubkyAppBlob {}

impl HashId for PubkyAppBlob {
fn get_id_data(&self) -> String {
Expand Down Expand Up @@ -75,9 +79,13 @@ impl HasPath for PubkyAppBlob {
}

impl Validatable for PubkyAppBlob {
fn validate(&self, id: &str) -> Result<(), String> {
// Validate the tag ID
self.validate_id(id)
fn validate(&self, id: Option<&str>) -> Result<(), String> {
// Validate the blob ID
if let Some(id) = id {
self.validate_id(id)?;
};

Ok(())
}
}

Expand Down
24 changes: 16 additions & 8 deletions src/models/bookmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
use serde::{Deserialize, Serialize};

#[cfg(target_arch = "wasm32")]
use crate::traits::ToJson;
use crate::traits::Json;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;

Expand Down Expand Up @@ -42,9 +42,14 @@ impl PubkyAppBookmark {
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
impl PubkyAppBookmark {
/// Serialize to JSON for WASM.
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = fromJson))]
pub fn from_json(js_value: &JsValue) -> Result<Self, String> {
Self::import_json(js_value)
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toJson))]
pub fn json(&self) -> Result<JsValue, JsValue> {
self.to_json()
pub fn to_json(&self) -> Result<JsValue, String> {
self.export_json()
}

/// Getter for `uri`.
Expand All @@ -55,7 +60,7 @@ impl PubkyAppBookmark {
}

#[cfg(target_arch = "wasm32")]
impl ToJson for PubkyAppBookmark {}
impl Json for PubkyAppBookmark {}

impl HashId for PubkyAppBookmark {
/// Bookmark ID is created based on the hash of the URI bookmarked.
Expand All @@ -73,8 +78,11 @@ impl HasPath for PubkyAppBookmark {
}

impl Validatable for PubkyAppBookmark {
fn validate(&self, id: &str) -> Result<(), String> {
self.validate_id(id)?;
fn validate(&self, id: Option<&str>) -> Result<(), String> {
// Validate the bookmark ID
if let Some(id) = id {
self.validate_id(id)?;
}
// Additional bookmark validation can be added here.
Ok(())
}
Expand Down Expand Up @@ -113,15 +121,15 @@ mod tests {
let bookmark =
PubkyAppBookmark::new("pubky://user_id/pub/pubky.app/posts/post_id".to_string());
let id = bookmark.create_id();
let result = bookmark.validate(&id);
let result = bookmark.validate(Some(&id));
assert!(result.is_ok());
}

#[test]
fn test_validate_invalid_id() {
let bookmark = PubkyAppBookmark::new("user_id/pub/pubky.app/posts/post_id".to_string());
let invalid_id = "INVALIDID";
let result = bookmark.validate(invalid_id);
let result = bookmark.validate(Some(invalid_id));
assert!(result.is_err());
}

Expand Down
43 changes: 31 additions & 12 deletions src/models/feed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use std::str::FromStr;

#[cfg(target_arch = "wasm32")]
use crate::traits::ToJson;
use crate::traits::Json;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;

Expand Down Expand Up @@ -67,10 +67,14 @@ pub struct PubkyAppFeedConfig {
#[cfg(target_arch = "wasm32")]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
impl PubkyAppFeedConfig {
/// Serialize to JSON for WASM.
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = fromJson))]
pub fn from_json(js_value: &JsValue) -> Result<Self, String> {
Self::import_json(js_value)
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toJson))]
pub fn json(&self) -> Result<JsValue, JsValue> {
self.to_json()
pub fn to_json(&self) -> Result<JsValue, String> {
self.export_json()
}

/// Getter for `tags`.
Expand Down Expand Up @@ -104,8 +108,15 @@ impl PubkyAppFeedConfig {
}
}

impl Validatable for PubkyAppFeedConfig {
fn validate(&self, _id: Option<&str>) -> Result<(), String> {
// TODO: validate config?
Ok(())
}
}

#[cfg(target_arch = "wasm32")]
impl ToJson for PubkyAppFeedConfig {}
impl Json for PubkyAppFeedConfig {}

/// Represents a feed configuration.
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
Expand Down Expand Up @@ -150,9 +161,14 @@ impl PubkyAppFeed {
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
impl PubkyAppFeed {
/// Serialize to JSON for WASM.
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = fromJson))]
pub fn from_json(js_value: &JsValue) -> Result<Self, String> {
Self::import_json(js_value)
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toJson))]
pub fn json(&self) -> Result<JsValue, JsValue> {
self.to_json()
pub fn to_json(&self) -> Result<JsValue, String> {
self.export_json()
}

/// Getter for `feed`.
Expand All @@ -169,7 +185,7 @@ impl PubkyAppFeed {
}

#[cfg(target_arch = "wasm32")]
impl ToJson for PubkyAppFeed {}
impl Json for PubkyAppFeed {}

impl HashId for PubkyAppFeed {
/// Generates an ID based on the serialized `feed` object.
Expand All @@ -187,8 +203,11 @@ impl HasPath for PubkyAppFeed {
}

impl Validatable for PubkyAppFeed {
fn validate(&self, id: &str) -> Result<(), String> {
self.validate_id(id)?;
fn validate(&self, id: Option<&str>) -> Result<(), String> {
// Validate the feed ID
if let Some(id) = id {
self.validate_id(id)?;
}

// Validate name
if self.name.trim().is_empty() {
Expand Down Expand Up @@ -319,7 +338,7 @@ mod tests {
);
let feed_id = feed.create_id();

let result = feed.validate(&feed_id);
let result = feed.validate(Some(&feed_id));
assert!(result.is_ok());
}

Expand All @@ -334,7 +353,7 @@ mod tests {
"Rust Bitcoiners".to_string(),
);
let invalid_id = "INVALIDID";
let result = feed.validate(invalid_id);
let result = feed.validate(Some(invalid_id));
assert!(result.is_err());
}

Expand Down
29 changes: 18 additions & 11 deletions src/models/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::str::FromStr;
use url::Url;

#[cfg(target_arch = "wasm32")]
use crate::traits::ToJson;
use crate::traits::Json;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;

Expand Down Expand Up @@ -77,14 +77,18 @@ impl PubkyAppFile {
pub fn content_type(&self) -> String {
self.content_type.clone()
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = fromJson))]
pub fn from_json(js_value: &JsValue) -> Result<Self, String> {
Self::import_json(js_value)
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toJson))]
pub fn json(&self) -> Result<JsValue, JsValue> {
self.to_json()
pub fn to_json(&self) -> Result<JsValue, String> {
self.export_json()
}
}

#[cfg(target_arch = "wasm32")]
impl ToJson for PubkyAppFile {}
impl Json for PubkyAppFile {}

impl PubkyAppFile {
/// Creates a new `PubkyAppFile` instance.
Expand Down Expand Up @@ -138,8 +142,11 @@ impl Validatable for PubkyAppFile {
}
}

fn validate(&self, id: &str) -> Result<(), String> {
self.validate_id(id)?;
fn validate(&self, id: Option<&str>) -> Result<(), String> {
// Validate the file ID
if let Some(id) = id {
self.validate_id(id)?;
}

// Validate name
let name_length = self.name.chars().count();
Expand Down Expand Up @@ -226,7 +233,7 @@ mod tests {
1024,
);
let id = file.create_id();
let result = file.validate(&id);
let result = file.validate(Some(&id));
assert!(result.is_ok());
}

Expand All @@ -239,7 +246,7 @@ mod tests {
1024,
);
let invalid_id = "INVALIDID";
let result = file.validate(invalid_id);
let result = file.validate(Some(invalid_id));
assert!(result.is_err());
}

Expand All @@ -252,7 +259,7 @@ mod tests {
1024,
);
let id = file.create_id();
let result = file.validate(&id);
let result = file.validate(Some(&id));
assert!(result.is_err());
}

Expand All @@ -265,7 +272,7 @@ mod tests {
MAX_SIZE + 1,
);
let id = file.create_id();
let result = file.validate(&id);
let result = file.validate(Some(&id));
assert!(result.is_err());
}

Expand All @@ -278,7 +285,7 @@ mod tests {
MAX_SIZE + 1,
);
let id = file.create_id();
let result = file.validate(&id);
let result = file.validate(Some(&id));
assert!(result.is_err());
}

Expand Down
32 changes: 22 additions & 10 deletions src/models/follow.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::{
common::timestamp,
traits::{HasPubkyIdPath, Validatable},
APP_PATH, PUBLIC_PATH,
PubkyId, APP_PATH, PUBLIC_PATH,
};
use serde::{Deserialize, Serialize};

#[cfg(target_arch = "wasm32")]
use crate::traits::ToJson;
use crate::traits::Json;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;

Expand All @@ -31,7 +31,7 @@ pub struct PubkyAppFollow {
}

// #[cfg(target_arch = "wasm32")]
// impl ToJson for PubkyAppFollow {}
// impl Json for PubkyAppFollow {}

impl PubkyAppFollow {
/// Creates a new `PubkyAppFollow` instance.
Expand All @@ -44,17 +44,26 @@ impl PubkyAppFollow {
#[cfg(target_arch = "wasm32")]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
impl PubkyAppFollow {
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = fromJson))]
pub fn from_json(js_value: &JsValue) -> Result<Self, String> {
Self::import_json(js_value)
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen(js_name = toJson))]
pub fn json(&self) -> Result<JsValue, JsValue> {
self.to_json()
pub fn to_json(&self) -> Result<JsValue, String> {
self.export_json()
}
}

#[cfg(target_arch = "wasm32")]
impl ToJson for PubkyAppFollow {}
impl Json for PubkyAppFollow {}

impl Validatable for PubkyAppFollow {
fn validate(&self, _id: &str) -> Result<(), String> {
fn validate(&self, id: Option<&str>) -> Result<(), String> {
// Validate the followee ID
if let Some(id) = id {
PubkyId::try_from(id)?;
}
// TODO: additional follow validation? E.g., validate `created_at`?
Ok(())
}
Expand Down Expand Up @@ -92,7 +101,7 @@ mod tests {
#[test]
fn test_validate() {
let follow = PubkyAppFollow::new();
let result = follow.validate("some_user_id");
let result = follow.validate(Some("operrr8wsbpr3ue9d4qj41ge1kcc6r7fdiy6o3ugjrrhi4y77rdo"));
assert!(result.is_ok());
}

Expand All @@ -105,8 +114,11 @@ mod tests {
"#;

let blob = follow_json.as_bytes();
let follow_parsed =
<PubkyAppFollow as Validatable>::try_from(blob, "some_user_id").unwrap();
let follow_parsed = <PubkyAppFollow as Validatable>::try_from(
blob,
"operrr8wsbpr3ue9d4qj41ge1kcc6r7fdiy6o3ugjrrhi4y77rdo",
)
.unwrap();

assert_eq!(follow_parsed.created_at, 1627849723);
}
Expand Down
Loading

0 comments on commit 114eb08

Please sign in to comment.