Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f338fce
feat(typescript-rxjs): add support for returning statusCode and progr…
denyo Feb 27, 2020
c1923af
feat(typescript-rxjs): use ?? instead of || to support relative baseP…
denyo Feb 27, 2020
00cd0da
feat(typescript-rxjs): regenerate samples
denyo Feb 27, 2020
60e460e
refactor(typescript-rxjs): change explicit undefined checks to shorth…
denyo Feb 27, 2020
45b4fb7
feat(typescript-rxjs): add missing progressSubscriber key when buildi…
denyo Feb 27, 2020
92eb049
feat(typescript-rxjs): regenerate samples
denyo Feb 27, 2020
ce40312
style(typescript-rxjs): remove whitespace, add colons
denyo Feb 27, 2020
7056095
feat(typescript-rxjs): regenerate samples
denyo Feb 27, 2020
673d67c
refactor(typescript-rxjs): destructure configuration in BaseApi
denyo Feb 27, 2020
9502f2f
fix(typescript-rxjs): returning empty string for apiKey and accessToken
denyo Feb 27, 2020
a5c5a86
feat(typescript-rxjs): replace withStatusCode option with response = …
denyo Mar 5, 2020
dfdb999
feat(typescript-rxjs): regenerate samples
denyo Mar 5, 2020
4d89d41
Merge branch 'master' into feature/rxjs-statuscode-and-progress
denyo Mar 5, 2020
c6091fd
Merge branch 'master' into feature/rxjs-statuscode-and-progress
denyo Mar 7, 2020
d9b688a
Merge branch 'master' into feature/rxjs-statuscode-and-progress
denyo Mar 30, 2020
59420b4
Merge branch 'master' into feature/rxjs-statuscode-and-progress
denyo Apr 16, 2020
0b71548
Prints out the parameter name in throwIfNullOrUndefined
jvandort Apr 28, 2020
7ddf3ad
Fixed misspelling
jvandort Apr 28, 2020
3279d2a
Merge branch 'master' into feature/rxjs-statuscode-and-progress
denyo May 6, 2020
e131635
feat(typescript-rxjs): add withProgressSubscriber additional-properti…
denyo May 13, 2020
77b56b6
refactor(typescript-rxjs): use backticks instead of String constructo…
denyo May 13, 2020
b826928
feat(typescript-rxjs): replace Object.keys() with Object.entries() in…
denyo May 13, 2020
9cea1f7
style(typescript-rxjs): improve indentation of new withProgressSubscr…
denyo May 13, 2020
5ca8f47
feat(typescript-rxjs): use entire es2017 lib in tsconfig.json for bui…
denyo May 13, 2020
7d895d6
feat(typescript-rxjs): regenerate samples
denyo May 13, 2020
3aff87c
Merge branch 'master' into feature/rxjs-cli-option-for-progressSubscr…
denyo May 13, 2020
36fca0d
Merge branch 'tx_rxjs_print_param_name' into feature/rxjs-cli-option-…
denyo May 13, 2020
7f22d95
Merge branch 'master' into feature/rxjs-cli-option-for-progressSubscr…
denyo Jun 20, 2020
c22297b
feat(typescript-rxjs): adjust sample generation, regenerate samples
denyo Jun 20, 2020
68292d7
docs(typescript-rxjs): regenerate docs
denyo Jun 20, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
generatorName: typescript-rxjs
outputDir: samples/client/petstore/typescript-rxjs/builds/with-interfaces
outputDir: samples/client/petstore/typescript-rxjs/builds/with-progress-subscriber
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
additionalProperties:
withInterfaces: "true"
withProgressSubscriber: "true"
2 changes: 1 addition & 1 deletion docs/generators/typescript-rxjs.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ sidebar_label: typescript-rxjs
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|supportsES6|Generate code that conforms to ES6.| |false|
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
|withProgressSubscriber|Setting this property to true will generate API controller methods with support for subscribing to request progress.| |false|

