Skip to content

Commit

Permalink
Merge pull request #399 from hey-api/fix/0-39-1
Browse files Browse the repository at this point in the history
fix: export enums from index.ts
  • Loading branch information
mrlubos authored Apr 17, 2024
2 parents d0cc1a3 + f527218 commit dad799d
Show file tree
Hide file tree
Showing 38 changed files with 285 additions and 190 deletions.
5 changes: 5 additions & 0 deletions .changeset/polite-rice-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hey-api/openapi-ts": patch
---

fix: rename models.gen.ts to types.gen.ts
5 changes: 5 additions & 0 deletions .changeset/spicy-numbers-smell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hey-api/openapi-ts": patch
---

fix: export enums from index.ts
29 changes: 23 additions & 6 deletions docs/openapi-ts/migrating.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@ Currently, `index.ts` file exports all generated artifacts. We will be slowly mo
export { ApiError } from './core/ApiError';
export { CancelablePromise, CancelError } from './core/CancelablePromise';
export { OpenAPI, type OpenAPIConfig } from './core/OpenAPI';
export * from './models'; // [!code --]
export * from './schemas'; // [!code --]
export * from './services'; // [!code --]
export * from './enums.gen'; // [!code --]
export * from './schemas.gen'; // [!code --]
export * from './services.gen'; // [!code --]
export * from './types.gen'; // [!code --]
```

Any non-core related imports should be imported as

```js
import type { Model } from 'client/models';
import { $Schema } from 'client/schemas';
import { DefaultService } from 'client/services';
import { Enum } from 'client/enums.gen'
import { $Schema } from 'client/schemas.gen';
import { DefaultService } from 'client/services.gen';
import type { Model } from 'client/types.gen';
```

You don't have to update imports from `core` directory. These will be addressed in later releases.
Expand All @@ -50,6 +52,21 @@ This config option is deprecated and will be removed.

This config option is deprecated and will be removed.

## v0.40.0

### Exported `enums.gen.ts` file

Enums are now re-exported from the main `index.ts` file. This enables a cleaner migration to v0.39.0.

### Renamed `models.gen.ts` file

`models.gen.ts` is now called `types.gen.ts`. If you use imports from `models.gen.ts`, you should be able to easily find and replace all instances.

```js
import type { Model } from 'client/models.gen' // [!code --]
import type { Model } from 'client/types.gen' // [!code ++]
```

## v0.39.0

### Single `enums.gen.ts` file
Expand Down
54 changes: 36 additions & 18 deletions packages/openapi-ts/src/compiler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,24 @@ export type { Property } from './typedef';
export type { Comments } from './utils';
export type { ClassElement, Node, TypeNode } from 'typescript';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const generatedFileName = (fileName: string, insertGen = true) => {
const splitNameAndExtension = (fileName: string) => {
const match = fileName.match(/\.[0-9a-z]+$/i);
const extension = match ? match[0].slice(1) : '';
const filePath = fileName.slice(0, fileName.length - (extension ? extension.length + 1 : 0));
return [filePath, insertGen && 'gen', extension].filter(Boolean).join('.');
};

export const filePath = (folderPath: string, fileName: string, insertGen = true) => {
const name = generatedFileName(fileName, insertGen);
return path.resolve(folderPath, name);
const name = fileName.slice(0, fileName.length - (extension ? extension.length + 1 : 0));
return { extension, name };
};

export class TypeScriptFile {
private _headers: Array<string> = [];
private _imports: Array<ts.Node> = [];
private _items: Array<ts.Node | string> = [];
private _name: string;
private _path: PathLike;

public constructor({ path, header = true }: { path: PathLike; header?: boolean }) {
this._path = path;
public constructor({ dir, name, header = true }: { dir: string; name: string; header?: boolean }) {
this._name = this._setName(name);
this._path = path.resolve(dir, this.getName());

if (header) {
const text = 'This file is auto-generated by @hey-api/openapi-ts';
const comment = addLeadingComment(undefined, [text], true, false);
Expand All @@ -46,10 +43,36 @@ export class TypeScriptFile {
this._items = [...this._items, ...nodes];
}

public addNamedImport(...params: Parameters<typeof module.createNamedImportDeclarations>): void {
public addNamedImport(...params: Parameters<typeof compiler.import.named>): void {
this._imports = [...this._imports, compiler.import.named(...params)];
}

public getName(withExtension = true) {
if (withExtension) {
return this._name;
}

const { name } = splitNameAndExtension(this._name);
return name;
}

public isEmpty() {
return !this._items.length;
}

public remove(options?: Parameters<typeof rmSync>[1]) {
rmSync(this._path, options);
}

private _setName(fileName: string) {
if (fileName.includes('index')) {
return fileName;
}

const { extension, name } = splitNameAndExtension(fileName);
return [name, 'gen', extension].filter(Boolean).join('.');
}

public toString(seperator: string = '\n') {
let output: string[] = [];
if (this._headers.length) {
Expand All @@ -63,17 +86,12 @@ export class TypeScriptFile {
}

public write(seperator = '\n') {
// TODO: throw if path is not set. do not throw if items are empty
if (!this._items.length || !this._path) {
if (this.isEmpty()) {
this.remove({ force: true });
return;
}
writeFileSync(this._path, this.toString(seperator));
}

public remove(options?: Parameters<typeof rmSync>[1]) {
rmSync(this._path, options);
}
}

export const compiler = {
Expand Down
36 changes: 27 additions & 9 deletions packages/openapi-ts/src/utils/write/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import path from 'node:path';

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

import { TypeScriptFile } from '../../../compiler';
import { setConfig } from '../../config';
import { writeClientIndex } from '../index';
import { processIndex } from '../index';

vi.mock('node:fs');

describe('writeClientIndex', () => {
describe('processIndex', () => {
it('writes to filesystem', async () => {
setConfig({
client: 'fetch',
Expand All @@ -30,15 +31,32 @@ describe('writeClientIndex', () => {
useOptions: true,
});

const client: Parameters<typeof writeClientIndex>[0] = {
enumNames: [],
models: [],
server: 'http://localhost:8080',
services: [],
version: '1.0',
const files: Parameters<typeof processIndex>[0]['files'] = {
enums: new TypeScriptFile({
dir: '/',
name: 'enums.ts',
}),
index: new TypeScriptFile({
dir: '/',
name: 'index.ts',
}),
schemas: new TypeScriptFile({
dir: '/',
name: 'schemas.ts',
}),
services: new TypeScriptFile({
dir: '/',
name: 'services.ts',
}),
types: new TypeScriptFile({
dir: '/',
name: 'models.ts',
}),
};

await writeClientIndex(client, '/');
await processIndex({ files });

files.index.write();

expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/', '/index.ts'), expect.anything());
});
Expand Down
28 changes: 22 additions & 6 deletions packages/openapi-ts/src/utils/write/__tests__/models.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import path from 'node:path';

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

import { TypeScriptFile } from '../../../compiler';
import { setConfig } from '../../config';
import { writeTypesAndEnums } from '../models';
import { openApi } from './models';
import { processTypesAndEnums } from '../models';

vi.mock('node:fs');

describe('writeTypesAndEnums', () => {
describe('processTypesAndEnums', () => {
it('writes to filesystem', async () => {
setConfig({
client: 'fetch',
Expand All @@ -32,7 +32,7 @@ describe('writeTypesAndEnums', () => {
useOptions: true,
});

const client: Parameters<typeof writeTypesAndEnums>[2] = {
const client: Parameters<typeof processTypesAndEnums>[0]['client'] = {
enumNames: [],
models: [
{
Expand All @@ -59,8 +59,24 @@ describe('writeTypesAndEnums', () => {
version: 'v1',
};

await writeTypesAndEnums(openApi, '/', client);
const fileEnums = new TypeScriptFile({
dir: '/',
name: 'enums.ts',
});
const fileModels = new TypeScriptFile({
dir: '/',
name: 'models.ts',
});

await processTypesAndEnums({
client,
fileEnums,
fileModels,
});

fileEnums.write();
fileModels.write();

expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/', '/models.gen.ts'), expect.anything());
expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/models.gen.ts'), expect.anything());
});
});
16 changes: 12 additions & 4 deletions packages/openapi-ts/src/utils/write/__tests__/schemas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import path from 'node:path';

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

import { TypeScriptFile } from '../../../compiler';
import { setConfig } from '../../config';
import { writeSchemas } from '../schemas';
import { processSchemas } from '../schemas';
import { openApi } from './models';

vi.mock('node:fs');

describe('writeSchemas', () => {
describe('processSchemas', () => {
it('writes to filesystem', async () => {
setConfig({
client: 'fetch',
Expand Down Expand Up @@ -42,8 +43,15 @@ describe('writeSchemas', () => {
};
}

await writeSchemas(openApi, '/');
const file = new TypeScriptFile({
dir: '/',
name: 'schemas.ts',
});

await processSchemas({ file, openApi });

file.write();

expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/', '/schemas.gen.ts'), expect.anything());
expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/schemas.gen.ts'), expect.anything());
});
});
23 changes: 17 additions & 6 deletions packages/openapi-ts/src/utils/write/__tests__/services.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { writeFileSync } from 'node:fs';
import path from 'node:path';

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

import { TypeScriptFile } from '../../../compiler';
import { setConfig } from '../../config';
import { writeServices } from '../services';
import { openApi } from './models';
import { processServices } from '../services';

vi.mock('node:fs');

describe('writeServices', () => {
describe('processServices', () => {
it('writes to filesystem', async () => {
setConfig({
client: 'fetch',
Expand All @@ -30,7 +31,7 @@ describe('writeServices', () => {
useOptions: false,
});

const client: Parameters<typeof writeServices>[2] = {
const client: Parameters<typeof processServices>[0]['client'] = {
enumNames: [],
models: [],
server: 'http://localhost:8080',
Expand All @@ -45,8 +46,18 @@ describe('writeServices', () => {
version: 'v1',
};

await writeServices(openApi, '/', client);
const file = new TypeScriptFile({
dir: '/',
name: 'services.ts',
});
const files = {
services: file,
};

await processServices({ client, files });

file.write();

expect(writeFileSync).toHaveBeenCalled();
expect(writeFileSync).toHaveBeenCalledWith(path.resolve('/services.gen.ts'), expect.anything());
});
});
Loading

0 comments on commit dad799d

Please sign in to comment.