Skip to content

Commit 958bb22

Browse files
committed
Merge branch 'pr/1'
2 parents 00cb70b + f84337a commit 958bb22

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+10202
-1087
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ $ openapi --help
4949
--exportSchemas <value> Write schemas to disk (default: false)
5050
--postfix <value> Service name postfix (default: "Service")
5151
--request <value> Path to custom request file
52+
--exportClient <value> Generate and write client class to disk (default: false)
53+
--name <value> Custom client class name (default: "AppClient")
5254
-h, --help display help for command
5355
5456
Examples
@@ -395,6 +397,29 @@ const getToken = async () => {
395397
OpenAPI.TOKEN = getToken;
396398
```
397399

400+
### Generate client instance with `--exportClient` option
401+
402+
The OpenAPI generator allows to create client instances to support the multiple backend services use case.
403+
The generated client uses an instance of the server configuration and not the global `OpenAPI` constant.
404+
405+
To generate a client instance, use `--exportClient` option. To set a custom name to the client class, use `--name` option.
406+
407+
```
408+
openapi --input ./spec.json --output ./dist --exportClient true --name DemoAppClient
409+
```
410+
411+
The generated client will be exported from the `index` file and can be used as shown below:
412+
```typescript
413+
// create the client instance with server and authentication details
414+
const appClient = new DemoAppClient({ BASE: 'http://server-host.com', TOKEN: '1234' });
415+
416+
// use the client instance to make the API call
417+
const res: OrganizationResponse = await appClient.organizations.createOrganization({
418+
name: 'OrgName',
419+
description: 'OrgDescription',
420+
});
421+
```
422+
398423
### References
399424

400425
Local references to schema definitions (those beginning with `#/definitions/schemas/`)

bin/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ const params = program
2020
.option('--exportModels <value>', 'Write models to disk', true)
2121
.option('--exportSchemas <value>', 'Write schemas to disk', false)
2222
.option('--postfix <value>', 'Service name postfix', 'Service')
23+
.option('--exportClient <value>', 'Generate and write client class to disk', false)
2324
.option('--request <value>', 'Path to custom request file')
25+
.option('--name <value>', 'Custom client class name', 'AppClient')
2426
.parse(process.argv)
2527
.opts();
2628

@@ -38,6 +40,8 @@ if (OpenAPI) {
3840
exportModels: JSON.parse(params.exportModels) === true,
3941
exportSchemas: JSON.parse(params.exportSchemas) === true,
4042
postfix: params.postfix,
43+
exportClient: JSON.parse(params.exportClient) === true,
44+
clientName: params.name,
4145
request: params.request,
4246
})
4347
.then(() => {

jest.config.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict';
2+
3+
module.exports = {
4+
projects: [
5+
{
6+
displayName: 'UNIT',
7+
testEnvironment: 'node',
8+
testMatch: [
9+
'<rootDir>/src/**/*.spec.ts',
10+
'<rootDir>/test/index.spec.js',
11+
'<rootDir>/test/index.client.spec.js',
12+
],
13+
moduleFileExtensions: ['js', 'ts', 'd.ts'],
14+
moduleNameMapper: {
15+
'\\.hbs$': '<rootDir>/src/templates/__mocks__/index.js',
16+
},
17+
},
18+
{
19+
displayName: 'E2E',
20+
testEnvironment: 'node',
21+
testMatch: [
22+
'<rootDir>/test/e2e/v2.fetch.spec.js',
23+
'<rootDir>/test/e2e/v2.xhr.spec.js',
24+
'<rootDir>/test/e2e/v2.node.spec.js',
25+
'<rootDir>/test/e2e/v2.axios.spec.js',
26+
'<rootDir>/test/e2e/v2.babel.spec.js',
27+
'<rootDir>/test/e2e/v3.fetch.spec.js',
28+
'<rootDir>/test/e2e/v3.xhr.spec.js',
29+
'<rootDir>/test/e2e/v3.node.spec.js',
30+
'<rootDir>/test/e2e/v3.axios.spec.js',
31+
'<rootDir>/test/e2e/v3.babel.spec.js',
32+
],
33+
},
34+
],
35+
collectCoverageFrom: ['<rootDir>/src/**/*.ts', '!<rootDir>/src/**/*.d.ts', '!<rootDir>/bin', '!<rootDir>/dist'],
36+
};

src/index.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ export type Options = {
2121
exportModels?: boolean;
2222
exportSchemas?: boolean;
2323
postfix?: string;
24+
exportClient?: boolean;
2425
request?: string;
26+
clientName?: string;
2527
write?: boolean;
2628
};
2729

@@ -39,6 +41,8 @@ export type Options = {
3941
* @param exportModels: Generate models
4042
* @param exportSchemas: Generate schemas
4143
* @param postfix: Service name postfix
44+
* @param exportClient: Generate client class
45+
* @param clientName: Custom client class name
4246
* @param request: Path to custom request file
4347
* @param write Write the files to disk (true or false)
4448
*/
@@ -53,6 +57,8 @@ export async function generate({
5357
exportModels = true,
5458
exportSchemas = false,
5559
postfix = 'Service',
60+
exportClient = false,
61+
clientName = 'AppClient',
5662
request,
5763
write = true,
5864
}: Options): Promise<void> {
@@ -67,7 +73,7 @@ export async function generate({
6773
switch (openApiVersion) {
6874
case OpenApiVersion.V2: {
6975
const client = parseV2(openApi);
70-
const clientFinal = postProcessClient(client);
76+
const clientFinal = postProcessClient(client, exportClient);
7177
if (!write) break;
7278
await writeClient(
7379
clientFinal,
@@ -81,14 +87,16 @@ export async function generate({
8187
exportModels,
8288
exportSchemas,
8389
postfix,
90+
exportClient,
91+
clientName,
8492
request
8593
);
8694
break;
8795
}
8896

8997
case OpenApiVersion.V3: {
9098
const client = parseV3(openApi);
91-
const clientFinal = postProcessClient(client);
99+
const clientFinal = postProcessClient(client, exportClient);
92100
if (!write) break;
93101
await writeClient(
94102
clientFinal,
@@ -102,6 +110,8 @@ export async function generate({
102110
exportModels,
103111
exportSchemas,
104112
postfix,
113+
exportClient,
114+
clientName,
105115
request
106116
);
107117
break;

src/openApi/v2/parser/getOperationPath.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { getOperationPath } from './getOperationPath';
33
describe('getOperationPath', () => {
44
it('should produce correct result', () => {
55
expect(getOperationPath('/api/v{api-version}/list/{id}/{type}')).toEqual(
6-
'/api/v${OpenAPI.VERSION}/list/${id}/${type}'
6+
'/api/v${apiVersion}/list/${id}/${type}'
77
);
8-
expect(getOperationPath('/api/v{api-version}/list/{id}')).toEqual('/api/v${OpenAPI.VERSION}/list/${id}');
8+
expect(getOperationPath('/api/v{api-version}/list/{id}')).toEqual('/api/v${apiVersion}/list/${id}');
99
expect(getOperationPath('/api/v1/list/{id}')).toEqual('/api/v1/list/${id}');
1010
expect(getOperationPath('/api/{foobar}')).toEqual('/api/${foobar}');
1111
expect(getOperationPath('/api/{fooBar}')).toEqual('/api/${fooBar}');

src/openApi/v2/parser/getOperationPath.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import { getOperationParameterName } from './getOperationParameterName';
88
* @param path
99
*/
1010
export function getOperationPath(path: string): string {
11-
return path
12-
.replace(/\{(.*?)\}/g, (_, w: string) => {
13-
return `\${${getOperationParameterName(w)}}`;
14-
})
15-
.replace('${apiVersion}', '${OpenAPI.VERSION}');
11+
return path.replace(/\{(.*?)\}/g, (_, w: string) => {
12+
return `\${${getOperationParameterName(w)}}`;
13+
});
1614
}

src/openApi/v3/parser/getOperationPath.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { getOperationPath } from './getOperationPath';
33
describe('getOperationPath', () => {
44
it('should produce correct result', () => {
55
expect(getOperationPath('/api/v{api-version}/list/{id}/{type}')).toEqual(
6-
'/api/v${OpenAPI.VERSION}/list/${id}/${type}'
6+
'/api/v${apiVersion}/list/${id}/${type}'
77
);
8-
expect(getOperationPath('/api/v{api-version}/list/{id}')).toEqual('/api/v${OpenAPI.VERSION}/list/${id}');
8+
expect(getOperationPath('/api/v{api-version}/list/{id}')).toEqual('/api/v${apiVersion}/list/${id}');
99
expect(getOperationPath('/api/v1/list/{id}')).toEqual('/api/v1/list/${id}');
1010
expect(getOperationPath('/api/{foobar}')).toEqual('/api/${foobar}');
1111
expect(getOperationPath('/api/{fooBar}')).toEqual('/api/${fooBar}');

src/openApi/v3/parser/getOperationPath.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import { getOperationParameterName } from './getOperationParameterName';
88
* @param path
99
*/
1010
export function getOperationPath(path: string): string {
11-
return path
12-
.replace(/\{(.*?)\}/g, (_, w: string) => {
13-
return `\${${getOperationParameterName(w)}}`;
14-
})
15-
.replace('${apiVersion}', '${OpenAPI.VERSION}');
11+
return path.replace(/\{(.*?)\}/g, (_, w: string) => {
12+
return `\${${getOperationParameterName(w)}}`;
13+
});
1614
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{{>header}}
2+
3+
import type { ApiRequestOptions } from './ApiRequestOptions';
4+
import type { OpenAPIConfig } from './OpenAPI';
5+
import type { CancelablePromise } from './CancelablePromise';
6+
7+
export class BaseHttpRequest {
8+
readonly openApiConfig: OpenAPIConfig;
9+
10+
constructor(openApiConfig: OpenAPIConfig) {
11+
this.openApiConfig = openApiConfig;
12+
}
13+
14+
request<T>(options: ApiRequestOptions): CancelablePromise<T> {
15+
throw new Error('Not Implemented');
16+
}
17+
}

0 commit comments

Comments
 (0)