Skip to content

Commit 16f101d

Browse files
Himenonclaude
andauthored
feat: Completely remove TypeScript AST dependency and migrate to string-based code generation (#141)
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 7b64d04 commit 16f101d

107 files changed

Lines changed: 1443 additions & 2185 deletions

File tree

Some content is hidden

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

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[日本語](./docs/ja/README-ja.md)
44

55
This library provides TypeScript type definitions and extracted parameters from OpenAPI v3.0.x compliant specifications.
6-
TypeScript AST is used to generate the code, which is accurately converted to TypeScript code.
6+
Template literals are used to generate the code, which is accurately converted to TypeScript code.
77
Since the parameters extracted from OpenAPI can be used freely, it can be used for automatic generation of API Client and Server Side code, load balancer configuration files, etc.
88

99
## Playground
@@ -436,10 +436,10 @@ export namespace Schemas {
436436
}
437437
```
438438

439-
### Define a code template with TypeScript AST
439+
### Define a code template with Template literals
440440

441-
You can extend your code using the API of TypeScript AST.
442-
You can directly use the API of TypeScript AST or use the wrapper API of TypeScript AST provided by this library.
441+
You can extend your code using the API for generating code.
442+
You can directly use the Template literals or use the wrapper API provided by this library.
443443

444444
```ts
445445
import * as Types from "@himenon/openapi-typescript-code-generator/dist/types";
@@ -456,7 +456,7 @@ const generator: Types.CodeGenerator.GenerateFunction<Option> = (
456456
return payload.map(params => {
457457
return factory.InterfaceDeclaration.create({
458458
export: true,
459-
name: params.functionName,
459+
name: params.convertedParams.functionName,
460460
members: [],
461461
});
462462
});
@@ -487,7 +487,7 @@ Generates code that converts OpenAPI Schema to TypeScript type definitions.
487487
#### generateCode
488488

489489
You can specify several of your own code generators, and the generators can use parameters extracted from OpenAPI Schema.
490-
It internally performs the conversion of an array of `string` or `ts.Statement` as a string.
490+
It internally performs the conversion of an array of `string` as a string.
491491

492492
For example, creating a generator in units of file divisions increases the reusability of the generator.
493493

@@ -507,7 +507,7 @@ This is a type definition file for `Templates.FunctionalApiClient`. The reason i
507507
import { TsGenerator } from "@himenon/openapi-typescript-code-generator/dist/api";
508508
```
509509

510-
This is a wrapper API for the TypeScript AST used internally.
510+
This is an API for generating code using Template literals.
511511
It is subject to change without notice.
512512

513513
### OpenApiTools
@@ -561,7 +561,7 @@ If your changes are in line with the design concept, please submit a pull reques
561561
- Typedefs should not contain any entities (file size should be 0 when typedefs are converted to `.js`)
562562
- The directory structure should be mapped to the typedef structure.
563563
- No dependency on any API client library.
564-
- Can be extended by TypeScript AST.
564+
- Can be extended by Template literals.
565565
- Conform to the OpenAPI specification.
566566
- It should be a single file to maintain portability.
567567

@@ -580,9 +580,9 @@ pnpm run test
580580

581581
## Useful development tools
582582

583-
TypeScript AST
583+
Prettier (or other formatters)
584584

585-
- https://ts-ast-viewer.com
585+
- https://prettier.io/
586586

587587
## LICENCE
588588

docs/ja/README-ja.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# @himenon/openapi-typescript-code-generator
22

33
このライブラリは OpenAPI v3.0.x 系に準拠した仕様書から TypeScript の型定義と抽出したパラメーターを提供します。
4-
コードの生成には TypeScript AST を利用し、正確に TypeScript のコードへ変換します。
4+
コードの生成にはテンプレートリテラルを利用し、正確に TypeScript のコードへ変換します。
55
OpenAPI から抽出したパラメーターは自由に使うことができるため、API Client や Server Side 用のコード、ロードバランサーの設定ファイルなどの自動生成に役立てることができます。
66

77
## Playground
@@ -432,10 +432,10 @@ export namespace Schemas {
432432
}
433433
```
434434

435-
### TypeScript AST によるコードテンプレートを定義する
435+
### テンプレートリテラルによるコードテンプレートを定義する
436436

437-
TypeScript AST の API を利用したコードの拡張が可能です
438-
直接 TypeScript の AST の API を利用したり、本ライブラリが提供する TypeScript AST のラッパー API を利用できます。
437+
テンプレートリテラルを利用したコードの拡張が可能です
438+
直接テンプレートリテラルを利用したり、本ライブラリが提供するコード生成用 API を利用できます。
439439

440440
```ts
441441
import * as Types from "@himenon/openapi-typescript-code-generator/dist/types";
@@ -452,7 +452,7 @@ const generator: Types.CodeGenerator.GenerateFunction<Option> = (
452452
return payload.map(params => {
453453
return factory.InterfaceDeclaration.create({
454454
export: true,
455-
name: params.functionName,
455+
name: params.convertedParams.functionName,
456456
members: [],
457457
});
458458
});
@@ -483,7 +483,7 @@ OpenAPI Schema を TypeScript の型定義に変換したコードを生成し
483483
#### generateCode
484484

485485
独自のコードジェネレーターを複数指定することができ、ジェネレーターは OpenAPI Schema から抽出したパラメーターを利用できます。
486-
内部で`string`または`ts.Statement`の配列を文字列として変換を行います。
486+
内部で`string`の配列を文字列として変換を行います。
487487

488488
たとえばファイルの分割の単位でジェネレーターを作成するとジェネレーターの再利用性が高まります。
489489

@@ -503,7 +503,7 @@ OpenAPI Schema から抽出したパラメーターを取得できます。
503503
import { TsGenerator } from "@himenon/openapi-typescript-code-generator/dist/api";
504504
```
505505

506-
内部で利用している TypeScript AST のラッパー API です。
506+
内部で利用している、テンプレートリテラルを用いてコードを生成するための API です。
507507
告知なく変更する可能性があります。
508508

509509
### OpenApiTools
@@ -557,7 +557,7 @@ API 仕様書から TypeScript のコードへ変換するとき、参照関係
557557
- 型定義に実体が含まれないこと(型定義部分を`.js`に変換したとき、ファイルサイズが 0 になること)
558558
- ディレクトリ構造が型定義の構造に写像されること
559559
- どの API クライアントライブラリにも依存しないこと
560-
- TypeScript AST による拡張ができること
560+
- テンプレートリテラルによる拡張ができること
561561
- OpenAPI の仕様に準拠すること
562562
- 1 ファイル化することにより、ポータビリティを保つこと
563563

@@ -576,9 +576,9 @@ pnpm run test
576576

577577
### 便利な開発ツール
578578

579-
TypeScript AST
579+
Prettier (or other formatters)
580580

581-
- https://ts-ast-viewer.com
581+
- https://prettier.io/
582582

583583
## LICENCE
584584

examples/readme-sample/ast-code-template.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const generator: Types.CodeGenerator.GenerateFunction<Option> = (
1212
return payload.map(params => {
1313
return factory.InterfaceDeclaration.create({
1414
export: true,
15-
name: params.functionName,
15+
name: params.convertedParams.functionName,
1616
members: [],
1717
});
1818
});

examples/readme-sample/generator-template.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type * as Types from "@himenon/openapi-typescript-code-generator/dist/typ
33
import * as fs from "fs";
44

55
/** ここにCode Templateの定義を記述してください */
6+
// @ts-ignore -- placeholder example, generator is intentionally omitted
67
const customGenerator: Types.CodeGenerator.CustomGenerator<{}> = {
78
/** .... */
89
};

examples/readme-sample/use-extract-schema-params.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ type Option = {};
44

55
const generator: Types.CodeGenerator.GenerateFunction<Option> = (payload: Types.CodeGenerator.Params[]): string[] => {
66
return payload.map(params => {
7-
return `function ${params.operationId}() { console.log("${params.comment}") }`;
7+
return `function ${params.operationId}() { console.log("${params.operationParams.comment}") }`;
88
});
99
};
1010

package.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
{
22
"name": "@himenon/openapi-typescript-code-generator",
33
"version": "1.1.3",
4-
"description": "OpenAPI Code Generator using TypeScript AST.",
4+
"description": "OpenAPI Code Generator using Template literals.",
55
"keywords": [
66
"openapi",
77
"openapi3",
88
"openapi-codegen",
99
"openapi-generator",
10-
"typescript",
11-
"typescript-ast"
10+
"typescript"
1211
],
1312
"homepage": "https://github.com/Himenon/openapi-typescript-code-generator#readme",
1413
"bugs": {
@@ -119,9 +118,6 @@
119118
"typescript": "6.0.3",
120119
"vitest": "^4.1.5"
121120
},
122-
"peerDependencies": {
123-
"typescript": ">=5"
124-
},
125121
"packageManager": "pnpm@10.33.2",
126122
"engines": {
127123
"node": ">=22.0.0"

src/code-templates/_shared/ApiClientArgument.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import type ts from "typescript";
2-
31
import type { TsGenerator } from "../../api";
42
import type { CodeGenerator } from "../../types";
53

@@ -52,7 +50,7 @@ export const createResponseContentTypeReference = (factory: TsGenerator.Factory.
5250
};
5351

5452
const createHeaders = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params) => {
55-
const members = [];
53+
const members: string[] = [];
5654

5755
if (convertedParams.has2OrMoreRequestContentTypes) {
5856
members.push(
@@ -90,10 +88,10 @@ const createHeaders = (factory: TsGenerator.Factory.Type, { convertedParams }: C
9088
* requestBody: {requestBodyName}[T];
9189
* }
9290
*/
93-
export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params): ts.InterfaceDeclaration | undefined => {
91+
export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params): string | undefined => {
9492
const { convertedParams } = params;
95-
const typeParameters: ts.TypeParameterDeclaration[] = [];
96-
const members: ts.TypeElement[] = [];
93+
const typeParameters: string[] = [];
94+
const members: string[] = [];
9795
if (convertedParams.hasRequestBody && convertedParams.has2OrMoreRequestContentTypes) {
9896
typeParameters.push(
9997
factory.TypeParameterDeclaration.create({

src/code-templates/_shared/ApiClientInterface.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import ts from "typescript";
2-
31
import type { TsGenerator } from "../../api";
42
import type { CodeGenerator } from "../../types";
53
import type { MethodType } from "./MethodBody/types";
@@ -12,7 +10,7 @@ const createErrorResponsesTypeAlias = (typeName: string, factory: TsGenerator.Fa
1210
return factory.TypeAliasDeclaration.create({
1311
export: true,
1412
name: typeName,
15-
type: ts.factory.createToken(ts.SyntaxKind.VoidKeyword),
13+
type: "void",
1614
});
1715
}
1816
return factory.TypeAliasDeclaration.create({
@@ -33,7 +31,7 @@ const createSuccessResponseTypeAlias = (typeName: string, factory: TsGenerator.F
3331
return factory.TypeAliasDeclaration.create({
3432
export: true,
3533
name: typeName,
36-
type: ts.factory.createToken(ts.SyntaxKind.VoidKeyword),
34+
type: "void",
3735
});
3836
}
3937
return factory.TypeAliasDeclaration.create({
@@ -156,12 +154,7 @@ const createEncodingInterface = (factory: TsGenerator.Factory.Type) => {
156154
});
157155
};
158156

159-
export const create = (
160-
factory: TsGenerator.Factory.Type,
161-
list: CodeGenerator.Params[],
162-
methodType: MethodType,
163-
option: Option,
164-
): ts.Statement[] => {
157+
export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], methodType: MethodType, option: Option): string[] => {
165158
const objectLikeOrAnyType = factory.UnionTypeNode.create({
166159
typeNodes: [
167160
factory.TypeReferenceNode.create({

src/code-templates/_shared/MethodBody/CallRequest.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import type ts from "typescript";
2-
31
import type { TsGenerator } from "../../../api";
42
import type { CodeGenerator } from "../../../types";
53
import * as Utils from "../utils";
@@ -18,7 +16,7 @@ export interface Params {
1816
* "application/x-www-form-urlencoded": {},
1917
* }
2018
*/
21-
const createEncodingParams = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params): ts.Expression | undefined => {
19+
const createEncodingParams = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params): string | undefined => {
2220
const content = params.operationParams.requestBody?.content;
2321
if (!content) {
2422
return;
@@ -36,7 +34,7 @@ const createEncodingParams = (factory: TsGenerator.Factory.Type, params: CodeGen
3634
/**
3735
* this.apiClient.request("GET", url, requestBody, headers, queryParameters);
3836
*/
39-
export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, methodType: MethodType): ts.CallExpression => {
37+
export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, methodType: MethodType): string => {
4038
const { convertedParams } = params;
4139
const apiClientVariableIdentifier: Record<MethodType, string> = {
4240
class: "this.apiClient.request",

src/code-templates/_shared/MethodBody/HeaderParameter.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import type ts from "typescript";
2-
31
import type { TsGenerator } from "../../../api";
42
import * as Utils from "../utils";
53

@@ -8,7 +6,7 @@ export interface Params {
86
object: Utils.LiteralExpressionObject;
97
}
108

11-
export const create = (factory: TsGenerator.Factory.Type, params: Params): ts.VariableStatement => {
9+
export const create = (factory: TsGenerator.Factory.Type, params: Params): string => {
1210
return factory.VariableStatement.create({
1311
declarationList: factory.VariableDeclarationList.create({
1412
flag: "const",

0 commit comments

Comments
 (0)