diff --git a/README.md b/README.md
index 162fb539..89fd628a 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[日本語](./docs/ja/README-ja.md)
This library provides TypeScript type definitions and extracted parameters from OpenAPI v3.0.x compliant specifications.
-TypeScript AST is used to generate the code, which is accurately converted to TypeScript code.
+Template literals are used to generate the code, which is accurately converted to TypeScript code.
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.
## Playground
@@ -436,10 +436,10 @@ export namespace Schemas {
}
```
-### Define a code template with TypeScript AST
+### Define a code template with Template literals
-You can extend your code using the API of TypeScript AST.
-You can directly use the API of TypeScript AST or use the wrapper API of TypeScript AST provided by this library.
+You can extend your code using the API for generating code.
+You can directly use the Template literals or use the wrapper API provided by this library.
```ts
import * as Types from "@himenon/openapi-typescript-code-generator/dist/types";
@@ -456,7 +456,7 @@ const generator: Types.CodeGenerator.GenerateFunction = (
return payload.map(params => {
return factory.InterfaceDeclaration.create({
export: true,
- name: params.functionName,
+ name: params.convertedParams.functionName,
members: [],
});
});
@@ -487,7 +487,7 @@ Generates code that converts OpenAPI Schema to TypeScript type definitions.
#### generateCode
You can specify several of your own code generators, and the generators can use parameters extracted from OpenAPI Schema.
-It internally performs the conversion of an array of `string` or `ts.Statement` as a string.
+It internally performs the conversion of an array of `string` as a string.
For example, creating a generator in units of file divisions increases the reusability of the generator.
@@ -507,7 +507,7 @@ This is a type definition file for `Templates.FunctionalApiClient`. The reason i
import { TsGenerator } from "@himenon/openapi-typescript-code-generator/dist/api";
```
-This is a wrapper API for the TypeScript AST used internally.
+This is an API for generating code using Template literals.
It is subject to change without notice.
### OpenApiTools
@@ -561,7 +561,7 @@ If your changes are in line with the design concept, please submit a pull reques
- Typedefs should not contain any entities (file size should be 0 when typedefs are converted to `.js`)
- The directory structure should be mapped to the typedef structure.
- No dependency on any API client library.
-- Can be extended by TypeScript AST.
+- Can be extended by Template literals.
- Conform to the OpenAPI specification.
- It should be a single file to maintain portability.
@@ -580,9 +580,9 @@ pnpm run test
## Useful development tools
-TypeScript AST
+Prettier (or other formatters)
-- https://ts-ast-viewer.com
+- https://prettier.io/
## LICENCE
diff --git a/docs/ja/README-ja.md b/docs/ja/README-ja.md
index 26c83dcb..907f2be5 100644
--- a/docs/ja/README-ja.md
+++ b/docs/ja/README-ja.md
@@ -1,7 +1,7 @@
# @himenon/openapi-typescript-code-generator
このライブラリは OpenAPI v3.0.x 系に準拠した仕様書から TypeScript の型定義と抽出したパラメーターを提供します。
-コードの生成には TypeScript AST を利用し、正確に TypeScript のコードへ変換します。
+コードの生成にはテンプレートリテラルを利用し、正確に TypeScript のコードへ変換します。
OpenAPI から抽出したパラメーターは自由に使うことができるため、API Client や Server Side 用のコード、ロードバランサーの設定ファイルなどの自動生成に役立てることができます。
## Playground
@@ -432,10 +432,10 @@ export namespace Schemas {
}
```
-### TypeScript AST によるコードテンプレートを定義する
+### テンプレートリテラルによるコードテンプレートを定義する
-TypeScript AST の API を利用したコードの拡張が可能です。
-直接 TypeScript の AST の API を利用したり、本ライブラリが提供する TypeScript AST のラッパー API を利用できます。
+テンプレートリテラルを利用したコードの拡張が可能です。
+直接テンプレートリテラルを利用したり、本ライブラリが提供するコード生成用 API を利用できます。
```ts
import * as Types from "@himenon/openapi-typescript-code-generator/dist/types";
@@ -452,7 +452,7 @@ const generator: Types.CodeGenerator.GenerateFunction = (
return payload.map(params => {
return factory.InterfaceDeclaration.create({
export: true,
- name: params.functionName,
+ name: params.convertedParams.functionName,
members: [],
});
});
@@ -483,7 +483,7 @@ OpenAPI Schema を TypeScript の型定義に変換したコードを生成し
#### generateCode
独自のコードジェネレーターを複数指定することができ、ジェネレーターは OpenAPI Schema から抽出したパラメーターを利用できます。
-内部で`string`または`ts.Statement`の配列を文字列として変換を行います。
+内部で`string`の配列を文字列として変換を行います。
たとえばファイルの分割の単位でジェネレーターを作成するとジェネレーターの再利用性が高まります。
@@ -503,7 +503,7 @@ OpenAPI Schema から抽出したパラメーターを取得できます。
import { TsGenerator } from "@himenon/openapi-typescript-code-generator/dist/api";
```
-内部で利用している TypeScript AST のラッパー API です。
+内部で利用している、テンプレートリテラルを用いてコードを生成するための API です。
告知なく変更する可能性があります。
### OpenApiTools
@@ -557,7 +557,7 @@ API 仕様書から TypeScript のコードへ変換するとき、参照関係
- 型定義に実体が含まれないこと(型定義部分を`.js`に変換したとき、ファイルサイズが 0 になること)
- ディレクトリ構造が型定義の構造に写像されること
- どの API クライアントライブラリにも依存しないこと
-- TypeScript AST による拡張ができること
+- テンプレートリテラルによる拡張ができること
- OpenAPI の仕様に準拠すること
- 1 ファイル化することにより、ポータビリティを保つこと
@@ -576,9 +576,9 @@ pnpm run test
### 便利な開発ツール
-TypeScript AST
+Prettier (or other formatters)
-- https://ts-ast-viewer.com
+- https://prettier.io/
## LICENCE
diff --git a/examples/readme-sample/ast-code-template.ts b/examples/readme-sample/ast-code-template.ts
index 5b31d893..88d5d378 100644
--- a/examples/readme-sample/ast-code-template.ts
+++ b/examples/readme-sample/ast-code-template.ts
@@ -12,7 +12,7 @@ const generator: Types.CodeGenerator.GenerateFunction = (
return payload.map(params => {
return factory.InterfaceDeclaration.create({
export: true,
- name: params.functionName,
+ name: params.convertedParams.functionName,
members: [],
});
});
diff --git a/examples/readme-sample/generator-template.ts b/examples/readme-sample/generator-template.ts
index f6884661..77506bc3 100644
--- a/examples/readme-sample/generator-template.ts
+++ b/examples/readme-sample/generator-template.ts
@@ -3,6 +3,7 @@ import type * as Types from "@himenon/openapi-typescript-code-generator/dist/typ
import * as fs from "fs";
/** ここにCode Templateの定義を記述してください */
+// @ts-ignore -- placeholder example, generator is intentionally omitted
const customGenerator: Types.CodeGenerator.CustomGenerator<{}> = {
/** .... */
};
diff --git a/examples/readme-sample/use-extract-schema-params.ts b/examples/readme-sample/use-extract-schema-params.ts
index 1a842eb2..ef1231e1 100644
--- a/examples/readme-sample/use-extract-schema-params.ts
+++ b/examples/readme-sample/use-extract-schema-params.ts
@@ -4,7 +4,7 @@ type Option = {};
const generator: Types.CodeGenerator.GenerateFunction = (payload: Types.CodeGenerator.Params[]): string[] => {
return payload.map(params => {
- return `function ${params.operationId}() { console.log("${params.comment}") }`;
+ return `function ${params.operationId}() { console.log("${params.operationParams.comment}") }`;
});
};
diff --git a/package.json b/package.json
index 2c050448..c1b4674c 100644
--- a/package.json
+++ b/package.json
@@ -1,14 +1,13 @@
{
"name": "@himenon/openapi-typescript-code-generator",
"version": "1.1.3",
- "description": "OpenAPI Code Generator using TypeScript AST.",
+ "description": "OpenAPI Code Generator using Template literals.",
"keywords": [
"openapi",
"openapi3",
"openapi-codegen",
"openapi-generator",
- "typescript",
- "typescript-ast"
+ "typescript"
],
"homepage": "https://github.com/Himenon/openapi-typescript-code-generator#readme",
"bugs": {
@@ -119,9 +118,6 @@
"typescript": "6.0.3",
"vitest": "^4.1.5"
},
- "peerDependencies": {
- "typescript": ">=5"
- },
"packageManager": "pnpm@10.33.2",
"engines": {
"node": ">=22.0.0"
diff --git a/src/code-templates/_shared/ApiClientArgument.ts b/src/code-templates/_shared/ApiClientArgument.ts
index 96ea3c3e..ad69a784 100644
--- a/src/code-templates/_shared/ApiClientArgument.ts
+++ b/src/code-templates/_shared/ApiClientArgument.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../api";
import type { CodeGenerator } from "../../types";
@@ -52,7 +50,7 @@ export const createResponseContentTypeReference = (factory: TsGenerator.Factory.
};
const createHeaders = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params) => {
- const members = [];
+ const members: string[] = [];
if (convertedParams.has2OrMoreRequestContentTypes) {
members.push(
@@ -90,10 +88,10 @@ const createHeaders = (factory: TsGenerator.Factory.Type, { convertedParams }: C
* requestBody: {requestBodyName}[T];
* }
*/
-export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params): ts.InterfaceDeclaration | undefined => {
+export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params): string | undefined => {
const { convertedParams } = params;
- const typeParameters: ts.TypeParameterDeclaration[] = [];
- const members: ts.TypeElement[] = [];
+ const typeParameters: string[] = [];
+ const members: string[] = [];
if (convertedParams.hasRequestBody && convertedParams.has2OrMoreRequestContentTypes) {
typeParameters.push(
factory.TypeParameterDeclaration.create({
diff --git a/src/code-templates/_shared/ApiClientInterface.ts b/src/code-templates/_shared/ApiClientInterface.ts
index 8c1bf860..f243596e 100644
--- a/src/code-templates/_shared/ApiClientInterface.ts
+++ b/src/code-templates/_shared/ApiClientInterface.ts
@@ -1,5 +1,3 @@
-import ts from "typescript";
-
import type { TsGenerator } from "../../api";
import type { CodeGenerator } from "../../types";
import type { MethodType } from "./MethodBody/types";
@@ -12,7 +10,7 @@ const createErrorResponsesTypeAlias = (typeName: string, factory: TsGenerator.Fa
return factory.TypeAliasDeclaration.create({
export: true,
name: typeName,
- type: ts.factory.createToken(ts.SyntaxKind.VoidKeyword),
+ type: "void",
});
}
return factory.TypeAliasDeclaration.create({
@@ -33,7 +31,7 @@ const createSuccessResponseTypeAlias = (typeName: string, factory: TsGenerator.F
return factory.TypeAliasDeclaration.create({
export: true,
name: typeName,
- type: ts.factory.createToken(ts.SyntaxKind.VoidKeyword),
+ type: "void",
});
}
return factory.TypeAliasDeclaration.create({
@@ -156,12 +154,7 @@ const createEncodingInterface = (factory: TsGenerator.Factory.Type) => {
});
};
-export const create = (
- factory: TsGenerator.Factory.Type,
- list: CodeGenerator.Params[],
- methodType: MethodType,
- option: Option,
-): ts.Statement[] => {
+export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], methodType: MethodType, option: Option): string[] => {
const objectLikeOrAnyType = factory.UnionTypeNode.create({
typeNodes: [
factory.TypeReferenceNode.create({
diff --git a/src/code-templates/_shared/MethodBody/CallRequest.ts b/src/code-templates/_shared/MethodBody/CallRequest.ts
index daff3818..3f394254 100644
--- a/src/code-templates/_shared/MethodBody/CallRequest.ts
+++ b/src/code-templates/_shared/MethodBody/CallRequest.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import * as Utils from "../utils";
@@ -18,7 +16,7 @@ export interface Params {
* "application/x-www-form-urlencoded": {},
* }
*/
-const createEncodingParams = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params): ts.Expression | undefined => {
+const createEncodingParams = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params): string | undefined => {
const content = params.operationParams.requestBody?.content;
if (!content) {
return;
@@ -36,7 +34,7 @@ const createEncodingParams = (factory: TsGenerator.Factory.Type, params: CodeGen
/**
* this.apiClient.request("GET", url, requestBody, headers, queryParameters);
*/
-export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, methodType: MethodType): ts.CallExpression => {
+export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, methodType: MethodType): string => {
const { convertedParams } = params;
const apiClientVariableIdentifier: Record = {
class: "this.apiClient.request",
diff --git a/src/code-templates/_shared/MethodBody/HeaderParameter.ts b/src/code-templates/_shared/MethodBody/HeaderParameter.ts
index 1b86d551..48ca25a1 100644
--- a/src/code-templates/_shared/MethodBody/HeaderParameter.ts
+++ b/src/code-templates/_shared/MethodBody/HeaderParameter.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import * as Utils from "../utils";
@@ -8,7 +6,7 @@ export interface Params {
object: Utils.LiteralExpressionObject;
}
-export const create = (factory: TsGenerator.Factory.Type, params: Params): ts.VariableStatement => {
+export const create = (factory: TsGenerator.Factory.Type, params: Params): string => {
return factory.VariableStatement.create({
declarationList: factory.VariableDeclarationList.create({
flag: "const",
diff --git a/src/code-templates/_shared/MethodBody/PathParameter.ts b/src/code-templates/_shared/MethodBody/PathParameter.ts
index e0887831..c6eebc39 100644
--- a/src/code-templates/_shared/MethodBody/PathParameter.ts
+++ b/src/code-templates/_shared/MethodBody/PathParameter.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import { escapeText2 as escapeText } from "../../../utils";
@@ -16,8 +14,8 @@ export const isPathParameter = (params: any): params is CodeGenerator.PickedPara
const generateUrlVariableStatement = (
factory: TsGenerator.Factory.Type,
urlTemplate: Utils.Params$TemplateExpression,
- variableExpression: ts.Expression,
-): ts.VariableStatement => {
+ variableExpression: string,
+): string => {
return factory.VariableStatement.create({
declarationList: factory.VariableDeclarationList.create({
declarations: [
@@ -38,10 +36,7 @@ const generateUrlVariableStatement = (
/**
* const uri = `[head]${params.parameter.[parameterName]}`;
*/
-const generateUriVariableStatement = (
- factory: TsGenerator.Factory.Type,
- urlTemplate: Utils.Params$TemplateExpression,
-): ts.VariableStatement => {
+const generateUriVariableStatement = (factory: TsGenerator.Factory.Type, urlTemplate: Utils.Params$TemplateExpression): string => {
return factory.VariableStatement.create({
declarationList: factory.VariableDeclarationList.create({
declarations: [
@@ -134,7 +129,7 @@ export const create = (
requestUri: string,
pathParameters: CodeGenerator.PickedParameter[],
methodType: MethodType,
-): ts.VariableStatement => {
+): string => {
const urlTemplate: Utils.Params$TemplateExpression =
pathParameters.length > 0 ? generateUrlTemplateExpression(factory, requestUri, pathParameters) : [{ type: "string", value: requestUri }];
if (methodType === "currying-function") {
diff --git a/src/code-templates/_shared/MethodBody/QueryParameter.ts b/src/code-templates/_shared/MethodBody/QueryParameter.ts
index d8d51b98..99bee82b 100644
--- a/src/code-templates/_shared/MethodBody/QueryParameter.ts
+++ b/src/code-templates/_shared/MethodBody/QueryParameter.ts
@@ -1,5 +1,3 @@
-import ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import * as Utils from "../../../utils";
import * as UtilsExtra from "../utils";
@@ -18,9 +16,9 @@ export interface Params {
};
}
-export const create = (factory: TsGenerator.Factory.Type, params: Params): ts.VariableStatement => {
- const properties: ts.PropertyAssignment[] = Object.entries(params.object).reduce((previous, [key, item]) => {
- const childProperties: ts.PropertyAssignment[] = [
+export const create = (factory: TsGenerator.Factory.Type, params: Params): string => {
+ const properties: string[] = Object.entries(params.object).reduce((previous, [key, item]) => {
+ const childProperties: string[] = [
factory.PropertyAssignment.create({
name: "value",
initializer:
@@ -40,7 +38,7 @@ export const create = (factory: TsGenerator.Factory.Type, params: Params): ts.Va
childProperties.push(
factory.PropertyAssignment.create({
name: "explode",
- initializer: item.explode ? ts.factory.createTrue() : ts.factory.createFalse(),
+ initializer: item.explode ? "true" : "false",
}),
);
const childObjectInitializer = factory.ObjectLiteralExpression.create({
diff --git a/src/code-templates/_shared/MethodBody/__tests__/PathParameter-test.ts b/src/code-templates/_shared/MethodBody/__tests__/PathParameter-test.ts
index 3b144a60..167f6e31 100644
--- a/src/code-templates/_shared/MethodBody/__tests__/PathParameter-test.ts
+++ b/src/code-templates/_shared/MethodBody/__tests__/PathParameter-test.ts
@@ -1,4 +1,3 @@
-import ts from "typescript";
import { describe, expect, test } from "vitest";
import { TsGenerator } from "../../../../api";
@@ -6,75 +5,30 @@ import type { CodeGenerator } from "../../../../types";
import * as Utils from "../../utils";
import * as PathParameter from "../PathParameter";
-const EOL = "\n";
-
-const traverse =
- (expression: ts.Expression) =>
- (context: Pick) =>
- (rootNode: T) => {
- const visit = (node: ts.Node): ts.Node => {
- if (!ts.isSourceFile(node)) {
- return node;
- }
- return context.factory.updateSourceFile(
- node,
- [ts.factory.createExpressionStatement(expression)],
- node.isDeclarationFile,
- node.referencedFiles,
- node.typeReferenceDirectives,
- node.hasNoDefaultLib,
- node.libReferenceDirectives,
- );
- };
- return ts.visitNode(rootNode, visit);
- };
-
-const getText = (expression: ts.Expression) => {
- const source = ts.createSourceFile("", "", ts.ScriptTarget.ESNext);
- const result = ts.transform(source, [traverse(expression)]);
- result.dispose();
-
- const printer = ts.createPrinter(); // AST -> TypeScriptに変換
- return printer.printFile(result.transformed[0] as any);
-};
-
describe("PathParameter Test", () => {
const factory = TsGenerator.Factory.create();
const generate = (url: string, pathParameter: CodeGenerator.PickedParameter[]): string => {
const urlTemplates = PathParameter.generateUrlTemplateExpression(factory, url, pathParameter);
- const expression = Utils.generateTemplateExpression(factory, urlTemplates);
- return getText(expression);
+ return Utils.generateTemplateExpression(factory, urlTemplates);
};
test("generateUrlTemplateExpression", () => {
- expect(generate("/{a}", [{ in: "path", name: "a", required: true }])).toEqual(`\`/\${encodeURIComponent(params.parameter.a)}\`;${EOL}`);
- expect(generate("/{a}/", [{ in: "path", name: "a", required: true }])).toEqual(`\`/\${encodeURIComponent(params.parameter.a)}/\`;${EOL}`);
- expect(generate("/a/{b}", [{ in: "path", name: "b", required: true }])).toEqual(`\`/a/\${encodeURIComponent(params.parameter.b)}\`;${EOL}`);
- expect(generate("/a/{b}/", [{ in: "path", name: "b", required: true }])).toEqual(
- `\`/a/\${encodeURIComponent(params.parameter.b)}/\`;${EOL}`,
- );
- expect(generate("/a/{b}/c", [{ in: "path", name: "b", required: true }])).toEqual(
- `\`/a/\${encodeURIComponent(params.parameter.b)}/c\`;${EOL}`,
- );
- expect(generate("/a/{b}/c/", [{ in: "path", name: "b", required: true }])).toEqual(
- `\`/a/\${encodeURIComponent(params.parameter.b)}/c/\`;${EOL}`,
- );
- expect(generate("/a/b/{c}", [{ in: "path", name: "c", required: true }])).toEqual(
- `\`/a/b/\${encodeURIComponent(params.parameter.c)}\`;${EOL}`,
- );
- expect(generate("/a/b/{c}", [{ in: "path", name: "c", required: true }])).toEqual(
- `\`/a/b/\${encodeURIComponent(params.parameter.c)}\`;${EOL}`,
- );
- expect(generate("/a/b/{c}/", [{ in: "path", name: "c", required: true }])).toEqual(
- `\`/a/b/\${encodeURIComponent(params.parameter.c)}/\`;${EOL}`,
- );
+ expect(generate("/{a}", [{ in: "path", name: "a", required: true }])).toEqual("`/${encodeURIComponent(params.parameter.a)}`");
+ expect(generate("/{a}/", [{ in: "path", name: "a", required: true }])).toEqual("`/${encodeURIComponent(params.parameter.a)}/`");
+ expect(generate("/a/{b}", [{ in: "path", name: "b", required: true }])).toEqual("`/a/${encodeURIComponent(params.parameter.b)}`");
+ expect(generate("/a/{b}/", [{ in: "path", name: "b", required: true }])).toEqual("`/a/${encodeURIComponent(params.parameter.b)}/`");
+ expect(generate("/a/{b}/c", [{ in: "path", name: "b", required: true }])).toEqual("`/a/${encodeURIComponent(params.parameter.b)}/c`");
+ expect(generate("/a/{b}/c/", [{ in: "path", name: "b", required: true }])).toEqual("`/a/${encodeURIComponent(params.parameter.b)}/c/`");
+ expect(generate("/a/b/{c}", [{ in: "path", name: "c", required: true }])).toEqual("`/a/b/${encodeURIComponent(params.parameter.c)}`");
+ expect(generate("/a/b/{c}", [{ in: "path", name: "c", required: true }])).toEqual("`/a/b/${encodeURIComponent(params.parameter.c)}`");
+ expect(generate("/a/b/{c}/", [{ in: "path", name: "c", required: true }])).toEqual("`/a/b/${encodeURIComponent(params.parameter.c)}/`");
expect(generate("/a/b/{c}.json", [{ in: "path", name: "c", required: true }])).toEqual(
- `\`/a/b/\${encodeURIComponent(params.parameter.c)}.json\`;${EOL}`,
+ "`/a/b/${encodeURIComponent(params.parameter.c)}.json`",
);
expect(generate("/{a}.json/{a}.json/{a}.json", [{ in: "path", name: "a", required: true }])).toEqual(
- `\`/\${encodeURIComponent(params.parameter.a)}.json/\${encodeURIComponent(params.parameter.a)}.json/\${encodeURIComponent(params.parameter.a)}.json\`;${EOL}`,
+ "`/${encodeURIComponent(params.parameter.a)}.json/${encodeURIComponent(params.parameter.a)}.json/${encodeURIComponent(params.parameter.a)}.json`",
);
expect(generate("/.json.{a}.json/{a}.json.{a}", [{ in: "path", name: "a", required: true }])).toEqual(
- `\`/.json.\${encodeURIComponent(params.parameter.a)}.json/\${encodeURIComponent(params.parameter.a)}.json.\${encodeURIComponent(params.parameter.a)}\`;${EOL}`,
+ "`/.json.${encodeURIComponent(params.parameter.a)}.json/${encodeURIComponent(params.parameter.a)}.json.${encodeURIComponent(params.parameter.a)}`",
);
expect(
@@ -82,54 +36,54 @@ describe("PathParameter Test", () => {
{ in: "path", name: "a", required: true },
{ in: "path", name: "b", required: true },
]),
- ).toBe(`\`/\${encodeURIComponent(params.parameter.a)}/\${encodeURIComponent(params.parameter.b)}\`;${EOL}`);
+ ).toBe("`/${encodeURIComponent(params.parameter.a)}/${encodeURIComponent(params.parameter.b)}`");
expect(
generate("/{a}/{b}/", [
{ in: "path", name: "a", required: true },
{ in: "path", name: "b", required: true },
]),
- ).toBe(`\`/\${encodeURIComponent(params.parameter.a)}/\${encodeURIComponent(params.parameter.b)}/\`;${EOL}`);
+ ).toBe("`/${encodeURIComponent(params.parameter.a)}/${encodeURIComponent(params.parameter.b)}/`");
expect(
generate("/{a}/{b}/c", [
{ in: "path", name: "a", required: true },
{ in: "path", name: "b", required: true },
]),
- ).toBe(`\`/\${encodeURIComponent(params.parameter.a)}/\${encodeURIComponent(params.parameter.b)}/c\`;${EOL}`);
+ ).toBe("`/${encodeURIComponent(params.parameter.a)}/${encodeURIComponent(params.parameter.b)}/c`");
expect(
generate("/{a}/{b}/c/", [
{ in: "path", name: "a", required: true },
{ in: "path", name: "b", required: true },
]),
- ).toBe(`\`/\${encodeURIComponent(params.parameter.a)}/\${encodeURIComponent(params.parameter.b)}/c/\`;${EOL}`);
+ ).toBe("`/${encodeURIComponent(params.parameter.a)}/${encodeURIComponent(params.parameter.b)}/c/`");
expect(
generate("/{a}/b/{c}", [
{ in: "path", name: "a", required: true },
{ in: "path", name: "c", required: true },
]),
- ).toBe(`\`/\${encodeURIComponent(params.parameter.a)}/b/\${encodeURIComponent(params.parameter.c)}\`;${EOL}`);
+ ).toBe("`/${encodeURIComponent(params.parameter.a)}/b/${encodeURIComponent(params.parameter.c)}`");
expect(
generate("/{a}/b/{c}/", [
{ in: "path", name: "a", required: true },
{ in: "path", name: "c", required: true },
]),
- ).toBe(`\`/\${encodeURIComponent(params.parameter.a)}/b/\${encodeURIComponent(params.parameter.c)}/\`;${EOL}`);
+ ).toBe("`/${encodeURIComponent(params.parameter.a)}/b/${encodeURIComponent(params.parameter.c)}/`");
expect(
generate("/a/{b}/{c}", [
{ in: "path", name: "b", required: true },
{ in: "path", name: "c", required: true },
]),
- ).toBe(`\`/a/\${encodeURIComponent(params.parameter.b)}/\${encodeURIComponent(params.parameter.c)}\`;${EOL}`);
+ ).toBe("`/a/${encodeURIComponent(params.parameter.b)}/${encodeURIComponent(params.parameter.c)}`");
expect(
generate("/a/{b}/{c}/", [
{ in: "path", name: "b", required: true },
{ in: "path", name: "c", required: true },
]),
- ).toBe(`\`/a/\${encodeURIComponent(params.parameter.b)}/\${encodeURIComponent(params.parameter.c)}/\`;${EOL}`);
+ ).toBe("`/a/${encodeURIComponent(params.parameter.b)}/${encodeURIComponent(params.parameter.c)}/`");
expect(
generate("/a/{b}...{c}/", [
{ in: "path", name: "b", required: true },
{ in: "path", name: "c", required: true },
]),
- ).toBe(`\`/a/\${encodeURIComponent(params.parameter.b)}...\${encodeURIComponent(params.parameter.c)}/\`;${EOL}`);
+ ).toBe("`/a/${encodeURIComponent(params.parameter.b)}...${encodeURIComponent(params.parameter.c)}/`");
});
});
diff --git a/src/code-templates/_shared/MethodBody/index.ts b/src/code-templates/_shared/MethodBody/index.ts
index 9148f999..b1fb347a 100644
--- a/src/code-templates/_shared/MethodBody/index.ts
+++ b/src/code-templates/_shared/MethodBody/index.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import { escapeText2 as escapeText } from "../../../utils";
@@ -11,8 +9,8 @@ import * as PathParameter from "./PathParameter";
import * as QueryParameter from "./QueryParameter";
import type { MethodType } from "./types";
-export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, methodType: MethodType): ts.Statement[] => {
- const statements: ts.Statement[] = [];
+export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, methodType: MethodType): string[] => {
+ const statements: string[] = [];
const { convertedParams, operationParams } = params;
const { pickedParameters } = convertedParams;
@@ -65,7 +63,7 @@ export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.
const content = operationParams.requestBody?.content;
if (content) {
const encodingMap = createEncodingMap(content);
- let identifier: ts.Identifier | undefined;
+ let identifier: string | undefined;
if (convertedParams.has2OrMoreRequestContentTypes) {
identifier = factory.Identifier.create({
name: JSON.stringify(encodingMap, null, 2),
diff --git a/src/code-templates/_shared/utils.ts b/src/code-templates/_shared/utils.ts
index d90f5921..2894a00e 100644
--- a/src/code-templates/_shared/utils.ts
+++ b/src/code-templates/_shared/utils.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../api";
import * as Utils from "../../utils";
@@ -10,7 +8,7 @@ export interface StringItem {
export interface ExpressionItem {
type: "property";
- value: ts.Expression;
+ value: string;
}
export type Item = StringItem | ExpressionItem;
@@ -24,7 +22,7 @@ const getTemplateSpan = (
lastIndex: number,
currentItem: ExpressionItem,
nextItem: Item | undefined,
-): ts.TemplateSpan[] => {
+): string[] => {
// == last
if (!nextItem) {
return [
@@ -99,7 +97,7 @@ const getTemplateSpan = (
* `${a}b${c}`
* ``
*/
-export const generateTemplateExpression = (factory: TsGenerator.Factory.Type, list: Params$TemplateExpression): ts.Expression => {
+export const generateTemplateExpression = (factory: TsGenerator.Factory.Type, list: Params$TemplateExpression): string => {
if (list.length === 0) {
return factory.NoSubstitutionTemplateLiteral.create({
text: "",
@@ -117,7 +115,7 @@ export const generateTemplateExpression = (factory: TsGenerator.Factory.Type, li
}
const lastIndex = spanList.length - 1;
const restValue = lastIndex % 2;
- let templateSpans: ts.TemplateSpan[] = [];
+ let templateSpans: string[] = [];
for (let i = 0; i <= (lastIndex - restValue) / 2; i++) {
if (spanList.length === 0) {
continue;
@@ -176,10 +174,7 @@ export const splitVariableText = (text: string): VariableElement[] => {
}, []);
};
-export const generateVariableIdentifier = (
- factory: TsGenerator.Factory.Type,
- name: string,
-): ts.Identifier | ts.PropertyAccessExpression | ts.ElementAccessExpression => {
+export const generateVariableIdentifier = (factory: TsGenerator.Factory.Type, name: string): string => {
if (name.startsWith("/")) {
throw new Error(`can't start '/'. name=${name}`);
}
@@ -197,7 +192,7 @@ export const generateVariableIdentifier = (
name: n2.value,
});
- return rest.reduce((previous, current) => {
+ return rest.reduce((previous, current) => {
if (current.kind === "string" && Utils.isAvailableVariableName(current.value)) {
return factory.PropertyAccessExpression.create({
expression: previous,
@@ -207,7 +202,7 @@ export const generateVariableIdentifier = (
// 直接 .value でアクセスできない場合に ["value"] といった形で参照する
return factory.ElementAccessExpression.create({
expression: previous,
- index: current.value,
+ argumentExpression: factory.StringLiteral.create({ text: current.value }),
});
}, first);
};
@@ -219,8 +214,8 @@ export interface LiteralExpressionObject {
export const generateObjectLiteralExpression = (
factory: TsGenerator.Factory.Type,
obj: LiteralExpressionObject,
- extraProperties: ts.PropertyAssignment[] = [],
-): ts.ObjectLiteralExpression => {
+ extraProperties: string[] = [],
+): string => {
const properties = Object.entries(obj).map(([key, item]) => {
const initializer =
item.type === "variable" ? generateVariableIdentifier(factory, item.value) : factory.StringLiteral.create({ text: item.value });
@@ -231,7 +226,7 @@ export const generateObjectLiteralExpression = (
});
return factory.ObjectLiteralExpression.create({
- properties: extraProperties.concat(properties),
+ properties: [...extraProperties, ...properties],
multiLine: true,
});
};
diff --git a/src/code-templates/class-api-client/ApiClientClass/Class.ts b/src/code-templates/class-api-client/ApiClientClass/Class.ts
index 826476d9..fbf51526 100644
--- a/src/code-templates/class-api-client/ApiClientClass/Class.ts
+++ b/src/code-templates/class-api-client/ApiClientClass/Class.ts
@@ -1,5 +1,3 @@
-import ts from "typescript";
-
import type { TsGenerator } from "../../../api";
/**
@@ -7,15 +5,15 @@ import type { TsGenerator } from "../../../api";
* {members}
* }
*/
-export const create = (factory: TsGenerator.Factory.Type, members: ts.ClassElement[]): ts.ClassDeclaration => {
+export const create = (factory: TsGenerator.Factory.Type, members: string[]): string => {
return factory.ClassDeclaration.create({
name: "Client",
export: true,
members: [
factory.PropertyDeclaration.create({
- modifiers: [ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword)],
+ modifiers: ["private"],
name: "baseUrl",
- type: ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
+ type: "string",
}),
...members,
],
diff --git a/src/code-templates/class-api-client/ApiClientClass/Constructor.ts b/src/code-templates/class-api-client/ApiClientClass/Constructor.ts
index 7c589c05..26230c5d 100644
--- a/src/code-templates/class-api-client/ApiClientClass/Constructor.ts
+++ b/src/code-templates/class-api-client/ApiClientClass/Constructor.ts
@@ -1,11 +1,9 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
/**
* constructor(private apiClient: ApiClient, private baseUrl: string) { }
*/
-export const create = (factory: TsGenerator.Factory.Type): ts.ConstructorDeclaration => {
+export const create = (factory: TsGenerator.Factory.Type): string => {
const parameter1 = factory.ParameterDeclaration.create({
modifiers: "private",
name: "apiClient",
diff --git a/src/code-templates/class-api-client/ApiClientClass/Method.ts b/src/code-templates/class-api-client/ApiClientClass/Method.ts
index e32445fd..4a2e3773 100644
--- a/src/code-templates/class-api-client/ApiClientClass/Method.ts
+++ b/src/code-templates/class-api-client/ApiClientClass/Method.ts
@@ -1,7 +1,5 @@
import { EOL } from "node:os";
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import * as MethodBody from "../../_shared/MethodBody";
@@ -10,7 +8,7 @@ import type { Option } from "../../_shared/types";
export { MethodBody };
const generateParams = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params) => {
- const typeArguments: ts.TypeNode[] = [];
+ const typeArguments: string[] = [];
if (convertedParams.has2OrMoreRequestContentTypes) {
typeArguments.push(
factory.TypeReferenceNode.create({
@@ -41,7 +39,7 @@ const generateResponseReturnType = (
successResponseContentTypeList: string[],
option: Option,
) => {
- let objectType: ts.TypeNode = factory.TypeNode.create({
+ let objectType: string = factory.TypeNode.create({
type: "void",
});
if (successResponseNameList.length === 1) {
@@ -66,7 +64,7 @@ const generateResponseReturnType = (
}
const isOnlyOneResponseContentType = successResponseContentTypeList.length === 1;
- let indexType: ts.TypeNode = factory.TypeReferenceNode.create({
+ let indexType: string = factory.TypeReferenceNode.create({
name: "ResponseContentType",
});
if (isOnlyOneResponseContentType) {
@@ -93,8 +91,8 @@ const generateResponseReturnType = (
});
};
-const methodTypeParameters = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params): ts.TypeParameterDeclaration[] => {
- const typeParameters: ts.TypeParameterDeclaration[] = [];
+const methodTypeParameters = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params): string[] => {
+ const typeParameters: string[] = [];
if (convertedParams.has2OrMoreRequestContentTypes) {
typeParameters.push(
factory.TypeParameterDeclaration.create({
@@ -124,10 +122,10 @@ const methodTypeParameters = (factory: TsGenerator.Factory.Type, { convertedPara
*
* }
*/
-export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, option: Option): ts.MethodDeclaration => {
+export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, option: Option): string => {
const { convertedParams } = params;
- const typeParameters: ts.TypeParameterDeclaration[] = methodTypeParameters(factory, params);
- const methodArguments: ts.ParameterDeclaration[] = [];
+ const typeParameters: string[] = methodTypeParameters(factory, params);
+ const methodArguments: string[] = [];
const hasParamsArguments =
convertedParams.hasParameter ||
convertedParams.hasRequestBody ||
@@ -138,7 +136,7 @@ export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.
methodArguments.push(generateParams(factory, params));
}
- const returnType: ts.TypeNode = generateResponseReturnType(
+ const returnType: string = generateResponseReturnType(
factory,
convertedParams.responseSuccessNames,
convertedParams.successResponseContentTypes,
diff --git a/src/code-templates/class-api-client/ApiClientClass/index.ts b/src/code-templates/class-api-client/ApiClientClass/index.ts
index a528d391..717e9716 100644
--- a/src/code-templates/class-api-client/ApiClientClass/index.ts
+++ b/src/code-templates/class-api-client/ApiClientClass/index.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import * as ApiClientInterface from "../../_shared/ApiClientInterface";
@@ -10,7 +8,7 @@ import * as Method from "./Method";
export { Method };
-export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: Option): ts.Statement[] => {
+export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: Option): string[] => {
const methodList = list.map(params => {
return Method.create(factory, params, option);
});
diff --git a/src/code-templates/class-api-client/index.ts b/src/code-templates/class-api-client/index.ts
index a1e1def7..38ca27f0 100644
--- a/src/code-templates/class-api-client/index.ts
+++ b/src/code-templates/class-api-client/index.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import { TsGenerator } from "../../api";
import type { CodeGenerator } from "../../types";
import * as ApiClientArgument from "../_shared/ApiClientArgument";
@@ -12,7 +10,7 @@ export const generator: CodeGenerator.GenerateFunction = (
codeGeneratorParamsList: CodeGenerator.Params[],
option?: Option,
): CodeGenerator.IntermediateCode[] => {
- const statements: ts.Statement[] = [];
+ const statements: string[] = [];
const factory = TsGenerator.Factory.create();
codeGeneratorParamsList.forEach(codeGeneratorParams => {
const { convertedParams } = codeGeneratorParams;
diff --git a/src/code-templates/currying-functional-api-client/FunctionalApiClient/CurryingArrowFunction.ts b/src/code-templates/currying-functional-api-client/FunctionalApiClient/CurryingArrowFunction.ts
index 300e9fa4..4f931d7d 100644
--- a/src/code-templates/currying-functional-api-client/FunctionalApiClient/CurryingArrowFunction.ts
+++ b/src/code-templates/currying-functional-api-client/FunctionalApiClient/CurryingArrowFunction.ts
@@ -1,5 +1,3 @@
-import ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import * as MethodBody from "../../_shared/MethodBody";
@@ -8,7 +6,7 @@ import type { Option } from "../../_shared/types";
export { MethodBody };
const generateParams = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params) => {
- const typeArguments: ts.TypeNode[] = [];
+ const typeArguments: string[] = [];
if (convertedParams.has2OrMoreRequestContentTypes) {
typeArguments.push(
factory.TypeReferenceNode.create({
@@ -39,7 +37,7 @@ const generateResponseReturnType = (
successResponseContentTypeList: string[],
option: Option,
) => {
- let objectType: ts.TypeNode = factory.TypeNode.create({
+ let objectType: string = factory.TypeNode.create({
type: "void",
});
if (successResponseNameList.length === 1) {
@@ -64,7 +62,7 @@ const generateResponseReturnType = (
}
const isOnlyOneResponseContentType = successResponseContentTypeList.length === 1;
- let indexType: ts.TypeNode = factory.TypeReferenceNode.create({
+ let indexType: string = factory.TypeReferenceNode.create({
name: "ResponseContentType",
});
if (isOnlyOneResponseContentType) {
@@ -91,8 +89,8 @@ const generateResponseReturnType = (
});
};
-const methodTypeParameters = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params): ts.TypeParameterDeclaration[] => {
- const typeParameters: ts.TypeParameterDeclaration[] = [];
+const methodTypeParameters = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params): string[] => {
+ const typeParameters: string[] = [];
if (convertedParams.has2OrMoreRequestContentTypes) {
typeParameters.push(
factory.TypeParameterDeclaration.create({
@@ -119,10 +117,10 @@ const methodTypeParameters = (factory: TsGenerator.Factory.Type, { convertedPara
/**
* async (params: {argumentParamsTypeDeclaration}<{RequestContentType}>): Promise<{requestBodyName}[ResponseContentType]> => {}
*/
-export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, option: Option): ts.ArrowFunction => {
+export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, option: Option): string => {
const { convertedParams } = params;
- const typeParameters: ts.TypeParameterDeclaration[] = methodTypeParameters(factory, params);
- const methodArguments: ts.ParameterDeclaration[] = [];
+ const typeParameters: string[] = methodTypeParameters(factory, params);
+ const methodArguments: string[] = [];
const hasParamsArguments =
convertedParams.hasParameter ||
convertedParams.hasRequestBody ||
@@ -133,7 +131,7 @@ export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.
methodArguments.push(generateParams(factory, params));
}
- const returnType: ts.TypeNode = generateResponseReturnType(
+ const returnType: string = generateResponseReturnType(
factory,
convertedParams.responseSuccessNames,
convertedParams.successResponseContentTypes,
@@ -175,7 +173,6 @@ export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.
}),
}),
],
- equalsGreaterThanToken: ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
body: curryingFunction,
});
};
diff --git a/src/code-templates/currying-functional-api-client/FunctionalApiClient/ReturnStatement.ts b/src/code-templates/currying-functional-api-client/FunctionalApiClient/ReturnStatement.ts
index a55ee765..fbff3240 100644
--- a/src/code-templates/currying-functional-api-client/FunctionalApiClient/ReturnStatement.ts
+++ b/src/code-templates/currying-functional-api-client/FunctionalApiClient/ReturnStatement.ts
@@ -1,9 +1,7 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
-export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[]): ts.ReturnStatement => {
+export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[]): string => {
const properties = list.map(item => {
return factory.ShorthandPropertyAssignment.create({
name: item.convertedParams.functionName,
diff --git a/src/code-templates/currying-functional-api-client/FunctionalApiClient/index.ts b/src/code-templates/currying-functional-api-client/FunctionalApiClient/index.ts
index 57d4c719..98195ab9 100644
--- a/src/code-templates/currying-functional-api-client/FunctionalApiClient/index.ts
+++ b/src/code-templates/currying-functional-api-client/FunctionalApiClient/index.ts
@@ -1,12 +1,11 @@
import { EOL } from "node:os";
-import ts from "typescript";
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import type { Option } from "../../_shared/types";
import * as ArrowFunction from "./CurryingArrowFunction";
-export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: Option): ts.Statement[] => {
+export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: Option): string[] => {
const variableStatements = list.map(params => {
return factory.VariableStatement.create({
comment: option.additionalMethodComment
@@ -14,7 +13,7 @@ export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Pa
.filter(t => !!t)
.join(EOL)
: params.operationParams.comment,
- modifiers: [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
+ modifiers: ["export"],
declarationList: factory.VariableDeclarationList.create({
declarations: [
factory.VariableDeclaration.create({
diff --git a/src/code-templates/currying-functional-api-client/index.ts b/src/code-templates/currying-functional-api-client/index.ts
index a8485e94..43fa0a6e 100644
--- a/src/code-templates/currying-functional-api-client/index.ts
+++ b/src/code-templates/currying-functional-api-client/index.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import { TsGenerator } from "../../api";
import type { CodeGenerator } from "../../types";
import * as ApiClientArgument from "../_shared/ApiClientArgument";
@@ -13,7 +11,7 @@ export const generator: CodeGenerator.GenerateFunction = (
codeGeneratorParamsList: CodeGenerator.Params[],
option?: Option,
): CodeGenerator.IntermediateCode[] => {
- const statements: ts.Statement[] = [];
+ const statements: string[] = [];
const factory = TsGenerator.Factory.create();
codeGeneratorParamsList.forEach(codeGeneratorParams => {
const { convertedParams } = codeGeneratorParams;
diff --git a/src/code-templates/functional-api-client/FunctionalApiClient/ArrowFunction.ts b/src/code-templates/functional-api-client/FunctionalApiClient/ArrowFunction.ts
index ff5258f7..1b6b0629 100644
--- a/src/code-templates/functional-api-client/FunctionalApiClient/ArrowFunction.ts
+++ b/src/code-templates/functional-api-client/FunctionalApiClient/ArrowFunction.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import * as MethodBody from "../../_shared/MethodBody";
@@ -8,7 +6,7 @@ import type { Option } from "../../_shared/types";
export { MethodBody };
const generateParams = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params) => {
- const typeArguments: ts.TypeNode[] = [];
+ const typeArguments: string[] = [];
if (convertedParams.has2OrMoreRequestContentTypes) {
typeArguments.push(
factory.TypeReferenceNode.create({
@@ -39,7 +37,7 @@ const generateResponseReturnType = (
successResponseContentTypeList: string[],
option: Option,
) => {
- let objectType: ts.TypeNode = factory.TypeNode.create({
+ let objectType: string = factory.TypeNode.create({
type: "void",
});
if (successResponseNameList.length === 1) {
@@ -64,7 +62,7 @@ const generateResponseReturnType = (
}
const isOnlyOneResponseContentType = successResponseContentTypeList.length === 1;
- let indexType: ts.TypeNode = factory.TypeReferenceNode.create({
+ let indexType: string = factory.TypeReferenceNode.create({
name: "ResponseContentType",
});
if (isOnlyOneResponseContentType) {
@@ -91,8 +89,8 @@ const generateResponseReturnType = (
});
};
-const methodTypeParameters = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params): ts.TypeParameterDeclaration[] => {
- const typeParameters: ts.TypeParameterDeclaration[] = [];
+const methodTypeParameters = (factory: TsGenerator.Factory.Type, { convertedParams }: CodeGenerator.Params): string[] => {
+ const typeParameters: string[] = [];
if (convertedParams.has2OrMoreRequestContentTypes) {
typeParameters.push(
factory.TypeParameterDeclaration.create({
@@ -119,10 +117,10 @@ const methodTypeParameters = (factory: TsGenerator.Factory.Type, { convertedPara
/**
* async (params: {argumentParamsTypeDeclaration}<{RequestContentType}>): Promise<{requestBodyName}[ResponseContentType]> => {}
*/
-export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, option: Option): ts.ArrowFunction => {
+export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.Params, option: Option): string => {
const { convertedParams } = params;
- const typeParameters: ts.TypeParameterDeclaration[] = methodTypeParameters(factory, params);
- const methodArguments: ts.ParameterDeclaration[] = [];
+ const typeParameters: string[] = methodTypeParameters(factory, params);
+ const methodArguments: string[] = [];
const hasParamsArguments =
convertedParams.hasParameter ||
convertedParams.hasRequestBody ||
@@ -133,7 +131,7 @@ export const create = (factory: TsGenerator.Factory.Type, params: CodeGenerator.
methodArguments.push(generateParams(factory, params));
}
- const returnType: ts.TypeNode = generateResponseReturnType(
+ const returnType: string = generateResponseReturnType(
factory,
convertedParams.responseSuccessNames,
convertedParams.successResponseContentTypes,
diff --git a/src/code-templates/functional-api-client/FunctionalApiClient/ClientTypeDefinition.ts b/src/code-templates/functional-api-client/FunctionalApiClient/ClientTypeDefinition.ts
index 02974a18..f45e9e89 100644
--- a/src/code-templates/functional-api-client/FunctionalApiClient/ClientTypeDefinition.ts
+++ b/src/code-templates/functional-api-client/FunctionalApiClient/ClientTypeDefinition.ts
@@ -1,7 +1,6 @@
-import type ts from "typescript";
import type { TsGenerator } from "../../../api";
-export const create = (factory: TsGenerator.Factory.Type): ts.TypeAliasDeclaration[] => {
+export const create = (factory: TsGenerator.Factory.Type): string[] => {
return [
factory.TypeAliasDeclaration.create({
name: "ClientFunction",
diff --git a/src/code-templates/functional-api-client/FunctionalApiClient/ReturnStatement.ts b/src/code-templates/functional-api-client/FunctionalApiClient/ReturnStatement.ts
index a55ee765..fbff3240 100644
--- a/src/code-templates/functional-api-client/FunctionalApiClient/ReturnStatement.ts
+++ b/src/code-templates/functional-api-client/FunctionalApiClient/ReturnStatement.ts
@@ -1,9 +1,7 @@
-import type ts from "typescript";
-
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
-export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[]): ts.ReturnStatement => {
+export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[]): string => {
const properties = list.map(item => {
return factory.ShorthandPropertyAssignment.create({
name: item.convertedParams.functionName,
diff --git a/src/code-templates/functional-api-client/FunctionalApiClient/index.ts b/src/code-templates/functional-api-client/FunctionalApiClient/index.ts
index 81ff6f26..8838d8cb 100644
--- a/src/code-templates/functional-api-client/FunctionalApiClient/index.ts
+++ b/src/code-templates/functional-api-client/FunctionalApiClient/index.ts
@@ -1,12 +1,11 @@
import { EOL } from "node:os";
-import ts from "typescript";
import type { TsGenerator } from "../../../api";
import type { CodeGenerator } from "../../../types";
import type { Option } from "../../_shared/types";
import * as ArrowFunction from "./ArrowFunction";
-export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: Option): ts.VariableStatement => {
+export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Params[], option: Option): string => {
const properties = list.map(params => {
return factory.PropertyAssignment.create({
name: params.convertedParams.functionName,
@@ -46,7 +45,7 @@ export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Pa
}),
factory.ParameterDeclaration.create({
name: "baseUrl",
- type: ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
+ type: "string",
}),
],
body: factory.Block.create({
@@ -75,7 +74,7 @@ export const create = (factory: TsGenerator.Factory.Type, list: CodeGenerator.Pa
});
return factory.VariableStatement.create({
- modifiers: [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)],
+ modifiers: ["export"],
declarationList: factory.VariableDeclarationList.create({
declarations: [
factory.VariableDeclaration.create({
diff --git a/src/code-templates/functional-api-client/index.ts b/src/code-templates/functional-api-client/index.ts
index 3e20747c..441e9a6c 100644
--- a/src/code-templates/functional-api-client/index.ts
+++ b/src/code-templates/functional-api-client/index.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import { TsGenerator } from "../../api";
import type { CodeGenerator } from "../../types";
import * as ApiClientArgument from "../_shared/ApiClientArgument";
@@ -14,7 +12,7 @@ export const generator: CodeGenerator.GenerateFunction = (
codeGeneratorParamsList: CodeGenerator.Params[],
option?: Option,
): CodeGenerator.IntermediateCode[] => {
- const statements: ts.Statement[] = [];
+ const statements: string[] = [];
const factory = TsGenerator.Factory.create();
codeGeneratorParamsList.forEach(codeGeneratorParams => {
const { convertedParams } = codeGeneratorParams;
diff --git a/src/index.ts b/src/index.ts
index 8a9b3c14..ac407f47 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -58,7 +58,7 @@ export class CodeGenerator {
const statements = this.parser.getOpenApiTypeDefinitionStatements();
generatorTemplates?.forEach(generatorTemplate => {
const payload = this.parser.getCodeGeneratorParamsArray(allowOperationIds);
- const extraStatements = Api.TsGenerator.Utils.convertIntermediateCodes(generatorTemplate.generator(payload, generatorTemplate.option));
+ const extraStatements = generatorTemplate.generator(payload, generatorTemplate.option);
statements.push(...extraStatements);
});
return statements;
@@ -76,7 +76,7 @@ export class CodeGenerator {
const payload = this.parser.getCodeGeneratorParamsArray(allowOperationIds);
const create = () => {
return generatorTemplates.flatMap(generatorTemplate => {
- return Api.TsGenerator.Utils.convertIntermediateCodes(generatorTemplate?.generator(payload, generatorTemplate.option));
+ return generatorTemplate?.generator(payload, generatorTemplate.option);
});
};
return [Api.OpenApiTools.Comment.generateLeading(this.resolvedReferenceDocument), Api.TsGenerator.generate(create)].join(EOL + EOL + EOL);
diff --git a/src/internal/OpenApiTools/ConverterContext.ts b/src/internal/OpenApiTools/ConverterContext.ts
index 48242e6e..3d351ff3 100644
--- a/src/internal/OpenApiTools/ConverterContext.ts
+++ b/src/internal/OpenApiTools/ConverterContext.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import * as Utils from "../../utils";
import type { Factory } from "../TsGenerator";
@@ -68,10 +66,10 @@ export interface Types {
generateParameterName: (operationId: string) => string;
generateRequestBodyName: (operationId: string) => string;
generateFunctionName: (operationId: string) => string;
- convertFormatTypeNode: (schema: { format?: string }) => undefined | ts.TypeNode;
+ convertFormatTypeNode: (schema: { format?: string }) => string | undefined;
}
-const createFormatSchemaToTypeNode = (factory: Factory.Type, target: FormatConversion): ts.TypeNode => {
+const createFormatSchemaToTypeNode = (factory: Factory.Type, target: FormatConversion): string => {
const typeNodes = target.output.type.map(value => {
return factory.TypeReferenceNode.create({
name: value,
@@ -111,11 +109,9 @@ export const create = (factory: Factory.Type, options?: Options): Types => {
return convertOperationId(operationId);
},
escapeDeclarationText: (text: string) => {
- // console.log(`escapeDeclarationText: ${text}` + `-> ${convertReservedWord(convertString(text).replace(/\./g, "$"))}`.padStart(100, " "));
return convertReservedWord(convertString(text).replace(/\./g, "$"));
},
escapeReferenceDeclarationText: (text: string) => {
- // console.log(`escapeDeclarationText3: ${text}` + `-> ${convertReservedWord(convertString(text))}`.padStart(100, " "));
return convertReservedWord(convertString(text));
},
escapePropertySignatureName: (text: string) => {
diff --git a/src/internal/OpenApiTools/Parser.ts b/src/internal/OpenApiTools/Parser.ts
index 9e8534e7..2240a773 100644
--- a/src/internal/OpenApiTools/Parser.ts
+++ b/src/internal/OpenApiTools/Parser.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { CodeGenerator, OpenApi } from "../../types";
import * as TypeScriptCodeGenerator from "../TsGenerator";
import * as ConvertContext from "./ConverterContext";
@@ -92,21 +90,6 @@ export class Parser {
this.convertContext,
);
}
- // if (rootSchema.components.securitySchemes) {
- // SecuritySchemas.generateNamespace(this.entryPoint, currentPoint, store, factory, rootSchema.components.securitySchemes);
- // }
- // if (rootSchema.components.pathItems) {
- // PathItems.generateNamespace(this.entryPoint, currentPoint, store, factory, rootSchema.components.pathItems, toTypeNodeContext);
- // }
- // TODO Feature Development
- // if (rootSchema.components.links) {
- // statements.push(Links.generateNamespace(this.entryPoint, currentPoint, factory, rootSchema.components.links));
- // }
-
- // TODO Feature Development
- // if (rootSchema.components.callbacks) {
- // statements.push(Callbacks.generateNamespace(this.entryPoint, currentPoint, factory, rootSchema.components.callbacks));
- // }
}
if (rootSchema.paths) {
Paths.generateStatements(
@@ -125,11 +108,11 @@ export class Parser {
return Extractor.generateCodeGeneratorParamsArray(this.store, this.convertContext, allowOperationIds);
}
- public getOpenApiTypeDefinitionStatements(): ts.Statement[] {
+ public getOpenApiTypeDefinitionStatements(): string[] {
return this.store.getRootStatements();
}
- public getAdditionalTypeStatements(): ts.Statement[] {
+ public getAdditionalTypeStatements(): string[] {
return this.store.getAdditionalStatements();
}
}
diff --git a/src/internal/OpenApiTools/TypeNodeContext.ts b/src/internal/OpenApiTools/TypeNodeContext.ts
index bd0f3e43..e982190a 100644
--- a/src/internal/OpenApiTools/TypeNodeContext.ts
+++ b/src/internal/OpenApiTools/TypeNodeContext.ts
@@ -1,15 +1,15 @@
import * as Path from "node:path";
import * as DotProp from "dot-prop";
-import ts from "typescript";
-
import type { OpenApi } from "../../types";
import { DevelopmentError } from "../Exception";
import type * as TypeScriptCodeGenerator from "../TsGenerator";
import type * as ConverterContext from "./ConverterContext";
import * as Reference from "./components/Reference";
+import * as Schema from "./components/Schema";
import * as Guard from "./Guard";
import * as ToTypeNode from "./toTypeNode";
+import type { ObjectSchema } from "./types";
import type * as Walker from "./Walker";
export interface ReferencePathSet {
@@ -17,7 +17,19 @@ export interface ReferencePathSet {
base: string;
}
-const generatePath = (entryPoint: string, currentPoint: string, referencePath: string): ReferencePathSet => {
+/**
+ * エントリポイント、現在のファイルパス、参照パスから、相対的なパスの配列とベースディレクトリを生成します。
+ *
+ * @param entryPoint - OpenAPI定義のエントリポイント(例: "openapi.yml")
+ * @param currentPoint - 現在処理中のファイルパス(例: "components/schemas/A.yml")
+ * @param referencePath - 参照先のパス(例: "components/schemas/B.yml")
+ * @returns パスの配列とベースディレクトリのセット
+ *
+ * @example
+ * generatePath("openapi.yml", "components/schemas/User.yml", "components/schemas/Common.yml")
+ * // 返り値の例: { pathArray: ["Common"], base: "components/schemas" }
+ */
+export const generatePath = (entryPoint: string, currentPoint: string, referencePath: string): ReferencePathSet => {
const ext = Path.extname(currentPoint); // .yml
const from = Path.relative(Path.dirname(entryPoint), currentPoint).replace(ext, ""); // components/schemas/A/B
const base = Path.dirname(from).replace(Path.sep, "/");
@@ -29,7 +41,16 @@ const generatePath = (entryPoint: string, currentPoint: string, referencePath: s
};
};
-const calculateReferencePath = (
+/**
+ * store を参照して、参照先のパスから TypeScript の型名や名前空間の階層を計算します。
+ *
+ * @param store - 型定義の情報を保持するストア
+ * @param base - 探索のベースディレクトリ
+ * @param pathArray - 探索対象のパス配列
+ * @param converterContext - 変換コンテキスト
+ * @returns 解決された型名や未解決のパス、階層の深さなどの情報
+ */
+export const calculateReferencePath = (
store: Walker.Store,
base: string,
pathArray: string[],
@@ -123,52 +144,68 @@ export const create = (
return;
}
if (reference.type === "remote") {
- const typeNode = ToTypeNode.convert(
- entryPoint,
- reference.referencePoint,
- factory,
- reference.data,
- {
- rootSchema,
- setReferenceHandler,
- resolveReferencePath,
- findSchemaByPathArray,
- },
- converterContext,
- );
- if (ts.isTypeLiteralNode(typeNode)) {
+ const data = reference.data;
+ const context = { rootSchema, setReferenceHandler, resolveReferencePath, findSchemaByPathArray };
+ // Determine if the schema should be treated as an interface equivalent
+ // (e.g., plain object schemas that are not nullable and don't produce IntersectionTypeNode)
+ const isInterfaceEquivalent = (() => {
+ if (typeof data === "boolean") return true;
+ if (Guard.isReference(data)) return false;
+ if (Guard.isOneOfSchema(data) || Guard.isAllOfSchema(data) || Guard.isAnyOfSchema(data)) return false;
+ if (Guard.isHasNoMembersObject(data)) return true;
+ if (!Guard.isObjectSchema(data)) return false;
+ if (data.nullable) return false;
+ if (data.additionalProperties && typeof data.additionalProperties === "object") {
+ const hasOptionalProp = Object.keys(data.properties || {}).some(key => !(data.required || []).includes(key));
+ if (hasOptionalProp) return false;
+ }
+ return true;
+ })();
+ if (isInterfaceEquivalent) {
+ let members: string[] = [];
+ if (
+ typeof data !== "boolean" &&
+ !Guard.isReference(data) &&
+ Guard.isObjectSchema(data) &&
+ !Guard.isHasNoMembersObject(data) &&
+ data.additionalProperties !== true
+ ) {
+ const objData = data as ObjectSchema;
+ const propertySignatures = Schema.generatePropertySignatures(
+ entryPoint,
+ reference.referencePoint,
+ factory,
+ objData,
+ context,
+ converterContext,
+ );
+ if (Guard.isObjectSchemaWithAdditionalProperties(objData)) {
+ const additionalProperties = ToTypeNode.convertAdditionalProperties(
+ entryPoint,
+ reference.referencePoint,
+ factory,
+ objData,
+ context,
+ converterContext,
+ );
+ members = [...propertySignatures, additionalProperties];
+ } else {
+ members = propertySignatures;
+ }
+ }
store.addStatement(reference.path, {
kind: "interface",
name: reference.name,
- value: factory.InterfaceDeclaration.create({
- export: true,
- name: reference.name,
- members: typeNode.members,
- }),
+ value: factory.InterfaceDeclaration.create({ export: true, name: reference.name, members }),
});
} else {
+ const typeStr = ToTypeNode.convert(entryPoint, reference.referencePoint, factory, data, context, converterContext);
const value = factory.TypeAliasDeclaration.create({
export: true,
name: converterContext.escapeDeclarationText(reference.name),
- type: ToTypeNode.convert(
- entryPoint,
- reference.referencePoint,
- factory,
- reference.data,
- {
- rootSchema,
- setReferenceHandler,
- resolveReferencePath,
- findSchemaByPathArray,
- },
- converterContext,
- ),
- });
- store.addStatement(reference.path, {
- name: reference.name,
- kind: "typeAlias",
- value,
+ type: typeStr,
});
+ store.addStatement(reference.path, { name: reference.name, kind: "typeAlias", value });
}
} else if (reference.type === "local") {
if (!store.isAfterDefined(reference.path)) {
diff --git a/src/internal/OpenApiTools/Walker/State.ts b/src/internal/OpenApiTools/Walker/State.ts
index b1d7d31c..77603bca 100644
--- a/src/internal/OpenApiTools/Walker/State.ts
+++ b/src/internal/OpenApiTools/Walker/State.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
export interface OperationState {
@@ -11,7 +9,7 @@ export interface OperationState {
export interface Type {
document: OpenApi.Document;
- additionalStatements: ts.Statement[];
+ additionalStatements: string[];
operations: {
[operationId: string]: OperationState;
};
diff --git a/src/internal/OpenApiTools/Walker/Store.ts b/src/internal/OpenApiTools/Walker/Store.ts
index 38b3c9f2..723a081b 100644
--- a/src/internal/OpenApiTools/Walker/Store.ts
+++ b/src/internal/OpenApiTools/Walker/Store.ts
@@ -1,7 +1,6 @@
import * as Path from "node:path";
import { Tree } from "@himenon/path-oriented-data-structure";
import * as DotProp from "dot-prop";
-import type ts from "typescript";
import type { OpenApi } from "../../../types";
import { UnSupportError } from "../../Exception";
@@ -33,8 +32,8 @@ class Store {
this.getChildByPaths = getChildByPaths;
}
- public convertNamespace(tree: Tree | Structure.NamespaceTree.Item): ts.Statement {
- const statements: ts.Statement[] = [];
+ public convertNamespace(tree: Tree | Structure.NamespaceTree.Item): string {
+ const statements: string[] = [];
Object.values(tree.getChildren()).map(child => {
if (child instanceof Tree || child instanceof Structure.NamespaceTree.Item) {
statements.push(this.convertNamespace(child));
@@ -62,10 +61,10 @@ class Store {
private capitalizeFirstLetter(text: string): string {
return text.charAt(0).toUpperCase() + text.slice(1);
}
- public getRootStatements(): ts.Statement[] {
+ public getRootStatements(): string[] {
// Debug Point: 抽象的なデータ構造全体を把握するために出力すると良い
// fs.writeFileSync("debug/tree.json", JSON.stringify(this.operator.getHierarchy(), null, 2), { encoding: "utf-8" });
- const statements = Def.componentNames.reduce((statements, componentName) => {
+ const statements = Def.componentNames.reduce((statements, componentName) => {
const treeOfNamespace = this.getChildByPaths(componentName, "namespace");
if (treeOfNamespace) {
treeOfNamespace.name = this.capitalizeFirstLetter(treeOfNamespace.name);
@@ -75,7 +74,7 @@ class Store {
}, []);
return statements;
}
- public getAdditionalStatements(): ts.Statement[] {
+ public getAdditionalStatements(): string[] {
return this.state.additionalStatements;
}
/**
@@ -131,7 +130,7 @@ class Store {
}
this.state.operations[operationId] = operationState;
}
- public addAdditionalStatement(statements: ts.Statement[]) {
+ public addAdditionalStatement(statements: string[]) {
this.state.additionalStatements = this.state.additionalStatements.concat(statements);
}
public getPathItem(localPath: string): OpenApi.PathItem {
diff --git a/src/internal/OpenApiTools/Walker/structure/InterfaceNode.ts b/src/internal/OpenApiTools/Walker/structure/InterfaceNode.ts
index 1c861056..90913d65 100644
--- a/src/internal/OpenApiTools/Walker/structure/InterfaceNode.ts
+++ b/src/internal/OpenApiTools/Walker/structure/InterfaceNode.ts
@@ -1,15 +1,14 @@
import { Node as BaseNode } from "@himenon/path-oriented-data-structure";
-import type ts from "typescript";
export type Kind = "interface";
export interface Params {
name: string;
- value: ts.InterfaceDeclaration;
+ value: string;
}
export class Item extends BaseNode {
- public value: ts.InterfaceDeclaration;
+ public value: string;
constructor(params: Params) {
super("interface", params.name);
this.value = params.value;
diff --git a/src/internal/OpenApiTools/Walker/structure/TypeAliasNode.ts b/src/internal/OpenApiTools/Walker/structure/TypeAliasNode.ts
index 587d57b2..c34d013a 100644
--- a/src/internal/OpenApiTools/Walker/structure/TypeAliasNode.ts
+++ b/src/internal/OpenApiTools/Walker/structure/TypeAliasNode.ts
@@ -1,15 +1,14 @@
import { Node as BaseNode } from "@himenon/path-oriented-data-structure";
-import type ts from "typescript";
export type Kind = "typeAlias";
export interface Params {
name: string;
- value: ts.TypeAliasDeclaration;
+ value: string;
}
export class Item extends BaseNode {
- public value: ts.TypeAliasDeclaration;
+ public value: string;
constructor(params: Params) {
super("typeAlias", params.name);
this.value = params.value;
diff --git a/src/internal/OpenApiTools/__tests__/TypeNodeContext.test.ts b/src/internal/OpenApiTools/__tests__/TypeNodeContext.test.ts
new file mode 100644
index 00000000..504dda68
--- /dev/null
+++ b/src/internal/OpenApiTools/__tests__/TypeNodeContext.test.ts
@@ -0,0 +1,123 @@
+import { describe, expect, it, vi } from "vitest";
+import * as TypeNodeContext from "../TypeNodeContext";
+
+describe("TypeNodeContext", () => {
+ describe("generatePath", () => {
+ it("同じディレクトリ内のファイル参照において正しいパス配列を生成できること", () => {
+ const entryPoint = "src/api/openapi.yml";
+ const currentPoint = "src/api/components/schemas/User.yml";
+ // referencePath はエントリポイント(src/api/openapi.yml)からの相対パス(拡張子なし)
+ const referencePath = "components/schemas/Common";
+
+ const result = TypeNodeContext.generatePath(entryPoint, currentPoint, referencePath);
+
+ // from = components/schemas/User
+ // base = components/schemas
+ expect(result.base).toBe("components/schemas");
+ // components/schemas から components/schemas/Common への相対パスは "Common"
+ expect(result.pathArray).toEqual(["Common"]);
+ });
+
+ it("親ディレクトリのファイル参照において正しいパス配列を生成できること", () => {
+ const entryPoint = "openapi.yml";
+ const currentPoint = "components/schemas/User.yml";
+ const referencePath = "components/Common";
+
+ const result = TypeNodeContext.generatePath(entryPoint, currentPoint, referencePath);
+
+ expect(result.base).toBe("components/schemas");
+ // components/schemas から components/Common への相対パスは "../Common"
+ expect(result.pathArray).toEqual(["..", "Common"]);
+ });
+
+ it("パスにバックスラッシュが含まれる場合でも POSIX スタイルとして正しく処理されること", () => {
+ // Windows スタイルの入力をシミュレートするが、内部で POSIX 変換されることを期待
+ const entryPoint = "api/openapi.yml";
+ const currentPoint = "api/components/schemas/User.yml";
+ const referencePath = "components/schemas/Common";
+
+ const result = TypeNodeContext.generatePath(entryPoint, currentPoint, referencePath);
+
+ expect(result.base).toBe("components/schemas");
+ expect(result.pathArray).toEqual(["Common"]);
+ });
+ });
+
+ describe("calculateReferencePath", () => {
+ const mockConverterContext = {
+ escapeDeclarationText: (text: string) => text,
+ } as any;
+
+ it("ストアに登録されたインターフェースを解決できること", () => {
+ const mockStore = {
+ getStatement: vi.fn().mockImplementation((path, kind) => {
+ if (path === "components/schemas/User" && kind === "interface") {
+ return { name: "User" };
+ }
+ return undefined;
+ }),
+ } as any;
+
+ const base = "components/schemas";
+ const pathArray = ["User"];
+ const result = TypeNodeContext.calculateReferencePath(mockStore, base, pathArray, mockConverterContext);
+
+ expect(result.name).toBe("User");
+ expect(result.maybeResolvedName).toBe("User");
+ expect(result.unresolvedPaths).toEqual([]);
+ expect(result.depth).toBe(1);
+ });
+
+ it("名前空間を経由して型を解決できること", () => {
+ const mockStore = {
+ getStatement: vi.fn().mockImplementation((path, kind) => {
+ if (path === "components/schemas" && kind === "namespace") {
+ return { name: "Schemas" };
+ }
+ if (path === "components/schemas/User" && kind === "interface") {
+ return { name: "User" };
+ }
+ return undefined;
+ }),
+ } as any;
+
+ const base = "components";
+ const pathArray = ["schemas", "User"];
+ const result = TypeNodeContext.calculateReferencePath(mockStore, base, pathArray, mockConverterContext);
+
+ expect(result.name).toBe("Schemas.User");
+ expect(result.maybeResolvedName).toBe("Schemas.User");
+ expect(result.depth).toBe(2);
+ });
+
+ it("未解決のパスがある場合に maybeResolvedName に含まれること", () => {
+ const mockStore = {
+ getStatement: vi.fn().mockImplementation((path, kind) => {
+ if (path === "components/schemas" && kind === "namespace") {
+ return { name: "Schemas" };
+ }
+ // User は見つからない
+ return undefined;
+ }),
+ } as any;
+
+ const base = "components";
+ const pathArray = ["schemas", "User"];
+ const result = TypeNodeContext.calculateReferencePath(mockStore, base, pathArray, mockConverterContext);
+
+ expect(result.name).toBe("Schemas");
+ expect(result.maybeResolvedName).toBe("Schemas.User");
+ expect(result.unresolvedPaths).toEqual(["User"]);
+ });
+
+ it("型が全く見つからない場合にエラーを投げること", () => {
+ const mockStore = {
+ getStatement: vi.fn().mockReturnValue(undefined),
+ } as any;
+
+ expect(() => {
+ TypeNodeContext.calculateReferencePath(mockStore, "base", ["Unknown"], mockConverterContext);
+ }).toThrow("Local Reference Error");
+ });
+ });
+});
diff --git a/src/internal/OpenApiTools/components/Header.ts b/src/internal/OpenApiTools/components/Header.ts
index 9230e933..ef58c953 100644
--- a/src/internal/OpenApiTools/components/Header.ts
+++ b/src/internal/OpenApiTools/components/Header.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import type { Factory } from "../../TsGenerator";
import type * as ConverterContext from "../ConverterContext";
@@ -15,7 +13,7 @@ export const generateTypeNode = (
header: OpenApi.Header,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.TypeAliasDeclaration => {
+): string => {
return factory.TypeAliasDeclaration.create({
export: true,
name: converterContext.escapeDeclarationText(name),
@@ -31,7 +29,7 @@ export const generatePropertySignature = (
header: OpenApi.Header | OpenApi.Reference,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.PropertySignature => {
+): string => {
if (Guard.isReference(header)) {
const reference = Reference.generate(entryPoint, currentPoint, header);
if (reference.type === "local") {
@@ -69,7 +67,7 @@ export const generatePropertySignatures = (
headers: Record,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.PropertySignature[] => {
+): string[] => {
return Object.entries(headers).map(([headerName, header]) => {
return generatePropertySignature(entryPoint, currentPoint, factory, headerName, header, context, converterContext);
});
@@ -83,7 +81,7 @@ export const generateInterface = (
headers: Record,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.InterfaceDeclaration => {
+): string => {
return factory.InterfaceDeclaration.create({
export: true,
name: converterContext.escapeDeclarationText(name),
diff --git a/src/internal/OpenApiTools/components/MediaType.ts b/src/internal/OpenApiTools/components/MediaType.ts
index e5a1d053..5d24d7ed 100644
--- a/src/internal/OpenApiTools/components/MediaType.ts
+++ b/src/internal/OpenApiTools/components/MediaType.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import type { Factory } from "../../TsGenerator";
import type * as ConverterContext from "../ConverterContext";
@@ -13,7 +11,7 @@ export const generatePropertySignature = (
schema: OpenApi.Schema,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.PropertySignature => {
+): string => {
return factory.PropertySignature.create({
readOnly: false,
name: converterContext.escapePropertySignatureName(protocol),
@@ -30,8 +28,8 @@ export const generatePropertySignatures = (
content: Record,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.PropertySignature[] => {
- return Object.entries(content).reduce((previous, [protocol, mediaType]) => {
+): string[] => {
+ return Object.entries(content).reduce((previous, [protocol, mediaType]) => {
if (!mediaType.schema) {
return previous;
}
@@ -47,7 +45,7 @@ export const generateInterface = (
content: Record,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.InterfaceDeclaration => {
+): string => {
return factory.InterfaceDeclaration.create({
export: true,
name,
diff --git a/src/internal/OpenApiTools/components/Operation.ts b/src/internal/OpenApiTools/components/Operation.ts
index 12ee85ab..934aa8d6 100644
--- a/src/internal/OpenApiTools/components/Operation.ts
+++ b/src/internal/OpenApiTools/components/Operation.ts
@@ -1,8 +1,6 @@
import { EOL } from "node:os";
import * as path from "node:path";
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import type { Factory } from "../../TsGenerator";
import type * as ConverterContext from "../ConverterContext";
@@ -132,8 +130,8 @@ export const generateStatements = (
pathItemParameters: OpenApi.PathItem["parameters"],
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.Statement[] => {
- let statements: ts.Statement[] = [];
+): string[] => {
+ let statements: string[] = [];
const operationId = operation.operationId;
if (!operationId) {
throw new Error(`not setting operationId\n${JSON.stringify(operation)}`);
diff --git a/src/internal/OpenApiTools/components/Parameter.ts b/src/internal/OpenApiTools/components/Parameter.ts
index 822ca592..b27c629b 100644
--- a/src/internal/OpenApiTools/components/Parameter.ts
+++ b/src/internal/OpenApiTools/components/Parameter.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import type { Factory } from "../../TsGenerator";
import type * as ConverterContext from "../ConverterContext";
@@ -15,7 +13,7 @@ export const generateTypeNode = (
parameter: OpenApi.Parameter,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.TypeNode => {
+): string => {
return ToTypeNode.convert(entryPoint, currentPoint, factory, parameter.schema || { type: "null" }, context, converterContext);
};
@@ -27,7 +25,7 @@ export const generateTypeAlias = (
parameter: OpenApi.Parameter,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.TypeAliasDeclaration => {
+): string => {
return factory.TypeAliasDeclaration.create({
export: true,
name: converterContext.escapeDeclarationText(name),
@@ -44,7 +42,7 @@ export const generatePropertySignatureObject = (
parameter: OpenApi.Parameter | OpenApi.Reference,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): { name: string; typeElement: ts.PropertySignature } => {
+): { name: string; typeElement: string } => {
if (Guard.isReference(parameter)) {
const reference = Reference.generate(entryPoint, currentPoint, parameter);
if (reference.type === "local") {
@@ -110,8 +108,8 @@ export const generatePropertySignatures = (
parameters: (OpenApi.Parameter | OpenApi.Reference)[],
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.PropertySignature[] => {
- const typeElementMap = parameters.reduce>((all, parameter) => {
+): string[] => {
+ const typeElementMap = parameters.reduce>((all, parameter) => {
const { name, typeElement } = generatePropertySignatureObject(
entryPoint,
currentPoint,
@@ -135,7 +133,7 @@ export const generateInterface = (
parameters: (OpenApi.Parameter | OpenApi.Reference)[],
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.InterfaceDeclaration => {
+): string => {
return factory.InterfaceDeclaration.create({
export: true,
name,
@@ -155,7 +153,7 @@ export const generateAliasInterface = (
parameters: (OpenApi.Parameter | OpenApi.Reference)[],
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.InterfaceDeclaration => {
+): string => {
return factory.InterfaceDeclaration.create({
export: true,
name: converterContext.escapeDeclarationText(name),
diff --git a/src/internal/OpenApiTools/components/PathItem.ts b/src/internal/OpenApiTools/components/PathItem.ts
index 3d7c621b..f55ee0ab 100644
--- a/src/internal/OpenApiTools/components/PathItem.ts
+++ b/src/internal/OpenApiTools/components/PathItem.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import type { Factory } from "../../TsGenerator";
import type * as ConverterContext from "../ConverterContext";
@@ -154,8 +152,8 @@ export const generateStatements = (
pathItem: OpenApi.PathItem,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.Statement[] => {
- const statements: ts.Statement[][] = [];
+): string[] => {
+ const statements: string[][] = [];
if (pathItem.get) {
statements.push(
Operation.generateStatements(
@@ -284,10 +282,6 @@ export const generateStatements = (
),
);
}
- // TODO Check usage
- // if (pathItem.parameters) {
- // Parameters.generateNamespaceWithList(entryPoint, currentPoint, store, factory, pathItem.parameters, context);
- // }
return statements.flat();
};
diff --git a/src/internal/OpenApiTools/components/RequestBody.ts b/src/internal/OpenApiTools/components/RequestBody.ts
index f187089e..82bb980d 100644
--- a/src/internal/OpenApiTools/components/RequestBody.ts
+++ b/src/internal/OpenApiTools/components/RequestBody.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import type { Factory } from "../../TsGenerator";
import type * as ConverterContext from "../ConverterContext";
@@ -15,7 +13,7 @@ export const generateInterface = (
requestBody: OpenApi.RequestBody,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.InterfaceDeclaration => {
+): string => {
/**
* requestBody:
* content:
diff --git a/src/internal/OpenApiTools/components/Responses.ts b/src/internal/OpenApiTools/components/Responses.ts
index a4a78632..a9f877f5 100644
--- a/src/internal/OpenApiTools/components/Responses.ts
+++ b/src/internal/OpenApiTools/components/Responses.ts
@@ -1,7 +1,5 @@
import * as path from "node:path";
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import { UndefinedComponent } from "../../Exception";
import type { Factory } from "../../TsGenerator";
@@ -128,8 +126,8 @@ export const generateInterfacesWithStatusCode = (
responses: OpenApi.Responses,
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
-): ts.Statement[] => {
- const statements: ts.Statement[] = [];
+): string[] => {
+ const statements: string[] = [];
Object.entries(responses).forEach(([statusCode, response]) => {
if (!response) {
return;
diff --git a/src/internal/OpenApiTools/components/Schema.ts b/src/internal/OpenApiTools/components/Schema.ts
index 3480ffcb..f8c522ac 100644
--- a/src/internal/OpenApiTools/components/Schema.ts
+++ b/src/internal/OpenApiTools/components/Schema.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import { FeatureDevelopmentError } from "../../Exception";
import type { Factory } from "../../TsGenerator";
@@ -10,8 +8,8 @@ import type { AnySchema, ArraySchema, ObjectSchema, PrimitiveSchema } from "../t
import type * as Walker from "../Walker";
import * as ExternalDocumentation from "./ExternalDocumentation";
-const nullable = (factory: Factory.Type, typeNode: ts.TypeNode, nullable: boolean): ts.TypeNode => {
- if (nullable) {
+const nullable = (factory: Factory.Type, typeNode: string, isNullable: boolean): string => {
+ if (isNullable) {
return factory.UnionTypeNode.create({
typeNodes: [
typeNode,
@@ -31,7 +29,7 @@ export const generatePropertySignatures = (
schema: ObjectSchema,
context: ToTypeNode.Context,
convertContext: ConvertContext.Types,
-): ts.PropertySignature[] => {
+): string[] => {
if (!schema.properties) {
return [];
}
@@ -66,11 +64,11 @@ export const generateTypeAliasDeclarationForObject = (
schema: ObjectSchema,
context: ToTypeNode.Context,
convertContext: ConvertContext.Types,
-): ts.TypeAliasDeclaration => {
+): string => {
if (schema.type !== "object") {
throw new FeatureDevelopmentError("Please use generateTypeAlias");
}
- let members: ts.TypeElement[] = [];
+ let members: string[] = [];
const propertySignatures = generatePropertySignatures(entryPoint, currentPoint, factory, schema, context, convertContext);
if (Guard.isObjectSchemaWithAdditionalProperties(schema)) {
const additionalProperties = ToTypeNode.convertAdditionalProperties(entryPoint, currentPoint, factory, schema, context, convertContext);
@@ -101,11 +99,11 @@ export const generateInterface = (
schema: ObjectSchema,
context: ToTypeNode.Context,
convertContext: ConvertContext.Types,
-): ts.InterfaceDeclaration => {
+): string => {
if (schema.type !== "object") {
throw new FeatureDevelopmentError("Please use generateTypeAlias");
}
- let members: ts.TypeElement[] = [];
+ let members: string[] = [];
const propertySignatures = generatePropertySignatures(entryPoint, currentPoint, factory, schema, context, convertContext);
if (Guard.isObjectSchemaWithAdditionalProperties(schema)) {
const additionalProperties = ToTypeNode.convertAdditionalProperties(entryPoint, currentPoint, factory, schema, context, convertContext);
@@ -133,7 +131,7 @@ export const generateArrayTypeAlias = (
schema: ArraySchema,
context: ToTypeNode.Context,
convertContext: ConvertContext.Types,
-): ts.TypeAliasDeclaration => {
+): string => {
return factory.TypeAliasDeclaration.create({
export: true,
name: convertContext.escapeDeclarationText(name),
@@ -142,7 +140,7 @@ export const generateArrayTypeAlias = (
});
};
-const createNullableTypeNodeOrAny = (factory: Factory.Type, schema: OpenApi.Schema) => {
+const createNullableTypeNodeOrAny = (factory: Factory.Type, schema: OpenApi.Schema): string => {
const typeNode = factory.TypeNode.create({
type: "any",
});
@@ -164,7 +162,7 @@ export const generateNotInferedTypeAlias = (
name: string,
schema: OpenApi.Schema,
convertContext: ConvertContext.Types,
-) => {
+): string => {
const typeNode = createNullableTypeNodeOrAny(factory, schema);
return factory.TypeAliasDeclaration.create({
export: true,
@@ -181,14 +179,14 @@ export const generateTypeAlias = (
name: string,
schema: PrimitiveSchema | AnySchema,
convertContext: ConvertContext.Types,
-): ts.TypeAliasDeclaration => {
- let type: ts.TypeNode;
- let formatTypeNode: ts.TypeNode | undefined;
+): string => {
+ let type: string;
+ let formatTypeNode: string | undefined;
if (schema.format && schema.type !== "any") {
formatTypeNode = convertContext.convertFormatTypeNode(schema);
}
if (formatTypeNode) {
- type = formatTypeNode;
+ type = schema.nullable === true ? `(${formatTypeNode})` : formatTypeNode;
} else if (schema.enum) {
if (Guard.isNumberArray(schema.enum) && (schema.type === "number" || schema.type === "integer")) {
type = factory.TypeNode.create({
@@ -232,7 +230,7 @@ export const generateMultiTypeAlias = (
context: ToTypeNode.Context,
multiType: "oneOf" | "allOf" | "anyOf",
convertContext: ConvertContext.Types,
-): ts.TypeAliasDeclaration => {
+): string => {
const type = ToTypeNode.generateMultiTypeNode(
entryPoint,
currentPoint,
diff --git a/src/internal/OpenApiTools/components/SecuritySchema.ts b/src/internal/OpenApiTools/components/SecuritySchema.ts
index 4ca37c39..79e9534e 100644
--- a/src/internal/OpenApiTools/components/SecuritySchema.ts
+++ b/src/internal/OpenApiTools/components/SecuritySchema.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import type { Factory } from "../../TsGenerator";
@@ -8,8 +6,8 @@ export const generatePropertySignatures = (
_currentPoint: string,
factory: Factory.Type,
securitySchema: OpenApi.SecuritySchema,
-): ts.PropertySignature[] => {
- const signatures: ts.PropertySignature[] = [
+): string[] => {
+ return [
factory.PropertySignature.create({
readOnly: false,
name: "type",
@@ -35,8 +33,6 @@ export const generatePropertySignatures = (
type: factory.LiteralTypeNode.create({ value: securitySchema.openIdConnectUrl }),
}),
];
-
- return signatures;
};
export const generateInterface = (
@@ -45,7 +41,7 @@ export const generateInterface = (
factory: Factory.Type,
name: string,
securitySchema: OpenApi.SecuritySchema,
-): ts.InterfaceDeclaration => {
+): string => {
return factory.InterfaceDeclaration.create({
export: true,
name,
diff --git a/src/internal/OpenApiTools/paths/index.ts b/src/internal/OpenApiTools/paths/index.ts
index 076a0793..c5381190 100644
--- a/src/internal/OpenApiTools/paths/index.ts
+++ b/src/internal/OpenApiTools/paths/index.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../../types";
import type { Factory } from "../../TsGenerator";
import type * as ConverterContext from "../ConverterContext";
@@ -18,7 +16,7 @@ export const generateStatements = (
context: ToTypeNode.Context,
converterContext: ConverterContext.Types,
): void => {
- const statements: ts.Statement[][] = [];
+ const statements: string[][] = [];
for (const [requestUri, pathItem] of Object.entries(paths)) {
if (!requestUri.startsWith("/")) {
throw new Error(`Not start slash: ${requestUri}`);
diff --git a/src/internal/OpenApiTools/toTypeNode.ts b/src/internal/OpenApiTools/toTypeNode.ts
index f87fc147..9c1d4b57 100644
--- a/src/internal/OpenApiTools/toTypeNode.ts
+++ b/src/internal/OpenApiTools/toTypeNode.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type { OpenApi } from "../../types";
import { UnSupportError } from "../Exception";
import * as Logger from "../Logger";
@@ -39,12 +37,34 @@ export type Convert = (
setReference: Context,
convertContext: ConverterContext.Types,
option?: Option,
-) => ts.TypeNode;
+) => string;
export interface Option {
parent?: any;
}
+const isSingleElementUnionOrIntersection = (schema: OpenApi.JSONSchema | OpenApi.Reference): boolean => {
+ if (typeof schema === "boolean" || Guard.isReference(schema)) return false;
+ const s = schema as OpenApi.Schema;
+ if (Guard.isOneOfSchema(s)) return s.oneOf.length === 1;
+ if (Guard.isAllOfSchema(s)) return s.allOf.length === 1;
+ if (Guard.isAnyOfSchema(s)) return s.anyOf.length === 1;
+ if (s.enum && s.enum.length === 1) {
+ const effectiveType = s.type ?? "string";
+ if (effectiveType === "string" && Guard.isStringArray(s.enum)) return true;
+ if ((effectiveType === "number" || effectiveType === "integer") && Guard.isNumberArray(s.enum)) return true;
+ if (effectiveType === "boolean" && Guard.isBooleanArray(s.enum)) return true;
+ }
+ return false;
+};
+
+const wrapIfNeeded = (converted: string, schema: OpenApi.JSONSchema | OpenApi.Reference): string => {
+ if (isSingleElementUnionOrIntersection(schema) && !converted.startsWith("(")) {
+ return `(${converted})`;
+ }
+ return converted;
+};
+
export const generateMultiTypeNode = (
entryPoint: string,
currentPoint: string,
@@ -54,8 +74,10 @@ export const generateMultiTypeNode = (
convert: Convert,
convertContext: ConverterContext.Types,
multiType: "oneOf" | "allOf" | "anyOf",
-): ts.TypeNode => {
- const typeNodes = schemas.map(schema => convert(entryPoint, currentPoint, factory, schema, setReference, convertContext));
+): string => {
+ const typeNodes = schemas.map(schema =>
+ wrapIfNeeded(convert(entryPoint, currentPoint, factory, schema, setReference, convertContext), schema),
+ );
if (multiType === "oneOf") {
return factory.UnionTypeNode.create({
typeNodes,
@@ -74,8 +96,8 @@ export const generateMultiTypeNode = (
});
};
-const nullable = (factory: Factory.Type, typeNode: ts.TypeNode, nullable: boolean): ts.TypeNode => {
- if (nullable) {
+const nullable = (factory: Factory.Type, typeNode: string, isNullable: boolean): string => {
+ if (isNullable) {
return factory.UnionTypeNode.create({
typeNodes: [
typeNode,
@@ -96,7 +118,7 @@ export const convert: Convert = (
context: Context,
converterContext: ConverterContext.Types,
option?: Option,
-): ts.TypeNode => {
+): string => {
if (typeof schema === "boolean") {
// https://swagger.io/docs/specification/data-models/dictionaries/#free-form
return factory.TypeNode.create({
@@ -178,17 +200,14 @@ export const convert: Convert = (
].join("\n");
Logger.info(message);
}
- const typeNode = factory.TypeNode.create({
+ return factory.TypeNode.create({
type: "any",
});
- return typeNode;
- // Logger.showFilePosition(entryPoint, currentPoint);
- // throw new UnsetTypeError("Please set 'type' or '$ref' property \n" + JSON.stringify(schema));
}
switch (schema.type) {
case "boolean": {
const items = schema.enum;
- let typeNode: ts.TypeNode;
+ let typeNode: string;
if (items && Guard.isBooleanArray(items)) {
typeNode = factory.TypeNode.create({
type: schema.type,
@@ -209,7 +228,7 @@ export const convert: Convert = (
case "integer":
case "number": {
const items = schema.enum;
- let typeNode: ts.TypeNode;
+ let typeNode: string;
const formatTypeNode = converterContext.convertFormatTypeNode(schema);
if (formatTypeNode) {
return formatTypeNode;
@@ -232,7 +251,7 @@ export const convert: Convert = (
if (formatTypeNode) {
return formatTypeNode;
}
- let typeNode: ts.TypeNode;
+ let typeNode: string;
if (items && Guard.isStringArray(items)) {
typeNode = factory.TypeNode.create({
type: schema.type,
@@ -249,14 +268,22 @@ export const convert: Convert = (
if (Array.isArray(schema.items) || typeof schema.items === "boolean") {
throw new UnSupportError(`schema.items = ${JSON.stringify(schema.items)}`);
}
- const typeNode = factory.TypeNode.create({
- type: schema.type,
- value: schema.items
- ? convert(entryPoint, currentPoint, factory, schema.items, context, converterContext, { parent: schema })
- : factory.TypeNode.create({
- type: "undefined",
- }),
- });
+ let itemValue: string;
+ if (schema.items) {
+ const itemsSchema = schema.items as OpenApi.Schema;
+ const itemFormatType = converterContext.convertFormatTypeNode(itemsSchema);
+ if (itemFormatType) {
+ itemValue = `(${itemFormatType})`;
+ } else {
+ itemValue = wrapIfNeeded(
+ convert(entryPoint, currentPoint, factory, schema.items, context, converterContext, { parent: schema }),
+ schema.items as OpenApi.Schema,
+ );
+ }
+ } else {
+ itemValue = factory.TypeNode.create({ type: "undefined" });
+ }
+ const typeNode = factory.TypeNode.create({ type: schema.type, value: itemValue });
return nullable(factory, typeNode, !!schema.nullable);
}
case "object": {
@@ -269,7 +296,7 @@ export const convert: Convert = (
});
}
- const value: ts.PropertySignature[] = Object.entries(schema.properties || {}).map(([name, jsonSchema]) => {
+ const value: string[] = Object.entries(schema.properties || {}).map(([name, jsonSchema]) => {
return factory.PropertySignature.create({
readOnly: typeof jsonSchema !== "boolean" ? !!jsonSchema.readOnly : false,
name: converterContext.escapePropertySignatureName(name),
@@ -315,7 +342,6 @@ export const convert: Convert = (
return factory.TypeNode.create({
type: "any",
});
- // throw new UnknownError("what is this? \n" + JSON.stringify(schema, null, 2));
}
};
@@ -326,7 +352,7 @@ export const convertAdditionalProperties = (
schema: ObjectSchemaWithAdditionalProperties,
setReference: Context,
convertContext: ConverterContext.Types,
-): ts.IndexSignatureDeclaration => {
+): string => {
// // https://swagger.io/docs/specification/data-models/dictionaries/#free-form
if (schema.additionalProperties === true) {
factory.TypeNode.create({
@@ -334,11 +360,10 @@ export const convertAdditionalProperties = (
value: [],
});
}
- const additionalProperties = factory.IndexSignatureDeclaration.create({
+ return factory.IndexSignatureDeclaration.create({
name: "key",
type: convert(entryPoint, currentPoint, factory, schema.additionalProperties, setReference, convertContext, {
parent: schema.properties,
}),
});
- return additionalProperties;
};
diff --git a/src/internal/TsGenerator/__tests__/factory.test.ts b/src/internal/TsGenerator/__tests__/factory.test.ts
new file mode 100644
index 00000000..f668fbe6
--- /dev/null
+++ b/src/internal/TsGenerator/__tests__/factory.test.ts
@@ -0,0 +1,167 @@
+import { EOL } from "node:os";
+import { describe, expect, it } from "vitest";
+import * as Factory from "../factory";
+
+describe("TsGenerator Factory Helpers", () => {
+ describe("escapeTemplateText", () => {
+ it("テンプレートリテラル内の特殊文字をエスケープできること", () => {
+ // バックスラッシュ、バッククォート、${ をエスケープする
+ expect(Factory.escapeTemplateText("path\\to\\file")).toBe("path\\\\to\\\\file");
+ expect(Factory.escapeTemplateText("`quoted`")).toBe("\\`quoted\\`");
+ expect(Factory.escapeTemplateText("${variable}")).toBe("\\${variable}");
+ });
+ });
+
+ describe("escapeIdentifier", () => {
+ it("識別子に含まれるハイフンをアンダースコアに置換できること", () => {
+ expect(Factory.escapeIdentifier("my-variable-name")).toBe("my_variable_name");
+ expect(Factory.escapeIdentifier("nochange")).toBe("nochange");
+ });
+ });
+
+ describe("indentLines", () => {
+ it("各行にインデントを付与し、空行はそのままにすること", () => {
+ const input = "line1\n\nline2";
+ const expected = " line1\n\n line2";
+ expect(Factory.indentLines(input, " ")).toBe(expected);
+ });
+ });
+
+ describe("hasTopLevelOp", () => {
+ it("トップレベルに | または & がある場合は true を返すこと", () => {
+ expect(Factory.hasTopLevelOp("A | B")).toBe(true);
+ expect(Factory.hasTopLevelOp("A & B")).toBe(true);
+ });
+
+ it("括弧や型引数の中にある演算子は無視されること", () => {
+ expect(Factory.hasTopLevelOp("(A | B)")).toBe(false);
+ expect(Factory.hasTopLevelOp("Array")).toBe(false);
+ expect(Factory.hasTopLevelOp("{ prop: A | B }")).toBe(false);
+ expect(Factory.hasTopLevelOp("[A | B]")).toBe(false);
+ });
+
+ it("ネストが深い場合の演算子も正しく無視されること", () => {
+ expect(Factory.hasTopLevelOp("A | Array<{ p: B & C }>")).toBe(true);
+ expect(Factory.hasTopLevelOp("Array<{ p: B & C }> | D")).toBe(true);
+ expect(Factory.hasTopLevelOp("Map")).toBe(false);
+ });
+ });
+
+ describe("buildComment", () => {
+ it("単一ラインのコメントを生成できること", () => {
+ expect(Factory.buildComment("hello")).toBe(`/** hello */${EOL}`);
+ });
+
+ it("複数ラインのコメントを生成できること", () => {
+ const input = "line1\nline2";
+ const expected = `/**${EOL} * line1${EOL} * line2${EOL} */${EOL}`;
+ expect(Factory.buildComment(input)).toBe(expected);
+ });
+
+ it("deprecated フラグがある場合に @deprecated タグを付与すること", () => {
+ const expected = `/**${EOL} * @deprecated${EOL} * old feature${EOL} */${EOL}`;
+ expect(Factory.buildComment("old feature", true)).toBe(expected);
+ });
+
+ it("コメント内の特殊な記号をエスケープすること", () => {
+ expect(Factory.buildComment("*/")).toContain("\\*\\\\/");
+ expect(Factory.buildComment("/*")).toContain("/\\\\*");
+ });
+ });
+
+ describe("addComment", () => {
+ it("コメントがある場合にコードの前に付与すること", () => {
+ const code = "const a = 1;";
+ const comment = "my variable";
+ const result = Factory.addComment(code, comment);
+ expect(result).toBe(`/** my variable */${EOL}${code}`);
+ });
+
+ it("コメントも deprecated もない場合は元のコードを返すこと", () => {
+ const code = "const a = 1;";
+ expect(Factory.addComment(code)).toBe(code);
+ });
+ });
+});
+
+describe("TsGenerator Factory Create API", () => {
+ const factory = Factory.create();
+
+ describe("StringLiteral", () => {
+ it("文字列リテラルを生成できること(ダブルクォート)", () => {
+ expect(factory.StringLiteral.create({ text: 'hello "world"' })).toBe('"hello \\"world\\""');
+ });
+
+ it("文字列リテラルを生成できること(シングルクォート)", () => {
+ expect(factory.StringLiteral.create({ text: "hello 'world'", isSingleQuote: true })).toBe("'hello \\'world\\''");
+ });
+ });
+
+ describe("TypeNode", () => {
+ it("プリミティブ型を生成できること", () => {
+ expect(factory.TypeNode.create({ type: "string" })).toBe("string");
+ expect(factory.TypeNode.create({ type: "number" })).toBe("number");
+ expect(factory.TypeNode.create({ type: "boolean" })).toBe("boolean");
+ });
+
+ it("enum 文字列型を生成できること", () => {
+ expect(factory.TypeNode.create({ type: "string", enum: ["a", "b"] })).toBe('"a" | "b"');
+ });
+
+ it("配列型を生成できること", () => {
+ expect(factory.TypeNode.create({ type: "array", value: "string" })).toBe("string[]");
+ });
+
+ it("トップレベル演算子を含む型の配列は括弧で囲まれること", () => {
+ expect(factory.TypeNode.create({ type: "array", value: "string | number" })).toBe("(string | number)[]");
+ });
+
+ it("オブジェクト型(インライン)を生成できること", () => {
+ const result = factory.TypeNode.create({ type: "object", value: ["id: string;", "name: string;"] });
+ expect(result).toBe("{\n id: string;\n name: string;\n}");
+ });
+ });
+
+ describe("UnionTypeNode", () => {
+ it("ユニオン型を生成できること", () => {
+ expect(factory.UnionTypeNode.create({ typeNodes: ["string", "number"] })).toBe("string | number");
+ });
+
+ it("ネストした演算子を持つ型は括弧で囲まれること", () => {
+ expect(factory.UnionTypeNode.create({ typeNodes: ["A & B", "C"] })).toBe("(A & B) | C");
+ });
+ });
+
+ describe("InterfaceDeclaration", () => {
+ it("インターフェース宣言を生成できること", () => {
+ const result = factory.InterfaceDeclaration.create({
+ name: "MyInterface",
+ members: ["id: string;", "name?: string;"],
+ export: true,
+ });
+ expect(result).toBe("export interface MyInterface {\n id: string;\n name?: string;\n}");
+ });
+ });
+
+ describe("Namespace", () => {
+ it("名前空間を生成できること", () => {
+ const result = factory.Namespace.create({
+ name: "MyNamespace",
+ statements: ["export type T = string;"],
+ export: true,
+ });
+ expect(result).toBe("export namespace MyNamespace {\n export type T = string;\n}");
+ });
+
+ it("ネストした名前空間を一括生成できること", () => {
+ const result = factory.Namespace.createMultiple({
+ names: ["A", "B", "C"],
+ statements: ["export const v = 1;"],
+ export: true,
+ });
+ expect(result).toContain("namespace A");
+ expect(result).toContain("namespace B");
+ expect(result).toContain("namespace C");
+ });
+ });
+});
diff --git a/src/internal/TsGenerator/factory.ts b/src/internal/TsGenerator/factory.ts
new file mode 100644
index 00000000..47d112de
--- /dev/null
+++ b/src/internal/TsGenerator/factory.ts
@@ -0,0 +1,697 @@
+import { EOL } from "node:os";
+
+// --- Private helpers ---
+
+/**
+ * テンプレートリテラル内の特殊文字(\, `, ${)をエスケープします。
+ *
+ * @param text - エスケープ対象の文字列
+ * @returns エスケープ済みの文字列
+ *
+ * @example
+ * escapeTemplateText("const a = `${val}`") // "const a = \\`${val}\\`"
+ */
+export const escapeTemplateText = (text: string): string => text.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
+
+/**
+ * 識別子として使用できない文字(現在はハイフンのみ)をアンダースコアに置換します。
+ *
+ * @param text - 置換対象の文字列
+ * @returns 置換後の文字列
+ *
+ * @example
+ * escapeIdentifier("my-var") // "my_var"
+ */
+export const escapeIdentifier = (text: string): string => text.replace(/-/g, "_");
+
+/**
+ * 文字列の各行に指定されたインデントを付与します。
+ * 空行にはインデントを付与しません。
+ *
+ * @param s - インデントを付与する文字列
+ * @param indent - 付与するインデント文字列(スペースやタブなど)
+ * @returns インデントが付与された文字列
+ *
+ * @example
+ * indentLines("line1\n\nline2", " ")
+ * // 返り値:
+ * // " line1"
+ * // ""
+ * // " line2"
+ */
+export const indentLines = (s: string, indent: string): string =>
+ s
+ .split("\n")
+ .map(line => (line ? `${indent}${line}` : line))
+ .join("\n");
+
+/**
+ * 文字列のトップレベルに演算子(| または &)が含まれているか判定します。
+ * 括弧、型引数、オブジェクト定義などのネスト内にある演算子は無視されます。
+ *
+ * @param s - 判定対象の型定義文字列
+ * @returns トップレベルに演算子が含まれる場合は true、それ以外は false
+ *
+ * @example
+ * hasTopLevelOp("A | B") // true
+ * hasTopLevelOp("Array") // false
+ * hasTopLevelOp("{ a: A | B }") // false
+ */
+export const hasTopLevelOp = (s: string): boolean => {
+ let depth = 0;
+ for (let i = 0; i < s.length - 2; i++) {
+ const c = s[i];
+ if (c === "{" || c === "<" || c === "(" || c === "[") depth++;
+ else if (c === "}" || c === ">" || c === ")" || c === "]") depth--;
+ else if (depth === 0 && (s[i] === "|" || s[i] === "&") && s[i - 1] === " " && s[i + 1] === " ") return true;
+ }
+ return false;
+};
+
+/**
+ * JSDoc 形式のコメントブロックを生成します。
+ * 複数行のコメントや @deprecated タグにも対応しています。
+ *
+ * @param comment - コメント本文
+ * @param deprecated - @deprecated タグを含めるかどうか
+ * @returns 生成された JSDoc 文字列(末尾に改行を含む)
+ *
+ * @example
+ * buildComment("hello") // "/** hello *\/\n"
+ * buildComment("deprecated message", true)
+ * // 返り値:
+ * // "/**"
+ * // " * @deprecated"
+ * // " * deprecated message"
+ * // " *\/"
+ */
+export const buildComment = (comment: string, deprecated?: boolean): string => {
+ const escaped = comment
+ .replace(/\*\//, "\\*\\\\/")
+ .replace(/\/\*/, "/\\\\*")
+ .replace(/\*\/\*/, "\\*\\/\\*");
+ const lines = deprecated ? ["@deprecated", ...escaped.split(/\r?\n/)] : escaped.split(/\r?\n/);
+ const filtered = lines.filter((line, i) => !(i === lines.length - 1 && line === ""));
+ if (filtered.length === 1) {
+ return `/** ${filtered[0]} */${EOL}`;
+ }
+ return `/**${EOL}${filtered.map(l => (l.trimEnd() ? ` * ${l.trimEnd()}` : " *")).join(EOL)}${EOL} */${EOL}`;
+};
+
+/**
+ * コードに JSDoc コメントを付与します。
+ * コメントも deprecated フラグもない場合は、元のコードをそのまま返します。
+ *
+ * @param code - 元のコード
+ * @param comment - コメント本文
+ * @param deprecated - @deprecated フラグ
+ * @returns コメントが付与されたコード
+ *
+ * @example
+ * addComment("const a = 1;", "My constant")
+ * // 返り値:
+ * // "/** My constant *\/"
+ * // "const a = 1;"
+ */
+export const addComment = (code: string, comment?: string, deprecated?: boolean): string => {
+ if (!comment && !deprecated) return code;
+ return buildComment(comment || "", deprecated) + code;
+};
+
+// --- Factory interface ---
+
+export interface Type {
+ Identifier: {
+ create(p: { name: string }): string;
+ };
+ StringLiteral: {
+ create(p: { text: string; isSingleQuote?: boolean }): string;
+ };
+ RegularExpressionLiteral: {
+ create(p: { text: string }): string;
+ };
+ LiteralTypeNode: {
+ create(p: { value: string | boolean | number; comment?: string }): string;
+ };
+ TypeNode: {
+ create(
+ p:
+ | { type: "string"; enum?: string[] }
+ | { type: "integer" | "number"; enum?: number[] }
+ | { type: "boolean"; enum?: boolean[] }
+ | { type: "object"; value?: string[] }
+ | { type: "array"; value: string }
+ | { type: "null" | "undefined" | "never" | "void" | "any" },
+ ): string;
+ };
+ TypeReferenceNode: {
+ create(p: { name: string; typeArguments?: readonly string[] }): string;
+ };
+ UnionTypeNode: {
+ create(p: { typeNodes: string[] }): string;
+ };
+ IntersectionTypeNode: {
+ create(p: { typeNodes: string[] }): string;
+ };
+ TypeLiteralNode: {
+ create(p: { members: string[] }): string;
+ };
+ IndexedAccessTypeNode: {
+ create(p: { objectType: string; indexType: string }): string;
+ };
+ TypeOperatorNode: {
+ create(p: { syntaxKind: "keyof" | "unique" | "readonly"; type: string }): string;
+ };
+ FunctionTypeNode: {
+ create(p: { typeParameters?: readonly string[]; parameters: readonly string[]; type: string }): string;
+ };
+ TypeParameterDeclaration: {
+ create(p: { name: string; constraint?: string; defaultType?: string }): string;
+ };
+ ParameterDeclaration: {
+ create(p: { name: string; optional?: true; modifiers?: "private" | "public"; type?: string }): string;
+ };
+ PropertySignature: {
+ create(p: { name: string; readOnly: boolean; optional: boolean; type: string; comment?: string }): string;
+ };
+ PropertyDeclaration: {
+ create(p: {
+ modifiers?: readonly string[];
+ name: string;
+ questionOrExclamationToken?: "?" | "!" | undefined;
+ type?: string;
+ initializer?: string;
+ }): string;
+ };
+ IndexSignatureDeclaration: {
+ create(p: { name: string; type: string }): string;
+ };
+ NoSubstitutionTemplateLiteral: {
+ create(p: { text: string; rawText?: string }): string;
+ };
+ TemplateHead: {
+ create(p: { text: string; rawText?: string }): string;
+ };
+ TemplateMiddle: {
+ create(p: { text: string; rawText?: string }): string;
+ };
+ TemplateTail: {
+ create(p: { text: string; rawText?: string }): string;
+ };
+ TemplateSpan: {
+ create(p: { expression: string; literal: string }): string;
+ };
+ TemplateExpression: {
+ create(p: { head: string; templateSpans: string[] }): string;
+ };
+ BinaryExpression: {
+ create(p: { left: string; operator: "+" | "="; right: string }): string;
+ };
+ PropertyAccessExpression: {
+ create(p: { expression: string; name: string }): string;
+ };
+ ElementAccessExpression: {
+ create(p: { expression: string; argumentExpression: string }): string;
+ };
+ CallExpression: {
+ create(p: { expression: string; typeArguments?: readonly string[]; argumentsArray: readonly string[] }): string;
+ };
+ ObjectLiteralExpression: {
+ create(p: { properties: string[]; multiLine?: boolean }): string;
+ };
+ PropertyAssignment: {
+ create(p: { name: string; initializer: string; comment?: string }): string;
+ };
+ ShorthandPropertyAssignment: {
+ create(p: { name: string }): string;
+ };
+ ArrowFunction: {
+ create(p: {
+ typeParameters?: readonly string[];
+ parameters: readonly string[];
+ type?: string;
+ equalsGreaterThanToken?: unknown;
+ body: string;
+ }): string;
+ };
+ ReturnStatement: {
+ create(p: { expression?: string }): string;
+ };
+ ExpressionStatement: {
+ create(p: { expression: string }): string;
+ };
+ Block: {
+ create(p: { statements: string[]; multiLine?: boolean }): string;
+ };
+ VariableDeclaration: {
+ create(p: { name: string; type?: string; initializer?: string }): string;
+ };
+ VariableDeclarationList: {
+ create(p: { declarations: readonly string[]; flag: "const" }): string;
+ };
+ VariableStatement: {
+ create(p: { comment?: string; deprecated?: boolean; modifiers?: readonly string[]; declarationList: string }): string;
+ };
+ TypeAliasDeclaration: {
+ create(p: { export?: true; name: string; type: string; comment?: string; deprecated?: boolean }): string;
+ };
+ InterfaceDeclaration: {
+ create(p: {
+ export?: true;
+ deprecated?: boolean;
+ name: string;
+ members: readonly string[];
+ typeParameters?: readonly string[];
+ comment?: string;
+ }): string;
+ };
+ MethodDeclaration: {
+ create(p: {
+ name: string;
+ async?: boolean;
+ private?: boolean;
+ typeParameters?: readonly string[];
+ parameters?: readonly string[];
+ type?: string;
+ body?: string;
+ comment?: string;
+ deprecated?: boolean;
+ }): string;
+ };
+ ConstructorDeclaration: {
+ create(p: { parameters?: readonly string[]; body?: string }): string;
+ };
+ ClassDeclaration: {
+ create(p: { name: string; export?: true; members: readonly string[]; typeParameterDeclaration: readonly string[] }): string;
+ };
+ Namespace: {
+ create(p: { export?: true; name: string; statements: string[]; comment?: string; deprecated?: boolean }): string;
+ findNamespace(p: { node: string; name: string }): string | undefined;
+ createMultiple(p: { export?: true; names: string[]; statements: string[]; comment?: string; deprecated?: boolean }): string;
+ update(p: { node: string; statements: string[] }): string;
+ addStatements(p: { node: string; statements: string[] }): string;
+ };
+}
+
+export const create = (): Type => {
+ return {
+ Identifier: {
+ create(p) {
+ return p.name;
+ },
+ },
+
+ StringLiteral: {
+ create(p) {
+ if (p.isSingleQuote) {
+ const escaped = p.text.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
+ return `'${escaped}'`;
+ }
+ const escaped = p.text.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
+ return `"${escaped}"`;
+ },
+ },
+
+ RegularExpressionLiteral: {
+ create(p) {
+ return p.text;
+ },
+ },
+
+ LiteralTypeNode: {
+ create(p) {
+ const node = (() => {
+ if (typeof p.value === "string") {
+ const escaped = p.value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
+ return `"${escaped}"`;
+ }
+ if (typeof p.value === "number") {
+ return `${p.value}`;
+ }
+ return p.value ? "true" : "false";
+ })();
+ return addComment(node, p.comment);
+ },
+ },
+
+ TypeNode: {
+ create(p) {
+ switch (p.type) {
+ case "string":
+ if (p.enum) {
+ return p.enum.map(v => `"${v.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`).join(" | ");
+ }
+ return "string";
+ case "number":
+ case "integer":
+ if (p.enum) {
+ return p.enum.join(" | ");
+ }
+ return "number";
+ case "boolean":
+ if (p.enum) {
+ return p.enum.map(v => `${v}`).join(" | ");
+ }
+ return "boolean";
+ case "object": {
+ const members = p.value || [];
+ if (members.length === 0) return "{}";
+ return `{\n${members.map(m => indentLines(m, " ")).join("\n")}\n}`;
+ }
+ case "array": {
+ const needsParens = hasTopLevelOp(p.value) && !p.value.startsWith("(");
+ return needsParens ? `(${p.value})[]` : `${p.value}[]`;
+ }
+ case "null":
+ return "null";
+ case "undefined":
+ return "undefined";
+ case "never":
+ return "never";
+ case "void":
+ return "void";
+ case "any":
+ return "any";
+ default:
+ return "any";
+ }
+ },
+ },
+
+ TypeReferenceNode: {
+ create(p) {
+ if (p.typeArguments && p.typeArguments.length > 0) {
+ return `${p.name}<${p.typeArguments.join(", ")}>`;
+ }
+ return p.name;
+ },
+ },
+
+ UnionTypeNode: {
+ create(p) {
+ return p.typeNodes.map(t => (hasTopLevelOp(t) && !t.startsWith("(") ? `(${t})` : t)).join(" | ");
+ },
+ },
+
+ IntersectionTypeNode: {
+ create(p) {
+ return p.typeNodes.map(t => (hasTopLevelOp(t) && !t.startsWith("(") ? `(${t})` : t)).join(" & ");
+ },
+ },
+
+ TypeLiteralNode: {
+ create(p) {
+ if (p.members.length === 0) return "{}";
+ return `{\n${p.members.map(m => indentLines(m, " ")).join("\n")}\n}`;
+ },
+ },
+
+ IndexedAccessTypeNode: {
+ create(p) {
+ const obj = hasTopLevelOp(p.objectType) && !p.objectType.startsWith("(") ? `(${p.objectType})` : p.objectType;
+ return `${obj}[${p.indexType}]`;
+ },
+ },
+
+ TypeOperatorNode: {
+ create(p) {
+ return `${p.syntaxKind} ${p.type}`;
+ },
+ },
+
+ FunctionTypeNode: {
+ create(p) {
+ const typeParams = p.typeParameters?.length ? `<${p.typeParameters.join(", ")}>` : "";
+ return `${typeParams}(${p.parameters.join(", ")}) => ${p.type}`;
+ },
+ },
+
+ TypeParameterDeclaration: {
+ create(p) {
+ let result = p.name;
+ if (p.constraint) result += ` extends ${p.constraint}`;
+ if (p.defaultType) result += ` = ${p.defaultType}`;
+ return result;
+ },
+ },
+
+ ParameterDeclaration: {
+ create(p) {
+ const mod = p.modifiers ? `${p.modifiers} ` : "";
+ const opt = p.optional ? "?" : "";
+ const type = p.type ? `: ${p.type}` : "";
+ return `${mod}${p.name}${opt}${type}`;
+ },
+ },
+
+ PropertySignature: {
+ create(p) {
+ const readonly = p.readOnly ? "readonly " : "";
+ const optional = p.optional ? "?" : "";
+ const node = `${readonly}${p.name}${optional}: ${p.type};`;
+ return addComment(node, p.comment);
+ },
+ },
+
+ PropertyDeclaration: {
+ create(p) {
+ const mods = p.modifiers?.length ? `${p.modifiers.join(" ")} ` : "";
+ const token = p.questionOrExclamationToken || "";
+ const type = p.type ? `: ${p.type}` : "";
+ const init = p.initializer ? ` = ${p.initializer}` : "";
+ return `${mods}${p.name}${token}${type}${init};`;
+ },
+ },
+
+ IndexSignatureDeclaration: {
+ create(p) {
+ return `[${p.name}: string]: ${p.type};`;
+ },
+ },
+
+ NoSubstitutionTemplateLiteral: {
+ create(p) {
+ return `\`${escapeTemplateText(p.rawText ?? p.text)}\``;
+ },
+ },
+
+ TemplateHead: {
+ create(p) {
+ return `\`${escapeTemplateText(p.rawText ?? p.text)}\${`;
+ },
+ },
+
+ TemplateMiddle: {
+ create(p) {
+ return `}${escapeTemplateText(p.rawText ?? p.text)}\${`;
+ },
+ },
+
+ TemplateTail: {
+ create(p) {
+ return `}${escapeTemplateText(p.rawText ?? p.text)}\``;
+ },
+ },
+
+ TemplateSpan: {
+ create(p) {
+ return `${p.expression}${p.literal}`;
+ },
+ },
+
+ TemplateExpression: {
+ create(p) {
+ return p.head + p.templateSpans.join("");
+ },
+ },
+
+ BinaryExpression: {
+ create(p) {
+ return `${p.left} ${p.operator} ${p.right}`;
+ },
+ },
+
+ PropertyAccessExpression: {
+ create(p) {
+ return `${p.expression}.${p.name}`;
+ },
+ },
+
+ ElementAccessExpression: {
+ create(p) {
+ return `${p.expression}[${p.argumentExpression}]`;
+ },
+ },
+
+ CallExpression: {
+ create(p) {
+ const typeArgs = p.typeArguments?.length ? `<${p.typeArguments.join(", ")}>` : "";
+ return `${p.expression}${typeArgs}(${p.argumentsArray.join(", ")})`;
+ },
+ },
+
+ ObjectLiteralExpression: {
+ create(p) {
+ if (!p.multiLine) {
+ return `{ ${p.properties.join(", ")} }`;
+ }
+ if (p.properties.length === 0) return "{}";
+ return `{\n${p.properties.map(prop => indentLines(prop, " ")).join(",\n")}\n}`;
+ },
+ },
+
+ PropertyAssignment: {
+ create(p) {
+ const base = `${p.name}: ${p.initializer}`;
+ return addComment(base, p.comment);
+ },
+ },
+
+ ShorthandPropertyAssignment: {
+ create(p) {
+ return p.name;
+ },
+ },
+
+ ArrowFunction: {
+ create(p) {
+ const typeParams = p.typeParameters?.length ? `<${p.typeParameters.join(", ")}>` : "";
+ const params = `(${p.parameters.join(", ")})`;
+ const ret = p.type ? `: ${p.type}` : "";
+ return `${typeParams}${params}${ret} => ${p.body}`;
+ },
+ },
+
+ ReturnStatement: {
+ create(p) {
+ return p.expression !== undefined ? `return ${p.expression};` : "return;";
+ },
+ },
+
+ ExpressionStatement: {
+ create(p) {
+ return `${p.expression};`;
+ },
+ },
+
+ Block: {
+ create(p) {
+ if (p.statements.length === 0) return "{}";
+ if (!p.multiLine) {
+ return `{ ${p.statements.join(" ")} }`;
+ }
+ return `{\n${p.statements.map(s => indentLines(s, " ")).join("\n")}\n}`;
+ },
+ },
+
+ VariableDeclaration: {
+ create(p) {
+ const type = p.type ? `: ${p.type}` : "";
+ const init = p.initializer !== undefined ? ` = ${p.initializer}` : "";
+ return `${p.name}${type}${init}`;
+ },
+ },
+
+ VariableDeclarationList: {
+ create(p) {
+ return `const ${p.declarations.join(", ")}`;
+ },
+ },
+
+ VariableStatement: {
+ create(p) {
+ const mods = p.modifiers?.length ? `${p.modifiers.join(" ")} ` : "";
+ const node = `${mods}${p.declarationList};`;
+ return addComment(node, p.comment, p.deprecated);
+ },
+ },
+
+ TypeAliasDeclaration: {
+ create(p) {
+ const exp = p.export ? "export " : "";
+ const node = `${exp}type ${p.name} = ${p.type};`;
+ return addComment(node, p.comment, p.deprecated);
+ },
+ },
+
+ InterfaceDeclaration: {
+ create(p) {
+ const exp = p.export ? "export " : "";
+ const typeParams = p.typeParameters?.length ? `<${p.typeParameters.join(", ")}>` : "";
+ const body = p.members.length > 0 ? `{\n${p.members.map(m => indentLines(m, " ")).join("\n")}\n}` : "{\n}";
+ const node = `${exp}interface ${escapeIdentifier(p.name)}${typeParams} ${body}`;
+ return addComment(node, p.comment, p.deprecated);
+ },
+ },
+
+ MethodDeclaration: {
+ create(p) {
+ const modifiers: string[] = [];
+ if (p.private) modifiers.push("private");
+ else modifiers.push("public");
+ if (p.async) modifiers.push("async");
+ const mods = `${modifiers.join(" ")} `;
+ const typeParams = p.typeParameters?.length ? `<${p.typeParameters.join(", ")}>` : "";
+ const params = `(${(p.parameters || []).join(", ")})`;
+ const ret = p.type ? `: ${p.type}` : "";
+ const body = p.body || "{}";
+ const node = `${mods}${p.name}${typeParams}${params}${ret} ${body}`;
+ return addComment(node, p.comment, p.deprecated);
+ },
+ },
+
+ ConstructorDeclaration: {
+ create(p) {
+ const params = `(${(p.parameters || []).join(", ")})`;
+ const body = p.body || "{}";
+ return `constructor${params} ${body}`;
+ },
+ },
+
+ ClassDeclaration: {
+ create(p) {
+ const exp = p.export ? "export " : "";
+ const typeParams = p.typeParameterDeclaration.length ? `<${p.typeParameterDeclaration.join(", ")}>` : "";
+ const body = p.members.length > 0 ? `{\n${p.members.map(m => indentLines(m, " ")).join("\n")}\n}` : "{}";
+ return `${exp}class ${p.name}${typeParams} ${body}`;
+ },
+ },
+
+ Namespace: {
+ create(p) {
+ const exp = p.export ? "export " : "";
+ const body = p.statements.length > 0 ? `{\n${p.statements.map(s => indentLines(s, " ")).join("\n")}\n}` : "{ }";
+ const node = `${exp}namespace ${p.name} ${body}`;
+ return addComment(node, p.comment, p.deprecated);
+ },
+ findNamespace(p) {
+ const re = new RegExp(`(?:export\\s+)?namespace\\s+${escapeIdentifier(p.name)}\\s*\\{`);
+ return re.test(p.node) ? p.node : undefined;
+ },
+ createMultiple(p) {
+ const names = [...p.names].reverse();
+ const firstName = names[0];
+ const restNames = names.slice(1);
+ const exp = p.export ? "export " : "";
+ const body = p.statements.length > 0 ? `{\n${p.statements.map(s => indentLines(s, " ")).join("\n")}\n}` : "{}";
+ const current = addComment(`${exp}namespace ${firstName} ${body}`, p.comment, p.deprecated);
+ return restNames.reduce((prev, name) => {
+ return `export namespace ${name} {\n${indentLines(prev, " ")}\n}`;
+ }, current);
+ },
+ update(p) {
+ const insertPoint = p.node.lastIndexOf("}");
+ if (insertPoint === -1) return p.node;
+ const added = p.statements.map(s => indentLines(s, " ")).join("\n");
+ return `${p.node.slice(0, insertPoint) + added}\n}`;
+ },
+ addStatements(p) {
+ return p.statements.reduce((node, s) => {
+ const insertPoint = node.lastIndexOf("}");
+ if (insertPoint === -1) return node;
+ return `${node.slice(0, insertPoint) + indentLines(s, " ")}\n}`;
+ }, p.node);
+ },
+ },
+ };
+};
diff --git a/src/internal/TsGenerator/factory/ArrowFunction.ts b/src/internal/TsGenerator/factory/ArrowFunction.ts
deleted file mode 100644
index c3f1e78f..00000000
--- a/src/internal/TsGenerator/factory/ArrowFunction.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- typeParameters: ts.TypeParameterDeclaration[] | undefined;
- parameters: ts.ParameterDeclaration[];
- type?: ts.TypeNode;
- equalsGreaterThanToken?: ts.EqualsGreaterThanToken;
- body: ts.ConciseBody;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.ArrowFunction;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.ArrowFunction => {
- const node = factory.createArrowFunction(
- undefined,
- params.typeParameters,
- params.parameters,
- params.type,
- params.equalsGreaterThanToken,
- params.body,
- );
-
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/BinaryExpression.ts b/src/internal/TsGenerator/factory/BinaryExpression.ts
deleted file mode 100644
index ac593253..00000000
--- a/src/internal/TsGenerator/factory/BinaryExpression.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import ts from "typescript";
-
-const operators = {
- "+": ts.SyntaxKind.PlusToken,
- "=": ts.SyntaxKind.EqualsToken,
-} as const;
-
-export interface Params {
- left: ts.Expression;
- operator: keyof typeof operators;
- right: ts.Expression;
-}
-
-export interface Factory {
- create: (params: Params) => ts.BinaryExpression;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.BinaryExpression => {
- const node = factory.createBinaryExpression(params.left, operators[params.operator], params.right);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/Block.ts b/src/internal/TsGenerator/factory/Block.ts
deleted file mode 100644
index a5d7e6d8..00000000
--- a/src/internal/TsGenerator/factory/Block.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- statements: readonly ts.Statement[];
- multiLine: boolean;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.Block;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.Block => {
- const node = factory.createBlock(params.statements, params.multiLine);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/CallExpression.ts b/src/internal/TsGenerator/factory/CallExpression.ts
deleted file mode 100644
index 9c6a97d1..00000000
--- a/src/internal/TsGenerator/factory/CallExpression.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- expression: ts.Expression;
- typeArguments?: readonly ts.TypeNode[] | undefined;
- argumentsArray: readonly ts.Expression[];
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.CallExpression;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.CallExpression => {
- const node = factory.createCallExpression(params.expression, params.typeArguments, params.argumentsArray);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/ClassDeclaration.ts b/src/internal/TsGenerator/factory/ClassDeclaration.ts
deleted file mode 100644
index 21052223..00000000
--- a/src/internal/TsGenerator/factory/ClassDeclaration.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import ts from "typescript";
-
-export interface Params$Create {
- name: string;
- export?: true;
- members: readonly ts.ClassElement[];
- typeParameterDeclaration: readonly ts.TypeParameterDeclaration[];
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.ClassDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.ClassDeclaration => {
- const node = factory.createClassDeclaration(
- params.export && [factory.createModifier(ts.SyntaxKind.ExportKeyword)],
- factory.createIdentifier(params.name),
- params.typeParameterDeclaration,
- undefined,
- params.members,
- );
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/ConstructorDeclaration.ts b/src/internal/TsGenerator/factory/ConstructorDeclaration.ts
deleted file mode 100644
index 961e50b6..00000000
--- a/src/internal/TsGenerator/factory/ConstructorDeclaration.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- parameters?: ts.ParameterDeclaration[];
- body?: ts.Block;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.ConstructorDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.ConstructorDeclaration => {
- const node = factory.createConstructorDeclaration(undefined, params.parameters || [], params.body);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/ElementAccessExpression.ts b/src/internal/TsGenerator/factory/ElementAccessExpression.ts
deleted file mode 100644
index 154c5c0f..00000000
--- a/src/internal/TsGenerator/factory/ElementAccessExpression.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- expression: ts.Expression;
- index: number | string | ts.Expression;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.ElementAccessExpression;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.ElementAccessExpression => {
- const index = typeof params.index === "string" ? factory.createStringLiteral(params.index) : params.index;
- const node = factory.createElementAccessExpression(params.expression, index);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/ExpressionStatement.ts b/src/internal/TsGenerator/factory/ExpressionStatement.ts
deleted file mode 100644
index 201b2a13..00000000
--- a/src/internal/TsGenerator/factory/ExpressionStatement.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- expression: ts.Expression;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.ExpressionStatement;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.ExpressionStatement => {
- const node = factory.createExpressionStatement(params.expression);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/FunctionTypeNode.ts b/src/internal/TsGenerator/factory/FunctionTypeNode.ts
deleted file mode 100644
index f01e5c6e..00000000
--- a/src/internal/TsGenerator/factory/FunctionTypeNode.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- typeParameters: readonly ts.TypeParameterDeclaration[] | undefined;
- parameters: readonly ts.ParameterDeclaration[];
- type: ts.TypeNode;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.FunctionTypeNode;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.FunctionTypeNode => {
- const node = factory.createFunctionTypeNode(params.typeParameters, params.parameters, params.type);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/Identifier.ts b/src/internal/TsGenerator/factory/Identifier.ts
deleted file mode 100644
index 92f0fd49..00000000
--- a/src/internal/TsGenerator/factory/Identifier.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- name: string;
-}
-
-export interface Factory {
- create: (params: Params) => ts.Identifier;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.Identifier => {
- const node = factory.createIdentifier(params.name);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/IndexSignatureDeclaration.ts b/src/internal/TsGenerator/factory/IndexSignatureDeclaration.ts
deleted file mode 100644
index a64bc680..00000000
--- a/src/internal/TsGenerator/factory/IndexSignatureDeclaration.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import ts from "typescript";
-
-export interface Params$Create {
- name: string;
- type: ts.TypeNode;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.IndexSignatureDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.IndexSignatureDeclaration => {
- const node = factory.createIndexSignature(
- undefined,
- // TODO Feature Development: Refactoring
- [
- factory.createParameterDeclaration(
- undefined,
- undefined,
- factory.createIdentifier(params.name),
- undefined,
- factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
- undefined,
- ),
- ],
- params.type,
- );
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/IndexedAccessTypeNode.ts b/src/internal/TsGenerator/factory/IndexedAccessTypeNode.ts
deleted file mode 100644
index 132e6d2a..00000000
--- a/src/internal/TsGenerator/factory/IndexedAccessTypeNode.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- objectType: ts.TypeNode;
- indexType: ts.TypeNode;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.IndexedAccessTypeNode;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.IndexedAccessTypeNode => {
- const node = factory.createIndexedAccessTypeNode(params.objectType, params.indexType);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/InterfaceDeclaration.ts b/src/internal/TsGenerator/factory/InterfaceDeclaration.ts
deleted file mode 100644
index 023b7af2..00000000
--- a/src/internal/TsGenerator/factory/InterfaceDeclaration.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import ts from "typescript";
-
-import { escapeIdentiferText, generateComment } from "./utils";
-
-export interface Params$Create {
- export?: true;
- deprecated?: boolean;
- name: string;
- members: readonly ts.TypeElement[];
- typeParameters?: readonly ts.TypeParameterDeclaration[];
- comment?: string;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.InterfaceDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.InterfaceDeclaration => {
- const node = ts.factory.createInterfaceDeclaration(
- params.export && [factory.createModifier(ts.SyntaxKind.ExportKeyword)],
- factory.createIdentifier(escapeIdentiferText(params.name)),
- params.typeParameters,
- undefined,
- params.members,
- );
- if (params.comment) {
- const comment = generateComment(params.comment, params.deprecated);
- return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment.value, comment.hasTrailingNewLine);
- }
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/IntersectionTypeNode.ts b/src/internal/TsGenerator/factory/IntersectionTypeNode.ts
deleted file mode 100644
index 0d596d39..00000000
--- a/src/internal/TsGenerator/factory/IntersectionTypeNode.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- typeNodes: ts.TypeNode[];
-}
-
-export interface Factory {
- create: (params: Params) => ts.IntersectionTypeNode;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.IntersectionTypeNode => {
- const node = factory.createIntersectionTypeNode(params.typeNodes);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/LiteralTypeNode.ts b/src/internal/TsGenerator/factory/LiteralTypeNode.ts
deleted file mode 100644
index 4842304d..00000000
--- a/src/internal/TsGenerator/factory/LiteralTypeNode.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import ts from "typescript";
-
-import { generateComment } from "./utils";
-
-export interface Params {
- value: string | boolean | number;
- comment?: string;
-}
-
-export interface Factory {
- create: (params: Params) => ts.LiteralTypeNode;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.LiteralTypeNode => {
- const createNode = () => {
- if (typeof params.value === "string") {
- const literal = ts.setEmitFlags(factory.createStringLiteral(params.value), ts.EmitFlags.NoAsciiEscaping);
- return factory.createLiteralTypeNode(literal);
- }
-
- if (typeof params.value === "number") {
- if (params.value < 0) {
- return factory.createLiteralTypeNode(
- factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, factory.createNumericLiteral(-params.value)),
- );
- }
- return factory.createLiteralTypeNode(factory.createNumericLiteral(params.value));
- }
- return factory.createLiteralTypeNode(params.value ? factory.createTrue() : factory.createFalse());
- };
- const node = createNode();
- if (params.comment) {
- const comment = generateComment(params.comment);
- return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment.value, comment.hasTrailingNewLine);
- }
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/MethodDeclaration.ts b/src/internal/TsGenerator/factory/MethodDeclaration.ts
deleted file mode 100644
index 62f417c0..00000000
--- a/src/internal/TsGenerator/factory/MethodDeclaration.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import ts from "typescript";
-
-import { generateComment } from "./utils";
-
-export interface Params$Create {
- name: string;
- async?: boolean;
- private?: boolean;
- typeParameters?: readonly ts.TypeParameterDeclaration[];
- parameters?: ts.ParameterDeclaration[];
- type?: ts.TypeNode;
- body?: ts.Block;
- comment?: string;
- deprecated?: boolean;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.MethodDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.MethodDeclaration => {
- const modifiers: ts.Modifier[] = [];
- if (params.private) {
- modifiers.push(factory.createModifier(ts.SyntaxKind.PrivateKeyword));
- } else {
- modifiers.push(factory.createModifier(ts.SyntaxKind.PublicKeyword));
- }
- if (params.async) {
- modifiers.push(factory.createModifier(ts.SyntaxKind.AsyncKeyword));
- }
- const node = factory.createMethodDeclaration(
- modifiers,
- undefined,
- factory.createIdentifier(params.name),
- undefined,
- params.typeParameters,
- params.parameters || [],
- params.type,
- params.body,
- );
- if (params.comment) {
- const comment = generateComment(params.comment, params.deprecated);
- return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment.value, comment.hasTrailingNewLine);
- }
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/ModuleBlock.ts b/src/internal/TsGenerator/factory/ModuleBlock.ts
deleted file mode 100644
index 3c25a8ee..00000000
--- a/src/internal/TsGenerator/factory/ModuleBlock.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface UpdateParams {
- node: ts.ModuleBlock;
- statements: ts.Statement[];
-}
-
-export interface Factory {
- update: (params: UpdateParams) => ts.ModuleBlock;
-}
-
-export const update =
- ({ factory }: Pick): Factory["update"] =>
- (params: UpdateParams): ts.ModuleBlock => {
- const { node, statements } = params;
- return factory.updateModuleBlock(node, statements);
- };
-
-export const make = (context: Pick): Factory => {
- return {
- update: update(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/Namespace.ts b/src/internal/TsGenerator/factory/Namespace.ts
deleted file mode 100644
index 7c332655..00000000
--- a/src/internal/TsGenerator/factory/Namespace.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import ts from "typescript";
-
-import * as ModuleBlock from "./ModuleBlock";
-import { generateComment } from "./utils";
-
-export interface Params$FindStatement {
- node: ts.ModuleDeclaration;
- name: string;
-}
-
-export interface Params$Create {
- export?: true;
- name: string;
- statements: ts.Statement[];
- comment?: string;
- deprecated?: boolean;
-}
-
-export interface Params$CreateMulti extends Omit {
- names: string[];
-}
-export interface Params$Update {
- node: ts.ModuleDeclaration;
- statements: ts.Statement[];
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.ModuleDeclaration;
- findNamespace: (params: Params$FindStatement) => ts.Statement | undefined;
- createMultiple: (params: Params$CreateMulti) => ts.ModuleDeclaration;
- update: (params: Params$Update) => ts.ModuleDeclaration;
- addStatements: (params: Params$Update) => ts.ModuleDeclaration;
-}
-
-// eslint-disable-next-line no-unused-vars
-export const findStatement =
- (_context: Pick): Factory["findNamespace"] =>
- (params: Params$FindStatement): ts.Statement | undefined => {
- let statement: ts.Statement | undefined;
- params.node.forEachChild(node => {
- if (ts.isModuleDeclaration(node) && node.name.text === params.name) {
- statement = node;
- }
- });
- return statement;
- };
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.ModuleDeclaration => {
- const node = factory.createModuleDeclaration(
- params.export && [factory.createModifier(ts.SyntaxKind.ExportKeyword)],
- factory.createIdentifier(params.name),
- factory.createModuleBlock(params.statements),
- ts.NodeFlags.Namespace,
- );
- if (params.comment) {
- const comment = generateComment(params.comment, params.deprecated);
- return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment.value, comment.hasTrailingNewLine);
- }
- return node;
- };
-
-export const createMultiple =
- (context: Pick): Factory["createMultiple"] =>
- (params: Params$CreateMulti): ts.ModuleDeclaration => {
- const names = params.names.reverse();
- const firstName = names[0];
- const restNames = names.slice(1, names.length);
- const child = create(context)({
- export: true,
- name: firstName,
- statements: params.statements,
- comment: params.comment,
- deprecated: params.deprecated,
- });
- return restNames.reduce((previousStatement, currentName) => {
- return create(context)({
- export: true,
- name: currentName,
- statements: [previousStatement],
- });
- }, child);
- };
-
-export const update =
- (context: Pick): Factory["update"] =>
- (params: Params$Update): ts.ModuleDeclaration => {
- const { factory } = context;
- const { node, statements } = params;
- if (node.body && ts.isModuleBlock(node.body)) {
- const body = ModuleBlock.update(context)({ node: node.body, statements });
- return factory.updateModuleDeclaration(node, node.modifiers, node.name, body);
- }
- return factory.updateModuleDeclaration(node, node.modifiers, node.name, node.body);
- };
-
-export const addStatements =
- (context: Pick): Factory["addStatements"] =>
- (params: Params$Update): ts.ModuleDeclaration => {
- const { factory } = context;
- const { node, statements } = params;
- if (node.body && ts.isModuleBlock(node.body)) {
- const body = ModuleBlock.update(context)({ node: node.body, statements: node.body.statements.concat(statements) });
- return factory.updateModuleDeclaration(node, node.modifiers, node.name, body);
- }
- return factory.updateModuleDeclaration(node, node.modifiers, node.name, node.body);
- };
-
-export const make = (context: Pick): Factory => {
- return {
- findNamespace: findStatement(context),
- create: create(context),
- update: update(context),
- createMultiple: createMultiple(context),
- addStatements: addStatements(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/NoSubstitutionTemplateLiteral.ts b/src/internal/TsGenerator/factory/NoSubstitutionTemplateLiteral.ts
deleted file mode 100644
index d1f76838..00000000
--- a/src/internal/TsGenerator/factory/NoSubstitutionTemplateLiteral.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- text: string;
- rawText?: string;
-}
-
-export interface Factory {
- create: (params: Params) => ts.NoSubstitutionTemplateLiteral;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.NoSubstitutionTemplateLiteral => {
- const node = factory.createNoSubstitutionTemplateLiteral(params.text, params.rawText);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/ObjectLiteralExpression.ts b/src/internal/TsGenerator/factory/ObjectLiteralExpression.ts
deleted file mode 100644
index a57d5f73..00000000
--- a/src/internal/TsGenerator/factory/ObjectLiteralExpression.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- properties: ts.ObjectLiteralElementLike[];
- multiLine?: boolean;
-}
-
-export interface Factory {
- create: (params: Params) => ts.ObjectLiteralExpression;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.ObjectLiteralExpression => {
- const node = factory.createObjectLiteralExpression(params.properties, params.multiLine);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/ParameterDeclaration.ts b/src/internal/TsGenerator/factory/ParameterDeclaration.ts
deleted file mode 100644
index c9c16f4c..00000000
--- a/src/internal/TsGenerator/factory/ParameterDeclaration.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import ts from "typescript";
-
-export interface Params$Create {
- name: string;
- optional?: true;
- modifiers?: "private" | "public";
- type?: ts.TypeNode;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.ParameterDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.ParameterDeclaration => {
- const modifiers = (() => {
- if (params.modifiers === "private") {
- return [factory.createModifier(ts.SyntaxKind.PrivateKeyword)];
- }
- if (params.modifiers === "public") {
- return [factory.createModifier(ts.SyntaxKind.PublicKeyword)];
- }
- return;
- })();
- const node = factory.createParameterDeclaration(
- modifiers,
- undefined,
- factory.createIdentifier(params.name),
- params.optional && factory.createToken(ts.SyntaxKind.QuestionToken),
- params.type,
- undefined,
- );
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/PropertyAccessExpression.ts b/src/internal/TsGenerator/factory/PropertyAccessExpression.ts
deleted file mode 100644
index c64ebcc8..00000000
--- a/src/internal/TsGenerator/factory/PropertyAccessExpression.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import type ts from "typescript";
-
-const generateExpression = (factory: ts.NodeFactory) => {
- return {
- this: factory.createThis(),
- };
-};
-
-export interface Params$Create {
- expression: string | "this" | ts.Expression;
- name: string;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.PropertyAccessExpression;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.PropertyAccessExpression => {
- let expression: ts.Expression = typeof params.expression === "string" ? factory.createIdentifier(params.expression) : params.expression;
- const expressionMap = generateExpression(factory);
- if (typeof params.expression === "string" && params.expression in expressionMap) {
- expression = generateExpression(factory)[params.expression as "this"];
- }
- const node = factory.createPropertyAccessExpression(expression, factory.createIdentifier(params.name));
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/PropertyAssignment.ts b/src/internal/TsGenerator/factory/PropertyAssignment.ts
deleted file mode 100644
index 6eb8de08..00000000
--- a/src/internal/TsGenerator/factory/PropertyAssignment.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import ts from "typescript";
-import { generateComment } from "./utils";
-
-export interface Params {
- name: string;
- initializer: ts.Expression;
- comment?: string;
- deprecated?: boolean;
-}
-
-export interface Factory {
- create: (params: Params) => ts.PropertyAssignment;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.PropertyAssignment => {
- const node = factory.createPropertyAssignment(params.name, params.initializer);
- if (params.comment) {
- const comment = generateComment(params.comment, params.deprecated);
- return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment.value, comment.hasTrailingNewLine);
- }
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/PropertyDeclaration.ts b/src/internal/TsGenerator/factory/PropertyDeclaration.ts
deleted file mode 100644
index c5bb1ed1..00000000
--- a/src/internal/TsGenerator/factory/PropertyDeclaration.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- modifiers: readonly ts.Modifier[] | undefined;
- name: string | ts.PropertyName;
- questionOrExclamationToken?: ts.QuestionToken | ts.ExclamationToken | undefined;
- type: ts.TypeNode | undefined;
- initializer?: ts.Expression | undefined;
-}
-
-export interface Factory {
- create: (params: Params) => ts.PropertyDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.PropertyDeclaration => {
- const node = factory.createPropertyDeclaration(
- params.modifiers,
- params.name,
- params.questionOrExclamationToken,
- params.type,
- params.initializer,
- );
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/PropertySignature.ts b/src/internal/TsGenerator/factory/PropertySignature.ts
deleted file mode 100644
index a23ff35f..00000000
--- a/src/internal/TsGenerator/factory/PropertySignature.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import ts from "typescript";
-
-import { generateComment } from "./utils";
-
-export interface Params {
- name: string;
- readOnly: boolean;
- optional: boolean;
- type: ts.TypeNode;
- comment?: string;
-}
-
-export interface Factory {
- create: (params: Params) => ts.PropertySignature;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.PropertySignature => {
- const node = factory.createPropertySignature(
- params.readOnly ? [factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)] : undefined,
- params.name,
- params.optional ? factory.createToken(ts.SyntaxKind.QuestionToken) : undefined,
- params.type,
- );
- if (params.comment) {
- const comment = generateComment(params.comment);
- return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment.value, comment.hasTrailingNewLine);
- }
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/RegularExpressionLiteral.ts b/src/internal/TsGenerator/factory/RegularExpressionLiteral.ts
deleted file mode 100644
index bb76c7ed..00000000
--- a/src/internal/TsGenerator/factory/RegularExpressionLiteral.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- text: string;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.RegularExpressionLiteral;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.RegularExpressionLiteral => {
- return factory.createRegularExpressionLiteral(params.text);
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/ReturnStatement.ts b/src/internal/TsGenerator/factory/ReturnStatement.ts
deleted file mode 100644
index 0b941aee..00000000
--- a/src/internal/TsGenerator/factory/ReturnStatement.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- expression?: ts.Expression;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.ReturnStatement;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.ReturnStatement => {
- const node = factory.createReturnStatement(params.expression);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/ShorthandPropertyAssignment.ts b/src/internal/TsGenerator/factory/ShorthandPropertyAssignment.ts
deleted file mode 100644
index 0c30250b..00000000
--- a/src/internal/TsGenerator/factory/ShorthandPropertyAssignment.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- name: string;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.ShorthandPropertyAssignment;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.ShorthandPropertyAssignment => {
- const node = factory.createShorthandPropertyAssignment(params.name, undefined);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/StringLiteral.ts b/src/internal/TsGenerator/factory/StringLiteral.ts
deleted file mode 100644
index 5bea140b..00000000
--- a/src/internal/TsGenerator/factory/StringLiteral.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- text: string;
- isSingleQuote?: boolean;
-}
-
-export interface Factory {
- create: (params: Params) => ts.StringLiteral;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.StringLiteral => {
- const node = factory.createStringLiteral(params.text, params.isSingleQuote);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TemplateExpression.ts b/src/internal/TsGenerator/factory/TemplateExpression.ts
deleted file mode 100644
index 475993a7..00000000
--- a/src/internal/TsGenerator/factory/TemplateExpression.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- head: ts.TemplateHead;
- templateSpans: readonly ts.TemplateSpan[];
-}
-
-export interface Factory {
- create: (params: Params) => ts.TemplateExpression;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.TemplateExpression => {
- const node = factory.createTemplateExpression(params.head, params.templateSpans);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TemplateHead.ts b/src/internal/TsGenerator/factory/TemplateHead.ts
deleted file mode 100644
index 7c160f58..00000000
--- a/src/internal/TsGenerator/factory/TemplateHead.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- text: string;
- rawText?: string;
-}
-
-export interface Factory {
- create: (params: Params) => ts.TemplateHead;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.TemplateHead => {
- const node = factory.createTemplateHead(params.text, params.rawText, undefined);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TemplateMiddle.ts b/src/internal/TsGenerator/factory/TemplateMiddle.ts
deleted file mode 100644
index 35c0e0a6..00000000
--- a/src/internal/TsGenerator/factory/TemplateMiddle.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- text: string;
- rawText?: string;
-}
-
-export interface Factory {
- create: (params: Params) => ts.TemplateMiddle;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.TemplateMiddle => {
- const node = factory.createTemplateMiddle(params.text, params.rawText, undefined);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TemplateSpan.ts b/src/internal/TsGenerator/factory/TemplateSpan.ts
deleted file mode 100644
index b09b9484..00000000
--- a/src/internal/TsGenerator/factory/TemplateSpan.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- expression: ts.Expression;
- literal: ts.TemplateMiddle | ts.TemplateTail;
-}
-
-export interface Factory {
- create: (params: Params) => ts.TemplateSpan;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.TemplateSpan => {
- const node = factory.createTemplateSpan(params.expression, params.literal);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TemplateTail.ts b/src/internal/TsGenerator/factory/TemplateTail.ts
deleted file mode 100644
index 53dfb43f..00000000
--- a/src/internal/TsGenerator/factory/TemplateTail.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- text: string;
- rawText?: string;
-}
-
-export interface Factory {
- create: (params: Params) => ts.TemplateTail;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.TemplateTail => {
- const node = factory.createTemplateTail(params.text, params.rawText);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TypeAliasDeclaration.ts b/src/internal/TsGenerator/factory/TypeAliasDeclaration.ts
deleted file mode 100644
index 4b4bf17e..00000000
--- a/src/internal/TsGenerator/factory/TypeAliasDeclaration.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import ts from "typescript";
-
-import { generateComment } from "./utils";
-
-export interface Params$Create {
- export?: true;
- name: string;
- type: ts.TypeNode;
- comment?: string;
- deprecated?: boolean;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.TypeAliasDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.TypeAliasDeclaration => {
- const node = factory.createTypeAliasDeclaration(
- params.export && [factory.createModifier(ts.SyntaxKind.ExportKeyword)],
- factory.createIdentifier(params.name),
- undefined,
- params.type,
- );
- if (params.comment) {
- const comment = generateComment(params.comment, params.deprecated);
- return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment.value, comment.hasTrailingNewLine);
- }
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TypeLiteralNode.ts b/src/internal/TsGenerator/factory/TypeLiteralNode.ts
deleted file mode 100644
index a1e28a0f..00000000
--- a/src/internal/TsGenerator/factory/TypeLiteralNode.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- members: readonly ts.TypeElement[] | undefined;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.TypeLiteralNode;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.TypeLiteralNode => {
- const node = factory.createTypeLiteralNode(params.members);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TypeNode.ts b/src/internal/TsGenerator/factory/TypeNode.ts
deleted file mode 100644
index 0b4b3e7e..00000000
--- a/src/internal/TsGenerator/factory/TypeNode.ts
+++ /dev/null
@@ -1,131 +0,0 @@
-import ts from "typescript";
-
-import { UnSupportError } from "../../Exception";
-import * as LiteralTypeNode from "./LiteralTypeNode";
-import * as UnionTypeNode from "./UnionTypeNode";
-
-export interface StringParams {
- type: "string";
- enum?: string[];
-}
-
-export interface IntegerParams {
- type: "integer";
- enum?: number[];
-}
-
-export interface NumberParams {
- type: "number";
- enum?: number[];
-}
-
-export interface BooleanParams {
- type: "boolean";
- enum?: boolean[];
-}
-
-export interface ObjectParams {
- type: "object";
- value: ts.TypeElement[];
-}
-
-export interface UndefinedParams {
- type: "undefined";
-}
-
-export interface ArrayParams {
- type: "array";
- value: ts.TypeNode;
-}
-
-export interface NullParams {
- type: "null";
-}
-
-export interface NeverParams {
- type: "never";
-}
-
-export interface AnyParams {
- type: "any";
-}
-
-export interface VoidParams {
- type: "void";
-}
-
-export type Params$Create =
- | StringParams
- | IntegerParams
- | NumberParams
- | BooleanParams
- | ObjectParams
- | ArrayParams
- | UndefinedParams
- | NullParams
- | VoidParams
- | NeverParams
- | AnyParams;
-
-export interface Factory {
- create: (params: Params$Create) => ts.TypeNode;
-}
-
-export const create =
- (context: Pick): Factory["create"] =>
- (params: Params$Create): ts.TypeNode => {
- const { factory } = context;
- const literalTypeNode = LiteralTypeNode.create(context);
- const unionTypeNode = UnionTypeNode.create(context);
- const createNode = () => {
- switch (params.type) {
- case "string":
- if (params.enum) {
- return unionTypeNode({
- typeNodes: params.enum.map(value => literalTypeNode({ value })),
- });
- }
- return factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
- case "number":
- case "integer":
- if (params.enum) {
- return unionTypeNode({
- typeNodes: params.enum.map(value => literalTypeNode({ value })),
- });
- }
- return factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword);
- case "boolean": {
- if (params.enum) {
- return unionTypeNode({
- typeNodes: params.enum.map(value => literalTypeNode({ value })),
- });
- }
- return factory.createKeywordTypeNode(ts.SyntaxKind.BooleanKeyword);
- }
- case "object":
- return factory.createTypeLiteralNode(params.value);
- case "undefined":
- return factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword);
- case "null":
- return factory.createLiteralTypeNode(factory.createNull());
- case "array":
- return factory.createArrayTypeNode(params.value);
- case "never":
- return factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword);
- case "void":
- return factory.createKeywordTypeNode(ts.SyntaxKind.VoidKeyword);
- case "any":
- return factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);
- default:
- throw new UnSupportError(`UnSupport Type: ${JSON.stringify(params)}`);
- }
- };
- const node = createNode();
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TypeOperatorNode.ts b/src/internal/TsGenerator/factory/TypeOperatorNode.ts
deleted file mode 100644
index ac06bc76..00000000
--- a/src/internal/TsGenerator/factory/TypeOperatorNode.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import ts from "typescript";
-
-const syntaxKinds = {
- keyof: ts.SyntaxKind.KeyOfKeyword,
- unique: ts.SyntaxKind.UniqueKeyword,
- readonly: ts.SyntaxKind.ReadonlyKeyword,
-} as const;
-
-export interface Params$Create {
- syntaxKind: keyof typeof syntaxKinds;
- type: ts.TypeNode;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.TypeOperatorNode;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.TypeOperatorNode => {
- const node = factory.createTypeOperatorNode(syntaxKinds[params.syntaxKind], params.type);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TypeParameterDeclaration.ts b/src/internal/TsGenerator/factory/TypeParameterDeclaration.ts
deleted file mode 100644
index 26bb4287..00000000
--- a/src/internal/TsGenerator/factory/TypeParameterDeclaration.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- name: string;
- constraint?: ts.TypeNode;
- defaultType?: ts.TypeNode;
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.TypeParameterDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.TypeParameterDeclaration => {
- const node = factory.createTypeParameterDeclaration([], factory.createIdentifier(params.name), params.constraint, params.defaultType);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/TypeReferenceNode.ts b/src/internal/TsGenerator/factory/TypeReferenceNode.ts
deleted file mode 100644
index e1c369b1..00000000
--- a/src/internal/TsGenerator/factory/TypeReferenceNode.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import type ts from "typescript";
-
-export interface Params$Create {
- name: string;
- typeArguments?: readonly ts.TypeNode[];
-}
-
-export interface Factory {
- create: (params: Params$Create) => ts.TypeReferenceNode;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params$Create): ts.TypeReferenceNode => {
- const node = factory.createTypeReferenceNode(factory.createIdentifier(params.name), params.typeArguments);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/UnionTypeNode.ts b/src/internal/TsGenerator/factory/UnionTypeNode.ts
deleted file mode 100644
index 0bcdcedf..00000000
--- a/src/internal/TsGenerator/factory/UnionTypeNode.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- typeNodes: ts.TypeNode[];
-}
-
-export interface Factory {
- create: (params: Params) => ts.UnionTypeNode;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.UnionTypeNode => {
- const node = factory.createUnionTypeNode(params.typeNodes);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/VariableDeclaration.ts b/src/internal/TsGenerator/factory/VariableDeclaration.ts
deleted file mode 100644
index ce1e7e0c..00000000
--- a/src/internal/TsGenerator/factory/VariableDeclaration.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type ts from "typescript";
-
-export interface Params {
- name: string | ts.BindingName;
- type?: ts.TypeNode;
- initializer?: ts.Expression;
-}
-
-export interface Factory {
- create: (params: Params) => ts.VariableDeclaration;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.VariableDeclaration => {
- const node = factory.createVariableDeclaration(params.name, undefined, params.type, params.initializer);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/VariableDeclarationList.ts b/src/internal/TsGenerator/factory/VariableDeclarationList.ts
deleted file mode 100644
index c7ad8d68..00000000
--- a/src/internal/TsGenerator/factory/VariableDeclarationList.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import ts from "typescript";
-
-const flags = {
- const: ts.NodeFlags.Const,
-} as const;
-
-export interface Params {
- declarations: readonly ts.VariableDeclaration[];
- flag: keyof typeof flags;
-}
-
-export interface Factory {
- create: (params: Params) => ts.VariableDeclarationList;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.VariableDeclarationList => {
- const node = factory.createVariableDeclarationList(params.declarations, flags[params.flag]);
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/VariableStatement.ts b/src/internal/TsGenerator/factory/VariableStatement.ts
deleted file mode 100644
index b5a2870a..00000000
--- a/src/internal/TsGenerator/factory/VariableStatement.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import ts from "typescript";
-import { generateComment } from "./utils";
-
-export interface Params {
- comment?: string;
- deprecated?: boolean;
- modifiers?: ts.Modifier[];
- declarationList: ts.VariableDeclarationList | ts.VariableDeclaration[];
-}
-
-export interface Factory {
- create: (params: Params) => ts.VariableStatement;
-}
-
-export const create =
- ({ factory }: Pick): Factory["create"] =>
- (params: Params): ts.VariableStatement => {
- const node = factory.createVariableStatement(params.modifiers, params.declarationList);
- if (params.comment) {
- const comment = generateComment(params.comment, params.deprecated);
- return ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment.value, comment.hasTrailingNewLine);
- }
- return node;
- };
-
-export const make = (context: Pick): Factory => {
- return {
- create: create(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/index.ts b/src/internal/TsGenerator/factory/index.ts
deleted file mode 100644
index 103b3eba..00000000
--- a/src/internal/TsGenerator/factory/index.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import ts from "typescript";
-
-import * as ArrowFunction from "./ArrowFunction";
-import * as BinaryExpression from "./BinaryExpression";
-import * as Block from "./Block";
-import * as CallExpression from "./CallExpression";
-import * as ClassDeclaration from "./ClassDeclaration";
-import * as ConstructorDeclaration from "./ConstructorDeclaration";
-import * as ElementAccessExpression from "./ElementAccessExpression";
-import * as ExpressionStatement from "./ExpressionStatement";
-import * as FunctionTypeNode from "./FunctionTypeNode";
-import * as Identifier from "./Identifier";
-import * as IndexedAccessTypeNode from "./IndexedAccessTypeNode";
-import * as IndexSignatureDeclaration from "./IndexSignatureDeclaration";
-import * as InterfaceDeclaration from "./InterfaceDeclaration";
-import * as IntersectionTypeNode from "./IntersectionTypeNode";
-import * as LiteralTypeNode from "./LiteralTypeNode";
-import * as MethodDeclaration from "./MethodDeclaration";
-import * as Namespace from "./Namespace";
-import * as NoSubstitutionTemplateLiteral from "./NoSubstitutionTemplateLiteral";
-import * as ObjectLiteralExpression from "./ObjectLiteralExpression";
-import * as ParameterDeclaration from "./ParameterDeclaration";
-import * as PropertyAccessExpression from "./PropertyAccessExpression";
-import * as PropertyAssignment from "./PropertyAssignment";
-import * as PropertyDeclaration from "./PropertyDeclaration";
-import * as PropertySignature from "./PropertySignature";
-import * as RegularExpressionLiteral from "./RegularExpressionLiteral";
-import * as ReturnStatement from "./ReturnStatement";
-import * as ShorthandPropertyAssignment from "./ShorthandPropertyAssignment";
-import * as StringLiteral from "./StringLiteral";
-import * as TemplateExpression from "./TemplateExpression";
-import * as TemplateHead from "./TemplateHead";
-import * as TemplateMiddle from "./TemplateMiddle";
-import * as TemplateSpan from "./TemplateSpan";
-import * as TemplateTail from "./TemplateTail";
-import * as TypeAliasDeclaration from "./TypeAliasDeclaration";
-import * as TypeLiteralNode from "./TypeLiteralNode";
-import * as TypeNode from "./TypeNode";
-import * as TypeOperatorNode from "./TypeOperatorNode";
-import * as TypeParameterDeclaration from "./TypeParameterDeclaration";
-import * as TypeReferenceNode from "./TypeReferenceNode";
-import * as UnionTypeNode from "./UnionTypeNode";
-import * as VariableDeclaration from "./VariableDeclaration";
-import * as VariableDeclarationList from "./VariableDeclarationList";
-import * as VariableStatement from "./VariableStatement";
-export interface Type {
- ArrowFunction: ArrowFunction.Factory;
- Block: Block.Factory;
- ClassDeclaration: ClassDeclaration.Factory;
- InterfaceDeclaration: InterfaceDeclaration.Factory;
- ParameterDeclaration: ParameterDeclaration.Factory;
- IndexedAccessTypeNode: IndexedAccessTypeNode.Factory;
- MethodDeclaration: MethodDeclaration.Factory;
- TypeOperatorNode: TypeOperatorNode.Factory;
- Namespace: Namespace.Factory;
- PropertySignature: PropertySignature.Factory;
- PropertyDeclaration: PropertyDeclaration.Factory;
- RegularExpressionLiteral: RegularExpressionLiteral.Factory;
- TypeAliasDeclaration: TypeAliasDeclaration.Factory;
- TypeNode: TypeNode.Factory;
- LiteralTypeNode: LiteralTypeNode.Factory;
- IndexSignatureDeclaration: IndexSignatureDeclaration.Factory;
- UnionTypeNode: UnionTypeNode.Factory;
- IntersectionTypeNode: IntersectionTypeNode.Factory;
- TypeReferenceNode: TypeReferenceNode.Factory;
- TypeParameterDeclaration: TypeParameterDeclaration.Factory;
- ConstructorDeclaration: ConstructorDeclaration.Factory;
- ReturnStatement: ReturnStatement.Factory;
- VariableDeclaration: VariableDeclaration.Factory;
- VariableDeclarationList: VariableDeclarationList.Factory;
- VariableStatement: VariableStatement.Factory;
- BinaryExpression: BinaryExpression.Factory;
- PropertyAccessExpression: PropertyAccessExpression.Factory;
- NoSubstitutionTemplateLiteral: NoSubstitutionTemplateLiteral.Factory;
- TemplateSpan: TemplateSpan.Factory;
- TemplateExpression: TemplateExpression.Factory;
- TemplateHead: TemplateHead.Factory;
- TemplateMiddle: TemplateMiddle.Factory;
- TemplateTail: TemplateTail.Factory;
- Identifier: Identifier.Factory;
- PropertyAssignment: PropertyAssignment.Factory;
- ObjectLiteralExpression: ObjectLiteralExpression.Factory;
- ElementAccessExpression: ElementAccessExpression.Factory;
- ExpressionStatement: ExpressionStatement.Factory;
- CallExpression: CallExpression.Factory;
- StringLiteral: StringLiteral.Factory;
- FunctionTypeNode: FunctionTypeNode.Factory;
- TypeLiteralNode: TypeLiteralNode.Factory;
- ShorthandPropertyAssignment: ShorthandPropertyAssignment.Factory;
-}
-
-export const create = (): Type => {
- const context: Pick = {
- factory: ts.factory,
- };
- return {
- ArrowFunction: ArrowFunction.make(context),
- Block: Block.make(context),
- ClassDeclaration: ClassDeclaration.make(context),
- ParameterDeclaration: ParameterDeclaration.make(context),
- InterfaceDeclaration: InterfaceDeclaration.make(context),
- IndexedAccessTypeNode: IndexedAccessTypeNode.make(context),
- Namespace: Namespace.make(context),
- PropertySignature: PropertySignature.make(context),
- PropertyDeclaration: PropertyDeclaration.make(context),
- TypeAliasDeclaration: TypeAliasDeclaration.make(context),
- TypeNode: TypeNode.make(context),
- LiteralTypeNode: LiteralTypeNode.make(context),
- IndexSignatureDeclaration: IndexSignatureDeclaration.make(context),
- UnionTypeNode: UnionTypeNode.make(context),
- IntersectionTypeNode: IntersectionTypeNode.make(context),
- TypeReferenceNode: TypeReferenceNode.make(context),
- TypeParameterDeclaration: TypeParameterDeclaration.make(context),
- TypeOperatorNode: TypeOperatorNode.make(context),
- MethodDeclaration: MethodDeclaration.make(context),
- ConstructorDeclaration: ConstructorDeclaration.make(context),
- ReturnStatement: ReturnStatement.make(context),
- VariableDeclaration: VariableDeclaration.make(context),
- VariableDeclarationList: VariableDeclarationList.make(context),
- VariableStatement: VariableStatement.make(context),
- BinaryExpression: BinaryExpression.make(context),
- PropertyAccessExpression: PropertyAccessExpression.make(context),
- RegularExpressionLiteral: RegularExpressionLiteral.make(context),
- NoSubstitutionTemplateLiteral: NoSubstitutionTemplateLiteral.make(context),
- TemplateSpan: TemplateSpan.make(context),
- TemplateExpression: TemplateExpression.make(context),
- TemplateHead: TemplateHead.make(context),
- TemplateMiddle: TemplateMiddle.make(context),
- TemplateTail: TemplateTail.make(context),
- Identifier: Identifier.make(context),
- ShorthandPropertyAssignment: ShorthandPropertyAssignment.make(context),
- PropertyAssignment: PropertyAssignment.make(context),
- ObjectLiteralExpression: ObjectLiteralExpression.make(context),
- ElementAccessExpression: ElementAccessExpression.make(context),
- ExpressionStatement: ExpressionStatement.make(context),
- CallExpression: CallExpression.make(context),
- StringLiteral: StringLiteral.make(context),
- FunctionTypeNode: FunctionTypeNode.make(context),
- TypeLiteralNode: TypeLiteralNode.make(context),
- };
-};
diff --git a/src/internal/TsGenerator/factory/utils.ts b/src/internal/TsGenerator/factory/utils.ts
deleted file mode 100644
index 21d0b485..00000000
--- a/src/internal/TsGenerator/factory/utils.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { EOL } from "node:os";
-
-export interface Comment {
- hasTrailingNewLine: boolean;
- value: string;
-}
-
-export const isOnlyAlphabetText = (text: string): boolean => {
- return new RegExp(/^[a-zA-Z]+$/).test(text);
-};
-
-export const escapeIdentiferText = (text: string): string => {
- return text.replace(/-/g, "_");
-};
-
-export const generateComment = (comment: string, deprecated?: boolean): Comment => {
- const excapedComment = comment
- .replace(/\*\//, "\\*\\\\/") // */ -> \*\/
- .replace(/\/\*/, "/\\\\*") // /* -> \/\*
- .replace(/\*\/\*/, "\\*\\/\\*"); // */* -> \*\/\*
- const splitComments = deprecated ? ["@deprecated"].concat(excapedComment.split(/\r?\n/)) : excapedComment.split(/\r?\n/);
- const comments = splitComments.filter((comment, index) => {
- if (index === splitComments.length - 1 && comment === "") {
- return false;
- }
- return true;
- });
- if (comments.length === 1) {
- return {
- hasTrailingNewLine: true,
- value: `* ${comments.join("")} `,
- };
- }
- return {
- hasTrailingNewLine: true,
- value: `*${EOL}${comments.map(comment => ` * ${comment}`).join(EOL)}${EOL} `,
- };
-};
diff --git a/src/internal/TsGenerator/index.ts b/src/internal/TsGenerator/index.ts
index 59b30474..63ae40b2 100644
--- a/src/internal/TsGenerator/index.ts
+++ b/src/internal/TsGenerator/index.ts
@@ -1,27 +1,9 @@
-import ts from "typescript";
-
-import { DevelopmentError } from "../Exception";
import * as Factory from "./factory";
-import { type CreateFunction, traverse } from "./traverse";
-
-export * as Utils from "./utils";
-export { type CreateFunction, Factory };
+export { Factory };
-export type TransformerFactory = ts.TransformerFactory;
-
-export const convertAstToTypeScriptCode = (sourceFile: ts.SourceFile): string => {
- const printer = ts.createPrinter(); // AST -> TypeScriptに変換
- return printer.printFile(sourceFile);
-};
+export type CreateFunction = () => string[];
export const generate = (createFunction: CreateFunction): string => {
- const source = ts.createSourceFile("", "", ts.ScriptTarget.ESNext);
- const transformers: TransformerFactory[] = [traverse(createFunction)];
- const result = ts.transform(source, transformers);
- result.dispose();
- if (result.transformed.length > 1) {
- throw new DevelopmentError("Invalid length");
- }
- return convertAstToTypeScriptCode(result.transformed[0]);
+ return `${createFunction().join("\n")}\n`;
};
diff --git a/src/internal/TsGenerator/traverse.ts b/src/internal/TsGenerator/traverse.ts
deleted file mode 100644
index be538a11..00000000
--- a/src/internal/TsGenerator/traverse.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import ts from "typescript";
-
-export type CreateFunction = (context: Pick) => ts.Statement[];
-
-export const traverse =
- (create: CreateFunction) =>
- (context: Pick): ts.Transformer =>
- (rootNode: T): T => {
- const visit = (node: ts.Node): ts.Node => {
- if (!ts.isSourceFile(node)) {
- return node;
- }
- return context.factory.updateSourceFile(
- node,
- create(context),
- node.isDeclarationFile,
- node.referencedFiles,
- node.typeReferenceDirectives,
- node.hasNoDefaultLib,
- node.libReferenceDirectives,
- );
- };
- return ts.visitNode(rootNode, visit) as T;
- };
diff --git a/src/internal/TsGenerator/utils.ts b/src/internal/TsGenerator/utils.ts
deleted file mode 100644
index 1e5549a7..00000000
--- a/src/internal/TsGenerator/utils.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import ts from "typescript";
-
-import type { CodeGenerator } from "../../types";
-
-export const stringToStatements = (code: string): ts.Statement[] => {
- const source = ts.createSourceFile("", code, ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
- return Array.from(source.statements);
-};
-
-export const convertIntermediateCodes = (intermediateCodes: CodeGenerator.IntermediateCode[]): ts.Statement[] => {
- return intermediateCodes.reduce((result, intermediateCode) => {
- if (typeof intermediateCode === "string") {
- return [...result, ...stringToStatements(intermediateCode)];
- }
- return result.concat(intermediateCode);
- }, []);
-};
diff --git a/src/typedef/CodeGenerator.ts b/src/typedef/CodeGenerator.ts
index 866182c3..5a68ae73 100644
--- a/src/typedef/CodeGenerator.ts
+++ b/src/typedef/CodeGenerator.ts
@@ -1,5 +1,3 @@
-import type ts from "typescript";
-
import type * as OpenApi from "./OpenApi";
export type PickedParameter = Pick;
@@ -56,7 +54,7 @@ export interface Params {
/**
* Used to further transform the code created by the specified Generator Template.
*/
-export type IntermediateCode = string | ts.Statement;
+export type IntermediateCode = string;
export type GenerateFunction = (payload: Params[], option?: Option) => IntermediateCode[];
diff --git a/test/__tests__/class/__snapshots__/cloudflare-test.ts.snap b/test/__tests__/class/__snapshots__/cloudflare-test.ts.snap
index 439c032b..7634c572 100644
--- a/test/__tests__/class/__snapshots__/cloudflare-test.ts.snap
+++ b/test/__tests__/class/__snapshots__/cloudflare-test.ts.snap
@@ -54817,12 +54817,12 @@ export class Client {
Accept: "application/json"
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return this.apiClient.request({
httpMethod: "PUT",
url,
@@ -54876,12 +54876,12 @@ export class Client {
"CF-WORKER-MAIN-MODULE-PART": params.parameter["CF-WORKER-MAIN-MODULE-PART"]
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return this.apiClient.request({
httpMethod: "PUT",
url,
@@ -55209,12 +55209,12 @@ export class Client {
Accept: "application/json"
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
const queryParameters: QueryParameters = {
rollback_to: { value: params.parameter.rollback_to, explode: false }
};
@@ -55257,12 +55257,12 @@ export class Client {
"CF-WORKER-MAIN-MODULE-PART": params.parameter["CF-WORKER-MAIN-MODULE-PART"]
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return this.apiClient.request({
httpMethod: "PUT",
url,
@@ -55455,12 +55455,12 @@ export class Client {
"CF-WORKER-MAIN-MODULE-PART": params.parameter["CF-WORKER-MAIN-MODULE-PART"]
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return this.apiClient.request({
httpMethod: "PUT",
url,
diff --git a/test/__tests__/class/__snapshots__/typedef-with-template-test.ts.snap b/test/__tests__/class/__snapshots__/typedef-with-template-test.ts.snap
index 9bf246e4..de6c1167 100644
--- a/test/__tests__/class/__snapshots__/typedef-with-template-test.ts.snap
+++ b/test/__tests__/class/__snapshots__/typedef-with-template-test.ts.snap
@@ -1504,13 +1504,13 @@ export class Client {
Accept: "application/json"
};
const requestEncodings: Record> = {
- "application/x-www-form-urlencoded": {
- "color": {
- "style": "form",
- "explode": false
- }
- }
-};
+ "application/x-www-form-urlencoded": {
+ "color": {
+ "style": "form",
+ "explode": false
+ }
+ }
+ };
return this.apiClient.request({
httpMethod: "POST",
url,
@@ -1526,19 +1526,19 @@ export class Client {
Accept: "application/json"
};
const requestEncodings: Record> = {
- "application/x-www-form-urlencoded": {
- "color": {
- "style": "form",
- "explode": false
- }
- },
- "application/json": {
- "color": {
- "style": "form",
- "explode": false
- }
- }
-};
+ "application/x-www-form-urlencoded": {
+ "color": {
+ "style": "form",
+ "explode": false
+ }
+ },
+ "application/json": {
+ "color": {
+ "style": "form",
+ "explode": false
+ }
+ }
+ };
return this.apiClient.request({
httpMethod: "POST",
url,
diff --git a/test/__tests__/currying-functional/__snapshots__/coudflare-test.ts.snap b/test/__tests__/currying-functional/__snapshots__/coudflare-test.ts.snap
index 3227cc62..c7df42e5 100644
--- a/test/__tests__/currying-functional/__snapshots__/coudflare-test.ts.snap
+++ b/test/__tests__/currying-functional/__snapshots__/coudflare-test.ts.snap
@@ -54803,12 +54803,12 @@ export const namespace$worker$script$upload$worker$module = (apiC
Accept: "application/json"
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return apiClient.request({
httpMethod: "PUT",
uri,
@@ -54862,12 +54862,12 @@ export const namespace$worker$put$script$content = (apiClient: Ap
"CF-WORKER-MAIN-MODULE-PART": params.parameter["CF-WORKER-MAIN-MODULE-PART"]
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return apiClient.request({
httpMethod: "PUT",
uri,
@@ -55195,12 +55195,12 @@ export const worker$script$upload$worker$module = (apiClient: Api
Accept: "application/json"
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
const queryParameters: QueryParameters = {
rollback_to: { value: params.parameter.rollback_to, explode: false }
};
@@ -55243,12 +55243,12 @@ export const worker$script$put$content = (apiClient: ApiClient> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return apiClient.request({
httpMethod: "PUT",
uri,
@@ -55441,12 +55441,12 @@ export const worker$environment$put$script$content = (apiClient:
"CF-WORKER-MAIN-MODULE-PART": params.parameter["CF-WORKER-MAIN-MODULE-PART"]
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return apiClient.request({
httpMethod: "PUT",
uri,
diff --git a/test/__tests__/functional/__snapshots__/coudflare-test.ts.snap b/test/__tests__/functional/__snapshots__/coudflare-test.ts.snap
index 37f2cb3f..3be4f1d2 100644
--- a/test/__tests__/functional/__snapshots__/coudflare-test.ts.snap
+++ b/test/__tests__/functional/__snapshots__/coudflare-test.ts.snap
@@ -54806,12 +54806,12 @@ export const createClient = (apiClient: ApiClient,
Accept: "application/json"
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return apiClient.request({
httpMethod: "PUT",
url,
@@ -54865,12 +54865,12 @@ export const createClient = (apiClient: ApiClient,
"CF-WORKER-MAIN-MODULE-PART": params.parameter["CF-WORKER-MAIN-MODULE-PART"]
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return apiClient.request({
httpMethod: "PUT",
url,
@@ -55198,12 +55198,12 @@ export const createClient = (apiClient: ApiClient,
Accept: "application/json"
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
const queryParameters: QueryParameters = {
rollback_to: { value: params.parameter.rollback_to, explode: false }
};
@@ -55246,12 +55246,12 @@ export const createClient = (apiClient: ApiClient,
"CF-WORKER-MAIN-MODULE-PART": params.parameter["CF-WORKER-MAIN-MODULE-PART"]
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return apiClient.request({
httpMethod: "PUT",
url,
@@ -55444,12 +55444,12 @@ export const createClient = (apiClient: ApiClient,
"CF-WORKER-MAIN-MODULE-PART": params.parameter["CF-WORKER-MAIN-MODULE-PART"]
};
const requestEncodings: Record> = {
- "multipart/form-data": {
- "": {
- "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
- }
- }
-};
+ "multipart/form-data": {
+ "": {
+ "contentType": "application/javascript+module, text/javascript+module, application/javascript, text/javascript, application/wasm, text/plain, application/octet-stream"
+ }
+ }
+ };
return apiClient.request({
httpMethod: "PUT",
url,
diff --git a/test/__tests__/functional/__snapshots__/typedef-with-template-test.ts.snap b/test/__tests__/functional/__snapshots__/typedef-with-template-test.ts.snap
index 3eaff708..1b7d500c 100644
--- a/test/__tests__/functional/__snapshots__/typedef-with-template-test.ts.snap
+++ b/test/__tests__/functional/__snapshots__/typedef-with-template-test.ts.snap
@@ -1515,13 +1515,13 @@ export const createClient = (apiClient: ApiClient,
Accept: "application/json"
};
const requestEncodings: Record> = {
- "application/x-www-form-urlencoded": {
- "color": {
- "style": "form",
- "explode": false
- }
- }
-};
+ "application/x-www-form-urlencoded": {
+ "color": {
+ "style": "form",
+ "explode": false
+ }
+ }
+ };
return apiClient.request({
httpMethod: "POST",
url,
@@ -1537,19 +1537,19 @@ export const createClient = (apiClient: ApiClient,
Accept: "application/json"
};
const requestEncodings: Record> = {
- "application/x-www-form-urlencoded": {
- "color": {
- "style": "form",
- "explode": false
- }
- },
- "application/json": {
- "color": {
- "style": "form",
- "explode": false
- }
- }
-};
+ "application/x-www-form-urlencoded": {
+ "color": {
+ "style": "form",
+ "explode": false
+ }
+ },
+ "application/json": {
+ "color": {
+ "style": "form",
+ "explode": false
+ }
+ }
+ };
return apiClient.request({
httpMethod: "POST",
url,
diff --git a/test/__tests__/functional/unknown-schema-domain-test copy.ts b/test/__tests__/functional/unknown-schema-domain-test copy.ts
new file mode 100644
index 00000000..7eba0731
--- /dev/null
+++ b/test/__tests__/functional/unknown-schema-domain-test copy.ts
@@ -0,0 +1,12 @@
+import * as fs from "node:fs";
+import { describe, expect, test } from "vitest";
+
+import * as Utils from "../../utils";
+
+describe("Unknown", () => {
+ test("client.ts", () => {
+ const generateCode = fs.readFileSync("test/code/functional/unknown.schema.domain/client.ts", { encoding: "utf-8" });
+ const text = Utils.replaceVersionInfo(generateCode);
+ expect(text).toMatchSnapshot();
+ });
+});