Added comments & license info

This commit is contained in:
Tino Fuhrmann 2019-04-30 19:01:43 +02:00
parent 7a372acbed
commit 35d3cc20c9
11 changed files with 237 additions and 18 deletions

View File

@ -12,10 +12,23 @@ import { {{classname}} } from '..{{filename}}';
{{/imports}}
{{#operations}}
/**
* {{#description}}{{{description}}}{{/description}}{{^description}}no description{{/description}}
*/
export class {{classname}}RequestFactory extends BaseAPIRequestFactory {
// TODO: allow passing of Configuration via Options (=> overwrites config set for this request factory
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
{{#allParams}}
* @param {{paramName}} {{description}}
{{/allParams}}
*/
public {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): RequestContext {
let config = options || this.configuration;
{{#allParams}}
@ -116,8 +129,6 @@ export class {{classname}}RequestFactory extends BaseAPIRequestFactory {
}
{{/operations}}
// TODO: find way to split these two files (both dependent on apitemplatefiles)
{{#operations}}
@ -125,7 +136,10 @@ export class {{classname}}ResponseProcessor {
{{#operation}}
/**
*
* Unwraps the actual response sent by the server from the response context and deserializes the response content
* to the expected objects
*
* @params response Response returned by the server for a request to {{nicknam}}
* @throws ApiException if the response code was not in [200, 299]
*/
public {{nickname}}(response: ResponseContext): {{#returnType}} {{{returnType}}}{{/returnType}} {{^returnType}} void {{/returnType}} {

View File

@ -1,3 +1,12 @@
/**
* Represents an error caused by an api call i.e. it has attributes for a HTTP status code
* and the returned body object.
*
* Example
* API returns a ErrorMessageObject whenever HTTP status code is not in [200, 299]
* => ApiException(404, someErrorMessageObject)
*
*/
export class ApiException<T> extends Error {
public constructor(public code: number, public body: T) {
super("HTTP-Code: " + code + "\nMessage: " + JSON.stringify(body))

View File

@ -1,8 +1,27 @@
import {RequestContext, ResponseContext} from './http/http';
import { Observable, from } from 'rxjs';
/**
* Defines the contract for a middleware intercepting requests before
* they are sent (but after the RequestContext was created)
* and before the ResponseContext is unwrapped.
*
*/
export interface Middleware {
/**
* Modifies the request before the request is sent.
*
* @param context RequestContext of a request which is about to be sent to the server
* @returns an observable of the updated request context
*
*/
pre(context: RequestContext): Observable<RequestContext>;
/**
* Modifies the returned response before it is deserialized.
*
* @param context ResponseContext of a sent request
* @returns an observable of the modified response context
*/
post(context: ResponseContext): Observable<ResponseContext>;
}
@ -22,7 +41,26 @@ export class PromiseMiddlewareWrapper implements Middleware {
}
/**
* Defines the contract for a middleware intercepting requests before
* they are sent (but after the RequestContext was created)
* and before the ResponseContext is unwrapped.
*
*/
export interface PromiseMiddleware {
/**
* Modifies the request before the request is sent.
*
* @param context RequestContext of a request which is about to be sent to the server
* @returns an observable of the updated request context
*
*/
pre(context: RequestContext): Observable<RequestContext>;
/**
* Modifies the returned response before it is deserialized.
*
* @param context ResponseContext of a sent request
* @returns an observable of the modified response context
*/
post(context: ResponseContext): Observable<ResponseContext>;
}

View File

@ -3,6 +3,10 @@ import {RequestContext} from '../http/http';
//@ts-ignore
import * as btoa from "btoa";
/**
* Base class for all authentication schemes.
*
*/
export abstract class SecurityAuthentication {
public constructor(private name: string) {
@ -17,10 +21,19 @@ export abstract class SecurityAuthentication {
return this.name;
}
/**
* Applies the authentication scheme to the request context
*
* @params context the request context which should use this authentication scheme
*/
public abstract applySecurityAuthentication(context: RequestContext): void;
}
/**
* Applies no authentication.
*
*/
export class NoAuthentication extends SecurityAuthentication {
public constructor() {
@ -32,12 +45,24 @@ export class NoAuthentication extends SecurityAuthentication {
}
}
/**
* Applies an api key to the request context.
*
*/
export class APIKeyAuthentication extends SecurityAuthentication {
/**
* Configures this api key authentication with the necessary properties
*
* @param authName: name of this authentication scheme as specified in the swagger.json
* @param paramName: Parameter name used for the api key
* @param keyLocation: Parameter location, either query, header or cookie.
* @param apiKey: The api key to be used for every request
*/
public constructor(authName: string, private paramName: string, private keyLocation: "query" | "header" | "cookie", private apiKey: string) {
super(authName);
}
public applySecurityAuthentication(context: RequestContext) {
if (this.keyLocation === "header") {
context.setHeaderParam(this.paramName, this.apiKey);
@ -48,10 +73,22 @@ export class APIKeyAuthentication extends SecurityAuthentication {
}
}
}
// TODO: guarantee that auth was configured properly
/**
* Applies basic http authentication to a request.
*
*/
export class HttpBasicAuthentication extends SecurityAuthentication {
/**
* Configures the http authentication with the required details.
*
*
* @param authName name of the authentication scheme as defined in swagger json
* @param username username for http basic authentication
* @param password password for http basic authentication
*/
public constructor(authName: string, private username: string, private password: string) {
super(authName);
}
@ -62,6 +99,7 @@ export class HttpBasicAuthentication extends SecurityAuthentication {
}
}
// TODO: How to handle oauth2 authentication!
export class OAuth2Authentication extends SecurityAuthentication {
public constructor(authName: string) {
super(authName);
@ -84,6 +122,10 @@ export type OAuth2Configuration = string;
export type AuthMethodsConfiguration = { {{#authMethods}}"{{name}}"?:{{#isApiKey}}ApiKeyConfiguration{{/isApiKey}}{{#isHttp}}HttpBasicConfiguration{{/isHttp}}{{#isOAuth}}OAuth2Configuration{{/isOAuth}}, {{/authMethods}} }
/**
* Creates the authentication methods from a swagger description.
*
*/
export function configureAuthMethods(conf: AuthMethodsConfiguration | undefined): AuthMethods {
let authMethods: AuthMethods = {
}

View File

@ -4,12 +4,30 @@ import {IsomorphicFetchHttpLibrary} from "./http/isomorphic-fetch";
import {ServerConfiguration, server1} from './servers';
import {configureAuthMethods, AuthMethods, AuthMethodsConfiguration} from './auth/auth';
/**
* Inetrface with which a configuration object can be configured.
*
*/
export interface ConfigurationParameters {
/**
* Default server to use
*/
baseServer?: ServerConfiguration<any>;
httpApi?: HttpLibrary; // override for fetch implementation
/**
* HTTP library to use e.g. IsomorphicFetch
*/
httpApi?: HttpLibrary;
/**
* The middlewares which will be applied to requests and responses
*/
middleware?: Middleware[]; // middleware to apply before/after fetch requests
/**
* configures all middlewares using the promise api instead of observables (which Middleware uses)
*/
promiseMiddleware?: PromiseMiddleware[];
/**
* Configuration for the available authentication methods
*/
authMethods?: AuthMethodsConfiguration
}
@ -20,9 +38,19 @@ export class Configuration {
middleware: Middleware[];
authMethods: AuthMethods;
/**
* Creates a new configuration object based on the given configuration.
* If a property is not included in conf, a default is used:
* - baseServer: server1
* - httpApi: IsomorphicFetchHttpLibrary
* - middleware: []
* - promiseMiddleware: []
* - authMethods: {}
* @param conf particial configuration
*/
constructor(conf: ConfigurationParameters = {}) {
this.baseServer = conf.baseServer !== undefined ? conf.baseServer : server1;
this.httpApi = conf.httpApi || new IsomorphicFetchHttpLibrary(); // TODO: replace with window.fetch?
this.httpApi = conf.httpApi || new IsomorphicFetchHttpLibrary(); // TODO: replace with window.fetch if available?
this.middleware = conf.middleware || [];
this.authMethods = configureAuthMethods(conf.authMethods);
if (conf.promiseMiddleware) {

View File

@ -26,6 +26,17 @@ export class Observable{{classname}} {
}
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
{{#allParams}}
* @param {{paramName}} {{description}}
{{/allParams}}
*/
public {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {
const requestContext = this.requestFactory.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options);

View File

@ -22,6 +22,17 @@ export class Promise{{classname}} {
}
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
{{#allParams}}
* @param {{paramName}} {{description}}
{{/allParams}}
*/
public {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {
const result = this.api.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}options);
return result.toPromise();

View File

@ -8,6 +8,9 @@ import { Observable } from 'rxjs';
export * from './isomorphic-fetch';
/**
* Represents a HTTP Method.
*/
export enum HttpMethod {
GET = "GET",
HEAD = "HEAD",
@ -19,16 +22,15 @@ export enum HttpMethod {
TRACE = "TRACE",
PATCH = "PATCH"
}
/**
* Represents a http file which will be uploaded to a server.
*/
export interface HttpFile {
data: Buffer;
name: string;
}
export interface FormEntry {
contentDisposition: string;
value: string | Blob;
}
export class HttpException extends Error {
public constructor(msg: string) {
@ -36,24 +38,49 @@ export class HttpException extends Error {
}
}
/**
* Represents a HTTP request context
*
*/
export class RequestContext {
private headers: { [key: string]: string } = {};
private body: string | FormData = "";
private url: URLParse;
/**
* Creates the request context using a http method and request resource url
*
* @param url url of the requested resource
* @param httpMethod http method
*/
public constructor(url: string, private httpMethod: HttpMethod) {
this.url = URLParse(url, true);
}
/*
* Returns the url set in the constructor including the query string
*
*/
public getUrl(): string {
return this.url.toString();
}
/**
* Replaces the url set in the constructor with this url.
*
*/
public setUrl(url: string) {
this.url = URLParse(url, true);
}
/**
* Sets the body of the http request either as a string or FormData
* Setting a body on a HTTP GET request is disallowed under HTTP-Spec 1.1. Section
* 4.3 and this method throws an HttpException accordingly.
*
* @param body the body of the request
*/
public setBody(body: string | FormData) {
// HTTP-Spec 1.1 Section 4.3
if (this.httpMethod === HttpMethod.GET) {
@ -85,6 +112,10 @@ export class RequestContext {
this.url.set("query", queryObj);
}
/**
* Sets a cookie with the name and value. NO check for duplicate cookies is performed
*
*/
public addCookie(name: string, value: string): void {
if (!this.headers["Cookie"]) {
this.headers["Cookie"] = "";

View File

@ -1,10 +1,21 @@
import {RequestContext, HttpMethod} from './http/http';
/**
*
* Represents the configuration of a server including its
* url template and variable configuration based on the url.
*
*/
export class ServerConfiguration<T> {
public constructor(private url: string, private variableConfiguration: T) {
}
/**
* Sets the value of the variables of this server.
*
* @param variableConfiguration a partial variable configuration for the variables contained in the url
*/
public setVariables(variableConfiguration: Partial<T>) {
for (const key in variableConfiguration) {
const val = variableConfiguration[key]
@ -27,7 +38,15 @@ export class ServerConfiguration<T> {
}
return replacedUrl
}
/**
* Creates a new request context for this server using the url with variables
* replaced with their respective values and the endpoint of the request appended.
*
* @param endpoint the endpoint to be queried on the server
* @param httpMethod httpMethod to be used
*
*/
public makeRequestContext(endpoint: string, httpMethod: HttpMethod): RequestContext {
return new RequestContext(this.getUrl() + endpoint, httpMethod);
}

View File

@ -1,3 +1,11 @@
/*
TODO: LICENSE INFO
*/
/**
* {{{appName}}}
* {{{appDescription}}}
*
* {{#version}}OpenAPI spec version: {{{version}}}{{/version}}
* {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}}
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/

View File

@ -1,3 +1,11 @@
/**
* Returns if a specific http code is in a given code range
* where the code range is defined as a combination of digits
* and "X" (the letter X) with a length of 3
*
* @param codeRange string with length 3 consisting of digits and "X" (the letter X)
* @param code the http status code to be checked against the code range
*/
export function isCodeInRange(codeRange: string, code: number): boolean {
// This is how the default value is encoded in OAG
if (codeRange === "0") {