
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\public-api.ts

/*
 * Public API Surface of x-framework-api-sdk
 */
//
// Base ...
export * from './lib/base/x-base.guard';
export * from './lib/base/x-base-entity.service';
export * from './lib/base/i-x-entity-actions.interface';

//
// Config ...
export * from './lib/config/x-saherelm-api-sdk.config';

//
// Models ...
export * from './lib/models/x-person.dto';
export * from './lib/models/x-reference.dto';

//
// Tokens ...
export * from './lib/tokens/x-injectable-tokens';

//
// Tools ...
export * from './lib/tools/x-role.tools';
export * from './lib/tools/x-model.tools';
export * from './lib/tools/x-route.tools';

//
// Services ...
export * from './lib/services/x-push-token-fetcher.service';

//
// Typings ...
export * from './lib/typings/x-role.typings';
export * from './lib/strings/x-string.typings';
export * from './lib/typings/x-endpoint.typings';
export * from './lib/typings/x-push-provider.typings';

//
// Guards ...
export * from './lib/guards/user.guard';
export * from './lib/guards/admin.guard';
export * from './lib/guards/agent.guard';
export * from './lib/guards/admin-or-agent.guard';

//
// Strings ...
export * from './lib/strings/x-string.typings';
export * from './lib/strings/x-string.services';
export * from './lib/strings/models/x-string.dto';
export * from './lib/configurations/x-configurations.service';
export * from './lib/strings/services/x-string.entity.service';
export * from './lib/strings/services/x-string.provider.service';
export * from './lib/strings/services/x-string.entity.push.service';

//
// Terms ...
export * from './lib/terms/x-terms.service';
export * from './lib/terms/x-terms.typings.dto';
export * from './lib/terms/services/x-terms.push.service';
export * from './lib/terms/services/x-terms.provider.service';

//
// Tags ...
export * from './lib/tags/x-tag.typings';
export * from './lib/tags/x-tag.services';
export * from './lib/tags/models/x-tag.dto';
export * from './lib/tags/services/x-tag.entity.service';
export * from './lib/tags/services/x-tag.provider.service';
export * from './lib/tags/services/x-tag.entity.push.service';

//
// Files ...
export * from './lib/files/x-file.typings';
export * from './lib/files/x-file.services';
export * from './lib/files/models/x-file.dto';
export * from './lib/files/services/x-file.entity.service';
export * from './lib/files/services/x-file.provider.service';
export * from './lib/files/services/x-file.entity.push.service';

//
// Webinars ...
export * from './lib/webinars/x-webinar.typings';
export * from './lib/webinars/x-webinar.services';
export * from './lib/webinars/models/x-webinar.dto';
export * from './lib/webinars/services/x-webinar.push.service';
export * from './lib/webinars/services/x-webinar.entity.service';
export * from './lib/webinars/services/x-webinar.provider.service';
export * from './lib/webinars/services/x-webinar.entity.push.service';
export * from './lib/webinars/services/x-webinarsubscriber.entity.service';

//
// Module Service ...
export * from './lib/x-saherelm-api.service';

//
// Module ...
export * from './lib/x-saherelm-api-sdk.module';

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\x-saherelm-api-sdk.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { XFrameworkCoreModule } from 'x-framework-core';
import { XFrameworkServicesModule } from 'x-framework-services';
import { XFrameworkIdentitySdkModule } from 'x-framework-identity-sdk';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    HttpClientModule,
    XFrameworkCoreModule,
    XFrameworkServicesModule,
    XFrameworkIdentitySdkModule,
  ],
  exports: [
    CommonModule,
    HttpClientModule,
    XFrameworkCoreModule,
    XFrameworkServicesModule,
    XFrameworkIdentitySdkModule,
  ],
  providers: [],
})
export class XSaherElmApiSdkModule {}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\x-saherelm-api.service.ts

import { XLoggable } from 'x-framework-core';
import { Inject, Injectable } from '@angular/core';
import { XTagServices } from './tags/x-tag.services';
import { XFileServices } from './files/x-file.services';
import { XTermsServices } from './terms/x-terms.service';
import { XStringServices } from './strings/x-string.services';
import { XWebinarServices } from './webinars/x-webinar.services';
import { X_SAHERELM_API_SDK_CONFIG } from './tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from './config/x-saherelm-api-sdk.config';
import { XConfigurationsService } from './configurations/x-configurations.service';