## IMPORT MAPPING

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class TypeScriptRxjsClientCodegen extends AbstractTypeScriptClientCodegen
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTypeScriptClientCodegen.class);

public static final String NPM_REPOSITORY = "npmRepository";
public static final String WITH_INTERFACES = "withInterfaces";
public static final String WITH_PROGRESS_SUBSCRIBER = "withProgressSubscriber";

protected String npmRepository = null;
protected Set<String> reservedParamNames = new HashSet<>();
Expand All @@ -60,7 +60,7 @@ public TypeScriptRxjsClientCodegen() {
typeMapping.put("file", "Blob");

this.cliOptions.add(new CliOption(NPM_REPOSITORY, "Use this property to set an url your private npmRepo in the package.json"));
this.cliOptions.add(new CliOption(WITH_INTERFACES, "Setting this property to true will generate interfaces next to the default class implementations.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
this.cliOptions.add(new CliOption(WITH_PROGRESS_SUBSCRIBER, "Setting this property to true will generate API controller methods with support for subscribing to request progress.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));

// these are used in the api template for more efficient destructuring
this.reservedParamNames.add("headers");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// tslint:disable
{{>licenseInfo}}
import { Observable } from 'rxjs';
import { BaseAPI{{#hasHttpHeaders}}, HttpHeaders{{/hasHttpHeaders}}{{#hasQueryParams}}, HttpQuery{{/hasQueryParams}}{{#hasRequiredParams}}, throwIfNullOrUndefined{{/hasRequiredParams}}{{#hasPathParams}}, encodeURI{{/hasPathParams}}{{#hasListContainers}}, COLLECTION_FORMATS{{/hasListContainers}} } from '../runtime';
import { BaseAPI{{#hasHttpHeaders}}, HttpHeaders{{/hasHttpHeaders}}{{#hasQueryParams}}, HttpQuery{{/hasQueryParams}}{{#hasRequiredParams}}, throwIfNullOrUndefined{{/hasRequiredParams}}{{#hasPathParams}}, encodeURI{{/hasPathParams}}{{#hasListContainers}}, COLLECTION_FORMATS{{/hasListContainers}}, OperationOpts, RawAjaxResponse } from '../runtime';
{{#imports.0}}
import {
{{#imports}}
Expand Down Expand Up @@ -37,7 +37,12 @@ export class {{classname}} extends BaseAPI {
* {{&summary}}
{{/summary}}
*/
{{nickname}} = ({{#allParams.0}}{ {{#allParams}}{{paramName}}{{#vendorExtensions.x-param-name-alternative}}: {{vendorExtensions.x-param-name-alternative}}{{/vendorExtensions.x-param-name-alternative}}{{^-last}}, {{/-last}}{{/allParams}} }: {{operationIdCamelCase}}Request{{/allParams.0}}): Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> => {
{{nickname}}({{#allParams.0}}{ {{#allParams}}{{paramName}}{{#vendorExtensions.x-param-name-alternative}}: {{vendorExtensions.x-param-name-alternative}}{{/vendorExtensions.x-param-name-alternative}}{{^-last}}, {{/-last}}{{/allParams}} }: {{operationIdCamelCase}}Request{{/allParams.0}}): Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}>
{{#withProgressSubscriber}}
{{nickname}}({{#allParams.0}}{ {{#allParams}}{{paramName}}{{#vendorExtensions.x-param-name-alternative}}: {{vendorExtensions.x-param-name-alternative}}{{/vendorExtensions.x-param-name-alternative}}{{^-last}}, {{/-last}}{{/allParams}} }: {{operationIdCamelCase}}Request, {{/allParams.0}}opts?: Pick<OperationOpts, 'progressSubscriber'>): Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}>
{{/withProgressSubscriber}}
{{nickname}}({{#allParams.0}}{ {{#allParams}}{{paramName}}{{#vendorExtensions.x-param-name-alternative}}: {{vendorExtensions.x-param-name-alternative}}{{/vendorExtensions.x-param-name-alternative}}{{^-last}}, {{/-last}}{{/allParams}} }: {{operationIdCamelCase}}Request, {{/allParams.0}}opts?: OperationOpts): Observable<{{#returnType}}RawAjaxResponse<{{{returnType}}}>{{/returnType}}{{^returnType}}void | RawAjaxResponse<void>{{/returnType}}>
{{nickname}}({{#allParams.0}}{ {{#allParams}}{{paramName}}{{#vendorExtensions.x-param-name-alternative}}: {{vendorExtensions.x-param-name-alternative}}{{/vendorExtensions.x-param-name-alternative}}{{^-last}}, {{/-last}}{{/allParams}} }: {{operationIdCamelCase}}Request, {{/allParams.0}}opts?: OperationOpts): Observable<{{#returnType}}{{{returnType}}} | RawAjaxResponse<{{{returnType}}}>{{/returnType}}{{^returnType}}void | RawAjaxResponse<void>{{/returnType}}> {
{{#hasParams}}
{{#allParams}}
{{#required}}
Expand Down Expand Up @@ -177,7 +182,7 @@ export class {{classname}} extends BaseAPI {

{{/hasFormParams}}
return this.request<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}>({
path: '{{{path}}}'{{#pathParams}}.replace({{=<% %>=}}'{<%baseName%>}'<%={{ }}=%>, encodeURI({{> paramNamePartial}})){{/pathParams}},
url: '{{{path}}}'{{#pathParams}}.replace({{=<% %>=}}'{<%baseName%>}'<%={{ }}=%>, encodeURI({{> paramNamePartial}})){{/pathParams}},
method: '{{httpMethod}}',
{{#hasHttpHeaders}}
headers,
Expand All @@ -204,9 +209,12 @@ export class {{classname}} extends BaseAPI {
body: formData,
{{/hasFormParams}}
{{#isResponseFile}}
responseType: 'blob'
responseType: 'blob',
{{/isResponseFile}}
});
{{#withProgressSubscriber}}
progressSubscriber: opts?.progressSubscriber,
{{/withProgressSubscriber}}
}, opts?.responseOpts);
};

{{/operation}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
"scripts" : {
"build": "tsc --outDir dist/",
"build": "node_modules/.bin/tsc --outDir dist/",
"prepare": "npm run build"
},
"dependencies": {
"rxjs": "^6.3.3"
},
"devDependencies": {
"typescript": "^3.0.1"
"typescript": "^3.7"
}{{#npmRepository}},{{/npmRepository}}
{{#npmRepository}}
"publishConfig": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// tslint:disable
{{>licenseInfo}}
import { Observable, of } from 'rxjs';
import { Observable, of, Subscriber } from 'rxjs';
import { ajax, AjaxRequest, AjaxResponse } from 'rxjs/ajax';
import { map, concatMap } from 'rxjs/operators';

Expand All @@ -19,11 +19,11 @@ export class Configuration {
constructor(private configuration: ConfigurationParameters = {}) {}

get basePath(): string {
return this.configuration.basePath || BASE_PATH;
return this.configuration.basePath ?? BASE_PATH;
}

get middleware(): Middleware[] {
return this.configuration.middleware || [];
return this.configuration.middleware ?? [];
}

get username(): string | undefined {
Expand All @@ -36,18 +36,12 @@ export class Configuration {

get apiKey(): ((name: string) => string) | undefined {
const { apiKey } = this.configuration;
if (!apiKey) {
return undefined;
}
return typeof apiKey === 'string' ? () => apiKey : apiKey;
return apiKey ? (typeof apiKey === 'string' ? () => apiKey : apiKey) : undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think double ternary is appropriate there. It's obfuscating the conditional, it makes it less readable. I've addressed the nully coalescing in #5329, and I think webpack can take care of the compressing the code.

}

get accessToken(): ((name: string, scopes?: string[]) => string) | undefined {
const { accessToken } = this.configuration;
if (!accessToken) {
return undefined;
}
return typeof accessToken === 'string' ? () => accessToken : accessToken;
return accessToken ? (typeof accessToken === 'string' ? () => accessToken : accessToken) : undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double ternary is problematic, as I described above.

}
}

Expand All @@ -73,31 +67,35 @@ export class BaseAPI {
withPostMiddleware = (postMiddlewares: Array<Middleware['post']>) =>
this.withMiddleware(postMiddlewares.map((post) => ({ post })));

protected request = <T>(requestOpts: RequestOpts): Observable<T> =>
this.rxjsRequest(this.createRequestArgs(requestOpts)).pipe(
protected request<T>(requestOpts: RequestOpts): Observable<T>
protected request<T>(requestOpts: RequestOpts, responseOpts?: ResponseOpts): Observable<RawAjaxResponse<T>>
protected request<T>(requestOpts: RequestOpts, responseOpts?: ResponseOpts): Observable<T | RawAjaxResponse<T>> {
return this.rxjsRequest(this.createRequestArgs(requestOpts)).pipe(
map((res) => {
if (res.status >= 200 && res.status < 300) {
return res.response as T;
const { status, response } = res;
if (status >= 200 && status < 300) {
return responseOpts?.respone === 'raw' ? res : response;
}
throw res;
})
);
}

private createRequestArgs = (requestOpts: RequestOpts): RequestArgs => {
let url = this.configuration.basePath + requestOpts.path;
if (requestOpts.query !== undefined && Object.keys(requestOpts.query).length !== 0) {
// 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.
url += '?' + queryString(requestOpts.query);
}
private createRequestArgs = ({ url: baseUrl, query, method, headers, body, responseType{{#withProgressSubscriber}}, progressSubscriber{{/withProgressSubscriber}} }: RequestOpts): RequestArgs => {
// 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: requestOpts.method,
headers: requestOpts.headers,
body: requestOpts.body instanceof FormData ? requestOpts.body : JSON.stringify(requestOpts.body),
responseType: requestOpts.responseType || 'json',
method,
headers,
body: body instanceof FormData ? body : JSON.stringify(body),
responseType: responseType ?? 'json',
{{#withProgressSubscriber}}
progressSubscriber,
{{/withProgressSubscriber}}
};
}

Expand Down Expand Up @@ -146,24 +144,41 @@ 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 {
path: string;
export interface RequestOpts extends AjaxRequest {
query?: HttpQuery; // additional prop
// the following props have improved types over AjaxRequest
method: HttpMethod;
headers?: HttpHeaders;
query?: HttpQuery;
body?: HttpBody;
responseType?: 'json' | 'blob' | 'arraybuffer' | 'text';
{{#withProgressSubscriber}}
progressSubscriber?: Subscriber<ProgressEvent>;
{{/withProgressSubscriber}}
}

export interface ResponseOpts {
respone?: 'raw';
}

export interface OperationOpts {
{{#withProgressSubscriber}}
progressSubscriber?: Subscriber<ProgressEvent>;
{{/withProgressSubscriber}}
responseOpts?: ResponseOpts;
}

// AjaxResponse with typed response
export interface RawAjaxResponse<T> extends AjaxResponse {
response: T;
}

export const encodeURI = (value: any) => encodeURIComponent(String(value));
export const encodeURI = (value: any) => encodeURIComponent(`${value}`);

const queryString = (params: HttpQuery): string => Object.keys(params)
.map((key) => {
const value = params[key];
return (value instanceof Array)
? value.map((val) => `${encodeURI(key)}=${encodeURI(val)}`).join('&')
: `${encodeURI(key)}=${encodeURI(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('&');

// alias fallback for not being a breaking change
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
"moduleResolution": "node",
"outDir": "dist",
"rootDir": ".",
{{^supportsES6}}
"lib": [
{{^supportsES6}}
"es6",
"dom"
{{/supportsES6}}
"dom",
"es2017"
],
{{/supportsES6}}
"typeRoots": [
"node_modules/@types"
]
Expand Down
Loading