[typescript-rxjs] runtime and api cleanup (#3316)

* feat(typescript-rxjs): use interfaces from rxjs/ajax, use shorthands

* feat(typescript-rxjs): regenerate samples

* docs(typescript-rxjs): extend readme by middleware howto

* feat(typescript-rxjs): stop generating empty comment when there is no description in model

* feat(typescript-rxjs): import throwIfRequired and COLLECTION_FORMATS only when needed

* feat(typescript-rxjs): generate HttpHeaders and HttpQuery only if needed, improve formatting

* feat(typescript-rxjs): conditionally import HttpHeaders and HttpQuery

* feat(typescript-rxjs): add encodeURI helper, refactor queryString helper

* feat(typescript-rxjs): improve condition for hasListContainers

* feat(typescript-rxjs): regenerate samples
This commit is contained in:
Bernd Hacker 2019-07-22 11:21:37 +02:00 committed by Esteban Gehring
parent 76fecf744b
commit d2576f411e
47 changed files with 537 additions and 808 deletions

View File

@ -28,6 +28,7 @@ import java.text.SimpleDateFormat;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -162,26 +163,36 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen
} }
private void addNpmPackageGeneration() { private void addNpmPackageGeneration() {
if (additionalProperties.containsKey(NPM_REPOSITORY)) { if (additionalProperties.containsKey(NPM_REPOSITORY)) {
this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString()); this.setNpmRepository(additionalProperties.get(NPM_REPOSITORY).toString());
} }
//Files for building our lib // Files for building our lib
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("package.mustache", "", "package.json")); supportingFiles.add(new SupportingFile("package.mustache", "", "package.json"));
} }
@Override @Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> operations, List<Object> allModels) { public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> operations, List<Object> allModels) {
this.addOperationModelImportInfomation(operations); // Convert List of CodegenOperation to List of ExtendedCodegenOperation
Map<String, Object> _operations = (Map<String, Object>) operations.get("operations");
List<CodegenOperation> os = (List<CodegenOperation>) _operations.get("operation");
List<ExtendedCodegenOperation> newOs = new ArrayList<ExtendedCodegenOperation>();
for (CodegenOperation o : os) {
newOs.add(new ExtendedCodegenOperation(o));
}
_operations.put("operation", newOs);
this.addOperationModelImportInformation(operations);
this.updateOperationParameterEnumInformation(operations); this.updateOperationParameterEnumInformation(operations);
this.addConditionalImportInformation(operations);
return operations; return operations;
} }
private void addOperationModelImportInfomation(Map<String, Object> operations) { private void addOperationModelImportInformation(Map<String, Object> operations) {
// This method will add extra infomation to the operations.imports array. // This method will add extra information to the operations.imports array.
// The api template uses this infomation to import all the required // The api template uses this information to import all the required
// models for a given operation. // models for a given operation.
List<Map<String, Object>> imports = (List<Map<String, Object>>) operations.get("imports"); List<Map<String, Object>> imports = (List<Map<String, Object>>) operations.get("imports");
for (Map<String, Object> im : imports) { for (Map<String, Object> im : imports) {
@ -190,22 +201,79 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen
} }
private void updateOperationParameterEnumInformation(Map<String, Object> operations) { private void updateOperationParameterEnumInformation(Map<String, Object> operations) {
// This method will add extra infomation as to whether or not we have enums and // This method will add extra information as to whether or not we have enums and
// update their names with the operation.id prefixed. // update their names with the operation.id prefixed.
Map<String, Object> _operations = (Map<String, Object>) operations.get("operations"); Map<String, Object> _operations = (Map<String, Object>) operations.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) _operations.get("operation"); List<ExtendedCodegenOperation> operationList = (List<ExtendedCodegenOperation>) _operations.get("operation");
boolean hasEnum = false; boolean hasEnums = false;
for (CodegenOperation op : operationList) { for (ExtendedCodegenOperation op : operationList) {
for (CodegenParameter param : op.allParams) { for (CodegenParameter param : op.allParams) {
if (Boolean.TRUE.equals(param.isEnum)) { if (Boolean.TRUE.equals(param.isEnum)) {
hasEnum = true; hasEnums = true;
param.datatypeWithEnum = param.datatypeWithEnum param.datatypeWithEnum = param.datatypeWithEnum
.replace(param.enumName, op.operationIdCamelCase + param.enumName); .replace(param.enumName, op.operationIdCamelCase + param.enumName);
} }
} }
} }
operations.put("hasEnums", hasEnum); operations.put("hasEnums", hasEnums);
}
private void addConditionalImportInformation(Map<String, Object> operations) {
// This method will determine if there are required parameters and if there are list containers
Map<String, Object> _operations = (Map<String, Object>) operations.get("operations");
List<ExtendedCodegenOperation> operationList = (List<ExtendedCodegenOperation>) _operations.get("operation");
boolean hasRequiredParameters = false;
boolean hasListContainers = false;
boolean hasHttpHeaders = false;
boolean hasQueryParams = false;
boolean hasPathParams = false;
for (ExtendedCodegenOperation op : operationList) {
if (op.getHasRequiredParams()) {
hasRequiredParameters = true;
}
for (CodegenParameter param : op.headerParams) {
if (param.isListContainer) {
hasListContainers = true;
break;
}
}
for (CodegenParameter param : op.queryParams) {
if (param.isListContainer && !param.isCollectionFormatMulti) {
hasListContainers = true;
break;
}
}
for (CodegenParameter param : op.formParams) {
if (param.isListContainer && !param.isCollectionFormatMulti) {
hasListContainers = true;
break;
}
}
if (op.hasHttpHeaders) {
hasHttpHeaders = true;
}
if (op.getHasQueryParams()) {
hasQueryParams = true;
}
if (op.getHasPathParams()) {
hasPathParams = true;
}
if(hasRequiredParameters && hasListContainers && hasHttpHeaders && hasQueryParams && hasPathParams){
break;
}
}
operations.put("hasRequiredParameters", hasRequiredParameters);
operations.put("hasListContainers", hasListContainers);
operations.put("hasHttpHeaders", hasHttpHeaders);
operations.put("hasQueryParams", hasQueryParams);
operations.put("hasPathParams", hasPathParams);
} }
private void addExtraReservedWords() { private void addExtraReservedWords() {
@ -228,4 +296,71 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen
this.reservedWords.add("Middleware"); this.reservedWords.add("Middleware");
this.reservedWords.add("AjaxResponse"); this.reservedWords.add("AjaxResponse");
} }
class ExtendedCodegenOperation extends CodegenOperation {
public boolean hasHttpHeaders;
public ExtendedCodegenOperation(CodegenOperation o) {
super();
// Copy all fields of CodegenOperation
this.responseHeaders.addAll(o.responseHeaders);
this.hasAuthMethods = o.hasAuthMethods;
this.hasConsumes = o.hasConsumes;
this.hasProduces = o.hasProduces;
this.hasParams = o.hasParams;
this.hasOptionalParams = o.hasOptionalParams;
this.returnTypeIsPrimitive = o.returnTypeIsPrimitive;
this.returnSimpleType = o.returnSimpleType;
this.subresourceOperation = o.subresourceOperation;
this.isMapContainer = o.isMapContainer;
this.isListContainer = o.isListContainer;
this.isMultipart = o.isMultipart;
this.hasMore = o.hasMore;
this.isResponseBinary = o.isResponseBinary;
this.hasReference = o.hasReference;
this.isRestfulIndex = o.isRestfulIndex;
this.isRestfulShow = o.isRestfulShow;
this.isRestfulCreate = o.isRestfulCreate;
this.isRestfulUpdate = o.isRestfulUpdate;
this.isRestfulDestroy = o.isRestfulDestroy;
this.isRestful = o.isRestful;
this.path = o.path;
this.operationId = o.operationId;
this.returnType = o.returnType;
this.httpMethod = o.httpMethod;
this.returnBaseType = o.returnBaseType;
this.returnContainer = o.returnContainer;
this.summary = o.summary;
this.unescapedNotes = o.unescapedNotes;
this.notes = o.notes;
this.baseName = o.baseName;
this.defaultResponse = o.defaultResponse;
this.discriminator = o.discriminator;
this.consumes = o.consumes;
this.produces = o.produces;
this.bodyParam = o.bodyParam;
this.allParams = o.allParams;
this.bodyParams = o.bodyParams;
this.pathParams = o.pathParams;
this.queryParams = o.queryParams;
this.headerParams = o.headerParams;
this.formParams = o.formParams;
this.requiredParams = o.requiredParams;
this.optionalParams = o.optionalParams;
this.authMethods = o.authMethods;
this.tags = o.tags;
this.responses = o.responses;
this.imports = o.imports;
this.examples = o.examples;
this.externalDocs = o.externalDocs;
this.vendorExtensions = o.vendorExtensions;
this.nickname = o.nickname;
this.operationIdLowerCase = o.operationIdLowerCase;
this.operationIdCamelCase = o.operationIdCamelCase;
// new fields
this.hasHttpHeaders = o.getHasHeaderParams() || o.getHasBodyParam() || o.hasAuthMethods;
}
}
} }

View File

