web_lib

Common web application libraries
git clone https://radroots.dev/git/web_lib.git
Log | Files | Refs | LICENSE

web.ts (5104B)


      1 import { err_msg, schema_media_resource } from '@radroots/utils';
      2 import { type IHttpResponse, is_err_response, is_error_response, is_pass_response, WebHttp } from '@radroots/http';
      3 import { nostr_event_sign_attest } from "@radroots/nostr";
      4 import { cl_radroots_error } from "./error.js";
      5 import type {
      6     IClientRadroots,
      7     IClientRadrootsAccountsActivate,
      8     IClientRadrootsAccountsActivateResolve,
      9     IClientRadrootsAccountsCreate,
     10     IClientRadrootsAccountsCreateResolve,
     11     IClientRadrootsAccountsRequest,
     12     IClientRadrootsAccountsRequestResolve,
     13     IClientRadrootsMediaImageUpload,
     14     IClientRadrootsMediaImageUploadResolve
     15 } from "./types.js";
     16 
     17 export interface IWebClientRadroots extends IClientRadroots { }
     18 
     19 export class WebClientRadroots implements IWebClientRadroots {
     20     private _base_url: string
     21     private _http_client: WebHttp
     22 
     23     constructor(base_url: string) {
     24         if (!base_url) throw new Error(cl_radroots_error.missing_base_url);
     25         const parsed_url = new URL(base_url);
     26         const sanitized_base_url = `${parsed_url.origin}${parsed_url.pathname}`.replace(/\/+$/, ``);
     27         this._base_url = sanitized_base_url;
     28         this._http_client = new WebHttp();
     29     }
     30 
     31     private is_res_pass(res: IHttpResponse): boolean {
     32         return is_pass_response(res.data);
     33     }
     34 
     35     private parse_res_field(field: unknown): string | undefined {
     36         if (typeof field === `string` && field) return field;
     37     }
     38 
     39     private is_record(value: unknown): value is Record<string, unknown> {
     40         return typeof value === "object" && value !== null;
     41     }
     42 
     43     private create_x_nostr_event(secret_key: string): string {
     44         return JSON.stringify(nostr_event_sign_attest(secret_key));
     45     }
     46 
     47     public async accounts_request(opts: IClientRadrootsAccountsRequest): Promise<IClientRadrootsAccountsRequestResolve> {
     48         const { profile_name, secret_key } = opts
     49         const res = await this._http_client.fetch({
     50             url: `${this._base_url}/v1/accounts/request`,
     51             method: "post",
     52             headers: {
     53                 "X-Nostr-Event": this.create_x_nostr_event(secret_key),
     54             },
     55             data: { profile_name }
     56         });
     57         if (is_err_response(res)) return res;
     58         if (is_error_response(res)) return err_msg(res.error);
     59         else if (this.is_res_pass(res)) {
     60             const res_data = this.is_record(res.data) ? res.data : null;
     61             const tok = res_data ? this.parse_res_field(res_data["tok"]) : undefined;
     62             if (tok) return { result: tok };
     63         }
     64         return err_msg(cl_radroots_error.account_registered);
     65     }
     66 
     67     public async accounts_create(opts: IClientRadrootsAccountsCreate): Promise<IClientRadrootsAccountsCreateResolve> {
     68         const { tok, secret_key } = opts
     69         const res = await this._http_client.fetch({
     70             url: `${this._base_url}/v1/accounts/create`,
     71             method: "post",
     72             headers: {
     73                 "X-Nostr-Event": this.create_x_nostr_event(secret_key),
     74             },
     75             authorization: tok
     76         });
     77         if (is_err_response(res)) return res;
     78         if (is_error_response(res)) return err_msg(res.error);
     79         else if (this.is_res_pass(res)) {
     80             const res_data = this.is_record(res.data) ? res.data : null;
     81             const id = res_data ? this.parse_res_field(res_data["id"]) : undefined;
     82             if (id) return { result: id };
     83         }
     84         return err_msg(cl_radroots_error.request_failure);
     85     }
     86 
     87     public async accounts_activate(opts: IClientRadrootsAccountsActivate): Promise<IClientRadrootsAccountsActivateResolve> {
     88         const { id, secret_key } = opts
     89         const res = await this._http_client.fetch({
     90             url: `${this._base_url}/v1/accounts/activate`,
     91             method: "post",
     92             headers: {
     93                 "X-Nostr-Event": this.create_x_nostr_event(secret_key),
     94             },
     95             data: { id }
     96         });
     97         if (is_err_response(res)) return res;
     98         if (is_error_response(res)) return err_msg(res.error);
     99         else if (this.is_res_pass(res)) return { result: id };
    100         return err_msg(cl_radroots_error.request_failure);
    101     }
    102 
    103     public async media_image_upload(opts: IClientRadrootsMediaImageUpload): Promise<IClientRadrootsMediaImageUploadResolve> {
    104         const { mime_type, file_data, secret_key } = opts
    105         const res = await this._http_client.fetch({
    106             url: `${this._base_url}/v1/media/image/upload`,
    107             method: "put",
    108             headers: {
    109                 "Content-Type": mime_type || "image/png",
    110                 "X-Nostr-Event": this.create_x_nostr_event(secret_key),
    111             },
    112             data_bin: file_data
    113         });
    114         if (is_err_response(res)) return res;
    115         if (is_error_response(res)) return err_msg(res.error);
    116         else if (this.is_res_pass(res)) {
    117             const res_data = schema_media_resource.safeParse(res.data);
    118             if (res_data.success && res_data.data) return res_data.data;
    119         }
    120         return err_msg(cl_radroots_error.request_failure);
    121     }
    122 }