Skip to content

Commit 7b4352c

Browse files
committed
- Added write client class methods
1 parent d0900ce commit 7b4352c

14 files changed

+155
-26
lines changed

src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export type Options = {
3636
* @param input The relative ___location of the OpenAPI spec
3737
* @param output The relative ___location of the output directory
3838
* @param httpClient The selected httpClient (fetch, xhr, node or axios)
39+
* @param clientName Custom client class name
3940
* @param useOptions Use options or arguments functions
4041
* @param useUnionTypes Use union types instead of enums
4142
* @param exportCore: Generate core client classes
@@ -51,6 +52,7 @@ export async function generate({
5152
input,
5253
output,
5354
httpClient = HttpClient.FETCH,
55+
clientName,
5456
useOptions = false,
5557
useUnionTypes = false,
5658
exportCore = true,
@@ -88,6 +90,7 @@ export async function generate({
8890
exportSchemas,
8991
indent,
9092
postfix,
93+
clientName,
9194
request
9295
);
9396
break;
@@ -110,6 +113,7 @@ export async function generate({
110113
exportSchemas,
111114
indent,
112115
postfix,
116+
clientName,
113117
request
114118
);
115119
break;

src/templates/client.hbs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { OpenAPIConfig } from './core/OpenAPI';
55
import { {{{httpRequest}}} } from './core/{{{httpRequest}}}';
66
{{#if services}}
77
{{#each services}}
8-
import { {{{name}}} } from './services/{{{name}}}';
8+
import { {{{name}}}{{{@root.postfix}}} } from './services/{{{name}}}{{{@root.postfix}}}';
99
{{/each}}
1010
{{/if}}
1111

@@ -14,10 +14,10 @@ type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;
1414
export class {{{clientName}}} {
1515

1616
{{#each services}}
17-
readonly {{{name}}}: {{{name}}};
17+
public readonly {{{name}}}: {{{name}}}{{{@root.postfix}}};
1818
{{/each}}
1919

20-
readonly request: BaseHttpRequest;
20+
public readonly request: BaseHttpRequest;
2121

2222
constructor(config?: OpenAPIConfig, HttpRequest: HttpRequestConstructor = {{{httpRequest}}}) {
2323
this.request = new HttpRequest({
@@ -33,7 +33,7 @@ export class {{{clientName}}} {
3333
});
3434

3535
{{#each services}}
36-
this.{{{name}}} = new {{{name}}}(this.request);
36+
this.{{{name}}} = new {{{name}}}{{{@root.postfix}}}(this.request);
3737
{{/each}}
3838
}
3939
}

src/templates/core/HttpRequest.hbs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ import { request as __request } from './request';
66

77
export class {{HttpRequest}} extends BaseHttpRequest {
88

9-
constructor(config: OpenAPIConfig) {
10-
super(config);
11-
}
9+
constructor(config: OpenAPIConfig) {
10+
super(config);
11+
}
1212

1313
/**
1414
* Request method
1515
* @param options The request options from the service
1616
* @returns CancelablePromise<T>
1717
* @throws ApiError
1818
*/
19-
public request<T>(options: ApiRequestOptions): CancelablePromise<T> {
20-
return __request(this.config, options);
21-
}
19+
public request<T>(options: ApiRequestOptions): CancelablePromise<T> {
20+
return __request(this.config, options);
21+
}
2222
}

src/utils/registerHandlebarTemplates.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Handlebars from 'handlebars/runtime';
22

33
import { HttpClient } from '../HttpClient';
4+
import templateClient from '../templates/client.hbs';
45
import templateCoreApiError from '../templates/core/ApiError.hbs';
56
import templateCoreApiRequestOptions from '../templates/core/ApiRequestOptions.hbs';
67
import templateCoreApiResult from '../templates/core/ApiResult.hbs';
@@ -10,6 +11,7 @@ import axiosGetResponseBody from '../templates/core/axios/getResponseBody.hbs';
1011
import axiosGetResponseHeader from '../templates/core/axios/getResponseHeader.hbs';
1112
import axiosRequest from '../templates/core/axios/request.hbs';
1213
import axiosSendRequest from '../templates/core/axios/sendRequest.hbs';
14+
import templateCoreBaseHttpRequest from '../templates/core/BaseHttpRequest.hbs';
1315
import templateCancelablePromise from '../templates/core/CancelablePromise.hbs';
1416
import fetchGetHeaders from '../templates/core/fetch/getHeaders.hbs';
1517
import fetchGetRequestBody from '../templates/core/fetch/getRequestBody.hbs';
@@ -29,6 +31,7 @@ import functionIsString from '../templates/core/functions/isString.hbs';
2931
import functionIsStringWithValue from '../templates/core/functions/isStringWithValue.hbs';
3032
import functionIsSuccess from '../templates/core/functions/isSuccess.hbs';
3133
import functionResolve from '../templates/core/functions/resolve.hbs';
34+
import templateCoreHttpRequest from '../templates/core/HttpRequest.hbs';
3235
import nodeGetHeaders from '../templates/core/node/getHeaders.hbs';
3336
import nodeGetRequestBody from '../templates/core/node/getRequestBody.hbs';
3437
import nodeGetResponseBody from '../templates/core/node/getResponseBody.hbs';
@@ -78,6 +81,7 @@ import { registerHandlebarHelpers } from './registerHandlebarHelpers';
7881

7982
export interface Templates {
8083
index: Handlebars.TemplateDelegate;
84+
client: Handlebars.TemplateDelegate;
8185
exports: {
8286
model: Handlebars.TemplateDelegate;
8387
schema: Handlebars.TemplateDelegate;
@@ -90,6 +94,8 @@ export interface Templates {
9094
apiResult: Handlebars.TemplateDelegate;
9195
cancelablePromise: Handlebars.TemplateDelegate;
9296
request: Handlebars.TemplateDelegate;
97+
baseHttpRequest: Handlebars.TemplateDelegate;
98+
httpRequest: Handlebars.TemplateDelegate;
9399
};
94100
}
95101

@@ -107,6 +113,7 @@ export function registerHandlebarTemplates(root: {
107113
// Main templates (entry points for the files we write to disk)
108114
const templates: Templates = {
109115
index: Handlebars.template(templateIndex),
116+
client: Handlebars.template(templateClient),
110117
exports: {
111118
model: Handlebars.template(templateExportModel),
112119
schema: Handlebars.template(templateExportSchema),
@@ -119,6 +126,8 @@ export function registerHandlebarTemplates(root: {
119126
apiResult: Handlebars.template(templateCoreApiResult),
120127
cancelablePromise: Handlebars.template(templateCancelablePromise),
121128
request: Handlebars.template(templateCoreRequest),
129+
httpRequest: Handlebars.template(templateCoreBaseHttpRequest),
130+
baseHttpRequest: Handlebars.template(templateCoreHttpRequest),
122131
},
123132
};
124133

src/utils/writeClient.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ describe('writeClient', () => {
1818

1919
const templates: Templates = {
2020
index: () => 'index',
21+
client: () => 'client',
2122
exports: {
2223
model: () => 'model',
2324
schema: () => 'schema',
@@ -30,6 +31,8 @@ describe('writeClient', () => {
3031
apiResult: () => 'apiResult',
3132
cancelablePromise: () => 'cancelablePromise',
3233
request: () => 'request',
34+
baseHttpRequest: () => 'baseHttpRequest',
35+
httpRequest: () => 'httpRequest',
3336
},
3437
};
3538

@@ -45,7 +48,8 @@ describe('writeClient', () => {
4548
true,
4649
true,
4750
Indent.SPACE_4,
48-
''
51+
'Service',
52+
'AppClient'
4953
);
5054

5155
expect(rmdir).toBeCalled();

src/utils/writeClient.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import type { Client } from '../client/interfaces/Client';
44
import { HttpClient } from '../HttpClient';
55
import { Indent } from '../Indent';
66
import { mkdir, rmdir } from './fileSystem';
7+
import { isDefined } from './isDefined';
78
import { isSubDirectory } from './isSubdirectory';
89
import { Templates } from './registerHandlebarTemplates';
10+
import { writeClientClass } from './writeClientClass';
911
import { writeClientCore } from './writeClientCore';
1012
import { writeClientIndex } from './writeClientIndex';
1113
import { writeClientModels } from './writeClientModels';
@@ -27,6 +29,7 @@ import { writeClientServices } from './writeClientServices';
2729
* @param exportSchemas: Generate schemas
2830
* @param indent: Indentation options (4, 2 or tab)
2931
* @param postfix: Service name postfix
32+
* @param clientName: Custom client class name
3033
* @param request: Path to custom request file
3134
*/
3235
export async function writeClient(
@@ -42,6 +45,7 @@ export async function writeClient(
4245
exportSchemas: boolean,
4346
indent: Indent,
4447
postfix: string,
48+
clientName?: string,
4549
request?: string
4650
): Promise<void> {
4751
const outputPath = resolve(process.cwd(), output);
@@ -87,6 +91,11 @@ export async function writeClient(
8791
await writeClientModels(client.models, templates, outputPathModels, httpClient, useUnionTypes, indent);
8892
}
8993

94+
if (isDefined(clientName)) {
95+
await mkdir(outputPath);
96+
await writeClientClass(client, templates, outputPath, httpClient, clientName, indent, postfix);
97+
}
98+
9099
if (exportCore || exportServices || exportSchemas || exportModels) {
91100
await mkdir(outputPath);
92101
await writeClientIndex(

src/utils/writeClientClass.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { Client } from '../client/interfaces/Client';
2+
import { HttpClient } from '../HttpClient';
3+
import { Indent } from '../Indent';
4+
import { mkdir, rmdir, writeFile } from './fileSystem';
5+
import { Templates } from './registerHandlebarTemplates';
6+
import { writeClientClass } from './writeClientClass';
7+
8+
jest.mock('./fileSystem');
9+
10+
describe('writeClientClass', () => {
11+
it('should write to filesystem', async () => {
12+
const client: Client = {
13+
server: 'http://localhost:8080',
14+
version: 'v1',
15+
models: [],
16+
services: [],
17+
};
18+
19+
const templates: Templates = {
20+
index: () => 'index',
21+
client: () => 'client',
22+
exports: {
23+
model: () => 'model',
24+
schema: () => 'schema',
25+
service: () => 'service',
26+
},
27+
core: {
28+
settings: () => 'settings',
29+
apiError: () => 'apiError',
30+
apiRequestOptions: () => 'apiRequestOptions',
31+
apiResult: () => 'apiResult',
32+
cancelablePromise: () => 'cancelablePromise',
33+
request: () => 'request',
34+
baseHttpRequest: () => 'baseHttpRequest',
35+
httpRequest: () => 'httpRequest',
36+
},
37+
};
38+
39+
await writeClientClass(client, templates, './dist', HttpClient.FETCH, 'AppClient', Indent.SPACE_4, '');
40+
41+
expect(rmdir).toBeCalled();
42+
expect(mkdir).toBeCalled();
43+
expect(writeFile).toBeCalled();
44+
});
45+
});

src/utils/writeClientClass.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { resolve } from 'path';
2+
3+
import type { Client } from '../client/interfaces/Client';
4+
import { HttpClient } from '../HttpClient';
5+
import { Indent } from '../Indent';
6+
import { writeFile } from './fileSystem';
7+
import { formatCode as f } from './formatCode';
8+
import { formatIndentation as i } from './formatIndentation';
9+
import { Templates } from './registerHandlebarTemplates';
10+
import { sortModelsByName } from './sortModelsByName';
11+
import { sortServicesByName } from './sortServicesByName';
12+
/**
13+
* Generate the OpenAPI client index file using the Handlebar template and write it to disk.
14+
* The index file just contains all the exports you need to use the client as a standalone
15+
* library. But yuo can also import individual models and services directly.
16+
* @param client Client object, containing, models, schemas and services
17+
* @param templates The loaded handlebar templates
18+
* @param outputPath Directory to write the generated files to
19+
* @param httpClient The selected httpClient (fetch, xhr, node or axios)
20+
* @param clientName Custom client class name
21+
* @param indent: Indentation options (4, 2 or tab)
22+
* @param postfix: Service name postfix
23+
*/
24+
export async function writeClientClass(
25+
client: Client,
26+
templates: Templates,
27+
outputPath: string,
28+
httpClient: HttpClient,
29+
clientName: string,
30+
indent: Indent,
31+
postfix: string
32+
): Promise<void> {
33+
const templateResult = templates.client({
34+
clientName,
35+
postfix,
36+
server: client.server,
37+
version: client.version,
38+
models: sortModelsByName(client.models),
39+
services: sortServicesByName(client.services),
40+
httpRequest: 'XhrBaseRequest',
41+
});
42+
43+
await writeFile(resolve(outputPath, 'client.ts'), i(f(templateResult), indent));
44+
}

src/utils/writeClientCore.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ describe('writeClientCore', () => {
1818

1919
const templates: Templates = {
2020
index: () => 'index',
21+
client: () => 'client',
2122
exports: {
2223
model: () => 'model',
2324
schema: () => 'schema',
@@ -30,6 +31,8 @@ describe('writeClientCore', () => {
3031
apiResult: () => 'apiResult',
3132
cancelablePromise: () => 'cancelablePromise',
3233
request: () => 'request',
34+
baseHttpRequest: () => 'baseHttpRequest',
35+
httpRequest: () => 'httpRequest',
3336
},
3437
};
3538

src/utils/writeClientIndex.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ describe('writeClientIndex', () => {
1616

1717
const templates: Templates = {
1818
index: () => 'index',
19+
client: () => 'client',
1920
exports: {
2021
model: () => 'model',
2122
schema: () => 'schema',
@@ -28,6 +29,8 @@ describe('writeClientIndex', () => {
2829
apiResult: () => 'apiResult',
2930
cancelablePromise: () => 'cancelablePromise',
3031
request: () => 'request',
32+
baseHttpRequest: () => 'baseHttpRequest',
33+
httpRequest: () => 'httpRequest',
3134
},
3235
};
3336

0 commit comments

Comments
 (0)