Skip to content
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

feat(client): generate all services in single services.ts file #215

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/blue-flies-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hey-api/openapi-ts": minor
---

feat(client): generate all services in single `services.ts` file
1 change: 0 additions & 1 deletion rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export function handlebarsPlugin(): Plugin {
ifNotNullNotUndefined: true,
ifOperationDataOptional: true,
intersection: true,
modelImports: true,
modelUnionType: true,
nameOperationDataType: true,
notEquals: true,
Expand Down
2 changes: 1 addition & 1 deletion src/templates/client.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { {{{httpRequest}}} } from './core/{{{httpRequest}}}';

{{#if services}}
{{#each services}}
import { {{{name}}}{{{@root.$config.postfixServices}}} } from './services/{{{name}}}{{{@root.$config.postfixServices}}}';
import { {{{name}}}{{{@root.$config.postfixServices}}} } from './services';
{{/each}}
{{/if}}

Expand Down
39 changes: 0 additions & 39 deletions src/templates/exportService.hbs
Original file line number Diff line number Diff line change
@@ -1,42 +1,3 @@
{{#equals @root.$config.client 'angular'}}
{{#if @root.$config.name}}
import { Injectable } from '@angular/core';
import type { Observable } from 'rxjs';
{{else}}
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import type { Observable } from 'rxjs';
{{/if}}
{{/equals}}
{{{modelImports this '../models'}}}
{{#equals @root.$config.serviceResponse 'response'}}
import type { ApiResult } from '../core/ApiResult';
{{/equals}}
{{#notEquals @root.$config.client 'angular'}}
import type { CancelablePromise } from '../core/CancelablePromise';
{{/notEquals}}
{{#if @root.$config.name}}
{{#equals @root.$config.client 'angular'}}
import { BaseHttpRequest } from '../core/BaseHttpRequest';
{{else}}
import type { BaseHttpRequest } from '../core/BaseHttpRequest';
{{/equals}}
{{else}}
{{#if @root.$config.useOptions}}
{{#equals @root.$config.serviceResponse 'generics'}}
import { mergeOpenApiConfig, OpenAPI } from '../core/OpenAPI';
import { request as __request } from '../core/request';
import type { TApiResponse, TConfig, TResult } from '../core/types';
{{else}}
import { OpenAPI } from '../core/OpenAPI';
import { request as __request } from '../core/request';
{{/equals}}
{{else}}
import { OpenAPI } from '../core/OpenAPI';
import { request as __request } from '../core/request';
{{/if}}
{{/if}}

{{{operationDataType this}}}

{{#equals @root.$config.client 'angular'}}
Expand Down
9 changes: 0 additions & 9 deletions src/utils/handlebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,6 @@ const escapeComment = (value: string) =>
.replace(/\/\*/g, '*')
.replace(/\r?\n(.*)/g, (_, w) => `${EOL} * ${w.trim()}`);

const modelImports = (model: Service, path: string) => {
if (model.imports.length === 0) {
return '';
}
return `import type { ${model.imports.join(',')} } from '${path}';`;
};

const dataParameters = (config: Config, parameters: OperationParameter[]) => {
if (config.experimental) {
let output = parameters
Expand Down Expand Up @@ -267,8 +260,6 @@ export const registerHandlebarHelpers = (config: Config, client: Client): void =
}
);

Handlebars.registerHelper('modelImports', modelImports);

Handlebars.registerHelper(
'modelUnionType',
function (models: Model[], parent: string | undefined, filterProperties: 'exact' | undefined) {
Expand Down
3 changes: 1 addition & 2 deletions src/utils/write/__tests__/services.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { writeFileSync } from 'node:fs';
import path from 'node:path';

import { describe, expect, it, vi } from 'vitest';

Expand Down Expand Up @@ -46,6 +45,6 @@ describe('writeClientServices', () => {
write: true,
});

expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/', '/UserService.ts'), 'service');
expect(writeFileSync).toHaveBeenCalled();
});
});
2 changes: 1 addition & 1 deletion src/utils/write/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const writeClient = async (client: Client, templates: Templates, config:
fn: writeClientModels,
},
{
dir: 'services',
dir: '',
enabled: config.exportServices,
fn: writeClientServices,
},
Expand Down
62 changes: 51 additions & 11 deletions src/utils/write/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import type { Client } from '../../types/client';
import type { Config } from '../../types/config';
import type { Templates } from '../handlebars';
import { sortByName } from '../sort';
import { unique } from '../unique';

/**
* Generate Services using the Handlebar template and write to disk.
Expand All @@ -23,20 +23,60 @@
if (client.services.length === 0) {
return;
}
// Generate file for each service.
// Generate a file with all services.
const results: string[] = [];
const imports: string[] = [];
for (const service of client.services) {
const file = path.resolve(outputPath, `${service.name}${config.postfixServices}.ts`);
const templateResult = templates.exports.service({
const result = templates.exports.service({
$config: config,
...service,
});
await writeFileSync(file, templateResult);
imports.push(...service.imports);
results.push(result);
}
// Import all models required by the services.
const uniqueImports = imports.filter(unique);
if (uniqueImports.length > 0) {
const importString = `import type { ${uniqueImports.join(',')} } from './models';`;
results.unshift(importString);
}

Check warning on line 42 in src/utils/write/services.ts

View check run for this annotation

Codecov / codecov/patch

src/utils/write/services.ts#L40-L42

Added lines #L40 - L42 were not covered by tests
// Import required packages and core files.
const imports2: string[] = [];
if (config.client === 'angular') {
imports2.push(`import { Injectable } from '@angular/core';`);
if (config.name === undefined) {
imports2.push(`import { HttpClient } from '@angular/common/http';`);
}
imports2.push(`import type { Observable } from 'rxjs';`);

Check warning on line 50 in src/utils/write/services.ts

View check run for this annotation

Codecov / codecov/patch

src/utils/write/services.ts#L46-L50

Added lines #L46 - L50 were not covered by tests
} else {
imports2.push(`import type { CancelablePromise } from './core/CancelablePromise';`);
}
if (config.serviceResponse === 'response') {
imports2.push(`import type { ApiResult } from './core/ApiResult;`);
}

Check warning on line 56 in src/utils/write/services.ts

View check run for this annotation

Codecov / codecov/patch

src/utils/write/services.ts#L55-L56

Added lines #L55 - L56 were not covered by tests
if (config.name) {
if (config.client === 'angular') {
imports2.push(`import { BaseHttpRequest } from './core/BaseHttpRequest';`);
} else {
imports2.push(`import type { BaseHttpRequest } from './core/BaseHttpRequest';`);
}

Check warning on line 62 in src/utils/write/services.ts

View check run for this annotation

Codecov / codecov/patch

src/utils/write/services.ts#L58-L62

Added lines #L58 - L62 were not covered by tests
} else {
if (config.useOptions) {
if (config.serviceResponse === 'generics') {
imports2.push(`import { mergeOpenApiConfig, OpenAPI } from './core/OpenAPI';`);
imports2.push(`import { request as __request } from './core/request';`);
imports2.push(`import type { TApiResponse, TConfig, TResult } from './core/types';`);
} else {
imports2.push(`import { OpenAPI } from './core/OpenAPI';`);
imports2.push(`import { request as __request } from './core/request';`);
}

Check warning on line 72 in src/utils/write/services.ts

View check run for this annotation

Codecov / codecov/patch

src/utils/write/services.ts#L65-L72

Added lines #L65 - L72 were not covered by tests
} else {
imports2.push(`import { OpenAPI } from './core/OpenAPI';`);
imports2.push(`import { request as __request } from './core/request';`);
}
}
results.unshift(imports2.join('\n'));
// Generate index file exporting all generated service files.
const file = path.resolve(outputPath, 'index.ts');
const content = sortByName(client.services).map(
service =>
`export { ${service.name}${config.postfixServices} } from './${service.name}${config.postfixServices}'`
);
await writeFileSync(file, content.join('\n'));
const file = path.resolve(outputPath, 'services.ts');
await writeFileSync(file, results.join('\n\n'));
};
Loading