Fix missing imports when using allOf composition (#13813)

This commit is contained in:
Neal Granger 2022-10-25 01:33:34 -07:00 committed by GitHub
parent 748de83d29
commit 3501771a2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 556 additions and 0 deletions

View File

@ -0,0 +1,4 @@
generatorName: typescript-rxjs
outputDir: samples/client/others/typescript-rxjs/allOf-composition
inputSpec: modules/openapi-generator/src/test/resources/3_0/allOf_composition.yaml
templateDir: modules/openapi-generator/src/main/resources/typescript-rxjs

View File

@ -18,6 +18,7 @@
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.parser.util.SchemaTypeUtil;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.DocumentationFeature;
@ -420,4 +421,10 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen
this.hasOptionalQueryParams = false; // will be updated within addConditionalImportInformation
}
}
@Override
protected void addImport(ComposedSchema composed, Schema childSchema, CodegenModel model, String modelName) {
// import everything (including child schema of a composed schema)
addImport(model, modelName);
}
}

View File

@ -0,0 +1,4 @@
wwwroot/*.js
node_modules
typings
dist

View File

@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@ -0,0 +1,15 @@
.gitignore
apis/DefaultApi.ts
apis/index.ts
index.ts
models/Hero.ts
models/Human.ts
models/SuperBaby.ts
models/SuperBabyAllOf.ts
models/SuperBoy.ts
models/SuperBoyAllOf.ts
models/SuperMan.ts
models/index.ts
runtime.ts
servers.ts
tsconfig.json

View File

@ -0,0 +1 @@
6.2.1-SNAPSHOT

View File

@ -0,0 +1,44 @@
// tslint:disable
/**
* Example
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import type { Observable } from 'rxjs';
import type { AjaxResponse } from 'rxjs/ajax';
import { BaseAPI, throwIfNullOrUndefined, encodeURI } from '../runtime';
import type { OperationOpts } from '../runtime';
import type {
SuperMan,
} from '../models';
export interface ListRequest {
personId: string;
}
/**
* no description
*/
export class DefaultApi extends BaseAPI {
/**
*/
list({ personId }: ListRequest): Observable<SuperMan>
list({ personId }: ListRequest, opts?: OperationOpts): Observable<AjaxResponse<SuperMan>>
list({ personId }: ListRequest, opts?: OperationOpts): Observable<SuperMan | AjaxResponse<SuperMan>> {
throwIfNullOrUndefined(personId, 'personId', 'list');
return this.request<SuperMan>({
url: '/person/display/{personId}'.replace('{personId}', encodeURI(personId)),
method: 'GET',
}, opts?.responseOpts);
};
}

View File

@ -0,0 +1 @@
export * from './DefaultApi';

View File

@ -0,0 +1,4 @@
export * from './runtime';
export * from './servers';
export * from './apis';
export * from './models';

View File

@ -0,0 +1,30 @@
// tslint:disable
/**
* Example
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* Hero
* @export
* @interface Hero
*/
export interface Hero {
/**
* @type {number}
* @memberof Hero
*/
reward?: number;
/**
* @type {string}
* @memberof Hero
*/
origin: string;
}

View File

@ -0,0 +1,30 @@
// tslint:disable
/**
* Example
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* Human
* @export
* @interface Human
*/
export interface Human {
/**
* @type {number}
* @memberof Human
*/
id: number;
/**
* @type {string}
* @memberof Human
*/
name?: string;
}

View File

@ -0,0 +1,23 @@
// tslint:disable
/**
* Example
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import type {
Human,
SuperBabyAllOf,
} from './';
/**
* @type SuperBaby
* @export
*/
export type SuperBaby = Human & SuperBabyAllOf;

View File

@ -0,0 +1,29 @@
// tslint:disable
/**
* Example
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* @export
* @interface SuperBabyAllOf
*/
export interface SuperBabyAllOf {
/**
* @type {string}
* @memberof SuperBabyAllOf
*/
gender?: string;
/**
* @type {number}
* @memberof SuperBabyAllOf
*/
age?: number;
}

View File

