这是indexloc提供的服务,不要输入任何密码
Skip to content
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/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