Skip to content

Commit 0984ef7

Browse files
committed
[typescript-axios] Add support for AWSv4 Signature
1 parent 93b76dd commit 0984ef7

35 files changed

Lines changed: 453 additions & 34 deletions

File tree

docs/generators/typescript-axios.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
4444
|withNodeImports|Setting this property to true adds imports for NodeJS| |false|
4545
|withSeparateModelsAndApi|Put the model and api in separate folders and in separate classes. This requires in addition a value for 'apiPackage' and 'modelPackage'| |false|
4646
|withoutPrefixEnums|Don't prefix enum names with class names| |false|
47+
|withAWSV4Signature|whether to include AWS v4 signature support| |false|
4748

4849
## IMPORT MAPPING
4950

@@ -265,7 +266,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
265266
|OAuth2_ClientCredentials|✗|OAS2,OAS3
266267
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
267268
|SignatureAuth|✗|OAS3
268-
|AWSV4Signature||ToolingExtension
269+
|AWSV4Signature||ToolingExtension
269270

270271
### Wire Format Feature
271272
| Name | Supported | Defined By |

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptAxiosClientCodegen.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@ public class TypeScriptAxiosClientCodegen extends AbstractTypeScriptClientCodege
4242
public static final String WITH_NODE_IMPORTS = "withNodeImports";
4343
public static final String STRING_ENUMS = "stringEnums";
4444
public static final String STRING_ENUMS_DESC = "Generate string enums instead of objects for enum values.";
45+
public static final String WITH_AWSV4_SIGNATURE = "withAWSV4Signature";
4546

4647
protected String npmRepository = null;
4748
protected Boolean stringEnums = false;
49+
protected boolean withAWSV4Signature = false;
4850

4951
private String tsModelPackage = "";
5052

@@ -53,7 +55,7 @@ public TypeScriptAxiosClientCodegen() {
5355

5456
modifyFeatureSet(features -> features
5557
.includeDocumentationFeatures(DocumentationFeature.Readme)
56-
.includeSecurityFeatures(SecurityFeature.BearerToken));
58+
.includeSecurityFeatures(SecurityFeature.BearerToken, SecurityFeature.AWSV4Signature));
5759

