diff --git a/bin/configs/typescript-consolidated-composed-schemas.yaml b/bin/configs/typescript-consolidated-composed-schemas.yaml new file mode 100644 index 000000000000..0da510f5bfc6 --- /dev/null +++ b/bin/configs/typescript-consolidated-composed-schemas.yaml @@ -0,0 +1,6 @@ +generatorName: typescript +outputDir: samples/openapi3/client/petstore/typescript/builds/composed-schemas +inputSpec: modules/openapi-generator/src/test/resources/3_0/composed-schemas.yaml +templateDir: modules/openapi-generator/src/main/resources/typescript +additionalProperties: + npmName: ts-petstore-client diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java index 821d190f5eb4..926a4eb41bbd 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptClientCodegen.java @@ -156,6 +156,7 @@ public TypeScriptClientCodegen() { typeMapping.put("ByteArray", "string"); typeMapping.put("UUID", "string"); typeMapping.put("Error", "Error"); + typeMapping.put("AnyType", "any"); cliOptions.add(new CliOption(NPM_NAME, "The name under which you want to publish generated npm package." + @@ -893,6 +894,13 @@ public String toOneOfName(List names, ComposedSchema composedSchema) { return String.join(" | ", types); } + @Override + public String toAllOfName(List names, ComposedSchema composedSchema) { + List types = getTypesFromSchemas(composedSchema.getAllOf()); + + return String.join(" & ", types); + } + /** * Extracts the list of type names from a list of schemas. * Excludes `AnyType` if there are other valid types extracted. diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.gitignore b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.gitignore new file mode 100644 index 000000000000..1521c8b7652b --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.gitignore @@ -0,0 +1 @@ +dist diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.openapi-generator-ignore b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.openapi-generator-ignore new file mode 100644 index 000000000000..7484ee590a38 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.openapi-generator/FILES b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.openapi-generator/FILES new file mode 100644 index 000000000000..3647b2a71bd5 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.openapi-generator/FILES @@ -0,0 +1,29 @@ +.gitignore +README.md +apis/DefaultApi.ts +apis/baseapi.ts +apis/exception.ts +auth/auth.ts +configuration.ts +git_push.sh +http/http.ts +http/isomorphic-fetch.ts +index.ts +middleware.ts +models/Cat.ts +models/CatAllOf.ts +models/Dog.ts +models/DogAllOf.ts +models/InlineObject.ts +models/ObjectSerializer.ts +models/PetByAge.ts +models/PetByType.ts +models/all.ts +package.json +rxjsStub.ts +servers.ts +tsconfig.json +types/ObjectParamAPI.ts +types/ObservableAPI.ts +types/PromiseAPI.ts +util.ts diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.openapi-generator/VERSION b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.openapi-generator/VERSION new file mode 100644 index 000000000000..862529f8cacd --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/.openapi-generator/VERSION @@ -0,0 +1 @@ +5.2.1-SNAPSHOT \ No newline at end of file diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/README.md b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/README.md new file mode 100644 index 000000000000..80b1ac5cc98b --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/README.md @@ -0,0 +1,30 @@ +## ts-petstore-client@1.0.0 + +This generator creates TypeScript/JavaScript client that utilizes fetch-api. + +### 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 ts-petstore-client@1.0.0 --save +``` + +_unPublished (not recommended):_ + +``` +npm install PATH_TO_GENERATED_PACKAGE --save diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/apis/DefaultApi.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/apis/DefaultApi.ts new file mode 100644 index 000000000000..b2fe591913cf --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/apis/DefaultApi.ts @@ -0,0 +1,213 @@ +// TODO: better import syntax? +import { BaseAPIRequestFactory, RequiredError } from './baseapi'; +import {Configuration} from '../configuration'; +import { RequestContext, HttpMethod, ResponseContext, HttpFile} from '../http/http'; +import {ObjectSerializer} from '../models/ObjectSerializer'; +import {ApiException} from './exception'; +import {isCodeInRange} from '../util'; + +import { Cat } from '../models/Cat'; +import { Dog } from '../models/Dog'; +import { InlineObject } from '../models/InlineObject'; +import { PetByAge } from '../models/PetByAge'; +import { PetByType } from '../models/PetByType'; + +/** + * no description + */ +export class DefaultApiRequestFactory extends BaseAPIRequestFactory { + + /** + * @param inlineObject + */ + public async filePost(inlineObject?: InlineObject, _options?: Configuration): Promise { + let _config = _options || this.configuration; + + + // Path Params + const localVarPath = '/file'; + + // Make Request Context + const requestContext = _config.baseServer.makeRequestContext(localVarPath, HttpMethod.POST); + requestContext.setHeaderParam("Accept", "application/json, */*;q=0.8") + + // Query Params + + // Header Params + + // Form Params + + + // Body Params + const contentType = ObjectSerializer.getPreferredMediaType([ + "application/json" + ]); + requestContext.setHeaderParam("Content-Type", contentType); + const serializedBody = ObjectSerializer.stringify( + ObjectSerializer.serialize(inlineObject, "InlineObject", ""), + contentType + ); + requestContext.setBody(serializedBody); + + // Apply auth methods + + return requestContext; + } + + /** + * @param petByAgePetByType + */ + public async petsFilteredPatch(petByAgePetByType?: PetByAge | PetByType, _options?: Configuration): Promise { + let _config = _options || this.configuration; + + + // Path Params + const localVarPath = '/pets-filtered'; + + // Make Request Context + const requestContext = _config.baseServer.makeRequestContext(localVarPath, HttpMethod.PATCH); + requestContext.setHeaderParam("Accept", "application/json, */*;q=0.8") + + // Query Params + + // Header Params + + // Form Params + + + // Body Params + const contentType = ObjectSerializer.getPreferredMediaType([ + "application/json" + ]); + requestContext.setHeaderParam("Content-Type", contentType); + const serializedBody = ObjectSerializer.stringify( + ObjectSerializer.serialize(petByAgePetByType, "PetByAge | PetByType", ""), + contentType + ); + requestContext.setBody(serializedBody); + + // Apply auth methods + + return requestContext; + } + + /** + * @param catDog + */ + public async petsPatch(catDog?: Cat | Dog, _options?: Configuration): Promise { + let _config = _options || this.configuration; + + + // Path Params + const localVarPath = '/pets'; + + // Make Request Context + const requestContext = _config.baseServer.makeRequestContext(localVarPath, HttpMethod.PATCH); + requestContext.setHeaderParam("Accept", "application/json, */*;q=0.8") + + // Query Params + + // Header Params + + // Form Params + + + // Body Params + const contentType = ObjectSerializer.getPreferredMediaType([ + "application/json" + ]); + requestContext.setHeaderParam("Content-Type", contentType); + const serializedBody = ObjectSerializer.stringify( + ObjectSerializer.serialize(catDog, "Cat | Dog", ""), + contentType + ); + requestContext.setBody(serializedBody); + + // Apply auth methods + + return requestContext; + } + +} + +export class DefaultApiResponseProcessor { + + /** + * 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 filePost + * @throws ApiException if the response code was not in [200, 299] + */ + public async filePost(response: ResponseContext): Promise { + const contentType = ObjectSerializer.normalizeMediaType(response.headers["content-type"]); + if (isCodeInRange("200", response.httpStatusCode)) { + return; + } + + // Work around for missing responses in specification, e.g. for petstore.yaml + if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { + const body: void = ObjectSerializer.deserialize( + ObjectSerializer.parse(await response.body.text(), contentType), + "void", "" + ) as void; + return body; + } + + let body = response.body || ""; + throw new ApiException(response.httpStatusCode, "Unknown API Status Code!\nBody: \"" + body + "\""); + } + + /** + * 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 petsFilteredPatch + * @throws ApiException if the response code was not in [200, 299] + */ + public async petsFilteredPatch(response: ResponseContext): Promise { + const contentType = ObjectSerializer.normalizeMediaType(response.headers["content-type"]); + if (isCodeInRange("200", response.httpStatusCode)) { + return; + } + + // Work around for missing responses in specification, e.g. for petstore.yaml + if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { + const body: void = ObjectSerializer.deserialize( + ObjectSerializer.parse(await response.body.text(), contentType), + "void", "" + ) as void; + return body; + } + + let body = response.body || ""; + throw new ApiException(response.httpStatusCode, "Unknown API Status Code!\nBody: \"" + body + "\""); + } + + /** + * 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 petsPatch + * @throws ApiException if the response code was not in [200, 299] + */ + public async petsPatch(response: ResponseContext): Promise { + const contentType = ObjectSerializer.normalizeMediaType(response.headers["content-type"]); + if (isCodeInRange("200", response.httpStatusCode)) { + return; + } + + // Work around for missing responses in specification, e.g. for petstore.yaml + if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) { + const body: void = ObjectSerializer.deserialize( + ObjectSerializer.parse(await response.body.text(), contentType), + "void", "" + ) as void; + return body; + } + + let body = response.body || ""; + throw new ApiException(response.httpStatusCode, "Unknown API Status Code!\nBody: \"" + body + "\""); + } + +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/apis/baseapi.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/apis/baseapi.ts new file mode 100644 index 000000000000..fe7ee3d15118 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/apis/baseapi.ts @@ -0,0 +1,37 @@ +import { Configuration } from '../configuration' + +/** + * + * @export + */ +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + + +/** + * + * @export + * @class BaseAPI + */ +export class BaseAPIRequestFactory { + + constructor(protected configuration: Configuration) { + } +}; + +/** + * + * @export + * @class RequiredError + * @extends {Error} + */ +export class RequiredError extends Error { + name: "RequiredError" = "RequiredError"; + constructor(public field: string, msg?: string) { + super(msg); + } +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/apis/exception.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/apis/exception.ts new file mode 100644 index 000000000000..fb8d314eb41d --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/apis/exception.ts @@ -0,0 +1,14 @@ +/** + * 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 extends Error { + public constructor(public code: number, public body: T) { + super("HTTP-Code: " + code + "\nMessage: " + JSON.stringify(body)) + } +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/auth/auth.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/auth/auth.ts new file mode 100644 index 000000000000..fa859aaa0981 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/auth/auth.ts @@ -0,0 +1,49 @@ +// typings for btoa are incorrect +import { RequestContext } from "../http/http"; + +/** + * 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; +} + +export interface TokenProvider { + getToken(): Promise | string; +} + + +export type AuthMethods = { +} + +export type ApiKeyConfiguration = string; +export type HttpBasicConfiguration = { "username": string, "password": string }; +export type HttpBearerConfiguration = { tokenProvider: TokenProvider }; +export type OAuth2Configuration = { accessToken: string }; + +export type AuthMethodsConfiguration = { +} + +/** + * Creates the authentication methods from a swagger description. + * + */ +export function configureAuthMethods(config: AuthMethodsConfiguration | undefined): AuthMethods { + let authMethods: AuthMethods = {} + + if (!config) { + return authMethods; + } + + return authMethods; +} \ No newline at end of file diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/configuration.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/configuration.ts new file mode 100644 index 000000000000..b78d85972a4a --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/configuration.ts @@ -0,0 +1,66 @@ +import { HttpLibrary } from "./http/http"; +import { Middleware, PromiseMiddleware, PromiseMiddlewareWrapper } from "./middleware"; +import { IsomorphicFetchHttpLibrary as DefaultHttpLibrary } from "./http/isomorphic-fetch"; +import { BaseServerConfiguration, server1 } from "./servers"; +import { configureAuthMethods, AuthMethods, AuthMethodsConfiguration } from "./auth/auth"; + +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; +} \ No newline at end of file diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/git_push.sh b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/git_push.sh new file mode 100644 index 000000000000..8442b80bb445 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/git_push.sh @@ -0,0 +1,52 @@ +#!/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-pestore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + 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' + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/http.ts new file mode 100644 index 000000000000..8b8219e910ff --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/http.ts @@ -0,0 +1,220 @@ +// typings of url-parse are incorrect... +// @ts-ignore +import * as URLParse from "url-parse"; +import { Observable, from } from '../rxjsStub'; + +export * from './isomorphic-fetch'; + +/** + * 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. + */ +export type HttpFile = Blob & { readonly name: string }; + + +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; + +/** + * Represents an HTTP request context + */ +export class RequestContext { + private headers: { [key: string]: string } = {}; + private body: RequestBody = undefined; + 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 = 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; + } +} + +export interface ResponseBody { + text(): Promise; + binary(): Promise; +} + +/** + * Helper class to generate a `ResponseBody` from binary data + */ +export class SelfDecodingBody implements ResponseBody { + constructor(private dataSource: Promise) {} + + binary(): Promise { + return this.dataSource; + } + + async text(): Promise { + const data: Blob = await this.dataSource; + // @ts-ignore + if (data.text) { + // @ts-ignore + return data.text(); + } + + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.addEventListener("load", () => resolve(reader.result as string)); + reader.addEventListener("error", () => reject(reader.error)); + reader.readAsText(data); + }); + } +} + +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 { + const data = await this.body.binary(); + const fileName = this.getParsedHeader("content-disposition")["filename"] || ""; + 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 + }); + } + } +} + +export interface HttpLibrary { + send(request: RequestContext): Observable; +} + +export interface PromiseHttpLibrary { + send(request: RequestContext): Promise; +} + +export function wrapHttpLibrary(promiseHttpLibrary: PromiseHttpLibrary): HttpLibrary { + return { + send(request: RequestContext): Observable { + return from(promiseHttpLibrary.send(request)); + } + } +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/isomorphic-fetch.ts new file mode 100644 index 000000000000..3af85f3d902c --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/isomorphic-fetch.ts @@ -0,0 +1,32 @@ +import {HttpLibrary, RequestContext, ResponseContext} from './http'; +import { from, Observable } from '../rxjsStub'; +import "whatwg-fetch"; + +export class IsomorphicFetchHttpLibrary implements HttpLibrary { + + public send(request: RequestContext): Observable { + let method = request.getHttpMethod().toString(); + let body = request.getBody(); + + const resultPromise = fetch(request.getUrl(), { + method: method, + body: body as any, + headers: request.getHeaders(), + credentials: "same-origin" + }).then((resp: any) => { + const headers: { [name: string]: string } = {}; + resp.headers.forEach((value: string, name: string) => { + headers[name] = value; + }); + + const body = { + text: () => resp.text(), + binary: () => resp.blob() + }; + return new ResponseContext(resp.status, headers, body); + }); + + return from>(resultPromise); + + } +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/index.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/index.ts new file mode 100644 index 000000000000..127f89d99723 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/index.ts @@ -0,0 +1,11 @@ +export * from "./http/http"; +export * from "./auth/auth"; +export * from "./models/all"; +export { createConfiguration } from "./configuration" +export { Configuration } from "./configuration" +export * from "./apis/exception"; +export * from "./servers"; + +export { PromiseMiddleware as Middleware } from './middleware'; +export { PromiseDefaultApi as DefaultApi } from './types/PromiseAPI'; + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/middleware.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/middleware.ts new file mode 100644 index 000000000000..e90071381890 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/middleware.ts @@ -0,0 +1,66 @@ +import {RequestContext, ResponseContext} from './http/http'; +import { Observable, from } from './rxjsStub'; + +/** + * 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; + /** + * 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; +} + +export class PromiseMiddlewareWrapper implements Middleware { + + public constructor(private middleware: PromiseMiddleware) { + + } + + pre(context: RequestContext): Observable { + return from(this.middleware.pre(context)); + } + + post(context: ResponseContext): Observable { + 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; + /** + * 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; +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/Cat.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/Cat.ts new file mode 100644 index 000000000000..eb878d1537e4 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/Cat.ts @@ -0,0 +1,43 @@ +/** + * Example + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * OpenAPI spec version: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { CatAllOf } from './CatAllOf'; +import { HttpFile } from '../http/http'; + +export class Cat { + 'hunts'?: boolean; + 'age'?: number; + + static readonly discriminator: string | undefined = undefined; + + static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ + { + "name": "hunts", + "baseName": "hunts", + "type": "boolean", + "format": "" + }, + { + "name": "age", + "baseName": "age", + "type": "number", + "format": "" + } ]; + + static getAttributeTypeMap() { + return Cat.attributeTypeMap; + } + + public constructor() { + } +} + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/CatAllOf.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/CatAllOf.ts new file mode 100644 index 000000000000..f492b8a9474d --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/CatAllOf.ts @@ -0,0 +1,42 @@ +/** + * Example + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * OpenAPI spec version: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { HttpFile } from '../http/http'; + +export class CatAllOf { + 'hunts'?: boolean; + 'age'?: number; + + static readonly discriminator: string | undefined = undefined; + + static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ + { + "name": "hunts", + "baseName": "hunts", + "type": "boolean", + "format": "" + }, + { + "name": "age", + "baseName": "age", + "type": "number", + "format": "" + } ]; + + static getAttributeTypeMap() { + return CatAllOf.attributeTypeMap; + } + + public constructor() { + } +} + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/Dog.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/Dog.ts new file mode 100644 index 000000000000..456b63bd0388 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/Dog.ts @@ -0,0 +1,46 @@ +/** + * Example + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * OpenAPI spec version: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { DogAllOf } from './DogAllOf'; +import { HttpFile } from '../http/http'; + +export class Dog { + 'bark'?: boolean; + 'breed'?: DogBreedEnum; + + static readonly discriminator: string | undefined = undefined; + + static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ + { + "name": "bark", + "baseName": "bark", + "type": "boolean", + "format": "" + }, + { + "name": "breed", + "baseName": "breed", + "type": "DogBreedEnum", + "format": "" + } ]; + + static getAttributeTypeMap() { + return Dog.attributeTypeMap; + } + + public constructor() { + } +} + + +export type DogBreedEnum = "Dingo" | "Husky" | "Retriever" | "Shepherd" ; + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/DogAllOf.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/DogAllOf.ts new file mode 100644 index 000000000000..75fb0ac2faea --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/DogAllOf.ts @@ -0,0 +1,45 @@ +/** + * Example + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * OpenAPI spec version: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { HttpFile } from '../http/http'; + +export class DogAllOf { + 'bark'?: boolean; + 'breed'?: DogAllOfBreedEnum; + + static readonly discriminator: string | undefined = undefined; + + static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ + { + "name": "bark", + "baseName": "bark", + "type": "boolean", + "format": "" + }, + { + "name": "breed", + "baseName": "breed", + "type": "DogAllOfBreedEnum", + "format": "" + } ]; + + static getAttributeTypeMap() { + return DogAllOf.attributeTypeMap; + } + + public constructor() { + } +} + + +export type DogAllOfBreedEnum = "Dingo" | "Husky" | "Retriever" | "Shepherd" ; + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/InlineObject.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/InlineObject.ts new file mode 100644 index 000000000000..d6ffd66e6929 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/InlineObject.ts @@ -0,0 +1,35 @@ +/** + * Example + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * OpenAPI spec version: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { HttpFile } from '../http/http'; + +export class InlineObject { + 'file'?: any; + + static readonly discriminator: string | undefined = undefined; + + static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ + { + "name": "file", + "baseName": "file", + "type": "any", + "format": "" + } ]; + + static getAttributeTypeMap() { + return InlineObject.attributeTypeMap; + } + + public constructor() { + } +} + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/ObjectSerializer.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/ObjectSerializer.ts new file mode 100644 index 000000000000..70178da770e5 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/ObjectSerializer.ts @@ -0,0 +1,238 @@ +export * from './Cat'; +export * from './CatAllOf'; +export * from './Dog'; +export * from './DogAllOf'; +export * from './InlineObject'; +export * from './PetByAge'; +export * from './PetByType'; + +import { Cat } from './Cat'; +import { CatAllOf } from './CatAllOf'; +import { Dog , DogBreedEnum } from './Dog'; +import { DogAllOf , DogAllOfBreedEnum } from './DogAllOf'; +import { InlineObject } from './InlineObject'; +import { PetByAge } from './PetByAge'; +import { PetByType, PetByTypePetTypeEnum } from './PetByType'; + +/* 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 +} + + +let enumsMap: Set = new Set([ + "DogBreedEnum", + "DogAllOfBreedEnum", + "PetByTypePetTypeEnum", +]); + +let typeMap: {[index: string]: any} = { + "Cat": Cat, + "CatAllOf": CatAllOf, + "Dog": Dog, + "DogAllOf": DogAllOf, + "InlineObject": InlineObject, + "PetByAge": PetByAge, + "PetByType": PetByType, +} + +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> + 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> + 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]; + instance[attributeType.name] = ObjectSerializer.deserialize(data[attributeType.baseName], attributeType.type, attributeType.format); + } + 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 { + /** 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 === "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 === "application/json") { + return JSON.parse(rawData); + } + + throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse."); + } +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/PetByAge.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/PetByAge.ts new file mode 100644 index 000000000000..bbd8a86a2666 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/PetByAge.ts @@ -0,0 +1,42 @@ +/** + * Example + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * OpenAPI spec version: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { HttpFile } from '../http/http'; + +export class PetByAge { + 'age': number; + 'nickname'?: string; + + static readonly discriminator: string | undefined = undefined; + + static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ + { + "name": "age", + "baseName": "age", + "type": "number", + "format": "" + }, + { + "name": "nickname", + "baseName": "nickname", + "type": "string", + "format": "" + } ]; + + static getAttributeTypeMap() { + return PetByAge.attributeTypeMap; + } + + public constructor() { + } +} + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/PetByType.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/PetByType.ts new file mode 100644 index 000000000000..2c8713e565af --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/PetByType.ts @@ -0,0 +1,45 @@ +/** + * Example + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * OpenAPI spec version: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { HttpFile } from '../http/http'; + +export class PetByType { + 'petType': PetByTypePetTypeEnum; + 'hunts'?: boolean; + + static readonly discriminator: string | undefined = undefined; + + static readonly attributeTypeMap: Array<{name: string, baseName: string, type: string, format: string}> = [ + { + "name": "petType", + "baseName": "pet_type", + "type": "PetByTypePetTypeEnum", + "format": "" + }, + { + "name": "hunts", + "baseName": "hunts", + "type": "boolean", + "format": "" + } ]; + + static getAttributeTypeMap() { + return PetByType.attributeTypeMap; + } + + public constructor() { + } +} + + +export type PetByTypePetTypeEnum = "Cat" | "Dog" ; + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/all.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/all.ts new file mode 100644 index 000000000000..851c461ecf68 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/models/all.ts @@ -0,0 +1,7 @@ +export * from './Cat' +export * from './CatAllOf' +export * from './Dog' +export * from './DogAllOf' +export * from './InlineObject' +export * from './PetByAge' +export * from './PetByType' diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/package.json b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/package.json new file mode 100644 index 000000000000..1605e85eb131 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/package.json @@ -0,0 +1,27 @@ +{ + "name": "ts-petstore-client", + "version": "1.0.0", + "description": "OpenAPI client for ts-petstore-client", + "author": "OpenAPI-Generator Contributors", + "keywords": [ + "fetch", + "typescript", + "openapi-client", + "openapi-generator" + ], + "license": "Unlicense", + "main": "./dist/index.js", + "typings": "./dist/index.d.ts", + "scripts": { + "build": "tsc", + "prepare": "npm run build" + }, + "dependencies": { + "whatwg-fetch": "^3.0.0", + "es6-promise": "^4.2.4", + "url-parse": "^1.4.3" + }, + "devDependencies": { + "typescript": "^3.9.3" + } +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/rxjsStub.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/rxjsStub.ts new file mode 100644 index 000000000000..4c73715a2486 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/rxjsStub.ts @@ -0,0 +1,27 @@ +export class Observable { + constructor(private promise: Promise) {} + + toPromise() { + return this.promise; + } + + pipe(callback: (value: T) => S | Promise): Observable { + return new Observable(this.promise.then(callback)); + } +} + +export function from(promise: Promise) { + return new Observable(promise); +} + +export function of(value: T) { + return new Observable(Promise.resolve(value)); +} + +export function mergeMap(callback: (value: T) => Observable) { + return (value: T) => callback(value).toPromise(); +} + +export function map(callback: any) { + return callback; +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/servers.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/servers.ts new file mode 100644 index 000000000000..f1bd953bf872 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/servers.ts @@ -0,0 +1,53 @@ +import { RequestContext, HttpMethod } from "./http/http"; + +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 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) { + 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); + } +} + +export const server1 = new ServerConfiguration<{ }>("http://api.example.xyz/v1", { }) + +export const servers = [server1]; diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/tsconfig.json b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/tsconfig.json new file mode 100644 index 000000000000..ce51978eb866 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "strict": true, + /* Basic Options */ + "target": "es5", + "module": "commonjs", + "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, + "lib": [ "es6", "dom" ], + }, + "exclude": [ + "dist", + "node_modules" + ], + "filesGlob": [ + "./**/*.ts", + ] +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/types/ObjectParamAPI.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/types/ObjectParamAPI.ts new file mode 100644 index 000000000000..d94a613229e6 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/types/ObjectParamAPI.ts @@ -0,0 +1,71 @@ +import { ResponseContext, RequestContext, HttpFile } from '../http/http'; +import * as models from '../models/all'; +import { Configuration} from '../configuration' + +import { Cat } from '../models/Cat'; +import { CatAllOf } from '../models/CatAllOf'; +import { Dog } from '../models/Dog'; +import { DogAllOf } from '../models/DogAllOf'; +import { InlineObject } from '../models/InlineObject'; +import { PetByAge } from '../models/PetByAge'; +import { PetByType } from '../models/PetByType'; + +import { ObservableDefaultApi } from "./ObservableAPI"; +import { DefaultApiRequestFactory, DefaultApiResponseProcessor} from "../apis/DefaultApi"; + +export interface DefaultApiFilePostRequest { + /** + * + * @type InlineObject + * @memberof DefaultApifilePost + */ + inlineObject?: InlineObject +} + +export interface DefaultApiPetsFilteredPatchRequest { + /** + * + * @type PetByAge | PetByType + * @memberof DefaultApipetsFilteredPatch + */ + petByAgePetByType?: PetByAge | PetByType +} + +export interface DefaultApiPetsPatchRequest { + /** + * + * @type Cat | Dog + * @memberof DefaultApipetsPatch + */ + catDog?: Cat | Dog +} + +export class ObjectDefaultApi { + private api: ObservableDefaultApi + + public constructor(configuration: Configuration, requestFactory?: DefaultApiRequestFactory, responseProcessor?: DefaultApiResponseProcessor) { + this.api = new ObservableDefaultApi(configuration, requestFactory, responseProcessor); + } + + /** + * @param param the request object + */ + public filePost(param: DefaultApiFilePostRequest, options?: Configuration): Promise { + return this.api.filePost(param.inlineObject, options).toPromise(); + } + + /** + * @param param the request object + */ + public petsFilteredPatch(param: DefaultApiPetsFilteredPatchRequest, options?: Configuration): Promise { + return this.api.petsFilteredPatch(param.petByAgePetByType, options).toPromise(); + } + + /** + * @param param the request object + */ + public petsPatch(param: DefaultApiPetsPatchRequest, options?: Configuration): Promise { + return this.api.petsPatch(param.catDog, options).toPromise(); + } + +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/types/ObservableAPI.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/types/ObservableAPI.ts new file mode 100644 index 000000000000..f9dd96c51981 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/types/ObservableAPI.ts @@ -0,0 +1,96 @@ +import { ResponseContext, RequestContext, HttpFile } from '../http/http'; +import * as models from '../models/all'; +import { Configuration} from '../configuration' +import { Observable, of, from } from '../rxjsStub'; +import {mergeMap, map} from '../rxjsStub'; +import { Cat } from '../models/Cat'; +import { CatAllOf } from '../models/CatAllOf'; +import { Dog } from '../models/Dog'; +import { DogAllOf } from '../models/DogAllOf'; +import { InlineObject } from '../models/InlineObject'; +import { PetByAge } from '../models/PetByAge'; +import { PetByType } from '../models/PetByType'; + +import { DefaultApiRequestFactory, DefaultApiResponseProcessor} from "../apis/DefaultApi"; +export class ObservableDefaultApi { + private requestFactory: DefaultApiRequestFactory; + private responseProcessor: DefaultApiResponseProcessor; + private configuration: Configuration; + + public constructor( + configuration: Configuration, + requestFactory?: DefaultApiRequestFactory, + responseProcessor?: DefaultApiResponseProcessor + ) { + this.configuration = configuration; + this.requestFactory = requestFactory || new DefaultApiRequestFactory(configuration); + this.responseProcessor = responseProcessor || new DefaultApiResponseProcessor(); + } + + /** + * @param inlineObject + */ + public filePost(inlineObject?: InlineObject, _options?: Configuration): Observable { + const requestContextPromise = this.requestFactory.filePost(inlineObject, _options); + + // build promise chain + let middlewarePreObservable = from(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.filePost(rsp))); + })); + } + + /** + * @param petByAgePetByType + */ + public petsFilteredPatch(petByAgePetByType?: PetByAge | PetByType, _options?: Configuration): Observable { + const requestContextPromise = this.requestFactory.petsFilteredPatch(petByAgePetByType, _options); + + // build promise chain + let middlewarePreObservable = from(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.petsFilteredPatch(rsp))); + })); + } + + /** + * @param catDog + */ + public petsPatch(catDog?: Cat | Dog, _options?: Configuration): Observable { + const requestContextPromise = this.requestFactory.petsPatch(catDog, _options); + + // build promise chain + let middlewarePreObservable = from(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.petsPatch(rsp))); + })); + } + +} diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/types/PromiseAPI.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/types/PromiseAPI.ts new file mode 100644 index 000000000000..4939db8127b3 --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/types/PromiseAPI.ts @@ -0,0 +1,54 @@ +import { ResponseContext, RequestContext, HttpFile } from '../http/http'; +import * as models from '../models/all'; +import { Configuration} from '../configuration' + +import { Cat } from '../models/Cat'; +import { CatAllOf } from '../models/CatAllOf'; +import { Dog } from '../models/Dog'; +import { DogAllOf } from '../models/DogAllOf'; +import { InlineObject } from '../models/InlineObject'; +import { PetByAge } from '../models/PetByAge'; +import { PetByType } from '../models/PetByType'; +import { ObservableDefaultApi } from './ObservableAPI'; + +import { DefaultApiRequestFactory, DefaultApiResponseProcessor} from "../apis/DefaultApi"; +export class PromiseDefaultApi { + private api: ObservableDefaultApi + + public constructor( + configuration: Configuration, + requestFactory?: DefaultApiRequestFactory, + responseProcessor?: DefaultApiResponseProcessor + ) { + this.api = new ObservableDefaultApi(configuration, requestFactory, responseProcessor); + } + + /** + * @param inlineObject + */ + public filePost(inlineObject?: InlineObject, _options?: Configuration): Promise { + const result = this.api.filePost(inlineObject, _options); + return result.toPromise(); + } + + /** + * @param petByAgePetByType + */ + public petsFilteredPatch(petByAgePetByType?: PetByAge | PetByType, _options?: Configuration): Promise { + const result = this.api.petsFilteredPatch(petByAgePetByType, _options); + return result.toPromise(); + } + + /** + * @param catDog + */ + public petsPatch(catDog?: Cat | Dog, _options?: Configuration): Promise { + const result = this.api.petsPatch(catDog, _options); + return result.toPromise(); + } + + +} + + + diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/util.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/util.ts new file mode 100644 index 000000000000..07317f5828bc --- /dev/null +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/util.ts @@ -0,0 +1,28 @@ +/** + * 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; + } +}