Skip to content

Move templates in clients #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Mar 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1d0a324
[TypeScript] Rewritten TypeScript client generator supporting fetch &…
TiFu Jun 15, 2020
1037f90
Add Deno support to typescript(experimental) generator (#6732)
chibat Jun 27, 2020
5a70a22
[typescript] Fix generation of enum models (#7529)
bodograumann Sep 28, 2020
4c30355
Unifies naming for isArray in Schema class properties (#7691)
spacether Oct 19, 2020
a3c4c3a
Removes secondaryParam and hasMore (#7882)
spacether Nov 7, 2020
b875aa4
Allows install typescript client via npm from Git (#7878)
ad-m Nov 24, 2020
4e7a0ef
[typescript(experimental)] fix for Deno v1.6 (#8265)
chibat Dec 28, 2020
5c6be5c
replace tab with spaces, minor code format change (#8775)
wing328 Feb 21, 2021
dc34fea
Add '.generator/templates/' from commit '5c6be5c1a1cbbfb722494af68cc1…
therve Mar 23, 2021
ab65f84
Apply template-patches/typescript-custom-license-header.patch
therve Mar 23, 2021
b77548f
Apply template-patches/typescript-star-imports.patch
therve Mar 23, 2021
af9f01a
Apply template-patches/typescript-date-serialization.patch
therve Mar 23, 2021
f0f1224
Apply template-patches/typescript-user-agent.patch
therve Mar 23, 2021
e85d2ed
Apply template-patches/typescript-alias-from-function.patch
therve Mar 23, 2021
82d47a1
Apply template-patches/typescript-per-endpoint-servers.patch
therve Mar 23, 2021
84e5c6e
Merge branch 'master' into datadog-api-spec/test/therve/templates
api-clients-generation-pipeline[bot] Mar 23, 2021
0932e8c
Merge branch 'master' into datadog-api-spec/test/therve/templates
api-clients-generation-pipeline[bot] Mar 23, 2021
5ab3922
Merge branch 'master' into datadog-api-spec/test/therve/templates
api-clients-generation-pipeline[bot] Mar 23, 2021
0b6a39c
Merge branch 'master' into datadog-api-spec/test/therve/templates
api-clients-generation-pipeline[bot] Mar 23, 2021
e13c4f6
Merge branch 'master' into datadog-api-spec/test/therve/templates
api-clients-generation-pipeline[bot] Mar 23, 2021
227b278
Regenerate client from commit 7e667f1 of spec repo
Mar 23, 2021
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
8 changes: 4 additions & 4 deletions .apigentools-info
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"spec_versions": {
"v1": {
"apigentools_version": "1.4.1.dev6",
"regenerated": "2021-03-23 10:51:13.975619",
"spec_repo_commit": "34cf37f"
"regenerated": "2021-03-23 14:01:21.590919",
"spec_repo_commit": "7e667f1"
},
"v2": {
"apigentools_version": "1.4.1.dev6",
"regenerated": "2021-03-23 10:51:18.277869",
"spec_repo_commit": "34cf37f"
"regenerated": "2021-03-23 14:01:26.701173",
"spec_repo_commit": "7e667f1"
}
}
}
1 change: 1 addition & 0 deletions .generator/templates/.gitignore.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
30 changes: 30 additions & 0 deletions .generator/templates/README.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## {{npmName}}@{{npmVersion}}

This generator creates TypeScript/JavaScript client that utilizes {{framework}}.

### Building

To build and compile the typescript sources to javascript use:
```
npm install
npm run build
```

### Publishing

First build the package then run ```npm publish```

### Consuming

navigate to the folder of your consuming project and run one of the following commands.

_published:_

```
npm install {{npmName}}@{{npmVersion}} --save
```

_unPublished (not recommended):_

```
npm install PATH_TO_GENERATED_PACKAGE --save
219 changes: 219 additions & 0 deletions .generator/templates/api/api.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
// TODO: better import syntax?
import { BaseAPIRequestFactory, RequiredError } from './baseapi{{extensionForDeno}}';
import {Configuration, getServer } from '../configuration{{extensionForDeno}}';
import { RequestContext, HttpMethod, ResponseContext, HttpFile} from '../http/http{{extensionForDeno}}';
{{#platforms}}
{{#node}}
import FormData from "form-data";
{{/node}}
{{/platforms}}
import {ObjectSerializer} from '../models/ObjectSerializer{{extensionForDeno}}';
import {ApiException} from './exception{{extensionForDeno}}';
import {isCodeInRange} from '../util{{extensionForDeno}}';
{{#useInversify}}
import { injectable } from "inversify";
{{/useInversify}}

{{#imports}}
import { {{classname}} } from '..{{filename}}{{extensionForDeno}}';
{{/imports}}
{{#operations}}

/**
* {{#description}}{{{description}}}{{/description}}{{^description}}no description{{/description}}
*/
{{#useInversify}}
@injectable()
{{/useInversify}}
export class {{classname}}RequestFactory extends BaseAPIRequestFactory {

{{#operation}}
/**
{{#notes}}
* {{&notes}}
{{/notes}}
{{#summary}}
* {{&summary}}
{{/summary}}
{{#allParams}}
* @param {{paramName}} {{description}}
{{/allParams}}
*/
public async {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}options?: Configuration): Promise<RequestContext> {
let config = options || this.configuration;
{{#allParams}}

{{#required}}
// verify required parameter '{{paramName}}' is not null or undefined
if ({{paramName}} === null || {{paramName}} === undefined) {
throw new RequiredError('Required parameter {{paramName}} was null or undefined when calling {{nickname}}.');
}

{{/required}}
{{/allParams}}

// Path Params
const localVarPath = '{{{path}}}'{{#pathParams}}
.replace('{' + '{{baseName}}' + '}', encodeURIComponent(String({{paramName}}))){{/pathParams}};

// Make Request Context
const requestContext = getServer(config, '{{classname}}.{{nickname}}').makeRequestContext(localVarPath, HttpMethod.{{httpMethod}});
requestContext.setHeaderParam("Accept", "application/json, */*;q=0.8")

// Query Params
{{#queryParams}}
if ({{paramName}} !== undefined) {
requestContext.setQueryParam("{{baseName}}", ObjectSerializer.serialize({{paramName}}, "{{{dataType}}}", "{{dataFormat}}"));
}
{{/queryParams}}

// Header Params
{{#headerParams}}
requestContext.setHeaderParam("{{baseName}}", ObjectSerializer.serialize({{paramName}}, "{{{dataType}}}", "{{dataFormat}}"));
{{/headerParams}}

// Form Params
{{#hasFormParams}}
let localVarFormParams = new FormData();
{{/hasFormParams}}

{{#formParams}}
{{#isArray}}
if ({{paramName}}) {
{{#isCollectionFormatMulti}}
{{paramName}}.forEach((element) => {
localVarFormParams.append('{{baseName}}', element as any);
})
{{/isCollectionFormatMulti}}
{{^isCollectionFormatMulti}}
// TODO: replace .append with .set
localVarFormParams.append('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS["{{collectionFormat}}"]));
{{/isCollectionFormatMulti}}
}
{{/isArray}}
{{^isArray}}
if ({{paramName}} !== undefined) {
// TODO: replace .append with .set
{{^isFile}}
localVarFormParams.append('{{baseName}}', {{paramName}} as any);
{{/isFile}}
{{#isFile}}
{{#platforms}}
{{#node}}
localVarFormParams.append('{{baseName}}', {{paramName}}.data, {{paramName}}.name);
{{/node}}
{{^node}}
localVarFormParams.append('{{baseName}}', {{paramName}}, {{paramName}}.name);
{{/node}}
{{/platforms}}
{{/isFile}}
}
{{/isArray}}
{{/formParams}}
{{#hasFormParams}}
requestContext.setBody(localVarFormParams);
{{/hasFormParams}}

// Body Params
{{#bodyParam}}
const contentType = ObjectSerializer.getPreferredMediaType([{{#consumes}}
"{{{mediaType}}}"{{^-last}},{{/-last}}
{{/consumes}}]);
requestContext.setHeaderParam("Content-Type", contentType);
const serializedBody = ObjectSerializer.stringify(
ObjectSerializer.serialize({{paramName}}, "{{{dataType}}}", "{{dataFormat}}"),
contentType
);
requestContext.setBody(serializedBody);
{{/bodyParam}}

{{#hasAuthMethods}}
let authMethod = null;
{{/hasAuthMethods}}
// Apply auth methods
{{#authMethods}}
authMethod = config.authMethods["{{name}}"]
if (authMethod) {
await authMethod.applySecurityAuthentication(requestContext);
}
{{/authMethods}}

return requestContext;
}

{{/operation}}
}
{{/operations}}
{{#operations}}

{{#useInversify}}
@injectable()
{{/useInversify}}
export class {{classname}}ResponseProcessor {

{{#operation}}
/**
* Unwraps the actual response sent by the server from the response context and deserializes the response content
* to the expected objects
*
* @params response Response returned by the server for a request to {{nickname}}
* @throws ApiException if the response code was not in [200, 299]
*/
public async {{nickname}}(response: ResponseContext): Promise<{{#returnType}}{{{returnType}}}{{/returnType}} {{^returnType}}void{{/returnType}}> {
const contentType = ObjectSerializer.normalizeMediaType(response.headers["content-type"]);
{{#responses}}
if (isCodeInRange("{{code}}", response.httpStatusCode)) {
{{#dataType}}
{{#isBinary}}
const body: {{{dataType}}} = await response.getBodyAsFile() as any as {{{returnType}}};
{{/isBinary}}
{{^isBinary}}
const body: {{{dataType}}} = ObjectSerializer.deserialize(
ObjectSerializer.parse(await response.body.text(), contentType),
"{{{dataType}}}", "{{returnFormat}}"
) as {{{dataType}}};
{{/isBinary}}
{{#is2xx}}
return body;
{{/is2xx}}
{{^is2xx}}
throw new ApiException<{{{dataType}}}>({{code}}, body);
{{/is2xx}}
{{/dataType}}
{{^dataType}}
{{#is2xx}}
return;
{{/is2xx}}
{{^is2xx}}
throw new ApiException<string>(response.httpStatusCode, "{{message}}");
{{/is2xx}}
{{/dataType}}
}
{{/responses}}

// Work around for missing responses in specification, e.g. for petstore.yaml
if (response.httpStatusCode >= 200 && response.httpStatusCode <= 299) {
{{#returnType}}
{{#isBinary}}
const body: {{{returnType}}} = await response.getBodyAsFile() as any as {{{returnType}}};
{{/isBinary}}
{{^isBinary}}
const body: {{{returnType}}} = ObjectSerializer.deserialize(
ObjectSerializer.parse(await response.body.text(), contentType),
"{{{returnType}}}", "{{returnFormat}}"
) as {{{returnType}}};
{{/isBinary}}
return body;
{{/returnType}}
{{^returnType}}
return;
{{/returnType}}
}

let body = response.body || "";
throw new ApiException<string>(response.httpStatusCode, "Unknown API Status Code!\nBody: \"" + body + "\"");
}

{{/operation}}
}
{{/operations}}
44 changes: 44 additions & 0 deletions .generator/templates/api/baseapi.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Configuration } from '../configuration{{extensionForDeno}}'
{{#useInversify}}
import { injectable, inject } from "inversify";
import { AbstractConfiguration } from "../services/configuration";
{{/useInversify}}

/**
*
* @export
*/
export const COLLECTION_FORMATS = {
csv: ",",
ssv: " ",
tsv: "\t",
pipes: "|",
};


/**
*
* @export
* @class BaseAPI
*/
{{#useInversify}}
@injectable()
{{/useInversify}}
export class BaseAPIRequestFactory {

constructor({{#useInversify}}@inject(AbstractConfiguration) {{/useInversify}}protected configuration: Configuration) {
}
};

/**
*
* @export
* @class RequiredError
* @extends {Error}
*/
export class RequiredError extends Error {
name: "RequiredError" = "RequiredError";
constructor(public field: string, msg?: string) {
super(msg);
}
}
14 changes: 14 additions & 0 deletions .generator/templates/api/exception.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Represents an error caused by an api call i.e. it has attributes for a HTTP status code
* and the returned body object.
*
* Example
* API returns a ErrorMessageObject whenever HTTP status code is not in [200, 299]
* => ApiException(404, someErrorMessageObject)
*
*/
export class ApiException<T> extends Error {
public constructor(public code: number, public body: T) {
super("HTTP-Code: " + code + "\nMessage: " + JSON.stringify(body))
}
}
66 changes: 66 additions & 0 deletions .generator/templates/api/middleware.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {RequestContext, ResponseContext} from './http/http{{extensionForDeno}}';
import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'./rxjsStub{{extensionForDeno}}'{{/useRxJS}};

/**
* Defines the contract for a middleware intercepting requests before
* they are sent (but after the RequestContext was created)
* and before the ResponseContext is unwrapped.
*
*/
export interface Middleware {
/**
* Modifies the request before the request is sent.
*
* @param context RequestContext of a request which is about to be sent to the server
* @returns an observable of the updated request context
*
*/
pre(context: RequestContext): Observable<RequestContext>;
/**
* Modifies the returned response before it is deserialized.
*
* @param context ResponseContext of a sent request
* @returns an observable of the modified response context
*/
post(context: ResponseContext): Observable<ResponseContext>;
}

export class PromiseMiddlewareWrapper implements Middleware {

public constructor(private middleware: PromiseMiddleware) {

}

pre(context: RequestContext): Observable<RequestContext> {
return from(this.middleware.pre(context));
}

post(context: ResponseContext): Observable<ResponseContext> {
return from(this.middleware.post(context));
}

}

/**
* Defines the contract for a middleware intercepting requests before
* they are sent (but after the RequestContext was created)
* and before the ResponseContext is unwrapped.
*
*/
export interface PromiseMiddleware {
/**
* Modifies the request before the request is sent.
*
* @param context RequestContext of a request which is about to be sent to the server
* @returns an observable of the updated request context
*
*/
pre(context: RequestContext): Promise<RequestContext>;
/**
* Modifies the returned response before it is deserialized.
*
* @param context ResponseContext of a sent request
* @returns an observable of the modified response context
*/
post(context: ResponseContext): Promise<ResponseContext>;
}
Loading