adjust frontend to new backend

This commit is contained in:
wea_ondara
2024-05-27 19:05:54 +02:00
parent 8b60d023e8
commit 265a5f3063
67 changed files with 5506 additions and 703 deletions

View File

@@ -0,0 +1 @@
dist

30
templates/README.mustache Normal file
View File

@@ -0,0 +1,30 @@
## {{npmName}}@{{npmVersion}}
This generator creates TypeScript/JavaScript client that utilizes {{framework}}.
### Building
To build and compile the typescript sources to javascript use:
```
npm install
npm run build
```
### Publishing
First build the package then run ```npm publish```
### Consuming
navigate to the folder of your consuming project and run one of the following commands.
_published:_
```
npm install {{npmName}}@{{npmVersion}} --save
```
_unPublished (not recommended):_
```
npm install PATH_TO_GENERATED_PACKAGE --save

249
templates/api/api.mustache Normal file
View File

@@ -0,0 +1,249 @@
// TODO: better import syntax?
import {BaseAPIRequestFactory, RequiredError, COLLECTION_FORMATS} from './baseapi{{extensionForDeno}}';
import {Configuration} from '../configuration{{extensionForDeno}}';
import {RequestContext, HttpMethod, ResponseContext, HttpFile} from '../http/http{{extensionForDeno}}';
{{#platforms}}
{{#node}}
import {{^supportsES6}}* as{{/supportsES6}} FormData from "form-data";
import { URLSearchParams } from 'url';
{{/node}}
{{/platforms}}
import {ObjectSerializer} from '../models/ObjectSerializer{{extensionForDeno}}';
import {ApiException} from './exception{{extensionForDeno}}';
import {canConsumeForm, isCodeInRange} from '../util{{extensionForDeno}}';
import {SecurityAuthentication} from '../auth/auth{{extensionForDeno}}';
{{#useInversify}}
import { injectable } from "inversify";
{{/useInversify}}
{{#imports}}
import { {{classname}} } from '{{filename}}{{extensionForDeno}}';
{{/imports}}
{{#operations}}
/**
* {{{description}}}{{^description}}no description{{/description}}
*/
{{#useInversify}}
@injectable()
{{/useInversify}}
export class {{classname}}RequestFactory extends BaseAPIRequestFactory {
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
{{#allParams}}
* @param {{paramName}} {{description}}
{{/allParams}}
*/
public async {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}_options?: Configuration): Promise<RequestContext> {
let _config = _options || this.configuration;
{{#allParams}}
{{#required}}
// verify required parameter '{{paramName}}' is not null or undefined
if ({{paramName}} === null || {{paramName}} === undefined) {
throw new RequiredError("{{classname}}", "{{nickname}}", "{{paramName}}");
}
{{/required}}
{{/allParams}}
// Path Params
const localVarPath = '{{{path}}}'{{#pathParams}}
.replace('{' + '{{baseName}}' + '}', encodeURIComponent(String({{paramName}}))){{/pathParams}};
// Make Request Context
const requestContext = _config.baseServer.makeRequestContext(localVarPath, HttpMethod.{{httpMethod}});
requestContext.setHeaderParam("Accept", "application/json, */*;q=0.8")
{{#queryParams}}
// Query Params
if ({{paramName}} !== undefined) {
requestContext.setQueryParam("{{baseName}}", ObjectSerializer.serialize({{paramName}}, "{{{dataType}}}", "{{dataFormat}}"));
}
{{/queryParams}}
{{#headerParams}}
// Header Params
requestContext.setHeaderParam("{{baseName}}", ObjectSerializer.serialize({{paramName}}, "{{{dataType}}}", "{{dataFormat}}"));
{{/headerParams}}
{{#hasFormParams}}
// Form Params
const useForm = canConsumeForm([
{{#consumes}}
'{{{mediaType}}}',
{{/consumes}}
]);
let localVarFormParams
if (useForm) {
localVarFormParams = new FormData();
} else {
localVarFormParams = new URLSearchParams();
}
{{/hasFormParams}}
{{#formParams}}
{{#isArray}}
if ({{paramName}}) {
{{#isCollectionFormatMulti}}
{{paramName}}.forEach((element) => {
localVarFormParams.append('{{baseName}}', element as any);
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
// TODO: replace .append with .set
localVarFormParams.append('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS["{{collectionFormat}}"]));
{{/isCollectionFormatMulti}}
}
{{/isArray}}
{{^isArray}}
if ({{paramName}} !== undefined) {
// TODO: replace .append with .set
{{^isFile}}
localVarFormParams.append('{{baseName}}', {{paramName}} as any);
{{/isFile}}
{{#isFile}}
if (localVarFormParams instanceof FormData) {
{{#platforms}}
{{#node}}
localVarFormParams.append('{{baseName}}', {{paramName}}.data, {{paramName}}.name);
{{/node}}
{{^node}}
localVarFormParams.append('{{baseName}}', {{paramName}}, {{paramName}}.name);
{{/node}}
{{/platforms}}
}
{{/isFile}}
}
{{/isArray}}
{{/formParams}}
{{#hasFormParams}}
requestContext.setBody(localVarFormParams);
if(!useForm) {
const contentType = ObjectSerializer.getPreferredMediaType([{{#consumes}}
"{{{mediaType}}}"{{^-last}},{{/-last}}
{{/consumes}}]);
requestContext.setHeaderParam("Content-Type", contentType);
}
{{/hasFormParams}}
{{#bodyParam}}
// Body Params
const contentType = ObjectSerializer.getPreferredMediaType([{{#consumes}}
"{{{mediaType}}}"{{^-last}},{{/-last}}
{{/consumes}}]);
requestContext.setHeaderParam("Content-Type", contentType);
const serializedBody = ObjectSerializer.stringify(
ObjectSerializer.serialize({{paramName}}, "{{{dataType}}}", "{{dataFormat}}"),
contentType
);
requestContext.setBody(serializedBody);
{{/bodyParam}}
{{#hasAuthMethods}}
let authMethod: SecurityAuthentication | undefined;
{{/hasAuthMethods}}
{{#authMethods}}
// Apply auth methods
authMethod = _config.authMethods["{{name}}"]
if (authMethod?.applySecurityAuthentication) {
await authMethod?.applySecurityAuthentication(requestContext);
}
{{/authMethods}}
{{^useInversify}}
const defaultAuth: SecurityAuthentication | undefined = _options?.authMethods?.default || this.configuration?.authMethods?.default
if (defaultAuth?.applySecurityAuthentication) {
await defaultAuth?.applySecurityAuthentication(requestContext);
}
{{/useInversify}}
return requestContext;
}
{{/operation}}
}
{{/operations}}
{{#operations}}
{{#useInversify}}
@injectable()
{{/useInversify}}
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 {{nickname}}
* @throws ApiException if the response code was not in [200, 299]
*/
public async {{nickname}}(response: ResponseContext): Promise<{{{returnType}}} {{^returnType}}void{{/returnType}}> {
const contentType = ObjectSerializer.normalizeMediaType(response.headers["content-type"]);
{{#responses}}
if (isCodeInRange("{{code}}", response.httpStatusCode)) {
{{#dataType}}
{{#isBinary}}
const body: {{{dataType}}} = await response.getBodyAsFile() as any as {{{returnType}}};
{{/isBinary}}
{{^isBinary}}
const body: {{{dataType}}} = ObjectSerializer.deserialize(
ObjectSerializer.parse(await response.body.text(), contentType),
"{{{dataType}}}", "{{returnFormat}}"
) as {{{dataType}}};
{{/isBinary}}
{{#is2xx}}
return body;
{{/is2xx}}
{{^is2xx}}
throw new ApiException<{{{dataType}}}>(response.httpStatusCode, "{{message}}", body, response.headers);
{{/is2xx}}
{{/dataType}}
{{^dataType}}
{{#is2xx}}
return;
{{/is2xx}}
{{^is2xx}}
throw new ApiException<undefined>(response.httpStatusCode, "{{message}}", undefined, response.headers);
{{/is2xx}}
{{/dataType}}
}
{{/responses}}
// Work around for missing responses in specification, e.g. for petstore.yaml
// if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) {
// {{#returnType}}
// {{#isBinary}}
// const body: {{{returnType}}} = await response.getBodyAsFile() as any as {{{returnType}}};
// {{/isBinary}}
// {{^isBinary}}
// const body: {{{returnType}}} = ObjectSerializer.deserialize(
// ObjectSerializer.parse(await response.body.text(), contentType),
// "{{{returnType}}}", "{{returnFormat}}"
// ) as {{{returnType}}};
// {{/isBinary}}
// return body;
// {{/returnType}}
// {{^returnType}}
// return;
// {{/returnType}}
// }
throw new ApiException<string | {{{fileContentDataType}}} | undefined>(response.httpStatusCode, "Unknown API Status Code!", await response.getBodyAsAny(), response.headers);
}
{{/operation}}
}
{{/operations}}

View File

@@ -0,0 +1,44 @@
import { Configuration } from '../configuration{{extensionForDeno}}'
{{#useInversify}}
import { injectable, inject } from "inversify";
import { AbstractConfiguration } from "../services/configuration";
{{/useInversify}}
/**
*
* @export
*/
export const COLLECTION_FORMATS = {
csv: ",",
ssv: " ",
tsv: "\t",
pipes: "|",
};
/**
*
* @export
* @class BaseAPI
*/
{{#useInversify}}
@injectable()
{{/useInversify}}
export class BaseAPIRequestFactory {
constructor({{#useInversify}}@inject(AbstractConfiguration) {{/useInversify}}protected configuration: Configuration) {
}
};
/**
*
* @export
* @class RequiredError
* @extends {Error}
*/
export class RequiredError extends Error {
name: "RequiredError" = "RequiredError";
constructor(public api: string, public method: string, public field: string) {
super("Required parameter " + field + " was null or undefined when calling " + api + "." + method + ".");
}
}

View File

@@ -0,0 +1,15 @@
/**
* 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, message: string, public body: T, public headers: { [key: string]: string; }) {
super("HTTP-Code: " + code + "\nMessage: " + message + "\nBody: " + JSON.stringify(body) + "\nHeaders: " +
JSON.stringify(headers))
}
}

View File

@@ -0,0 +1,66 @@
import {RequestContext, ResponseContext} from './http/http{{extensionForDeno}}';
import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'./rxjsStub{{extensionForDeno}}'{{/useRxJS}};
/**
* 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>;
}
export class PromiseMiddlewareWrapper implements Middleware {
public constructor(private middleware: PromiseMiddleware) {
}
pre(context: RequestContext): Observable<RequestContext> {
return from(this.middleware.pre(context));
}
post(context: ResponseContext): Observable<ResponseContext> {
return from(this.middleware.post(context));
}
}
/**
* 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): Promise<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): Promise<ResponseContext>;
}

View File

@@ -0,0 +1,84 @@
# {{moduleName}}.{{classname}}{{#description}}
{{description}}{{/description}}
All URIs are relative to *{{basePath}}*
Method | HTTP request | Description
------------- | ------------- | -------------
{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}
{{#operations}}
{{#operation}}
# **{{{operationId}}}**
> {{#returnType}}{{{returnType}}} {{/returnType}}{{{operationId}}}({{#requiredParams}}{{^defaultValue}}{{paramName}}{{^-last}}, {{/-last}}{{/defaultValue}}{{/requiredParams}})
{{#notes}}
{{{notes}}}
{{/notes}}
### Example
```typescript
import { {{{moduleName}}} } from '{{{projectName}}}';
import * as fs from 'fs';
const configuration = {{{moduleName}}}.createConfiguration();
const apiInstance = new {{{moduleName}}}.{{classname}}(configuration);
{{#hasParams}}
let body:{{{moduleName}}}.{{classname}}{{operationIdCamelCase}}Request = {
{{#allParams}}
// {{{dataType}}}{{#description}} | {{{description}}}{{/description}}{{^required}} (optional){{/required}}
{{paramName}}: {{{example}}},
{{/allParams}}
};
{{/hasParams}}
{{^hasParams}}
let body:any = {};
{{/hasParams}}
apiInstance.{{{operationId}}}(body).then((data:any) => {
console.log('API called successfully. Returned data: ' + data);
}).catch((error:any) => console.error(error));
```
### Parameters
{{^hasParams}}This endpoint does not need any parameter.{{/hasParams}}{{#allParams}}{{#-last}}
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}
{{#allParams}}{{^defaultValue}} **{{paramName}}** | {{^isPrimitiveType}}**{{{dataType}}}**{{/isPrimitiveType}}{{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}| {{description}} |
{{/defaultValue}}{{/allParams}}{{#allParams}}{{#defaultValue}} **{{paramName}}** | {{^isPrimitiveType}}{{^isEnum}}**{{dataType}}**{{/isEnum}}{{/isPrimitiveType}}{{#isPrimitiveType}}[**{{dataType}}**]{{/isPrimitiveType}}{{#isEnum}}{{#allowableValues}}{{#enumVars}}{{#-first}}**Array<{{/-first}}{{value}}{{^-last}} &#124; {{/-last}}{{#-last}}>**{{/-last}}{{/enumVars}}{{/allowableValues}}{{/isEnum}} | {{description}} |{{^required}} (optional){{/required}} defaults to {{{.}}}
{{/defaultValue}}{{/allParams}}
### Return type
{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void (empty response body){{/returnType}}
### Authorization
{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}](README.md#{{{name}}}){{^-last}}, {{/-last}}{{/authMethods}}
### HTTP request headers
- **Content-Type**: {{#consumes}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}}
{{#responses.0}}
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
{{#responses}}
**{{code}}** | {{message}} | {{#headers}} * {{baseName}} - {{description}} <br> {{/headers}}{{^headers.0}} - {{/headers.0}} |
{{/responses}}
{{/responses.0}}
[[Back to top]](#) [[Back to API list]](README.md#documentation-for-api-endpoints) [[Back to Model list]](README.md#documentation-for-models) [[Back to README]](README.md)
{{/operation}}
{{/operations}}

View File

@@ -0,0 +1,178 @@
{{#platforms}}
{{#node}}
// typings for btoa are incorrect
//@ts-ignore
import {{^supportsES6}}* as{{/supportsES6}} btoa from "btoa";
{{/node}}
{{/platforms}}
import { RequestContext } from "../http/http{{extensionForDeno}}";
{{#useInversify}}
import { injectable, inject, named } from "inversify";
import { AbstractTokenProvider } from "../services/configuration";
{{/useInversify}}
/**
* Interface authentication schemes.
*/
export interface SecurityAuthentication {
/*
* @return returns the name of the security authentication as specified in OAI
*/
getName(): string;
/**
* Applies the authentication scheme to the request context
*
* @params context the request context which should use this authentication scheme
*/
applySecurityAuthentication(context: RequestContext): void | Promise<void>;
}
{{#useInversify}}
export const AuthApiKey = Symbol("auth.api_key");
export const AuthUsername = Symbol("auth.username");
export const AuthPassword = Symbol("auth.password");
{{/useInversify}}
export interface TokenProvider {
getToken(): Promise<string> | string;
}
{{#authMethods}}
/**
* Applies {{type}} authentication to the request context.
*/
{{#useInversify}}
@injectable()
{{/useInversify}}
export class {{#lambda.pascalcase}}{{name}}{{/lambda.pascalcase}}Authentication implements SecurityAuthentication {
{{#isApiKey}}
/**
* Configures this api key authentication with the necessary properties
*
* @param apiKey: The api key to be used for every request
*/
public constructor({{#useInversify}}@inject(AuthApiKey) @named("{{name}}") {{/useInversify}}private apiKey: string) {}
{{/isApiKey}}
{{#isBasicBasic}}
/**
* Configures the http authentication with the required details.
*
* @param username username for http basic authentication
* @param password password for http basic authentication
*/
public constructor(
{{#useInversify}}@inject(AuthUsername) @named("{{name}}") {{/useInversify}}private username: string,
{{#useInversify}}@inject(AuthPassword) @named("{{name}}") {{/useInversify}}private password: string
) {}
{{/isBasicBasic}}
{{#isBasicBearer}}
/**
* Configures the http authentication with the required details.
*
* @param tokenProvider service that can provide the up-to-date token when needed
*/
public constructor({{#useInversify}}@inject(AbstractTokenProvider) @named("{{name}}") {{/useInversify}}private tokenProvider: TokenProvider) {}
{{/isBasicBearer}}
{{#isOAuth}}
/**
* Configures OAuth2 with the necessary properties
*
* @param accessToken: The access token to be used for every request
*/
public constructor(private accessToken: string) {}
{{/isOAuth}}
public getName(): string {
return "{{name}}";
}
public {{#isBasicBearer}}async {{/isBasicBearer}}applySecurityAuthentication(context: RequestContext) {
{{#isApiKey}}
context.{{#isKeyInHeader}}setHeaderParam{{/isKeyInHeader}}{{#isKeyInQuery}}setQueryParam{{/isKeyInQuery}}{{#isKeyInCookie}}addCookie{{/isKeyInCookie}}("{{keyParamName}}", this.apiKey);
{{/isApiKey}}
{{#isBasicBasic}}
let comb = this.username + ":" + this.password;
context.setHeaderParam("Authorization", "Basic " + btoa(comb));
{{/isBasicBasic}}
{{#isBasicBearer}}
context.setHeaderParam("Authorization", "Bearer " + await this.tokenProvider.getToken());
{{/isBasicBearer}}
{{#isOAuth}}
context.setHeaderParam("Authorization", "Bearer " + this.accessToken);
{{/isOAuth}}
}
}
{{/authMethods}}
export type AuthMethods = {
{{^useInversify}}
"default"?: SecurityAuthentication,
{{/useInversify}}
{{#authMethods}}
"{{name}}"?: SecurityAuthentication{{^-last}},{{/-last}}
{{/authMethods}}
}
{{#useInversify}}
export const authMethodServices = {
{{^useInversify}}
"default"?: SecurityAuthentication,
{{/useInversify}}
{{#authMethods}}
"{{name}}": {{#lambda.pascalcase}}{{name}}{{/lambda.pascalcase}}Authentication{{^-last}},{{/-last}}
{{/authMethods}}
}
{{/useInversify}}
export type ApiKeyConfiguration = string;
export type HttpBasicConfiguration = { "username": string, "password": string };
export type HttpBearerConfiguration = { tokenProvider: TokenProvider };
export type OAuth2Configuration = { accessToken: string };
export type AuthMethodsConfiguration = {
{{^useInversify}}
"default"?: SecurityAuthentication,
{{/useInversify}}
{{#authMethods}}
"{{name}}"?: {{#isApiKey}}ApiKeyConfiguration{{/isApiKey}}{{#isBasicBasic}}HttpBasicConfiguration{{/isBasicBasic}}{{#isBasicBearer}}HttpBearerConfiguration{{/isBasicBearer}}{{#isOAuth}}OAuth2Configuration{{/isOAuth}}{{^-last}},{{/-last}}
{{/authMethods}}
}
/**
* Creates the authentication methods from a swagger description.
*
*/
export function configureAuthMethods(config: AuthMethodsConfiguration | undefined): AuthMethods {
let authMethods: AuthMethods = {}
if (!config) {
return authMethods;
}
{{^useInversify}}
authMethods["default"] = config["default"]
{{/useInversify}}
{{#authMethods}}
if (config["{{name}}"]) {
authMethods["{{name}}"] = new {{#lambda.pascalcase}}{{name}}{{/lambda.pascalcase}}Authentication(
{{#isApiKey}}
config["{{name}}"]
{{/isApiKey}}
{{#isBasicBasic}}
config["{{name}}"]["username"],
config["{{name}}"]["password"]
{{/isBasicBasic}}
{{#isBasicBearer}}
config["{{name}}"]["tokenProvider"]
{{/isBasicBearer}}
{{#isOAuth}}
config["{{name}}"]["accessToken"]
{{/isOAuth}}
);
}
{{/authMethods}}
return authMethods;
}

View File

@@ -0,0 +1,73 @@
import { HttpLibrary } from "./http/http{{extensionForDeno}}";
import { Middleware, PromiseMiddleware, PromiseMiddlewareWrapper } from "./middleware{{extensionForDeno}}";
{{#frameworks}}
{{#fetch-api}}
import { IsomorphicFetchHttpLibrary as DefaultHttpLibrary } from "./http/isomorphic-fetch{{extensionForDeno}}";
{{/fetch-api}}
{{#jquery}}
import { JQueryHttpLibrary as DefaultHttpLibrary } from "./http/jquery";
{{/jquery}}
{{/frameworks}}
import { BaseServerConfiguration, server1 } from "./servers{{extensionForDeno}}";
import { configureAuthMethods, AuthMethods, AuthMethodsConfiguration } from "./auth/auth{{extensionForDeno}}";
export interface Configuration {
readonly baseServer: BaseServerConfiguration;
readonly httpApi: HttpLibrary;
readonly middleware: Middleware[];
readonly authMethods: AuthMethods;
}
/**
* Interface with which a configuration object can be configured.
*/
export interface ConfigurationParameters {
/**
* Default server to use
*/
baseServer?: BaseServerConfiguration;
/**
* HTTP library to use e.g. IsomorphicFetch
*/
httpApi?: HttpLibrary;
/**
* The middlewares which will be applied to requests and responses
*/
middleware?: Middleware[];
/**
* Configures all middlewares using the promise api instead of observables (which Middleware uses)
*/
promiseMiddleware?: PromiseMiddleware[];
/**
* Configuration for the available authentication methods
*/
authMethods?: AuthMethodsConfiguration
}
/**
* Configuration factory function
*
* If a property is not included in conf, a default is used:
* - baseServer: server1
* - httpApi: IsomorphicFetchHttpLibrary
* - middleware: []
* - promiseMiddleware: []
* - authMethods: {}
*
* @param conf partial configuration
*/
export function createConfiguration(conf: ConfigurationParameters = {}): Configuration {
const configuration: Configuration = {
baseServer: conf.baseServer !== undefined ? conf.baseServer : server1,
httpApi: conf.httpApi || new DefaultHttpLibrary(),
middleware: conf.middleware || [],
authMethods: configureAuthMethods(conf.authMethods)
};
if (conf.promiseMiddleware) {
conf.promiseMiddleware.forEach(
m => configuration.middleware.push(new PromiseMiddlewareWrapper(m))
);
}
return configuration;
}

View File

@@ -0,0 +1,51 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update"
git_user_id=$1
git_repo_id=$2
release_note=$3
if [ "$git_user_id" = "" ]; then
git_user_id="{{{gitUserId}}}"
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
fi
if [ "$git_repo_id" = "" ]; then
git_repo_id="{{{gitRepoId}}}"
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
fi
if [ "$release_note" = "" ]; then
release_note="{{{releaseNote}}}"
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
fi
# Initialize the local directory as a Git repository
git init
# Adds the files in the local repository and stages them for commit.
git add .
# Commits the tracked changes and prepares them to be pushed to a remote repository.
git commit -m "$release_note"
# Sets the new remote
git_remote=$(git remote)
if [ "$git_remote" = "" ]; then # git remote not defined
if [ "$GIT_TOKEN" = "" ]; then
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
else
git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@github.com/${git_user_id}/${git_repo_id}.git
fi
fi
git pull origin master
# Pushes (Forces) the changes in the local repository up to the remote repository
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
git push origin master 2>&1 | grep -v 'To https'

View File

@@ -0,0 +1,339 @@
{{#platforms}}
{{#node}}
// TODO: evaluate if we can easily get rid of this library
import {{^supportsES6}}* as{{/supportsES6}} FormData from "form-data";
import { URLSearchParams } from 'url';
import * as http from 'http';
import * as https from 'https';
{{/node}}
{{/platforms}}
{{#platforms}}
{{^deno}}
import {{^supportsES6}}* as{{/supportsES6}} URLParse from "url-parse";
{{/deno}}
{{/platforms}}
import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{extensionForDeno}}'{{/useRxJS}};
{{#platforms}}
{{^deno}}
{{#frameworks}}
{{#fetch-api}}
export * from './isomorphic-fetch';
{{/fetch-api}}
{{#jquery}}
export * from './jquery';
{{/jquery}}
{{/frameworks}}
{{/deno}}
{{/platforms}}
/**
* Represents an HTTP method.
*/
export enum HttpMethod {
GET = "GET",
HEAD = "HEAD",
POST = "POST",
PUT = "PUT",
DELETE = "DELETE",
CONNECT = "CONNECT",
OPTIONS = "OPTIONS",
TRACE = "TRACE",
PATCH = "PATCH"
}
/**
* Represents an HTTP file which will be transferred from or to a server.
*/
{{#platforms}}
{{#node}}
export type HttpFile = {
data: {{{fileContentDataType}}},
name: string
};
{{/node}}
{{^node}}
export type HttpFile = {{{fileContentDataType}}} & { readonly name: string };
{{/node}}
{{/platforms}}
{{#platforms}}
{{#deno}}
/**
* URLParse Wrapper for Deno
*/
class URLParse {
private url: URL;
constructor(address: string, _parser: boolean) {
this.url = new URL(address);
}
public set(_part: 'query', obj: {[key: string]: string | undefined}) {
for (const key in obj) {
const value = obj[key];
if (value) {
this.url.searchParams.set(key, value);
} else {
this.url.searchParams.set(key, "");
}
}
}
public get query() {
const obj: {[key: string]: string} = {};
for (const [key, value] of this.url.searchParams.entries()) {
obj[key] = value;
}
return obj;
}
public toString() {
return this.url.toString();
}
}
{{/deno}}
{{/platforms}}
export class HttpException extends Error {
public constructor(msg: string) {
super(msg);
}
}
/**
* Represents the body of an outgoing HTTP request.
*/
export type RequestBody = undefined | string | FormData | URLSearchParams;
/**
* Represents an HTTP request context
*/
export class RequestContext {
private headers: { [key: string]: string } = {};
private body: RequestBody = undefined;
private url: URLParse;
{{#platforms}}
{{#node}}
private agent: http.Agent | https.Agent | undefined = undefined;
{{/node}}
{{/platforms}}
/**
* 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 = new 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 = new URLParse(url, true);
}
/**
* Sets the body of the http request either as a string or FormData
*
* Note that setting a body on a HTTP GET, HEAD, DELETE, CONNECT or TRACE
* request is discouraged.
* https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html#rfc.section.7.3.1
*
* @param body the body of the request
*/
public setBody(body: RequestBody) {
this.body = body;
}
public getHttpMethod(): HttpMethod {
return this.httpMethod;
}
public getHeaders(): { [key: string]: string } {
return this.headers;
}
public getBody(): RequestBody {
return this.body;
}
public setQueryParam(name: string, value: string) {
let queryObj = this.url.query;
queryObj[name] = value;
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"] = "";
}
this.headers["Cookie"] += name + "=" + value + "; ";
}
public setHeaderParam(key: string, value: string): void {
this.headers[key] = value;
}
{{#platforms}}
{{#node}}
public setAgent(agent: http.Agent | https.Agent) {
this.agent = agent;
}
public getAgent(): http.Agent | https.Agent | undefined {
return this.agent;
}
{{/node}}
{{/platforms}}
}
export interface ResponseBody {
text(): Promise<string>;
binary(): Promise<{{{fileContentDataType}}}>;
}
/**
* Helper class to generate a `ResponseBody` from binary data
*/
export class SelfDecodingBody implements ResponseBody {
constructor(private dataSource: Promise<{{{fileContentDataType}}}>) {}
binary(): Promise<{{{fileContentDataType}}}> {
return this.dataSource;
}
async text(): Promise<string> {
const data: {{{fileContentDataType}}} = await this.dataSource;
{{#platforms}}
{{#node}}
return data.toString();
{{/node}}
{{#browser}}
// @ts-ignore
if (data.text) {
// @ts-ignore
return data.text();
}
return new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener("load", () => resolve(reader.result as string));
reader.addEventListener("error", () => reject(reader.error));
reader.readAsText(data);
});
{{/browser}}
{{#deno}}
return data.text();
{{/deno}}
{{/platforms}}
}
}
export class ResponseContext {
public constructor(
public httpStatusCode: number,
public headers: { [key: string]: string },
public body: ResponseBody
) {}
/**
* Parse header value in the form `value; param1="value1"`
*
* E.g. for Content-Type or Content-Disposition
* Parameter names are converted to lower case
* The first parameter is returned with the key `""`
*/
public getParsedHeader(headerName: string): { [parameter: string]: string } {
const result: { [parameter: string]: string } = {};
if (!this.headers[headerName]) {
return result;
}
const parameters = this.headers[headerName].split(";");
for (const parameter of parameters) {
let [key, value] = parameter.split("=", 2);
key = key.toLowerCase().trim();
if (value === undefined) {
result[""] = key;
} else {
value = value.trim();
if (value.startsWith('"') && value.endsWith('"')) {
value = value.substring(1, value.length - 1);
}
result[key] = value;
}
}
return result;
}
public async getBodyAsFile(): Promise<HttpFile> {
const data = await this.body.binary();
const fileName = this.getParsedHeader("content-disposition")["filename"] || "";
{{#platforms}}
{{#node}}
return { data, name: fileName };
{{/node}}
{{^node}}
const contentType = this.headers["content-type"] || "";
try {
return new File([data], fileName, { type: contentType });
} catch (error) {
/** Fallback for when the File constructor is not available */
return Object.assign(data, {
name: fileName,
type: contentType
});
}
{{/node}}
{{/platforms}}
}
/**
* Use a heuristic to get a body of unknown data structure.
* Return as string if possible, otherwise as binary.
*/
public getBodyAsAny(): Promise<string | {{{fileContentDataType}}} | undefined> {
try {
return this.body.text();
} catch {}
try {
return this.body.binary();
} catch {}
return Promise.resolve(undefined);
}
}
export interface HttpLibrary {
send(request: RequestContext): Observable<ResponseContext>;
}
export interface PromiseHttpLibrary {
send(request: RequestContext): Promise<ResponseContext>;
}
export function wrapHttpLibrary(promiseHttpLibrary: PromiseHttpLibrary): HttpLibrary {
return {
send(request: RequestContext): Observable<ResponseContext> {
return from(promiseHttpLibrary.send(request));
}
}
}

View File

@@ -0,0 +1,56 @@
import {HttpLibrary, RequestContext, ResponseContext} from './http{{extensionForDeno}}';
import { from, Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{extensionForDeno}}'{{/useRxJS}};
{{#platforms}}
{{#node}}
import fetch from "node-fetch";
{{/node}}
{{#browser}}
import "whatwg-fetch";
{{/browser}}
{{/platforms}}
export class IsomorphicFetchHttpLibrary implements HttpLibrary {
public send(request: RequestContext): Observable<ResponseContext> {
let method = request.getHttpMethod().toString();
let body = request.getBody();
const resultPromise = fetch(request.getUrl(), {
method: method,
body: body as any,
headers: request.getHeaders(),
{{#platforms}}
{{#node}}
agent: request.getAgent(),
{{/node}}
{{#browser}}
credentials: "same-origin"
{{/browser}}
{{/platforms}}
}).then((resp: any) => {
const headers: { [name: string]: string } = {};
resp.headers.forEach((value: string, name: string) => {
headers[name] = value;
});
{{#platforms}}
{{#node}}
const body = {
text: () => resp.text(),
binary: () => resp.buffer()
};
{{/node}}
{{^node}}
const body = {
text: () => resp.text(),
binary: () => resp.blob()
};
{{/node}}
{{/platforms}}
return new ResponseContext(resp.status, headers, body);
});
return from<Promise<ResponseContext>>(resultPromise);
}
}

View File

@@ -0,0 +1,86 @@
import { HttpLibrary, RequestContext, ResponseContext, HttpException, SelfDecodingBody } from './http';
import * as e6p from 'es6-promise'
import { from, Observable } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub'{{/useRxJS}};
e6p.polyfill();
import * as $ from 'jquery';
export class JQueryHttpLibrary implements HttpLibrary {
public send(request: RequestContext): Observable<ResponseContext> {
let method = request.getHttpMethod().toString();
let body = request.getBody();
let headerParams = request.getHeaders()
let requestOptions: any = {
url: request.getUrl(),
type: method,
headers: request.getHeaders(),
processData: false,
xhrFields: { withCredentials: true },
data: body
};
// If we want a blob, we have to set the xhrFields' responseType AND add a
// custom converter to overwrite the default deserialization of JQuery...
requestOptions["xhrFields"] = { responseType: 'blob' };
requestOptions["converters"] = {}
requestOptions["converters"]["* blob"] = (result:any) => result;
requestOptions["dataType"] = "blob";
if (request.getHeaders()['Content-Type']) {
requestOptions.contentType = headerParams['Content-Type'];
}
requestOptions.dataFilter = ((headerParams: { [key:string]: string}) => {
return (data: string, type: string) => {
if (headerParams["Accept"] == "application/json" && data == "") {
return "{}"
} else {
return data
}
}
})(headerParams);
if (request.getHeaders()["Cookie"]) {
throw new HttpException("Setting the \"Cookie\"-Header field is blocked by every major browser when using jquery.ajax requests. Please switch to another library like fetch to enable this option");
}
if (body && body.constructor.name == "FormData") {
requestOptions.contentType = false;
}
const sentRequest = $.ajax(requestOptions);
const resultPromise = new Promise<ResponseContext>((resolve, reject) => {
sentRequest.done((data, _, jqXHR) => {
const result = new ResponseContext(
jqXHR.status,
this.getResponseHeaders(jqXHR),
new SelfDecodingBody(Promise.resolve(data))
);
resolve(result);
})
sentRequest.fail((jqXHR: any) => {
const headers = this.getResponseHeaders(jqXHR)
const result = new ResponseContext(jqXHR.status, headers, jqXHR.responseText);
resolve(result);
})
})
return from(resultPromise);
}
private getResponseHeaders(jqXHR: any): { [key: string]: string } {
const responseHeaders: { [key: string]: string } = {};
var headers = jqXHR.getAllResponseHeaders();
headers = headers.split("\n");
headers.forEach(function (header: any) {
header = header.split(": ");
var key = header.shift();
if (key.length == 0) return
// chrome60+ force lowercase, other browsers can be different
key = key.toLowerCase();
responseHeaders[key] = header.join(": ");
});
return responseHeaders
}
}

View File

@@ -0,0 +1,55 @@
import { RequestContext, HttpMethod } from "./http/http{{extensionForDeno}}";
export interface BaseServerConfiguration {
makeRequestContext(endpoint: string, httpMethod: HttpMethod): RequestContext;
}
/**
*
* Represents the configuration of a server including its
* url template and variable configuration based on the url.
*
*/
export class ServerConfiguration<T extends { [key: string]: string }> implements BaseServerConfiguration {
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>) {
Object.assign(this.variableConfiguration, variableConfiguration);
}
public getConfiguration(): T {
return this.variableConfiguration
}
private getUrl() {
let replacedUrl = this.url;
for (const key in this.variableConfiguration) {
var re = new RegExp("{" + key + "}","g");
replacedUrl = replacedUrl.replace(re, this.variableConfiguration[key]);
}
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);
}
}
{{#servers}}
export const server{{-index}} = new ServerConfiguration<{ {{#variables}} "{{name}}": {{#enumValues}}"{{.}}"{{^-last}} | {{/-last}}{{/enumValues}}{{^enumValues}}string{{/enumValues}}{{^-last}},{{/-last}} {{/variables}} }>("{{url}}", { {{#variables}} "{{name}}": "{{defaultValue}}" {{^-last}},{{/-last}}{{/variables}} })
{{/servers}}
export const servers = [{{#servers}}server{{-index}}{{^-last}}, {{/-last}}{{/servers}}];

41
templates/index.mustache Normal file
View File

@@ -0,0 +1,41 @@
export * from "./http/http{{extensionForDeno}}";
export * from "./auth/auth{{extensionForDeno}}";
export * from "./models/all{{extensionForDeno}}";
export { createConfiguration } from "./configuration{{extensionForDeno}}"
export{{#platforms}}{{#deno}} type{{/deno}}{{/platforms}} { Configuration } from "./configuration{{extensionForDeno}}"
export * from "./apis/exception{{extensionForDeno}}";
export * from "./servers{{extensionForDeno}}";
export { RequiredError } from "./apis/baseapi{{extensionForDeno}}";
{{#useRxJS}}
export { Middleware } from './middleware{{extensionForDeno}}';
{{/useRxJS}}
{{^useRxJS}}
export{{#platforms}}{{#deno}} type{{/deno}}{{/platforms}} { PromiseMiddleware as Middleware } from './middleware{{extensionForDeno}}';
{{/useRxJS}}
{{#useObjectParameters}}
export { {{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}{{classname}}{{operationIdCamelCase}}Request, {{/operation}}Object{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/ObjectParamAPI{{extensionForDeno}}';
{{/useObjectParameters}}
{{^useObjectParameters}}
{{#useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}Observable{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/ObservableAPI{{extensionForDeno}}';
{{/useRxJS}}
{{^useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}Promise{{classname}} as {{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './types/PromiseAPI{{extensionForDeno}}';
{{/useRxJS}}
{{/useObjectParameters}}
{{#useInversify}}
export * from "./services/index{{extensionForDeno}}";
{{#useObjectParameters}}
export { {{#apiInfo}}{{#apis}}{{#operations}}AbstractObject{{classname}} as Abstract{{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './services/ObjectParamAPI';
{{/useObjectParameters}}
{{^useObjectParameters}}
{{#useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}AbstractObservable{{classname}} as Abstract{{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './services/ObservableAPI{{extensionForDeno}}';
{{/useRxJS}}
{{^useRxJS}}
export { {{#apiInfo}}{{#apis}}{{#operations}}AbstractPromise{{classname}} as Abstract{{classname}}{{^-last}}, {{/-last}} {{/operations}}{{/apis}}{{/apiInfo}}} from './services/PromiseAPI{{extensionForDeno}}';
{{/useRxJS}}
{{/useObjectParameters}}
{{/useInversify}}

View File

@@ -0,0 +1,11 @@
/**
* {{{appName}}}
* {{{appDescription}}}
*
* {{#version}}OpenAPI spec version: {{{.}}}{{/version}}
* {{#infoEmail}}Contact: {{{.}}}{{/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

@@ -0,0 +1,261 @@
{{#models}}
{{#model}}
export * from '{{{ importPath }}}{{extensionForDeno}}';
{{/model}}
{{/models}}
{{#models}}
{{#model}}
import { {{classname}}{{#hasEnums}}{{#vars}}{{#isEnum}}, {{classname}}{{enumName}} {{/isEnum}} {{/vars}}{{/hasEnums}} } from '{{{ importPath }}}{{extensionForDeno}}';
{{/model}}
{{/models}}
/* tslint:disable:no-unused-variable */
let primitives = [
"string",
"boolean",
"double",
"integer",
"long",
"float",
"number",
"any"
];
const supportedMediaTypes: { [mediaType: string]: number } = {
"application/json": Infinity,
"application/octet-stream": 0,
"application/x-www-form-urlencoded": 0
}
let enumsMap: Set<string> = new Set<string>([
{{#models}}
{{#model}}
{{#isEnum}}
"{{classname}}{{enumName}}",
{{/isEnum}}
{{#hasEnums}}
{{#vars}}
{{#isEnum}}
"{{classname}}{{enumName}}",
{{/isEnum}}
{{/vars}}
{{/hasEnums}}
{{/model}}
{{/models}}
]);
let typeMap: {[index: string]: any} = {
{{#models}}
{{#model}}
{{^isEnum}}
"{{classname}}": {{classname}},
{{/isEnum}}
{{/model}}
{{/models}}
}
export class ObjectSerializer {
public static findCorrectType(data: any, expectedType: string) {
if (data == undefined) {
return expectedType;
} else if (primitives.indexOf(expectedType.toLowerCase()) !== -1) {
return expectedType;
} else if (expectedType === "Date") {
return expectedType;
} else {
if (enumsMap.has(expectedType)) {
return expectedType;
}
if (!typeMap[expectedType]) {
return expectedType; // w/e we don't know the type
}
// Check the discriminator
let discriminatorProperty = typeMap[expectedType].discriminator;
if (discriminatorProperty == null) {
return expectedType; // the type does not have a discriminator. use it.
} else {
if (data[discriminatorProperty]) {
var discriminatorType = data[discriminatorProperty];
if(typeMap[discriminatorType]){
return discriminatorType; // use the type given in the discriminator
} else {
return expectedType; // discriminator did not map to a type
}
} else {
return expectedType; // discriminator was not present (or an empty string)
}
}
}
}
public static serialize(data: any, type: string, format: string) {
if (data == undefined) {
return data;
} else if (primitives.indexOf(type.toLowerCase()) !== -1) {
return data;
} else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6
let subType: string = type.replace("Array<", ""); // Array<Type> => Type>
subType = subType.substring(0, subType.length - 1); // Type> => Type
let transformedData: any[] = [];
for (let index in data) {
let date = data[index];
transformedData.push(ObjectSerializer.serialize(date, subType, format));
}
return transformedData;
} else if (type === "Date") {
if (format == "date") {
let month = data.getMonth()+1
month = month < 10 ? "0" + month.toString() : month.toString()
let day = data.getDate();
day = day < 10 ? "0" + day.toString() : day.toString();
return data.getFullYear() + "-" + month + "-" + day;
} else {
return data.toISOString();
}
} else {
if (enumsMap.has(type)) {
return data;
}
if (!typeMap[type]) { // in case we dont know the type
return data;
}
// Get the actual type of this object
type = this.findCorrectType(data, type);
// get the map for the correct type.
let attributeTypes = typeMap[type].getAttributeTypeMap();
let instance: {[index: string]: any} = {};
for (let index in attributeTypes) {
let attributeType = attributeTypes[index];
instance[attributeType.baseName] = ObjectSerializer.serialize(data[attributeType.name], attributeType.type, attributeType.format);
}
return instance;
}
}
public static deserialize(data: any, type: string, format: string) {
// polymorphism may change the actual type.
type = ObjectSerializer.findCorrectType(data, type);
if (data == undefined) {
return data;
} else if (primitives.indexOf(type.toLowerCase()) !== -1) {
return data;
} else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6
let subType: string = type.replace("Array<", ""); // Array<Type> => Type>
subType = subType.substring(0, subType.length - 1); // Type> => Type
let transformedData: any[] = [];
for (let index in data) {
let date = data[index];
transformedData.push(ObjectSerializer.deserialize(date, subType, format));
}
return transformedData;
} else if (type === "Date") {
return new Date(data);
} else {
if (enumsMap.has(type)) {// is Enum
return data;
}
if (!typeMap[type]) { // dont know the type
return data;
}
let instance = new typeMap[type]();
let attributeTypes = typeMap[type].getAttributeTypeMap();
for (let index in attributeTypes) {
let attributeType = attributeTypes[index];
let value = ObjectSerializer.deserialize(data[attributeType.baseName], attributeType.type, attributeType.format);
if (value !== undefined) {
instance[attributeType.name] = value;
}
}
return instance;
}
}
/**
* Normalize media type
*
* We currently do not handle any media types attributes, i.e. anything
* after a semicolon. All content is assumed to be UTF-8 compatible.
*/
public static normalizeMediaType(mediaType: string | undefined): string | undefined {
if (mediaType === undefined) {
return undefined;
}
return mediaType.split(";")[0].trim().toLowerCase();
}
/**
* From a list of possible media types, choose the one we can handle best.
*
* The order of the given media types does not have any impact on the choice
* made.
*/
public static getPreferredMediaType(mediaTypes: Array<string>): string {
/** According to OAS 3 we should default to json */
if (!mediaTypes) {
return "application/json";
}
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
let selectedMediaType: string | undefined = undefined;
let selectedRank: number = -Infinity;
for (const mediaType of normalMediaTypes) {
if (supportedMediaTypes[mediaType!] > selectedRank) {
selectedMediaType = mediaType;
selectedRank = supportedMediaTypes[mediaType!];
}
}
if (selectedMediaType === undefined) {
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
}
return selectedMediaType!;
}
/**
* Convert data to a string according the given media type
*/
public static stringify(data: any, mediaType: string): string {
if (mediaType === "text/plain") {
return String(data);
}
if (mediaType === "application/json") {
return JSON.stringify(data);
}
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.stringify.");
}
/**
* Parse data from a string according to the given media type
*/
public static parse(rawData: string, mediaType: string | undefined) {
if (mediaType === undefined) {
throw new Error("Cannot parse content. No Content-Type defined.");
}
if (mediaType === "text/plain") {
return rawData;
}
if (mediaType === "application/json") {
return JSON.parse(rawData);
}
if (mediaType === "text/html") {
return rawData;
}
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
}
}

View File

@@ -0,0 +1,126 @@
{{>licenseInfo}}
{{#models}}
{{#model}}
{{#tsImports}}
import { {{classname}} } from '{{filename}}{{extensionForDeno}}';
{{/tsImports}}
import { HttpFile } from '../http/http{{extensionForDeno}}';
{{#description}}
/**
* {{{.}}}
*/
{{/description}}
{{^isEnum}}
export interface I{{classname}} {{#parent}}extends I{{{.}}} {{/parent}}{
{{#vars}}
{{#description}}
/**
* {{{.}}}
*/
{{/description}}
'{{name}}'?: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}};
{{/vars}}
}
export class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}implements I{{classname}} {
{{#vars}}
{{#description}}
/**
* {{{.}}}
*/
{{/description}}
'{{name}}'{{#required}}!{{/required}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}};
{{/vars}}
{{#discriminator}}
static readonly discriminator: string | undefined = "{{discriminatorName}}";
{{/discriminator}}
{{^discriminator}}
static readonly discriminator: string | undefined = undefined;
{{/discriminator}}
{{^isArray}}
static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string, required?: boolean, minLength?: number, maxLength?: number, min?: number, max?: number, pattern?: RegExp}> = [
{{#vars}}
{
"name": "{{name}}",
"baseName": "{{baseName}}",
"type": "{{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}",
"format": "{{dataFormat}}"
{{#required}},"required": {{required}}{{/required}}
{{#minLength}},"minLength": {{minLength}}{{/minLength}}
{{#maxLength}},"maxLength": {{maxLength}}{{/maxLength}}
{{#min}},"min": {{min}}{{/min}}
{{#max}},"max": {{max}}{{/max}}
{{#pattern}},"pattern": {{pattern}}{{/pattern}}
}{{^-last}},
{{/-last}}
{{/vars}}
];
static getAttributeTypeMap() {
{{#parent}}
return super.getAttributeTypeMap().concat({{classname}}.attributeTypeMap);
{{/parent}}
{{^parent}}
return {{classname}}.attributeTypeMap;
{{/parent}}
}
{{/isArray}}
public constructor(json?: I{{classname}} | any) {
{{#parent}}
super();
{{/parent}}
{{#allVars}}
{{#discriminatorValue}}
this.{{name}} = "{{discriminatorValue}}";
{{/discriminatorValue}}
{{/allVars}}
{{#discriminatorName}}
this.{{discriminatorName}} = "{{classname}}";
{{/discriminatorName}}
this.init(json);
}
{{^isArray}}
static fromJson(json?: I{{classname}} | any): {{classname}} {
return new {{classname}}().init(json);
}
init(json?: I{{classname}} | any): this {
{{#parent}}
super.init(json);
{{/parent}}
{{#vars}}
this['{{name}}'] = {{#isDateTime}}(json && (['number', 'string'].includes(typeof json['{{name}}']) || json['{{name}}'] instanceof Date)) ? new Date(json['{{name}}'] as any){{/isDateTime}}{{^isDateTime}}json ? {{#isModel}}{{dataType}}.fromJson(json['{{name}}']){{/isModel}}{{^isModel}}json['{{name}}']{{/isModel}}{{/isDateTime}} : {{defaultValue}} as any;
{{/vars}}
return this;
}
toJson(): any {
const ret: any = {};
{{#vars}}
ret['{{name}}'] = {{#isDateTime}}this.{{name}} instanceof Date ? this.{{name}}.toISOString() : this.{{name}}{{/isDateTime}}{{^isDateTime}}this['{{name}}']{{#isModel}}?.toJson(){{/isModel}}{{/isDateTime}};
{{/vars}}
return ret;
}
{{/isArray}}
}
{{#hasEnums}}
{{#vars}}
{{#isEnum}}
export type {{classname}}{{enumName}} ={{#allowableValues}}{{#values}} "{{.}}" {{^-last}}|{{/-last}}{{/values}}{{/allowableValues}};
{{/isEnum}}
{{/vars}}
{{/hasEnums}}
{{/isEnum}}
{{#isEnum}}
export type {{classname}} ={{#allowableValues}}{{#values}} "{{.}}" {{^-last}}|{{/-last}}{{/values}}{{/allowableValues}};
{{/isEnum}}
{{/model}}
{{/models}}

View File

@@ -0,0 +1,5 @@
{{#models}}
{{#model}}
export * from '{{{ importPath }}}{{extensionForDeno}}'
{{/model}}
{{/models}}

View File

@@ -0,0 +1,76 @@
{
"name": "{{npmName}}",
"version": "{{npmVersion}}",
"description": "OpenAPI client for {{npmName}}",
"author": "OpenAPI-Generator Contributors",
"repository": {
"type": "git",
"url": "https://{{gitHost}}/{{gitUserId}}/{{gitRepoId}}.git"
},
"keywords": [
"fetch",
"typescript",
"openapi-client",
"openapi-generator"
],
"license": "Unlicense",
"main": "./dist/index.js",
{{#supportsES6}}
"type": "module",
"module": "./dist/index.js",
{{/supportsES6}}
{{^supportsES6}}
"type": "commonjs",
{{/supportsES6}}
"exports": {
".": "./dist/index.js"
},
"typings": "./dist/index.d.ts",
"scripts": {
"build": "tsc",
"prepare": "npm run build"
},
"dependencies": {
{{#frameworks}}
{{#fetch-api}}
{{#platforms}}
{{#node}}
"node-fetch": "^2.6.0",
"@types/node-fetch": "^2.5.7",
{{/node}}
{{#browser}}
"whatwg-fetch": "^3.0.0",
{{/browser}}
{{/platforms}}
{{/fetch-api}}
{{#jquery}}
"@types/jquery": "^3.3.29",
"jquery": "^3.4.1",
{{/jquery}}
{{/frameworks}}
{{#platforms}}
{{#node}}
"@types/node": "*",
"form-data": "^2.5.0",
"btoa": "^1.2.1",
{{/node}}
{{/platforms}}
{{#useRxJS}}
"rxjs": "^6.4.0",
{{/useRxJS}}
{{#useInversify}}
"inversify": "^5.0.1",
{{/useInversify}}
"es6-promise": "^4.2.4",
"url-parse": "^1.4.3"
},
"devDependencies": {
"typescript": "^4.0",
"@types/url-parse": "1.4.4"
}{{#npmRepository}},{{/npmRepository}}
{{#npmRepository}}
"publishConfig":{
"registry":"{{npmRepository}}"
}
{{/npmRepository}}
}

View File

@@ -0,0 +1,27 @@
export class Observable<T> {
constructor(private promise: Promise<T>) {}
toPromise() {
return this.promise;
}
pipe<S>(callback: (value: T) => S | Promise<S>): Observable<S> {
return new Observable(this.promise.then(callback));
}
}
export function from<T>(promise: Promise<any>) {
return new Observable(promise);
}
export function of<T>(value: T) {
return new Observable<T>(Promise.resolve(value));
}
export function mergeMap<T, S>(callback: (value: T) => Observable<S>) {
return (value: T) => callback(value).toPromise();
}
export function map(callback: any) {
return callback;
}

View File

@@ -0,0 +1,35 @@
import type { HttpFile } from '../http/http';
import type { Configuration } from '../configuration'
import type * as req from "../types/ObjectParamAPI";
{{#useRxJS}}
import type { Observable } from 'rxjs';
{{/useRxJS}}
{{#models}}
{{#model}}
import type { {{{ classname }}} } from '{{{ importPath }}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
export abstract class AbstractObject{{classname}} {
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
* @param param the request object
*/
public abstract {{nickname}}(param: req.{{classname}}{{operationIdCamelCase}}Request, options?: Configuration): {{#useRxJS}}Observable{{/useRxJS}}{{^useRxJS}}Promise{{/useRxJS}}<{{{returnType}}}{{^returnType}}void{{/returnType}}>;
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -0,0 +1,23 @@
import type { HttpFile } from "../http/http";
import type { Observable } from {{#useRxJS}}"rxjs"{{/useRxJS}}{{^useRxJS}}"../rxjsStub"{{/useRxJS}};
import type { Configuration } from "../configuration";
{{#models}}
{{#model}}
import { {{{ classname }}} } from "{{{ importPath }}}";
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
export abstract class AbstractObservable{{classname}} {
{{#operation}}
public abstract {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): Observable<{{{returnType}}}{{^returnType}}void{{/returnType}}>;
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -0,0 +1,22 @@
import type { HttpFile } from "../http/http";
import type { Configuration } from "../configuration";
{{#models}}
{{#model}}
import { {{{ classname }}} } from "{{{ importPath }}}";
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
export abstract class AbstractPromise{{classname}} {
{{#operation}}
public abstract {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): Promise<{{{returnType}}}{{^returnType}}void{{/returnType}}>;
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -0,0 +1,23 @@
import type { Configuration } from "../configuration";
import type { HttpFile, RequestContext, ResponseContext } from "../http/http";
{{#imports}}
import { {{classname}} } from "{{filename}}";
{{/imports}}
{{#operations}}
export abstract class Abstract{{classname}}RequestFactory {
{{#operation}}
public abstract {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): Promise<RequestContext>;
{{/operation}}
}
export abstract class Abstract{{classname}}ResponseProcessor {
{{#operation}}
public abstract {{nickname}}(response: ResponseContext): Promise<{{{returnType}}} {{^returnType}}void{{/returnType}}>;
{{/operation}}
}
{{/operations}}

View File

@@ -0,0 +1,21 @@
import type { AbstractServerConfiguration } from "./http";
import type { HttpLibrary, RequestContext } from "../http/http";
import type { Middleware } from "../middleware";
import type { AuthMethods, TokenProvider } from "../auth/auth";
import type { Configuration } from "../configuration";
export abstract class AbstractConfiguration implements Configuration {
abstract get baseServer(): AbstractServerConfiguration;
abstract get httpApi(): HttpLibrary;
abstract get middleware(): Middleware[];
abstract get authMethods(): AuthMethods;
}
export abstract class AbstractAuthMethod {
public abstract getName(): string;
public abstract applySecurityAuthentication(context: RequestContext): void | Promise<void>;
};
export abstract class AbstractTokenProvider implements TokenProvider {
public abstract getToken(): string | Promise<string>;
}

View File

@@ -0,0 +1,19 @@
{{#useRxJS}}
import type { Observable } from "rxjs";
{{/useRxJS}}
import type { {{^useRxJS}}Promise{{/useRxJS}}HttpLibrary, HttpMethod, RequestContext, ResponseContext } from "../http/http";
import type { {{^useRxJS}}Promise{{/useRxJS}}Middleware } from "../middleware";
import type { BaseServerConfiguration } from "../servers";
export abstract class AbstractHttpLibrary implements {{^useRxJS}}Promise{{/useRxJS}}HttpLibrary {
public abstract send(request: RequestContext): {{#useRxJS}}Observable{{/useRxJS}}{{^useRxJS}}Promise{{/useRxJS}}<ResponseContext>;
};
export abstract class AbstractMiddleware implements {{^useRxJS}}Promise{{/useRxJS}}Middleware {
public abstract pre(context: RequestContext): {{#useRxJS}}Observable{{/useRxJS}}{{^useRxJS}}Promise{{/useRxJS}}<RequestContext>;
public abstract post(context: ResponseContext): {{#useRxJS}}Observable{{/useRxJS}}{{^useRxJS}}Promise{{/useRxJS}}<ResponseContext>;
}
export abstract class AbstractServerConfiguration implements BaseServerConfiguration {
public abstract makeRequestContext(endpoint: string, httpMethod: HttpMethod): RequestContext;
};

View File

@@ -0,0 +1,165 @@
import { inject, injectable, multiInject, optional, interfaces } from "inversify";
import { Configuration } from "../configuration";
import { ServerConfiguration, servers } from "../servers";
import { HttpLibrary{{^useRxJS}}, wrapHttpLibrary{{/useRxJS}} } from "../http/http";
import { Middleware{{^useRxJS}}, PromiseMiddlewareWrapper{{/useRxJS}} } from "../middleware";
import { authMethodServices, AuthMethods } from "../auth/auth";
{{#frameworks}}
{{#fetch-api}}
import { IsomorphicFetchHttpLibrary as DefaultHttpLibrary } from "../http/isomorphic-fetch";
{{/fetch-api}}
{{#jquery}}
import { JQueryHttpLibrary as DefaultHttpLibrary } from "../http/jquery";
{{/jquery}}
{{/frameworks}}
import { AbstractHttpLibrary, AbstractMiddleware, AbstractServerConfiguration } from "./http";
import { AbstractConfiguration, AbstractAuthMethod, AbstractTokenProvider } from "./configuration";
export { AbstractHttpLibrary, AbstractMiddleware, AbstractServerConfiguration, AbstractConfiguration, AbstractAuthMethod, AbstractTokenProvider };
{{#useObjectParameters}}
import * as apis from "../types/ObjectParamAPI";
import * as apiServices from "./ObjectParamAPI";
{{/useObjectParameters}}
{{^useObjectParameters}}
{{#useRxJS}}
import * as apis from "../types/ObservableAPI";
import * as apiServices from "./ObservableAPI";
{{/useRxJS}}
{{^useRxJS}}
import * as apis from "../types/PromiseAPI";
import * as apiServices from "./PromiseAPI";
{{/useRxJS}}
{{/useObjectParameters}}
@injectable()
class InjectableConfiguration implements AbstractConfiguration {
public httpApi: HttpLibrary = new DefaultHttpLibrary();
public middleware: Middleware[] = [];
public authMethods: AuthMethods = {};
constructor(
@inject(AbstractServerConfiguration) @optional() public baseServer: AbstractServerConfiguration = servers[0],
@inject(AbstractHttpLibrary) @optional() httpApi: AbstractHttpLibrary,
@multiInject(AbstractMiddleware) @optional() middleware: AbstractMiddleware[] = [],
@multiInject(AbstractAuthMethod) @optional() securityConfiguration: AbstractAuthMethod[] = []
) {
{{#useRxJS}}
this.httpApi = httpApi || new DefaultHttpLibrary();
this.middleware = middleware;
{{/useRxJS}}
{{^useRxJS}}
this.httpApi = httpApi === undefined ? new DefaultHttpLibrary() : wrapHttpLibrary(httpApi);
for (const _middleware of middleware) {
this.middleware.push(new PromiseMiddlewareWrapper(_middleware));
}
{{/useRxJS}}
for (const authMethod of securityConfiguration) {
const authName = authMethod.getName();
// @ts-ignore
if (authMethodServices[authName] !== undefined) {
// @ts-ignore
this.authMethods[authName] = authMethod;
}
}
}
}
/**
* Helper class to simplify binding the services
*/
export class ApiServiceBinder {
constructor(private container: interfaces.Container) {
this.container.bind(AbstractConfiguration).to(InjectableConfiguration);
}
/**
* Allows you to bind a server configuration without having to import the service identifier.
*/
public get bindServerConfiguration() {
return this.container.bind(AbstractServerConfiguration);
}
/**
* Use one of the predefined server configurations.
*
* To customize the server variables you can call `setVariables` on the
* return value;
*/
public bindServerConfigurationToPredefined(idx: number) {
this.bindServerConfiguration.toConstantValue(servers[idx]);
return servers[idx];
}
/**
* Explicitly define the service base url
*/
public bindServerConfigurationToURL(url: string) {
return this.bindServerConfiguration.toConstantValue(
new ServerConfiguration<{}>(url, {})
);
}
/**
* Allows you to bind a http library without having to import the service identifier.
*/
public get bindHttpLibrary() {
return this.container.bind(AbstractHttpLibrary);
}
/**
* Allows you to bind a middleware without having to import the service identifier.
*
* You can bind multiple middlewares by calling this multiple method times.
*/
public get bindMiddleware() {
return this.container.bind(AbstractMiddleware);
}
/**
* Allows you to bind an auth method without having to import the service identifier.
*
* Note: The name of the bound auth method needs to be known in the specs,
* because the name is used to decide for which endpoints to apply the authentication.
*/
public get bindAuthMethod() {
return this.container.bind(AbstractAuthMethod);
}
/**
* Use one of the predefined auth methods.
*
* Make sure that you have injected all dependencies for it.
*/
public bindAuthMethodToPredefined(name: keyof AuthMethods) {
return this.bindAuthMethod.to(authMethodServices[name]);
}
/**
* Bind all the apis to their respective service identifiers
*
* If you want to only bind some of the apis, you need to do that manually.
*/
public bindAllApiServices() {
{{#apiInfo}}
{{#apis}}
{{#operations}}
{{#useObjectParameters}}
this.container.bind(apiServices.AbstractObject{{classname}}).to(apis.Object{{classname}}).inSingletonScope();
{{/useObjectParameters}}
{{^useObjectParameters}}
{{#useRxJS}}
this.container.bind(apiServices.AbstractObservable{{classname}}).to(apis.Observable{{classname}}).inSingletonScope();
{{/useRxJS}}
{{^useRxJS}}
this.container.bind(apiServices.AbstractPromise{{classname}}).to(apis.Promise{{classname}}).inSingletonScope();
{{/useRxJS}}
{{/useObjectParameters}}
{{/operations}}
{{/apis}}
{{/apiInfo}}
}
}

View File

@@ -0,0 +1,44 @@
{
"compilerOptions": {
"strict": true,
/* Basic Options */
{{#supportsES6}}
"target": "es6",
"esModuleInterop": true,
{{/supportsES6}}
{{^supportsES6}}
"target": "es5",
{{/supportsES6}}
"moduleResolution": "node",
"declaration": true,
/* Additional Checks */
"noUnusedLocals": false, /* Report errors on unused locals. */ // TODO: reenable (unused imports!)
"noUnusedParameters": false, /* Report errors on unused parameters. */ // TODO: set to true again
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
"removeComments": true,
"sourceMap": true,
"outDir": "./dist",
"noLib": false,
{{#platforms}}
{{#node}}
"lib": [ "es2016" ],
{{/node}}
{{#browser}}
"lib": [ "es2016", "dom" ],
{{/browser}}
{{/platforms}}
{{#useInversify}}
"experimentalDecorators": true,
{{/useInversify}}
},
"exclude": [
"dist",
"node_modules"
],
"filesGlob": [
"./**/*.ts",
]
}

View File

@@ -0,0 +1,57 @@
import { ResponseContext, RequestContext, HttpFile } from '../http/http{{extensionForDeno}}';
import { Configuration} from '../configuration{{extensionForDeno}}'
{{#useRxJS}}
import { Observable } from 'rxjs';
{{/useRxJS}}
{{#models}}
{{#model}}
import { {{{ classname }}} } from '{{{ importPath }}}{{extensionForDeno}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
import { Observable{{classname}} } from "./ObservableAPI{{extensionForDeno}}";
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}{{extensionForDeno}}";
{{#operation}}
export interface {{classname}}{{operationIdCamelCase}}Request {
{{#allParams}}
/**
* {{description}}
* @type {{dataType}}
* @memberof {{classname}}{{nickname}}
*/
{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}
{{/allParams}}
}
{{/operation}}
export class Object{{classname}} {
private api: Observable{{classname}}
public constructor(configuration: Configuration, requestFactory?: {{classname}}RequestFactory, responseProcessor?: {{classname}}ResponseProcessor) {
this.api = new Observable{{classname}}(configuration, requestFactory, responseProcessor);
}
{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
* @param param the request object
*/
public {{nickname}}(param: {{classname}}{{operationIdCamelCase}}Request{{^hasRequiredParams}} = {}{{/hasRequiredParams}}, options?: Configuration): {{#useRxJS}}Observable{{/useRxJS}}{{^useRxJS}}Promise{{/useRxJS}}<{{{returnType}}}{{^returnType}}void{{/returnType}}> {
return this.api.{{nickname}}({{#allParams}}param.{{paramName}}, {{/allParams}} options){{^useRxJS}}.toPromise(){{/useRxJS}};
}
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -0,0 +1,87 @@
import { ResponseContext, RequestContext, HttpFile } from '../http/http{{extensionForDeno}}';
import { Configuration} from '../configuration{{extensionForDeno}}'
import { Observable, of, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{extensionForDeno}}'{{/useRxJS}};
import {mergeMap, map} from {{#useRxJS}}'rxjs/operators'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{extensionForDeno}}'{{/useRxJS}};
{{#useInversify}}
import { injectable, inject, optional } from "inversify";
import { AbstractConfiguration } from "../services/configuration{{extensionForDeno}}";
{{/useInversify}}
{{#models}}
{{#model}}
import { {{{ classname }}} } from '{{{ importPath }}}{{extensionForDeno}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
{{#operations}}
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}{{extensionForDeno}}";
{{#useInversify}}
import { Abstract{{classname}}RequestFactory, Abstract{{classname}}ResponseProcessor } from "../apis/{{classname}}.service{{extensionForDeno}}";
@injectable()
{{/useInversify}}
export class Observable{{classname}} {
{{#useInversify}}
private requestFactory: Abstract{{classname}}RequestFactory;
private responseProcessor: Abstract{{classname}}ResponseProcessor;
{{/useInversify}}
{{^useInversify}}
private requestFactory: {{classname}}RequestFactory;
private responseProcessor: {{classname}}ResponseProcessor;
{{/useInversify}}
private configuration: Configuration;
public constructor(
{{#useInversify}}
@inject(AbstractConfiguration) configuration: Configuration,
@inject(Abstract{{classname}}RequestFactory) @optional() requestFactory?: Abstract{{classname}}RequestFactory,
@inject(Abstract{{classname}}ResponseProcessor) @optional() responseProcessor?: Abstract{{classname}}ResponseProcessor
{{/useInversify}}
{{^useInversify}}
configuration: Configuration,
requestFactory?: {{classname}}RequestFactory,
responseProcessor?: {{classname}}ResponseProcessor
{{/useInversify}}
) {
this.configuration = configuration;
this.requestFactory = requestFactory || new {{classname}}RequestFactory(configuration);
this.responseProcessor = responseProcessor || new {{classname}}ResponseProcessor();
}
{{#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}}void{{/returnType}}> {
const requestContextPromise = this.requestFactory.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}_options);
// build promise chain
let middlewarePreObservable = from<RequestContext>(requestContextPromise);
for (let middleware of this.configuration.middleware) {
middlewarePreObservable = middlewarePreObservable.pipe(mergeMap((ctx: RequestContext) => middleware.pre(ctx)));
}
return middlewarePreObservable.pipe(mergeMap((ctx: RequestContext) => this.configuration.httpApi.send(ctx))).
pipe(mergeMap((response: ResponseContext) => {
let middlewarePostObservable = of(response);
for (let middleware of this.configuration.middleware) {
middlewarePostObservable = middlewarePostObservable.pipe(mergeMap((rsp: ResponseContext) => middleware.post(rsp)));
}
return middlewarePostObservable.pipe(map((rsp: ResponseContext) => this.responseProcessor.{{nickname}}(rsp)));
}));
}
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@@ -0,0 +1,67 @@
import { ResponseContext, RequestContext, HttpFile } from '../http/http{{extensionForDeno}}';
import { Configuration} from '../configuration{{extensionForDeno}}'
{{#useInversify}}
import { injectable, inject, optional } from "inversify";
import { AbstractConfiguration } from "../services/configuration";
{{/useInversify}}
{{#models}}
{{#model}}
import { {{{ classname }}} } from '{{{ importPath }}}{{extensionForDeno}}';
{{/model}}
{{/models}}
{{#apiInfo}}
{{#apis}}
import { Observable{{classname}} } from './ObservableAPI{{extensionForDeno}}';
{{#operations}}
import { {{classname}}RequestFactory, {{classname}}ResponseProcessor} from "../apis/{{classname}}{{extensionForDeno}}";
{{#useInversify}}
import { Abstract{{classname}}RequestFactory, Abstract{{classname}}ResponseProcessor } from "../apis/{{classname}}.service";
@injectable()
{{/useInversify}}
export class Promise{{classname}} {
private api: Observable{{classname}}
public constructor(
{{#useInversify}}
@inject(AbstractConfiguration) configuration: Configuration,
@inject(Abstract{{classname}}RequestFactory) @optional() requestFactory?: Abstract{{classname}}RequestFactory,
@inject(Abstract{{classname}}ResponseProcessor) @optional() responseProcessor?: Abstract{{classname}}ResponseProcessor
{{/useInversify}}
{{^useInversify}}
configuration: Configuration,
requestFactory?: {{classname}}RequestFactory,
responseProcessor?: {{classname}}ResponseProcessor
{{/useInversify}}
) {
this.api = new Observable{{classname}}(configuration, requestFactory, responseProcessor);
}
{{#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}}void{{/returnType}}> {
const result = this.api.{{nickname}}({{#allParams}}{{paramName}}, {{/allParams}}_options);
return result.toPromise();
}
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

37
templates/util.mustache Normal file
View File

@@ -0,0 +1,37 @@
/**
* 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") {
return true;
}
if (codeRange == code.toString()) {
return true;
} else {
const codeString = code.toString();
if (codeString.length != codeRange.length) {
return false;
}
for (let i = 0; i < codeString.length; i++) {
if (codeRange.charAt(i) != "X" && codeRange.charAt(i) != codeString.charAt(i)) {
return false;
}
}
return true;
}
}
/**
* Returns if it can consume form
*
* @param consumes array
*/
export function canConsumeForm(contentTypes: string[]): boolean {
return contentTypes.indexOf('multipart/form-data') !== -1
}