@ -0,0 +1,23 @@
// tslint:disable
/**
* Example
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import type {
Human,
SuperBoyAllOf,
} from './';
/**
* @type SuperBoy
* @export
*/
export type SuperBoy = Human & SuperBoyAllOf;

View File

@ -0,0 +1,29 @@
// tslint:disable
/**
* Example
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* @export
* @interface SuperBoyAllOf
*/
export interface SuperBoyAllOf {
/**
* @type {string}
* @memberof SuperBoyAllOf
*/
category?: string;
/**
* @type {number}
* @memberof SuperBoyAllOf
*/
level: number;
}

View File

@ -0,0 +1,24 @@
// tslint:disable
/**
* Example
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import type {
Hero,
Human,
SuperBoyAllOf,
} from './';
/**
* @type SuperMan
* @export
*/
export type SuperMan = Hero & Human & SuperBoyAllOf;

View File

@ -0,0 +1,7 @@
export * from './Hero';
export * from './Human';
export * from './SuperBaby';
export * from './SuperBabyAllOf';
export * from './SuperBoy';
export * from './SuperBoyAllOf';
export * from './SuperMan';

View File

@ -0,0 +1,193 @@
// tslint:disable
/**
* Example
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { of } from 'rxjs';
import type { Observable } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import type { AjaxConfig, AjaxResponse } from 'rxjs/ajax';
import { map, concatMap } from 'rxjs/operators';
import { servers } from './servers';
export const BASE_PATH = servers[0].getUrl();
export interface ConfigurationParameters {
basePath?: string; // override base path
middleware?: Middleware[]; // middleware to apply before/after rxjs requests
username?: string; // parameter for basic security
password?: string; // parameter for basic security
apiKey?: string | ((name: string) => string); // parameter for apiKey security
accessToken?: string | ((name?: string, scopes?: string[]) => string); // parameter for oauth2 security
}
export class Configuration {
constructor(private configuration: ConfigurationParameters = {}) {}
get basePath(): string {
return this.configuration.basePath ?? BASE_PATH;
}
get middleware(): Middleware[] {
return this.configuration.middleware ?? [];
}
get username(): string | undefined {
return this.configuration.username;
}
get password(): string | undefined {
return this.configuration.password;
}
get apiKey(): ((name: string) => string) | undefined {
const { apiKey } = this.configuration;
return apiKey ? (typeof apiKey === 'string' ? () => apiKey : apiKey) : undefined;
}
get accessToken(): ((name: string, scopes?: string[]) => string) | undefined {
const { accessToken } = this.configuration;
return accessToken ? (typeof accessToken === 'string' ? () => accessToken : accessToken) : undefined;
}
}
/**
* This is the base class for all generated API classes.
*/
export class BaseAPI {
private middleware: Middleware[] = [];
constructor(protected configuration = new Configuration()) {
this.middleware = configuration.middleware;
}
withMiddleware = (middlewares: Middleware[]): this => {
const next = this.clone();
next.middleware = next.middleware.concat(middlewares);
return next;
};
withPreMiddleware = (preMiddlewares: Array<Middleware['pre']>) =>
this.withMiddleware(preMiddlewares.map((pre) => ({ pre })));
withPostMiddleware = (postMiddlewares: Array<Middleware['post']>) =>
this.withMiddleware(postMiddlewares.map((post) => ({ post })));
protected request<T>(requestOpts: RequestOpts): Observable<T>
protected request<T>(requestOpts: RequestOpts, responseOpts?: ResponseOpts): Observable<AjaxResponse<T>>
protected request<T>(requestOpts: RequestOpts, responseOpts?: ResponseOpts): Observable<T | AjaxResponse<T>> {
return this.rxjsRequest<T>(this.createRequestArgs(requestOpts)).pipe(
map((res) => {
const { status, response } = res;
if (status >= 200 && status < 300) {
return responseOpts?.response === 'raw' ? res : response;
}
throw res;
})
);
}
private createRequestArgs = ({ url: baseUrl, query, method, headers, body, responseType }: RequestOpts): AjaxConfig => {
// only add the queryString to the URL if there are query parameters.
// this is done to avoid urls ending with a '?' character which buggy webservers
// do not handle correctly sometimes.
const url = `${this.configuration.basePath}${baseUrl}${query && Object.keys(query).length ? `?${queryString(query)}`: ''}`;
return {
url,
method,
headers,
body: body instanceof FormData ? body : JSON.stringify(body),
responseType: responseType ?? 'json',
};
}
private rxjsRequest = <T>(params: AjaxConfig): Observable<AjaxResponse<T>> =>
of(params).pipe(
map((request) => {
this.middleware.filter((item) => item.pre).forEach((mw) => (request = mw.pre!(request)));
return request;
}),
concatMap((args) =>
ajax<T>(args).pipe(
map((response) => {
this.middleware.filter((item) => item.post).forEach((mw) => (response = mw.post!(response)));
return response;
})
)
)
);
/**
* Create a shallow clone of `this` by constructing a new instance
* and then shallow cloning data members.
*/
private clone = (): this =>
Object.assign(Object.create(Object.getPrototypeOf(this)), this);
}
/**
* @deprecated
* export for not being a breaking change
*/
export class RequiredError extends Error {
override name: 'RequiredError' = 'RequiredError';
}
export const COLLECTION_FORMATS = {
csv: ',',
ssv: ' ',
tsv: '\t',
pipes: '|',
};
export type Json = any;
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
export type HttpHeaders = { [key: string]: string };
export type HttpQuery = Partial<{ [key: string]: string | number | null | boolean | Array<string | number | null | boolean> }>; // partial is needed for strict mode
export type HttpBody = Json | FormData;
export interface RequestOpts extends AjaxConfig {
// TODO: replace custom 'query' prop with 'queryParams'
query?: HttpQuery; // additional prop
// the following props have improved types over AjaxRequest
method: HttpMethod;
headers?: HttpHeaders;
body?: HttpBody;
}
export interface ResponseOpts {
response?: 'raw';
}
export interface OperationOpts {
responseOpts?: ResponseOpts;
}
export const encodeURI = (value: any) => encodeURIComponent(`${value}`);
const queryString = (params: HttpQuery): string => Object.entries(params)
.map(([key, value]) => value instanceof Array
? value.map((val) => `${encodeURI(key)}=${encodeURI(val)}`).join('&')
: `${encodeURI(key)}=${encodeURI(value)}`
)
.join('&');
export const throwIfNullOrUndefined = (value: any, paramName: string, nickname: string) => {
if (value == null) {
throw new Error(`Parameter "${paramName}" was null or undefined when calling "${nickname}".`);
}
};
export interface Middleware {
pre?(request: AjaxConfig): AjaxConfig;
post?(response: AjaxResponse<any>): AjaxResponse<any>;
}