@ -27,7 +27,7 @@ npm run build
### Publishing ### Publishing
First build the package then run ```npm publish``` First build the package then run `npm publish`
### Consuming ### Consuming
@ -43,3 +43,45 @@ _unPublished (not recommended):_
``` ```
npm install PATH_TO_GENERATED_PACKAGE --save npm install PATH_TO_GENERATED_PACKAGE --save
```
### How to apply middleware
First, add a singleton class that extends the generated `Configuration` class.
```
export class AuthInterceptor extends Configuration {
private static config: AuthInterceptor;
private constructor() {
const middleware: Middleware[] = [
{
pre(request: RequestArgs): RequestArgs {
const token = getAuthToken();
return {
...request,
headers: {
...request.headers,
Authorization: `Bearer ${token}`,
},
};
},
},
];
super({ middleware });
}
public static get Instance() {
return AuthInterceptor.config || (AuthInterceptor.config = new this());
}
}
```
Next, pass it to the generated api controller.
```
const api = new StoreApi(AuthInterceptor.Instance);
```

View File

@ -1,7 +1,7 @@
// tslint:disable // tslint:disable
{{>licenseInfo}} {{>licenseInfo}}
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI{{#hasHttpHeaders}}, HttpHeaders{{/hasHttpHeaders}}{{#hasQueryParams}}, HttpQuery{{/hasQueryParams}}{{#hasRequiredParameters}}, throwIfRequired{{/hasRequiredParameters}}{{#hasPathParams}}, encodeURI{{/hasPathParams}}{{#hasListContainers}}, COLLECTION_FORMATS{{/hasListContainers}} } from '../runtime';
{{#imports.0}} {{#imports.0}}
import { import {
{{#imports}} {{#imports}}
@ -38,12 +38,15 @@ export class {{classname}} extends BaseAPI {
{{/summary}} {{/summary}}
*/ */
{{nickname}} = ({{#allParams.0}}requestParameters: {{operationIdCamelCase}}Request{{/allParams.0}}): Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> => { {{nickname}} = ({{#allParams.0}}requestParameters: {{operationIdCamelCase}}Request{{/allParams.0}}): Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> => {
{{#hasParams}}
{{#allParams}} {{#allParams}}
{{#required}} {{#required}}
throwIfRequired(requestParameters, '{{paramName}}', '{{nickname}}'); throwIfRequired(requestParameters, '{{paramName}}', '{{nickname}}');
{{/required}} {{/required}}
{{/allParams}} {{/allParams}}
{{/hasParams}}
{{#hasHttpHeaders}}
const headers: HttpHeaders = { const headers: HttpHeaders = {
{{#bodyParam}} {{#bodyParam}}
{{^consumes}} {{^consumes}}
@ -81,6 +84,8 @@ export class {{classname}} extends BaseAPI {
{{/authMethods}} {{/authMethods}}
}; };
{{/hasHttpHeaders}}
{{#hasQueryParams}}
const query: HttpQuery = { const query: HttpQuery = {
{{#queryParams}} {{#queryParams}}
{{#isListContainer}} {{#isListContainer}}
@ -114,6 +119,7 @@ export class {{classname}} extends BaseAPI {
{{/authMethods}} {{/authMethods}}
}; };
{{/hasQueryParams}}
{{#hasFormParams}} {{#hasFormParams}}
const formData = new FormData(); const formData = new FormData();
{{/hasFormParams}} {{/hasFormParams}}
@ -139,10 +145,14 @@ export class {{classname}} extends BaseAPI {
{{/isListContainer}} {{/isListContainer}}
{{/formParams}} {{/formParams}}
return this.request<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}>({ return this.request<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}>({
path: `{{{path}}}`{{#pathParams}}.replace({{=<% %>=}}`{<%baseName%>}`<%={{ }}=%>, encodeURIComponent(String(requestParameters.{{paramName}}))){{/pathParams}}, path: '{{{path}}}'{{#pathParams}}.replace({{=<% %>=}}'{<%baseName%>}'<%={{ }}=%>, encodeURI(requestParameters.{{paramName}})){{/pathParams}},
method: '{{httpMethod}}', method: '{{httpMethod}}',
{{#hasHttpHeaders}}
headers, headers,
{{/hasHttpHeaders}}
{{#hasQueryParams}}
query, query,
{{/hasQueryParams}}
{{#hasBodyParam}} {{#hasBodyParam}}
{{#bodyParam}} {{#bodyParam}}
{{#isContainer}} {{#isContainer}}

View File

@ -16,8 +16,8 @@ export interface {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
[key: string]: {{{additionalPropertiesType}}}{{#hasVars}} | any{{/hasVars}}; [key: string]: {{{additionalPropertiesType}}}{{#hasVars}} | any{{/hasVars}};
{{/additionalPropertiesType}} {{/additionalPropertiesType}}
{{#vars}} {{#vars}}
/** /**{{#description}}
* {{{description}}} * {{{description}}}{{/description}}
* @type {{=<% %>=}}{<%&datatype%>}<%={{ }}=%> * @type {{=<% %>=}}{<%&datatype%>}<%={{ }}=%>
* @memberof {{classname}} * @memberof {{classname}}
*/ */

View File

@ -1,7 +1,7 @@
// tslint:disable // tslint:disable
{{>licenseInfo}} {{>licenseInfo}}
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { ajax, AjaxResponse } from 'rxjs/ajax'; import { ajax, AjaxRequest, AjaxResponse } from 'rxjs/ajax';
import { map, concatMap } from 'rxjs/operators'; import { map, concatMap } from 'rxjs/operators';
export const BASE_PATH = '{{{basePath}}}'.replace(/\/+$/, ''); export const BASE_PATH = '{{{basePath}}}'.replace(/\/+$/, '');
@ -73,8 +73,8 @@ export class BaseAPI {
withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) => withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) =>
this.withMiddleware<T>(postMiddlewares.map((post) => ({ post }))); this.withMiddleware<T>(postMiddlewares.map((post) => ({ post })));
protected request = <T>(context: RequestOpts): Observable<T> => protected request = <T>(requestOpts: RequestOpts): Observable<T> =>
this.rxjsRequest(this.createRequestArgs(context)).pipe( this.rxjsRequest(this.createRequestArgs(requestOpts)).pipe(
map((res) => { map((res) => {
if (res.status >= 200 && res.status < 300) { if (res.status >= 200 && res.status < 300) {
return res.response as T; return res.response as T;
@ -83,46 +83,38 @@ export class BaseAPI {
}) })
); );
private createRequestArgs = (context: RequestOpts): RequestArgs => { private createRequestArgs = (requestOpts: RequestOpts): RequestArgs => {
let url = this.configuration.basePath + context.path; let url = this.configuration.basePath + requestOpts.path;
if (context.query !== undefined && Object.keys(context.query).length !== 0) { if (requestOpts.query !== undefined && Object.keys(requestOpts.query).length !== 0) {
// only add the queryString to the URL if there are query parameters. // only add the queryString to the URL if there are query parameters.
// this is done to avoid urls ending with a '?' character which buggy webservers // this is done to avoid urls ending with a '?' character which buggy webservers
// do not handle correctly sometimes. // do not handle correctly sometimes.
url += '?' + queryString(context.query); url += '?' + queryString(requestOpts.query);
} }
const body = context.body instanceof FormData ? context.body : JSON.stringify(context.body);
const options = { return {
method: context.method, url,
headers: context.headers, method: requestOpts.method,
body, headers: requestOpts.headers,
body: requestOpts.body instanceof FormData ? requestOpts.body : JSON.stringify(requestOpts.body),
}; };
return { url, options };
} }
private rxjsRequest = (params: RequestContext): Observable<AjaxResponse> => { private rxjsRequest = (params: RequestArgs): Observable<AjaxResponse> =>
const preMiddlewares = this.middleware.filter((item) => item.pre); of(params).pipe(
const postMiddlewares = this.middleware.filter((item) => item.post); map((request) => {
this.middleware.filter((item) => item.pre).forEach((mw) => (request = mw.pre!(request)));
return of(params).pipe( return request;
map((args) => {
if (preMiddlewares) {
preMiddlewares.forEach((mw) => (args = mw.pre!({ ...args })));
}
return args;
}), }),
concatMap((args) => concatMap((args) =>
ajax({ url: args.url, ...args.options }).pipe( ajax(args).pipe(
map((response) => { map((response) => {
if (postMiddlewares) { this.middleware.filter((item) => item.post).forEach((mw) => (response = mw.post!(response)));
postMiddlewares.forEach((mw) => (response = mw.post!({ ...params, response })));
}
return response; return response;
}) })
) )
) )
); );
}
/** /**
* Create a shallow clone of `this` by constructing a new instance * Create a shallow clone of `this` by constructing a new instance
@ -151,27 +143,22 @@ export type HttpQuery = { [key: string]: string | number | null | boolean | Arra
export type HttpBody = Json | FormData; export type HttpBody = Json | FormData;
export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original';
export interface RequestArgs {
url: string;
options: RequestInit;
}
export interface RequestOpts { export interface RequestOpts {
path: string; path: string;
method: HttpMethod; method: HttpMethod;
headers: HttpHeaders; headers?: HttpHeaders;
query?: HttpQuery; query?: HttpQuery;
body?: HttpBody; body?: HttpBody;
} }
export const encodeURI = (value: any) => encodeURIComponent(String(value))
const queryString = (params: HttpQuery): string => Object.keys(params) const queryString = (params: HttpQuery): string => Object.keys(params)
.map((key) => { .map((key) => {
const value = params[key]; const value = params[key];
if (value instanceof Array) { return (value instanceof Array)
return value.map((val) => `${encodeURIComponent(key)}=${encodeURIComponent(String(val))}`) ? value.map((val) => `${encodeURI(key)}=${encodeURI(val)}`).join('&')
.join('&'); : `${encodeURI(key)}=${encodeURI(value)}`;
}
return `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`;
}) })
.join('&'); .join('&');
@ -184,12 +171,11 @@ export const throwIfRequired = (params: {[key: string]: any}, key: string, nickn
} }
} }
export interface RequestContext extends RequestArgs {} // alias for easier importing
export interface ResponseContext extends RequestArgs { export interface RequestArgs extends AjaxRequest {}
response: AjaxResponse; export interface ResponseArgs extends AjaxResponse {}
}
export interface Middleware { export interface Middleware {
pre?(context: RequestContext): RequestArgs; pre?(request: RequestArgs): RequestArgs;
post?(context: ResponseContext): AjaxResponse; post?(response: ResponseArgs): ResponseArgs;
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, HttpQuery, throwIfRequired, encodeURI, COLLECTION_FORMATS } from '../runtime';
import { import {
ApiResponse, ApiResponse,
Pet, Pet,
@ -76,14 +76,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet`, path: '/pet',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -104,14 +100,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'DELETE', method: 'DELETE',
headers, headers,
query,
}); });
} }
@ -136,7 +128,7 @@ export class PetApi extends BaseAPI {
}; };
return this.request<Array<Pet>>({ return this.request<Array<Pet>>({
path: `/pet/findByStatus`, path: '/pet/findByStatus',
method: 'GET', method: 'GET',
headers, headers,
query, query,
@ -164,7 +156,7 @@ export class PetApi extends BaseAPI {
}; };
return this.request<Array<Pet>>({ return this.request<Array<Pet>>({
path: `/pet/findByTags`, path: '/pet/findByTags',
method: 'GET', method: 'GET',
headers, headers,
query, query,
@ -182,14 +174,10 @@ export class PetApi extends BaseAPI {
...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication ...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication
}; };
const query: HttpQuery = {
};
return this.request<Pet>({ return this.request<Pet>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'GET', method: 'GET',
headers, headers,
query,
}); });
} }
@ -209,14 +197,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet`, path: '/pet',
method: 'PUT', method: 'PUT',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -236,9 +220,6 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
const formData = new FormData(); const formData = new FormData();
if (requestParameters.name !== undefined) { if (requestParameters.name !== undefined) {
formData.append('name', requestParameters.name as any); formData.append('name', requestParameters.name as any);
@ -249,10 +230,9 @@ export class PetApi extends BaseAPI {
} }
return this.request<void>({ return this.request<void>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'POST', method: 'POST',
headers, headers,
query,
body: formData, body: formData,
}); });
} }
@ -272,9 +252,6 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
const formData = new FormData(); const formData = new FormData();
if (requestParameters.additionalMetadata !== undefined) { if (requestParameters.additionalMetadata !== undefined) {
formData.append('additionalMetadata', requestParameters.additionalMetadata as any); formData.append('additionalMetadata', requestParameters.additionalMetadata as any);
@ -285,10 +262,9 @@ export class PetApi extends BaseAPI {
} }
return this.request<ApiResponse>({ return this.request<ApiResponse>({
path: `/pet/{petId}/uploadImage`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}/uploadImage'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'POST', method: 'POST',
headers, headers,
query,
body: formData, body: formData,
}); });
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, throwIfRequired, encodeURI } from '../runtime';
import { import {
Order, Order,
} from '../models'; } from '../models';
@ -41,17 +41,9 @@ export class StoreApi extends BaseAPI {
deleteOrder = (requestParameters: DeleteOrderRequest): Observable<void> => { deleteOrder = (requestParameters: DeleteOrderRequest): Observable<void> => {
throwIfRequired(requestParameters, 'orderId', 'deleteOrder'); throwIfRequired(requestParameters, 'orderId', 'deleteOrder');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/store/order/{orderId}`.replace(`{orderId}`, encodeURIComponent(String(requestParameters.orderId))), path: '/store/order/{orderId}'.replace('{orderId}', encodeURI(requestParameters.orderId)),
method: 'DELETE', method: 'DELETE',
headers,
query,
}); });
} }
@ -60,19 +52,14 @@ export class StoreApi extends BaseAPI {
* Returns pet inventories by status * Returns pet inventories by status
*/ */
getInventory = (): Observable<{ [key: string]: number; }> => { getInventory = (): Observable<{ [key: string]: number; }> => {
const headers: HttpHeaders = { const headers: HttpHeaders = {
...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication ...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication
}; };
const query: HttpQuery = {
};
return this.request<{ [key: string]: number; }>({ return this.request<{ [key: string]: number; }>({
path: `/store/inventory`, path: '/store/inventory',
method: 'GET', method: 'GET',
headers, headers,
query,
}); });
} }
@ -83,17 +70,9 @@ export class StoreApi extends BaseAPI {
getOrderById = (requestParameters: GetOrderByIdRequest): Observable<Order> => { getOrderById = (requestParameters: GetOrderByIdRequest): Observable<Order> => {
throwIfRequired(requestParameters, 'orderId', 'getOrderById'); throwIfRequired(requestParameters, 'orderId', 'getOrderById');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<Order>({ return this.request<Order>({
path: `/store/order/{orderId}`.replace(`{orderId}`, encodeURIComponent(String(requestParameters.orderId))), path: '/store/order/{orderId}'.replace('{orderId}', encodeURI(requestParameters.orderId)),
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -107,14 +86,10 @@ export class StoreApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<Order>({ return this.request<Order>({
path: `/store/order`, path: '/store/order',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, HttpQuery, throwIfRequired, encodeURI } from '../runtime';
import { import {
User, User,
} from '../models'; } from '../models';
@ -63,14 +63,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user`, path: '/user',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -85,14 +81,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/createWithArray`, path: '/user/createWithArray',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -107,14 +99,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/createWithList`, path: '/user/createWithList',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -126,17 +114,9 @@ export class UserApi extends BaseAPI {
deleteUser = (requestParameters: DeleteUserRequest): Observable<void> => { deleteUser = (requestParameters: DeleteUserRequest): Observable<void> => {
throwIfRequired(requestParameters, 'username', 'deleteUser'); throwIfRequired(requestParameters, 'username', 'deleteUser');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'DELETE', method: 'DELETE',
headers,
query,
}); });
} }
@ -146,17 +126,9 @@ export class UserApi extends BaseAPI {
getUserByName = (requestParameters: GetUserByNameRequest): Observable<User> => { getUserByName = (requestParameters: GetUserByNameRequest): Observable<User> => {
throwIfRequired(requestParameters, 'username', 'getUserByName'); throwIfRequired(requestParameters, 'username', 'getUserByName');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<User>({ return this.request<User>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -167,18 +139,14 @@ export class UserApi extends BaseAPI {
throwIfRequired(requestParameters, 'username', 'loginUser'); throwIfRequired(requestParameters, 'username', 'loginUser');
throwIfRequired(requestParameters, 'password', 'loginUser'); throwIfRequired(requestParameters, 'password', 'loginUser');
const headers: HttpHeaders = {
};
const query: HttpQuery = { const query: HttpQuery = {
...(requestParameters.username && { 'username': requestParameters.username }), ...(requestParameters.username && { 'username': requestParameters.username }),
...(requestParameters.password && { 'password': requestParameters.password }), ...(requestParameters.password && { 'password': requestParameters.password }),
}; };
return this.request<string>({ return this.request<string>({
path: `/user/login`, path: '/user/login',
method: 'GET', method: 'GET',
headers,
query, query,
}); });
} }
@ -187,18 +155,9 @@ export class UserApi extends BaseAPI {
* Logs out current logged in user session * Logs out current logged in user session
*/ */
logoutUser = (): Observable<void> => { logoutUser = (): Observable<void> => {
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/logout`, path: '/user/logout',
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -214,14 +173,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'PUT', method: 'PUT',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }

View File

@ -18,19 +18,16 @@
*/ */
export interface ApiResponse { export interface ApiResponse {
/** /**
*
* @type {number} * @type {number}
* @memberof ApiResponse * @memberof ApiResponse
*/ */
code?: number; code?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof ApiResponse * @memberof ApiResponse
*/ */
type?: string; type?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof ApiResponse * @memberof ApiResponse
*/ */

View File

@ -18,13 +18,11 @@
*/ */
export interface Category { export interface Category {
/** /**
*
* @type {number} * @type {number}
* @memberof Category * @memberof Category
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof Category * @memberof Category
*/ */

View File

@ -18,25 +18,21 @@
*/ */
export interface Order { export interface Order {
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
id?: number; id?: number;
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
petId?: number; petId?: number;
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
quantity?: number; quantity?: number;
/** /**
*
* @type {Date} * @type {Date}
* @memberof Order * @memberof Order
*/ */
@ -48,7 +44,6 @@ export interface Order {
*/ */
status?: OrderStatusEnum; status?: OrderStatusEnum;
/** /**
*
* @type {boolean} * @type {boolean}
* @memberof Order * @memberof Order
*/ */

View File

@ -23,31 +23,26 @@ import {
*/ */
export interface Pet { export interface Pet {
/** /**
*
* @type {number} * @type {number}
* @memberof Pet * @memberof Pet
*/ */
id?: number; id?: number;
/** /**
*
* @type {Category} * @type {Category}
* @memberof Pet * @memberof Pet
*/ */
category?: Category; category?: Category;
/** /**
*
* @type {string} * @type {string}
* @memberof Pet * @memberof Pet
*/ */
name: string; name: string;
/** /**
*
* @type {Array<string>} * @type {Array<string>}
* @memberof Pet * @memberof Pet
*/ */
photoUrls: Array<string>; photoUrls: Array<string>;
/** /**
*
* @type {Array<Tag>} * @type {Array<Tag>}
* @memberof Pet * @memberof Pet
*/ */

View File

@ -18,13 +18,11 @@
*/ */
export interface Tag { export interface Tag {
/** /**
*
* @type {number} * @type {number}
* @memberof Tag * @memberof Tag
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof Tag * @memberof Tag
*/ */

View File

@ -18,43 +18,36 @@
*/ */
export interface User { export interface User {
/** /**
*
* @type {number} * @type {number}
* @memberof User * @memberof User
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
username?: string; username?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
firstName?: string; firstName?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
lastName?: string; lastName?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
email?: string; email?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
password?: string; password?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */

View File

@ -12,7 +12,7 @@
*/ */
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { ajax, AjaxResponse } from 'rxjs/ajax'; import { ajax, AjaxRequest, AjaxResponse } from 'rxjs/ajax';
import { map, concatMap } from 'rxjs/operators'; import { map, concatMap } from 'rxjs/operators';
export const BASE_PATH = 'http://petstore.swagger.io/v2'.replace(/\/+$/, ''); export const BASE_PATH = 'http://petstore.swagger.io/v2'.replace(/\/+$/, '');
@ -84,8 +84,8 @@ export class BaseAPI {
withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) => withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) =>
this.withMiddleware<T>(postMiddlewares.map((post) => ({ post }))); this.withMiddleware<T>(postMiddlewares.map((post) => ({ post })));
protected request = <T>(context: RequestOpts): Observable<T> => protected request = <T>(requestOpts: RequestOpts): Observable<T> =>
this.rxjsRequest(this.createRequestArgs(context)).pipe( this.rxjsRequest(this.createRequestArgs(requestOpts)).pipe(
map((res) => { map((res) => {
if (res.status >= 200 && res.status < 300) { if (res.status >= 200 && res.status < 300) {
return res.response as T; return res.response as T;
@ -94,46 +94,38 @@ export class BaseAPI {
}) })
); );
private createRequestArgs = (context: RequestOpts): RequestArgs => { private createRequestArgs = (requestOpts: RequestOpts): RequestArgs => {
let url = this.configuration.basePath + context.path; let url = this.configuration.basePath + requestOpts.path;
if (context.query !== undefined && Object.keys(context.query).length !== 0) { if (requestOpts.query !== undefined && Object.keys(requestOpts.query).length !== 0) {
// only add the queryString to the URL if there are query parameters. // only add the queryString to the URL if there are query parameters.
// this is done to avoid urls ending with a '?' character which buggy webservers // this is done to avoid urls ending with a '?' character which buggy webservers
// do not handle correctly sometimes. // do not handle correctly sometimes.
url += '?' + queryString(context.query); url += '?' + queryString(requestOpts.query);
} }
const body = context.body instanceof FormData ? context.body : JSON.stringify(context.body);
const options = { return {
method: context.method, url,
headers: context.headers, method: requestOpts.method,
body, headers: requestOpts.headers,
body: requestOpts.body instanceof FormData ? requestOpts.body : JSON.stringify(requestOpts.body),
}; };
return { url, options };
} }
private rxjsRequest = (params: RequestContext): Observable<AjaxResponse> => { private rxjsRequest = (params: RequestArgs): Observable<AjaxResponse> =>
const preMiddlewares = this.middleware.filter((item) => item.pre); of(params).pipe(
const postMiddlewares = this.middleware.filter((item) => item.post); map((request) => {
this.middleware.filter((item) => item.pre).forEach((mw) => (request = mw.pre!(request)));
return of(params).pipe( return request;
map((args) => {
if (preMiddlewares) {
preMiddlewares.forEach((mw) => (args = mw.pre!({ ...args })));
}
return args;
}), }),
concatMap((args) => concatMap((args) =>
ajax({ url: args.url, ...args.options }).pipe( ajax(args).pipe(
map((response) => { map((response) => {
if (postMiddlewares) { this.middleware.filter((item) => item.post).forEach((mw) => (response = mw.post!(response)));
postMiddlewares.forEach((mw) => (response = mw.post!({ ...params, response })));
}
return response; return response;
}) })
) )
) )
); );
}
/** /**
* Create a shallow clone of `this` by constructing a new instance * Create a shallow clone of `this` by constructing a new instance
@ -162,27 +154,22 @@ export type HttpQuery = { [key: string]: string | number | null | boolean | Arra
export type HttpBody = Json | FormData; export type HttpBody = Json | FormData;
export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original';
export interface RequestArgs {
url: string;
options: RequestInit;
}
export interface RequestOpts { export interface RequestOpts {
path: string; path: string;
method: HttpMethod; method: HttpMethod;
headers: HttpHeaders; headers?: HttpHeaders;
query?: HttpQuery; query?: HttpQuery;
body?: HttpBody; body?: HttpBody;
} }
export const encodeURI = (value: any) => encodeURIComponent(String(value))
const queryString = (params: HttpQuery): string => Object.keys(params) const queryString = (params: HttpQuery): string => Object.keys(params)
.map((key) => { .map((key) => {
const value = params[key]; const value = params[key];
if (value instanceof Array) { return (value instanceof Array)
return value.map((val) => `${encodeURIComponent(key)}=${encodeURIComponent(String(val))}`) ? value.map((val) => `${encodeURI(key)}=${encodeURI(val)}`).join('&')
.join('&'); : `${encodeURI(key)}=${encodeURI(value)}`;
}
return `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`;
}) })
.join('&'); .join('&');
@ -195,12 +182,11 @@ export const throwIfRequired = (params: {[key: string]: any}, key: string, nickn
} }
} }
export interface RequestContext extends RequestArgs {} // alias for easier importing
export interface ResponseContext extends RequestArgs { export interface RequestArgs extends AjaxRequest {}
response: AjaxResponse; export interface ResponseArgs extends AjaxResponse {}
}
export interface Middleware { export interface Middleware {
pre?(context: RequestContext): RequestArgs; pre?(request: RequestArgs): RequestArgs;
post?(context: ResponseContext): AjaxResponse; post?(response: ResponseArgs): ResponseArgs;
} }

View File

@ -27,7 +27,7 @@ npm run build
### Publishing ### Publishing
First build the package then run ```npm publish``` First build the package then run `npm publish`
### Consuming ### Consuming
@ -43,3 +43,45 @@ _unPublished (not recommended):_
``` ```
npm install PATH_TO_GENERATED_PACKAGE --save npm install PATH_TO_GENERATED_PACKAGE --save
```
### How to apply middleware
First, add a singleton class that extends the generated `Configuration` class.
```
export class AuthInterceptor extends Configuration {
private static config: AuthInterceptor;
private constructor() {
const middleware: Middleware[] = [
{
pre(request: RequestArgs): RequestArgs {
const token = getAuthToken();
return {
...request,
headers: {
...request.headers,
Authorization: `Bearer ${token}`,
},
};
},
},
];
super({ middleware });
}
public static get Instance() {
return AuthInterceptor.config || (AuthInterceptor.config = new this());
}
}
```
Next, pass it to the generated api controller.
```
const api = new StoreApi(AuthInterceptor.Instance);
```

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, HttpQuery, throwIfRequired, encodeURI, COLLECTION_FORMATS } from '../runtime';
import { import {
ApiResponse, ApiResponse,
Pet, Pet,
@ -76,14 +76,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet`, path: '/pet',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -104,14 +100,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'DELETE', method: 'DELETE',
headers, headers,
query,
}); });
} }
@ -136,7 +128,7 @@ export class PetApi extends BaseAPI {
}; };
return this.request<Array<Pet>>({ return this.request<Array<Pet>>({
path: `/pet/findByStatus`, path: '/pet/findByStatus',
method: 'GET', method: 'GET',
headers, headers,
query, query,
@ -164,7 +156,7 @@ export class PetApi extends BaseAPI {
}; };
return this.request<Array<Pet>>({ return this.request<Array<Pet>>({
path: `/pet/findByTags`, path: '/pet/findByTags',
method: 'GET', method: 'GET',
headers, headers,
query, query,
@ -182,14 +174,10 @@ export class PetApi extends BaseAPI {
...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication ...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication
}; };
const query: HttpQuery = {
};
return this.request<Pet>({ return this.request<Pet>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'GET', method: 'GET',
headers, headers,
query,
}); });
} }
@ -209,14 +197,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet`, path: '/pet',
method: 'PUT', method: 'PUT',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -236,9 +220,6 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
const formData = new FormData(); const formData = new FormData();
if (requestParameters.name !== undefined) { if (requestParameters.name !== undefined) {
formData.append('name', requestParameters.name as any); formData.append('name', requestParameters.name as any);
@ -249,10 +230,9 @@ export class PetApi extends BaseAPI {
} }
return this.request<void>({ return this.request<void>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'POST', method: 'POST',
headers, headers,
query,
body: formData, body: formData,
}); });
} }
@ -272,9 +252,6 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
const formData = new FormData(); const formData = new FormData();
if (requestParameters.additionalMetadata !== undefined) { if (requestParameters.additionalMetadata !== undefined) {
formData.append('additionalMetadata', requestParameters.additionalMetadata as any); formData.append('additionalMetadata', requestParameters.additionalMetadata as any);
@ -285,10 +262,9 @@ export class PetApi extends BaseAPI {
} }
return this.request<ApiResponse>({ return this.request<ApiResponse>({
path: `/pet/{petId}/uploadImage`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}/uploadImage'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'POST', method: 'POST',
headers, headers,
query,
body: formData, body: formData,
}); });
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, throwIfRequired, encodeURI } from '../runtime';
import { import {
Order, Order,
} from '../models'; } from '../models';
@ -41,17 +41,9 @@ export class StoreApi extends BaseAPI {
deleteOrder = (requestParameters: DeleteOrderRequest): Observable<void> => { deleteOrder = (requestParameters: DeleteOrderRequest): Observable<void> => {
throwIfRequired(requestParameters, 'orderId', 'deleteOrder'); throwIfRequired(requestParameters, 'orderId', 'deleteOrder');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/store/order/{orderId}`.replace(`{orderId}`, encodeURIComponent(String(requestParameters.orderId))), path: '/store/order/{orderId}'.replace('{orderId}', encodeURI(requestParameters.orderId)),
method: 'DELETE', method: 'DELETE',
headers,
query,
}); });
} }
@ -60,19 +52,14 @@ export class StoreApi extends BaseAPI {
* Returns pet inventories by status * Returns pet inventories by status
*/ */
getInventory = (): Observable<{ [key: string]: number; }> => { getInventory = (): Observable<{ [key: string]: number; }> => {
const headers: HttpHeaders = { const headers: HttpHeaders = {
...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication ...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication
}; };
const query: HttpQuery = {
};
return this.request<{ [key: string]: number; }>({ return this.request<{ [key: string]: number; }>({
path: `/store/inventory`, path: '/store/inventory',
method: 'GET', method: 'GET',
headers, headers,
query,
}); });
} }
@ -83,17 +70,9 @@ export class StoreApi extends BaseAPI {
getOrderById = (requestParameters: GetOrderByIdRequest): Observable<Order> => { getOrderById = (requestParameters: GetOrderByIdRequest): Observable<Order> => {
throwIfRequired(requestParameters, 'orderId', 'getOrderById'); throwIfRequired(requestParameters, 'orderId', 'getOrderById');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<Order>({ return this.request<Order>({
path: `/store/order/{orderId}`.replace(`{orderId}`, encodeURIComponent(String(requestParameters.orderId))), path: '/store/order/{orderId}'.replace('{orderId}', encodeURI(requestParameters.orderId)),
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -107,14 +86,10 @@ export class StoreApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<Order>({ return this.request<Order>({
path: `/store/order`, path: '/store/order',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, HttpQuery, throwIfRequired, encodeURI } from '../runtime';
import { import {
User, User,
} from '../models'; } from '../models';
@ -63,14 +63,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user`, path: '/user',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -85,14 +81,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/createWithArray`, path: '/user/createWithArray',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -107,14 +99,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/createWithList`, path: '/user/createWithList',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -126,17 +114,9 @@ export class UserApi extends BaseAPI {
deleteUser = (requestParameters: DeleteUserRequest): Observable<void> => { deleteUser = (requestParameters: DeleteUserRequest): Observable<void> => {
throwIfRequired(requestParameters, 'username', 'deleteUser'); throwIfRequired(requestParameters, 'username', 'deleteUser');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'DELETE', method: 'DELETE',
headers,
query,
}); });
} }
@ -146,17 +126,9 @@ export class UserApi extends BaseAPI {
getUserByName = (requestParameters: GetUserByNameRequest): Observable<User> => { getUserByName = (requestParameters: GetUserByNameRequest): Observable<User> => {
throwIfRequired(requestParameters, 'username', 'getUserByName'); throwIfRequired(requestParameters, 'username', 'getUserByName');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<User>({ return this.request<User>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -167,18 +139,14 @@ export class UserApi extends BaseAPI {
throwIfRequired(requestParameters, 'username', 'loginUser'); throwIfRequired(requestParameters, 'username', 'loginUser');
throwIfRequired(requestParameters, 'password', 'loginUser'); throwIfRequired(requestParameters, 'password', 'loginUser');
const headers: HttpHeaders = {
};
const query: HttpQuery = { const query: HttpQuery = {
...(requestParameters.username && { 'username': requestParameters.username }), ...(requestParameters.username && { 'username': requestParameters.username }),
...(requestParameters.password && { 'password': requestParameters.password }), ...(requestParameters.password && { 'password': requestParameters.password }),
}; };
return this.request<string>({ return this.request<string>({
path: `/user/login`, path: '/user/login',
method: 'GET', method: 'GET',
headers,
query, query,
}); });
} }
@ -187,18 +155,9 @@ export class UserApi extends BaseAPI {
* Logs out current logged in user session * Logs out current logged in user session
*/ */
logoutUser = (): Observable<void> => { logoutUser = (): Observable<void> => {
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/logout`, path: '/user/logout',
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -214,14 +173,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'PUT', method: 'PUT',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }

View File

@ -18,19 +18,16 @@
*/ */
export interface ApiResponse { export interface ApiResponse {
/** /**
*
* @type {number} * @type {number}
* @memberof ApiResponse * @memberof ApiResponse
*/ */
code?: number; code?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof ApiResponse * @memberof ApiResponse
*/ */
type?: string; type?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof ApiResponse * @memberof ApiResponse
*/ */

View File

@ -18,13 +18,11 @@
*/ */
export interface Category { export interface Category {
/** /**
*
* @type {number} * @type {number}
* @memberof Category * @memberof Category
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof Category * @memberof Category
*/ */

View File

@ -18,25 +18,21 @@
*/ */
export interface Order { export interface Order {
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
id?: number; id?: number;
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
petId?: number; petId?: number;
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
quantity?: number; quantity?: number;
/** /**
*
* @type {Date} * @type {Date}
* @memberof Order * @memberof Order
*/ */
@ -48,7 +44,6 @@ export interface Order {
*/ */
status?: OrderStatusEnum; status?: OrderStatusEnum;
/** /**
*
* @type {boolean} * @type {boolean}
* @memberof Order * @memberof Order
*/ */

View File

@ -23,31 +23,26 @@ import {
*/ */
export interface Pet { export interface Pet {
/** /**
*
* @type {number} * @type {number}
* @memberof Pet * @memberof Pet
*/ */
id?: number; id?: number;
/** /**
*
* @type {Category} * @type {Category}
* @memberof Pet * @memberof Pet
*/ */
category?: Category; category?: Category;
/** /**
*
* @type {string} * @type {string}
* @memberof Pet * @memberof Pet
*/ */
name: string; name: string;
/** /**
*
* @type {Array<string>} * @type {Array<string>}
* @memberof Pet * @memberof Pet
*/ */
photoUrls: Array<string>; photoUrls: Array<string>;
/** /**
*
* @type {Array<Tag>} * @type {Array<Tag>}
* @memberof Pet * @memberof Pet
*/ */

View File

@ -18,13 +18,11 @@
*/ */
export interface Tag { export interface Tag {
/** /**
*
* @type {number} * @type {number}
* @memberof Tag * @memberof Tag
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof Tag * @memberof Tag
*/ */

View File

@ -18,43 +18,36 @@
*/ */
export interface User { export interface User {
/** /**
*
* @type {number} * @type {number}
* @memberof User * @memberof User
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
username?: string; username?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
firstName?: string; firstName?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
lastName?: string; lastName?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
email?: string; email?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
password?: string; password?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */

View File

@ -12,7 +12,7 @@
*/ */
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { ajax, AjaxResponse } from 'rxjs/ajax'; import { ajax, AjaxRequest, AjaxResponse } from 'rxjs/ajax';
import { map, concatMap } from 'rxjs/operators'; import { map, concatMap } from 'rxjs/operators';
export const BASE_PATH = 'http://petstore.swagger.io/v2'.replace(/\/+$/, ''); export const BASE_PATH = 'http://petstore.swagger.io/v2'.replace(/\/+$/, '');
@ -84,8 +84,8 @@ export class BaseAPI {
withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) => withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) =>
this.withMiddleware<T>(postMiddlewares.map((post) => ({ post }))); this.withMiddleware<T>(postMiddlewares.map((post) => ({ post })));
protected request = <T>(context: RequestOpts): Observable<T> => protected request = <T>(requestOpts: RequestOpts): Observable<T> =>
this.rxjsRequest(this.createRequestArgs(context)).pipe( this.rxjsRequest(this.createRequestArgs(requestOpts)).pipe(
map((res) => { map((res) => {
if (res.status >= 200 && res.status < 300) { if (res.status >= 200 && res.status < 300) {
return res.response as T; return res.response as T;
@ -94,46 +94,38 @@ export class BaseAPI {
}) })
); );
private createRequestArgs = (context: RequestOpts): RequestArgs => { private createRequestArgs = (requestOpts: RequestOpts): RequestArgs => {
let url = this.configuration.basePath + context.path; let url = this.configuration.basePath + requestOpts.path;
if (context.query !== undefined && Object.keys(context.query).length !== 0) { if (requestOpts.query !== undefined && Object.keys(requestOpts.query).length !== 0) {
// only add the queryString to the URL if there are query parameters. // only add the queryString to the URL if there are query parameters.
// this is done to avoid urls ending with a '?' character which buggy webservers // this is done to avoid urls ending with a '?' character which buggy webservers
// do not handle correctly sometimes. // do not handle correctly sometimes.
url += '?' + queryString(context.query); url += '?' + queryString(requestOpts.query);
} }
const body = context.body instanceof FormData ? context.body : JSON.stringify(context.body);
const options = { return {
method: context.method, url,
headers: context.headers, method: requestOpts.method,
body, headers: requestOpts.headers,
body: requestOpts.body instanceof FormData ? requestOpts.body : JSON.stringify(requestOpts.body),
}; };
return { url, options };
} }
private rxjsRequest = (params: RequestContext): Observable<AjaxResponse> => { private rxjsRequest = (params: RequestArgs): Observable<AjaxResponse> =>
const preMiddlewares = this.middleware.filter((item) => item.pre); of(params).pipe(
const postMiddlewares = this.middleware.filter((item) => item.post); map((request) => {
this.middleware.filter((item) => item.pre).forEach((mw) => (request = mw.pre!(request)));
return of(params).pipe( return request;
map((args) => {
if (preMiddlewares) {
preMiddlewares.forEach((mw) => (args = mw.pre!({ ...args })));
}
return args;
}), }),
concatMap((args) => concatMap((args) =>
ajax({ url: args.url, ...args.options }).pipe( ajax(args).pipe(
map((response) => { map((response) => {
if (postMiddlewares) { this.middleware.filter((item) => item.post).forEach((mw) => (response = mw.post!(response)));
postMiddlewares.forEach((mw) => (response = mw.post!({ ...params, response })));
}
return response; return response;
}) })
) )
) )
); );
}
/** /**
* Create a shallow clone of `this` by constructing a new instance * Create a shallow clone of `this` by constructing a new instance
@ -162,27 +154,22 @@ export type HttpQuery = { [key: string]: string | number | null | boolean | Arra
export type HttpBody = Json | FormData; export type HttpBody = Json | FormData;
export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original';
export interface RequestArgs {
url: string;
options: RequestInit;
}
export interface RequestOpts { export interface RequestOpts {
path: string; path: string;
method: HttpMethod; method: HttpMethod;
headers: HttpHeaders; headers?: HttpHeaders;
query?: HttpQuery; query?: HttpQuery;
body?: HttpBody; body?: HttpBody;
} }
export const encodeURI = (value: any) => encodeURIComponent(String(value))
const queryString = (params: HttpQuery): string => Object.keys(params) const queryString = (params: HttpQuery): string => Object.keys(params)
.map((key) => { .map((key) => {
const value = params[key]; const value = params[key];
if (value instanceof Array) { return (value instanceof Array)
return value.map((val) => `${encodeURIComponent(key)}=${encodeURIComponent(String(val))}`) ? value.map((val) => `${encodeURI(key)}=${encodeURI(val)}`).join('&')
.join('&'); : `${encodeURI(key)}=${encodeURI(value)}`;
}
return `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`;
}) })
.join('&'); .join('&');
@ -195,12 +182,11 @@ export const throwIfRequired = (params: {[key: string]: any}, key: string, nickn
} }
} }
export interface RequestContext extends RequestArgs {} // alias for easier importing
export interface ResponseContext extends RequestArgs { export interface RequestArgs extends AjaxRequest {}
response: AjaxResponse; export interface ResponseArgs extends AjaxResponse {}
}
export interface Middleware { export interface Middleware {
pre?(context: RequestContext): RequestArgs; pre?(request: RequestArgs): RequestArgs;
post?(context: ResponseContext): AjaxResponse; post?(response: ResponseArgs): ResponseArgs;
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, HttpQuery, throwIfRequired, encodeURI, COLLECTION_FORMATS } from '../runtime';
import { import {
ApiResponse, ApiResponse,
Pet, Pet,
@ -76,14 +76,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet`, path: '/pet',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -104,14 +100,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'DELETE', method: 'DELETE',
headers, headers,
query,
}); });
} }
@ -136,7 +128,7 @@ export class PetApi extends BaseAPI {
}; };
return this.request<Array<Pet>>({ return this.request<Array<Pet>>({
path: `/pet/findByStatus`, path: '/pet/findByStatus',
method: 'GET', method: 'GET',
headers, headers,
query, query,
@ -164,7 +156,7 @@ export class PetApi extends BaseAPI {
}; };
return this.request<Array<Pet>>({ return this.request<Array<Pet>>({
path: `/pet/findByTags`, path: '/pet/findByTags',
method: 'GET', method: 'GET',
headers, headers,
query, query,
@ -182,14 +174,10 @@ export class PetApi extends BaseAPI {
...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication ...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication
}; };
const query: HttpQuery = {
};
return this.request<Pet>({ return this.request<Pet>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'GET', method: 'GET',
headers, headers,
query,
}); });
} }
@ -209,14 +197,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet`, path: '/pet',
method: 'PUT', method: 'PUT',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -236,9 +220,6 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
const formData = new FormData(); const formData = new FormData();
if (requestParameters.name !== undefined) { if (requestParameters.name !== undefined) {
formData.append('name', requestParameters.name as any); formData.append('name', requestParameters.name as any);
@ -249,10 +230,9 @@ export class PetApi extends BaseAPI {
} }
return this.request<void>({ return this.request<void>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'POST', method: 'POST',
headers, headers,
query,
body: formData, body: formData,
}); });
} }
@ -272,9 +252,6 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
const formData = new FormData(); const formData = new FormData();
if (requestParameters.additionalMetadata !== undefined) { if (requestParameters.additionalMetadata !== undefined) {
formData.append('additionalMetadata', requestParameters.additionalMetadata as any); formData.append('additionalMetadata', requestParameters.additionalMetadata as any);
@ -285,10 +262,9 @@ export class PetApi extends BaseAPI {
} }
return this.request<ApiResponse>({ return this.request<ApiResponse>({
path: `/pet/{petId}/uploadImage`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}/uploadImage'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'POST', method: 'POST',
headers, headers,
query,
body: formData, body: formData,
}); });
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, throwIfRequired, encodeURI } from '../runtime';
import { import {
Order, Order,
} from '../models'; } from '../models';
@ -41,17 +41,9 @@ export class StoreApi extends BaseAPI {
deleteOrder = (requestParameters: DeleteOrderRequest): Observable<void> => { deleteOrder = (requestParameters: DeleteOrderRequest): Observable<void> => {
throwIfRequired(requestParameters, 'orderId', 'deleteOrder'); throwIfRequired(requestParameters, 'orderId', 'deleteOrder');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/store/order/{orderId}`.replace(`{orderId}`, encodeURIComponent(String(requestParameters.orderId))), path: '/store/order/{orderId}'.replace('{orderId}', encodeURI(requestParameters.orderId)),
method: 'DELETE', method: 'DELETE',
headers,
query,
}); });
} }
@ -60,19 +52,14 @@ export class StoreApi extends BaseAPI {
* Returns pet inventories by status * Returns pet inventories by status
*/ */
getInventory = (): Observable<{ [key: string]: number; }> => { getInventory = (): Observable<{ [key: string]: number; }> => {
const headers: HttpHeaders = { const headers: HttpHeaders = {
...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication ...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication
}; };
const query: HttpQuery = {
};
return this.request<{ [key: string]: number; }>({ return this.request<{ [key: string]: number; }>({
path: `/store/inventory`, path: '/store/inventory',
method: 'GET', method: 'GET',
headers, headers,
query,
}); });
} }
@ -83,17 +70,9 @@ export class StoreApi extends BaseAPI {
getOrderById = (requestParameters: GetOrderByIdRequest): Observable<Order> => { getOrderById = (requestParameters: GetOrderByIdRequest): Observable<Order> => {
throwIfRequired(requestParameters, 'orderId', 'getOrderById'); throwIfRequired(requestParameters, 'orderId', 'getOrderById');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<Order>({ return this.request<Order>({
path: `/store/order/{orderId}`.replace(`{orderId}`, encodeURIComponent(String(requestParameters.orderId))), path: '/store/order/{orderId}'.replace('{orderId}', encodeURI(requestParameters.orderId)),
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -107,14 +86,10 @@ export class StoreApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<Order>({ return this.request<Order>({
path: `/store/order`, path: '/store/order',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, HttpQuery, throwIfRequired, encodeURI } from '../runtime';
import { import {
User, User,
} from '../models'; } from '../models';
@ -63,14 +63,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user`, path: '/user',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -85,14 +81,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/createWithArray`, path: '/user/createWithArray',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -107,14 +99,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/createWithList`, path: '/user/createWithList',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -126,17 +114,9 @@ export class UserApi extends BaseAPI {
deleteUser = (requestParameters: DeleteUserRequest): Observable<void> => { deleteUser = (requestParameters: DeleteUserRequest): Observable<void> => {
throwIfRequired(requestParameters, 'username', 'deleteUser'); throwIfRequired(requestParameters, 'username', 'deleteUser');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'DELETE', method: 'DELETE',
headers,
query,
}); });
} }
@ -146,17 +126,9 @@ export class UserApi extends BaseAPI {
getUserByName = (requestParameters: GetUserByNameRequest): Observable<User> => { getUserByName = (requestParameters: GetUserByNameRequest): Observable<User> => {
throwIfRequired(requestParameters, 'username', 'getUserByName'); throwIfRequired(requestParameters, 'username', 'getUserByName');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<User>({ return this.request<User>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -167,18 +139,14 @@ export class UserApi extends BaseAPI {
throwIfRequired(requestParameters, 'username', 'loginUser'); throwIfRequired(requestParameters, 'username', 'loginUser');
throwIfRequired(requestParameters, 'password', 'loginUser'); throwIfRequired(requestParameters, 'password', 'loginUser');
const headers: HttpHeaders = {
};
const query: HttpQuery = { const query: HttpQuery = {
...(requestParameters.username && { 'username': requestParameters.username }), ...(requestParameters.username && { 'username': requestParameters.username }),
...(requestParameters.password && { 'password': requestParameters.password }), ...(requestParameters.password && { 'password': requestParameters.password }),
}; };
return this.request<string>({ return this.request<string>({
path: `/user/login`, path: '/user/login',
method: 'GET', method: 'GET',
headers,
query, query,
}); });
} }
@ -187,18 +155,9 @@ export class UserApi extends BaseAPI {
* Logs out current logged in user session * Logs out current logged in user session
*/ */
logoutUser = (): Observable<void> => { logoutUser = (): Observable<void> => {
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/logout`, path: '/user/logout',
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -214,14 +173,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'PUT', method: 'PUT',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }

View File

@ -18,19 +18,16 @@
*/ */
export interface ApiResponse { export interface ApiResponse {
/** /**
*
* @type {number} * @type {number}
* @memberof ApiResponse * @memberof ApiResponse
*/ */
code?: number; code?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof ApiResponse * @memberof ApiResponse
*/ */
type?: string; type?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof ApiResponse * @memberof ApiResponse
*/ */

View File

@ -18,13 +18,11 @@
*/ */
export interface Category { export interface Category {
/** /**
*
* @type {number} * @type {number}
* @memberof Category * @memberof Category
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof Category * @memberof Category
*/ */

View File

@ -18,25 +18,21 @@
*/ */
export interface Order { export interface Order {
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
id?: number; id?: number;
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
petId?: number; petId?: number;
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
quantity?: number; quantity?: number;
/** /**
*
* @type {Date} * @type {Date}
* @memberof Order * @memberof Order
*/ */
@ -48,7 +44,6 @@ export interface Order {
*/ */
status?: OrderStatusEnum; status?: OrderStatusEnum;
/** /**
*
* @type {boolean} * @type {boolean}
* @memberof Order * @memberof Order
*/ */

View File

@ -23,31 +23,26 @@ import {
*/ */
export interface Pet { export interface Pet {
/** /**
*
* @type {number} * @type {number}
* @memberof Pet * @memberof Pet
*/ */
id?: number; id?: number;
/** /**
*
* @type {Category} * @type {Category}
* @memberof Pet * @memberof Pet
*/ */
category?: Category; category?: Category;
/** /**
*
* @type {string} * @type {string}
* @memberof Pet * @memberof Pet
*/ */
name: string; name: string;
/** /**
*
* @type {Array<string>} * @type {Array<string>}
* @memberof Pet * @memberof Pet
*/ */
photoUrls: Array<string>; photoUrls: Array<string>;
/** /**
*
* @type {Array<Tag>} * @type {Array<Tag>}
* @memberof Pet * @memberof Pet
*/ */

View File

@ -18,13 +18,11 @@
*/ */
export interface Tag { export interface Tag {
/** /**
*
* @type {number} * @type {number}
* @memberof Tag * @memberof Tag
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof Tag * @memberof Tag
*/ */

View File

@ -18,43 +18,36 @@
*/ */
export interface User { export interface User {
/** /**
*
* @type {number} * @type {number}
* @memberof User * @memberof User
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
username?: string; username?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
firstName?: string; firstName?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
lastName?: string; lastName?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
email?: string; email?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
password?: string; password?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */

View File

@ -12,7 +12,7 @@
*/ */
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { ajax, AjaxResponse } from 'rxjs/ajax'; import { ajax, AjaxRequest, AjaxResponse } from 'rxjs/ajax';
import { map, concatMap } from 'rxjs/operators'; import { map, concatMap } from 'rxjs/operators';
export const BASE_PATH = 'http://petstore.swagger.io/v2'.replace(/\/+$/, ''); export const BASE_PATH = 'http://petstore.swagger.io/v2'.replace(/\/+$/, '');
@ -84,8 +84,8 @@ export class BaseAPI {
withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) => withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) =>
this.withMiddleware<T>(postMiddlewares.map((post) => ({ post }))); this.withMiddleware<T>(postMiddlewares.map((post) => ({ post })));
protected request = <T>(context: RequestOpts): Observable<T> => protected request = <T>(requestOpts: RequestOpts): Observable<T> =>
this.rxjsRequest(this.createRequestArgs(context)).pipe( this.rxjsRequest(this.createRequestArgs(requestOpts)).pipe(
map((res) => { map((res) => {
if (res.status >= 200 && res.status < 300) { if (res.status >= 200 && res.status < 300) {
return res.response as T; return res.response as T;
@ -94,46 +94,38 @@ export class BaseAPI {
}) })
); );
private createRequestArgs = (context: RequestOpts): RequestArgs => { private createRequestArgs = (requestOpts: RequestOpts): RequestArgs => {
let url = this.configuration.basePath + context.path; let url = this.configuration.basePath + requestOpts.path;
if (context.query !== undefined && Object.keys(context.query).length !== 0) { if (requestOpts.query !== undefined && Object.keys(requestOpts.query).length !== 0) {
// only add the queryString to the URL if there are query parameters. // only add the queryString to the URL if there are query parameters.
// this is done to avoid urls ending with a '?' character which buggy webservers // this is done to avoid urls ending with a '?' character which buggy webservers
// do not handle correctly sometimes. // do not handle correctly sometimes.
url += '?' + queryString(context.query); url += '?' + queryString(requestOpts.query);
} }
const body = context.body instanceof FormData ? context.body : JSON.stringify(context.body);
const options = { return {
method: context.method, url,
headers: context.headers, method: requestOpts.method,
body, headers: requestOpts.headers,
body: requestOpts.body instanceof FormData ? requestOpts.body : JSON.stringify(requestOpts.body),
}; };
return { url, options };
} }
private rxjsRequest = (params: RequestContext): Observable<AjaxResponse> => { private rxjsRequest = (params: RequestArgs): Observable<AjaxResponse> =>
const preMiddlewares = this.middleware.filter((item) => item.pre); of(params).pipe(
const postMiddlewares = this.middleware.filter((item) => item.post); map((request) => {
this.middleware.filter((item) => item.pre).forEach((mw) => (request = mw.pre!(request)));
return of(params).pipe( return request;
map((args) => {
if (preMiddlewares) {
preMiddlewares.forEach((mw) => (args = mw.pre!({ ...args })));
}
return args;
}), }),
concatMap((args) => concatMap((args) =>
ajax({ url: args.url, ...args.options }).pipe( ajax(args).pipe(
map((response) => { map((response) => {
if (postMiddlewares) { this.middleware.filter((item) => item.post).forEach((mw) => (response = mw.post!(response)));
postMiddlewares.forEach((mw) => (response = mw.post!({ ...params, response })));
}
return response; return response;
}) })
) )
) )
); );
}
/** /**
* Create a shallow clone of `this` by constructing a new instance * Create a shallow clone of `this` by constructing a new instance
@ -162,27 +154,22 @@ export type HttpQuery = { [key: string]: string | number | null | boolean | Arra
export type HttpBody = Json | FormData; export type HttpBody = Json | FormData;
export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original';
export interface RequestArgs {
url: string;
options: RequestInit;
}
export interface RequestOpts { export interface RequestOpts {
path: string; path: string;
method: HttpMethod; method: HttpMethod;
headers: HttpHeaders; headers?: HttpHeaders;
query?: HttpQuery; query?: HttpQuery;
body?: HttpBody; body?: HttpBody;
} }
export const encodeURI = (value: any) => encodeURIComponent(String(value))
const queryString = (params: HttpQuery): string => Object.keys(params) const queryString = (params: HttpQuery): string => Object.keys(params)
.map((key) => { .map((key) => {
const value = params[key]; const value = params[key];
if (value instanceof Array) { return (value instanceof Array)
return value.map((val) => `${encodeURIComponent(key)}=${encodeURIComponent(String(val))}`) ? value.map((val) => `${encodeURI(key)}=${encodeURI(val)}`).join('&')
.join('&'); : `${encodeURI(key)}=${encodeURI(value)}`;
}
return `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`;
}) })
.join('&'); .join('&');
@ -195,12 +182,11 @@ export const throwIfRequired = (params: {[key: string]: any}, key: string, nickn
} }
} }
export interface RequestContext extends RequestArgs {} // alias for easier importing
export interface ResponseContext extends RequestArgs { export interface RequestArgs extends AjaxRequest {}
response: AjaxResponse; export interface ResponseArgs extends AjaxResponse {}
}
export interface Middleware { export interface Middleware {
pre?(context: RequestContext): RequestArgs; pre?(request: RequestArgs): RequestArgs;
post?(context: ResponseContext): AjaxResponse; post?(response: ResponseArgs): ResponseArgs;
} }

View File

@ -27,7 +27,7 @@ npm run build
### Publishing ### Publishing
First build the package then run ```npm publish``` First build the package then run `npm publish`
### Consuming ### Consuming
@ -43,3 +43,45 @@ _unPublished (not recommended):_
``` ```
npm install PATH_TO_GENERATED_PACKAGE --save npm install PATH_TO_GENERATED_PACKAGE --save
```
### How to apply middleware
First, add a singleton class that extends the generated `Configuration` class.
```
export class AuthInterceptor extends Configuration {
private static config: AuthInterceptor;
private constructor() {
const middleware: Middleware[] = [
{
pre(request: RequestArgs): RequestArgs {
const token = getAuthToken();
return {
...request,
headers: {
...request.headers,
Authorization: `Bearer ${token}`,
},
};
},
},
];
super({ middleware });
}
public static get Instance() {
return AuthInterceptor.config || (AuthInterceptor.config = new this());
}
}
```
Next, pass it to the generated api controller.
```
const api = new StoreApi(AuthInterceptor.Instance);
```

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, HttpQuery, throwIfRequired, encodeURI, COLLECTION_FORMATS } from '../runtime';
import { import {
ApiResponse, ApiResponse,
Pet, Pet,
@ -76,14 +76,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet`, path: '/pet',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -104,14 +100,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'DELETE', method: 'DELETE',
headers, headers,
query,
}); });
} }
@ -136,7 +128,7 @@ export class PetApi extends BaseAPI {
}; };
return this.request<Array<Pet>>({ return this.request<Array<Pet>>({
path: `/pet/findByStatus`, path: '/pet/findByStatus',
method: 'GET', method: 'GET',
headers, headers,
query, query,
@ -164,7 +156,7 @@ export class PetApi extends BaseAPI {
}; };
return this.request<Array<Pet>>({ return this.request<Array<Pet>>({
path: `/pet/findByTags`, path: '/pet/findByTags',
method: 'GET', method: 'GET',
headers, headers,
query, query,
@ -182,14 +174,10 @@ export class PetApi extends BaseAPI {
...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication ...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication
}; };
const query: HttpQuery = {
};
return this.request<Pet>({ return this.request<Pet>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'GET', method: 'GET',
headers, headers,
query,
}); });
} }
@ -209,14 +197,10 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/pet`, path: '/pet',
method: 'PUT', method: 'PUT',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -236,9 +220,6 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
const formData = new FormData(); const formData = new FormData();
if (requestParameters.name !== undefined) { if (requestParameters.name !== undefined) {
formData.append('name', requestParameters.name as any); formData.append('name', requestParameters.name as any);
@ -249,10 +230,9 @@ export class PetApi extends BaseAPI {
} }
return this.request<void>({ return this.request<void>({
path: `/pet/{petId}`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'POST', method: 'POST',
headers, headers,
query,
body: formData, body: formData,
}); });
} }
@ -272,9 +252,6 @@ export class PetApi extends BaseAPI {
}), }),
}; };
const query: HttpQuery = {
};
const formData = new FormData(); const formData = new FormData();
if (requestParameters.additionalMetadata !== undefined) { if (requestParameters.additionalMetadata !== undefined) {
formData.append('additionalMetadata', requestParameters.additionalMetadata as any); formData.append('additionalMetadata', requestParameters.additionalMetadata as any);
@ -285,10 +262,9 @@ export class PetApi extends BaseAPI {
} }
return this.request<ApiResponse>({ return this.request<ApiResponse>({
path: `/pet/{petId}/uploadImage`.replace(`{petId}`, encodeURIComponent(String(requestParameters.petId))), path: '/pet/{petId}/uploadImage'.replace('{petId}', encodeURI(requestParameters.petId)),
method: 'POST', method: 'POST',
headers, headers,
query,
body: formData, body: formData,
}); });
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, throwIfRequired, encodeURI } from '../runtime';
import { import {
Order, Order,
} from '../models'; } from '../models';
@ -41,17 +41,9 @@ export class StoreApi extends BaseAPI {
deleteOrder = (requestParameters: DeleteOrderRequest): Observable<void> => { deleteOrder = (requestParameters: DeleteOrderRequest): Observable<void> => {
throwIfRequired(requestParameters, 'orderId', 'deleteOrder'); throwIfRequired(requestParameters, 'orderId', 'deleteOrder');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/store/order/{orderId}`.replace(`{orderId}`, encodeURIComponent(String(requestParameters.orderId))), path: '/store/order/{orderId}'.replace('{orderId}', encodeURI(requestParameters.orderId)),
method: 'DELETE', method: 'DELETE',
headers,
query,
}); });
} }
@ -60,19 +52,14 @@ export class StoreApi extends BaseAPI {
* Returns pet inventories by status * Returns pet inventories by status
*/ */
getInventory = (): Observable<{ [key: string]: number; }> => { getInventory = (): Observable<{ [key: string]: number; }> => {
const headers: HttpHeaders = { const headers: HttpHeaders = {
...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication ...(this.configuration.apiKey && { 'api_key': this.configuration.apiKey('api_key') }), // api_key authentication
}; };
const query: HttpQuery = {
};
return this.request<{ [key: string]: number; }>({ return this.request<{ [key: string]: number; }>({
path: `/store/inventory`, path: '/store/inventory',
method: 'GET', method: 'GET',
headers, headers,
query,
}); });
} }
@ -83,17 +70,9 @@ export class StoreApi extends BaseAPI {
getOrderById = (requestParameters: GetOrderByIdRequest): Observable<Order> => { getOrderById = (requestParameters: GetOrderByIdRequest): Observable<Order> => {
throwIfRequired(requestParameters, 'orderId', 'getOrderById'); throwIfRequired(requestParameters, 'orderId', 'getOrderById');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<Order>({ return this.request<Order>({
path: `/store/order/{orderId}`.replace(`{orderId}`, encodeURIComponent(String(requestParameters.orderId))), path: '/store/order/{orderId}'.replace('{orderId}', encodeURI(requestParameters.orderId)),
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -107,14 +86,10 @@ export class StoreApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<Order>({ return this.request<Order>({
path: `/store/order`, path: '/store/order',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }

View File

@ -12,7 +12,7 @@
*/ */
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { BaseAPI, throwIfRequired, HttpHeaders, HttpQuery, COLLECTION_FORMATS } from '../runtime'; import { BaseAPI, HttpHeaders, HttpQuery, throwIfRequired, encodeURI } from '../runtime';
import { import {
User, User,
} from '../models'; } from '../models';
@ -63,14 +63,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user`, path: '/user',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -85,14 +81,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/createWithArray`, path: '/user/createWithArray',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -107,14 +99,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/createWithList`, path: '/user/createWithList',
method: 'POST', method: 'POST',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }
@ -126,17 +114,9 @@ export class UserApi extends BaseAPI {
deleteUser = (requestParameters: DeleteUserRequest): Observable<void> => { deleteUser = (requestParameters: DeleteUserRequest): Observable<void> => {
throwIfRequired(requestParameters, 'username', 'deleteUser'); throwIfRequired(requestParameters, 'username', 'deleteUser');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'DELETE', method: 'DELETE',
headers,
query,
}); });
} }
@ -146,17 +126,9 @@ export class UserApi extends BaseAPI {
getUserByName = (requestParameters: GetUserByNameRequest): Observable<User> => { getUserByName = (requestParameters: GetUserByNameRequest): Observable<User> => {
throwIfRequired(requestParameters, 'username', 'getUserByName'); throwIfRequired(requestParameters, 'username', 'getUserByName');
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<User>({ return this.request<User>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -167,18 +139,14 @@ export class UserApi extends BaseAPI {
throwIfRequired(requestParameters, 'username', 'loginUser'); throwIfRequired(requestParameters, 'username', 'loginUser');
throwIfRequired(requestParameters, 'password', 'loginUser'); throwIfRequired(requestParameters, 'password', 'loginUser');
const headers: HttpHeaders = {
};
const query: HttpQuery = { const query: HttpQuery = {
...(requestParameters.username && { 'username': requestParameters.username }), ...(requestParameters.username && { 'username': requestParameters.username }),
...(requestParameters.password && { 'password': requestParameters.password }), ...(requestParameters.password && { 'password': requestParameters.password }),
}; };
return this.request<string>({ return this.request<string>({
path: `/user/login`, path: '/user/login',
method: 'GET', method: 'GET',
headers,
query, query,
}); });
} }
@ -187,18 +155,9 @@ export class UserApi extends BaseAPI {
* Logs out current logged in user session * Logs out current logged in user session
*/ */
logoutUser = (): Observable<void> => { logoutUser = (): Observable<void> => {
const headers: HttpHeaders = {
};
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/logout`, path: '/user/logout',
method: 'GET', method: 'GET',
headers,
query,
}); });
} }
@ -214,14 +173,10 @@ export class UserApi extends BaseAPI {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
const query: HttpQuery = {
};
return this.request<void>({ return this.request<void>({
path: `/user/{username}`.replace(`{username}`, encodeURIComponent(String(requestParameters.username))), path: '/user/{username}'.replace('{username}', encodeURI(requestParameters.username)),
method: 'PUT', method: 'PUT',
headers, headers,
query,
body: requestParameters.body, body: requestParameters.body,
}); });
} }

View File

@ -18,19 +18,16 @@
*/ */
export interface ApiResponse { export interface ApiResponse {
/** /**
*
* @type {number} * @type {number}
* @memberof ApiResponse * @memberof ApiResponse
*/ */
code?: number; code?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof ApiResponse * @memberof ApiResponse
*/ */
type?: string; type?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof ApiResponse * @memberof ApiResponse
*/ */

View File

@ -18,13 +18,11 @@
*/ */
export interface Category { export interface Category {
/** /**
*
* @type {number} * @type {number}
* @memberof Category * @memberof Category
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof Category * @memberof Category
*/ */

View File

@ -18,25 +18,21 @@
*/ */
export interface Order { export interface Order {
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
id?: number; id?: number;
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
petId?: number; petId?: number;
/** /**
*
* @type {number} * @type {number}
* @memberof Order * @memberof Order
*/ */
quantity?: number; quantity?: number;
/** /**
*
* @type {Date} * @type {Date}
* @memberof Order * @memberof Order
*/ */
@ -48,7 +44,6 @@ export interface Order {
*/ */
status?: OrderStatusEnum; status?: OrderStatusEnum;
/** /**
*
* @type {boolean} * @type {boolean}
* @memberof Order * @memberof Order
*/ */

View File

@ -23,31 +23,26 @@ import {
*/ */
export interface Pet { export interface Pet {
/** /**
*
* @type {number} * @type {number}
* @memberof Pet * @memberof Pet
*/ */
id?: number; id?: number;
/** /**
*
* @type {Category} * @type {Category}
* @memberof Pet * @memberof Pet
*/ */
category?: Category; category?: Category;
/** /**
*
* @type {string} * @type {string}
* @memberof Pet * @memberof Pet
*/ */
name: string; name: string;
/** /**
*
* @type {Array<string>} * @type {Array<string>}
* @memberof Pet * @memberof Pet
*/ */
photoUrls: Array<string>; photoUrls: Array<string>;
/** /**
*
* @type {Array<Tag>} * @type {Array<Tag>}
* @memberof Pet * @memberof Pet
*/ */

View File

@ -18,13 +18,11 @@
*/ */
export interface Tag { export interface Tag {
/** /**
*
* @type {number} * @type {number}
* @memberof Tag * @memberof Tag
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof Tag * @memberof Tag
*/ */

View File

@ -18,43 +18,36 @@
*/ */
export interface User { export interface User {
/** /**
*
* @type {number} * @type {number}
* @memberof User * @memberof User
*/ */
id?: number; id?: number;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
username?: string; username?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
firstName?: string; firstName?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
lastName?: string; lastName?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
email?: string; email?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */
password?: string; password?: string;
/** /**
*
* @type {string} * @type {string}
* @memberof User * @memberof User
*/ */

View File

@ -12,7 +12,7 @@
*/ */
import { Observable, of } from 'rxjs'; import { Observable, of } from 'rxjs';
import { ajax, AjaxResponse } from 'rxjs/ajax'; import { ajax, AjaxRequest, AjaxResponse } from 'rxjs/ajax';
import { map, concatMap } from 'rxjs/operators'; import { map, concatMap } from 'rxjs/operators';
export const BASE_PATH = 'http://petstore.swagger.io/v2'.replace(/\/+$/, ''); export const BASE_PATH = 'http://petstore.swagger.io/v2'.replace(/\/+$/, '');
@ -84,8 +84,8 @@ export class BaseAPI {
withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) => withPostMiddleware = <T extends BaseAPI>(postMiddlewares: Array<Middleware['post']>) =>
this.withMiddleware<T>(postMiddlewares.map((post) => ({ post }))); this.withMiddleware<T>(postMiddlewares.map((post) => ({ post })));
protected request = <T>(context: RequestOpts): Observable<T> => protected request = <T>(requestOpts: RequestOpts): Observable<T> =>
this.rxjsRequest(this.createRequestArgs(context)).pipe( this.rxjsRequest(this.createRequestArgs(requestOpts)).pipe(
map((res) => { map((res) => {
if (res.status >= 200 && res.status < 300) { if (res.status >= 200 && res.status < 300) {
return res.response as T; return res.response as T;
@ -94,46 +94,38 @@ export class BaseAPI {
}) })
); );
private createRequestArgs = (context: RequestOpts): RequestArgs => { private createRequestArgs = (requestOpts: RequestOpts): RequestArgs => {
let url = this.configuration.basePath + context.path; let url = this.configuration.basePath + requestOpts.path;
if (context.query !== undefined && Object.keys(context.query).length !== 0) { if (requestOpts.query !== undefined && Object.keys(requestOpts.query).length !== 0) {
// only add the queryString to the URL if there are query parameters. // only add the queryString to the URL if there are query parameters.
// this is done to avoid urls ending with a '?' character which buggy webservers // this is done to avoid urls ending with a '?' character which buggy webservers
// do not handle correctly sometimes. // do not handle correctly sometimes.
url += '?' + queryString(context.query); url += '?' + queryString(requestOpts.query);
} }
const body = context.body instanceof FormData ? context.body : JSON.stringify(context.body);
const options = { return {
method: context.method, url,
headers: context.headers, method: requestOpts.method,
body, headers: requestOpts.headers,
body: requestOpts.body instanceof FormData ? requestOpts.body : JSON.stringify(requestOpts.body),
}; };
return { url, options };
} }
private rxjsRequest = (params: RequestContext): Observable<AjaxResponse> => { private rxjsRequest = (params: RequestArgs): Observable<AjaxResponse> =>
const preMiddlewares = this.middleware.filter((item) => item.pre); of(params).pipe(
const postMiddlewares = this.middleware.filter((item) => item.post); map((request) => {
this.middleware.filter((item) => item.pre).forEach((mw) => (request = mw.pre!(request)));
return of(params).pipe( return request;
map((args) => {
if (preMiddlewares) {
preMiddlewares.forEach((mw) => (args = mw.pre!({ ...args })));
}
return args;
}), }),
concatMap((args) => concatMap((args) =>
ajax({ url: args.url, ...args.options }).pipe( ajax(args).pipe(
map((response) => { map((response) => {
if (postMiddlewares) { this.middleware.filter((item) => item.post).forEach((mw) => (response = mw.post!(response)));
postMiddlewares.forEach((mw) => (response = mw.post!({ ...params, response })));
}
return response; return response;
}) })
) )
) )
); );
}
/** /**
* Create a shallow clone of `this` by constructing a new instance * Create a shallow clone of `this` by constructing a new instance
@ -162,27 +154,22 @@ export type HttpQuery = { [key: string]: string | number | null | boolean | Arra
export type HttpBody = Json | FormData; export type HttpBody = Json | FormData;
export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original';
export interface RequestArgs {
url: string;
options: RequestInit;
}
export interface RequestOpts { export interface RequestOpts {
path: string; path: string;
method: HttpMethod; method: HttpMethod;
headers: HttpHeaders; headers?: HttpHeaders;
query?: HttpQuery; query?: HttpQuery;
body?: HttpBody; body?: HttpBody;
} }
export const encodeURI = (value: any) => encodeURIComponent(String(value))
const queryString = (params: HttpQuery): string => Object.keys(params) const queryString = (params: HttpQuery): string => Object.keys(params)
.map((key) => { .map((key) => {
const value = params[key]; const value = params[key];
if (value instanceof Array) { return (value instanceof Array)
return value.map((val) => `${encodeURIComponent(key)}=${encodeURIComponent(String(val))}`) ? value.map((val) => `${encodeURI(key)}=${encodeURI(val)}`).join('&')
.join('&'); : `${encodeURI(key)}=${encodeURI(value)}`;
}
return `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`;
}) })
.join('&'); .join('&');
@ -195,12 +182,11 @@ export const throwIfRequired = (params: {[key: string]: any}, key: string, nickn
} }
} }
export interface RequestContext extends RequestArgs {} // alias for easier importing
export interface ResponseContext extends RequestArgs { export interface RequestArgs extends AjaxRequest {}
response: AjaxResponse; export interface ResponseArgs extends AjaxResponse {}
}
export interface Middleware { export interface Middleware {
pre?(context: RequestContext): RequestArgs; pre?(request: RequestArgs): RequestArgs;
post?(context: ResponseContext): AjaxResponse; post?(response: ResponseArgs): ResponseArgs;
} }