add: apps js sdk
This commit is contained in:
parent
e393221b4f
commit
636ecce9f4
11 changed files with 223 additions and 41 deletions
|
@ -41,6 +41,7 @@ pub const ME_JS: &str = include_str!("./public/js/me.js");
|
|||
pub const STREAMS_JS: &str = include_str!("./public/js/streams.js");
|
||||
pub const CARP_JS: &str = include_str!("./public/js/carp.js");
|
||||
pub const PROTO_LINKS_JS: &str = include_str!("./public/js/proto_links.js");
|
||||
pub const APP_SDK_JS: &str = include_str!("./public/js/app_sdk.js");
|
||||
|
||||
// html
|
||||
pub const BODY: &str = include_str!("./public/html/body.lisp");
|
||||
|
|
|
@ -234,6 +234,7 @@ version = "1.0.0"
|
|||
"stacks:label.block_all" = "Block all"
|
||||
"stacks:label.unblock_all" = "Unblock all"
|
||||
|
||||
"forge:label.forges" = "Forges"
|
||||
"forge:label.my_forges" = "My forges"
|
||||
"forge:label.create_new" = "Create new forge"
|
||||
"forge:tab.info" = "Info"
|
||||
|
@ -242,6 +243,7 @@ version = "1.0.0"
|
|||
"forge:action.close" = "Close"
|
||||
|
||||
"developer:label.for_developers" = "for Developers"
|
||||
"developer:label.apps" = "Apps"
|
||||
"developer:label.my_apps" = "My apps"
|
||||
"developer:label.create_new" = "Create new app"
|
||||
"developer:label.homepage" = "Homepage"
|
||||
|
|
|
@ -1142,16 +1142,6 @@
|
|||
(text "{{ icon \"circle-user-round\" }}")
|
||||
(span
|
||||
(text "{{ text \"auth:link.my_profile\" }}")))
|
||||
(a
|
||||
("href" "/journals/0/0")
|
||||
(icon (text "notebook"))
|
||||
(str (text "general:link.journals")))
|
||||
(text "{% if config.lw_host -%}")
|
||||
(button
|
||||
("onclick" "document.getElementById('littleweb').showModal()")
|
||||
(icon (text "globe"))
|
||||
(str (text "general:link.little_web")))
|
||||
(text "{%- endif %}")
|
||||
(text "{% if not user.settings.disable_achievements -%}")
|
||||
(a
|
||||
("href" "/achievements")
|
||||
|
|
|
@ -39,12 +39,6 @@
|
|||
("title" "Create post")
|
||||
(icon (text "square-pen")))
|
||||
|
||||
(a
|
||||
("href" "/chats/0/0")
|
||||
("class" "button {% if selected == 'chats' -%}active{%- endif %}")
|
||||
("title" "Chats")
|
||||
(icon (text "message-circle")))
|
||||
|
||||
(a
|
||||
("href" "/requests")
|
||||
("class" "button {% if selected == 'requests' -%}active{%- endif %}")
|
||||
|
@ -65,6 +59,43 @@
|
|||
("id" "notifications_span")
|
||||
(text "{{ user.notification_count }}")))
|
||||
|
||||
(text "{% if user -%}")
|
||||
(div
|
||||
("class" "dropdown")
|
||||
(button
|
||||
("class" "flex-row {% if selected == 'chats' or selected == 'journals' -%}active{%- endif %}")
|
||||
("onclick" "trigger('atto::hooks::dropdown', [event])")
|
||||
("exclude" "dropdown")
|
||||
("title" "More services")
|
||||
(icon (text "grip")))
|
||||
|
||||
(div
|
||||
("class" "inner")
|
||||
(a
|
||||
("href" "/chats/0/0")
|
||||
("title" "Chats")
|
||||
(icon (text "message-circle"))
|
||||
(str (text "communities:label.chats")))
|
||||
(a
|
||||
("href" "/journals/0/0")
|
||||
(icon (text "notebook"))
|
||||
(str (text "general:link.journals")))
|
||||
(a
|
||||
("href" "/forges")
|
||||
(icon (text "anvil"))
|
||||
(str (text "forge:label.forges")))
|
||||
(a
|
||||
("href" "/developer")
|
||||
(icon (text "code"))
|
||||
(str (text "developer:label.apps")))
|
||||
(text "{% if config.lw_host -%}")
|
||||
(button
|
||||
("onclick" "document.getElementById('littleweb').showModal()")
|
||||
(icon (text "globe"))
|
||||
(str (text "general:link.little_web")))
|
||||
(text "{%- endif %}")))
|
||||
(text "{%- endif %}")
|
||||
|
||||
(text "{% if not hide_user_menu -%}")
|
||||
(div
|
||||
("class" "dropdown")
|
||||
|
|
108
crates/app/src/public/js/app_sdk.js
Normal file
108
crates/app/src/public/js/app_sdk.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
import {
|
||||
JSONParse as json_parse,
|
||||
JSONStringify as json_stringify,
|
||||
} from "https://unpkg.com/json-with-bigint@3.4.4/json-with-bigint.js";
|
||||
|
||||
export default function tetratto(tetratto_host, api_key) {
|
||||
function api_promise(res) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (res.ok) {
|
||||
resolve(res.payload);
|
||||
} else {
|
||||
reject(res.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function app() {
|
||||
return api_promise(
|
||||
json_parse(
|
||||
await (
|
||||
await fetch(`${tetratto_host}/api/v1/app_data/app`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Atto-Secret-Key": api_key,
|
||||
},
|
||||
})
|
||||
).text(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
async function query(body) {
|
||||
return api_promise(
|
||||
json_parse(
|
||||
await (
|
||||
await fetch(`${tetratto_host}/api/v1/app_data/query`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Atto-Secret-Key": api_key,
|
||||
},
|
||||
body: json_stringify(body),
|
||||
})
|
||||
).text(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
async function insert(key, value) {
|
||||
return api_promise(
|
||||
json_parse(
|
||||
await (
|
||||
await fetch(`${tetratto_host}/api/v1/app_data`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Atto-Secret-Key": api_key,
|
||||
},
|
||||
body: json_stringify({
|
||||
key,
|
||||
value,
|
||||
}),
|
||||
})
|
||||
).text(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
async function remove(id) {
|
||||
return api_promise(
|
||||
json_parse(
|
||||
await (
|
||||
await fetch(`${tetratto_host}/api/v1/app_data/${id}`, {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Atto-Secret-Key": api_key,
|
||||
},
|
||||
})
|
||||
).text(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
async function remove_query(body) {
|
||||
return api_promise(
|
||||
json_parse(
|
||||
await (
|
||||
await fetch(`${tetratto_host}/api/v1/app_data/query`, {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Atto-Secret-Key": api_key,
|
||||
},
|
||||
body: json_stringify(body),
|
||||
})
|
||||
).text(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
app,
|
||||
query,
|
||||
insert,
|
||||
remove,
|
||||
remove_query,
|
||||
};
|
||||
}
|
|
@ -415,33 +415,35 @@ media_theme_pref();
|
|||
});
|
||||
|
||||
self.define("hooks::long_text.init", (_) => {
|
||||
for (const element of Array.from(
|
||||
document.querySelectorAll("[hook=long]") || [],
|
||||
)) {
|
||||
const is_long = element.innerText.length >= 64 * 8;
|
||||
setTimeout(() => {
|
||||
for (const element of Array.from(
|
||||
document.querySelectorAll("[hook=long]") || [],
|
||||
)) {
|
||||
const is_long = element.innerText.length >= 64 * 8;
|
||||
|
||||
if (!is_long) {
|
||||
continue;
|
||||
if (!is_long) {
|
||||
continue;
|
||||
}
|
||||
|
||||
element.classList.add("hook:long.hidden_text");
|
||||
|
||||
if (element.getAttribute("hook-arg") === "lowered") {
|
||||
element.classList.add("hook:long.hidden_text+lowered");
|
||||
}
|
||||
|
||||
const html = element.innerHTML;
|
||||
const short = html.slice(0, 64 * 8);
|
||||
element.innerHTML = `${short}...`;
|
||||
|
||||
// event
|
||||
const listener = () => {
|
||||
self["hooks::long"](element, html);
|
||||
element.removeEventListener("click", listener);
|
||||
};
|
||||
|
||||
element.addEventListener("click", listener);
|
||||
}
|
||||
|
||||
element.classList.add("hook:long.hidden_text");
|
||||
|
||||
if (element.getAttribute("hook-arg") === "lowered") {
|
||||
element.classList.add("hook:long.hidden_text+lowered");
|
||||
}
|
||||
|
||||
const html = element.innerHTML;
|
||||
const short = html.slice(0, 64 * 8);
|
||||
element.innerHTML = `${short}...`;
|
||||
|
||||
// event
|
||||
const listener = () => {
|
||||
self["hooks::long"](element, html);
|
||||
element.removeEventListener("click", listener);
|
||||
};
|
||||
|
||||
element.addEventListener("click", listener);
|
||||
}
|
||||
}, 150);
|
||||
});
|
||||
|
||||
self.define("hooks::alt", (_) => {
|
||||
|
|
|
@ -9,6 +9,23 @@ use tetratto_core::model::{
|
|||
ApiReturn, Error,
|
||||
};
|
||||
|
||||
pub async fn get_app_request(
|
||||
headers: HeaderMap,
|
||||
Extension(data): Extension<State>,
|
||||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
let app = match get_app_from_key!(data, headers) {
|
||||
Some(x) => x,
|
||||
None => return Json(Error::NotAllowed.into()),
|
||||
};
|
||||
|
||||
Json(ApiReturn {
|
||||
ok: true,
|
||||
message: "Success".to_string(),
|
||||
payload: Some(app),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn query_request(
|
||||
headers: HeaderMap,
|
||||
Extension(data): Extension<State>,
|
||||
|
|
|
@ -433,6 +433,7 @@ pub fn routes() -> Router {
|
|||
.route("/apps/{id}/roll", post(apps::roll_api_key_request))
|
||||
// app data
|
||||
.route("/app_data", post(app_data::create_request))
|
||||
.route("/app_data/app", get(app_data::get_app_request))
|
||||
.route("/app_data/{id}", delete(app_data::delete_request))
|
||||
.route("/app_data/{id}/value", post(app_data::update_value_request))
|
||||
.route("/app_data/query", post(app_data::query_request))
|
||||
|
|
|
@ -20,3 +20,4 @@ serve_asset!(me_js_request: ME_JS("text/javascript"));
|
|||
serve_asset!(streams_js_request: STREAMS_JS("text/javascript"));
|
||||
serve_asset!(carp_js_request: CARP_JS("text/javascript"));
|
||||
serve_asset!(proto_links_request: PROTO_LINKS_JS("text/javascript"));
|
||||
serve_asset!(app_sdk_request: APP_SDK_JS("text/javascript"));
|
||||
|
|
|
@ -21,6 +21,7 @@ pub fn routes(config: &Config) -> Router {
|
|||
.route("/js/streams.js", get(assets::streams_js_request))
|
||||
.route("/js/carp.js", get(assets::carp_js_request))
|
||||
.route("/js/proto_links.js", get(assets::proto_links_request))
|
||||
.route("/js/app_sdk.js", get(assets::app_sdk_request))
|
||||
.nest_service(
|
||||
"/public",
|
||||
get_service(tower_http::services::ServeDir::new(&config.dirs.assets)),
|
||||
|
|
28
example/app_sdk_test.js
Normal file
28
example/app_sdk_test.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
// @ts-nocheck
|
||||
// APP_API_KEY=... deno run --allow-net --allow-import --allow-env -r app_sdk_test.js
|
||||
const deno = Deno;
|
||||
const sdk = (await import("http://localhost:4118/js/app_sdk.js")).default(
|
||||
"http://localhost:4118",
|
||||
deno.env.get("APP_API_KEY"),
|
||||
);
|
||||
|
||||
// check data used
|
||||
console.log("data used:", (await sdk.app()).data_used);
|
||||
|
||||
// record insert
|
||||
await sdk.insert("deno_test", "Hello, Deno!");
|
||||
console.log("record created");
|
||||
console.log("data used:", (await sdk.app()).data_used);
|
||||
|
||||
// testing record query then delete
|
||||
const record = (
|
||||
await sdk.query({
|
||||
query: { KeyIs: "deno_test" },
|
||||
mode: { One: 0 },
|
||||
})
|
||||
).One;
|
||||
|
||||
console.log(record);
|
||||
await sdk.remove(record.id);
|
||||
console.log("record deleted");
|
||||
console.log("data used:", (await sdk.app()).data_used);
|
Loading…
Add table
Add a link
Reference in a new issue