Skip to content

Instantly share code, notes, and snippets.

@manix84
Last active February 8, 2025 18:10
Show Gist options
  • Save manix84/75ce19b4d1fcaf96684e30f1b7d5bdfb to your computer and use it in GitHub Desktop.
Save manix84/75ce19b4d1fcaf96684e30f1b7d5bdfb to your computer and use it in GitHub Desktop.

Revisions

  1. manix84 revised this gist Feb 8, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion usage_example.ts
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@ import { request } from './request';

    export const fetchInit = async (
    user_id: string
    ): Promise<DashboardInitResponse> => {
    ): Promise<UserInitResponse> => {
    return request(`/init`, {
    method: 'POST',
    params: {
  2. manix84 created this gist Feb 8, 2025.
    68 changes: 68 additions & 0 deletions request.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    /**
    This code is licensed under the terms of the MIT license
    */

    export class ResponseError extends Error {
    public code!: number;
    }

    export const request = async <T>(
    path: string,
    options: RequestInit & { params?: Record<string, any> } = {
    headers: new Headers(),
    },
    retry: number = 0,
    _retry_initial_count: number = 0 // @info: Internal use only - Used to count the number of retries
    ): Promise<T> => {
    const isAbsolute = /^(?:[a-z+]+:)?\/\//i.test(path);
    let url = `${!isAbsolute ? BASE_SERVER_URL : ''}${path}`;

    // Extract params from options
    const { params, ...fetchOptions } = options;
    const method = fetchOptions.method?.toUpperCase() || 'GET';

    if (method === 'GET' && params && Object.keys(params).length) {
    const queryString = new URLSearchParams(params).toString();
    url += `?${queryString}`;
    } else if (params && Object.keys(params).length) {
    fetchOptions.body = JSON.stringify(params);
    fetchOptions.headers = new Headers(fetchOptions.headers);
    fetchOptions.headers.set('Content-Type', 'application/json');
    }

    console.debug(path, fetchOptions, {
    params,
    isAbsolute,
    url,
    retry,
    _retry_initial_count,
    });

    return await fetch(url, fetchOptions).then(async (response) => {
    if (!response.ok) {
    if (retry > 0) {
    return request(
    path,
    { ...fetchOptions, params },
    retry - 1,
    _retry_initial_count || retry
    );
    }
    const json = await response.json();
    const error = new ResponseError(
    json?.error || response.statusText || 'network request failed'
    );
    error.code = response.status;
    throw error;
    }

    const contentType = response.headers.get('content-type');
    if (contentType?.includes('application/json')) {
    const json = await response.json();
    if (json.error) throw new Error(json.error);
    return json;
    }

    return response.text() as unknown as T;
    });
    };
    16 changes: 16 additions & 0 deletions usage_example.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    import { request } from './request';

    export const fetchInit = async (
    user_id: string
    ): Promise<DashboardInitResponse> => {
    return request(`/init`, {
    method: 'POST',
    params: {
    user_id
    },
    });
    };

    fetchInit('aBc1234DeF').then((responseData) => {
    console.log({responseData});
    })