/* * Copyright (C) 2019-2022 Open StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ import {SCMap} from '../general/map'; import {SCErrorResponse} from './error'; import {SCIndexRequest, SCIndexResponse, SCIndexRoute} from './routes'; import { SCBookAvailabilityRequest, SCBookAvailabilityResponse, SCBookAvailabilityRoute, } from './routes/book-availability'; import {SCBulkAddRequest, SCBulkAddResponse, SCBulkAddRoute} from './routes/bulk-add'; import {SCBulkDoneRequest, SCBulkDoneResponse, SCBulkDoneRoute} from './routes/bulk-done'; import {SCBulkRequest, SCBulkResponse, SCBulkRoute} from './routes/bulk-request'; import {SCFeedbackRequest, SCFeedbackResponse, SCFeedbackRoute} from './routes/feedback'; import {SCSearchRequest, SCSearchResponse, SCSearchRoute} from './routes/search'; import {SCMultiSearchRequest, SCMultiSearchResponse, SCMultiSearchRoute} from './routes/search-multi'; import {SCThingUpdateRequest, SCThingUpdateResponse, SCThingUpdateRoute} from './routes/thing-update'; /** * Possible Verbs for HTTP requests */ export enum SCRouteHttpVerbs { GET = 'GET', POST = 'POST', PUT = 'PUT', } /** * The constructor of an error response */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export type SCErrorResponseConstructor = new (...arguments_: any[]) => SCErrorResponse; /** * A description of a route */ export interface SCRoute { /** * A map of names of possible errors that can be returned by the route with their appropriate status codes */ errorNames: SCErrorResponseConstructor[]; /** * HTTP verb to use to request the route */ method: SCRouteHttpVerbs; /** * Map of obligatory parameters and their type that have to be set via the requested path */ obligatoryParameters?: SCMap; /** * Name of the type of the request body */ requestBodyName: string; /** * Name of the type of the response body */ responseBodyName: string; /** * Status code for success */ statusCodeSuccess: number; /** * URL path of the route */ urlPath: string; } /** * An abstract route */ export abstract class SCAbstractRoute implements SCRoute { /** * @see SCRoute.errorNames */ errorNames: SCErrorResponseConstructor[] = []; /** * @see SCRoute.method */ method: SCRouteHttpVerbs = SCRouteHttpVerbs.GET; /** * @see SCRoute.obligatoryParameters */ obligatoryParameters?: SCMap; /** * @see SCRoute.requestBodyName */ requestBodyName = 'any'; /** * @see SCRoute.responseBodyName */ responseBodyName = 'any'; /** * @see SCRoute.statusCodeSuccess */ statusCodeSuccess = 200; /** * @see SCRoute.urlPath */ urlPath = '/'; /** * Get "compiled" URL path * * @param parameters Parameters to compile URL path with */ public getUrlPath(parameters: SCMap = {}): string { let obligatoryParameters: string[] = []; if (typeof this.obligatoryParameters === 'object') { obligatoryParameters = Object.keys(this.obligatoryParameters); } if (Object.keys(parameters).length > obligatoryParameters.length) { throw new Error('Extraneous parameters provided.'); } return this.urlPath .split('/') .map(part => { if (part.indexOf(':') !== 0) { return part; } const parameter = part.slice(1); if (parameters[parameter] === undefined) { throw new TypeError(`Parameter '${parameter}' not provided.`); } return parameters[parameter]; }) .join('/'); } } /** * Possible requests */ export type SCRequests = | SCBookAvailabilityRequest | SCBulkRequest | SCBulkAddRequest | SCBulkDoneRequest | SCFeedbackRequest | SCIndexRequest | SCMultiSearchRequest | SCSearchRequest | SCThingUpdateRequest; /** * Possible responses */ export type SCResponses = | SCBookAvailabilityResponse | SCBulkResponse | SCBulkAddResponse | SCBulkDoneResponse | SCFeedbackResponse | SCIndexResponse | SCMultiSearchResponse | SCSearchResponse | SCThingUpdateResponse; /** * Associated response for a request */ export type SCAssociatedResponse = REQUEST extends SCBookAvailabilityRequest ? SCBookAvailabilityResponse : REQUEST extends SCBulkRequest ? SCBulkResponse : REQUEST extends SCBulkAddRequest ? SCBulkAddResponse : REQUEST extends SCBulkDoneRequest ? SCBulkDoneResponse : REQUEST extends SCFeedbackRequest ? SCFeedbackResponse : REQUEST extends SCIndexRequest ? SCIndexResponse : REQUEST extends SCMultiSearchRequest ? SCMultiSearchResponse : REQUEST extends SCSearchRequest ? SCSearchResponse : REQUEST extends SCThingUpdateRequest ? SCThingUpdateResponse : never; /** * Associated request for a response */ export type SCAssociatedRequest = RESPONSE extends SCBookAvailabilityResponse ? SCBookAvailabilityRequest : RESPONSE extends SCBulkResponse ? SCBulkRequest : RESPONSE extends SCBulkAddResponse ? SCBulkAddRequest : RESPONSE extends SCBulkDoneResponse ? SCBulkDoneRequest : RESPONSE extends SCFeedbackResponse ? SCFeedbackRequest : RESPONSE extends SCIndexResponse ? SCIndexRequest : RESPONSE extends SCMultiSearchResponse ? SCMultiSearchRequest : RESPONSE extends SCSearchResponse ? SCSearchRequest : RESPONSE extends SCThingUpdateResponse ? SCThingUpdateRequest : never; /** * Associated request for a route */ export type SCAssignedRequest = ROUTE extends SCBookAvailabilityRoute ? SCBookAvailabilityRequest : ROUTE extends SCBulkRoute ? SCBulkRequest : ROUTE extends SCBulkAddRoute ? SCBulkAddRequest : ROUTE extends SCBulkDoneRoute ? SCBulkDoneRequest : ROUTE extends SCFeedbackRoute ? SCFeedbackRequest : ROUTE extends SCIndexRoute ? SCIndexRequest : ROUTE extends SCMultiSearchRoute ? SCMultiSearchRequest : ROUTE extends SCSearchRoute ? SCSearchRequest : ROUTE extends SCThingUpdateRoute ? SCThingUpdateRequest : never; /** * Associated response for a route */ export type SCAssignedResponse = ROUTE extends SCBookAvailabilityRoute ? SCBookAvailabilityResponse : ROUTE extends SCBulkRoute ? SCBulkResponse : ROUTE extends SCBulkAddRoute ? SCBulkAddResponse : ROUTE extends SCBulkDoneRoute ? SCBulkDoneResponse : ROUTE extends SCFeedbackRoute ? SCFeedbackResponse : ROUTE extends SCIndexRoute ? SCIndexResponse : ROUTE extends SCMultiSearchRoute ? SCMultiSearchResponse : ROUTE extends SCSearchRoute ? SCSearchResponse : ROUTE extends SCThingUpdateRoute ? SCThingUpdateResponse : never;