View File

@ -0,0 +1,43 @@
/**
*
* Represents the configuration of a server including its
* url template and variable configuration based on the url.
*
*/
export class ServerConfiguration<T extends { [key: string]: string }> {
public constructor(private url: string, private variableConfiguration: T, private description: string) {}
/**
* Sets the value of the variables of this server.
*
* @param variableConfiguration a partial variable configuration for the variables contained in the url
*/
public setVariables(variableConfiguration: Partial<T>) {
Object.assign(this.variableConfiguration, variableConfiguration);
}
public getConfiguration(): T {
return this.variableConfiguration;
}
public getDescription(): string {
return this.description;
}
/**
* Constructions the URL this server using the url with variables
* replaced with their respective values
*/
public getUrl(): string {
let replacedUrl = this.url;
for (const key in this.variableConfiguration) {
var re = new RegExp("{" + key + "}","g");
replacedUrl = replacedUrl.replace(re, this.variableConfiguration[key]);
}
return replacedUrl;
}
}
const server1 = new ServerConfiguration<{ }>("http://api.example.xyz/v1", { }, "");
export const servers = [server1];

View File

@ -0,0 +1,22 @@
{
"compilerOptions": {
"declaration": true,
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
"rootDir": ".",
"lib": [
"es6",
"dom",
"es2017"
],
"typeRoots": [
"node_modules/@types"
]
},
"exclude": [
"dist",
"node_modules"
]
}