diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularAdditionalPropertiesIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularAdditionalPropertiesIntegrationTest.java index f8acc26f6487..ee87da560e37 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularAdditionalPropertiesIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularAdditionalPropertiesIntegrationTest.java @@ -58,7 +58,7 @@ protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { return new IntegrationTestPathsConfig("typescript/additional-properties"); } - @Test(enabled = false) + @Test @Override public void generatesCorrectDirectoryStructure() throws IOException { // test are currently disabled in Superclass diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularArrayAndObjectIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularArrayAndObjectIntegrationTest.java index 0b4b5eaa5fe1..9bbb9ea4ef53 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularArrayAndObjectIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularArrayAndObjectIntegrationTest.java @@ -58,7 +58,7 @@ protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { return new IntegrationTestPathsConfig("typescript/array-and-object"); } - @Test(enabled = false) + @Test @Override public void generatesCorrectDirectoryStructure() throws IOException { // test are currently disabled in Superclass diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularParamsStrategyCustomIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularParamsStrategyCustomIntegrationTest.java index 07d13ee584e3..ceac06d46ffb 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularParamsStrategyCustomIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularParamsStrategyCustomIntegrationTest.java @@ -57,7 +57,7 @@ protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { return new IntegrationTestPathsConfig("typescript/custom-path-params"); } - @Test(enabled = false) + @Test @Override public void generatesCorrectDirectoryStructure() throws IOException { // test are currently disabled in Superclass diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularPetstoreIntegrationTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularPetstoreIntegrationTest.java index cf6a215c984f..251463ce653e 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularPetstoreIntegrationTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/typescriptangular/TypescriptAngularPetstoreIntegrationTest.java @@ -58,7 +58,7 @@ protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { return new IntegrationTestPathsConfig("typescript/petstore"); } - @Test(enabled = false) + @Test @Override public void generatesCorrectDirectoryStructure() throws IOException { // test are currently disabled in Superclass diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/README.md b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/README.md index d46ff5c06b91..1962e720580f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/README.md +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/README.md @@ -1,30 +1,35 @@ -## additionalPropertiesTest@1.0.2 +# additionalPropertiesTest@1.0.2 -### Building +This is a test spec + +The version of the OpenAPI document: 1.0.0 + +## Building To install the required dependencies and to build the typescript sources run: -``` + +```console npm install npm run build ``` -### publishing +## Publishing -First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) +First build the package then run `npm publish dist` (don't forget to specify the `dist` folder!) -### consuming +## Consuming Navigate to the folder of your consuming project and run one of next commands. _published:_ -``` +```console npm install additionalPropertiesTest@1.0.2 --save ``` _without publishing (not recommended):_ -``` +```console npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save ``` @@ -33,173 +38,126 @@ _It's important to take the tgz file, otherwise you'll get trouble with links on _using `npm link`:_ In PATH_TO_GENERATED_PACKAGE/dist: -``` + +```console npm link ``` In your project: -``` + +```console npm link additionalPropertiesTest ``` __Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. -Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Please refer to this issue for a solution / workaround. Published packages are not effected by this issue. - -#### General usage +### General usage In your Angular project: +```typescript -``` -// without configuring providers -import { ApiModule } from 'additionalPropertiesTest'; -import { HttpClientModule } from '@angular/common/http'; - -@NgModule({ - imports: [ - ApiModule, - // make sure to import the HttpClientModule in the AppModule only, - // see https://github.com/angular/angular/issues/20575 - HttpClientModule - ], - declarations: [ AppComponent ], - providers: [], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - -``` -// configuring providers -import { ApiModule, Configuration, ConfigurationParameters } from 'additionalPropertiesTest'; - -export function apiConfigFactory (): Configuration { - const params: ConfigurationParameters = { - // set configuration parameters here. - } - return new Configuration(params); -} - -@NgModule({ - imports: [ ApiModule.forRoot(apiConfigFactory) ], - declarations: [ AppComponent ], - providers: [], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - -``` -// configuring providers with an authentication service that manages your access tokens -import { ApiModule, Configuration } from 'additionalPropertiesTest'; +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'additionalPropertiesTest'; -@NgModule({ - imports: [ ApiModule ], - declarations: [ AppComponent ], +export const appConfig: ApplicationConfig = { providers: [ - { - provide: Configuration, - useFactory: (authService: AuthService) => new Configuration( - { - basePath: environment.apiUrl, - accessToken: authService.getAccessToken.bind(authService) - } - ), - deps: [AuthService], - multi: false - } + // ... + provideHttpClient(), + provideApi() ], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - +}; ``` -import { DefaultApi } from 'additionalPropertiesTest'; -export class AppComponent { - constructor(private apiGateway: DefaultApi) { } -} +**NOTE** +If you're still using `AppModule` and haven't [migrated](https://angular.dev/reference/migrations/standalone) yet, you can still import an Angular module: +```typescript +import { ApiModule } from 'additionalPropertiesTest'; ``` -Note: The ApiModule is restricted to being instantiated once app wide. -This is to ensure that all services are treated as singletons. - -#### Using multiple OpenAPI files / APIs / ApiModules -In order to use multiple `ApiModules` generated from different OpenAPI files, -you can create an alias name when importing the modules -in order to avoid naming conflicts: -``` -import { ApiModule } from 'my-api-path'; -import { ApiModule as OtherApiModule } from 'my-other-api-path'; -import { HttpClientModule } from '@angular/common/http'; +If different from the generated base path, during app bootstrap, you can provide the base path to your service. -@NgModule({ - imports: [ - ApiModule, - OtherApiModule, - // make sure to import the HttpClientModule in the AppModule only, - // see https://github.com/angular/angular/issues/20575 - HttpClientModule - ] -}) -export class AppModule { +```typescript +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'additionalPropertiesTest'; -} +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideApi('http://localhost:9999') + ], +}; ``` +```typescript +// with a custom configuration +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'additionalPropertiesTest'; -### Set service base path -If different than the generated base path, during app bootstrap, you can provide the base path to your service. - -``` -import { BASE_PATH } from 'additionalPropertiesTest'; - -bootstrap(AppComponent, [ - { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, -]); +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideApi({ + withCredentials: true, + username: 'user', + password: 'password' + }) + ], +}; ``` -or -``` -import { BASE_PATH } from 'additionalPropertiesTest'; +```typescript +// with factory building a custom configuration +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi, Configuration } from 'additionalPropertiesTest'; -@NgModule({ - imports: [], - declarations: [ AppComponent ], - providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], - bootstrap: [ AppComponent ] -}) -export class AppModule {} +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + { + provide: Configuration, + useFactory: (authService: AuthService) => new Configuration({ + basePath: 'http://localhost:9999', + withCredentials: true, + username: authService.getUsername(), + password: authService.getPassword(), + }), + deps: [AuthService], + multi: false + } + ], +}; ``` +### Using multiple OpenAPI files / APIs -#### Using @angular/cli -First extend your `src/environments/*.ts` files by adding the corresponding base path: - -``` -export const environment = { - production: false, - API_BASE_PATH: 'http://127.0.0.1:8080' -}; -``` +In order to use multiple APIs generated from different OpenAPI files, +you can create an alias name when importing the modules +in order to avoid naming conflicts: -In the src/app/app.module.ts: -``` -import { BASE_PATH } from 'additionalPropertiesTest'; +```typescript +import { provideApi as provideUserApi } from 'my-user-api-path'; +import { provideApi as provideAdminApi } from 'my-admin-api-path'; +import { HttpClientModule } from '@angular/common/http'; import { environment } from '../environments/environment'; -@NgModule({ - declarations: [ - AppComponent - ], - imports: [ ], - providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], - bootstrap: [ AppComponent ] -}) -export class AppModule { } +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideUserApi(environment.basePath), + provideAdminApi(environment.basePath), + ], +}; ``` ### Customizing path parameter encoding @@ -215,6 +173,7 @@ pass an arrow-function or method-reference to the `encodeParam` property of the (see [General Usage](#general-usage) above). Example value for use in your Configuration-Provider: + ```typescript new Configuration({ encodeParam: (param: Param) => myFancyParamEncoder(param), diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api.base.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api.base.service.ts new file mode 100644 index 000000000000..7e447ce347e4 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api.base.service.ts @@ -0,0 +1,95 @@ +/** + * OpenAPI Additional Properties + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http'; +import { CustomHttpParameterCodec } from './encoder'; +import { Configuration } from './configuration'; +import { OpenApiHttpParams, QueryParamStyle, concatHttpParamsObject} from './query.params'; + +export class BaseService { + protected basePath = 'http://additional-properties.swagger.io/v2'; + public defaultHeaders = new HttpHeaders(); + public configuration: Configuration; + public encoder: HttpParameterCodec; + + constructor(basePath?: string|string[], configuration?: Configuration) { + this.configuration = configuration || new Configuration(); + if (typeof this.configuration.basePath !== 'string') { + const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined; + if (firstBasePath != undefined) { + basePath = firstBasePath; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + protected canConsumeForm(consumes: string[]): boolean { + return consumes.indexOf('multipart/form-data') !== -1; + } + + protected addToHttpParams(httpParams: OpenApiHttpParams, key: string, value: any | null | undefined, paramStyle: QueryParamStyle, explode: boolean): OpenApiHttpParams { + if (value === null || value === undefined) { + return httpParams; + } + + if (paramStyle === QueryParamStyle.DeepObject) { + if (typeof value !== 'object') { + throw Error(`An object must be provided for key ${key} as it is a deep object`); + } + + return Object.keys(value as Record).reduce( + (hp, k) => hp.append(`${key}[${k}]`, value[k]), + httpParams, + ); + } else if (paramStyle === QueryParamStyle.Json) { + return httpParams.append(key, JSON.stringify(value)); + } else { + // Form-style, SpaceDelimited or PipeDelimited + + if (Object(value) !== value) { + // If it is a primitive type, add its string representation + return httpParams.append(key, value.toString()); + } else if (value instanceof Date) { + return httpParams.append(key, value.toISOString()); + } else if (Array.isArray(value)) { + // Otherwise, if it's an array, add each element. + if (paramStyle === QueryParamStyle.Form) { + return httpParams.set(key, value, {explode: explode, delimiter: ','}); + } else if (paramStyle === QueryParamStyle.SpaceDelimited) { + return httpParams.set(key, value, {explode: explode, delimiter: ' '}); + } else { + // PipeDelimited + return httpParams.set(key, value, {explode: explode, delimiter: '|'}); + } + } else { + // Otherwise, if it's an object, add each field. + if (paramStyle === QueryParamStyle.Form) { + if (explode) { + Object.keys(value).forEach(k => { + httpParams = this.addToHttpParams(httpParams, k, value[k], paramStyle, explode); + }); + return httpParams; + } else { + return concatHttpParamsObject(httpParams, key, value, ','); + } + } else if (paramStyle === QueryParamStyle.SpaceDelimited) { + return concatHttpParamsObject(httpParams, key, value, ' '); + } else { + // PipeDelimited + return concatHttpParamsObject(httpParams, key, value, '|'); + } + } + } + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/user.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/user.service.ts index f6819d6c99ec..c9edb354bc36 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/user.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/api/user.service.ts @@ -1,8 +1,6 @@ /** * OpenAPI Additional Properties - * This is a test spec * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -13,10 +11,10 @@ import { Inject, Injectable, Optional } from '@angular/core'; import { HttpClient, HttpHeaders, HttpParams, - HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + HttpResponse, HttpEvent, HttpContext } from '@angular/common/http'; -import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +import { OpenApiHttpParams, QueryParamStyle } from '../query.params'; // @ts-ignore import { User } from '../model/user'; @@ -24,101 +22,43 @@ import { User } from '../model/user'; // @ts-ignore import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; import { Configuration } from '../configuration'; +import { BaseService } from '../api.base.service'; @Injectable({ providedIn: 'root' }) -export class UserService { +export class UserService extends BaseService { - protected basePath = 'http://additional-properties.swagger.io/v2'; - public defaultHeaders = new HttpHeaders(); - public configuration = new Configuration(); - public encoder: HttpParameterCodec; - - constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { - if (configuration) { - this.configuration = configuration; - } - if (typeof this.configuration.basePath !== 'string') { - if (Array.isArray(basePath) && basePath.length > 0) { - basePath = basePath[0]; - } - - if (typeof basePath !== 'string') { - basePath = this.basePath; - } - this.configuration.basePath = basePath; - } - this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); - } - - - // @ts-ignore - private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { - if (typeof value === "object" && value instanceof Date === false) { - httpParams = this.addToHttpParamsRecursive(httpParams, value); - } else { - httpParams = this.addToHttpParamsRecursive(httpParams, value, key); - } - return httpParams; - } - - private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { - if (value == null) { - return httpParams; - } - - if (typeof value === "object") { - if (Array.isArray(value)) { - (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); - } else if (value instanceof Date) { - if (key != null) { - httpParams = httpParams.append(key, (value as Date).toISOString().substring(0, 10)); - } else { - throw Error("key may not be null if value is Date"); - } - } else { - Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( - httpParams, value[k], key != null ? `${key}.${k}` : k)); - } - } else if (key != null) { - httpParams = httpParams.append(key, value); - } else { - throw Error("key may not be null if value is not object or array"); - } - return httpParams; + constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) { + super(basePath, configuration); } /** * Add a new User to the store + * @endpoint post /user * @param body User object that needs to be added to the store * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public addUser(body?: { [key: string]: string; }, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public addUser(body?: { [key: string]: string; }, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public addUser(body?: { [key: string]: string; }, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public addUser(body?: { [key: string]: string; }, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public addUser(body?: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public addUser(body?: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public addUser(body?: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public addUser(body?: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header @@ -142,14 +82,16 @@ export class UserService { } let localVarPath = `/user`; - return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('post', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: body, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -157,32 +99,28 @@ export class UserService { /** * Update an existing User + * @endpoint put /user * @param body User object that needs to be added to the store * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public updateUser(body?: { [key: string]: string; }, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public updateUser(body?: { [key: string]: string; }, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public updateUser(body?: { [key: string]: string; }, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public updateUser(body?: { [key: string]: string; }, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public updateUser(body?: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public updateUser(body?: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public updateUser(body?: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public updateUser(body?: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header @@ -206,14 +144,16 @@ export class UserService { } let localVarPath = `/user`; - return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('put', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: body, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/configuration.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/configuration.ts index 526b454fb2bc..2a128451c081 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/configuration.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/configuration.ts @@ -1,4 +1,4 @@ -import { HttpParameterCodec } from '@angular/common/http'; +import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http'; import { Param } from './param'; export interface ConfigurationParameters { @@ -66,26 +66,30 @@ export class Configuration { */ credentials: {[ key: string ]: string | (() => string | undefined)}; - constructor(configurationParameters: ConfigurationParameters = {}) { - this.apiKeys = configurationParameters.apiKeys; - this.username = configurationParameters.username; - this.password = configurationParameters.password; - this.accessToken = configurationParameters.accessToken; - this.basePath = configurationParameters.basePath; - this.withCredentials = configurationParameters.withCredentials; - this.encoder = configurationParameters.encoder; - if (configurationParameters.encodeParam) { - this.encodeParam = configurationParameters.encodeParam; +constructor({ accessToken, apiKeys, basePath, credentials, encodeParam, encoder, password, username, withCredentials }: ConfigurationParameters = {}) { + if (apiKeys) { + this.apiKeys = apiKeys; } - else { - this.encodeParam = param => this.defaultEncodeParam(param); + if (username !== undefined) { + this.username = username; } - if (configurationParameters.credentials) { - this.credentials = configurationParameters.credentials; + if (password !== undefined) { + this.password = password; } - else { - this.credentials = {}; + if (accessToken !== undefined) { + this.accessToken = accessToken; } + if (basePath !== undefined) { + this.basePath = basePath; + } + if (withCredentials !== undefined) { + this.withCredentials = withCredentials; + } + if (encoder) { + this.encoder = encoder; + } + this.encodeParam = encodeParam ?? (param => this.defaultEncodeParam(param)); + this.credentials = credentials ?? {}; } /** @@ -148,6 +152,20 @@ export class Configuration { : value; } + public addCredentialToHeaders(credentialKey: string, headerName: string, headers: HttpHeaders, prefix?: string): HttpHeaders { + const value = this.lookupCredential(credentialKey); + return value + ? headers.set(headerName, (prefix ?? '') + value) + : headers; + } + + public addCredentialToQuery(credentialKey: string, paramName: string, query: HttpParams): HttpParams { + const value = this.lookupCredential(credentialKey); + return value + ? query.set(paramName, value) + : query; + } + private defaultEncodeParam(param: Param): string { // This implementation exists as fallback for missing configuration // and for backwards compatibility to older typescript-angular generator versions. diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/encoder.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/encoder.ts index 138c4d5cf2c1..af4523543e6c 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/encoder.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/encoder.ts @@ -18,3 +18,18 @@ export class CustomHttpParameterCodec implements HttpParameterCodec { return decodeURIComponent(v); } } + +export class IdentityHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return k; + } + encodeValue(v: string): string { + return v; + } + decodeKey(k: string): string { + return k; + } + decodeValue(v: string): string { + return v; + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/index.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/index.ts index 104dd3d21e35..02cb7d437fbf 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/index.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/index.ts @@ -3,4 +3,5 @@ export * from './model/models'; export * from './variables'; export * from './configuration'; export * from './api.module'; +export * from './provide-api'; export * from './param'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/model/user.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/model/user.ts index a62b83bbe77e..a0c311295ad9 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/model/user.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/model/user.ts @@ -1,8 +1,6 @@ /** * OpenAPI Additional Properties - * This is a test spec * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/package.json index fee4d4cb931e..70738b1c6575 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/package.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/package.json @@ -13,21 +13,22 @@ ], "license": "Unlicense", "scripts": { + "prepare": "npm run build", "build": "ng-packagr -p ng-package.json" }, "peerDependencies": { - "@angular/core": "^16.1.2", + "@angular/core": "^20.0.0", "rxjs": "^7.4.0" }, "devDependencies": { - "@angular/common": "^16.1.2", - "@angular/compiler": "^16.1.2", - "@angular/compiler-cli": "^16.1.2", - "@angular/core": "^16.1.2", - "@angular/platform-browser": "^16.1.2", - "ng-packagr": "^16.0.0", + "@angular/common": "^20.0.0", + "@angular/compiler": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "ng-packagr": "^20.0.0", "reflect-metadata": "^0.1.3", "rxjs": "^7.4.0", - "typescript": ">=4.9.3 <5.2.0", - "zone.js": "^0.13.0" + "typescript": ">=5.8.0 <5.9.0", + "zone.js": "^0.15.0" }} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/provide-api.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/provide-api.ts new file mode 100644 index 000000000000..19c762acdfe0 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/provide-api.ts @@ -0,0 +1,15 @@ +import { EnvironmentProviders, makeEnvironmentProviders } from "@angular/core"; +import { Configuration, ConfigurationParameters } from './configuration'; +import { BASE_PATH } from './variables'; + +// Returns the service class providers, to be used in the [ApplicationConfig](https://angular.dev/api/core/ApplicationConfig). +export function provideApi(configOrBasePath: string | ConfigurationParameters): EnvironmentProviders { + return makeEnvironmentProviders([ + typeof configOrBasePath === "string" + ? { provide: BASE_PATH, useValue: configOrBasePath } + : { + provide: Configuration, + useValue: new Configuration({ ...configOrBasePath }), + }, + ]); +} \ No newline at end of file diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/query.params.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/query.params.ts new file mode 100644 index 000000000000..4076c1140c83 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/query.params.ts @@ -0,0 +1,160 @@ +import { HttpParams, HttpParameterCodec } from '@angular/common/http'; +import { CustomHttpParameterCodec, IdentityHttpParameterCodec } from './encoder'; + +export enum QueryParamStyle { + Json, + Form, + DeepObject, + SpaceDelimited, + PipeDelimited, +} + +export type Delimiter = "," | " " | "|" | "\t"; + +export interface ParamOptions { + /** When true, serialized as multiple repeated key=value pairs. When false, serialized as a single key with joined values using `delimiter`. */ + explode?: boolean; + /** Delimiter used when explode=false. The delimiter itself is inserted unencoded between encoded values. */ + delimiter?: Delimiter; +} + +interface ParamEntry { + values: string[]; + options: Required; +} + +export class OpenApiHttpParams { + private params: Map = new Map(); + private defaults: Required; + private encoder: HttpParameterCodec; + + /** + * @param encoder Parameter serializer + * @param defaults Global defaults used when a specific parameter has no explicit options. + * By OpenAPI default, explode is true for query params with style=form. + */ + constructor(encoder?: HttpParameterCodec, defaults?: { explode?: boolean; delimiter?: Delimiter }) { + this.encoder = encoder || new CustomHttpParameterCodec(); + this.defaults = { + explode: defaults?.explode ?? true, + delimiter: defaults?.delimiter ?? ",", + }; + } + + private resolveOptions(local?: ParamOptions): Required { + return { + explode: local?.explode ?? this.defaults.explode, + delimiter: local?.delimiter ?? this.defaults.delimiter, + }; + } + + /** + * Replace the parameter's values and (optionally) its options. + * Options are stored per-parameter (not global). + */ + set(key: string, values: string[] | string, options?: ParamOptions): this { + const arr = Array.isArray(values) ? values.slice() : [values]; + const opts = this.resolveOptions(options); + this.params.set(key, {values: arr, options: opts}); + return this; + } + + /** + * Append a single value to the parameter. If the parameter didn't exist it will be created + * and use resolved options (global defaults merged with any provided options). + */ + append(key: string, value: string, options?: ParamOptions): this { + const entry = this.params.get(key); + if (entry) { + // If new options provided, override the stored options for subsequent serialization + if (options) { + entry.options = this.resolveOptions({...entry.options, ...options}); + } + entry.values.push(value); + } else { + this.set(key, [value], options); + } + return this; + } + + /** + * Serialize to a query string according to per-parameter OpenAPI options. + * - If explode=true for that parameter → repeated key=value pairs (each value encoded). + * - If explode=false for that parameter → single key=value where values are individually encoded + * and joined using the configured delimiter. The delimiter character is inserted AS-IS + * (not percent-encoded). + */ + toString(): string { + const records = this.toRecord(); + const parts: string[] = []; + + for (const key in records) { + parts.push(`${key}=${records[key]}`); + } + + return parts.join("&"); + } + + /** + * Return parameters as a plain record. + * - If a parameter has exactly one value, returns that value directly. + * - If a parameter has multiple values, returns a readonly array of values. + */ + toRecord(): Record> { + const parts: Record> = {}; + + for (const [key, entry] of this.params.entries()) { + const encodedKey = this.encoder.encodeKey(key); + + if (entry.options.explode) { + parts[encodedKey] = entry.values.map((v) => this.encoder.encodeValue(v)); + } else { + const encodedValues = entry.values.map((v) => this.encoder.encodeValue(v)); + + // join with the delimiter *unencoded* + parts[encodedKey] = encodedValues.join(entry.options.delimiter); + } + } + + return parts; + } + + /** + * Return an Angular's HttpParams with an identity parameter codec as the parameters are already encoded. + */ + toHttpParams(): HttpParams { + const records = this.toRecord(); + + let httpParams = new HttpParams({encoder: new IdentityHttpParameterCodec()}); + + return httpParams.appendAll(records); + } +} + +export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: string, item: { + [index: string]: any +}, delimiter: Delimiter): OpenApiHttpParams { + let keyAndValues: string[] = []; + + for (const k in item) { + keyAndValues.push(k); + + const value = item[k]; + + if (Array.isArray(value)) { + keyAndValues.push(...value.map(convertToString)); + } else { + keyAndValues.push(convertToString(value)); + } + } + + return httpParams.set(key, keyAndValues, {explode: false, delimiter: delimiter}); +} + +function convertToString(value: any): string { + if (value instanceof Date) { + return value.toISOString(); + } else { + return value.toString(); + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/tsconfig.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/tsconfig.json index 89cdedb1cb7f..eb405ea0e09f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/tsconfig.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/additional-properties-expected/tsconfig.json @@ -5,8 +5,11 @@ "noImplicitAny": false, "target": "es5", "module": "commonjs", + "downlevelIteration": true, "moduleResolution": "node", "removeComments": true, + "strictNullChecks": true, + "exactOptionalPropertyTypes": true, "sourceMap": true, "outDir": "./dist", "noLib": false, diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/README.md b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/README.md index 9d5891ab4e13..d6663a367fc5 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/README.md +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/README.md @@ -1,30 +1,35 @@ -## arrayAndAnyTest@1.0.2 +# arrayAndAnyTest@1.0.2 -### Building +No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + +The version of the OpenAPI document: 1.7.0 + +## Building To install the required dependencies and to build the typescript sources run: -``` + +```console npm install npm run build ``` -### publishing +## Publishing -First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) +First build the package then run `npm publish dist` (don't forget to specify the `dist` folder!) -### consuming +## Consuming Navigate to the folder of your consuming project and run one of next commands. _published:_ -``` +```console npm install arrayAndAnyTest@1.0.2 --save ``` _without publishing (not recommended):_ -``` +```console npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save ``` @@ -33,173 +38,126 @@ _It's important to take the tgz file, otherwise you'll get trouble with links on _using `npm link`:_ In PATH_TO_GENERATED_PACKAGE/dist: -``` + +```console npm link ``` In your project: -``` + +```console npm link arrayAndAnyTest ``` __Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. -Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Please refer to this issue for a solution / workaround. Published packages are not effected by this issue. - -#### General usage +### General usage In your Angular project: +```typescript -``` -// without configuring providers -import { ApiModule } from 'arrayAndAnyTest'; -import { HttpClientModule } from '@angular/common/http'; - -@NgModule({ - imports: [ - ApiModule, - // make sure to import the HttpClientModule in the AppModule only, - // see https://github.com/angular/angular/issues/20575 - HttpClientModule - ], - declarations: [ AppComponent ], - providers: [], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - -``` -// configuring providers -import { ApiModule, Configuration, ConfigurationParameters } from 'arrayAndAnyTest'; - -export function apiConfigFactory (): Configuration { - const params: ConfigurationParameters = { - // set configuration parameters here. - } - return new Configuration(params); -} - -@NgModule({ - imports: [ ApiModule.forRoot(apiConfigFactory) ], - declarations: [ AppComponent ], - providers: [], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - -``` -// configuring providers with an authentication service that manages your access tokens -import { ApiModule, Configuration } from 'arrayAndAnyTest'; +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'arrayAndAnyTest'; -@NgModule({ - imports: [ ApiModule ], - declarations: [ AppComponent ], +export const appConfig: ApplicationConfig = { providers: [ - { - provide: Configuration, - useFactory: (authService: AuthService) => new Configuration( - { - basePath: environment.apiUrl, - accessToken: authService.getAccessToken.bind(authService) - } - ), - deps: [AuthService], - multi: false - } + // ... + provideHttpClient(), + provideApi() ], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - +}; ``` -import { DefaultApi } from 'arrayAndAnyTest'; -export class AppComponent { - constructor(private apiGateway: DefaultApi) { } -} +**NOTE** +If you're still using `AppModule` and haven't [migrated](https://angular.dev/reference/migrations/standalone) yet, you can still import an Angular module: +```typescript +import { ApiModule } from 'arrayAndAnyTest'; ``` -Note: The ApiModule is restricted to being instantiated once app wide. -This is to ensure that all services are treated as singletons. - -#### Using multiple OpenAPI files / APIs / ApiModules -In order to use multiple `ApiModules` generated from different OpenAPI files, -you can create an alias name when importing the modules -in order to avoid naming conflicts: -``` -import { ApiModule } from 'my-api-path'; -import { ApiModule as OtherApiModule } from 'my-other-api-path'; -import { HttpClientModule } from '@angular/common/http'; +If different from the generated base path, during app bootstrap, you can provide the base path to your service. -@NgModule({ - imports: [ - ApiModule, - OtherApiModule, - // make sure to import the HttpClientModule in the AppModule only, - // see https://github.com/angular/angular/issues/20575 - HttpClientModule - ] -}) -export class AppModule { +```typescript +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'arrayAndAnyTest'; -} +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideApi('http://localhost:9999') + ], +}; ``` +```typescript +// with a custom configuration +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'arrayAndAnyTest'; -### Set service base path -If different than the generated base path, during app bootstrap, you can provide the base path to your service. - -``` -import { BASE_PATH } from 'arrayAndAnyTest'; - -bootstrap(AppComponent, [ - { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, -]); +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideApi({ + withCredentials: true, + username: 'user', + password: 'password' + }) + ], +}; ``` -or -``` -import { BASE_PATH } from 'arrayAndAnyTest'; +```typescript +// with factory building a custom configuration +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi, Configuration } from 'arrayAndAnyTest'; -@NgModule({ - imports: [], - declarations: [ AppComponent ], - providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], - bootstrap: [ AppComponent ] -}) -export class AppModule {} +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + { + provide: Configuration, + useFactory: (authService: AuthService) => new Configuration({ + basePath: 'http://localhost:9999', + withCredentials: true, + username: authService.getUsername(), + password: authService.getPassword(), + }), + deps: [AuthService], + multi: false + } + ], +}; ``` +### Using multiple OpenAPI files / APIs -#### Using @angular/cli -First extend your `src/environments/*.ts` files by adding the corresponding base path: - -``` -export const environment = { - production: false, - API_BASE_PATH: 'http://127.0.0.1:8080' -}; -``` +In order to use multiple APIs generated from different OpenAPI files, +you can create an alias name when importing the modules +in order to avoid naming conflicts: -In the src/app/app.module.ts: -``` -import { BASE_PATH } from 'arrayAndAnyTest'; +```typescript +import { provideApi as provideUserApi } from 'my-user-api-path'; +import { provideApi as provideAdminApi } from 'my-admin-api-path'; +import { HttpClientModule } from '@angular/common/http'; import { environment } from '../environments/environment'; -@NgModule({ - declarations: [ - AppComponent - ], - imports: [ ], - providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], - bootstrap: [ AppComponent ] -}) -export class AppModule { } +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideUserApi(environment.basePath), + provideAdminApi(environment.basePath), + ], +}; ``` ### Customizing path parameter encoding @@ -215,6 +173,7 @@ pass an arrow-function or method-reference to the `encodeParam` property of the (see [General Usage](#general-usage) above). Example value for use in your Configuration-Provider: + ```typescript new Configuration({ encodeParam: (param: Param) => myFancyParamEncoder(param), diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api.base.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api.base.service.ts new file mode 100644 index 000000000000..8868df446b43 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api.base.service.ts @@ -0,0 +1,95 @@ +/** + * Cupix API + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http'; +import { CustomHttpParameterCodec } from './encoder'; +import { Configuration } from './configuration'; +import { OpenApiHttpParams, QueryParamStyle, concatHttpParamsObject} from './query.params'; + +export class BaseService { + protected basePath = '/v1'; + public defaultHeaders = new HttpHeaders(); + public configuration: Configuration; + public encoder: HttpParameterCodec; + + constructor(basePath?: string|string[], configuration?: Configuration) { + this.configuration = configuration || new Configuration(); + if (typeof this.configuration.basePath !== 'string') { + const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined; + if (firstBasePath != undefined) { + basePath = firstBasePath; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + protected canConsumeForm(consumes: string[]): boolean { + return consumes.indexOf('multipart/form-data') !== -1; + } + + protected addToHttpParams(httpParams: OpenApiHttpParams, key: string, value: any | null | undefined, paramStyle: QueryParamStyle, explode: boolean): OpenApiHttpParams { + if (value === null || value === undefined) { + return httpParams; + } + + if (paramStyle === QueryParamStyle.DeepObject) { + if (typeof value !== 'object') { + throw Error(`An object must be provided for key ${key} as it is a deep object`); + } + + return Object.keys(value as Record).reduce( + (hp, k) => hp.append(`${key}[${k}]`, value[k]), + httpParams, + ); + } else if (paramStyle === QueryParamStyle.Json) { + return httpParams.append(key, JSON.stringify(value)); + } else { + // Form-style, SpaceDelimited or PipeDelimited + + if (Object(value) !== value) { + // If it is a primitive type, add its string representation + return httpParams.append(key, value.toString()); + } else if (value instanceof Date) { + return httpParams.append(key, value.toISOString()); + } else if (Array.isArray(value)) { + // Otherwise, if it's an array, add each element. + if (paramStyle === QueryParamStyle.Form) { + return httpParams.set(key, value, {explode: explode, delimiter: ','}); + } else if (paramStyle === QueryParamStyle.SpaceDelimited) { + return httpParams.set(key, value, {explode: explode, delimiter: ' '}); + } else { + // PipeDelimited + return httpParams.set(key, value, {explode: explode, delimiter: '|'}); + } + } else { + // Otherwise, if it's an object, add each field. + if (paramStyle === QueryParamStyle.Form) { + if (explode) { + Object.keys(value).forEach(k => { + httpParams = this.addToHttpParams(httpParams, k, value[k], paramStyle, explode); + }); + return httpParams; + } else { + return concatHttpParamsObject(httpParams, key, value, ','); + } + } else if (paramStyle === QueryParamStyle.SpaceDelimited) { + return concatHttpParamsObject(httpParams, key, value, ' '); + } else { + // PipeDelimited + return concatHttpParamsObject(httpParams, key, value, '|'); + } + } + } + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/project.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/project.service.ts index f0d6f543ad80..00f6d9d8f340 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/project.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/api/project.service.ts @@ -1,8 +1,6 @@ /** * Cupix API - * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) * - * The version of the OpenAPI document: 1.7.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -13,10 +11,10 @@ import { Inject, Injectable, Optional } from '@angular/core'; import { HttpClient, HttpHeaders, HttpParams, - HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + HttpResponse, HttpEvent, HttpContext } from '@angular/common/http'; -import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +import { OpenApiHttpParams, QueryParamStyle } from '../query.params'; // @ts-ignore import { ProjectEntity } from '../model/projectEntity'; @@ -26,89 +24,23 @@ import { ProjectList } from '../model/projectList'; // @ts-ignore import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; import { Configuration } from '../configuration'; +import { BaseService } from '../api.base.service'; @Injectable({ providedIn: 'root' }) -export class ProjectService { +export class ProjectService extends BaseService { - protected basePath = '/v1'; - public defaultHeaders = new HttpHeaders(); - public configuration = new Configuration(); - public encoder: HttpParameterCodec; - - constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { - if (configuration) { - this.configuration = configuration; - } - if (typeof this.configuration.basePath !== 'string') { - if (Array.isArray(basePath) && basePath.length > 0) { - basePath = basePath[0]; - } - - if (typeof basePath !== 'string') { - basePath = this.basePath; - } - this.configuration.basePath = basePath; - } - this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); - } - - /** - * @param consumes string[] mime-types - * @return true: consumes contains 'multipart/form-data', false: otherwise - */ - private canConsumeForm(consumes: string[]): boolean { - const form = 'multipart/form-data'; - for (const consume of consumes) { - if (form === consume) { - return true; - } - } - return false; - } - - // @ts-ignore - private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { - if (typeof value === "object" && value instanceof Date === false) { - httpParams = this.addToHttpParamsRecursive(httpParams, value); - } else { - httpParams = this.addToHttpParamsRecursive(httpParams, value, key); - } - return httpParams; - } - - private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { - if (value == null) { - return httpParams; - } - - if (typeof value === "object") { - if (Array.isArray(value)) { - (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); - } else if (value instanceof Date) { - if (key != null) { - httpParams = httpParams.append(key, (value as Date).toISOString().substring(0, 10)); - } else { - throw Error("key may not be null if value is Date"); - } - } else { - Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( - httpParams, value[k], key != null ? `${key}.${k}` : k)); - } - } else if (key != null) { - httpParams = httpParams.append(key, value); - } else { - throw Error("key may not be null if value is not object or array"); - } - return httpParams; + constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) { + super(basePath, configuration); } /** * Create a Project * Creates an empty Project + * @endpoint post /projects * @param name * @param address * @param longitude @@ -116,30 +48,25 @@ export class ProjectService { * @param meta * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; - public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public createProject(name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header const consumes: string[] = [ @@ -185,14 +112,16 @@ export class ProjectService { } let localVarPath = `/projects`; - return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('post', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -201,36 +130,32 @@ export class ProjectService { /** * Delete a Project * Returns a Project JSON object + * @endpoint delete /projects/{id} * @param id Project id * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public deleteProjectById(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; - public deleteProjectById(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public deleteProjectById(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public deleteProjectById(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + public deleteProjectById(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public deleteProjectById(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteProjectById(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteProjectById(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (id === null || id === undefined) { throw new Error('Required parameter id was null or undefined when calling deleteProjectById.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -245,13 +170,15 @@ export class ProjectService { } let localVarPath = `/projects/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`; - return this.httpClient.request('delete', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('delete', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -260,36 +187,32 @@ export class ProjectService { /** * Get a Project * Returns a Project JSON object + * @endpoint get /projects/{id} * @param id Project id * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public getProjectById(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; - public getProjectById(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public getProjectById(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public getProjectById(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + public getProjectById(id: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public getProjectById(id: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getProjectById(id: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getProjectById(id: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (id === null || id === undefined) { throw new Error('Required parameter id was null or undefined when calling getProjectById.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -304,13 +227,15 @@ export class ProjectService { } let localVarPath = `/projects/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`; - return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -319,6 +244,7 @@ export class ProjectService { /** * Get project list * Returns a Project JSON object + * @endpoint get /projects * @param page * @param perPage * @param kind @@ -329,64 +255,99 @@ export class ProjectService { * @param scope Valid with kind as location, and between 1~9 * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; - public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { - - let localVarQueryParameters = new HttpParams({encoder: this.encoder}); - if (page !== undefined && page !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - page, 'page'); - } - if (perPage !== undefined && perPage !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - perPage, 'per_page'); - } - if (kind !== undefined && kind !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - kind, 'kind'); - } - if (q !== undefined && q !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - q, 'q'); - } - if (filter !== undefined && filter !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - filter, 'filter'); - } - if (latitude !== undefined && latitude !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - latitude, 'latitude'); - } - if (longitude !== undefined && longitude !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - longitude, 'longitude'); - } - if (scope !== undefined && scope !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - scope, 'scope'); - } + public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getProjectList(page?: number, perPage?: number, kind?: 'my_models' | 'published' | 'location', q?: string, filter?: string, latitude?: number, longitude?: number, scope?: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { + + let localVarQueryParameters = new OpenApiHttpParams(this.encoder); + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'page', + page, + QueryParamStyle.Form, + false, + ); + + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'per_page', + perPage, + QueryParamStyle.Form, + false, + ); + + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'kind', + kind, + QueryParamStyle.Form, + false, + ); + + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'q', + q, + QueryParamStyle.Form, + false, + ); + + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'filter', + filter, + QueryParamStyle.Form, + false, + ); + + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'latitude', + latitude, + QueryParamStyle.Form, + false, + ); + + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'longitude', + longitude, + QueryParamStyle.Form, + false, + ); + + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'scope', + scope, + QueryParamStyle.Form, + false, + ); + let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -401,14 +362,16 @@ export class ProjectService { } let localVarPath = `/projects`; - return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, - params: localVarQueryParameters, + params: localVarQueryParameters.toHttpParams(), responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -416,6 +379,7 @@ export class ProjectService { /** * Update project + * @endpoint put /projects/{id} * @param id Project id * @param name User ID * @param address Address @@ -425,33 +389,28 @@ export class ProjectService { * @param thumbnail Project thumbnail * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; - public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public updateProject(id: number, name?: string, address?: string, longitude?: number, latitude?: number, meta?: string, thumbnail?: Blob, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (id === null || id === undefined) { throw new Error('Required parameter id was null or undefined when calling updateProject.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header const consumes: string[] = [ @@ -503,14 +462,16 @@ export class ProjectService { } let localVarPath = `/projects/${this.configuration.encodeParam({name: "id", value: id, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int32"})}`; - return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('put', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/configuration.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/configuration.ts index 526b454fb2bc..2a128451c081 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/configuration.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/configuration.ts @@ -1,4 +1,4 @@ -import { HttpParameterCodec } from '@angular/common/http'; +import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http'; import { Param } from './param'; export interface ConfigurationParameters { @@ -66,26 +66,30 @@ export class Configuration { */ credentials: {[ key: string ]: string | (() => string | undefined)}; - constructor(configurationParameters: ConfigurationParameters = {}) { - this.apiKeys = configurationParameters.apiKeys; - this.username = configurationParameters.username; - this.password = configurationParameters.password; - this.accessToken = configurationParameters.accessToken; - this.basePath = configurationParameters.basePath; - this.withCredentials = configurationParameters.withCredentials; - this.encoder = configurationParameters.encoder; - if (configurationParameters.encodeParam) { - this.encodeParam = configurationParameters.encodeParam; +constructor({ accessToken, apiKeys, basePath, credentials, encodeParam, encoder, password, username, withCredentials }: ConfigurationParameters = {}) { + if (apiKeys) { + this.apiKeys = apiKeys; } - else { - this.encodeParam = param => this.defaultEncodeParam(param); + if (username !== undefined) { + this.username = username; } - if (configurationParameters.credentials) { - this.credentials = configurationParameters.credentials; + if (password !== undefined) { + this.password = password; } - else { - this.credentials = {}; + if (accessToken !== undefined) { + this.accessToken = accessToken; } + if (basePath !== undefined) { + this.basePath = basePath; + } + if (withCredentials !== undefined) { + this.withCredentials = withCredentials; + } + if (encoder) { + this.encoder = encoder; + } + this.encodeParam = encodeParam ?? (param => this.defaultEncodeParam(param)); + this.credentials = credentials ?? {}; } /** @@ -148,6 +152,20 @@ export class Configuration { : value; } + public addCredentialToHeaders(credentialKey: string, headerName: string, headers: HttpHeaders, prefix?: string): HttpHeaders { + const value = this.lookupCredential(credentialKey); + return value + ? headers.set(headerName, (prefix ?? '') + value) + : headers; + } + + public addCredentialToQuery(credentialKey: string, paramName: string, query: HttpParams): HttpParams { + const value = this.lookupCredential(credentialKey); + return value + ? query.set(paramName, value) + : query; + } + private defaultEncodeParam(param: Param): string { // This implementation exists as fallback for missing configuration // and for backwards compatibility to older typescript-angular generator versions. diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/encoder.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/encoder.ts index 138c4d5cf2c1..af4523543e6c 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/encoder.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/encoder.ts @@ -18,3 +18,18 @@ export class CustomHttpParameterCodec implements HttpParameterCodec { return decodeURIComponent(v); } } + +export class IdentityHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return k; + } + encodeValue(v: string): string { + return v; + } + decodeKey(k: string): string { + return k; + } + decodeValue(v: string): string { + return v; + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/index.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/index.ts index 104dd3d21e35..02cb7d437fbf 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/index.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/index.ts @@ -3,4 +3,5 @@ export * from './model/models'; export * from './variables'; export * from './configuration'; export * from './api.module'; +export * from './provide-api'; export * from './param'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntity.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntity.ts index a0fc28a83a40..d5a18af616eb 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntity.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntity.ts @@ -1,8 +1,6 @@ /** * Cupix API - * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) * - * The version of the OpenAPI document: 1.7.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -25,10 +23,10 @@ export interface ProjectEntity { published_at?: string; } export namespace ProjectEntity { - export type KindEnum = 'project'; export const KindEnum = { - Project: 'project' as KindEnum - }; + Project: 'project' + } as const; + export type KindEnum = typeof KindEnum[keyof typeof KindEnum]; } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntityLocation.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntityLocation.ts index 30c1aaefd5ea..07a9989d039c 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntityLocation.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectEntityLocation.ts @@ -1,8 +1,6 @@ /** * Cupix API - * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) * - * The version of the OpenAPI document: 1.7.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectList.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectList.ts index 7801e2f203c5..19f439ca6c56 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectList.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/model/projectList.ts @@ -1,8 +1,6 @@ /** * Cupix API - * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) * - * The version of the OpenAPI document: 1.7.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/package.json index e7117de5831a..583735f9c96d 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/package.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/package.json @@ -13,21 +13,22 @@ ], "license": "Unlicense", "scripts": { + "prepare": "npm run build", "build": "ng-packagr -p ng-package.json" }, "peerDependencies": { - "@angular/core": "^16.1.2", + "@angular/core": "^20.0.0", "rxjs": "^7.4.0" }, "devDependencies": { - "@angular/common": "^16.1.2", - "@angular/compiler": "^16.1.2", - "@angular/compiler-cli": "^16.1.2", - "@angular/core": "^16.1.2", - "@angular/platform-browser": "^16.1.2", - "ng-packagr": "^16.0.0", + "@angular/common": "^20.0.0", + "@angular/compiler": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "ng-packagr": "^20.0.0", "reflect-metadata": "^0.1.3", "rxjs": "^7.4.0", - "typescript": ">=4.9.3 <5.2.0", - "zone.js": "^0.13.0" + "typescript": ">=5.8.0 <5.9.0", + "zone.js": "^0.15.0" }} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/provide-api.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/provide-api.ts new file mode 100644 index 000000000000..19c762acdfe0 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/provide-api.ts @@ -0,0 +1,15 @@ +import { EnvironmentProviders, makeEnvironmentProviders } from "@angular/core"; +import { Configuration, ConfigurationParameters } from './configuration'; +import { BASE_PATH } from './variables'; + +// Returns the service class providers, to be used in the [ApplicationConfig](https://angular.dev/api/core/ApplicationConfig). +export function provideApi(configOrBasePath: string | ConfigurationParameters): EnvironmentProviders { + return makeEnvironmentProviders([ + typeof configOrBasePath === "string" + ? { provide: BASE_PATH, useValue: configOrBasePath } + : { + provide: Configuration, + useValue: new Configuration({ ...configOrBasePath }), + }, + ]); +} \ No newline at end of file diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/query.params.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/query.params.ts new file mode 100644 index 000000000000..4076c1140c83 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/query.params.ts @@ -0,0 +1,160 @@ +import { HttpParams, HttpParameterCodec } from '@angular/common/http'; +import { CustomHttpParameterCodec, IdentityHttpParameterCodec } from './encoder'; + +export enum QueryParamStyle { + Json, + Form, + DeepObject, + SpaceDelimited, + PipeDelimited, +} + +export type Delimiter = "," | " " | "|" | "\t"; + +export interface ParamOptions { + /** When true, serialized as multiple repeated key=value pairs. When false, serialized as a single key with joined values using `delimiter`. */ + explode?: boolean; + /** Delimiter used when explode=false. The delimiter itself is inserted unencoded between encoded values. */ + delimiter?: Delimiter; +} + +interface ParamEntry { + values: string[]; + options: Required; +} + +export class OpenApiHttpParams { + private params: Map = new Map(); + private defaults: Required; + private encoder: HttpParameterCodec; + + /** + * @param encoder Parameter serializer + * @param defaults Global defaults used when a specific parameter has no explicit options. + * By OpenAPI default, explode is true for query params with style=form. + */ + constructor(encoder?: HttpParameterCodec, defaults?: { explode?: boolean; delimiter?: Delimiter }) { + this.encoder = encoder || new CustomHttpParameterCodec(); + this.defaults = { + explode: defaults?.explode ?? true, + delimiter: defaults?.delimiter ?? ",", + }; + } + + private resolveOptions(local?: ParamOptions): Required { + return { + explode: local?.explode ?? this.defaults.explode, + delimiter: local?.delimiter ?? this.defaults.delimiter, + }; + } + + /** + * Replace the parameter's values and (optionally) its options. + * Options are stored per-parameter (not global). + */ + set(key: string, values: string[] | string, options?: ParamOptions): this { + const arr = Array.isArray(values) ? values.slice() : [values]; + const opts = this.resolveOptions(options); + this.params.set(key, {values: arr, options: opts}); + return this; + } + + /** + * Append a single value to the parameter. If the parameter didn't exist it will be created + * and use resolved options (global defaults merged with any provided options). + */ + append(key: string, value: string, options?: ParamOptions): this { + const entry = this.params.get(key); + if (entry) { + // If new options provided, override the stored options for subsequent serialization + if (options) { + entry.options = this.resolveOptions({...entry.options, ...options}); + } + entry.values.push(value); + } else { + this.set(key, [value], options); + } + return this; + } + + /** + * Serialize to a query string according to per-parameter OpenAPI options. + * - If explode=true for that parameter → repeated key=value pairs (each value encoded). + * - If explode=false for that parameter → single key=value where values are individually encoded + * and joined using the configured delimiter. The delimiter character is inserted AS-IS + * (not percent-encoded). + */ + toString(): string { + const records = this.toRecord(); + const parts: string[] = []; + + for (const key in records) { + parts.push(`${key}=${records[key]}`); + } + + return parts.join("&"); + } + + /** + * Return parameters as a plain record. + * - If a parameter has exactly one value, returns that value directly. + * - If a parameter has multiple values, returns a readonly array of values. + */ + toRecord(): Record> { + const parts: Record> = {}; + + for (const [key, entry] of this.params.entries()) { + const encodedKey = this.encoder.encodeKey(key); + + if (entry.options.explode) { + parts[encodedKey] = entry.values.map((v) => this.encoder.encodeValue(v)); + } else { + const encodedValues = entry.values.map((v) => this.encoder.encodeValue(v)); + + // join with the delimiter *unencoded* + parts[encodedKey] = encodedValues.join(entry.options.delimiter); + } + } + + return parts; + } + + /** + * Return an Angular's HttpParams with an identity parameter codec as the parameters are already encoded. + */ + toHttpParams(): HttpParams { + const records = this.toRecord(); + + let httpParams = new HttpParams({encoder: new IdentityHttpParameterCodec()}); + + return httpParams.appendAll(records); + } +} + +export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: string, item: { + [index: string]: any +}, delimiter: Delimiter): OpenApiHttpParams { + let keyAndValues: string[] = []; + + for (const k in item) { + keyAndValues.push(k); + + const value = item[k]; + + if (Array.isArray(value)) { + keyAndValues.push(...value.map(convertToString)); + } else { + keyAndValues.push(convertToString(value)); + } + } + + return httpParams.set(key, keyAndValues, {explode: false, delimiter: delimiter}); +} + +function convertToString(value: any): string { + if (value instanceof Date) { + return value.toISOString(); + } else { + return value.toString(); + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/tsconfig.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/tsconfig.json index 89cdedb1cb7f..eb405ea0e09f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/tsconfig.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/array-and-object-expected/tsconfig.json @@ -5,8 +5,11 @@ "noImplicitAny": false, "target": "es5", "module": "commonjs", + "downlevelIteration": true, "moduleResolution": "node", "removeComments": true, + "strictNullChecks": true, + "exactOptionalPropertyTypes": true, "sourceMap": true, "outDir": "./dist", "noLib": false, diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/README.md b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/README.md index 3dbfaf6cd40d..a111c1816151 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/README.md +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/README.md @@ -1,30 +1,35 @@ -## custom-path-params-integration-test@1.0.3 +# custom-path-params-integration-test@1.0.3 -### Building +This API shows the usage of various path parameter styles + +The version of the OpenAPI document: 1.0.0 + +## Building To install the required dependencies and to build the typescript sources run: -``` + +```console npm install npm run build ``` -### publishing +## Publishing -First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) +First build the package then run `npm publish dist` (don't forget to specify the `dist` folder!) -### consuming +## Consuming Navigate to the folder of your consuming project and run one of next commands. _published:_ -``` +```console npm install custom-path-params-integration-test@1.0.3 --save ``` _without publishing (not recommended):_ -``` +```console npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save ``` @@ -33,173 +38,126 @@ _It's important to take the tgz file, otherwise you'll get trouble with links on _using `npm link`:_ In PATH_TO_GENERATED_PACKAGE/dist: -``` + +```console npm link ``` In your project: -``` + +```console npm link custom-path-params-integration-test ``` __Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. -Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Please refer to this issue for a solution / workaround. Published packages are not effected by this issue. - -#### General usage +### General usage In your Angular project: +```typescript -``` -// without configuring providers -import { ApiModule } from 'custom-path-params-integration-test'; -import { HttpClientModule } from '@angular/common/http'; - -@NgModule({ - imports: [ - ApiModule, - // make sure to import the HttpClientModule in the AppModule only, - // see https://github.com/angular/angular/issues/20575 - HttpClientModule - ], - declarations: [ AppComponent ], - providers: [], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - -``` -// configuring providers -import { ApiModule, Configuration, ConfigurationParameters } from 'custom-path-params-integration-test'; - -export function apiConfigFactory (): Configuration { - const params: ConfigurationParameters = { - // set configuration parameters here. - } - return new Configuration(params); -} - -@NgModule({ - imports: [ ApiModule.forRoot(apiConfigFactory) ], - declarations: [ AppComponent ], - providers: [], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - -``` -// configuring providers with an authentication service that manages your access tokens -import { ApiModule, Configuration } from 'custom-path-params-integration-test'; +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'custom-path-params-integration-test'; -@NgModule({ - imports: [ ApiModule ], - declarations: [ AppComponent ], +export const appConfig: ApplicationConfig = { providers: [ - { - provide: Configuration, - useFactory: (authService: AuthService) => new Configuration( - { - basePath: environment.apiUrl, - accessToken: authService.getAccessToken.bind(authService) - } - ), - deps: [AuthService], - multi: false - } + // ... + provideHttpClient(), + provideApi() ], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - +}; ``` -import { DefaultApi } from 'custom-path-params-integration-test'; -export class AppComponent { - constructor(private apiGateway: DefaultApi) { } -} +**NOTE** +If you're still using `AppModule` and haven't [migrated](https://angular.dev/reference/migrations/standalone) yet, you can still import an Angular module: +```typescript +import { ApiModule } from 'custom-path-params-integration-test'; ``` -Note: The ApiModule is restricted to being instantiated once app wide. -This is to ensure that all services are treated as singletons. - -#### Using multiple OpenAPI files / APIs / ApiModules -In order to use multiple `ApiModules` generated from different OpenAPI files, -you can create an alias name when importing the modules -in order to avoid naming conflicts: -``` -import { ApiModule } from 'my-api-path'; -import { ApiModule as OtherApiModule } from 'my-other-api-path'; -import { HttpClientModule } from '@angular/common/http'; +If different from the generated base path, during app bootstrap, you can provide the base path to your service. -@NgModule({ - imports: [ - ApiModule, - OtherApiModule, - // make sure to import the HttpClientModule in the AppModule only, - // see https://github.com/angular/angular/issues/20575 - HttpClientModule - ] -}) -export class AppModule { +```typescript +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'custom-path-params-integration-test'; -} +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideApi('http://localhost:9999') + ], +}; ``` +```typescript +// with a custom configuration +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'custom-path-params-integration-test'; -### Set service base path -If different than the generated base path, during app bootstrap, you can provide the base path to your service. - -``` -import { BASE_PATH } from 'custom-path-params-integration-test'; - -bootstrap(AppComponent, [ - { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, -]); +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideApi({ + withCredentials: true, + username: 'user', + password: 'password' + }) + ], +}; ``` -or -``` -import { BASE_PATH } from 'custom-path-params-integration-test'; +```typescript +// with factory building a custom configuration +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi, Configuration } from 'custom-path-params-integration-test'; -@NgModule({ - imports: [], - declarations: [ AppComponent ], - providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], - bootstrap: [ AppComponent ] -}) -export class AppModule {} +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + { + provide: Configuration, + useFactory: (authService: AuthService) => new Configuration({ + basePath: 'http://localhost:9999', + withCredentials: true, + username: authService.getUsername(), + password: authService.getPassword(), + }), + deps: [AuthService], + multi: false + } + ], +}; ``` +### Using multiple OpenAPI files / APIs -#### Using @angular/cli -First extend your `src/environments/*.ts` files by adding the corresponding base path: - -``` -export const environment = { - production: false, - API_BASE_PATH: 'http://127.0.0.1:8080' -}; -``` +In order to use multiple APIs generated from different OpenAPI files, +you can create an alias name when importing the modules +in order to avoid naming conflicts: -In the src/app/app.module.ts: -``` -import { BASE_PATH } from 'custom-path-params-integration-test'; +```typescript +import { provideApi as provideUserApi } from 'my-user-api-path'; +import { provideApi as provideAdminApi } from 'my-admin-api-path'; +import { HttpClientModule } from '@angular/common/http'; import { environment } from '../environments/environment'; -@NgModule({ - declarations: [ - AppComponent - ], - imports: [ ], - providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], - bootstrap: [ AppComponent ] -}) -export class AppModule { } +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideUserApi(environment.basePath), + provideAdminApi(environment.basePath), + ], +}; ``` ### Customizing path parameter encoding @@ -215,6 +173,7 @@ pass an arrow-function or method-reference to the `encodeParam` property of the (see [General Usage](#general-usage) above). Example value for use in your Configuration-Provider: + ```typescript new Configuration({ encodeParam: (param: Param) => myFancyParamEncoder(param), diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api.base.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api.base.service.ts new file mode 100644 index 000000000000..7d64e8080b4b --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api.base.service.ts @@ -0,0 +1,95 @@ +/** + * Path Parameter Stuff + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http'; +import { CustomHttpParameterCodec } from './encoder'; +import { Configuration } from './configuration'; +import { OpenApiHttpParams, QueryParamStyle, concatHttpParamsObject} from './query.params'; + +export class BaseService { + protected basePath = 'http://localhost'; + public defaultHeaders = new HttpHeaders(); + public configuration: Configuration; + public encoder: HttpParameterCodec; + + constructor(basePath?: string|string[], configuration?: Configuration) { + this.configuration = configuration || new Configuration(); + if (typeof this.configuration.basePath !== 'string') { + const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined; + if (firstBasePath != undefined) { + basePath = firstBasePath; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + protected canConsumeForm(consumes: string[]): boolean { + return consumes.indexOf('multipart/form-data') !== -1; + } + + protected addToHttpParams(httpParams: OpenApiHttpParams, key: string, value: any | null | undefined, paramStyle: QueryParamStyle, explode: boolean): OpenApiHttpParams { + if (value === null || value === undefined) { + return httpParams; + } + + if (paramStyle === QueryParamStyle.DeepObject) { + if (typeof value !== 'object') { + throw Error(`An object must be provided for key ${key} as it is a deep object`); + } + + return Object.keys(value as Record).reduce( + (hp, k) => hp.append(`${key}[${k}]`, value[k]), + httpParams, + ); + } else if (paramStyle === QueryParamStyle.Json) { + return httpParams.append(key, JSON.stringify(value)); + } else { + // Form-style, SpaceDelimited or PipeDelimited + + if (Object(value) !== value) { + // If it is a primitive type, add its string representation + return httpParams.append(key, value.toString()); + } else if (value instanceof Date) { + return httpParams.append(key, value.toISOString()); + } else if (Array.isArray(value)) { + // Otherwise, if it's an array, add each element. + if (paramStyle === QueryParamStyle.Form) { + return httpParams.set(key, value, {explode: explode, delimiter: ','}); + } else if (paramStyle === QueryParamStyle.SpaceDelimited) { + return httpParams.set(key, value, {explode: explode, delimiter: ' '}); + } else { + // PipeDelimited + return httpParams.set(key, value, {explode: explode, delimiter: '|'}); + } + } else { + // Otherwise, if it's an object, add each field. + if (paramStyle === QueryParamStyle.Form) { + if (explode) { + Object.keys(value).forEach(k => { + httpParams = this.addToHttpParams(httpParams, k, value[k], paramStyle, explode); + }); + return httpParams; + } else { + return concatHttpParamsObject(httpParams, key, value, ','); + } + } else if (paramStyle === QueryParamStyle.SpaceDelimited) { + return concatHttpParamsObject(httpParams, key, value, ' '); + } else { + // PipeDelimited + return concatHttpParamsObject(httpParams, key, value, '|'); + } + } + } + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/matrixParams.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/matrixParams.service.ts index 7a6d7d566120..d930f463f46f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/matrixParams.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/api/matrixParams.service.ts @@ -1,8 +1,6 @@ /** * Path Parameter Stuff - * This API shows the usage of various path parameter styles * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -13,10 +11,10 @@ import { Inject, Injectable, Optional } from '@angular/core'; import { HttpClient, HttpHeaders, HttpParams, - HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + HttpResponse, HttpEvent, HttpContext } from '@angular/common/http'; -import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +import { OpenApiHttpParams, QueryParamStyle } from '../query.params'; // @ts-ignore import { ComplexParams } from '../model/complexParams'; @@ -24,100 +22,42 @@ import { ComplexParams } from '../model/complexParams'; // @ts-ignore import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; import { Configuration } from '../configuration'; +import { BaseService } from '../api.base.service'; @Injectable({ providedIn: 'root' }) -export class MatrixParamsService { +export class MatrixParamsService extends BaseService { - protected basePath = 'http://localhost'; - public defaultHeaders = new HttpHeaders(); - public configuration = new Configuration(); - public encoder: HttpParameterCodec; - - constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { - if (configuration) { - this.configuration = configuration; - } - if (typeof this.configuration.basePath !== 'string') { - if (Array.isArray(basePath) && basePath.length > 0) { - basePath = basePath[0]; - } - - if (typeof basePath !== 'string') { - basePath = this.basePath; - } - this.configuration.basePath = basePath; - } - this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); - } - - - // @ts-ignore - private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { - if (typeof value === "object" && value instanceof Date === false) { - httpParams = this.addToHttpParamsRecursive(httpParams, value); - } else { - httpParams = this.addToHttpParamsRecursive(httpParams, value, key); - } - return httpParams; - } - - private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { - if (value == null) { - return httpParams; - } - - if (typeof value === "object") { - if (Array.isArray(value)) { - (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); - } else if (value instanceof Date) { - if (key != null) { - httpParams = httpParams.append(key, (value as Date).toISOString().substring(0, 10)); - } else { - throw Error("key may not be null if value is Date"); - } - } else { - Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( - httpParams, value[k], key != null ? `${key}.${k}` : k)); - } - } else if (key != null) { - httpParams = httpParams.append(key, value); - } else { - throw Error("key may not be null if value is not object or array"); - } - return httpParams; + constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) { + super(basePath, configuration); } /** + * @endpoint put /complexMatrixParamExploded{matrixParamExploded} * @param matrixParamExploded * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public complexMatrixParamExploded(matrixParamExploded?: ComplexParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -132,45 +72,43 @@ export class MatrixParamsService { } let localVarPath = `/complexMatrixParamExploded${this.configuration.encodeParam({name: "matrixParamExploded", value: matrixParamExploded, in: "path", style: "matrix", explode: true, dataType: "ComplexParams", dataFormat: undefined})}`; - return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('put', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); } /** + * @endpoint put /complexMatrixParamFlat{matrixParamFlat} * @param matrixParamFlat * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public complexMatrixParamFlat(matrixParamFlat?: ComplexParams, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -185,45 +123,43 @@ export class MatrixParamsService { } let localVarPath = `/complexMatrixParamFlat${this.configuration.encodeParam({name: "matrixParamFlat", value: matrixParamFlat, in: "path", style: "matrix", explode: false, dataType: "ComplexParams", dataFormat: undefined})}`; - return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('put', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); } /** + * @endpoint put /plainMatrixParamFlat{plainParamFlat} * @param plainParamFlat * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public plainMatrixParamFlat(plainParamFlat?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public plainMatrixParamFlat(plainParamFlat?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public plainMatrixParamFlat(plainParamFlat?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public plainMatrixParamFlat(plainParamFlat?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public plainMatrixParamFlat(plainParamFlat?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public plainMatrixParamFlat(plainParamFlat?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public plainMatrixParamFlat(plainParamFlat?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public plainMatrixParamFlat(plainParamFlat?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -238,45 +174,43 @@ export class MatrixParamsService { } let localVarPath = `/plainMatrixParamFlat${this.configuration.encodeParam({name: "plainParamFlat", value: plainParamFlat, in: "path", style: "matrix", explode: false, dataType: "string", dataFormat: undefined})}`; - return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('put', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); } /** + * @endpoint put /date-timeMatrixParamFlat{dateTimeParamFlat} * @param dateTimeParamFlat * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public plainMatrixParamFlat_1(dateTimeParamFlat?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -291,13 +225,15 @@ export class MatrixParamsService { } let localVarPath = `/date-timeMatrixParamFlat${this.configuration.encodeParam({name: "dateTimeParamFlat", value: dateTimeParamFlat, in: "path", style: "matrix", explode: false, dataType: "string", dataFormat: "date-time"})}`; - return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('put', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/configuration.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/configuration.ts index 526b454fb2bc..2a128451c081 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/configuration.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/configuration.ts @@ -1,4 +1,4 @@ -import { HttpParameterCodec } from '@angular/common/http'; +import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http'; import { Param } from './param'; export interface ConfigurationParameters { @@ -66,26 +66,30 @@ export class Configuration { */ credentials: {[ key: string ]: string | (() => string | undefined)}; - constructor(configurationParameters: ConfigurationParameters = {}) { - this.apiKeys = configurationParameters.apiKeys; - this.username = configurationParameters.username; - this.password = configurationParameters.password; - this.accessToken = configurationParameters.accessToken; - this.basePath = configurationParameters.basePath; - this.withCredentials = configurationParameters.withCredentials; - this.encoder = configurationParameters.encoder; - if (configurationParameters.encodeParam) { - this.encodeParam = configurationParameters.encodeParam; +constructor({ accessToken, apiKeys, basePath, credentials, encodeParam, encoder, password, username, withCredentials }: ConfigurationParameters = {}) { + if (apiKeys) { + this.apiKeys = apiKeys; } - else { - this.encodeParam = param => this.defaultEncodeParam(param); + if (username !== undefined) { + this.username = username; } - if (configurationParameters.credentials) { - this.credentials = configurationParameters.credentials; + if (password !== undefined) { + this.password = password; } - else { - this.credentials = {}; + if (accessToken !== undefined) { + this.accessToken = accessToken; } + if (basePath !== undefined) { + this.basePath = basePath; + } + if (withCredentials !== undefined) { + this.withCredentials = withCredentials; + } + if (encoder) { + this.encoder = encoder; + } + this.encodeParam = encodeParam ?? (param => this.defaultEncodeParam(param)); + this.credentials = credentials ?? {}; } /** @@ -148,6 +152,20 @@ export class Configuration { : value; } + public addCredentialToHeaders(credentialKey: string, headerName: string, headers: HttpHeaders, prefix?: string): HttpHeaders { + const value = this.lookupCredential(credentialKey); + return value + ? headers.set(headerName, (prefix ?? '') + value) + : headers; + } + + public addCredentialToQuery(credentialKey: string, paramName: string, query: HttpParams): HttpParams { + const value = this.lookupCredential(credentialKey); + return value + ? query.set(paramName, value) + : query; + } + private defaultEncodeParam(param: Param): string { // This implementation exists as fallback for missing configuration // and for backwards compatibility to older typescript-angular generator versions. diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/encoder.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/encoder.ts index 138c4d5cf2c1..af4523543e6c 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/encoder.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/encoder.ts @@ -18,3 +18,18 @@ export class CustomHttpParameterCodec implements HttpParameterCodec { return decodeURIComponent(v); } } + +export class IdentityHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return k; + } + encodeValue(v: string): string { + return v; + } + decodeKey(k: string): string { + return k; + } + decodeValue(v: string): string { + return v; + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/index.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/index.ts index 104dd3d21e35..02cb7d437fbf 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/index.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/index.ts @@ -3,4 +3,5 @@ export * from './model/models'; export * from './variables'; export * from './configuration'; export * from './api.module'; +export * from './provide-api'; export * from './param'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/complexParams.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/complexParams.ts index bed1db7a6eec..2b94af8186ae 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/complexParams.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/model/complexParams.ts @@ -1,8 +1,6 @@ /** * Path Parameter Stuff - * This API shows the usage of various path parameter styles * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/package.json index 61b2cb17bde1..043e51b38cee 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/package.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/package.json @@ -13,21 +13,22 @@ ], "license": "Unlicense", "scripts": { + "prepare": "npm run build", "build": "ng-packagr -p ng-package.json" }, "peerDependencies": { - "@angular/core": "^16.1.2", + "@angular/core": "^20.0.0", "rxjs": "^7.4.0" }, "devDependencies": { - "@angular/common": "^16.1.2", - "@angular/compiler": "^16.1.2", - "@angular/compiler-cli": "^16.1.2", - "@angular/core": "^16.1.2", - "@angular/platform-browser": "^16.1.2", - "ng-packagr": "^16.0.0", + "@angular/common": "^20.0.0", + "@angular/compiler": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "ng-packagr": "^20.0.0", "reflect-metadata": "^0.1.3", "rxjs": "^7.4.0", - "typescript": ">=4.9.3 <5.2.0", - "zone.js": "^0.13.0" + "typescript": ">=5.8.0 <5.9.0", + "zone.js": "^0.15.0" }} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/provide-api.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/provide-api.ts new file mode 100644 index 000000000000..19c762acdfe0 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/provide-api.ts @@ -0,0 +1,15 @@ +import { EnvironmentProviders, makeEnvironmentProviders } from "@angular/core"; +import { Configuration, ConfigurationParameters } from './configuration'; +import { BASE_PATH } from './variables'; + +// Returns the service class providers, to be used in the [ApplicationConfig](https://angular.dev/api/core/ApplicationConfig). +export function provideApi(configOrBasePath: string | ConfigurationParameters): EnvironmentProviders { + return makeEnvironmentProviders([ + typeof configOrBasePath === "string" + ? { provide: BASE_PATH, useValue: configOrBasePath } + : { + provide: Configuration, + useValue: new Configuration({ ...configOrBasePath }), + }, + ]); +} \ No newline at end of file diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/query.params.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/query.params.ts new file mode 100644 index 000000000000..4076c1140c83 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/query.params.ts @@ -0,0 +1,160 @@ +import { HttpParams, HttpParameterCodec } from '@angular/common/http'; +import { CustomHttpParameterCodec, IdentityHttpParameterCodec } from './encoder'; + +export enum QueryParamStyle { + Json, + Form, + DeepObject, + SpaceDelimited, + PipeDelimited, +} + +export type Delimiter = "," | " " | "|" | "\t"; + +export interface ParamOptions { + /** When true, serialized as multiple repeated key=value pairs. When false, serialized as a single key with joined values using `delimiter`. */ + explode?: boolean; + /** Delimiter used when explode=false. The delimiter itself is inserted unencoded between encoded values. */ + delimiter?: Delimiter; +} + +interface ParamEntry { + values: string[]; + options: Required; +} + +export class OpenApiHttpParams { + private params: Map = new Map(); + private defaults: Required; + private encoder: HttpParameterCodec; + + /** + * @param encoder Parameter serializer + * @param defaults Global defaults used when a specific parameter has no explicit options. + * By OpenAPI default, explode is true for query params with style=form. + */ + constructor(encoder?: HttpParameterCodec, defaults?: { explode?: boolean; delimiter?: Delimiter }) { + this.encoder = encoder || new CustomHttpParameterCodec(); + this.defaults = { + explode: defaults?.explode ?? true, + delimiter: defaults?.delimiter ?? ",", + }; + } + + private resolveOptions(local?: ParamOptions): Required { + return { + explode: local?.explode ?? this.defaults.explode, + delimiter: local?.delimiter ?? this.defaults.delimiter, + }; + } + + /** + * Replace the parameter's values and (optionally) its options. + * Options are stored per-parameter (not global). + */ + set(key: string, values: string[] | string, options?: ParamOptions): this { + const arr = Array.isArray(values) ? values.slice() : [values]; + const opts = this.resolveOptions(options); + this.params.set(key, {values: arr, options: opts}); + return this; + } + + /** + * Append a single value to the parameter. If the parameter didn't exist it will be created + * and use resolved options (global defaults merged with any provided options). + */ + append(key: string, value: string, options?: ParamOptions): this { + const entry = this.params.get(key); + if (entry) { + // If new options provided, override the stored options for subsequent serialization + if (options) { + entry.options = this.resolveOptions({...entry.options, ...options}); + } + entry.values.push(value); + } else { + this.set(key, [value], options); + } + return this; + } + + /** + * Serialize to a query string according to per-parameter OpenAPI options. + * - If explode=true for that parameter → repeated key=value pairs (each value encoded). + * - If explode=false for that parameter → single key=value where values are individually encoded + * and joined using the configured delimiter. The delimiter character is inserted AS-IS + * (not percent-encoded). + */ + toString(): string { + const records = this.toRecord(); + const parts: string[] = []; + + for (const key in records) { + parts.push(`${key}=${records[key]}`); + } + + return parts.join("&"); + } + + /** + * Return parameters as a plain record. + * - If a parameter has exactly one value, returns that value directly. + * - If a parameter has multiple values, returns a readonly array of values. + */ + toRecord(): Record> { + const parts: Record> = {}; + + for (const [key, entry] of this.params.entries()) { + const encodedKey = this.encoder.encodeKey(key); + + if (entry.options.explode) { + parts[encodedKey] = entry.values.map((v) => this.encoder.encodeValue(v)); + } else { + const encodedValues = entry.values.map((v) => this.encoder.encodeValue(v)); + + // join with the delimiter *unencoded* + parts[encodedKey] = encodedValues.join(entry.options.delimiter); + } + } + + return parts; + } + + /** + * Return an Angular's HttpParams with an identity parameter codec as the parameters are already encoded. + */ + toHttpParams(): HttpParams { + const records = this.toRecord(); + + let httpParams = new HttpParams({encoder: new IdentityHttpParameterCodec()}); + + return httpParams.appendAll(records); + } +} + +export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: string, item: { + [index: string]: any +}, delimiter: Delimiter): OpenApiHttpParams { + let keyAndValues: string[] = []; + + for (const k in item) { + keyAndValues.push(k); + + const value = item[k]; + + if (Array.isArray(value)) { + keyAndValues.push(...value.map(convertToString)); + } else { + keyAndValues.push(convertToString(value)); + } + } + + return httpParams.set(key, keyAndValues, {explode: false, delimiter: delimiter}); +} + +function convertToString(value: any): string { + if (value instanceof Date) { + return value.toISOString(); + } else { + return value.toString(); + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/tsconfig.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/tsconfig.json index 89cdedb1cb7f..eb405ea0e09f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/tsconfig.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/custom-path-params-expected/tsconfig.json @@ -5,8 +5,11 @@ "noImplicitAny": false, "target": "es5", "module": "commonjs", + "downlevelIteration": true, "moduleResolution": "node", "removeComments": true, + "strictNullChecks": true, + "exactOptionalPropertyTypes": true, "sourceMap": true, "outDir": "./dist", "noLib": false, diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/README.md b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/README.md index 5865977635e5..5dd1ce243b41 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/README.md +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/README.md @@ -1,30 +1,35 @@ -## petstore-integration-test@1.0.3 +# petstore-integration-test@1.0.3 -### Building +This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. + +The version of the OpenAPI document: 1.0.0 + +## Building To install the required dependencies and to build the typescript sources run: -``` + +```console npm install npm run build ``` -### publishing +## Publishing -First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!) +First build the package then run `npm publish dist` (don't forget to specify the `dist` folder!) -### consuming +## Consuming Navigate to the folder of your consuming project and run one of next commands. _published:_ -``` +```console npm install petstore-integration-test@1.0.3 --save ``` _without publishing (not recommended):_ -``` +```console npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save ``` @@ -33,173 +38,126 @@ _It's important to take the tgz file, otherwise you'll get trouble with links on _using `npm link`:_ In PATH_TO_GENERATED_PACKAGE/dist: -``` + +```console npm link ``` In your project: -``` + +```console npm link petstore-integration-test ``` __Note for Windows users:__ The Angular CLI has troubles to use linked npm packages. -Please refer to this issue https://github.com/angular/angular-cli/issues/8284 for a solution / workaround. +Please refer to this issue for a solution / workaround. Published packages are not effected by this issue. - -#### General usage +### General usage In your Angular project: +```typescript -``` -// without configuring providers -import { ApiModule } from 'petstore-integration-test'; -import { HttpClientModule } from '@angular/common/http'; - -@NgModule({ - imports: [ - ApiModule, - // make sure to import the HttpClientModule in the AppModule only, - // see https://github.com/angular/angular/issues/20575 - HttpClientModule - ], - declarations: [ AppComponent ], - providers: [], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - -``` -// configuring providers -import { ApiModule, Configuration, ConfigurationParameters } from 'petstore-integration-test'; - -export function apiConfigFactory (): Configuration { - const params: ConfigurationParameters = { - // set configuration parameters here. - } - return new Configuration(params); -} - -@NgModule({ - imports: [ ApiModule.forRoot(apiConfigFactory) ], - declarations: [ AppComponent ], - providers: [], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - -``` -// configuring providers with an authentication service that manages your access tokens -import { ApiModule, Configuration } from 'petstore-integration-test'; +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'petstore-integration-test'; -@NgModule({ - imports: [ ApiModule ], - declarations: [ AppComponent ], +export const appConfig: ApplicationConfig = { providers: [ - { - provide: Configuration, - useFactory: (authService: AuthService) => new Configuration( - { - basePath: environment.apiUrl, - accessToken: authService.getAccessToken.bind(authService) - } - ), - deps: [AuthService], - multi: false - } + // ... + provideHttpClient(), + provideApi() ], - bootstrap: [ AppComponent ] -}) -export class AppModule {} -``` - +}; ``` -import { DefaultApi } from 'petstore-integration-test'; -export class AppComponent { - constructor(private apiGateway: DefaultApi) { } -} +**NOTE** +If you're still using `AppModule` and haven't [migrated](https://angular.dev/reference/migrations/standalone) yet, you can still import an Angular module: +```typescript +import { ApiModule } from 'petstore-integration-test'; ``` -Note: The ApiModule is restricted to being instantiated once app wide. -This is to ensure that all services are treated as singletons. - -#### Using multiple OpenAPI files / APIs / ApiModules -In order to use multiple `ApiModules` generated from different OpenAPI files, -you can create an alias name when importing the modules -in order to avoid naming conflicts: -``` -import { ApiModule } from 'my-api-path'; -import { ApiModule as OtherApiModule } from 'my-other-api-path'; -import { HttpClientModule } from '@angular/common/http'; +If different from the generated base path, during app bootstrap, you can provide the base path to your service. -@NgModule({ - imports: [ - ApiModule, - OtherApiModule, - // make sure to import the HttpClientModule in the AppModule only, - // see https://github.com/angular/angular/issues/20575 - HttpClientModule - ] -}) -export class AppModule { +```typescript +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'petstore-integration-test'; -} +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideApi('http://localhost:9999') + ], +}; ``` +```typescript +// with a custom configuration +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi } from 'petstore-integration-test'; -### Set service base path -If different than the generated base path, during app bootstrap, you can provide the base path to your service. - -``` -import { BASE_PATH } from 'petstore-integration-test'; - -bootstrap(AppComponent, [ - { provide: BASE_PATH, useValue: 'https://your-web-service.com' }, -]); +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideApi({ + withCredentials: true, + username: 'user', + password: 'password' + }) + ], +}; ``` -or -``` -import { BASE_PATH } from 'petstore-integration-test'; +```typescript +// with factory building a custom configuration +import { ApplicationConfig } from '@angular/core'; +import { provideHttpClient } from '@angular/common/http'; +import { provideApi, Configuration } from 'petstore-integration-test'; -@NgModule({ - imports: [], - declarations: [ AppComponent ], - providers: [ provide: BASE_PATH, useValue: 'https://your-web-service.com' ], - bootstrap: [ AppComponent ] -}) -export class AppModule {} +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + { + provide: Configuration, + useFactory: (authService: AuthService) => new Configuration({ + basePath: 'http://localhost:9999', + withCredentials: true, + username: authService.getUsername(), + password: authService.getPassword(), + }), + deps: [AuthService], + multi: false + } + ], +}; ``` +### Using multiple OpenAPI files / APIs -#### Using @angular/cli -First extend your `src/environments/*.ts` files by adding the corresponding base path: - -``` -export const environment = { - production: false, - API_BASE_PATH: 'http://127.0.0.1:8080' -}; -``` +In order to use multiple APIs generated from different OpenAPI files, +you can create an alias name when importing the modules +in order to avoid naming conflicts: -In the src/app/app.module.ts: -``` -import { BASE_PATH } from 'petstore-integration-test'; +```typescript +import { provideApi as provideUserApi } from 'my-user-api-path'; +import { provideApi as provideAdminApi } from 'my-admin-api-path'; +import { HttpClientModule } from '@angular/common/http'; import { environment } from '../environments/environment'; -@NgModule({ - declarations: [ - AppComponent - ], - imports: [ ], - providers: [{ provide: BASE_PATH, useValue: environment.API_BASE_PATH }], - bootstrap: [ AppComponent ] -}) -export class AppModule { } +export const appConfig: ApplicationConfig = { + providers: [ + // ... + provideHttpClient(), + provideUserApi(environment.basePath), + provideAdminApi(environment.basePath), + ], +}; ``` ### Customizing path parameter encoding @@ -215,6 +173,7 @@ pass an arrow-function or method-reference to the `encodeParam` property of the (see [General Usage](#general-usage) above). Example value for use in your Configuration-Provider: + ```typescript new Configuration({ encodeParam: (param: Param) => myFancyParamEncoder(param), diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api.base.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api.base.service.ts new file mode 100644 index 000000000000..225e5863dcf2 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api.base.service.ts @@ -0,0 +1,95 @@ +/** + * OpenAPI Petstore + * + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ +import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http'; +import { CustomHttpParameterCodec } from './encoder'; +import { Configuration } from './configuration'; +import { OpenApiHttpParams, QueryParamStyle, concatHttpParamsObject} from './query.params'; + +export class BaseService { + protected basePath = 'http://petstore.swagger.io/v2'; + public defaultHeaders = new HttpHeaders(); + public configuration: Configuration; + public encoder: HttpParameterCodec; + + constructor(basePath?: string|string[], configuration?: Configuration) { + this.configuration = configuration || new Configuration(); + if (typeof this.configuration.basePath !== 'string') { + const firstBasePath = Array.isArray(basePath) ? basePath[0] : undefined; + if (firstBasePath != undefined) { + basePath = firstBasePath; + } + + if (typeof basePath !== 'string') { + basePath = this.basePath; + } + this.configuration.basePath = basePath; + } + this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); + } + + protected canConsumeForm(consumes: string[]): boolean { + return consumes.indexOf('multipart/form-data') !== -1; + } + + protected addToHttpParams(httpParams: OpenApiHttpParams, key: string, value: any | null | undefined, paramStyle: QueryParamStyle, explode: boolean): OpenApiHttpParams { + if (value === null || value === undefined) { + return httpParams; + } + + if (paramStyle === QueryParamStyle.DeepObject) { + if (typeof value !== 'object') { + throw Error(`An object must be provided for key ${key} as it is a deep object`); + } + + return Object.keys(value as Record).reduce( + (hp, k) => hp.append(`${key}[${k}]`, value[k]), + httpParams, + ); + } else if (paramStyle === QueryParamStyle.Json) { + return httpParams.append(key, JSON.stringify(value)); + } else { + // Form-style, SpaceDelimited or PipeDelimited + + if (Object(value) !== value) { + // If it is a primitive type, add its string representation + return httpParams.append(key, value.toString()); + } else if (value instanceof Date) { + return httpParams.append(key, value.toISOString()); + } else if (Array.isArray(value)) { + // Otherwise, if it's an array, add each element. + if (paramStyle === QueryParamStyle.Form) { + return httpParams.set(key, value, {explode: explode, delimiter: ','}); + } else if (paramStyle === QueryParamStyle.SpaceDelimited) { + return httpParams.set(key, value, {explode: explode, delimiter: ' '}); + } else { + // PipeDelimited + return httpParams.set(key, value, {explode: explode, delimiter: '|'}); + } + } else { + // Otherwise, if it's an object, add each field. + if (paramStyle === QueryParamStyle.Form) { + if (explode) { + Object.keys(value).forEach(k => { + httpParams = this.addToHttpParams(httpParams, k, value[k], paramStyle, explode); + }); + return httpParams; + } else { + return concatHttpParamsObject(httpParams, key, value, ','); + } + } else if (paramStyle === QueryParamStyle.SpaceDelimited) { + return concatHttpParamsObject(httpParams, key, value, ' '); + } else { + // PipeDelimited + return concatHttpParamsObject(httpParams, key, value, '|'); + } + } + } + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/pet.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/pet.service.ts index 01fbba4fbf3d..e0dc20938920 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/pet.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/pet.service.ts @@ -1,8 +1,6 @@ /** * OpenAPI Petstore - * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -13,10 +11,10 @@ import { Inject, Injectable, Optional } from '@angular/core'; import { HttpClient, HttpHeaders, HttpParams, - HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + HttpResponse, HttpEvent, HttpContext } from '@angular/common/http'; -import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +import { OpenApiHttpParams, QueryParamStyle } from '../query.params'; // @ts-ignore import { ApiResponse } from '../model/apiResponse'; @@ -26,124 +24,49 @@ import { Pet } from '../model/pet'; // @ts-ignore import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; import { Configuration } from '../configuration'; +import { BaseService } from '../api.base.service'; @Injectable({ providedIn: 'root' }) -export class PetService { +export class PetService extends BaseService { - protected basePath = 'http://petstore.swagger.io/v2'; - public defaultHeaders = new HttpHeaders(); - public configuration = new Configuration(); - public encoder: HttpParameterCodec; - - constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { - if (configuration) { - this.configuration = configuration; - } - if (typeof this.configuration.basePath !== 'string') { - if (Array.isArray(basePath) && basePath.length > 0) { - basePath = basePath[0]; - } - - if (typeof basePath !== 'string') { - basePath = this.basePath; - } - this.configuration.basePath = basePath; - } - this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); - } - - /** - * @param consumes string[] mime-types - * @return true: consumes contains 'multipart/form-data', false: otherwise - */ - private canConsumeForm(consumes: string[]): boolean { - const form = 'multipart/form-data'; - for (const consume of consumes) { - if (form === consume) { - return true; - } - } - return false; - } - - // @ts-ignore - private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { - if (typeof value === "object" && value instanceof Date === false) { - httpParams = this.addToHttpParamsRecursive(httpParams, value); - } else { - httpParams = this.addToHttpParamsRecursive(httpParams, value, key); - } - return httpParams; - } - - private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { - if (value == null) { - return httpParams; - } - - if (typeof value === "object") { - if (Array.isArray(value)) { - (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); - } else if (value instanceof Date) { - if (key != null) { - httpParams = httpParams.append(key, (value as Date).toISOString().substring(0, 10)); - } else { - throw Error("key may not be null if value is Date"); - } - } else { - Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( - httpParams, value[k], key != null ? `${key}.${k}` : k)); - } - } else if (key != null) { - httpParams = httpParams.append(key, value); - } else { - throw Error("key may not be null if value is not object or array"); - } - return httpParams; + constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) { + super(basePath, configuration); } /** * Add a new pet to the store + * @endpoint post /pet * @param body Pet object that needs to be added to the store * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public addPet(body: Pet, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public addPet(body: Pet, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public addPet(body: Pet, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public addPet(body: Pet, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public addPet(body: Pet, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public addPet(body: Pet, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public addPet(body: Pet, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public addPet(body: Pet, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling addPet.'); } let localVarHeaders = this.defaultHeaders; - let localVarCredential: string | undefined; // authentication (petstore_auth) required - localVarCredential = this.configuration.lookupCredential('petstore_auth'); - if (localVarCredential) { - localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); - } + localVarHeaders = this.configuration.addCredentialToHeaders('petstore_auth', 'Authorization', localVarHeaders, 'Bearer '); - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header @@ -168,14 +91,16 @@ export class PetService { } let localVarPath = `/pet`; - return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('post', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: body, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -183,15 +108,17 @@ export class PetService { /** * Deletes a pet + * @endpoint delete /pet/{petId} * @param petId Pet id to delete * @param apiKey * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public deletePet(petId: number, apiKey?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public deletePet(petId: number, apiKey?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public deletePet(petId: number, apiKey?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public deletePet(petId: number, apiKey?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public deletePet(petId: number, apiKey?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public deletePet(petId: number, apiKey?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public deletePet(petId: number, apiKey?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public deletePet(petId: number, apiKey?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (petId === null || petId === undefined) { throw new Error('Required parameter petId was null or undefined when calling deletePet.'); } @@ -201,28 +128,18 @@ export class PetService { localVarHeaders = localVarHeaders.set('api_key', String(apiKey)); } - let localVarCredential: string | undefined; // authentication (petstore_auth) required - localVarCredential = this.configuration.lookupCredential('petstore_auth'); - if (localVarCredential) { - localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); - } + localVarHeaders = this.configuration.addCredentialToHeaders('petstore_auth', 'Authorization', localVarHeaders, 'Bearer '); - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -237,13 +154,15 @@ export class PetService { } let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; - return this.httpClient.request('delete', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('delete', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -252,50 +171,47 @@ export class PetService { /** * Finds Pets by status * Multiple status values can be provided with comma separated strings + * @endpoint get /pet/findByStatus * @param status Status values that need to be considered for filter * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; - public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; - public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (status === null || status === undefined) { throw new Error('Required parameter status was null or undefined when calling findPetsByStatus.'); } - let localVarQueryParameters = new HttpParams({encoder: this.encoder}); - if (status) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - [...status].join(COLLECTION_FORMATS['csv']), 'status'); - } + let localVarQueryParameters = new OpenApiHttpParams(this.encoder); + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'status', + status, + QueryParamStyle.Form, + false, + ); + let localVarHeaders = this.defaultHeaders; - let localVarCredential: string | undefined; // authentication (petstore_auth) required - localVarCredential = this.configuration.lookupCredential('petstore_auth'); - if (localVarCredential) { - localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); - } + localVarHeaders = this.configuration.addCredentialToHeaders('petstore_auth', 'Authorization', localVarHeaders, 'Bearer '); - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/xml', - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/xml', + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -310,14 +226,16 @@ export class PetService { } let localVarPath = `/pet/findByStatus`; - return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request>('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, - params: localVarQueryParameters, + params: localVarQueryParameters.toHttpParams(), responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -326,50 +244,47 @@ export class PetService { /** * Finds Pets by tags * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + * @endpoint get /pet/findByTags * @param tags Tags to filter by * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public findPetsByTags(tags: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public findPetsByTags(tags: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; - public findPetsByTags(tags: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>>; - public findPetsByTags(tags: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + public findPetsByTags(tags: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public findPetsByTags(tags: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public findPetsByTags(tags: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>>; + public findPetsByTags(tags: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (tags === null || tags === undefined) { throw new Error('Required parameter tags was null or undefined when calling findPetsByTags.'); } - let localVarQueryParameters = new HttpParams({encoder: this.encoder}); - if (tags) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - [...tags].join(COLLECTION_FORMATS['csv']), 'tags'); - } + let localVarQueryParameters = new OpenApiHttpParams(this.encoder); + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'tags', + tags, + QueryParamStyle.Form, + false, + ); + let localVarHeaders = this.defaultHeaders; - let localVarCredential: string | undefined; // authentication (petstore_auth) required - localVarCredential = this.configuration.lookupCredential('petstore_auth'); - if (localVarCredential) { - localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); - } + localVarHeaders = this.configuration.addCredentialToHeaders('petstore_auth', 'Authorization', localVarHeaders, 'Bearer '); - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/xml', - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/xml', + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -384,14 +299,16 @@ export class PetService { } let localVarPath = `/pet/findByTags`; - return this.httpClient.request>('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request>('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, - params: localVarQueryParameters, + params: localVarQueryParameters.toHttpParams(), responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -400,44 +317,36 @@ export class PetService { /** * Find pet by ID * Returns a single pet + * @endpoint get /pet/{petId} * @param petId ID of pet to return * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public getPetById(petId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; - public getPetById(petId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public getPetById(petId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public getPetById(petId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + public getPetById(petId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public getPetById(petId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getPetById(petId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getPetById(petId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (petId === null || petId === undefined) { throw new Error('Required parameter petId was null or undefined when calling getPetById.'); } let localVarHeaders = this.defaultHeaders; - let localVarCredential: string | undefined; // authentication (api_key) required - localVarCredential = this.configuration.lookupCredential('api_key'); - if (localVarCredential) { - localVarHeaders = localVarHeaders.set('api_key', localVarCredential); - } + localVarHeaders = this.configuration.addCredentialToHeaders('api_key', 'api_key', localVarHeaders); - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/xml', - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/xml', + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -452,13 +361,15 @@ export class PetService { } let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; - return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -466,42 +377,34 @@ export class PetService { /** * Update an existing pet + * @endpoint put /pet * @param body Pet object that needs to be added to the store * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public updatePet(body: Pet, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public updatePet(body: Pet, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public updatePet(body: Pet, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public updatePet(body: Pet, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public updatePet(body: Pet, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public updatePet(body: Pet, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public updatePet(body: Pet, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public updatePet(body: Pet, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling updatePet.'); } let localVarHeaders = this.defaultHeaders; - let localVarCredential: string | undefined; // authentication (petstore_auth) required - localVarCredential = this.configuration.lookupCredential('petstore_auth'); - if (localVarCredential) { - localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); - } + localVarHeaders = this.configuration.addCredentialToHeaders('petstore_auth', 'Authorization', localVarHeaders, 'Bearer '); - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header @@ -526,14 +429,16 @@ export class PetService { } let localVarPath = `/pet`; - return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('put', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: body, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -541,44 +446,36 @@ export class PetService { /** * Updates a pet in the store with form data + * @endpoint post /pet/{petId} * @param petId ID of pet that needs to be updated * @param name Updated name of the pet * @param status Updated status of the pet * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public updatePetWithForm(petId: number, name?: string, status?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public updatePetWithForm(petId: number, name?: string, status?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public updatePetWithForm(petId: number, name?: string, status?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (petId === null || petId === undefined) { throw new Error('Required parameter petId was null or undefined when calling updatePetWithForm.'); } let localVarHeaders = this.defaultHeaders; - let localVarCredential: string | undefined; // authentication (petstore_auth) required - localVarCredential = this.configuration.lookupCredential('petstore_auth'); - if (localVarCredential) { - localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); - } + localVarHeaders = this.configuration.addCredentialToHeaders('petstore_auth', 'Authorization', localVarHeaders, 'Bearer '); - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header const consumes: string[] = [ @@ -615,14 +512,16 @@ export class PetService { } let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; - return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('post', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -630,45 +529,37 @@ export class PetService { /** * uploads an image + * @endpoint post /pet/{petId}/uploadImage * @param petId ID of pet to update * @param additionalMetadata Additional data to pass to server * @param file file to upload * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable; - public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public uploadFile(petId: number, additionalMetadata?: string, file?: Blob, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (petId === null || petId === undefined) { throw new Error('Required parameter petId was null or undefined when calling uploadFile.'); } let localVarHeaders = this.defaultHeaders; - let localVarCredential: string | undefined; // authentication (petstore_auth) required - localVarCredential = this.configuration.lookupCredential('petstore_auth'); - if (localVarCredential) { - localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential); - } + localVarHeaders = this.configuration.addCredentialToHeaders('petstore_auth', 'Authorization', localVarHeaders, 'Bearer '); - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header const consumes: string[] = [ @@ -708,14 +599,16 @@ export class PetService { } let localVarPath = `/pet/${this.configuration.encodeParam({name: "petId", value: petId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}/uploadImage`; - return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('post', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: localVarConvertFormParamsToString ? localVarFormParams.toString() : localVarFormParams, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/store.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/store.service.ts index b9b57010552d..72723f6925f1 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/store.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/store.service.ts @@ -1,8 +1,6 @@ /** * OpenAPI Petstore - * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -13,10 +11,10 @@ import { Inject, Injectable, Optional } from '@angular/core'; import { HttpClient, HttpHeaders, HttpParams, - HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + HttpResponse, HttpEvent, HttpContext } from '@angular/common/http'; -import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +import { OpenApiHttpParams, QueryParamStyle } from '../query.params'; // @ts-ignore import { Order } from '../model/order'; @@ -24,105 +22,47 @@ import { Order } from '../model/order'; // @ts-ignore import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; import { Configuration } from '../configuration'; +import { BaseService } from '../api.base.service'; @Injectable({ providedIn: 'root' }) -export class StoreService { +export class StoreService extends BaseService { - protected basePath = 'http://petstore.swagger.io/v2'; - public defaultHeaders = new HttpHeaders(); - public configuration = new Configuration(); - public encoder: HttpParameterCodec; - - constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { - if (configuration) { - this.configuration = configuration; - } - if (typeof this.configuration.basePath !== 'string') { - if (Array.isArray(basePath) && basePath.length > 0) { - basePath = basePath[0]; - } - - if (typeof basePath !== 'string') { - basePath = this.basePath; - } - this.configuration.basePath = basePath; - } - this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); - } - - - // @ts-ignore - private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { - if (typeof value === "object" && value instanceof Date === false) { - httpParams = this.addToHttpParamsRecursive(httpParams, value); - } else { - httpParams = this.addToHttpParamsRecursive(httpParams, value, key); - } - return httpParams; - } - - private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { - if (value == null) { - return httpParams; - } - - if (typeof value === "object") { - if (Array.isArray(value)) { - (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); - } else if (value instanceof Date) { - if (key != null) { - httpParams = httpParams.append(key, (value as Date).toISOString().substring(0, 10)); - } else { - throw Error("key may not be null if value is Date"); - } - } else { - Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( - httpParams, value[k], key != null ? `${key}.${k}` : k)); - } - } else if (key != null) { - httpParams = httpParams.append(key, value); - } else { - throw Error("key may not be null if value is not object or array"); - } - return httpParams; + constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) { + super(basePath, configuration); } /** * Delete purchase order by ID * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + * @endpoint delete /store/order/{orderId} * @param orderId ID of the order that needs to be deleted * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public deleteOrder(orderId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public deleteOrder(orderId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public deleteOrder(orderId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public deleteOrder(orderId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public deleteOrder(orderId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public deleteOrder(orderId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteOrder(orderId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteOrder(orderId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (orderId === null || orderId === undefined) { throw new Error('Required parameter orderId was null or undefined when calling deleteOrder.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -137,13 +77,15 @@ export class StoreService { } let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; - return this.httpClient.request('delete', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('delete', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -152,39 +94,31 @@ export class StoreService { /** * Returns pet inventories by status * Returns a map of status codes to quantities + * @endpoint get /store/inventory * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public getInventory(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<{ [key: string]: number; }>; - public getInventory(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public getInventory(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable>; - public getInventory(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable { + public getInventory(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable<{ [key: string]: number; }>; + public getInventory(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getInventory(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getInventory(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; - let localVarCredential: string | undefined; // authentication (api_key) required - localVarCredential = this.configuration.lookupCredential('api_key'); - if (localVarCredential) { - localVarHeaders = localVarHeaders.set('api_key', localVarCredential); - } + localVarHeaders = this.configuration.addCredentialToHeaders('api_key', 'api_key', localVarHeaders); - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -199,13 +133,15 @@ export class StoreService { } let localVarPath = `/store/inventory`; - return this.httpClient.request<{ [key: string]: number; }>('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request<{ [key: string]: number; }>('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -214,37 +150,33 @@ export class StoreService { /** * Find purchase order by ID * For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions + * @endpoint get /store/order/{orderId} * @param orderId ID of pet that needs to be fetched * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public getOrderById(orderId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; - public getOrderById(orderId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public getOrderById(orderId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public getOrderById(orderId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + public getOrderById(orderId: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public getOrderById(orderId: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getOrderById(orderId: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getOrderById(orderId: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (orderId === null || orderId === undefined) { throw new Error('Required parameter orderId was null or undefined when calling getOrderById.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/xml', - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/xml', + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -259,13 +191,15 @@ export class StoreService { } let localVarPath = `/store/order/${this.configuration.encodeParam({name: "orderId", value: orderId, in: "path", style: "simple", explode: false, dataType: "number", dataFormat: "int64"})}`; - return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -273,37 +207,33 @@ export class StoreService { /** * Place an order for a pet + * @endpoint post /store/order * @param body order placed for purchasing the pet * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public placeOrder(body: Order, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; - public placeOrder(body: Order, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public placeOrder(body: Order, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public placeOrder(body: Order, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + public placeOrder(body: Order, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public placeOrder(body: Order, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public placeOrder(body: Order, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public placeOrder(body: Order, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling placeOrder.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/xml', - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/xml', + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header @@ -326,14 +256,16 @@ export class StoreService { } let localVarPath = `/store/order`; - return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('post', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: body, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/user.service.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/user.service.ts index 3879b036f259..bd57c5670445 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/user.service.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/api/user.service.ts @@ -1,8 +1,6 @@ /** * OpenAPI Petstore - * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -13,10 +11,10 @@ import { Inject, Injectable, Optional } from '@angular/core'; import { HttpClient, HttpHeaders, HttpParams, - HttpResponse, HttpEvent, HttpParameterCodec, HttpContext + HttpResponse, HttpEvent, HttpContext } from '@angular/common/http'; -import { CustomHttpParameterCodec } from '../encoder'; import { Observable } from 'rxjs'; +import { OpenApiHttpParams, QueryParamStyle } from '../query.params'; // @ts-ignore import { User } from '../model/user'; @@ -24,105 +22,47 @@ import { User } from '../model/user'; // @ts-ignore import { BASE_PATH, COLLECTION_FORMATS } from '../variables'; import { Configuration } from '../configuration'; +import { BaseService } from '../api.base.service'; @Injectable({ providedIn: 'root' }) -export class UserService { +export class UserService extends BaseService { - protected basePath = 'http://petstore.swagger.io/v2'; - public defaultHeaders = new HttpHeaders(); - public configuration = new Configuration(); - public encoder: HttpParameterCodec; - - constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string|string[], @Optional() configuration: Configuration) { - if (configuration) { - this.configuration = configuration; - } - if (typeof this.configuration.basePath !== 'string') { - if (Array.isArray(basePath) && basePath.length > 0) { - basePath = basePath[0]; - } - - if (typeof basePath !== 'string') { - basePath = this.basePath; - } - this.configuration.basePath = basePath; - } - this.encoder = this.configuration.encoder || new CustomHttpParameterCodec(); - } - - - // @ts-ignore - private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams { - if (typeof value === "object" && value instanceof Date === false) { - httpParams = this.addToHttpParamsRecursive(httpParams, value); - } else { - httpParams = this.addToHttpParamsRecursive(httpParams, value, key); - } - return httpParams; - } - - private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams { - if (value == null) { - return httpParams; - } - - if (typeof value === "object") { - if (Array.isArray(value)) { - (value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key)); - } else if (value instanceof Date) { - if (key != null) { - httpParams = httpParams.append(key, (value as Date).toISOString().substring(0, 10)); - } else { - throw Error("key may not be null if value is Date"); - } - } else { - Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive( - httpParams, value[k], key != null ? `${key}.${k}` : k)); - } - } else if (key != null) { - httpParams = httpParams.append(key, value); - } else { - throw Error("key may not be null if value is not object or array"); - } - return httpParams; + constructor(protected httpClient: HttpClient, @Optional() @Inject(BASE_PATH) basePath: string|string[], @Optional() configuration?: Configuration) { + super(basePath, configuration); } /** * Create user * This can only be done by the logged in user. + * @endpoint post /user * @param body Created user object * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public createUser(body: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public createUser(body: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public createUser(body: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public createUser(body: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public createUser(body: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public createUser(body: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public createUser(body: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public createUser(body: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling createUser.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header @@ -145,14 +85,16 @@ export class UserService { } let localVarPath = `/user`; - return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('post', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: body, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -160,35 +102,31 @@ export class UserService { /** * Creates list of users with given input array + * @endpoint post /user/createWithArray * @param body List of user object * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public createUsersWithArrayInput(body: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public createUsersWithArrayInput(body: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public createUsersWithArrayInput(body: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public createUsersWithArrayInput(body: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public createUsersWithArrayInput(body: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public createUsersWithArrayInput(body: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public createUsersWithArrayInput(body: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public createUsersWithArrayInput(body: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling createUsersWithArrayInput.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header @@ -211,14 +149,16 @@ export class UserService { } let localVarPath = `/user/createWithArray`; - return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('post', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: body, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -226,35 +166,31 @@ export class UserService { /** * Creates list of users with given input array + * @endpoint post /user/createWithList * @param body List of user object * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public createUsersWithListInput(body: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public createUsersWithListInput(body: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public createUsersWithListInput(body: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public createUsersWithListInput(body: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public createUsersWithListInput(body: Array, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public createUsersWithListInput(body: Array, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public createUsersWithListInput(body: Array, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public createUsersWithListInput(body: Array, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (body === null || body === undefined) { throw new Error('Required parameter body was null or undefined when calling createUsersWithListInput.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header @@ -277,14 +213,16 @@ export class UserService { } let localVarPath = `/user/createWithList`; - return this.httpClient.request('post', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('post', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: body, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -293,35 +231,31 @@ export class UserService { /** * Delete user * This can only be done by the logged in user. + * @endpoint delete /user/{username} * @param username The name that needs to be deleted * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public deleteUser(username: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public deleteUser(username: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public deleteUser(username: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public deleteUser(username: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public deleteUser(username: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public deleteUser(username: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteUser(username: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public deleteUser(username: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (username === null || username === undefined) { throw new Error('Required parameter username was null or undefined when calling deleteUser.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -336,13 +270,15 @@ export class UserService { } let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; - return this.httpClient.request('delete', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('delete', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -350,37 +286,33 @@ export class UserService { /** * Get user by user name + * @endpoint get /user/{username} * @param username The name that needs to be fetched. Use user1 for testing. * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public getUserByName(username: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; - public getUserByName(username: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public getUserByName(username: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public getUserByName(username: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + public getUserByName(username: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public getUserByName(username: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getUserByName(username: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public getUserByName(username: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (username === null || username === undefined) { throw new Error('Required parameter username was null or undefined when calling getUserByName.'); } let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/xml', - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/xml', + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -395,13 +327,15 @@ export class UserService { } let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; - return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -409,15 +343,17 @@ export class UserService { /** * Logs user into the system + * @endpoint get /user/login * @param username The user name for login * @param password The password for login in clear text * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public loginUser(username: string, password: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable; - public loginUser(username: string, password: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public loginUser(username: string, password: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable>; - public loginUser(username: string, password: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext}): Observable { + public loginUser(username: string, password: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable; + public loginUser(username: string, password: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public loginUser(username: string, password: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable>; + public loginUser(username: string, password: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/xml' | 'application/json', context?: HttpContext, transferCache?: boolean}): Observable { if (username === null || username === undefined) { throw new Error('Required parameter username was null or undefined when calling loginUser.'); } @@ -425,35 +361,39 @@ export class UserService { throw new Error('Required parameter password was null or undefined when calling loginUser.'); } - let localVarQueryParameters = new HttpParams({encoder: this.encoder}); - if (username !== undefined && username !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - username, 'username'); - } - if (password !== undefined && password !== null) { - localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, - password, 'password'); - } + let localVarQueryParameters = new OpenApiHttpParams(this.encoder); + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'username', + username, + QueryParamStyle.Form, + false, + ); + + + localVarQueryParameters = this.addToHttpParams( + localVarQueryParameters, + 'password', + password, + QueryParamStyle.Form, + false, + ); + let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - 'application/xml', - 'application/json' - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + 'application/xml', + 'application/json' + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -468,14 +408,16 @@ export class UserService { } let localVarPath = `/user/login`; - return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, - params: localVarQueryParameters, + params: localVarQueryParameters.toHttpParams(), responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -483,31 +425,27 @@ export class UserService { /** * Logs out current logged in user session + * @endpoint get /user/logout * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public logoutUser(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public logoutUser(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public logoutUser(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public logoutUser(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public logoutUser(observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public logoutUser(observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public logoutUser(observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public logoutUser(observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; let responseType_: 'text' | 'json' | 'blob' = 'json'; @@ -522,13 +460,15 @@ export class UserService { } let localVarPath = `/user/logout`; - return this.httpClient.request('get', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('get', `${basePath}${localVarPath}`, { context: localVarHttpContext, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); @@ -537,15 +477,17 @@ export class UserService { /** * Updated user * This can only be done by the logged in user. + * @endpoint put /user/{username} * @param username name that need to be deleted * @param body Updated user object * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. * @param reportProgress flag to report request and response progress. + * @param options additional options */ - public updateUser(username: string, body: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable; - public updateUser(username: string, body: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public updateUser(username: string, body: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable>; - public updateUser(username: string, body: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext}): Observable { + public updateUser(username: string, body: User, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable; + public updateUser(username: string, body: User, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public updateUser(username: string, body: User, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable>; + public updateUser(username: string, body: User, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: undefined, context?: HttpContext, transferCache?: boolean}): Observable { if (username === null || username === undefined) { throw new Error('Required parameter username was null or undefined when calling updateUser.'); } @@ -555,21 +497,15 @@ export class UserService { let localVarHeaders = this.defaultHeaders; - let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept; - if (localVarHttpHeaderAcceptSelected === undefined) { - // to determine the Accept header - const httpHeaderAccepts: string[] = [ - ]; - localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts); - } + const localVarHttpHeaderAcceptSelected: string | undefined = options?.httpHeaderAccept ?? this.configuration.selectHeaderAccept([ + ]); if (localVarHttpHeaderAcceptSelected !== undefined) { localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected); } - let localVarHttpContext: HttpContext | undefined = options && options.context; - if (localVarHttpContext === undefined) { - localVarHttpContext = new HttpContext(); - } + const localVarHttpContext: HttpContext = options?.context ?? new HttpContext(); + + const localVarTransferCache: boolean = options?.transferCache ?? true; // to determine the Content-Type header @@ -592,14 +528,16 @@ export class UserService { } let localVarPath = `/user/${this.configuration.encodeParam({name: "username", value: username, in: "path", style: "simple", explode: false, dataType: "string", dataFormat: undefined})}`; - return this.httpClient.request('put', `${this.configuration.basePath}${localVarPath}`, + const { basePath, withCredentials } = this.configuration; + return this.httpClient.request('put', `${basePath}${localVarPath}`, { context: localVarHttpContext, body: body, responseType: responseType_, - withCredentials: this.configuration.withCredentials, + ...(withCredentials ? { withCredentials } : {}), headers: localVarHeaders, observe: observe, + ...(localVarTransferCache !== undefined ? { transferCache: localVarTransferCache } : {}), reportProgress: reportProgress } ); diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/configuration.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/configuration.ts index 4ad26d0bdcb9..775b99892d50 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/configuration.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/configuration.ts @@ -1,4 +1,4 @@ -import { HttpParameterCodec } from '@angular/common/http'; +import { HttpHeaders, HttpParams, HttpParameterCodec } from '@angular/common/http'; import { Param } from './param'; export interface ConfigurationParameters { @@ -66,26 +66,30 @@ export class Configuration { */ credentials: {[ key: string ]: string | (() => string | undefined)}; - constructor(configurationParameters: ConfigurationParameters = {}) { - this.apiKeys = configurationParameters.apiKeys; - this.username = configurationParameters.username; - this.password = configurationParameters.password; - this.accessToken = configurationParameters.accessToken; - this.basePath = configurationParameters.basePath; - this.withCredentials = configurationParameters.withCredentials; - this.encoder = configurationParameters.encoder; - if (configurationParameters.encodeParam) { - this.encodeParam = configurationParameters.encodeParam; +constructor({ accessToken, apiKeys, basePath, credentials, encodeParam, encoder, password, username, withCredentials }: ConfigurationParameters = {}) { + if (apiKeys) { + this.apiKeys = apiKeys; } - else { - this.encodeParam = param => this.defaultEncodeParam(param); + if (username !== undefined) { + this.username = username; } - if (configurationParameters.credentials) { - this.credentials = configurationParameters.credentials; + if (password !== undefined) { + this.password = password; } - else { - this.credentials = {}; + if (accessToken !== undefined) { + this.accessToken = accessToken; } + if (basePath !== undefined) { + this.basePath = basePath; + } + if (withCredentials !== undefined) { + this.withCredentials = withCredentials; + } + if (encoder) { + this.encoder = encoder; + } + this.encodeParam = encodeParam ?? (param => this.defaultEncodeParam(param)); + this.credentials = credentials ?? {}; // init default petstore_auth credential if (!this.credentials['petstore_auth']) { @@ -168,6 +172,20 @@ export class Configuration { : value; } + public addCredentialToHeaders(credentialKey: string, headerName: string, headers: HttpHeaders, prefix?: string): HttpHeaders { + const value = this.lookupCredential(credentialKey); + return value + ? headers.set(headerName, (prefix ?? '') + value) + : headers; + } + + public addCredentialToQuery(credentialKey: string, paramName: string, query: HttpParams): HttpParams { + const value = this.lookupCredential(credentialKey); + return value + ? query.set(paramName, value) + : query; + } + private defaultEncodeParam(param: Param): string { // This implementation exists as fallback for missing configuration // and for backwards compatibility to older typescript-angular generator versions. diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/encoder.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/encoder.ts index 138c4d5cf2c1..af4523543e6c 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/encoder.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/encoder.ts @@ -18,3 +18,18 @@ export class CustomHttpParameterCodec implements HttpParameterCodec { return decodeURIComponent(v); } } + +export class IdentityHttpParameterCodec implements HttpParameterCodec { + encodeKey(k: string): string { + return k; + } + encodeValue(v: string): string { + return v; + } + decodeKey(k: string): string { + return k; + } + decodeValue(v: string): string { + return v; + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/index.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/index.ts index 104dd3d21e35..02cb7d437fbf 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/index.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/index.ts @@ -3,4 +3,5 @@ export * from './model/models'; export * from './variables'; export * from './configuration'; export * from './api.module'; +export * from './provide-api'; export * from './param'; diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/apiResponse.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/apiResponse.ts index ca96abca935a..15c31ddb0955 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/apiResponse.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/apiResponse.ts @@ -1,8 +1,6 @@ /** * OpenAPI Petstore - * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/category.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/category.ts index 4e435cae1dbb..ac60a60b1afa 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/category.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/category.ts @@ -1,8 +1,6 @@ /** * OpenAPI Petstore - * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/order.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/order.ts index a730d4c17577..09e6aa71b916 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/order.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/order.ts @@ -1,8 +1,6 @@ /** * OpenAPI Petstore - * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -23,12 +21,12 @@ export interface Order { complete?: boolean; } export namespace Order { - export type StatusEnum = 'placed' | 'approved' | 'delivered'; export const StatusEnum = { - Placed: 'placed' as StatusEnum, - Approved: 'approved' as StatusEnum, - Delivered: 'delivered' as StatusEnum - }; + Placed: 'placed', + Approved: 'approved', + Delivered: 'delivered' + } as const; + export type StatusEnum = typeof StatusEnum[keyof typeof StatusEnum]; } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/pet.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/pet.ts index 284185ddd1ff..bb7a5850705f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/pet.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/pet.ts @@ -1,8 +1,6 @@ /** * OpenAPI Petstore - * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -25,12 +23,12 @@ export interface Pet { status?: Pet.StatusEnum; } export namespace Pet { - export type StatusEnum = 'available' | 'pending' | 'sold'; export const StatusEnum = { - Available: 'available' as StatusEnum, - Pending: 'pending' as StatusEnum, - Sold: 'sold' as StatusEnum - }; + Available: 'available', + Pending: 'pending', + Sold: 'sold' + } as const; + export type StatusEnum = typeof StatusEnum[keyof typeof StatusEnum]; } diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/tag.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/tag.ts index 73dee10beb56..3d1192e9f7a3 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/tag.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/tag.ts @@ -1,8 +1,6 @@ /** * OpenAPI Petstore - * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/user.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/user.ts index b3c99357e797..a933c7d5a458 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/user.ts +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/model/user.ts @@ -1,8 +1,6 @@ /** * OpenAPI Petstore - * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters. * - * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/package.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/package.json index 263335290957..0701ab261c12 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/package.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/package.json @@ -13,21 +13,22 @@ ], "license": "Unlicense", "scripts": { + "prepare": "npm run build", "build": "ng-packagr -p ng-package.json" }, "peerDependencies": { - "@angular/core": "^16.1.2", + "@angular/core": "^20.0.0", "rxjs": "^7.4.0" }, "devDependencies": { - "@angular/common": "^16.1.2", - "@angular/compiler": "^16.1.2", - "@angular/compiler-cli": "^16.1.2", - "@angular/core": "^16.1.2", - "@angular/platform-browser": "^16.1.2", - "ng-packagr": "^16.0.0", + "@angular/common": "^20.0.0", + "@angular/compiler": "^20.0.0", + "@angular/compiler-cli": "^20.0.0", + "@angular/core": "^20.0.0", + "@angular/platform-browser": "^20.0.0", + "ng-packagr": "^20.0.0", "reflect-metadata": "^0.1.3", "rxjs": "^7.4.0", - "typescript": ">=4.9.3 <5.2.0", - "zone.js": "^0.13.0" + "typescript": ">=5.8.0 <5.9.0", + "zone.js": "^0.15.0" }} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/provide-api.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/provide-api.ts new file mode 100644 index 000000000000..19c762acdfe0 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/provide-api.ts @@ -0,0 +1,15 @@ +import { EnvironmentProviders, makeEnvironmentProviders } from "@angular/core"; +import { Configuration, ConfigurationParameters } from './configuration'; +import { BASE_PATH } from './variables'; + +// Returns the service class providers, to be used in the [ApplicationConfig](https://angular.dev/api/core/ApplicationConfig). +export function provideApi(configOrBasePath: string | ConfigurationParameters): EnvironmentProviders { + return makeEnvironmentProviders([ + typeof configOrBasePath === "string" + ? { provide: BASE_PATH, useValue: configOrBasePath } + : { + provide: Configuration, + useValue: new Configuration({ ...configOrBasePath }), + }, + ]); +} \ No newline at end of file diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/query.params.ts b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/query.params.ts new file mode 100644 index 000000000000..4076c1140c83 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/query.params.ts @@ -0,0 +1,160 @@ +import { HttpParams, HttpParameterCodec } from '@angular/common/http'; +import { CustomHttpParameterCodec, IdentityHttpParameterCodec } from './encoder'; + +export enum QueryParamStyle { + Json, + Form, + DeepObject, + SpaceDelimited, + PipeDelimited, +} + +export type Delimiter = "," | " " | "|" | "\t"; + +export interface ParamOptions { + /** When true, serialized as multiple repeated key=value pairs. When false, serialized as a single key with joined values using `delimiter`. */ + explode?: boolean; + /** Delimiter used when explode=false. The delimiter itself is inserted unencoded between encoded values. */ + delimiter?: Delimiter; +} + +interface ParamEntry { + values: string[]; + options: Required; +} + +export class OpenApiHttpParams { + private params: Map = new Map(); + private defaults: Required; + private encoder: HttpParameterCodec; + + /** + * @param encoder Parameter serializer + * @param defaults Global defaults used when a specific parameter has no explicit options. + * By OpenAPI default, explode is true for query params with style=form. + */ + constructor(encoder?: HttpParameterCodec, defaults?: { explode?: boolean; delimiter?: Delimiter }) { + this.encoder = encoder || new CustomHttpParameterCodec(); + this.defaults = { + explode: defaults?.explode ?? true, + delimiter: defaults?.delimiter ?? ",", + }; + } + + private resolveOptions(local?: ParamOptions): Required { + return { + explode: local?.explode ?? this.defaults.explode, + delimiter: local?.delimiter ?? this.defaults.delimiter, + }; + } + + /** + * Replace the parameter's values and (optionally) its options. + * Options are stored per-parameter (not global). + */ + set(key: string, values: string[] | string, options?: ParamOptions): this { + const arr = Array.isArray(values) ? values.slice() : [values]; + const opts = this.resolveOptions(options); + this.params.set(key, {values: arr, options: opts}); + return this; + } + + /** + * Append a single value to the parameter. If the parameter didn't exist it will be created + * and use resolved options (global defaults merged with any provided options). + */ + append(key: string, value: string, options?: ParamOptions): this { + const entry = this.params.get(key); + if (entry) { + // If new options provided, override the stored options for subsequent serialization + if (options) { + entry.options = this.resolveOptions({...entry.options, ...options}); + } + entry.values.push(value); + } else { + this.set(key, [value], options); + } + return this; + } + + /** + * Serialize to a query string according to per-parameter OpenAPI options. + * - If explode=true for that parameter → repeated key=value pairs (each value encoded). + * - If explode=false for that parameter → single key=value where values are individually encoded + * and joined using the configured delimiter. The delimiter character is inserted AS-IS + * (not percent-encoded). + */ + toString(): string { + const records = this.toRecord(); + const parts: string[] = []; + + for (const key in records) { + parts.push(`${key}=${records[key]}`); + } + + return parts.join("&"); + } + + /** + * Return parameters as a plain record. + * - If a parameter has exactly one value, returns that value directly. + * - If a parameter has multiple values, returns a readonly array of values. + */ + toRecord(): Record> { + const parts: Record> = {}; + + for (const [key, entry] of this.params.entries()) { + const encodedKey = this.encoder.encodeKey(key); + + if (entry.options.explode) { + parts[encodedKey] = entry.values.map((v) => this.encoder.encodeValue(v)); + } else { + const encodedValues = entry.values.map((v) => this.encoder.encodeValue(v)); + + // join with the delimiter *unencoded* + parts[encodedKey] = encodedValues.join(entry.options.delimiter); + } + } + + return parts; + } + + /** + * Return an Angular's HttpParams with an identity parameter codec as the parameters are already encoded. + */ + toHttpParams(): HttpParams { + const records = this.toRecord(); + + let httpParams = new HttpParams({encoder: new IdentityHttpParameterCodec()}); + + return httpParams.appendAll(records); + } +} + +export function concatHttpParamsObject(httpParams: OpenApiHttpParams, key: string, item: { + [index: string]: any +}, delimiter: Delimiter): OpenApiHttpParams { + let keyAndValues: string[] = []; + + for (const k in item) { + keyAndValues.push(k); + + const value = item[k]; + + if (Array.isArray(value)) { + keyAndValues.push(...value.map(convertToString)); + } else { + keyAndValues.push(convertToString(value)); + } + } + + return httpParams.set(key, keyAndValues, {explode: false, delimiter: delimiter}); +} + +function convertToString(value: any): string { + if (value instanceof Date) { + return value.toISOString(); + } else { + return value.toString(); + } +} diff --git a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/tsconfig.json b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/tsconfig.json index 89cdedb1cb7f..eb405ea0e09f 100644 --- a/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/tsconfig.json +++ b/modules/openapi-generator/src/test/resources/integrationtests/typescript/petstore-expected/tsconfig.json @@ -5,8 +5,11 @@ "noImplicitAny": false, "target": "es5", "module": "commonjs", + "downlevelIteration": true, "moduleResolution": "node", "removeComments": true, + "strictNullChecks": true, + "exactOptionalPropertyTypes": true, "sourceMap": true, "outDir": "./dist", "noLib": false,