mirror of
https://github.com/aljazceru/pubky-core.git
synced 2026-01-30 03:14:25 +01:00
feat(js): add list() method
This commit is contained in:
@@ -40,5 +40,5 @@ tokio = "1.37.0"
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
||||
# [package.metadata.wasm-pack.profile.release]
|
||||
# wasm-opt = ['-g', '-O']
|
||||
[package.metadata.wasm-pack.profile.release]
|
||||
wasm-opt = ['-g', '-O']
|
||||
|
||||
@@ -111,3 +111,135 @@ test("forbidden", async (t) => {
|
||||
`HTTP status client error (403 Forbidden) for url (http://localhost:15411/${publicKey.z32()}/priv/example.com/arbitrary)`
|
||||
)
|
||||
})
|
||||
|
||||
test("list", async (t) => {
|
||||
const client = PubkyClient.testnet();
|
||||
|
||||
const keypair = Keypair.random()
|
||||
const publicKey = keypair.publicKey()
|
||||
const pubky = publicKey.z32()
|
||||
|
||||
const homeserver = PublicKey.from('8pinxxgqs41n4aididenw5apqp1urfmzdztr8jt4abrkdn435ewo')
|
||||
await client.signup(keypair, homeserver)
|
||||
|
||||
|
||||
|
||||
let urls = [
|
||||
`pubky://${pubky}/pub/a.wrong/a.txt`,
|
||||
`pubky://${pubky}/pub/example.com/a.txt`,
|
||||
`pubky://${pubky}/pub/example.com/b.txt`,
|
||||
`pubky://${pubky}/pub/example.wrong/a.txt`,
|
||||
`pubky://${pubky}/pub/example.com/c.txt`,
|
||||
`pubky://${pubky}/pub/example.com/d.txt`,
|
||||
`pubky://${pubky}/pub/z.wrong/a.txt`,
|
||||
]
|
||||
|
||||
for (let url of urls) {
|
||||
await client.put(url, Buffer.from(""));
|
||||
}
|
||||
|
||||
let url = `pubky://${pubky}/pub/example.com/`;
|
||||
|
||||
{
|
||||
let list = await client.list(url);
|
||||
|
||||
t.deepEqual(
|
||||
list,
|
||||
[
|
||||
`pubky://${pubky}/pub/example.com/a.txt`,
|
||||
`pubky://${pubky}/pub/example.com/b.txt`,
|
||||
`pubky://${pubky}/pub/example.com/c.txt`,
|
||||
`pubky://${pubky}/pub/example.com/d.txt`,
|
||||
|
||||
],
|
||||
"normal list with no limit or cursor"
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let list = await client.list(url, null, null, 2);
|
||||
|
||||
t.deepEqual(
|
||||
list,
|
||||
[
|
||||
`pubky://${pubky}/pub/example.com/a.txt`,
|
||||
`pubky://${pubky}/pub/example.com/b.txt`,
|
||||
|
||||
],
|
||||
"normal list with limit but no cursor"
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let list = await client.list(url, "a.txt", null, 2);
|
||||
|
||||
t.deepEqual(
|
||||
list,
|
||||
[
|
||||
`pubky://${pubky}/pub/example.com/b.txt`,
|
||||
`pubky://${pubky}/pub/example.com/c.txt`,
|
||||
|
||||
],
|
||||
"normal list with limit and a suffix cursor"
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let list = await client.list(url, `pubky://${pubky}/pub/example.com/a.txt`, null, 2);
|
||||
|
||||
t.deepEqual(
|
||||
list,
|
||||
[
|
||||
`pubky://${pubky}/pub/example.com/b.txt`,
|
||||
`pubky://${pubky}/pub/example.com/c.txt`,
|
||||
|
||||
],
|
||||
"normal list with limit and a full url cursor"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
let list = await client.list(url, null, true);
|
||||
|
||||
t.deepEqual(
|
||||
list,
|
||||
[
|
||||
`pubky://${pubky}/pub/example.com/d.txt`,
|
||||
`pubky://${pubky}/pub/example.com/c.txt`,
|
||||
`pubky://${pubky}/pub/example.com/b.txt`,
|
||||
`pubky://${pubky}/pub/example.com/a.txt`,
|
||||
|
||||
],
|
||||
"reverse list with no limit or cursor"
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let list = await client.list(url, null, true, 2);
|
||||
|
||||
t.deepEqual(
|
||||
list,
|
||||
[
|
||||
`pubky://${pubky}/pub/example.com/d.txt`,
|
||||
`pubky://${pubky}/pub/example.com/c.txt`,
|
||||
|
||||
],
|
||||
"reverse list with limit but no cursor"
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let list = await client.list(url, "d.txt", true, 2);
|
||||
|
||||
t.deepEqual(
|
||||
list,
|
||||
[
|
||||
`pubky://${pubky}/pub/example.com/c.txt`,
|
||||
`pubky://${pubky}/pub/example.com/b.txt`,
|
||||
|
||||
],
|
||||
"reverse list with limit and a suffix cursor"
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -107,6 +107,9 @@ impl PubkyClient {
|
||||
self.inner_delete(url).await
|
||||
}
|
||||
|
||||
/// Returns a [ListBuilder] to help pass options before calling [ListBuilder::send].
|
||||
///
|
||||
/// `url` sets the path you want to lest within.
|
||||
pub fn list<T: TryInto<Url>>(&self, url: T) -> Result<ListBuilder> {
|
||||
self.inner_list(url)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ pub struct ListBuilder<'a> {
|
||||
}
|
||||
|
||||
impl<'a> ListBuilder<'a> {
|
||||
/// Create a new List request builder
|
||||
pub fn new(client: &'a PubkyClient, url: Url) -> Self {
|
||||
Self {
|
||||
client,
|
||||
@@ -23,21 +24,31 @@ impl<'a> ListBuilder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the `reverse` option.
|
||||
pub fn reverse(mut self, reverse: bool) -> Self {
|
||||
self.reverse = reverse;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the `limit` value.
|
||||
pub fn limit(mut self, limit: u16) -> Self {
|
||||
self.limit = limit.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the `cursor` value.
|
||||
///
|
||||
/// usually the last url from previous responses.
|
||||
pub fn cursor(mut self, cursor: &'a str) -> Self {
|
||||
self.cursor = cursor.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Send the list request.
|
||||
///
|
||||
/// Returns a list of Pubky URLs of the files in the path of the `url`
|
||||
/// respecting [ListBuilder::reverse], [ListBuilder::limit] and [ListBuilder::cursor]
|
||||
/// options.
|
||||
pub async fn send(self) -> Result<Vec<String>> {
|
||||
let mut url = self.client.pubky_to_http(self.url).await?;
|
||||
|
||||
|
||||
@@ -236,8 +236,9 @@ mod tests {
|
||||
client.put(url.as_str(), &[0]).await.unwrap();
|
||||
}
|
||||
|
||||
let url = format!("pubky://{}/pub/example.com/", keypair.public_key());
|
||||
|
||||
{
|
||||
let url = format!("pubky://{}/pub/example.com/", keypair.public_key());
|
||||
let list = client.list(url.as_str()).unwrap().send().await.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
@@ -253,7 +254,6 @@ mod tests {
|
||||
}
|
||||
|
||||
{
|
||||
let url = format!("pubky://{}/pub/example.com/", keypair.public_key());
|
||||
let list = client
|
||||
.list(url.as_str())
|
||||
.unwrap()
|
||||
@@ -273,7 +273,6 @@ mod tests {
|
||||
}
|
||||
|
||||
{
|
||||
let url = format!("pubky://{}/pub/example.com/", keypair.public_key());
|
||||
let list = client
|
||||
.list(url.as_str())
|
||||
.unwrap()
|
||||
@@ -294,7 +293,6 @@ mod tests {
|
||||
}
|
||||
|
||||
{
|
||||
let url = format!("pubky://{}/pub/example.com/", keypair.public_key());
|
||||
let list = client
|
||||
.list(url.as_str())
|
||||
.unwrap()
|
||||
@@ -318,7 +316,6 @@ mod tests {
|
||||
}
|
||||
|
||||
{
|
||||
let url = format!("pubky://{}/pub/example.com/", keypair.public_key());
|
||||
let list = client
|
||||
.list(url.as_str())
|
||||
.unwrap()
|
||||
@@ -340,7 +337,6 @@ mod tests {
|
||||
}
|
||||
|
||||
{
|
||||
let url = format!("pubky://{}/pub/example.com/", keypair.public_key());
|
||||
let list = client
|
||||
.list(url.as_str())
|
||||
.unwrap()
|
||||
@@ -361,7 +357,6 @@ mod tests {
|
||||
}
|
||||
|
||||
{
|
||||
let url = format!("pubky://{}/pub/example.com/", keypair.public_key());
|
||||
let list = client
|
||||
.list(url.as_str())
|
||||
.unwrap()
|
||||
|
||||
@@ -3,7 +3,8 @@ use std::{
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use js_sys::{Array, Uint8Array};
|
||||
use wasm_bindgen::prelude::{wasm_bindgen, JsValue};
|
||||
|
||||
use reqwest::{IntoUrl, Method, RequestBuilder, Response};
|
||||
use url::Url;
|
||||
@@ -58,7 +59,7 @@ impl PubkyClient {
|
||||
pub fn create_recovery_file(
|
||||
keypair: &Keypair,
|
||||
passphrase: &str,
|
||||
) -> Result<js_sys::Uint8Array, JsValue> {
|
||||
) -> Result<Uint8Array, JsValue> {
|
||||
create_recovery_file(keypair.as_inner(), passphrase)
|
||||
.map(|b| b.as_slice().into())
|
||||
.map_err(|e| e.into())
|
||||
@@ -138,18 +139,69 @@ impl PubkyClient {
|
||||
self.inner_put(url, content).await.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
/// Download a small payload from a given path relative to a pubky author.
|
||||
pub async fn get(&self, url: &str) -> Result<Option<js_sys::Uint8Array>, JsValue> {
|
||||
#[wasm_bindgen]
|
||||
pub async fn get(&self, url: &str) -> Result<Option<Uint8Array>, JsValue> {
|
||||
self.inner_get(url)
|
||||
.await
|
||||
.map(|b| b.map(|b| (&*b).into()))
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
/// Delete a file at a path relative to a pubky author.
|
||||
#[wasm_bindgen]
|
||||
pub async fn delete(&self, url: &str) -> Result<(), JsValue> {
|
||||
self.inner_delete(url).await.map_err(|e| e.into())
|
||||
}
|
||||
|
||||
/// Returns a list of Pubky URLs of the files within the `url` path,
|
||||
/// respecting the `cursor`, `reverse` and `limit` options.
|
||||
///
|
||||
/// `cursor` is usually the last url from previous responses.
|
||||
#[wasm_bindgen]
|
||||
pub async fn list(
|
||||
&self,
|
||||
url: &str,
|
||||
cursor: Option<String>,
|
||||
reverse: Option<bool>,
|
||||
limit: Option<u16>,
|
||||
) -> Result<Array, JsValue> {
|
||||
// TODO: try later to return Vec<String> from async function.
|
||||
|
||||
if let Some(cursor) = cursor {
|
||||
return self
|
||||
.inner_list(url)?
|
||||
.reverse(reverse.unwrap_or(false))
|
||||
.limit(limit.unwrap_or(u16::MAX))
|
||||
.cursor(&cursor)
|
||||
.send()
|
||||
.await
|
||||
.map(|urls| {
|
||||
let js_array = Array::new();
|
||||
|
||||
for url in urls {
|
||||
js_array.push(&JsValue::from_str(&url));
|
||||
}
|
||||
|
||||
js_array
|
||||
})
|
||||
.map_err(|e| e.into());
|
||||
}
|
||||
|
||||
self.inner_list(url)?
|
||||
.reverse(reverse.unwrap_or(false))
|
||||
.limit(limit.unwrap_or(u16::MAX))
|
||||
.send()
|
||||
.await
|
||||
.map(|urls| {
|
||||
let js_array = Array::new();
|
||||
|
||||
for url in urls {
|
||||
js_array.push(&JsValue::from_str(&url));
|
||||
}
|
||||
|
||||
js_array
|
||||
})
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user