typescript – Are there technical issues/disavdantages on this BaseService that aims to simplify calling API endpoints

I have created an angular BaseService that aims to simplify calling API endpoints

I would like to know if you see any code smells, bad patterns or architecture issues.
What disadvantages could this have.

The idea is to decouple the api configuration from the implementation

The configuration is made in the api-config.ts

export enum ENDPOINT {
    CONFIGURATION_GET_MENU = 0,
    CONFIGURATION_GET_MINUTE_OFFSET,
    APPOINTMENT_GET_ADV_TYPES,
    APPOINTMENT_GET_ADV_DOMAIN_GROUPS,
    APPOINTMENT_GET_ADV_EXISTING_DATA,
    APPOINTMENT_DELETE_ADV,
    DASHBOARD_GET_NOSHOW_DATA,
}

export enum VERB {
    GET,
    GET_BY_PARAMS,
    POST_BODY,
    POST_BODY_PARAMS,
    PATCH,
}

export class ApiConfig {
    endpoint: ENDPOINT;
    url: string;
    verb: VERB;
}

const API_CONFIG: ApiConfig() = (
    {
        endpoint: ENDPOINT.CONFIGURATION_GET_MENU,
        url: '/cfg/getMenu',
        verb: VERB.GET
    },
       {
        endpoint: ENDPOINT.CONFIGURATION_GET_MINUTE_OFFSET,
        url: '/cfg/getCSMO',
        verb: VERB.GET_BY_PARAMS
    },
    {
        endpoint: ENDPOINT.APPOINTMENT_UPSERT_ADV_TYPES,
        url: '/aat/post',
        verb: VERB.POST_BODY
    },
    {
        endpoint: ENDPOINT.APPOINTMENT_DELETE_ADV,
        url: '/aat/delete',
        verb: VERB.PATCH
    }
    {
        endpoint: ENDPOINT.DASHBOARD_GET_NOSHOW_DATA,
        url: '/dsh/getCNSD',
        verb: VERB.POST_BODY_PARAMS
    }
);


export { API_CONFIG as API_CONFIG };

Then the baseService exposes a call method that determine what verb needs to be called and is the only place where httpClient is used

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { ConfigService } from 'src/app/app-config.service';
import { Observable } from 'rxjs/internal/Observable';
import { ApiConfig, API_CONFIG, ENDPOINT, VERB } from './api-config';

class CallOptions {
    body?: any;
    params?: HttpParams;
    queryString?: string;
}

@Injectable()
export class BaseService {

    constructor(protected httpClient: HttpClient, private configService: ConfigService) { }

    public call(apiEndpoint: ENDPOINT, opt: CallOptions): Observable<any> {

        const verb = this.getConfig(apiEndpoint).verb;

        switch (verb) {
            case VERB.GET:
                return this.get(apiEndpoint);
            case VERB.GET_BY_PARAMS:
                return this.getWithParams(apiEndpoint, opt.params);
            case VERB.PATCH:
                return this.patch(apiEndpoint, opt.queryString, opt.params);
            case VERB.POST_BODY:
                return this.post(apiEndpoint, opt.body);
            case VERB.POST_BODY_PARAMS:
                return this.postWithParams(apiEndpoint, opt.body, opt.params);
            default:
                const error = `BaseService: Verb ${verb} not supported yet`;
                console.log(error);
                throw new Error(error);
        }
    }
    //TODO if migration is finished convert this to private, it should not fail compiling
    protected getBaseUrl(): string {
        return this.configService.get('apiUrl');
    }

    private getConfig(apiEndpoint: ENDPOINT): ApiConfig {
        const apiConfigEndpoint = API_CONFIG.find(e => e.endpoint === apiEndpoint);
        if (apiConfigEndpoint === undefined) {
            const error = `BaseService: Endpoint (${apiEndpoint}) not configured`;
            console.log(error);
            throw new Error(error);
        }
        return apiConfigEndpoint;
    }

    private buildURL(apiEndpoint: ENDPOINT) {
        return `${this.getBaseUrl()}${this.getConfig(apiEndpoint).url}`;
    }

    private get(apiEndpoint: ENDPOINT): Observable<any> {
        return this.httpClient.get<any>(this.buildURL(apiEndpoint));
    }

    private getWithParams(apiEndpoint: ENDPOINT, params: HttpParams): Observable<any> {
        return this.httpClient.get<any>(this.buildURL(apiEndpoint), { params });
    }

    private post(apiEndpoint: ENDPOINT, body: any): Observable<any> {
        return this.httpClient.post<any>(this.buildURL(apiEndpoint), body);
    }

    private postWithParams(apiEndpoint: ENDPOINT, body: any, params: HttpParams): Observable<any> {
        return this.httpClient.post<any>(this.buildURL(apiEndpoint), body, { params });
    }

    private patch(apiEndpoint: ENDPOINT, queryParams: string, params: HttpParams): Observable<any> {
        return this.httpClient.patch<any>(`${this.buildURL(apiEndpoint)}?${queryParams}`, params);
    }
}

Since the call method returns an Observable it can be used in the same places and in the same way as when calling httpClient get or post methods

loadMenu$ = createEffect(() => this.actions$.pipe(
        ofType(actions.loadMenu),
        switchMap(() => this.baseService.call(ENDPOINT.CONFIGURATION_GET_MENU, {})
            .pipe(
                map(response => actions.loadMenuComplete({ menu: response.result })),
                catchError(() => of(actions.loadMenuFailure({ error: 'fail' })))
            )
        )
    ));