@Injectable({
  providedIn: 'root',
})
export class XSaherElmAPIService extends XLoggable {
  //
  //#region Constructor ...
  constructor(
    public tags: XTagServices,
    public files: XFileServices,
    public terms: XTermsServices,
    public strings: XStringServices,
    public webinars: XWebinarServices,
    @Inject(X_SAHERELM_API_SDK_CONFIG)
    public config: XSaherElmApiSDKConfig,
    public configurationService: XConfigurationsService
  ) {
    super(config);
  }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\base\i-x-entity-actions.interface.ts

import { Observable } from 'rxjs';
import { XBaseRangeRequestDto } from 'x-framework-core';
import { HttpEvent, HttpResponse } from '@angular/common/http';
import { XQueryDto, XQueryResultDto } from 'x-framework-identity-sdk';

export interface IXEntityActions<TModel, TKey> {
  //
  //#region Repository Implementation ...
  //
  //#region Retrieve ...
  //
  //#region Get ...
  /**
   * Retrieve Specified Item based on Id
   *
   * @param id the Object ID ...
   * @param containsDetail specify retrieve full details
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callGet(
    id: TKey,
    containsDetail?: boolean,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  callGet(
    id: TKey,
    containsDetail?: boolean,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  callGet(
    id: TKey,
    containsDetail?: boolean,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  callGet(
    id: TKey,
    containsDetail?: boolean,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion

  //
  //#region GetAll ...
  /**
   * Retrieve all Items
   *
   * @param containsDetail specify retrieve full details
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callGetAll(
    containsDetail?: boolean,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<TModel>>;
  callGetAll(
    containsDetail?: boolean,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<TModel>>>;
  callGetAll(
    containsDetail?: boolean,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<TModel>>>;
  callGetAll(
    containsDetail?: boolean,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion

  //
  //#region FindOne ...
  /**
   * Fine first Item which matched to the query string
   *
   * @param query search pattern
   * @param containsDetail specify retrieve full details
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callFindOne(
    query: string,
    containsDetail?: boolean,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  callFindOne(
    query: string,
    containsDetail?: boolean,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  callFindOne(
    query: string,
    containsDetail?: boolean,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  callFindOne(
    query: string,
    containsDetail?: boolean,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion

  //
  //#region FindMany ...
  /**
   * Find a Collection of items which matched to Specified Query string
   *
   * @param query search pattern
   * @param containsDetail specify retrieve full details
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callFindMany(
    query: string,
    containsDetail?: boolean,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<TModel>>;
  callFindMany(
    query: string,
    containsDetail?: boolean,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<TModel>>>;
  callFindMany(
    query: string,
    containsDetail?: boolean,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<TModel>>>;
  callFindMany(
    query: string,
    containsDetail?: boolean,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion

  //
  //#region Query ...
  /**
   * Retrieve Items based on XQuery model
   *
   * @param query specify data projection attributes
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callQuery(
    query: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<TModel>>;
  callQuery(
    query: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<TModel>>>;
  callQuery(
    query: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<TModel>>>;
  callQuery(
    query: XQueryDto,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion
  //#endregion

  //
  //#region Add ...
  //
  //#region Add ...
  /**
   * Add New Item
   *
   * @param body the new Content which requires to add
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callAdd(
    body: TModel,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  callAdd(
    body: TModel,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  callAdd(
    body: TModel,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  callAdd(
    body: TModel,
    connectionId?: string,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion

  //
  //#region AddOrUpdate ...
  /**
   * Add New Item or Update Exists Item
   *
   * @param body hte instance of Entity
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callAddOrUpdate(
    body: TModel,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  callAddOrUpdate(
    body: TModel,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  callAddOrUpdate(
    body: TModel,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  callAddOrUpdate(
    body: TModel,
    connectionId?: string,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion

  //
  //#region AddMany ...
  /**
   * Add a Collection of items
   *
   * @param body an instance of XBaseRangeRequest which contains a collection of items
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callAddMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  callAddMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  callAddMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  callAddMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion
  //#endregion

  //
  //#region Update ...
  //
  //#region Update ...
  /**
   * Update Specified Item
   *
   * @param body the instance with all changes
   * @param id the Id of Object which are going to replace or update with this
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callUpdate(
    id: TKey,
    body: TModel,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  callUpdate(
    id: TKey,
    body: TModel,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  callUpdate(
    id: TKey,
    body: TModel,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  callUpdate(
    id: TKey,
    body: TModel,
    connectionId?: string,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion

  //
  //#region UpdateMany ...
  /**
   * Update a Collection of Items
   *
   * @param body an instance of XBaseRangeRequestDto
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callUpdateMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  callUpdateMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  callUpdateMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  callUpdateMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion
  //#endregion

  //
  //#region Exists ...
  /**
   * Check an items is Exists or not
   *
   * @param id the id of item
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callIsExists(
    id: TKey,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  callIsExists(
    id: TKey,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  callIsExists(
    id: TKey,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  callIsExists(
    id: TKey,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion

  //
  //#region Remove ...
  //
  //#region Remove ...
  /**
   * Remove Specified item by its ID
   *
   * @param id pointer to specific instance
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callRemove(
    id: TKey,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  callRemove(
    id: TKey,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  callRemove(
    id: TKey,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  callRemove(
    id: TKey,
    connectionId?: string,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion

  //
  //#region RemoveMany ...
  /**
   * Remove a Collection of Items base on RangeRequest
   *
   * @param body an instance of XBaseRangeRequestDto
   * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
   * @param reportProgress flag to report request and response progress.
   */
  callRemoveMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  callRemoveMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  callRemoveMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  callRemoveMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: any,
    reportProgress?: boolean
  ): Observable<any>;
  //#endregion
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\base\x-base-entity.service.ts

import {
  XQueryDto,
  XQueryResultDto,
  XBaseApiService,
} from 'x-framework-identity-sdk';
import { Observable } from 'rxjs';
import {
  XBaseEndPointAction,
  XBaseEndPointParam,
} from '../typings/x-endpoint.typings';
import { IXEntityActions } from './i-x-entity-actions.interface';
import { HttpResponse, HttpEvent, HttpParams } from '@angular/common/http';
import { applyConnectionIdToHeader } from '../typings/x-push-provider.typings';
import { toXString, XBaseRangeRequestDto, XValidators } from 'x-framework-core';

export abstract class XBaseEntityService<TModel, TKey>
  extends XBaseApiService
  implements IXEntityActions<TModel, TKey>
{
  //
  //#region Repository Implementation ...
  //
  //#region Retrieve ...
  //
  //#region Get ...
  public callGet(
    id: TKey,
    containsDetail?: boolean,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  public callGet(
    id: TKey,
    containsDetail?: boolean,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  public callGet(
    id: TKey,
    containsDetail?: boolean,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  public callGet(
    id: TKey,
    containsDetail?: boolean,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(id);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.Get);

    //
    // Preparing HttpParams ...
    let params: HttpParams = null;
    if (!!containsDetail) {
      params = this.addContainsDetailQueryParam(params, containsDetail);
    }

    //
    // Prepare Result ...
    return this.httpClient.get<TModel>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region GetAll ...
  public callGetAll(
    containsDetail?: boolean,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel[]>;
  public callGetAll(
    containsDetail?: boolean,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel[]>>;
  public callGetAll(
    containsDetail?: boolean,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel[]>>;
  public callGetAll(
    containsDetail?: boolean,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.GetAll);

    //
    // Preparing HttpParams ...
    let params: HttpParams = null;
    if (!!containsDetail) {
      params = this.addContainsDetailQueryParam(params, containsDetail);
    }

    //
    // Prepare Result ...
    return this.httpClient.get<Array<TModel>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FindOne ...
  public callFindOne(
    query: string,
    containsDetail?: boolean,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  public callFindOne(
    query: string,
    containsDetail?: boolean,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  public callFindOne(
    query: string,
    containsDetail?: boolean,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  public callFindOne(
    query: string,
    containsDetail?: boolean,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.FindOne, {
      key: XBaseEndPointParam.XQuery,
      value: query,
    });

    //
    // Preparing HttpParams ...
    let params: HttpParams = null;
    if (!!containsDetail) {
      params = this.addContainsDetailQueryParam(params, containsDetail);
    }

    //
    // Prepare Result ...
    return this.httpClient.get<TModel>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FindMany ...
  public callFindMany(
    query: string,
    containsDetail?: boolean,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel[]>;
  public callFindMany(
    query: string,
    containsDetail?: boolean,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel[]>>;
  public callFindMany(
    query: string,
    containsDetail?: boolean,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel[]>>;
  public callFindMany(
    query: string,
    containsDetail?: boolean,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.FindMany, {
      key: XBaseEndPointParam.XQuery,
      value: query,
    });

    //
    // Preparing HttpParams ...
    let params: HttpParams = null;
    if (!!containsDetail) {
      params = this.addContainsDetailQueryParam(params, containsDetail);
    }

    //
    // Prepare Result ...
    return this.httpClient.get<Array<TModel>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Query ...
  public callQuery(
    query: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<TModel>>;
  public callQuery(
    query: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<TModel>>>;
  public callQuery(
    query: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<TModel>>>;
  public callQuery(
    query: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.Query);

    //
    // Preparing HttpParams ...
    const params: HttpParams = this.generateXQueryHttpParams(query);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<TModel>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Add ...
  //
  //#region Add ...
  public callAdd(
    body: TModel,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  public callAdd(
    body: TModel,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  public callAdd(
    body: TModel,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  public callAdd(
    body: TModel,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.Add);

    //
    // Prepare Result ...
    return this.httpClient.post<TModel>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddOrUpdate ...
  public callAddOrUpdate(
    body: TModel,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  public callAddOrUpdate(
    body: TModel,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  public callAddOrUpdate(
    body: TModel,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  public callAddOrUpdate(
    body: TModel,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.AddOrUpdate);

    //
    // Prepare Result ...
    return this.httpClient.post<TModel>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddMany ...
  public callAddMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public callAddMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public callAddMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public callAddMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(body);
    XValidators.validateHasChilds(body.items);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.AddMany);

    //
    // Prepare Result ...
    return this.httpClient.post<void>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Update ...
  //
  //#region Update ...
  public callUpdate(
    id: TKey,
    body: TModel,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  public callUpdate(
    id: TKey,
    body: TModel,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  public callUpdate(
    id: TKey,
    body: TModel,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  public callUpdate(
    id: TKey,
    body: TModel,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(id);
    XValidators.validateNotNull(body);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.Update, {
      key: XBaseEndPointParam.XId,
      value: toXString(id),
    });

    //
    // Prepare Result ...
    return this.httpClient.put<TModel>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region UpdateMany ...
  public callUpdateMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public callUpdateMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public callUpdateMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public callUpdateMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(body);
    XValidators.validateHasChilds(body.items);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.UpdateMany);

    //
    // Prepare Result ...
    return this.httpClient.post<boolean>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Exists ...
  public callIsExists(
    id: TKey,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public callIsExists(
    id: TKey,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public callIsExists(
    id: TKey,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public callIsExists(
    id: TKey,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(id);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.IsExists, {
      key: XBaseEndPointParam.XId,
      value: toXString(id),
    });

    //
    // Prepare Result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Remove ...
  //
  //#region Remove ...
  public callRemove(
    id: TKey,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<TModel>;
  public callRemove(
    id: TKey,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<TModel>>;
  public callRemove(
    id: TKey,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<TModel>>;
  public callRemove(
    id: TKey,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(id);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.Remove, {
      key: XBaseEndPointParam.XId,
      value: toXString(id),
    });

    //
    // Prepare Result ...
    return this.httpClient.delete<TModel>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RemoveMany ...
  public callRemoveMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public callRemoveMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public callRemoveMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public callRemoveMany(
    body: XBaseRangeRequestDto<TModel>,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(body);
    XValidators.validateHasChilds(body.items);

    //
    // Instantiiate Headers from Default Headers ...
    let headers = this.defaultHeaders;
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XBaseEndPointAction,
      XBaseEndPointParam
    >(XBaseEndPointAction.RemoveMany);

    //
    // Prepare Result ...
    return this.httpClient.post<void>(endPointPath, body, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\base\x-base.guard.ts

import {
  Route,
  CanLoad,
  UrlTree,
  UrlSegment,
  CanActivate,
  CanActivateChild,
  RouterStateSnapshot,
  ActivatedRouteSnapshot,
} from '@angular/router';
import { Observable } from 'rxjs';
import {
  XAccountService,
  XFrameworkIdentitySDKConfig,
  X_FRAMEWORK_IDENTITY_SDK_CONFIG,
} from 'x-framework-identity-sdk';
import { filter, map, tap } from 'rxjs/operators';
import { Inject, Injectable } from '@angular/core';
import { XManagerService } from 'x-framework-services';
import { XAvailableRoles } from '../typings/x-role.typings';
import { checkIsInRoleByInfo, toRoleInfo } from '../tools/x-role.tools';
import { isNullOrUndefined, XExceptionIDs, XLoggable, XOneOrManyType } from 'x-framework-core';

@Injectable({
  providedIn: 'root',
})
export abstract class XBaseGuard
  extends XLoggable
  implements CanActivate, CanActivateChild, CanLoad
{
  //
  abstract roles: XOneOrManyType<XAvailableRoles>;

  //
  constructor(
    private authService: XAccountService,
    private managerService: XManagerService,
    @Inject(X_FRAMEWORK_IDENTITY_SDK_CONFIG)
    public config: XFrameworkIdentitySDKConfig
  ) {
    super(config);
  }

  //
  //#region Actions ...
  //
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    return this.handleGuard();
  }

  //
  canActivateChild(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    return this.handleGuard();
  }

  //
  canLoad(
    route: Route,
    segments: UrlSegment[]
  ): Observable<boolean> | Promise<boolean> | boolean {
    return this.handleGuard();
  }
  //#endregion

  //
  //#region Private Action ...
  private handleGuard(): Observable<boolean> {
    return this.authService.state$.pipe(
      filter(
        (state) =>
          !isNullOrUndefined(state) && !!state.isLoggedIn && !!state.profile
      ),
      map((state) => state.profile),
      map((user) => toRoleInfo(user)),
      map((roleInfo) => checkIsInRoleByInfo(this.roles, roleInfo)),
      tap((isPassed) => {
        //
        if (!isPassed) {
          this.handleGuardReject();
        }
      })
    );
  }

  //
  private handleGuardReject(): void {
    //
    this.managerService.notificationService.presentErrorNotification({
      exception: XExceptionIDs.NotAllowed,
      dissmissable: true,
    });

    //
    this.managerService.navigateByPage(this.config.Pages.Login);
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\config\x-saherelm-api-sdk.config.ts

import { XFrameworkCoreConfig } from 'x-framework-core';
import { XFrameworkServicesConfig } from 'x-framework-services';
import { XFrameworkIdentitySDKConfig } from 'x-framework-identity-sdk';

export type XSharedConfig = XFrameworkCoreConfig &
  XFrameworkServicesConfig &
  XFrameworkIdentitySDKConfig & { [key: string]: any };

// tslint:disable-next-line:no-empty-interface
export interface XSaherElmApiSDKConfig extends XSharedConfig {
  //
  // Push Service Configuration ...
  pushMessageAction: string;
  pushServiceRoute: string;
  pushManagerReconnectDelay: number;

  //
  corsBypasserProxy: string;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\configurations\x-configurations.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable, Inject } from '@angular/core';
import { XApiEndPoint } from '../typings/x-endpoint.typings';
import { X_SAHERELM_API_SDK_CONFIG } from '../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../config/x-saherelm-api-sdk.config';
import { XApiConfiguration, XBaseApiService, X_API_CONFIG } from 'x-framework-identity-sdk';

@Injectable({
  providedIn: 'root',
})
export class XConfigurationsService extends XBaseApiService {
  //
  //#region Constructor ...
  constructor(
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    //
    super(
      XApiEndPoint.Configurations,
      true,
      true,
      httpClient,
      config,
      apiConfig
    );
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\files\x-file.services.ts

import { Injectable } from '@angular/core';
import { XFileEntityService } from './services/x-file.entity.service';
import { XFileProviderService } from './services/x-file.provider.service';
import { XFileEntityPushService } from './services/x-file.entity.push.service';

/**
 * Export All Provided File related Services ...
 */
@Injectable({
  providedIn: 'root',
})
export class XFileServices {
  //
  //#region Constructor ...
  public constructor(
    public fileEntityService: XFileEntityService,
    public fileProviderService: XFileProviderService,
    public fileEntityPushService: XFileEntityPushService
  ) {}
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\files\x-file.typings.ts

/**
 * All Available EndPoint Routes ...
 */
export enum XFileServiceRoute {
  All = 'All',
  Upload = '',
  Remove = '',
  Get = '{id}',
  Query = 'Query',
  GetTags = '{id}/Tags',
  QueryOwned = 'Query/Owned',
  StreamById = '{id}/Stream/ById',
  AttachTags = '{id}/Tags/AttachMany',
  DetachTags = '{id}/Tags/DetachMany',
  DownloadById = '{id}/Download/ById',
  StreamByName = '{name}/Stream/ByName',
  DownloadByName = '{id}/Download/ByName',
}

/**
 * All Params Which Used in Related Services ...
 */
export enum XFileParam {
  Id = 'id',
  Ids = 'ids',
  Tags = 'tags',
  Name = 'name',
  Files = 'files',
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\files\models\x-file.dto.ts

import {
  XBaseDto,
  hasChild,
  XFileType,
  typeGuard,
  isSameObject,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';
import {
  XReferenceDto,
  parseXReferences,
  references2String,
} from '../../models/x-reference.dto';
import { XPersonDto } from '../../models/x-person.dto';

/**
 * a Model for Describing a File ...
 */
export interface XFileEntity extends XBaseDto {
  id: string;
  type: XFileType;
  name: string;
  thumb?: string;
  path: string;
  thumbPath?: string;
  uploadedOn: Date;
  fileName?: string;
  ownerId: string;
  references: string;
}

/**
 * a Model for Describing a File ...
 */
export interface XFileDto extends XBaseDto {
  id: string;
  type: XFileType;
  name: string;
  thumb?: string;
  path: string;
  thumbPath?: string;
  uploadedOn: Date;
  fileName?: string;
  ownerId: string;
  owner?: XPersonDto;
  references: Array<XReferenceDto<string>>;
}

/**
 * Default model ...
 */
export const defaultFileDto: XFileDto = {
  id: '',
  name: '',
  path: '',
  ownerId: '',
  references: [],
  type: undefined,
  thumb: undefined,
  owner: undefined,
  fileName: undefined,
  thumbPath: undefined,
  uploadedOn: undefined,
};

/**
 * Preparing Dto Field ...
 *
 * @param model
 */
export function prepareFileDtoFields(model?: XFileDto) {
  //
  if (isNullOrUndefined(model)) {
    //
    model = {
      ...defaultFileDto,
    };
  }

  //
  model = {
    id: !isNullOrEmptyString(model.id) ? model.id : defaultFileDto.id,
    name: !isNullOrEmptyString(model.name) ? model.name : defaultFileDto.name,
    path: !isNullOrEmptyString(model.path) ? model.path : defaultFileDto.path,
    ownerId: !isNullOrEmptyString(model.ownerId)
      ? model.ownerId
      : defaultFileDto.ownerId,
    references:
      !isNullOrUndefined(model.references) && !hasChild(model.references)
        ? [...model.references]
        : defaultFileDto.references,
    type: !isNullOrUndefined(model.type) ? model.type : defaultFileDto.type,
    thumb: !isNullOrEmptyString(model.thumb)
      ? model.thumb
      : defaultFileDto.thumb,
    owner: !isNullOrUndefined(model.owner)
      ? { ...model.owner }
      : defaultFileDto.owner,
    fileName: !isNullOrEmptyString(model.fileName)
      ? model.fileName
      : defaultFileDto.fileName,
    thumbPath: !isNullOrEmptyString(model.thumbPath)
      ? model.thumbPath
      : defaultFileDto.thumbPath,
    uploadedOn: !isNullOrUndefined(model.uploadedOn)
      ? model.uploadedOn
      : defaultFileDto.uploadedOn,
  };

  //
  return model;
}

/**
 * Check Model is Default or not ...
 *
 * @param model
 */
export function isDefaultFileDto(model?: XFileDto) {
  return isSameObject(prepareFileDtoFields(model), defaultFileDto);
}

/**
 * Model Type Guard ...
 */
export const isXFileDto = typeGuard<XFileDto>([
  'id',
  'name',
  'ownerId',
  'type',
  'uploadedOn',
  'path',
]);

/**
 * Converts a FileDto to Entity ...
 *
 * @param value
 * @returns
 */
export function fileDtoToEntity(value: XFileDto) {
  //
  let result: XFileEntity = undefined;

  //
  if (!isNullOrUndefined(value) && isXFileDto(value)) {
    //
    const references = references2String(value.references);
    result = {
      id: value.id,
      type: value.type,
      name: value.name,
      thumb: value.thumb,
      path: value.path,
      thumbPath: value.thumbPath,
      uploadedOn: value.uploadedOn,
      fileName: value.fileName,
      ownerId: value.ownerId,
      references,
    };
  }

  //
  return result;
}

/**
 * Converts a FileEntity to Dto ...
 *
 * @param value
 * @param owner
 * @returns
 */
export function fileEntityToDto(
  value: XFileEntity,
  owner: XPersonDto = undefined
) {
  //
  let result: XFileDto = undefined;

  //
  if (!isNullOrUndefined(value) && isXFileDto(value)) {
    //
    const references = parseXReferences<string>(value.references);
    result = {
      id: value.id,
      type: value.type,
      name: value.name,
      thumb: value.thumb,
      path: value.path,
      thumbPath: value.thumbPath,
      uploadedOn: value.uploadedOn,
      fileName: value.fileName,
      ownerId: value.ownerId,
      owner,
      references,
    };
  }

  //
  return result;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\files\services\x-file.entity.push.service.ts

import { Injectable } from "@angular/core";
import { XFileEntity } from "../models/x-file.dto";
import { XBaseEntityPushService } from "x-framework-push-service";
import { HttpTransportType, ITransport } from "@microsoft/signalr";

@Injectable({
  providedIn: 'root'
})
export class XFileEntityPushService extends XBaseEntityPushService<XFileEntity> {
  //
  //#region Abstracts ...
  hubName(): string {
    return 'fileEntityHub';
  }

  requiredAccessToken(): boolean {
    return true;
  }

  transportType(): HttpTransportType | ITransport {
    return HttpTransportType.LongPolling;
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\files\services\x-file.entity.service.ts

import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { XFileEntity } from '../models/x-file.dto';
import { XApiEndPoint } from '../../typings/x-endpoint.typings';
import { XBaseEntityService } from '../../base/x-base-entity.service';
import { X_API_CONFIG, XApiConfiguration } from 'x-framework-identity-sdk';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';

/**
 * Provides all Entity Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XFileEntityService extends XBaseEntityService<
  XFileEntity,
  string
> {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(
      XApiEndPoint.FilesEntity,
      true,
      true,
      httpClient,
      config,
      apiConfig
    );
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\files\services\x-file.provider.service.ts

import {
  toArray,
  hasChild,
  XValidators,
  XOneOrManyType,
  isNullOrEmptyString,
} from 'x-framework-core';
import {
  HttpEvent,
  HttpParams,
  HttpClient,
  HttpHeaders,
  HttpResponse,
} from '@angular/common/http';
import {
  XQueryDto,
  X_API_CONFIG,
  XBaseApiService,
  XQueryResultDto,
  XApiConfiguration,
} from 'x-framework-identity-sdk';
import { Observable } from 'rxjs';
import { Router } from '@angular/router';
import { XFileDto } from '../models/x-file.dto';
import { Inject, Injectable } from '@angular/core';
import { fillRouteParams } from '../../tools/x-route.tools';
import { XApiEndPoint } from '../../typings/x-endpoint.typings';
import { XFileParam, XFileServiceRoute } from '../x-file.typings';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';
import { applyConnectionIdToHeader } from '../../typings/x-push-provider.typings';

/**
 * Provides all Provider Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XFileProviderService extends XBaseApiService {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(XApiEndPoint.FilesService, true, true, httpClient, config, apiConfig);
  }
  //#endregion

  //
  //#region Tools ...
  //
  //#region StreamById ...
  /**
   * Stream Specified File ...
   *
   * @param id
   * @param observe
   * @param reportProgress
   */
  public streamById(
    id: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<ArrayBuffer>;
  public streamById(
    id: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<ArrayBuffer>>;
  public streamById(
    id: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<ArrayBuffer>>;
  public streamById(
    id: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XFileServiceRoute.StreamById),
      //
      // Params ...
      [
        {
          key: XFileParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      responseType: 'arraybuffer',
      reportProgress,
    });
  }
  //#endregion

  //
  //#region StreamByName ...
  /**
   * Stream Specified File ...
   *
   * @param name
   * @param observe
   * @param reportProgress
   */
  public streamByName(
    name: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<ArrayBuffer>;
  public streamByName(
    name: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<ArrayBuffer>>;
  public streamByName(
    name: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<ArrayBuffer>>;
  public streamByName(
    name: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(name);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XFileServiceRoute.StreamByName),
      //
      // Params ...
      [
        {
          key: XFileParam.Name,
          value: name,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      responseType: 'arraybuffer',
      reportProgress,
    });
  }
  //#endregion

  //
  //#region DownloadById ...
  /**
   * Download Specified File ...
   *
   * @param id
   * @param observe
   * @param reportProgress
   */
  public downloadById(
    id: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Blob>;
  public downloadById(
    id: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Blob>>;
  public downloadById(
    id: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Blob>>;
  public downloadById(
    id: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XFileServiceRoute.DownloadById),
      //
      // Params ...
      [
        {
          key: XFileParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      responseType: 'blob',
      reportProgress,
    });
  }
  //#endregion

  //
  //#region DownloadByName ...
  /**
   * Download Specified File ...
   *
   * @param name
   * @param observe
   * @param reportProgress
   */
  public downloadByName(
    name: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Blob>;
  public downloadByName(
    name: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Blob>>;
  public downloadByName(
    name: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Blob>>;
  public downloadByName(
    name: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(name);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XFileServiceRoute.DownloadByName),
      //
      // Params ...
      [
        {
          key: XFileParam.Name,
          value: name,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      responseType: 'blob',
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Upload ...
  /**
   * Upload ...
   *
   * @param files
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public upload(
    files: XOneOrManyType<File>,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFileDto>>;
  public upload(
    files: XOneOrManyType<File>,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFileDto>>>;
  public upload(
    files: XOneOrManyType<File>,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFileDto>>>;
  public upload(
    files: XOneOrManyType<File>,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(files);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Preparing Form Data ...
    let formData = new FormData();
    const filesArr = toArray(files);
    if (hasChild(filesArr)) {
      //
      // Convert Files Array to Form Data ...
      filesArr.forEach((f) => {
        formData.append(XFileParam.Files, f, f.name);
      });
    }

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(XFileServiceRoute.Upload);

    //
    // Prepare Result ...
    return this.httpClient.post<Array<XFileDto>>(endPointPath, formData, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Remove ...
  /**
   * Remove Files ...
   *
   * @param id
   * @param ids
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public remove(
    ids?: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFileDto>>;
  public remove(
    ids?: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFileDto>>>;
  public remove(
    ids?: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFileDto>>>;
  public remove(
    ids?: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(ids);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Adding ids to Parmas ...
    if (!isNullOrEmptyString(ids)) {
      //
      params = this.addCustomParam(params, {
        key: XFileParam.Ids,
        value: ids,
      });
    }

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(XFileServiceRoute.Remove);

    //
    // Prepare Result ...
    return this.httpClient.delete<Array<XFileDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Model ...
  //
  //#region Get ...
  /**
   * Get Specified Model ...
   */
  public get(
    id: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XFileDto>;
  public get(
    id: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XFileDto>>;
  public get(
    id: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XFileDto>>;
  public get(
    id: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XFileServiceRoute.Get),
      //
      // Params ...
      [
        {
          key: XFileParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<XFileDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region All ...
  /**
   * Retrieve all Exists Models ...
   *
   * @param observe
   * @param reportProgress
   */
  public all(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFileDto>>;
  public all(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFileDto>>>;
  public all(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFileDto>>>;
  public all(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Preparing HttpParams ...

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(XFileServiceRoute.All);

    //
    // Prepare Result ...
    return this.httpClient.get<Array<XFileDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Query ...
  /**
   * Query Model ...
   *
   * @param query
   * @param observe
   * @param reportProgress
   */
  public query(
    query: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XFileDto>>;
  public query(
    query: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XFileDto>>>;
  public query(
    query: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XFileDto>>>;
  public query(
    query: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Preparing HttpParams ...
    params = this.generateXQueryHttpParams(query);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(XFileServiceRoute.Query);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XFileDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region QueryOwned ...
  /**
   * Query Owned Models ...
   *
   * @param query
   * @param observe
   * @param reportProgress
   */
  public queryOwned(
    query: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XFileDto>>;
  public queryOwned(
    query: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XFileDto>>>;
  public queryOwned(
    query: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XFileDto>>>;
  public queryOwned(
    query: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Preparing HttpParams ...
    params = this.generateXQueryHttpParams(query);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(XFileServiceRoute.QueryOwned);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XFileDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Tags ...
  //
  //#region AttachTags ...
  /**
   * Attach Specified Tags of Specified Model ...
   *
   * @param id
   * @param tags
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public attachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public attachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public attachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public attachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Attach Tags to Params ...
    if (!isNullOrEmptyString(tags)) {
      //
      params = this.addCustomParam(params, {
        key: XFileParam.Tags,
        value: tags,
      });
    }

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XFileServiceRoute.AttachTags),
      //
      // Params ...
      [
        {
          key: XFileParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.post<void>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region DetachTags ...
  /**
   * Detach Specified Tags of Specified Model ...
   *
   * @param id
   * @param tags
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public detachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public detachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public detachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public detachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Attach Tags to Params ...
    if (!isNullOrEmptyString(tags)) {
      //
      params = this.addCustomParam(params, {
        key: XFileParam.Tags,
        value: tags,
      });
    }

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XFileServiceRoute.DetachTags),
      //
      // Params ...
      [
        {
          key: XFileParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.delete<void>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region GetTags ...
  /**
   * Retrieve Tags of Specified Model ...
   *
   * @param id
   * @param observe
   * @param reportProgress
   */
  public getTags(
    id: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<string>>;
  public getTags(
    id: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<string>>>;
  public getTags(
    id: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<string>>>;
  public getTags(
    id: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XFileServiceRoute.GetTags),
      //
      // Params ...
      [
        {
          key: XFileParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<Array<string>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\guards\admin-or-agent.guard.ts

import { Injectable } from '@angular/core';
import { XBaseGuard } from '../base/x-base.guard';
import { XAvailableRoles } from '../typings/x-role.typings';

@Injectable({
  providedIn: 'root',
})
export class AdminOrAgentGuard extends XBaseGuard {
  roles = [
    XAvailableRoles.Admin,
    XAvailableRoles.Agent
  ];
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\guards\admin.guard.ts

import { Injectable } from '@angular/core';
import { XBaseGuard } from '../base/x-base.guard';
import { XAvailableRoles } from '../typings/x-role.typings';

@Injectable({
  providedIn: 'root',
})
export class AdminGuard extends XBaseGuard {
  roles = XAvailableRoles.Admin;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\guards\agent.guard.ts

import { Injectable } from '@angular/core';
import { XBaseGuard } from '../base/x-base.guard';
import { XAvailableRoles } from '../typings/x-role.typings';

@Injectable({
  providedIn: 'root',
})
export class AgentGuard extends XBaseGuard {
  roles = XAvailableRoles.Agent;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\guards\user.guard.ts

import { Injectable } from '@angular/core';
import { XBaseGuard } from '../base/x-base.guard';
import { XAvailableRoles } from '../typings/x-role.typings';

@Injectable({
  providedIn: 'root',
})
export class UserGuard extends XBaseGuard {
  roles = XAvailableRoles.User;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\models\x-person.dto.ts

import {
  XBaseDto,
  typeGuard,
  isSameObject,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';

/**
 * Simply Represent a User ...
 */
export interface XPersonDto extends XBaseDto {
  username: string;
  firstname: string;
  lastname: string;
  avatar: string;
}

/**
 * Default Model ...
 */
export const defaultPersonDto: XPersonDto = {
  username: '',
  firstname: '',
  lastname: '',
  avatar: '',
};

/**
 * Prepare Model Fields ...
 *
 * @param model
 * @returns
 */
export function preparePersonDtoFields(model?: XPersonDto) {
  //
  if (isNullOrUndefined(model)) {
    model = {
      ...defaultPersonDto,
    };
  }

  //
  model = {
    avatar: isNullOrEmptyString(model.avatar)
      ? defaultPersonDto.avatar
      : model.avatar,
    username: isNullOrEmptyString(model.username)
      ? defaultPersonDto.username
      : model.username,
    lastname: isNullOrEmptyString(model.lastname)
      ? defaultPersonDto.lastname
      : model.lastname,
    firstname: isNullOrEmptyString(model.firstname)
      ? defaultPersonDto.firstname
      : model.firstname,
  };

  //
  return model;
}

/**
 * Check Model is Default or not ...
 *
 * @param model
 * @returns
 */
export function isDefaultPersonDto(model?: XPersonDto) {
  return isSameObject(preparePersonDtoFields(model), defaultPersonDto);
}

/**
 * Model Type Guard ...
 */
export const isXPersonDto = typeGuard<XPersonDto>([
  'username',
  'firstname',
  'lastname',
]);

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\models\x-reference.dto.ts

import {
  nameof,
  toNumber,
  XBaseDto,
  hasChild,
  toXString,
  typeGuard,
  isSameObject,
  toListString,
  parseListString,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';

export interface XReferenceDto<T> extends XBaseDto {
  index: number;
  providedFor: string;
  referencedTo: T;
}

/**
 * Model Type Guard ...
 */
export const isXReferenceDto = typeGuard<XReferenceDto<any>>([
  'index',
  'providedFor',
  'referencedTo',
]);

export const defaultReferenceDto: XReferenceDto<any> = {
  index: 0,
  providedFor: '',
  referencedTo: undefined,
};

export function prepareReferenceDtoFields(model?: XReferenceDto<any>) {
  //
  if (isNullOrUndefined(model)) {
    //
    model = {
      ...defaultReferenceDto,
    };
  }

  //
  model = {
    index: !isNullOrUndefined(model.index)
      ? model.index
      : defaultReferenceDto.index,
    referencedTo: !isNullOrUndefined(model.referencedTo)
      ? model.referencedTo
      : defaultReferenceDto.referencedTo,
    providedFor: !isNullOrEmptyString(model.providedFor)
      ? model.providedFor
      : defaultReferenceDto.providedFor,
  };

  //
  return model;
}

export function isDefaultReferenceDto(model?: XReferenceDto<any>) {
  return isSameObject(prepareReferenceDtoFields(model), defaultReferenceDto);
}

/**
 * Converts any object to XReferenceDto<T> ...
 *
 * @param value
 * @returns
 */
export function parseXReferenceDto<T>(value: any) {
  //
  let result: XReferenceDto<T> = undefined;

  //
  let isPassed = false;
  isPassed =
    !isNullOrUndefined(value) &&
    Object.keys(value).includes(nameof<XReferenceDto<T>>('index')) &&
    Object.keys(value).includes(nameof<XReferenceDto<T>>('referencedTo')) &&
    Object.keys(value).includes(nameof<XReferenceDto<T>>('providedFor'));
  if (isPassed) {
    //
    result = {
      index: toNumber(value.index),
      providedFor: toXString(value.providedFor),
      referencedTo: value.referencedTo as unknown as T,
    };
  }

  //
  return result;
}

/**
 * Parse an String to XReferenceDto<T> ...
 *
 * @param value
 * @returns
 */
export function parseXReference<T = any>(value: string) {
  //
  var result: XReferenceDto<T> = undefined;

  //
  if (!isNullOrEmptyString(value)) {
    //
    let parts = parseListString(value, '_');
    let isValid =
      !isNullOrUndefined(parts) && hasChild(parts) && parts.length >= 3;

    //
    if (isValid) {
      //
      result = {
        index: toNumber(parts[2]),
        referencedTo: parts[1] as unknown as T,
        providedFor: toXString(parts[0]),
      };
    }
  }

  //
  return result;
}

/**
 * Parse References List From String ...
 *
 * @param value
 * @returns
 */
export function parseXReferences<T = any>(value: string) {
  //
  let result: Array<XReferenceDto<T>> = [];

  //
  if (!isNullOrEmptyString(value)) {
    //
    let parts = parseListString(value);
    let isValid = !isNullOrUndefined(parts) && hasChild(parts);
    if (isValid) {
      //
      parts.forEach((part) => {
        //
        var reference = parseXReference<T>(part);
        isValid = !isNullOrUndefined(reference);
        if (isValid) {
          result.push(reference);
        }
      });
    }
  }

  //
  return result;
}

/**
 * Converts an XReferenceDto<T> to String Reperesentation ...
 *
 * @param value
 * @param separator
 * @returns
 */
export function reference2String<T = any>(
  value: XReferenceDto<T>,
  separator: string = '_'
) {
  //
  let result: string = undefined;

  //
  if (!isNullOrUndefined(value)) {
    result = `${value.providedFor}${separator}${value.referencedTo}${separator}${value.index}`;
  }

  //
  return result;
}

/**
 * Converts references Array to String Representation ...
 *
 * @param value
 * @param separator
 * @returns
 */
export function references2String<T = any>(
  value: Array<XReferenceDto<T>>,
  separator: string = ','
) {
  //
  let result: string = undefined;

  //
  let arr: Array<string> = [];
  if (!isNullOrUndefined(value) && hasChild(value)) {
    //
    value.forEach((v) => {
      //
      let refStr = reference2String(v);
      arr.push(refStr);
    });
  }

  //
  result = toListString(arr, separator);

  //
  return result;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\services\x-push-token-fetcher.service.ts

import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Inject, Injectable } from '@angular/core';
import { XAccountService } from 'x-framework-identity-sdk';
import { isNullOrUndefined, XBaseService } from 'x-framework-core';
import { IXPushServiceTokenFetcher } from 'x-framework-push-service';
import { X_SAHERELM_API_SDK_CONFIG } from '../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../config/x-saherelm-api-sdk.config';

@Injectable({
  providedIn: 'root',
})
export class XPushTokenFetcherService
  extends XBaseService
  implements IXPushServiceTokenFetcher
{
  //
  //#region Props ...
  token: string;
  token$: Observable<string> = this.accountsService.state$.pipe(
    map((state) => (isNullOrUndefined(state) ? null : state.accessToken))
  );
  //#endregion

  //
  //#region Constructor ...
  constructor(
    //
    @Inject(X_SAHERELM_API_SDK_CONFIG)
    public config: XSaherElmApiSDKConfig,
    //
    public accountsService: XAccountService
  ) {
    super(config);

    //
    accountsService.state$.subscribe((state) => {
      //
      if (isNullOrUndefined(state)) {
        this.token = null;
      } else {
        this.token = state.accessToken;
      }
    });
  }
  //#endregion

  /**
   * retrieve current user's access token ...
   * @returns token
   */
  public getToken(): string {
    return this.token;
  }
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\strings\x-string.services.ts

import { Injectable } from '@angular/core';
import { XStringEntityService } from './services/x-string.entity.service';
import { XStringProviderService } from './services/x-string.provider.service';
import { XStringEntityPushService } from './services/x-string.entity.push.service';

/**
 * Export All Provided String related Services ...
 */
@Injectable({
  providedIn: 'root',
})
export class XStringServices {
  //
  //#region Constructor ...
  public constructor(
    public stringEntityService: XStringEntityService,
    public stringProviderService: XStringProviderService,
    public stringEntityPushService: XStringEntityPushService
  ) {}
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\strings\x-string.typings.ts

/**
 * All Available EndPoint Routes ...
 */
export enum XStringsServiceRoute {
  //
  // Retrievers ...
  Get = '',
  Resources = 'Resources',
  Languages = 'Languages',
  AsResource = 'AsResource',
  ResourceValue = 'ResourceValue',
  IsResourceExists = 'IsResourceExists',

  //
  // Query ...
  QueryResourceIds = 'QueryResourceIds',
  QueryLocaleResources = 'QueryLocaleResources',
  QueryLanguageResourcs = 'QueryLanguageResourcs',

  //
  // Add ...
  Add = 'Add',
  AddModel = 'AddModel',
  AddLocale = 'AddLocale',
  AddResource = 'AddResource',
  AddOrUpdate = 'AddOrUpdate',
  AddOrUpdateModel = 'AddOrUpdateModel',
  AddOrUpdateLocale = 'AddOrUpdateLocale',

  //
  // Update ...
  Update = 'Update',
  UpdateModel = 'UpdateModel',
  UpdateLocale = 'UpdateLocale',

  //
  // Remove ...
  Remove = 'Remove',
  RemoveLocales = 'RemoveLocales',
  RemoveResource = 'RemoveResource',
  RemoveLanguage = 'RemoveLanguage',
}

/**
 * All Params Which Used in Related Services ...
 */
export enum XStringParam {
  Value = 'value',
  Resource = 'resource',
  Language = 'language',
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\strings\models\x-string.dto.ts

import {
  XBaseDto,
  hasChild,
  typeGuard,
  isSameObject,
  XBaseNumberIDDto,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';

/**
 * Represent a Locale Resource ...
 */
export interface XStringDto extends XBaseNumberIDDto {
  language: string;
  resourceTitle: string;
  translatedValue: string;
}

/**
 * Default Model ...
 */
export const defaultStringDto: XStringDto = {
  id: undefined,
  language: '',
  resourceTitle: '',
  translatedValue: '',
};

/**
 * Prepare Model Fields ...
 *
 * @param model
 * @returns
 */
export function prepareStringDtoFields(model?: XStringDto) {
  //
  if (isNullOrUndefined(model)) {
    model = {
      ...defaultStringDto,
    };
  }

  //
  model = {
    id: isNullOrUndefined(model.id) ? defaultStringDto.id : model.id,
    language: isNullOrEmptyString(model.language)
      ? defaultStringDto.language
      : model.language,
    resourceTitle: isNullOrEmptyString(model.resourceTitle)
      ? defaultStringDto.resourceTitle
      : model.resourceTitle,
    translatedValue: isNullOrEmptyString(model.translatedValue)
      ? defaultStringDto.translatedValue
      : model.translatedValue,
  };

  //
  return model;
}

/**
 * Check Model is Default or not ...
 *
 * @param model
 * @returns
 */
export function isDefaultStringDto(model?: XStringDto) {
  return isSameObject(prepareStringDtoFields(model), defaultStringDto);
}

/**
 * Simply Represent a Locale ...
 */
export interface XLocaleResourceDto extends XBaseDto {
  language: string;
  value: string;
}

/**
 * Default Model ...
 */
export const defaultLocaleResourceDto: XLocaleResourceDto = {
  value: '',
  language: '',
};

/**
 * Prepare Model Fields ...
 *
 * @param model
 * @returns
 */
export function prepareLocaleResourceDtoFields(model?: XLocaleResourceDto) {
  //
  if (isNullOrUndefined(model)) {
    model = {
      ...defaultLocaleResourceDto,
    };
  }

  //
  model = {
    value: isNullOrEmptyString(model.value)
      ? defaultLocaleResourceDto.value
      : model.value,
    language: isNullOrEmptyString(model.language)
      ? defaultLocaleResourceDto.language
      : model.language,
  };

  //
  return model;
}

/**
 * Check Model is Default or not ...
 *
 * @param model
 * @returns
 */
export function isDefaultLocaleResourceDto(model?: XLocaleResourceDto) {
  return isSameObject(
    prepareLocaleResourceDtoFields(model),
    defaultLocaleResourceDto
  );
}

/**
 * Represent a Locale by it's Resources ...
 */
export interface XResourceDto extends XBaseDto {
  resource: string;
  locales: Array<XLocaleResourceDto>;
}

/**
 * Default Model ...
 */
export const defaultResourceDto: XResourceDto = {
  resource: '',
  locales: [],
};

/**
 * Prepare Model Fields ...
 *
 * @param model
 * @returns
 */
export function prepareResourceDtoFields(model?: XResourceDto) {
  //
  if (isNullOrUndefined(model)) {
    model = {
      ...defaultResourceDto,
    };
  }

  //
  model = {
    resource: isNullOrEmptyString(model.resource)
      ? defaultResourceDto.resource
      : model.resource,
    locales:
      isNullOrUndefined(model.locales) || !hasChild(model.locales)
        ? defaultResourceDto.locales
        : model.locales.map((l) => prepareLocaleResourceDtoFields(l)),
  };

  //
  return model;
}

/**
 * Check Model is Default or not ...
 *
 * @param model
 * @returns
 */
export function isDefaultResourceDto(model?: XResourceDto) {
  return isSameObject(prepareResourceDtoFields(model), defaultResourceDto);
}

/**
 * Model Type Guard ...
 */
export const isXStringDto = typeGuard<XStringDto>([
  'id',
  'language',
  'resourceTitle',
  'translatedValue',
]);

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\strings\services\x-string.entity.push.service.ts

import { Injectable } from '@angular/core';
import { XStringDto } from '../models/x-string.dto';
import { XBaseEntityPushService } from 'x-framework-push-service';
import { HttpTransportType, ITransport } from '@microsoft/signalr';

@Injectable({
  providedIn: 'root',
})
export class XStringEntityPushService extends XBaseEntityPushService<XStringDto> {
  //
  //#region Abstracts ...
  hubName(): string {
    return 'stringEntityHub';
  }

  requiredAccessToken(): boolean {
    return true;
  }

  transportType(): HttpTransportType | ITransport {
    return HttpTransportType.LongPolling;
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\strings\services\x-string.entity.service.ts

import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { XStringDto } from '../models/x-string.dto';
import { XApiEndPoint } from '../../typings/x-endpoint.typings';
import { XBaseEntityService } from '../../base/x-base-entity.service';
import { X_API_CONFIG, XApiConfiguration } from 'x-framework-identity-sdk';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';

/**
 * Provides all Entity Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XStringEntityService extends XBaseEntityService<
  XStringDto,
  number
> {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(
      XApiEndPoint.StringsEntity,
      true,
      true,
      httpClient,
      config,
      apiConfig
    );
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\strings\services\x-string.provider.service.ts

import {
  HttpEvent,
  HttpClient,
  HttpParams,
  HttpHeaders,
  HttpResponse,
} from '@angular/common/http';
import {
  XQueryDto,
  XStringDto,
  X_API_CONFIG,
  XBaseApiService,
  XQueryResultDto,
  XApiConfiguration,
} from 'x-framework-identity-sdk';
import { Observable } from 'rxjs';
import { Router } from '@angular/router';
import {
  XApiEndPoint,
  XBaseEndPointParam,
} from '../../typings/x-endpoint.typings';
import { XValidators } from 'x-framework-core';
import { Inject, Injectable } from '@angular/core';
import { XStringParam, XStringsServiceRoute } from '../x-string.typings';
import { XLocaleResourceDto, XResourceDto } from '../models/x-string.dto';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';
import { applyConnectionIdToHeader } from '../../typings/x-push-provider.typings';

/**
 * Provides all Provider Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XStringProviderService extends XBaseApiService {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(
      XApiEndPoint.StringsService,
      true,
      true,
      httpClient,
      config,
      apiConfig
    );
  }
  //#endregion

  //
  //#region Actions ...
  //
  //#region Retrievers ...
  //
  //#region Get ...
  /**
   * Retrieve Specified Resource ...
   *
   * @param resource
   * @param language
   * @param observe
   * @param reportProgress
   */
  public get(
    resource: string,
    language: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XStringDto>;
  public get(
    resource: string,
    language: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XStringDto>>;
  public get(
    resource: string,
    language: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XStringDto>>;
  public get(
    resource: string,
    language: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.Get);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Language,
      value: language,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<XStringDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Languages ...
  /**
   * Retrieve all Available Languages List ...
   *
   * @param observe
   * @param reportProgress
   */
  public languages(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<string>>;
  public languages(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<string>>>;
  public languages(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<string>>>;
  public languages(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.Languages);

    //
    // Preparing HttpParams ...

    //
    // Prepare Result ...
    return this.httpClient.get<Array<string>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Resources ...
  /**
   * Retrieve Specified Resource Items as XResourceDto Presentation ...
   *
   * @param resource
   * @param observe
   * @param reportProgress
   */
  public resources(
    resource: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XStringDto>>;
  public resources(
    resource: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XStringDto>>>;
  public resources(
    resource: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XStringDto>>>;
  public resources(
    resource: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(resource);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.Resources);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<Array<XStringDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AsResource ...
  /**
   * Retrieve Specified Resource Items as XResourceDto Presentation ...
   *
   * @param resource
   * @param observe
   * @param reportProgress
   */
  public asResource(
    resource: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XResourceDto>;
  public asResource(
    resource: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XResourceDto>>;
  public asResource(
    resource: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XResourceDto>>;
  public asResource(
    resource: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(resource);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.AsResource);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<XResourceDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region ResourceValue ...
  /**
   * Retrieve Specified Translation of Specified Resource ...
   *
   * @param resource
   * @param language
   * @param observe
   * @param reportProgress
   */
  public resourceValue(
    resource: string,
    language: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<string>;
  public resourceValue(
    resource: string,
    language: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<string>>;
  public resourceValue(
    resource: string,
    language: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<string>>;
  public resourceValue(
    resource: string,
    language: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.ResourceValue);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Language,
      value: language,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<string>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region IsResourceExists ...
  /**
   * Check Specified Resource Exists or not ...
   *
   * @param resource
   * @param language
   * @param observe
   * @param reportProgress
   */
  public isResourceExists(
    resource: string,
    language: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public isResourceExists(
    resource: string,
    language: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public isResourceExists(
    resource: string,
    language: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public isResourceExists(
    resource: string,
    language: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.IsResourceExists);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Language,
      value: language,
    });

    //
    // Prepare Result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Query ...
  //
  //#region QueryResourceIds ...
  /**
   * Query Resource IDs ...
   *
   * @param query
   * @param observe
   * @param reportProgress
   */
  public queryResourceIds(
    query: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<string>>;
  public queryResourceIds(
    query: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<string>>>;
  public queryResourceIds(
    query: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<string>>>;
  public queryResourceIds(
    query: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Query as Params ...
    params = this.generateXQueryHttpParams(query);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.QueryResourceIds);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<string>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region QueryLocaleResources ...
  /**
   * Query Locale Resources ...
   *
   * @param query
   * @param language
   * @param observe
   * @param reportProgress
   */
  public queryLocaleResources(
    query: XQueryDto,
    language: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XLocaleResourceDto>>;
  public queryLocaleResources(
    query: XQueryDto,
    language: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XLocaleResourceDto>>>;
  public queryLocaleResources(
    query: XQueryDto,
    language: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XLocaleResourceDto>>>;
  public queryLocaleResources(
    query: XQueryDto,
    language: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Query as Params ...
    params = this.generateXQueryHttpParams(query);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.QueryLocaleResources);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XLocaleResourceDto>>(
      endPointPath,
      {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe,
        params,
        reportProgress,
      }
    );
  }
  //#endregion

  //
  //#region QueryLanguageResources ...
  /**
   * Query Specified Language Resources ...
   *
   * @param query
   * @param language
   * @param observe
   * @param reportProgress
   */
  public queryLanguageResources(
    query: XQueryDto,
    language: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XStringDto>>;
  public queryLanguageResources(
    query: XQueryDto,
    language: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XStringDto>>>;
  public queryLanguageResources(
    query: XQueryDto,
    language: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XStringDto>>>;
  public queryLanguageResources(
    query: XQueryDto,
    language: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Query as Params ...
    params = this.generateXQueryHttpParams(query);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.QueryLocaleResources);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XStringDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Add ...
  //
  //#region Add ...
  /**
   * Add Specified Resource ...
   *
   * @param resource
   * @param value
   * @param language
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public add(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public add(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public add(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public add(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(value);
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.Add);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Value,
      value: value,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Language,
      value: language,
    });

    //
    // Prepare Result ...
    return this.httpClient.post<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddModel ...
  /**
   * Add Specified Resource ...
   *
   * @param model
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public addModel(
    model: XStringDto,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XStringDto>;
  public addModel(
    model: XStringDto,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XStringDto>>;
  public addModel(
    model: XStringDto,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XStringDto>>;
  public addModel(
    model: XStringDto,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(model.resourceTitle);
    XValidators.validateNotEmpty(model.translatedValue);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.AddModel);

    //
    // Prepare Result ...
    return this.httpClient.post<XStringDto>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddLocale ...
  /**
   * Add Specified Locale Resource ...
   *
   * @param model
   * @param resource
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public addLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XStringDto>;
  public addLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XStringDto>>;
  public addLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XStringDto>>;
  public addLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(model.value);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.AddLocale);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });

    //
    // Prepare Result ...
    return this.httpClient.post<XStringDto>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddResource ...
  /**
   * Add Or Update all XResourceDto(s) Locales ...
   *
   * @param model
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public addResource(
    model: XResourceDto,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XStringDto>>;
  public addResource(
    model: XResourceDto,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XStringDto>>>;
  public addResource(
    model: XResourceDto,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XStringDto>>>;
  public addResource(
    model: XResourceDto,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(model.resource);
    XValidators.validateHasChilds(model.locales);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.AddResource);

    //
    // Preparing HttpParams ...

    //
    // Prepare Result ...
    return this.httpClient.post<Array<XStringDto>>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddOrUpdate ...
  /**
   * Add Or Update Resource ...
   *
   * @param resource
   * @param value
   * @param language
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public addOrUpdate(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public addOrUpdate(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public addOrUpdate(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public addOrUpdate(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(value);
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.AddOrUpdate);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Value,
      value: value,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Language,
      value: language,
    });

    //
    // Prepare Result ...
    return this.httpClient.post<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddOrUpdateModel ...
  /**
   * Add Or Update Resource ...
   *
   * @param model
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public addOrUpdateModel(
    model: XStringDto,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XStringDto>;
  public addOrUpdateModel(
    model: XStringDto,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XStringDto>>;
  public addOrUpdateModel(
    model: XStringDto,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XStringDto>>;
  public addOrUpdateModel(
    model: XStringDto,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(model.resourceTitle);
    XValidators.validateNotEmpty(model.translatedValue);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.AddOrUpdateModel);

    //
    // Prepare Result ...
    return this.httpClient.post<XStringDto>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region AddOrUpdateLocale ...
  /**
   * Add Or Update Specified Locale Resource ...
   *
   * @param model
   * @param resource
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public addOrUpdateLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XStringDto>;
  public addOrUpdateLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XStringDto>>;
  public addOrUpdateLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XStringDto>>;
  public addOrUpdateLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(model.value);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.AddOrUpdateLocale);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });

    //
    // Prepare Result ...
    return this.httpClient.post<XStringDto>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Update ...
  //
  //#region Update ...
  /**
   * Update Specified Resource ...
   *
   * @param resource
   * @param value
   * @param language
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public update(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public update(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public update(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public update(
    resource: string,
    value: string,
    language: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(value);
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.Update);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Value,
      value: value,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Language,
      value: language,
    });

    //
    // Prepare Result ...
    return this.httpClient.put<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region UpdateModel ...
  /**
   * Update Specified Resource ...
   *
   * @param model
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public updateModel(
    model: XStringDto,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XStringDto>;
  public updateModel(
    model: XStringDto,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XStringDto>>;
  public updateModel(
    model: XStringDto,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XStringDto>>;
  public updateModel(
    model: XStringDto,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(model.resourceTitle);
    XValidators.validateNotEmpty(model.translatedValue);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.UpdateModel);

    //
    // Prepare Result ...
    return this.httpClient.put<XStringDto>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region UpdateLocale ...
  /**
   * Update Specified Locale Resource ...
   *
   * @param model
   * @param resource
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public updateLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XStringDto>;
  public updateLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XStringDto>>;
  public updateLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XStringDto>>;
  public updateLocale(
    model: XLocaleResourceDto,
    resource: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(model.value);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.UpdateLocale);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });

    //
    // Prepare Result ...
    return this.httpClient.put<XStringDto>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Remove ...
  //
  //#region Remove ...
  /**
   * Remove Specified Resource ...
   *
   * @param resource
   * @param language
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public remove(
    resource: string,
    language: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public remove(
    resource: string,
    language: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public remove(
    resource: string,
    language: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public remove(
    resource: string,
    language: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(resource);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Instantiiate Headers from Default Headers ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });
    params = this.addCustomParam(params, {
      key: XStringParam.Language,
      value: language,
    });

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.Remove);

    //
    // Prepare Result ...
    return this.httpClient.delete<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RemoveLocales ...
  public removeLocales(
    resource: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XStringDto>>;
  public removeLocales(
    resource: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XStringDto>>>;
  public removeLocales(
    resource: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XStringDto>>>;
  public removeLocales(
    resource: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(resource);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Instantiiate Headers from Default Headers ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Preparing HttpParams ...
    params = this.addCustomParam(params, {
      key: XStringParam.Resource,
      value: resource,
    });


    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.RemoveLocales);

    //
    // Prepare Result ...
    return this.httpClient.delete<Array<XStringDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RemoveResource ...
  /**
   * Remove all Resource of Specified XResourceDto ...
   *
   * @param model
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public removeResource(
    model: XResourceDto,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public removeResource(
    model: XResourceDto,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public removeResource(
    model: XResourceDto,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public removeResource(
    model: XResourceDto,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(model.resource);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Instantiiate Headers from Default Headers ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.RemoveResource);

    //
    // Prepare Result ...
    return this.httpClient.post<void>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RemoveLanguage ...
  /**
   * Remove all Specified Language's Resources ...
   *
   * @param language
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public removeLanguage(
    language: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public removeLanguage(
    language: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public removeLanguage(
    language: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public removeLanguage(
    language: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Instantiiate Headers from Default Headers ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute<
      XStringsServiceRoute,
      XBaseEndPointParam
    >(XStringsServiceRoute.RemoveLanguage);

    //
    // Prepare Result ...
    return this.httpClient.delete<void>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      reportProgress,
    });
  }
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tags\x-tag.services.ts

import { Injectable } from '@angular/core';
import { XTagEntityService } from './services/x-tag.entity.service';
import { XTagProviderService } from './services/x-tag.provider.service';
import { XTagEntityPushService } from './services/x-tag.entity.push.service';

/**
 * Export All Provided Tag related Services ...
 */
@Injectable({
  providedIn: 'root',
})
export class XTagServices {
  //
  //#region Constructor ...
  public constructor(
    public tagEntityService: XTagEntityService,
    public tagProviderService: XTagProviderService,
    public tagEntityPushService: XTagEntityPushService
  ) {}
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tags\x-tag.typings.ts

/**
 * All Available EndPoint Routes ...
 */
export enum XTagServiceRoute {
  Add = '',
  All = 'All',
  Get = '{id}',
  Update = '{id}',
  Remove = '{id}',
  Query = 'Query',
  GetTag = 'GetTag',
  FindOne = 'FindOne',
  FindMany = 'FindMany',
}

/**
 * All Params Which Used in Related Services ...
 */
export enum XTagParam {
  Id = 'id',
  Tag = 'tag',
  Query = 'query'
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tags\models\x-tag.dto.ts

import {
  hasChild,
  XBaseDto,
  typeGuard,
  isSameObject,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';
import {
  XReferenceDto,
  parseXReferences,
  references2String,
} from '../../models/x-reference.dto';

/**
 * Represent Specified Tag ...
 */
export interface XTagEntity extends XBaseDto {
  id: number;
  tag: string;
  references: string;
}

/**
 * Represent Specified Tag ...
 */
export interface XTagDto extends XBaseDto {
  id: number;
  tag: string;
  references: Array<XReferenceDto<string>>;
}

/**
 * Default Model ...
 */
export const defaultTagDto: XTagDto = {
  id: 0,
  tag: undefined,
  references: [],
};

/**
 * Prepare Model Fields ...
 *
 * @param model
 * @returns
 */
export function prepareTagDtoFields(model?: XTagDto) {
  //
  if (isNullOrUndefined(model)) {
    //
    model = {
      ...defaultTagDto,
    };
  }

  //
  model = {
    //
    id:
      !isNullOrUndefined(model.id) && model.id > 0
        ? model.id
        : defaultTagDto.id,
    tag: !isNullOrEmptyString(model.tag) ? model.tag : defaultTagDto.tag,
    references:
      !isNullOrUndefined(model.references) && hasChild(model.references)
        ? [...model.references]
        : defaultTagDto.references,
  };

  //
  return model;
}

/**
 * Check Model is Default or not ...
 *
 * @param model
 * @returns
 */
export function isDefaultTagDto(model?: XTagDto) {
  return isSameObject(prepareTagDtoFields(model), defaultTagDto);
}

/**
 * Model Type Guard ...
 */
export const isXTagDto = typeGuard<XTagDto>(['id', 'tag']);

/**
 * Tag Dto to Tag Entity ...
 *
 * @param value
 * @returns
 */
export function tagDto2Entity(value: XTagDto) {
  //
  let result: XTagEntity = undefined;

  //
  if (!isNullOrUndefined(value) && isXTagDto(value)) {
    //
    const references = references2String(value.references);
    result = {
      id: value.id,
      tag: value.tag,
      references,
    };
  }

  //
  return result;
}

/**
 * Tag Entity to Tag Dto ...
 *
 * @param value
 * @returns
 */
export function tagEntity2Dto(value: XTagEntity) {
  //
  let result: XTagDto = undefined;

  //
  if (!isNullOrUndefined(value) && isXTagDto(value)) {
    //
    const references = parseXReferences<string>(value.references);
    result = {
      id: value.id,
      tag: value.tag,
      references,
    };
  }

  //
  return result;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tags\services\x-tag.entity.push.service.ts

import { Injectable } from '@angular/core';
import { XTagEntity } from '../models/x-tag.dto';
import { XBaseEntityPushService } from 'x-framework-push-service';
import { HttpTransportType, ITransport } from '@microsoft/signalr';

@Injectable({
  providedIn: 'root',
})
export class XTagEntityPushService extends XBaseEntityPushService<XTagEntity> {
  //
  //#region Props ...
  //#endregion

  //
  //#region Abstracts ...
  hubName(): string {
    return 'tagEntityHub';
  }

  requiredAccessToken(): boolean {
    return true;
  }

  transportType(): HttpTransportType | ITransport {
    return HttpTransportType.LongPolling;
  }

  registerSubjects(): void {
    super.registerSubjects();
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tags\services\x-tag.entity.service.ts

import { Router } from '@angular/router';
import { XTagEntity } from '../models/x-tag.dto';
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { XApiEndPoint } from '../../typings/x-endpoint.typings';
import { XBaseEntityService } from '../../base/x-base-entity.service';
import { X_API_CONFIG, XApiConfiguration } from 'x-framework-identity-sdk';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';

/**
 * Provides all Entity Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XTagEntityService extends XBaseEntityService<
  XTagEntity,
  string
> {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(
      XApiEndPoint.TagsEntity,
      true,
      true,
      httpClient,
      config,
      apiConfig
    );
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tags\services\x-tag.provider.service.ts

import {
  toArray,
  hasChild,
  XValidators,
  XOneOrManyType,
  isNullOrEmptyString,
} from 'x-framework-core';
import {
  HttpEvent,
  HttpParams,
  HttpClient,
  HttpHeaders,
  HttpResponse,
} from '@angular/common/http';
import {
  XQueryDto,
  X_API_CONFIG,
  XBaseApiService,
  XQueryResultDto,
  XApiConfiguration,
} from 'x-framework-identity-sdk';
import { Observable } from 'rxjs';
import { Router } from '@angular/router';
import { XTagDto } from '../models/x-tag.dto';
import { Inject, Injectable } from '@angular/core';
import { fillRouteParams } from '../../tools/x-route.tools';
import { XTagParam, XTagServiceRoute } from '../x-tag.typings';
import { XApiEndPoint } from '../../typings/x-endpoint.typings';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';
import { applyConnectionIdToHeader } from '../../typings/x-push-provider.typings';

/**
 * Provides all Provider Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XTagProviderService extends XBaseApiService {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(XApiEndPoint.TagsService, true, true, httpClient, config, apiConfig);
  }
  //#endregion

  //
  //#region Actions ...
  //
  //#region Add ...
  /**
   * Add Model ...
   *
   * @param model
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public add(
    model: XTagDto,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTagDto>;
  public add(
    model: XTagDto,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTagDto>>;
  public add(
    model: XTagDto,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTagDto>>;
  public add(
    model: XTagDto,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(model.tag);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(XTagServiceRoute.Add);

    //
    // Prepare Result ...
    return this.httpClient.post<XTagDto>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Update ...
  /**
   * Update Model ...
   *
   * @param id
   * @param model
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public update(
    id: number,
    model: XTagDto,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTagDto>;
  public update(
    id: number,
    model: XTagDto,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTagDto>>;
  public update(
    id: number,
    model: XTagDto,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTagDto>>;
  public update(
    id: number,
    model: XTagDto,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(model.tag);

    //
    if (model.id !== id) {
      model.id = id;
    }

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XTagServiceRoute.Update),
      //
      // Params ...
      [
        {
          key: XTagParam.Id,
          value: id.toString(),
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.put<XTagDto>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Remove ...
  /**
   * Remove Model ...
   *
   * @param id
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public remove(
    id: number,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTagDto>;
  public remove(
    id: number,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTagDto>>;
  public remove(
    id: number,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTagDto>>;
  public remove(
    id: number,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint ...
    const endPointPath = fillRouteParams(
      this.getActionRoute(XTagServiceRoute.Remove),
      [
        {
          key: XTagParam.Id,
          value: id.toString(),
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.delete<XTagDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Get ...
  /**
   * Get Specified Model ...
   */
  public get(
    id: number,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTagDto>;
  public get(
    id: number,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTagDto>>;
  public get(
    id: number,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTagDto>>;
  public get(
    id: number,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint ...
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XTagServiceRoute.Get),
      //
      // Params ...
      [
        {
          key: XTagParam.Id,
          value: id.toString(),
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<XTagDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region GetTag ...
  /**
   * Get Specified Model by Providing Label ...
   */
  public getTag(
    tag: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTagDto>;
  public getTag(
    tag: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTagDto>>;
  public getTag(
    tag: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTagDto>>;
  public getTag(
    tag: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(tag);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Attach Tag to Params ...
    params = this.addCustomParam(params, {
      key: XTagParam.Tag,
      value: tag
    });

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint ...
    const endPointPath = this.getActionRoute(XTagServiceRoute.GetTag);

    //
    // Prepare Result ...
    return this.httpClient.get<XTagDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region All ...
  /**
   * Retrieve all Exists Models ...
   *
   * @param observe
   * @param reportProgress
   */
  public all(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XTagDto>>;
  public all(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XTagDto>>>;
  public all(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XTagDto>>>;
  public all(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Preparing HttpParams ...

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(XTagServiceRoute.All);

    //
    // Prepare Result ...
    return this.httpClient.get<Array<XTagDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FindOne ...
  /**
   * Detect Specified Model by Providing Label Query ...
   */
  public findOne(
    query: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XTagDto>;
  public findOne(
    query: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XTagDto>>;
  public findOne(
    query: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XTagDto>>;
  public findOne(
    query: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(query);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Attach Tag to Params ...
    params = this.addCustomParam(params, {
      key: XTagParam.Query,
      value: query
    });

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint ...
    const endPointPath = this.getActionRoute(XTagServiceRoute.FindOne);

    //
    // Prepare Result ...
    return this.httpClient.get<XTagDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region FindMany ...
  /**
   * Detect Specified Models by Providing Label Query ...
   */
  public findMany(
    query: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XTagDto>>;
  public findMany(
    query: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XTagDto>>>;
  public findMany(
    query: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XTagDto>>>;
  public findMany(
    query: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(query);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Attach Tag to Params ...
    params = this.addCustomParam(params, {
      key: XTagParam.Query,
      value: query
    });

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint ...
    const endPointPath = this.getActionRoute(XTagServiceRoute.FindMany);

    //
    // Prepare Result ...
    return this.httpClient.get<Array<XTagDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Query ...
  /**
   * Query Model ...
   *
   * @param query
   * @param observe
   * @param reportProgress
   */
  public query(
    query: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XTagDto>>;
  public query(
    query: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XTagDto>>>;
  public query(
    query: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XTagDto>>>;
  public query(
    query: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Preparing HttpParams ...
    params = this.generateXQueryHttpParams(query);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(XTagServiceRoute.Query);

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XTagDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\terms\x-terms.service.ts

import { Injectable } from '@angular/core';
import { XTermsPushService } from './services/x-terms.push.service';
import { XTermsProviderService } from './services/x-terms.provider.service';

/**
 * Export All Provided Terms related Services ...
 */
@Injectable({
  providedIn: 'root',
})
export class XTermsServices {
  //
  //#region Constructor ...
  public constructor(
    public termsPushService: XTermsPushService,
    public termsProviderService: XTermsProviderService
  ) {}
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\terms\x-terms.typings.dto.ts

/**
 * All Available EndPoint Routes ...
 */
export enum XTermsServiceRoute {
  Add = 'Terms/{language}',
  Get = 'Terms/{language}',
  Update = 'Terms/{language}',
  Remove = 'Terms/{language}',
  Has = 'Terms/{language}/Has',
  Languages = 'Terms/Languages',
}

/**
 * All Params Which Used in Related Services ...
 */
export enum XTermsParam {
  Terms = 'terms',
  Language = 'language',
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\terms\services\x-terms.provider.service.ts

import {
  HttpEvent,
  HttpClient,
  HttpParams,
  HttpHeaders,
  HttpResponse,
} from '@angular/common/http';
import {
  X_API_CONFIG,
  XBaseApiService,
  XApiConfiguration,
} from 'x-framework-identity-sdk';
import { Observable } from 'rxjs';
import { Router } from '@angular/router';
import { Inject, Injectable } from '@angular/core';
import { XLocale, XValidators } from 'x-framework-core';
import { fillRouteParams } from '../../tools/x-route.tools';
import { XApiEndPoint } from '../../typings/x-endpoint.typings';
import { XTermsParam, XTermsServiceRoute } from '../x-terms.typings.dto';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';
import { applyConnectionIdToHeader } from '../../typings/x-push-provider.typings';

/**
 * Provides all Provider Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XTermsProviderService extends XBaseApiService {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(
      XApiEndPoint.TermsAndConditions,
      true,
      true,
      httpClient,
      config,
      apiConfig
    );
  }
  //#endregion

  //
  //#region Actions ...
  //
  //#region Get ...
  /**
   * Get Specified Languages Terms and Conditions ...
   *
   * @param language
   * @param observe
   * @param reportProgress
   */
  public get(
    language: XLocale | string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<string>;
  public get(
    language: XLocale | string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<string>>;
  public get(
    language: XLocale | string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<string>>;
  public get(
    language: XLocale | string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint ...
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XTermsServiceRoute.Get),
      //
      // Params ...
      [
        {
          key: XTermsParam.Language,
          value: language,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<string>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Languages ...
  /**
   * Get Languages Lists which Contains Terms and Conditions ...
   *
   * @param observe
   * @param reportProgress
   */
  public getLanguages(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<string>>;
  public getLanguages(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<string>>>;
  public getLanguages(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<string>>>;
  public getLanguages(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint ...
    const endPointPath = this.getActionRoute(XTermsServiceRoute.Languages);

    //
    // Prepare Result ...
    return this.httpClient.get<Array<string>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Has ...
  /**
   * Check Specified Languages Terms and Conditions Exists or not ...
   *
   * @param language
   * @param observe
   * @param reportProgress
   */
  public has(
    language: XLocale | string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Boolean>;
  public has(
    language: XLocale | string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Boolean>>;
  public has(
    language: XLocale | string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Boolean>>;
  public has(
    language: XLocale | string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint ...
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XTermsServiceRoute.Has),
      //
      // Params ...
      [
        {
          key: XTermsParam.Language,
          value: language,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Add ...
  /**
   * Add Terms and Conditions For Spevified Language ...
   *
   * @param language
   * @param terms
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public add(
    language: XLocale | string,
    terms: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<string>;
  public add(
    language: XLocale | string,
    terms: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<string>>;
  public add(
    language: XLocale | string,
    terms: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<string>>;
  public add(
    language: XLocale | string,
    terms: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(terms);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint ...
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XTermsServiceRoute.Add),
      //
      // Params ...
      [
        {
          key: XTermsParam.Language,
          value: language,
        },
      ]
    );

    //
    // Add terms Query String ...
    params = this.addCustomParam(params, {
      key: XTermsParam.Terms,
      value: terms,
    });

    //
    // Prepare Result ...
    return this.httpClient.post<string>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Update ...
  /**
   * Update Terms and Conditions For Spevified Language ...
   *
   * @param language
   * @param terms
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public update(
    language: XLocale | string,
    terms: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public update(
    language: XLocale | string,
    terms: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public update(
    language: XLocale | string,
    terms: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public update(
    language: XLocale | string,
    terms: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(terms);
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint ...
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XTermsServiceRoute.Update),
      //
      // Params ...
      [
        {
          key: XTermsParam.Language,
          value: language,
        },
      ]
    );

    //
    // Add terms Query String ...
    params = this.addCustomParam(params, {
      key: XTermsParam.Terms,
      value: terms,
    });

    //
    // Prepare Result ...
    return this.httpClient.put<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Remove ...
  /**
   * Remove Terms and Conditions For Spevified Language ...
   *
   * @param language
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public remove(
    language: XLocale | string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public remove(
    language: XLocale | string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public remove(
    language: XLocale | string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public remove(
    language: XLocale | string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(language);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint ...
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XTermsServiceRoute.Remove),
      //
      // Params ...
      [
        {
          key: XTermsParam.Language,
          value: language,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.delete<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\terms\services\x-terms.push.service.ts

import { Subject } from 'rxjs';
import {
  XBasePushService,
  XBaseEntityPushAction,
  IXPushServiceTokenFetcher,
  XFrameworkPushServiceConfig,
  X_FRAMEWORK_PUSH_SERVICE_CONFIG,
  X_FRAMEWORK_PUSH_SERVICE_TOKEN_FETCHER,
} from 'x-framework-push-service';
import { parseJson } from 'x-framework-core';
import { Inject, Injectable, Optional } from '@angular/core';
import { XStringDto } from '../../strings/models/x-string.dto';
import { HttpTransportType, ITransport } from '@microsoft/signalr';

@Injectable({
  providedIn: 'root',
})
export class XTermsPushService extends XBasePushService {
  //
  //#region Props ...
  onTermsAdded$ = new Subject<{
    model: XStringDto;
    actorId: string;
  }>();
  onTermsDeleted$ = new Subject<{
    model: XStringDto;
    actorId: string;
  }>();
  onTermsUpdated$ = new Subject<{
    model: XStringDto;
    actorId: string;
  }>();
  //#endregion

  //
  //#region Constructor ...
  constructor(
    @Inject(X_FRAMEWORK_PUSH_SERVICE_CONFIG)
    public config: XFrameworkPushServiceConfig,
    @Optional()
    @Inject(X_FRAMEWORK_PUSH_SERVICE_TOKEN_FETCHER)
    public tokenFetcher?: IXPushServiceTokenFetcher
  ) {
    super(config, tokenFetcher);
  }
  //#endregion

  //
  //#region Abstraction ...
  hubName(): string {
    return 'termsHub';
  }

  requiredAccessToken(): boolean {
    return true;
  }

  transportType(): HttpTransportType | ITransport {
    return HttpTransportType.LongPolling;
  }

  registerSubjects(): void {
    super.registerSubjects();

    //
    this.onTermsAdded((model: XStringDto, actorId: string) => {
      this.onTermsAdded$.next({ model, actorId });
    });

    //
    this.onTermsDeleted((model: XStringDto, actorId: string) => {
      this.onTermsDeleted$.next({ model, actorId });
    });

    //
    this.onTermsUpdated((model: XStringDto, actorId: string) => {
      this.onTermsUpdated$.next({ model, actorId });
    });
  }
  //#endregion

  //
  //#region Event Listeners ...
  //
  //#region Onners ...
  /**
   * Register Terms Added Event Listener ...
   *
   * @param callback
   */
  public onTermsAdded(callback: (model: XStringDto, actorId: string) => any) {
    //
    this.on(XBaseEntityPushAction.Add, (modelJson: string, actorId: string) => {
      //
      const model = parseJson<XStringDto>(modelJson);
      callback(model, actorId);
    });
  }

  /**
   * Register Terms Deleted Event Listener ...
   *
   * @param callback
   */
  public onTermsDeleted(callback: (model: XStringDto, actorId: string) => any) {
    //
    this.on(
      XBaseEntityPushAction.Delete,
      (modelJson: string, actorId: string) => {
        //
        const model = parseJson<XStringDto>(modelJson);
        callback(model, actorId);
      }
    );
  }

  /**
   * Register Terms Updated Event Listener ...
   *
   * @param callback
   */
  public onTermsUpdated(callback: (model: XStringDto, actorId: string) => any) {
    //
    this.on(
      XBaseEntityPushAction.Update,
      (modelJson: string, actorId: string) => {
        //
        const model = parseJson<XStringDto>(modelJson);
        callback(model, actorId);
      }
    );
  }
  //#endregion

  //
  //#region Offers ...
  /**
   * UnRegister Added Event Listener ...
   *
   * @param callback
   */
  public offTermsAdded(callback?: (model: XStringDto, actorId: string) => any) {
    this.off(XBaseEntityPushAction.Add, callback);
  }

  /**
   * UnRegister Deleted Event Listener ...
   *
   * @param callback
   */
  public offTermsDeleted(
    callback?: (model: XStringDto, actorId: string) => any
  ) {
    this.off(XBaseEntityPushAction.Delete, callback);
  }

  /**
   * UnRegister Updated Event Listener ...
   *
   * @param callback
   */
  public offTermsUpdated(
    callback?: (model: XStringDto, actorId: string) => any
  ) {
    this.off(XBaseEntityPushAction.Update, callback);
  }
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tokens\x-injectable-tokens.ts

import { InjectionToken } from '@angular/core';
import { XSaherElmApiSDKConfig } from '../config/x-saherelm-api-sdk.config';

export const X_SAHERELM_API_SDK_CONFIG = new InjectionToken<XSaherElmApiSDKConfig>(
  'x_config'
);

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tools\x-model.tools.ts

import { isArray, isObject } from 'x-framework-core';

/**
 * since for better handling soft deleted in database from api side the deleted
 * property added to all XEntities, for better comparing objects we have to delete it.
 * this method do this for us ...
 * 
 * @param model the input object
 * @returns clear object
 */
export function prepareModel<T>(model: T) {
  //
  if (!isObject(model) || isArray(model)) {
    return model;
  }

  //
  delete (model as any)['deleted'];

  //
  return model;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tools\x-role.tools.ts

import {
  toArray,
  hasChild,
  XExceptionIDs,
  throwException,
  XOneOrManyType,
} from 'x-framework-core';
import { XUserProfileDto } from 'x-framework-identity-sdk';
import { XUserRoleInfo, XAvailableRoles } from '../typings/x-role.typings';

export function toRoleInfo(user: XUserProfileDto): XUserRoleInfo {
  //
  if (!user) {
    return null;
  }

  //
  const result: XUserRoleInfo = {
    isAdmin: hasChild(user.roles) && user.roles.includes(XAvailableRoles.Admin),
    isResponsibleManager:
      hasChild(user.roles) &&
      user.roles.includes(XAvailableRoles.ResponsibleManager),
    isJournalist:
      hasChild(user.roles) && user.roles.includes(XAvailableRoles.Journalist),
    isChiefClerk:
      hasChild(user.roles) && user.roles.includes(XAvailableRoles.ChiefClerk),
    isChiefClerkAssistant:
      hasChild(user.roles) &&
      user.roles.includes(XAvailableRoles.ChiefClerkAssistant),
    isActuary:
      hasChild(user.roles) && user.roles.includes(XAvailableRoles.Actuary),
    isActuaryAssistant:
      hasChild(user.roles) &&
      user.roles.includes(XAvailableRoles.ActuaryAssistant),
    isReporter:
      hasChild(user.roles) && user.roles.includes(XAvailableRoles.Reporter),
    isReporterAssistant:
      hasChild(user.roles) &&
      user.roles.includes(XAvailableRoles.ReporterAssistant),
    isAgent: hasChild(user.roles) && user.roles.includes(XAvailableRoles.Agent),
    isUser: hasChild(user.roles) && user.roles.includes(XAvailableRoles.User),
  };

  //
  return result;
}

export function toRoleInfoByRoles(roles: string[]): XUserRoleInfo {
  //
  if (!hasChild(roles)) {
    return null;
  }

  //
  const result: XUserRoleInfo = {
    isAdmin: hasChild(roles) && roles.includes(XAvailableRoles.Admin),
    isResponsibleManager:
      hasChild(roles) && roles.includes(XAvailableRoles.ResponsibleManager),
    isJournalist: hasChild(roles) && roles.includes(XAvailableRoles.Journalist),
    isChiefClerk: hasChild(roles) && roles.includes(XAvailableRoles.ChiefClerk),
    isChiefClerkAssistant:
      hasChild(roles) && roles.includes(XAvailableRoles.ChiefClerkAssistant),
    isActuary: hasChild(roles) && roles.includes(XAvailableRoles.Actuary),
    isActuaryAssistant:
      hasChild(roles) && roles.includes(XAvailableRoles.ActuaryAssistant),
    isReporter: hasChild(roles) && roles.includes(XAvailableRoles.Reporter),
    isReporterAssistant:
      hasChild(roles) && roles.includes(XAvailableRoles.ReporterAssistant),
    isAgent: hasChild(roles) && roles.includes(XAvailableRoles.Agent),
    isUser: hasChild(roles) && roles.includes(XAvailableRoles.User),
  };

  //
  return result;
}

export function getTopRoleByRoleInfo(roleInfo: XUserRoleInfo) {
  //
  if (!roleInfo) {
    throwException(XExceptionIDs.InvalidArgs);
  }

  //
  if (roleInfo.isAdmin) {
    return XAvailableRoles.Admin;
  } else if (roleInfo.isResponsibleManager) {
    return XAvailableRoles.ResponsibleManager;
  } else if (roleInfo.isJournalist) {
    return XAvailableRoles.Journalist;
  } else if (roleInfo.isChiefClerk) {
    return XAvailableRoles.ChiefClerk;
  } else if (roleInfo.isChiefClerkAssistant) {
    return XAvailableRoles.ChiefClerkAssistant;
  } else if (roleInfo.isActuary) {
    return XAvailableRoles.Actuary;
  } else if (roleInfo.isActuaryAssistant) {
    return XAvailableRoles.ActuaryAssistant;
  } else if (roleInfo.isReporter) {
    return XAvailableRoles.Reporter;
  } else if (roleInfo.isReporterAssistant) {
    return XAvailableRoles.ReporterAssistant;
  } else if (roleInfo.isAgent) {
    return XAvailableRoles.Agent;
  } else if (roleInfo.isUser) {
    return XAvailableRoles.User;
  } else {
    return null;
  }
}

export function getTopRoleByRoles(roles: string[]) {
  //
  const roleInfo = toRoleInfoByRoles(roles);
  if (!roleInfo) {
    return null;
  }

  //
  return getTopRoleByRoleInfo(roleInfo);
}

export function getTopRoleByProfile(user: XUserProfileDto) {
  //
  const roleInfo = toRoleInfo(user);
  if (!roleInfo) {
    return null;
  }

  //
  return getTopRoleByRoleInfo(roleInfo);
}

export function checkIsInRoleByInfo(
  roles: XOneOrManyType<XAvailableRoles>,
  roleInfo: XUserRoleInfo
): boolean {
  //
  let result = false;

  //
  // Normalize Roles ...
  const normalRoles = toArray(roles);

  //
  for (const role of normalRoles) {
    switch (role) {
      //
      case XAvailableRoles.Admin:
        result = result || roleInfo.isAdmin;
        break;

      //
      case XAvailableRoles.ResponsibleManager:
        result = result || roleInfo.isResponsibleManager;
        break;

      //
      case XAvailableRoles.Journalist:
        result = result || roleInfo.isJournalist;
        break;

      //
      case XAvailableRoles.ChiefClerk:
        result = result || roleInfo.isChiefClerk;
        break;

      //
      case XAvailableRoles.ChiefClerkAssistant:
        result = result || roleInfo.isChiefClerkAssistant;
        break;

      //
      case XAvailableRoles.Actuary:
        result = result || roleInfo.isActuary;
        break;

      //
      case XAvailableRoles.ActuaryAssistant:
        result = result || roleInfo.isActuaryAssistant;
        break;

      //
      case XAvailableRoles.Reporter:
        result = result || roleInfo.isReporter;
        break;

      //
      case XAvailableRoles.ReporterAssistant:
        result = result || roleInfo.isReporterAssistant;
        break;

      //
      case XAvailableRoles.Agent:
        result = result || roleInfo.isAgent;
        break;

      //
      case XAvailableRoles.User:
        result = result || roleInfo.isUser;
        break;

      //
      default:
        result = result || false;
        break;
    }
  }

  //
  return result;
}

export function checkIsInRoleByUser(
  role: XAvailableRoles,
  user: XUserProfileDto
): boolean {
  //
  // Validate Args ...
  if (!role || !user) {
    return false;
  }

  //
  const roleInfo = toRoleInfo(user);
  if (!roleInfo) {
    return false;
  }

  //
  switch (role) {
    //
    case XAvailableRoles.Admin:
      return roleInfo.isAdmin;

    //
    case XAvailableRoles.ResponsibleManager:
      return roleInfo.isResponsibleManager;

    //
    case XAvailableRoles.Journalist:
      return roleInfo.isJournalist;

    //
    case XAvailableRoles.ChiefClerk:
      return roleInfo.isChiefClerk;

    //
    case XAvailableRoles.ChiefClerkAssistant:
      return roleInfo.isChiefClerkAssistant;

    //
    case XAvailableRoles.Actuary:
      return roleInfo.isActuary;

    //
    case XAvailableRoles.ActuaryAssistant:
      return roleInfo.isActuaryAssistant;

    //
    case XAvailableRoles.Reporter:
      return roleInfo.isReporter;

    //
    case XAvailableRoles.ReporterAssistant:
      return roleInfo.isReporterAssistant;

    //
    case XAvailableRoles.Agent:
      return roleInfo.isAgent;

    //
    case XAvailableRoles.User:
      return roleInfo.isUser;

    //
    default:
      return false;
  }
}

export function extractAvaialableRoles() {
  //
  const AllRoles = Object.assign({}, XAvailableRoles);
  let result = Object.values(AllRoles);
  return result;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\tools\x-route.tools.ts

import {
  hasChild,
  XKeyValue,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';

/**
 * Prepare a route by replacing it's params by providing values ...
 */
export function fillRouteParams(
  route: string,
  params?: Array<XKeyValue<string, string>>
) {
  //
  let result = '';

  //
  // Validate ...
  if (isNullOrEmptyString(route)) {
    return result;
  }

  //
  // Check Params Has Child ...
  if (!isNullOrUndefined(params) && hasChild(params)) {
    //
    result = route;
    for (let param of params) {
      //
      const key = `{${param.key}}`;
      result = result.replace(key, param.value);
    }
  }

  //
  return result;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\typings\x-endpoint.typings.ts

//
//#region Custom Header and Params  ...
export enum XCHeader {
  Role = 'role',
  ForceRole = 'forceRole',
}
//#endregion

//
//#region Params ...
/**
 * Params Usually Used in Query Strings ...
 */
export enum XBaseParams {
  XId = 'id',
  XIds = 'ids',
  XSoftDelete = 'softDelete',
  XIgnoreSoftDeleteds = 'ignoreSoftDeleteds',
}

/**
 * prepare all Route Params which used in Account Services Endpoints ...
 */
export enum XBaseEndPointParam {
  XId = '{xId}',
  XIds = '{xIds}',
  XHash = '{xHash}',
  XDate = '{xDate}',
  XQuery = '{xQuery}',
  XTitle = '{xTitle}',
  XIdentifier = '{xIdentifier}',
  XConnectionID = '{xConnectionId}',
  XConnectionIDs = '{xConnectionIds}',
  XUserSelectByParam = '{xUserSelectByParam}',
  XIgnoreSoftDeleteds = '{xIgnoreSoftDeleteds}',
  XUserSelectByParams = '{xUserSelectByParams}',
}
export type XBaseEndPointParams = keyof typeof XBaseEndPointParam;

/**
 * All Commonly Used EndPoints Actions ...
 */
export enum XBaseEndPointAction {
  //
  // TODO: Complete this ...
  Get = '{xId}',
  GetAll = '',
  FindOne = 'FindOne/{xQuery}',
  FindMany = 'FindMany/{xQuery}',
  Query = 'Query',
  RequestPage = 'RequestPage',
  Add = '',
  AddOrUpdate = 'AddOrUpdate',
  AddMany = 'AddMany',
  Update = '{xId}',
  UpdateMany = 'UpdateMany',
  IsExists = '{xId}/IsExists',
  Remove = '{xId}',
  RemoveMany = 'RemoveMany',
}
export type XBaseEndPointActions = keyof typeof XBaseEndPointAction;
//#endregion

//
//#region Api EndPoints ...
/**
 * Represent all API End Points ...
 */
export enum XApiEndPoint {
  TagsEntity = 'Entities/Tags',
  TagsService = 'Services/Tags',
  FilesEntity = 'Entities/Files',
  FilesService = 'Services/Files',
  Configurations = 'Configurations',
  StringsEntity = 'Entities/Strings',
  StringsService = 'Services/Strings',
  WebinarsEntity = 'Entities/Webinars',
  WebinarsService = 'Services/Webinars',
  TermsAndConditions = 'Configurations',
}

export declare type XApiEndPoints = keyof typeof XApiEndPoint | string;
//#endregion

//
//#region Configuration ...
export enum XConfigurationEndPoint {
}

export type XConfigurationEndPoints = keyof typeof XConfigurationEndPoint;
//#endregion

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\typings\x-push-provider.typings.ts

import { HttpHeaders } from '@angular/common/http';
import { isNullOrEmptyString, isNullOrUndefined } from 'x-framework-core';

export enum XPushHeaderKeys {
  ConnectionId = 'requestID',
}

/**
 * add Connection Id to Headers ...
 * 
 * @param connectionId user connection id ...
 * @param headers an instance of HttpHeaders ...
 * 
 * @returns HttpHeaders instance
 */
export function applyConnectionIdToHeader(
  connectionId?: string,
  headers?: HttpHeaders
) {
  //
  // New Instance of Headers if Not provided ...
  if (isNullOrUndefined(headers)) {
    headers = new HttpHeaders();
  }

  //
  if (!isNullOrEmptyString(connectionId)) {
    headers = headers.set(XPushHeaderKeys.ConnectionId, connectionId);
  }

  //
  return headers;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\typings\x-role.typings.ts

export enum XAvailableRoles {
  Admin = 'admin',
  ResponsibleManager = 'responsible_manager',
  Journalist = 'journalist',
  ChiefClerk = 'chief_clerk',
  ChiefClerkAssistant = 'chief_clerk_assistant',
  Actuary = 'actuary',
  ActuaryAssistant = 'actuary_assistant',
  Reporter = 'reporter',
  ReporterAssistant = 'reporter_assistant',
  Agent = 'agent',
  User = 'user',
}

export interface XUserRoleInfo {
  isAdmin: boolean;
  isResponsibleManager: boolean;
  isJournalist: boolean;
  isChiefClerk: boolean;
  isChiefClerkAssistant: boolean;
  isActuary: boolean;
  isActuaryAssistant: boolean;
  isReporter: boolean;
  isReporterAssistant: boolean;
  isAgent: boolean;
  isUser: boolean;
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\webinars\x-webinar.services.ts

import { Injectable } from '@angular/core';
import { XWebinarPushService } from './services/x-webinar.push.service';
import { XWebinarEntityService } from './services/x-webinar.entity.service';
import { XWebinarProviderService } from './services/x-webinar.provider.service';
import { XWebinarEntityPushService } from './services/x-webinar.entity.push.service';
import { XWebinarSubscriberEntityService } from './services/x-webinarsubscriber.entity.service';

/**
 * Export All Provided Webinar related Services ...
 */
@Injectable({
  providedIn: 'root',
})
export class XWebinarServices {
  //
  //#region Constructor ...
  public constructor(
    public webinarPushService: XWebinarPushService,
    public webinarEntityService: XWebinarEntityService,
    public webinarProviderService: XWebinarProviderService,
    public webinarEntityPushService: XWebinarEntityPushService,
    public webinarSubscriberEntityService: XWebinarSubscriberEntityService
  ) {}
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\webinars\x-webinar.typings.ts

/**
 * All Available EndPoint Routes ...
 */
export enum XWebinarServiceRoute {
  CreateWebinar = '',
  GetWebinar = '{id}',
  GetWebinars = 'All',
  UpdateWebinar = '{id}',
  RemoveWebinar = '{id}',
  QueryWebinars = 'Query',
  GetFiles = '{id}/Files',
  GetTags = '{id}/Tags',
  AttachTags = '{id}/Tags',
  DetachTags = '{id}/Tags',
  RemoveFiles = '{id}/Files',
  UploadFiles = '{id}/Files',
  QueryOwnedWebinars = 'Query/Owned',
  GetSubscribers = '{id}/Subscribers',
  QueryJoinableWebinars = 'Query/Joinable',
  StreamFile = '{id}/Files/{fileId}/Stream',
  Subscribe = '{id}/Subscribe/{subscriberId}',
  QuerySubscribers = '{id}/Subscribers/Query',
  DownloadFile = '{id}/Files/{fileId}/Download',
  Unsubscribe = '{id}/Unsubscribe/{subscriberId}',
  GetSubscriber = '{id}/Subscriber/{subscriberId}',
  IsSubscribed = '{id}/IsSubscribed/{subscriberId}',
}

/**
 * All Params Which Used in Related Services ...
 */
export enum XWebinarParam {
  Id = 'id',
  Ids = 'ids',
  Tags = 'tags',
  Files = 'files',
  FileId = 'fileId',
  SubscriberId = 'subscriberId',
}

/**
 * Webinar Hub Actions ...
 */
export enum XWebinarPushAction {
  /// <summary>
  /// When a Webinar is Available to Join ...
  /// </summary>
  WebinarOpened = 'WebinarOpened',

  /// <summary>
  /// When a Webinar Closed ...
  /// </summary>
  WebinarClosed = 'WebinarClosed',

  /// <summary>
  /// When a Viewer is Joined to Webinar ...
  /// </summary>
  ViewerJoined = 'ViewerJoined',

  /// <summary>
  /// When a Webinar Subscriber Leaved a Webinar ...
  /// </summary>
  ViewerLeaved = 'ViewerLeaved',

  /// <summary>
  /// Retrieve Specified Webinar Visitors ...
  /// </summary>
  WebinarVisitors = 'WebinarVisitors',

  /// <summary>
  /// Send a Message to Webinar ...
  /// </summary>
  Message = 'Message',
}

/**
 * Webinar Entity Hub Actions ...
 */
export enum XWebinarEntityPushAction {
  Subscribe = 'Subscribe',
  Unsubscribe = 'Unsubscribe',
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\webinars\models\x-webinar.dto.ts

import {
  XBaseDto,
  typeGuard,
  isSameObject,
  XBaseNumberIDDto,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';
import {
  XResourceDto,
  prepareResourceDtoFields,
} from '../../strings/models/x-string.dto';
import { preparePersonDtoFields, XPersonDto } from '../../models/x-person.dto';

/**
 * Describe Webinar Types ...
 */
export enum XWebinarType {
  Public = 0,
  Private = 1,
}

export function ToWebinarType(index: number) {
  //
  if (index == 0) {
    return XWebinarType.Public;
  } else if (index == 1) {
    return XWebinarType.Private;
  }

  //
  return undefined;
}

/**
 * Represent a Webinar Model ...
 */
export interface XWebinarDto extends XBaseDto {
  id: string;
  ownerId: string;
  createdOn: Date;
  enabled: boolean;
  type: XWebinarType;
  owner?: XPersonDto;
  title: XResourceDto;
  description: XResourceDto;
}

/**
 * Default Model ...
 */
export const defaultWebinarDto: XWebinarDto = {
  id: '',
  ownerId: '',
  enabled: false,
  type: undefined,
  owner: undefined,
  title: undefined,
  createdOn: undefined,
  description: undefined,
};

/**
 * Prepare Model Fields ...
 *
 * @param model
 * @returns
 */
export function prepareWebinarDtoFields(model?: XWebinarDto) {
  //
  if (isNullOrUndefined(model)) {
    model = {
      ...defaultWebinarDto,
    };
  }

  //
  model = {
    id: isNullOrEmptyString(model.id) ? defaultWebinarDto.id : model.id,
    type: isNullOrUndefined(model.type) ? defaultWebinarDto.type : model.type,
    enabled: isNullOrUndefined(model.enabled)
      ? defaultWebinarDto.enabled
      : model.enabled,
    ownerId: isNullOrEmptyString(model.ownerId)
      ? defaultWebinarDto.ownerId
      : model.ownerId,
    createdOn: isNullOrUndefined(model.createdOn)
      ? defaultWebinarDto.createdOn
      : model.createdOn,
    owner: isNullOrUndefined(model.owner)
      ? defaultWebinarDto.owner
      : preparePersonDtoFields(model.owner),
    title: isNullOrUndefined(model.title)
      ? defaultWebinarDto.title
      : prepareResourceDtoFields(model.title),
    description: isNullOrUndefined(model.description)
      ? defaultWebinarDto.description
      : prepareResourceDtoFields(model.description),
  };

  //
  return model;
}

/**
 * Check Model is Default or not ...
 *
 * @param model
 * @returns
 */
export function isDefaultWebinarModel(model?: XWebinarDto) {
  return isSameObject(prepareWebinarDtoFields(model), defaultWebinarDto);
}

/**
 * Webinar Subscriber Model ...
 */
export interface XWebinarSubscriberDto extends XBaseNumberIDDto {
  webinarId: string;
  subscribedOn: Date;
  subscriberId: string;
  subscriber: XPersonDto;
}

/**
 * Default Model ...
 */
export const defaultWebinarSubscriberDto: XWebinarSubscriberDto = {
  id: undefined,
  webinarId: '',
  subscriberId: '',
  subscriber: undefined,
  subscribedOn: undefined,
};

/**
 * Prepare Model Fields ...
 *
 * @param model
 * @returns
 */
export function prepareWebinarSubscriberDtoFields(
  model?: XWebinarSubscriberDto
) {
  //
  if (isNullOrUndefined(model)) {
    model = {
      ...defaultWebinarSubscriberDto,
    };
  }

  //
  model = {
    id:
      isNullOrUndefined(model.id) || model.id <= 0
        ? defaultWebinarSubscriberDto.id
        : model.id,
    webinarId: isNullOrEmptyString(model.webinarId)
      ? defaultWebinarSubscriberDto.webinarId
      : model.webinarId,
    subscriberId: isNullOrEmptyString(model.subscriberId)
      ? defaultWebinarSubscriberDto.subscriberId
      : model.subscriberId,
    subscribedOn: isNullOrUndefined(model.subscribedOn)
      ? defaultWebinarSubscriberDto.subscribedOn
      : model.subscribedOn,
    subscriber: isNullOrUndefined(model.subscriber)
      ? defaultWebinarSubscriberDto.subscriber
      : preparePersonDtoFields(model.subscriber),
  };

  //
  return model;
}

/**
 * Check Model is Default or not ...
 *
 * @param model
 * @returns
 */
export function isDefaultWebinarSubscriberDto(model?: XWebinarSubscriberDto) {
  return isSameObject(
    prepareWebinarSubscriberDtoFields(model),
    defaultWebinarSubscriberDto
  );
}

/**
 * Model Type Guard ...
 */
export const isXWebinarDto = typeGuard<XWebinarDto>([
  'id',
  'ownerId',
  'type',
  'createdOn',
  'description',
  'title',
]);

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\webinars\services\x-webinar.entity.push.service.ts

import { Subject } from 'rxjs';
import { Injectable } from '@angular/core';
import { isNullOrUndefined, parseJson } from 'x-framework-core';
import { XWebinarEntityPushAction } from '../x-webinar.typings';
import { XBaseEntityPushService } from 'x-framework-push-service';
import { HttpTransportType, ITransport } from '@microsoft/signalr';
import { XWebinarDto, XWebinarSubscriberDto } from '../models/x-webinar.dto';

@Injectable({
  providedIn: 'root',
})
export class XWebinarEntityPushService extends XBaseEntityPushService<XWebinarDto> {
  //
  //#region Props ...
  onSubscribed$ = new Subject<{
    model: XWebinarSubscriberDto;
    actorId: string;
  }>();
  onUnsubscribed$ = new Subject<{
    model: XWebinarSubscriberDto;
    actorId: string;
  }>();
  //#endregion

  //
  //#region Abstracts ...
  hubName(): string {
    return 'webinarEntityHub';
  }

  requiredAccessToken(): boolean {
    return true;
  }

  transportType(): HttpTransportType | ITransport {
    return HttpTransportType.LongPolling;
  }

  registerSubjects(): void {
    super.registerSubjects();

    //
    this.onSubscribed((model: XWebinarSubscriberDto, actorId: string) => {
      this.onSubscribed$.next({ model, actorId });
    });

    //
    this.onUnsubscribed((model: XWebinarSubscriberDto, actorId: string) => {
      this.onUnsubscribed$.next({ model, actorId });
    });
  }
  //#endregion

  //
  //#region Actions ...
  /**
   * Fire New Subscriber Action ...
   *
   * @param model
   * @returns
   */
  public async subscribe(model: XWebinarSubscriberDto) {
    //
    // Validate ...
    let isValid = !isNullOrUndefined(model);
    if (!isValid) {
      return;
    }

    //
    await this.invoke(
      XWebinarEntityPushAction.Subscribe,
      JSON.stringify(model)
    );
  }

  /**
   * Fire Unsubscribe Action ...
   *
   * @param model
   * @returns
   */
  public async unsubscribe(model: XWebinarSubscriberDto) {
    //
    // Validate ...
    let isValid = !isNullOrUndefined(model);
    if (!isValid) {
      return;
    }

    //
    await this.invoke(
      XWebinarEntityPushAction.Unsubscribe,
      JSON.stringify(model)
    );
  }
  //#endregion

  //
  //#region Event Listeners ...
  //
  //#region Onners ...
  /**
   * Register Subscribe Event Listener ...
   *
   * @param callback
   */
  public onSubscribed(
    callback: (model: XWebinarSubscriberDto, actorId: string) => any
  ) {
    //
    this.on(
      XWebinarEntityPushAction.Subscribe,
      (modelJson: string, actorId: string) => {
        //
        const model = parseJson<XWebinarSubscriberDto>(modelJson);
        callback(model, actorId);
      }
    );
  }

  /**
   * Register Unsubscribe Event Listener ...
   *
   * @param callback
   */
  public onUnsubscribed(
    callback: (model: XWebinarSubscriberDto, actorId: string) => any
  ) {
    //
    this.on(
      XWebinarEntityPushAction.Unsubscribe,
      (modelJson: string, actorId: string) => {
        //
        const model = parseJson<XWebinarSubscriberDto>(modelJson);
        callback(model, actorId);
      }
    );
  }
  //#endregion

  //
  //#region Offers ...
  /**
   * UnRegister Subscribe Event Listener ...
   *
   * @param callback
   */
  public offSubscribed(
    callback?: (model: XWebinarSubscriberDto, actorId: string) => any
  ) {
    this.off(XWebinarEntityPushAction.Subscribe, callback);
  }

  /**
   * UnRegister Unsubscribe Event Listener ...
   *
   * @param callback
   */
  public offUnsubscribed(
    callback?: (model: XWebinarSubscriberDto, actorId: string) => any
  ) {
    this.off(XWebinarEntityPushAction.Unsubscribe, callback);
  }
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\webinars\services\x-webinar.entity.service.ts

import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { XWebinarDto } from '../models/x-webinar.dto';
import { XApiEndPoint } from '../../typings/x-endpoint.typings';
import { XBaseEntityService } from '../../base/x-base-entity.service';
import { X_API_CONFIG, XApiConfiguration } from 'x-framework-identity-sdk';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';

/**
 * Provides all Entity Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XWebinarEntityService extends XBaseEntityService<
  XWebinarDto,
  string
> {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(
      XApiEndPoint.WebinarsEntity,
      true,
      true,
      httpClient,
      config,
      apiConfig
    );
  }
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\webinars\services\x-webinar.provider.service.ts

import {
  toArray,
  hasChild,
  toFormData,
  XValidators,
  toListString,
  XOneOrManyType,
  isNullOrUndefined,
  isNullOrEmptyString,
} from 'x-framework-core';
import {
  HttpEvent,
  HttpClient,
  HttpParams,
  HttpHeaders,
  HttpResponse,
} from '@angular/common/http';
import {
  XQueryDto,
  X_API_CONFIG,
  XBaseApiService,
  XQueryResultDto,
  XApiConfiguration,
} from 'x-framework-identity-sdk';
import { Observable } from 'rxjs';
import { Router } from '@angular/router';
import { Inject, Injectable } from '@angular/core';
import { XFileDto } from '../../files/models/x-file.dto';
import { fillRouteParams } from '../../tools/x-route.tools';
import { XApiEndPoint } from '../../typings/x-endpoint.typings';
import { XWebinarParam, XWebinarServiceRoute } from '../x-webinar.typings';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XWebinarDto, XWebinarSubscriberDto } from '../models/x-webinar.dto';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';
import { applyConnectionIdToHeader } from '../../typings/x-push-provider.typings';

/**
 * Provides all Provider Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XWebinarProviderService extends XBaseApiService {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(
      XApiEndPoint.WebinarsService,
      true,
      true,
      httpClient,
      config,
      apiConfig
    );
  }
  //#endregion

  //
  //#region Webinar ...
  //
  //#region Create ...
  /**
   * Create Specified Described Webinars ...
   *
   * @param model
   * @param tags
   * @param files
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public create(
    model: XWebinarDto,
    tags?: XOneOrManyType<string>,
    files?: XOneOrManyType<File>,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XWebinarDto>;
  public create(
    model: XWebinarDto,
    tags?: XOneOrManyType<string>,
    files?: XOneOrManyType<File>,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XWebinarDto>>;
  public create(
    model: XWebinarDto,
    tags?: XOneOrManyType<string>,
    files?: XOneOrManyType<File>,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XWebinarDto>>;
  public create(
    model: XWebinarDto,
    tags?: XOneOrManyType<string>,
    files?: XOneOrManyType<File>,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotNull(model.title);
    XValidators.validateNotEmpty(model.ownerId);
    XValidators.validateNotNull(model.description);

    //
    // Since Here we support Medias, must sent all Body as
    // Form Data ...
    let formData: FormData = new FormData();

    //
    // Add Model to FormData ...
    formData = toFormData(
      { ...model }, // Model ...
      undefined, // Options ...
      formData, // Exists FormData Using ...
      undefined // Keys Prefix ...
    );

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(
      XWebinarServiceRoute.CreateWebinar
    );

    //
    // Handle Tags ...
    if (!isNullOrUndefined(tags)) {
      //
      const tagsArr = toArray(tags);
      if (hasChild(tagsArr)) {
        //
        const tagsListString = toListString(tagsArr);
        if (!isNullOrEmptyString(tagsListString)) {
          //
          params = this.addCustomParam(params, {
            key: XWebinarParam.Tags,
            value: tagsListString,
          });
        }
      }
    }

    //
    // Handle Files ...
    if (!isNullOrUndefined(files)) {
      //
      const filesArr = toArray(files);
      if (hasChild(filesArr)) {
        //
        // Convert Files Array to Form Data ...
        filesArr.forEach((f) => {
          formData.append(XWebinarParam.Files, f, f.name);
        });
      }
    }

    //
    // Prepare Result ...
    return this.httpClient.post<XWebinarDto>(endPointPath, formData, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Update ...
  /**
   * Update Webinar ...
   *
   * @param model
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public update(
    model: XWebinarDto,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XWebinarDto>;
  public update(
    model: XWebinarDto,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XWebinarDto>>;
  public update(
    model: XWebinarDto,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XWebinarDto>>;
  public update(
    model: XWebinarDto,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(model);
    XValidators.validateNotEmpty(model.id);
    XValidators.validateNotNull(model.title);
    XValidators.validateNotEmpty(model.ownerId);
    XValidators.validateNotNull(model.description);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.UpdateWebinar),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: model.id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.put<XWebinarDto>(endPointPath, model, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Remove ...
  /**
   * Remove Specified Webinar ...
   *
   * @param id
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public remove(
    id: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public remove(
    id: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public remove(
    id: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public remove(
    id: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.RemoveWebinar),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.delete<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Get ...
  /**
   * Get Specified Webinar ...
   */
  public get(
    id: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XWebinarDto>;
  public get(
    id: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XWebinarDto>>;
  public get(
    id: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XWebinarDto>>;
  public get(
    id: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    // headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.GetWebinar),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<XWebinarDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region All ...
  /**
   * Retrieve all Exists Webinars ...
   *
   * @param observe
   * @param reportProgress
   */
  public all(
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XWebinarDto>>;
  public all(
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XWebinarDto>>>;
  public all(
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XWebinarDto>>>;
  public all(
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Preparing HttpParams ...

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(XWebinarServiceRoute.GetWebinars);

    //
    // Prepare Result ...
    return this.httpClient.get<Array<XWebinarDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Query ...
  /**
   * Query Webinars ...
   *
   * @param query
   * @param observe
   * @param reportProgress
   */
  public query(
    query: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XWebinarDto>>;
  public query(
    query: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XWebinarDto>>>;
  public query(
    query: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XWebinarDto>>>;
  public query(
    query: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Preparing HttpParams ...
    params = this.generateXQueryHttpParams(query);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(
      XWebinarServiceRoute.QueryWebinars
    );

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XWebinarDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region QueryOwned ...
  /**
   * Query Owned Webinars ...
   *
   * @param query
   * @param observe
   * @param reportProgress
   */
  public queryOwned(
    query: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XWebinarDto>>;
  public queryOwned(
    query: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XWebinarDto>>>;
  public queryOwned(
    query: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XWebinarDto>>>;
  public queryOwned(
    query: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Preparing HttpParams ...
    params = this.generateXQueryHttpParams(query);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(
      XWebinarServiceRoute.QueryOwnedWebinars
    );

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XWebinarDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region QueryJoinable ...
  /**
   * Query Joinable Webinars ...
   *
   * @param query
   * @param observe
   * @param reportProgress
   */
  public queryJoinable(
    query: XQueryDto,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XWebinarDto>>;
  public queryJoinable(
    query: XQueryDto,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XWebinarDto>>>;
  public queryJoinable(
    query: XQueryDto,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XWebinarDto>>>;
  public queryJoinable(
    query: XQueryDto,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Preparing HttpParams ...
    params = this.generateXQueryHttpParams(query);

    //
    // Prepare Endpoint
    const endPointPath = this.getActionRoute(
      XWebinarServiceRoute.QueryJoinableWebinars
    );

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XWebinarDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Subscriber ...
  //
  //#region Subscribe ...
  /**
   * Subscribe a User to Webinar ...
   *
   * @param webinarId
   * @param subscriberId
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public subscribe(
    webinarId: string,
    subscriberId: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public subscribe(
    webinarId: string,
    subscriberId: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public subscribe(
    webinarId: string,
    subscriberId: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public subscribe(
    webinarId: string,
    subscriberId: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(webinarId);
    XValidators.validateNotEmpty(subscriberId);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.Subscribe),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: webinarId,
        },
        {
          key: XWebinarParam.SubscriberId,
          value: subscriberId,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.post<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region Unsubscribe ...
  /**
   * Unsubscribe Specified User from a Specified Webinar ...
   *
   * @param webinarId
   * @param subscriberId
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public unsubscribe(
    webinarId: string,
    subscriberId: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public unsubscribe(
    webinarId: string,
    subscriberId: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public unsubscribe(
    webinarId: string,
    subscriberId: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public unsubscribe(
    webinarId: string,
    subscriberId: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(webinarId);
    XValidators.validateNotEmpty(subscriberId);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.Unsubscribe),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: webinarId,
        },
        {
          key: XWebinarParam.SubscriberId,
          value: subscriberId,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.delete<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region IsSubscribed ...
  /**
   * Check Specified User Subscribed on a Webinar or not ...
   *
   * @param webinarId
   * @param subscriberId
   * @param observe
   * @param reportProgress
   */
  public isSubscribed(
    webinarId: string,
    subscriberId: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<boolean>;
  public isSubscribed(
    webinarId: string,
    subscriberId: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<boolean>>;
  public isSubscribed(
    webinarId: string,
    subscriberId: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<boolean>>;
  public isSubscribed(
    webinarId: string,
    subscriberId: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(webinarId);
    XValidators.validateNotEmpty(subscriberId);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.IsSubscribed),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: webinarId,
        },
        {
          key: XWebinarParam.SubscriberId,
          value: subscriberId,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<boolean>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region GetSubscriber ...
  /**
   * Retrieve Specified Subscriber ...
   *
   * @param webinarId
   * @param subscriberId
   * @param observe
   * @param reportProgress
   */
  public getSubscriber(
    webinarId: string,
    subscriberId: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XWebinarSubscriberDto>;
  public getSubscriber(
    webinarId: string,
    subscriberId: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XWebinarSubscriberDto>>;
  public getSubscriber(
    webinarId: string,
    subscriberId: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XWebinarSubscriberDto>>;
  public getSubscriber(
    webinarId: string,
    subscriberId: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(webinarId);
    XValidators.validateNotEmpty(subscriberId);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.GetSubscriber),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: webinarId,
        },
        {
          key: XWebinarParam.SubscriberId,
          value: subscriberId,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<XWebinarSubscriberDto>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region GetSubscribers ...
  /**
   * Retrieve Specified Webinars Subscribers ...
   *
   * @param webinarId
   * @param observe
   * @param reportProgress
   */
  public getSubscribers(
    webinarId: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XWebinarSubscriberDto>>;
  public getSubscribers(
    webinarId: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XWebinarSubscriberDto>>>;
  public getSubscribers(
    webinarId: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XWebinarSubscriberDto>>>;
  public getSubscribers(
    webinarId: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(webinarId);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.GetSubscribers),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: webinarId,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<Array<XWebinarSubscriberDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region QuerySubscribers ...
  /**
   * Query Specified Webinar's Subscribers ...
   *
   * @param query
   * @param webinarId
   * @param observe
   * @param reportProgress
   */
  public querySubscribers(
    query: XQueryDto,
    webinarId: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<XQueryResultDto<XWebinarSubscriberDto>>;
  public querySubscribers(
    query: XQueryDto,
    webinarId: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<XQueryResultDto<XWebinarSubscriberDto>>>;
  public querySubscribers(
    query: XQueryDto,
    webinarId: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<XQueryResultDto<XWebinarSubscriberDto>>>;
  public querySubscribers(
    query: XQueryDto,
    webinarId: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(query);
    XValidators.validateNotEmpty(webinarId);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.QuerySubscribers),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: webinarId,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<XQueryResultDto<XWebinarSubscriberDto>>(
      endPointPath,
      {
        withCredentials: this.apiConfig.withCredentials,
        headers,
        observe,
        params,
        reportProgress,
      }
    );
  }
  //#endregion
  //#endregion

  //
  //#region Files ...
  //
  //#region UploadFiles ...
  /**
   * Upload and Reference Files to Specified Webinar ...
   *
   * @param webinarId
   * @param files
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public uploadFiles(
    webinarId: string,
    files: XOneOrManyType<File>,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFileDto>>;
  public uploadFiles(
    webinarId: string,
    files: XOneOrManyType<File>,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFileDto>>>;
  public uploadFiles(
    webinarId: string,
    files: XOneOrManyType<File>,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFileDto>>>;
  public uploadFiles(
    webinarId: string,
    files: XOneOrManyType<File>,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotNull(files);
    XValidators.validateNotEmpty(webinarId);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Preparing Form Data ...
    let formData = new FormData();
    const filesArr = toArray(files);
    if (hasChild(filesArr)) {
      //
      // Convert Files Array to Form Data ...
      filesArr.forEach((f) => {
        formData.append(XWebinarParam.Files, f, f.name);
      });
    }

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.UploadFiles),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: webinarId,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.post<Array<XFileDto>>(endPointPath, formData, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region RemoveFiles ...
  /**
   * Remove Files of Specified Webinar ...
   *
   * @param id
   * @param ids
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public removeFiles(
    id: string,
    ids?: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFileDto>>;
  public removeFiles(
    id: string,
    ids?: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFileDto>>>;
  public removeFiles(
    id: string,
    ids?: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFileDto>>>;
  public removeFiles(
    id: string,
    ids?: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Adding ids to Parmas ...
    if (!isNullOrEmptyString(ids)) {
      //
      params = this.addCustomParam(params, {
        key: XWebinarParam.Ids,
        value: ids,
      });
    }

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.RemoveFiles),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.delete<Array<XFileDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region GetFiles ...
  /**
   * Get Files of Specified Webinar ...
   *
   * @param id
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public getFiles(
    id: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<XFileDto>>;
  public getFiles(
    id: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<XFileDto>>>;
  public getFiles(
    id: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<XFileDto>>>;
  public getFiles(
    id: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.GetFiles),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<Array<XFileDto>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region StreamFiles ...
  /**
   * Stream Specified File of Specified Webinar ...
   *
   * @param id
   * @param fileId
   * @param observe
   * @param reportProgress
   */
  public streamFile(
    id: string,
    fileId: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<ArrayBuffer>;
  public streamFile(
    id: string,
    fileId: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<ArrayBuffer>>;
  public streamFile(
    id: string,
    fileId: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<ArrayBuffer>>;
  public streamFile(
    id: string,
    fileId: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);
    XValidators.validateNotEmpty(fileId);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.StreamFile),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: id,
        },
        {
          key: XWebinarParam.FileId,
          value: fileId,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      responseType: 'arraybuffer',
      reportProgress,
    });
  }
  //#endregion

  //
  //#region DownloadFile ...
  /**
   * Download Specified File of Specified Webinar ...
   *
   * @param id
   * @param fileId
   * @param observe
   * @param reportProgress
   */
  public downloadFile(
    id: string,
    fileId: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Blob>;
  public downloadFile(
    id: string,
    fileId: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Blob>>;
  public downloadFile(
    id: string,
    fileId: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Blob>>;
  public downloadFile(
    id: string,
    fileId: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);
    XValidators.validateNotEmpty(fileId);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.DownloadFile),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: id,
        },
        {
          key: XWebinarParam.FileId,
          value: fileId,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      responseType: 'blob',
      reportProgress,
    });
  }
  //#endregion
  //#endregion

  //
  //#region Tags ...
  //
  //#region AttachTags ...
  /**
   * Attach Specified Tags of Specified Webinar ...
   *
   * @param id
   * @param tags
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public attachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public attachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public attachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public attachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Attach Tags to Params ...
    if (!isNullOrEmptyString(tags)) {
      //
      params = this.addCustomParam(params, {
        key: XWebinarParam.Tags,
        value: tags,
      });
    }

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.AttachTags),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.post<void>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region DetachTags ...
  /**
   * Detach Specified Tags of Specified Webinar ...
   *
   * @param id
   * @param tags
   * @param connectionId
   * @param observe
   * @param reportProgress
   */
  public detachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<void>;
  public detachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<void>>;
  public detachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<void>>;
  public detachTags(
    id: string,
    tags?: string,
    connectionId?: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Attach Tags to Params ...
    if (!isNullOrEmptyString(tags)) {
      //
      params = this.addCustomParam(params, {
        key: XWebinarParam.Tags,
        value: tags,
      });
    }

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);
    headers = applyConnectionIdToHeader(connectionId, headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.DetachTags),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.delete<void>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion

  //
  //#region GetTags ...
  /**
   * Retrieve Tags of Specified Webinar ...
   *
   * @param id
   * @param observe
   * @param reportProgress
   */
  public getTags(
    id: string,
    observe?: 'body',
    reportProgress?: boolean
  ): Observable<Array<string>>;
  public getTags(
    id: string,
    observe?: 'response',
    reportProgress?: boolean
  ): Observable<HttpResponse<Array<string>>>;
  public getTags(
    id: string,
    observe?: 'events',
    reportProgress?: boolean
  ): Observable<HttpEvent<Array<string>>>;
  public getTags(
    id: string,
    observe: any = 'body',
    reportProgress: boolean = false
  ): Observable<any> {
    //
    // Validate Args ...
    XValidators.validateNotEmpty(id);

    //
    // Base Requirements ...
    let params: HttpParams = null;
    let headers: HttpHeaders = this.defaultHeaders;

    //
    // Authentication ...
    headers = this.addAuthentication(headers);
    headers = this.addAcceptJson(headers);
    headers = this.addContentType(headers);

    //
    // Prepare Endpoint
    const endPointPath = fillRouteParams(
      //
      // Base Route on Endpoint ...
      this.getActionRoute(XWebinarServiceRoute.GetTags),
      //
      // Params ...
      [
        {
          key: XWebinarParam.Id,
          value: id,
        },
      ]
    );

    //
    // Prepare Result ...
    return this.httpClient.get<Array<string>>(endPointPath, {
      withCredentials: this.apiConfig.withCredentials,
      headers,
      observe,
      params,
      reportProgress,
    });
  }
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\webinars\services\x-webinar.push.service.ts

import { Subject } from 'rxjs';
import {
  XRTCPeerService,
  XHubConnectionDto,
  XBaseWebRTCService,
  IXPushServiceTokenFetcher,
  XFrameworkPushServiceConfig,
  X_FRAMEWORK_PUSH_SERVICE_CONFIG,
  X_FRAMEWORK_PUSH_SERVICE_TOKEN_FETCHER,
} from 'x-framework-push-service';
import { isNullOrEmptyString } from 'x-framework-core';
import { XWebinarPushAction } from '../x-webinar.typings';
import { Inject, Injectable, Optional } from '@angular/core';
import { HttpTransportType, ITransport } from '@microsoft/signalr';

@Injectable({
  providedIn: 'root',
})
export class XWebinarPushService extends XBaseWebRTCService {
  //
  //#region Props ...
  onViewerJoined$ = new Subject<{
    viewerId: string;
    webinarId: string;
    userId: string;
    username?: string;
  }>();
  onViewerLeaved$ = new Subject<{
    viewerId: string;
    webinarId: string;
    userId: string;
    username?: string;
  }>();
  onWebinarOpened$ = new Subject<string>();
  onWebinarClosed$ = new Subject<string>();
  //#endregion

  //
  //#region Constructor ...
  constructor(
    public rtcPeerService: XRTCPeerService,
    @Inject(X_FRAMEWORK_PUSH_SERVICE_CONFIG)
    public config: XFrameworkPushServiceConfig,
    @Optional()
    @Inject(X_FRAMEWORK_PUSH_SERVICE_TOKEN_FETCHER)
    public tokenFetcher?: IXPushServiceTokenFetcher
  ) {
    super(config, tokenFetcher);
  }
  //#endregion

  //
  //#region Abstracts ...
  hubName(): string {
    return 'webinarHub';
  }

  requiredAccessToken(): boolean {
    return true;
  }

  transportType(): HttpTransportType | ITransport {
    return HttpTransportType.ServerSentEvents;
  }

  skipNegotiation: false

  registerSubjects(): void {
    super.registerSubjects();

    //
    this.onWebinarClosed((webinarId: string) => {
      this.onWebinarClosed$.next(webinarId);
    });

    //
    this.onWebinarClosed((webinarId: string) => {
      this.onWebinarClosed$.next(webinarId);
    });

    //
    this.onViewerJoined(
      (
        viewerId: string,
        webinarId: string,
        userId: string,
        username?: string
      ) => {
        //
        this.onViewerJoined$.next({
          userId,
          viewerId,
          username,
          webinarId,
        });
      }
    );

    //
    this.onViewerLeaved(
      (
        viewerId: string,
        webinarId: string,
        userId: string,
        username?: string
      ) => {
        //
        this.onViewerLeaved$.next({
          userId,
          viewerId,
          username,
          webinarId,
        });
      }
    );
  }
  //#endregion

  //
  //#region Actions ...
  public async openWebinar(webinarId: string) {
    //
    // Validate ...
    if (isNullOrEmptyString(webinarId)) {
      return;
    }

    //
    await this.invoke(XWebinarPushAction.WebinarOpened, webinarId);
  }

  public async closeWebinar(webinarId: string) {
    //
    // Validate ...
    if (isNullOrEmptyString(webinarId)) {
      return;
    }

    //
    await this.invoke(XWebinarPushAction.WebinarClosed, webinarId);
  }

  public async joinWebinar(webinarId: string) {
    //
    // Validate ...
    if (isNullOrEmptyString(webinarId)) {
      return;
    }

    //
    await this.invoke(XWebinarPushAction.ViewerJoined, webinarId);
  }

  public async leaveWebinar(webinarId: string) {
    //
    // Validate ...
    if (isNullOrEmptyString(webinarId)) {
      return;
    }

    //
    await this.invoke(XWebinarPushAction.ViewerLeaved, webinarId);
  }

  public async webinarVisitors(webinarId: string) {
    //
    let result: Array<XHubConnectionDto> = [];

    //
    // Validate ...
    if (isNullOrEmptyString(webinarId)) {
      return result;
    }

    //
    result = await this.invoke<Array<XHubConnectionDto>>(XWebinarPushAction.WebinarVisitors, webinarId);
    return result;
  }

  public async sendMessage(webinarId: string, message: string) {
    //
    // Validate ...
    if (isNullOrEmptyString(webinarId)) {
      return;
    }

    //
    await this.invoke(XWebinarPushAction.Message, webinarId, message);
  }
  //#endregion

  //
  //#region Event Handlers ...
  //
  //#region Onners ...
  public onWebinarOpened(callback: (webinarId: string) => any) {
    this.on(XWebinarPushAction.WebinarOpened, callback);
  }

  public onWebinarClosed(callback: (webinarId?: string) => any) {
    this.on(XWebinarPushAction.WebinarClosed, callback);
  }

  public onViewerJoined(
    callback: (
      connectionId: string,
      webinarId: string,
      userId: string,
      username?: string
    ) => any
  ) {
    this.on(XWebinarPushAction.ViewerJoined, callback);
  }

  public onViewerLeaved(
    callback: (
      connectionId: string,
      webinarId: string,
      userId: string,
      username?: string
    ) => any
  ) {
    this.on(XWebinarPushAction.ViewerLeaved, callback);
  }
  //#endregion

  //
  //#region Offers ...
  public offWebinarOpened(callback?: (webinarId: string) => any) {
    this.off(XWebinarPushAction.WebinarOpened, callback);
  }

  public offWebinarClosed(callback?: (webinarId?: string) => any) {
    this.off(XWebinarPushAction.WebinarClosed, callback);
  }

  public offViewerJoined(
    callback?: (
      connectionId: string,
      webinarId: string,
      userId: string,
      username?: string
    ) => any
  ) {
    this.off(XWebinarPushAction.ViewerJoined, callback);
  }

  public offViewerLeaved(
    callback?: (
      connectionId: string,
      webinarId: string,
      userId: string,
      username?: string
    ) => any
  ) {
    this.off(XWebinarPushAction.ViewerLeaved, callback);
  }
  //#endregion
  //#endregion
}

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xApiSDKHolder\projects\x-saherelm-api-sdk\src\lib\webinars\services\x-webinarsubscriber.entity.service.ts

import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { XWebinarSubscriberDto } from '../models/x-webinar.dto';
import { XApiEndPoint } from '../../typings/x-endpoint.typings';
import { XBaseEntityService } from '../../base/x-base-entity.service';
import { X_API_CONFIG, XApiConfiguration } from 'x-framework-identity-sdk';
import { X_SAHERELM_API_SDK_CONFIG } from '../../tokens/x-injectable-tokens';
import { XSaherElmApiSDKConfig } from '../../config/x-saherelm-api-sdk.config';

/**
 * Provides all Entity Actions as a Service ...
 */
@Injectable({
  providedIn: 'root',
})
export class XWebinarSubscriberEntityService extends XBaseEntityService<
  XWebinarSubscriberDto,
  number
> {
  //
  //#region Constructor ...
  constructor(
    protected router: Router,
    protected httpClient: HttpClient,
    @Inject(X_SAHERELM_API_SDK_CONFIG) config: XSaherElmApiSDKConfig,
    @Inject(X_API_CONFIG) apiConfig: XApiConfiguration
  ) {
    super(
      XApiEndPoint.WebinarsEntity,
      true,
      true,
      httpClient,
      config,
      apiConfig
    );
  }
  //#endregion
}