5860
// clear import mapping (from default generator) as TS does not use it
5961
// at the moment
@@ -73,6 +75,7 @@ public TypeScriptAxiosClientCodegen() {
7375
this.cliOptions.add(new CliOption(USE_SINGLE_REQUEST_PARAMETER, "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
7476
this.cliOptions.add(new CliOption(WITH_NODE_IMPORTS, "Setting this property to true adds imports for NodeJS", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
7577
this.cliOptions.add(new CliOption(STRING_ENUMS, STRING_ENUMS_DESC).defaultValue(String.valueOf(this.stringEnums)));
78+
this.cliOptions.add(new CliOption(WITH_AWSV4_SIGNATURE, "whether to include AWS v4 signature support", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
7679
// Templates have no mapping between formatted property names and original base names so use only "original" and remove this option
7780
removeOption(CodegenConstants.MODEL_PROPERTY_NAMING);
7881
}
@@ -152,6 +155,11 @@ public void processOpts() {
152155
addNpmPackageGeneration();
153156
}
154157

158+
if (additionalProperties.containsKey(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT)) {
159+
this.setWithAWSV4Signature(Boolean.parseBoolean(additionalProperties.get(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT).toString()));
160+
}
161+
additionalProperties.put(CodegenConstants.WITH_AWSV4_SIGNATURE_COMMENT, withAWSV4Signature);
162+
155163
}
156164

157165
@Override
@@ -266,6 +274,10 @@ public ModelsMap postProcessModels(ModelsMap objs) {
266274
return objs;
267275
}
268276

277+
public void setWithAWSV4Signature(boolean withAWSV4Signature) {
278+
this.withAWSV4Signature = withAWSV4Signature;
279+
}
280+
269281
/**
270282
* Overriding toRegularExpression() to avoid escapeText() being called,
271283
* as it would return a broken regular expression if any escaped character / metacharacter were present.

modules/openapi-generator/src/main/resources/typescript-axios/api.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import FormData from 'form-data'
1616
{{/withNodeImports}}
1717
// Some imports not used depending on template conditions
1818
// @ts-ignore
19-
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from './common';
19+
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction{{#withAWSV4Signature}}, setAWS4SignatureInterceptor{{/withAWSV4Signature}} } from './common';
2020
import type { RequestArgs } from './base';
2121
// @ts-ignore
2222
import { BASE_PATH, COLLECTION_FORMATS, BaseAPI, RequiredError, operationServerMap } from './base';

modules/openapi-generator/src/main/resources/typescript-axios/apiInner.mustache

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import FormData from 'form-data'
1616
{{/withNodeImports}}
1717
// Some imports not used depending on template conditions
1818
// @ts-ignore
19-
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from '{{apiRelativeToRoot}}common';
19+
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction{{#withAWSV4Signature}}, setAWS4SignatureInterceptor{{/withAWSV4Signature}} } from '{{apiRelativeToRoot}}common';
2020
// @ts-ignore
2121
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError, operationServerMap } from '{{apiRelativeToRoot}}base';
2222
{{#imports}}
@@ -71,6 +71,10 @@ export const {{classname}}AxiosParamCreator = function (configuration?: Configur
7171
{{#authMethods}}
7272
// authentication {{name}} required
7373
{{#isApiKey}}
74+
{{#withAWSV4Signature}}
75+
// aws v4 signature authentication required
76+
await setAWS4SignatureInterceptor(globalAxios, configuration)
77+
{{/withAWSV4Signature}}
7478
{{#isKeyInHeader}}
7579
await setApiKeyToObject(localVarHeaderParameter, "{{keyParamName}}", configuration)
7680
{{/isKeyInHeader}}

modules/openapi-generator/src/main/resources/typescript-axios/common.mustache

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
import type { Configuration } from "./configuration";
66
import type { RequestArgs } from "./base";
7-
import type { AxiosInstance, AxiosResponse } from 'axios';
7+
import type { AxiosInstance, AxiosResponse } from "axios";
8+
{{#withAWSV4Signature}}
9+
import { aws4Interceptor } from "aws4-axios";
10+
{{/withAWSV4Signature}}
811
import { RequiredError } from "./base";
912
{{#withNodeImports}}
1013
import { URL, URLSearchParams } from 'url';
@@ -76,6 +79,25 @@ export const setOAuthToObject = async function (object: any, name: string, scope
7679
}
7780
}
7881

82+
{{#withAWSV4Signature}}
83+
export const setAWS4SignatureInterceptor = async function (globalAxios: AxiosInstance, configuration?: Configuration) {
84+
if (configuration && configuration.awsv4) {
85+
const interceptor = aws4Interceptor({
86+
options: {
87+
region: configuration.awsv4?.options?.region ?? process.env.AWS_REGION ?? 'us-east-1',
88+
service: configuration.awsv4?.options?.service ?? 'execute-api',
89+
},
90+
credentials: {
91+
accessKeyId: configuration.awsv4?.credentials?.accessKeyId ?? process.env.AWS_ACCESS_KEY_ID,
92+
secretAccessKey: configuration.awsv4?.credentials?.secretAccessKey ?? process.env.AWS_SECRET_ACCESS_KEY,
93+
sessionToken: configuration.awsv4?.credentials?.sessionToken ?? process.env.AWS_SESSION_TOKEN
94+
},
95+
});
96+
globalAxios.interceptors.request.use(interceptor);
97+
}
98+
}
99+
{{/withAWSV4Signature}}
100+
79101
function setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = ""): void {
80102
if (parameter == null) return;
81103
if (typeof parameter === "object") {

modules/openapi-generator/src/main/resources/typescript-axios/configuration.mustache

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
/* tslint:disable */
2-
/* eslint-disable */
32
{{>licenseInfo}}
43

4+
interface AWSv4Configuration {
5+
options?: {
6+
region?: string
7+
service?: string
8+
}
9+
credentials?: {
10+
accessKeyId?: string
11+
secretAccessKey?: string,
12+
sessionToken?: string
13+
}
14+
}
15+
516
export interface ConfigurationParameters {
617
apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);
718
username?: string;
819
password?: string;
920
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
21+
awsv4?: AWSv4Configuration;
1022
basePath?: string;
1123
serverIndex?: number;
1224
baseOptions?: any;
@@ -41,6 +53,17 @@ export class Configuration {
4153
* @memberof Configuration
4254
*/
4355
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
56+
/**
57+
* parameter for aws4 signature security
58+
* @param {Object} AWS4Signature - AWS4 Signature security
59+
* @param {string} options.region - aws region
60+
* @param {string} options.service - name of the service.
61+
* @param {string} credentials.accessKeyId - aws access key id
62+
* @param {string} credentials.secretAccessKey - aws access key
63+
* @param {string} credentials.sessionToken - aws session token
64+
* @memberof Configuration
65+
*/
66+
awsv4?: AWSv4Configuration;
4467
/**
4568
* override base path
4669
*
@@ -76,6 +99,7 @@ export class Configuration {
7699
this.username = param.username;
77100
this.password = param.password;
78101
this.accessToken = param.accessToken;
102+
this.awsv4 = param.awsv4;
79103
this.basePath = param.basePath;
80104
this.serverIndex = param.serverIndex;
81105
this.baseOptions = param.baseOptions;

modules/openapi-generator/src/main/resources/typescript-axios/package.mustache

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@
2626
"prepare": "npm run build"
2727
},
2828
"dependencies": {
29+
{{#withAWSV4Signature}}
30+
"axios": "^1.6.1",
31+
"aws4-axios": "^3.3.4"
32+
{{/withAWSV4Signature}}
33+
{{^withAWSV4Signature}}
2934
"axios": "^1.6.1"
35+
{{/withAWSV4Signature}}
3036
},
3137
"devDependencies": {
3238
"@types/node": "^12.11.5",

samples/client/echo_api/typescript-axios/build/common.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import type { Configuration } from "./configuration";
1717
import type { RequestArgs } from "./base";
18-
import type { AxiosInstance, AxiosResponse } from 'axios';
18+
import type { AxiosInstance, AxiosResponse } from "axios";
1919
import { RequiredError } from "./base";
2020

2121
/**
@@ -84,6 +84,7 @@ export const setOAuthToObject = async function (object: any, name: string, scope
8484
}
8585
}
8686

87+
8788
function setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = ""): void {
8889
if (parameter == null) return;
8990
if (typeof parameter === "object") {

samples/client/echo_api/typescript-axios/build/configuration.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* tslint:disable */
2-
/* eslint-disable */
32
/**
43
* Echo Server API
54
* Echo Server API
@@ -13,11 +12,24 @@
1312
*/
1413

1514

15+
interface AWSv4Configuration {
16+
options?: {
17+
region?: string
18+
service?: string
19+
}
20+
credentials?: {
21+
accessKeyId?: string
22+
secretAccessKey?: string,
23+
sessionToken?: string
24+
}
25+
}
26+
1627
export interface ConfigurationParameters {
1728
apiKey?: string | Promise<string> | ((name: string) => string) | ((name: string) => Promise<string>);
1829
username?: string;
1930
password?: string;
2031
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
32+
awsv4?: AWSv4Configuration;
2133
basePath?: string;
2234
serverIndex?: number;
2335
baseOptions?: any;
@@ -52,6 +64,17 @@ export class Configuration {
5264
* @memberof Configuration
5365
*/
5466
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise<string>);
67+
/**
68+
* parameter for aws4 signature security
69+
* @param {Object} AWS4Signature - AWS4 Signature security
70+
* @param {string} options.region - aws region
71+
* @param {string} options.service - name of the service.
72+
* @param {string} credentials.accessKeyId - aws access key id
73+
* @param {string} credentials.secretAccessKey - aws access key
74+
* @param {string} credentials.sessionToken - aws session token
75+
* @memberof Configuration
76+
*/
77+
awsv4?: AWSv4Configuration;
5578
/**
5679
* override base path
5780
*
@@ -87,6 +110,7 @@ export class Configuration {
87110
this.username = param.username;
88111
this.password = param.password;
89112
this.accessToken = param.accessToken;
113+
this.awsv4 = param.awsv4;
90114
this.basePath = param.basePath;
91115
this.serverIndex = param.serverIndex;
92116
this.baseOptions = param.baseOptions;

samples/client/others/typescript-axios/with-separate-models-and-api-inheritance/common.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import type { Configuration } from "./configuration";
1717
import type { RequestArgs } from "./base";
18-
import type { AxiosInstance, AxiosResponse } from 'axios';
18+
import type { AxiosInstance, AxiosResponse } from "axios";
1919
import { RequiredError } from "./base";
2020

2121
/**
@@ -84,6 +84,7 @@ export const setOAuthToObject = async function (object: any, name: string, scope
8484
}
8585
}
8686

87+
8788
function setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = ""): void {
8889
if (parameter == null) return;
8990
if (typeof parameter === "object") {

0 commit comments

Comments
 (0)