Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cli/examples/openapi-codegen.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineConfig } from "../lib/index.js";
import { defineConfig } from "../lib/index";

export default defineConfig({
withFile: {
Expand Down
4 changes: 2 additions & 2 deletions cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import { Cli } from "clipanion";

import { GenerateCommand } from "./commands/GenerateCommand.js";
import { InitCommand } from "./commands/InitCommand.js";
import { GenerateCommand } from "./commands/GenerateCommand";
import { InitCommand } from "./commands/InitCommand";
import { readFileSync } from "fs";
import { join, dirname } from "path";
import { fileURLToPath } from "url";
Expand Down
4 changes: 2 additions & 2 deletions cli/src/commands/GenerateCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { fileURLToPath } from "url";
import slash from "slash";

import { Config, FromOptions, Namespace } from "../types";
import { getOpenAPISourceFile } from "../core/getOpenAPISourceFile.js";
import { parseOpenAPISourceFile } from "../core/parseOpenAPISourceFile.js";
import { getOpenAPISourceFile } from "../core/getOpenAPISourceFile";
import { parseOpenAPISourceFile } from "../core/parseOpenAPISourceFile";
import { getGithubToken } from "../utils/getGithubToken";
import { resolveGithubPullRequest } from "../utils/resolveGithubPullRequest";

Expand Down
8 changes: 4 additions & 4 deletions cli/src/commands/InitCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import type { FileOptions, FromOptions, UrlOptions, Plugin } from "../types";
import {
generateConfigProperty,
getImports,
} from "../core/generateConfigProperty.js";
import { getText } from "../utils/getText.js";
import emptyConfig from "../templates/emptyConfig.js";
import { updateConfig } from "../core/updateConfig.js";
} from "../core/generateConfigProperty";
import { getText } from "../utils/getText";
import emptyConfig from "../templates/emptyConfig";
import { updateConfig } from "../core/updateConfig";
import { handlePromptCancel } from "../utils/handlePromptCancel";

export class InitCommand extends Command {
Expand Down
11 changes: 1 addition & 10 deletions cli/src/core/updateConfig.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ts from "typescript";
import type { Import } from "../types";
import { getText } from "../utils/getText";

const { factory: f } = ts;

Expand Down Expand Up @@ -183,13 +184,3 @@ function createImportStatements(imports: Map<string, string[]>) {
)
.join("\n");
}

function getText(expression: ts.Expression) {
try {
return (
((expression as unknown as Record<string, unknown>).text as string) ?? ""
);
} catch {
return "";
}
}
14 changes: 6 additions & 8 deletions cli/src/utils/getText.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import ts from "typescript";
import { isStringLiteral } from "typescript/ast";
import type { Expression } from "typescript/ast";

export function getText(expression: ts.Expression) {
try {
return (
((expression as unknown as Record<string, unknown>).text as string) ?? ""
);
} catch {
return "";
export function getText(expression: Expression) {
if (!isStringLiteral(expression)) {
throw new TypeError("Expected a string literal module specifier");
}
return expression.text;
}
6 changes: 4 additions & 2 deletions plugins/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "@openapi-codegen/typescript",
"version": "11.3.0",
"description": "OpenAPI Codegen typescript generators",
"type": "module",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"repository": {
Expand All @@ -12,7 +13,7 @@
"access": "public"
},
"scripts": {
"build": "pnpm --workspace-root tsc -p plugins/typescript/tsconfig.package.json",
"build": "pnpm --workspace-root tsc --emitDeclarationOnly --declaration -p plugins/typescript/tsconfig.package.json && tsup src/index.ts --outDir lib --format esm",
"prepublishOnly": "pnpm build"
},
"files": [
Expand All @@ -38,6 +39,7 @@
"devDependencies": {
"@types/lodash": "^4.17.25",
"@types/pluralize": "^0.0.33",
"@types/qs": "^6.15.1"
"@types/qs": "^6.15.1",
"tsup": "^8.5.1"
}
}
7 changes: 5 additions & 2 deletions plugins/typescript/src/core/analyzeImportUsage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ts from "typescript";
import * as ts from "typescript/ast";

/**
* Determines if a node represents a value usage context
Expand Down Expand Up @@ -68,7 +68,10 @@ export const analyzeImportUsage = (
return !(usages.type && usages.value);
}

return !ts.forEachChild(node, (child) => !checkNode(child as ts.Node));
return !(
typeof node.forEachChild === "function" &&
node.forEachChild((child) => !checkNode(child))
);
};

nodes.every(checkNode);
Expand Down
2 changes: 1 addition & 1 deletion plugins/typescript/src/core/camelizedPathParams.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { camel } from "case";
import { camel } from "../utils/case-interop";

/**
* Transform url params case to camel.
Expand Down
36 changes: 21 additions & 15 deletions plugins/typescript/src/core/createNamedImport.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { describe, it, expect } from "vitest";
import { createNamedImport, shouldUseTypeImport } from "./createNamedImport";
import { analyzeImportUsage } from "./analyzeImportUsage";
import { factory as f } from "typescript";
import * as ts from "typescript";
import * as f from "typescript/ast/factory";
import * as ts from "typescript/ast";

// Helper function to set parent references in AST nodes
const setParentReferences = (node: ts.Node): ts.Node => {
Expand All @@ -22,23 +22,17 @@ const setParentReferences = (node: ts.Node): ts.Node => {
describe("createNamedImport", () => {
it("should create a regular import when isTypeOnly is false", () => {
const result = createNamedImport("MyType", "./types", false);
expect(
(result.importClause as unknown as Record<string, unknown>)?.isTypeOnly
).toBe(false);
expect(result.importClause?.phaseModifier).toBeUndefined();
});

it("should create a type-only import when isTypeOnly is true", () => {
const result = createNamedImport("MyType", "./types", true);
expect(
(result.importClause as unknown as Record<string, unknown>)?.isTypeOnly
).toBe(true);
expect(result.importClause?.phaseModifier).toBe(ts.SyntaxKind.TypeKeyword);
});

it("should handle array of imports", () => {
const result = createNamedImport(["Type1", "Type2"], "./types", true);
expect(
(result.importClause as unknown as Record<string, unknown>)?.isTypeOnly
).toBe(true);
expect(result.importClause?.phaseModifier).toBe(ts.SyntaxKind.TypeKeyword);
expect(result.importClause?.namedBindings).toBeDefined();
});
});
Expand All @@ -63,7 +57,7 @@ describe("analyzeImportUsage", () => {
undefined,
f.createIdentifier("MyType"),
undefined,
f.createTypeReferenceNode(f.createIdentifier("User"), undefined)
f.createTypeReferenceNode(f.createIdentifier("User"))
)
),
];
Expand All @@ -74,7 +68,13 @@ describe("analyzeImportUsage", () => {
it("should detect value usage", () => {
const nodes = [
setParentReferences(
f.createCallExpression(f.createIdentifier("fetchData"), undefined, [])
f.createCallExpression(
f.createIdentifier("fetchData"),
undefined,
undefined,
[],
0
)
),
];

Expand All @@ -88,11 +88,17 @@ describe("analyzeImportUsage", () => {
undefined,
f.createIdentifier("MyType"),
undefined,
f.createTypeReferenceNode(f.createIdentifier("User"), undefined)
f.createTypeReferenceNode(f.createIdentifier("User"))
)
),
setParentReferences(
f.createCallExpression(f.createIdentifier("User"), undefined, [])
f.createCallExpression(
f.createIdentifier("User"),
undefined,
undefined,
[],
0
)
),
];

Expand Down
13 changes: 7 additions & 6 deletions plugins/typescript/src/core/createNamedImport.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { factory as f } from "typescript";
import type * as ts from "typescript";
import * as f from "typescript/ast/factory";
import { SyntaxKind } from "typescript/ast";
import type * as ts from "typescript/ast";
import { analyzeImportUsage } from "./analyzeImportUsage";

/**
Expand All @@ -19,15 +20,15 @@ export const createNamedImport = (
return f.createImportDeclaration(
undefined,
f.createImportClause(
isTypeOnly,
isTypeOnly ? SyntaxKind.TypeKeyword : undefined,
undefined,
f.createNamedImports(
fnNames.map((name) =>
f.createImportSpecifier(false, undefined, f.createIdentifier(name))
)
)
),
f.createStringLiteral(filename),
f.createStringLiteral(filename, 0),
undefined
);
};
Expand Down Expand Up @@ -81,8 +82,8 @@ export const createNamedImportWithTypes = (

return f.createImportDeclaration(
undefined,
f.createImportClause(false, undefined, f.createNamedImports(allImports)),
f.createStringLiteral(filename),
f.createImportClause(undefined, undefined, f.createNamedImports(allImports)),
f.createStringLiteral(filename, 0),
undefined
);
};
7 changes: 4 additions & 3 deletions plugins/typescript/src/core/createNamespaceImport.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { factory as f } from "typescript";
import * as f from "typescript/ast/factory";
import { SyntaxKind } from "typescript/ast";

/**
* Helper to create namespace import.
Expand All @@ -11,10 +12,10 @@ export const createNamespaceImport = (namespace: string, filename: string) =>
f.createImportDeclaration(
undefined,
f.createImportClause(
true,
SyntaxKind.TypeKeyword,
undefined,
f.createNamespaceImport(f.createIdentifier(namespace))
),
f.createStringLiteral(filename),
f.createStringLiteral(filename, 0),
undefined
);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { OperationObject } from "openapi3-ts/oas30";
import ts, { factory as f } from "typescript";
import ts, { factory as f } from "../typescript";
import { camelizedPathParams } from "./camelizedPathParams";

/**
Expand Down
4 changes: 2 additions & 2 deletions plugins/typescript/src/core/createOperationQueryFnNodes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { camelCase } from "lodash";
import { camelCase } from "../utils/lodash-interop";
import { OperationObject } from "openapi3-ts/oas30";
import ts, { factory as f } from "typescript";
import ts, { factory as f } from "../typescript";
import { camelizedPathParams } from "./camelizedPathParams";

/**
Expand Down
2 changes: 1 addition & 1 deletion plugins/typescript/src/core/createWatermark.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InfoObject } from "openapi3-ts/oas30";
import { factory as f } from "typescript";
import { factory as f } from "../typescript";

/**
* Generate a JSDoc comment with the generated watermark and `info.version`
Expand Down
7 changes: 4 additions & 3 deletions plugins/typescript/src/core/getDataResponseType.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import ts, { factory as f } from "typescript";
import * as ts from "typescript/ast";
import * as f from "typescript/ast/factory";
import {
ComponentsObject,
isReferenceObject,
ReferenceObject,
ResponseObject,
ResponsesObject,
} from "openapi3-ts/oas30";
import { uniqBy } from "lodash";
import { pascal } from "case";
import { uniqBy } from "../utils/lodash-interop";
import { pascal } from "../utils/case-interop";

import { findCompatibleMediaType } from "./findCompatibleMediaType";
import { getType } from "./schemaToTypeAliasDeclaration";
Expand Down
4 changes: 2 additions & 2 deletions plugins/typescript/src/core/getErrorResponseType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ts, { factory as f } from "typescript";
import ts, { factory as f } from "../typescript";
import {
ComponentsObject,
isReferenceObject,
Expand All @@ -9,7 +9,7 @@ import {

import { findCompatibleMediaType } from "./findCompatibleMediaType";
import { getType } from "./schemaToTypeAliasDeclaration";
import { pascal } from "case";
import { pascal } from "../utils/case-interop";

export const clientErrorStatus = "ClientErrorStatus";
export const serverErrorStatus = "ServerErrorStatus";
Expand Down
Loading