Skip to content

Commit

Permalink
feat: find and use import alias
Browse files Browse the repository at this point in the history
  • Loading branch information
mnahkies committed Apr 21, 2024
1 parent d8c47c9 commit 54335e8
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 12 deletions.
2 changes: 1 addition & 1 deletion packages/openapi-code-generator/src/core/file-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function isRemote(location: string): boolean {

export type CompilerOptions = Pick<
TsCompilerOptions,
"exactOptionalPropertyTypes"
"exactOptionalPropertyTypes" | "paths"
>

export function loadTsConfigCompilerOptions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const tsconfigSchema = z.object({
noPropertyAccessFromIndexSignature: z.boolean(),
allowUnusedLabels: z.boolean(),
allowUnreachableCode: z.boolean(),
paths: z.record(z.array(z.string())),
})
.partial(),
})
4 changes: 4 additions & 0 deletions packages/openapi-code-generator/src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ export function isDefined<T>(it: T | undefined): it is T {
return it !== undefined
}

export function isTruthy<T>(it: T | undefined | null | "" | 0): it is T {
return Boolean(it)
}

export function hasSingleElement<T>(it: T[]): it is [T] {
return it.length === 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ export class ImportBuilder {
private readonly imports: Record<string, Set<string>> = {}
private readonly importAll: Record<string, string> = {}

constructor(private readonly unit?: {filename: string}) {}
constructor(
private readonly unit?: {filename: string},
private readonly importAlias?: string,
) {}

from(from: string) {
return {
Expand Down Expand Up @@ -68,7 +71,7 @@ export class ImportBuilder {
}

private add(name: string, from: string, isAll: boolean): void {
from = ImportBuilder.normalizeFrom(from, this.unit?.filename)
from = this.normalizeFrom(from, this.unit?.filename)
const imports = (this.imports[from] =
this.imports[from] ?? new Set<string>())

Expand All @@ -79,13 +82,17 @@ export class ImportBuilder {
}
}

public static normalizeFrom(from: string, filename?: string) {
public normalizeFrom(from: string, filename?: string) {
if (from.endsWith(".ts")) {
from = from.substring(0, from.length - ".ts".length)
}

// TODO: does this work on windows?
if (filename && from.startsWith("./")) {
if (this.importAlias) {
return this.importAlias + from.split(path.sep).slice(1).join(path.sep)
}

const unitDirname = path.dirname(filename)
const fromDirname = path.dirname(from)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,20 @@ import {
SyntaxKind,
VariableDeclarationKind,
} from "ts-morph"
import {CompilerOptions} from "../../core/file-loader"
import {Input} from "../../core/input"
import {
IRModelObject,
IROperation,
IRParameter,
} from "../../core/openapi-types-normalized"
import {HttpMethod, isDefined, isHttpMethod, titleCase} from "../../core/utils"
import {
HttpMethod,
isDefined,
isHttpMethod,
isTruthy,
titleCase,
} from "../../core/utils"
import {OpenapiGeneratorConfig} from "../../templates.types"
import {CompilationUnit, ICompilable} from "../common/compilation-units"
import {ImportBuilder} from "../common/import-builder"
Expand Down Expand Up @@ -315,6 +322,7 @@ ${routes.join("\n\n")}
export class NextJSAppRouterBuilder implements ICompilable {
constructor(
public readonly filename: string,
private readonly imports: ImportBuilder,
private readonly companionFilename: string,
private readonly sourceFile: SourceFile,
) {}
Expand Down Expand Up @@ -388,7 +396,7 @@ export class NextJSAppRouterBuilder implements ICompilable {
toCompilationUnit(): CompilationUnit {
// Reconcile imports - attempt to find an existing one and replace it with correct one
const imports = this.sourceFile.getImportDeclarations()
const from = ImportBuilder.normalizeFrom(
const from = this.imports.normalizeFrom(
"./" + this.companionFilename,
"./" + this.filename,
)
Expand All @@ -412,25 +420,39 @@ export class NextJSAppRouterBuilder implements ICompilable {

return new CompilationUnit(
this.filename,
new ImportBuilder(),
this.imports,
this.toString(),
false,
)
}
}

function findImportAlias(dest: string, compilerOptions: CompilerOptions) {
const relative = "./" + path.relative(process.cwd(), dest) + "/*"

const alias = Object.entries(compilerOptions.paths || {}).find(([, paths]) =>
paths.includes(relative),
)

return alias ? alias[0].replace("*", "") : undefined
}

export async function generateTypescriptNextJS(
config: OpenapiGeneratorConfig,
): Promise<void> {
const input = config.input

const importAlias = findImportAlias(config.dest, config.compilerOptions)

const subDirectory = process.env["OPENAPI_INTEGRATION_TESTS"]
? path.basename(config.input.loader.entryPointKey)
: ""

const appDirectory = ["./app", subDirectory].filter(isDefined).join(path.sep)
const generatedDirectory = ["./generated", subDirectory]
.filter(isDefined)
const appDirectory = [".", "app", subDirectory]
.filter(isTruthy)
.join(path.sep)
const generatedDirectory = [".", "generated", subDirectory]
.filter(isTruthy)
.join(path.sep)

const rootTypeBuilder = await TypeBuilder.fromInput(
Expand All @@ -455,7 +477,7 @@ export async function generateTypescriptNextJS(
routeToNextJSFilepath(group.name),
)

const imports = new ImportBuilder({filename})
const imports = new ImportBuilder({filename}, importAlias)

const routerBuilder = new ServerRouterBuilder(
filename,
Expand Down Expand Up @@ -488,6 +510,7 @@ export async function generateTypescriptNextJS(

const nextJSAppRouterBuilder = new NextJSAppRouterBuilder(
nextJsAppRouterPath,
imports,
filename,
sourceFile,
)
Expand All @@ -508,7 +531,10 @@ export async function generateTypescriptNextJS(
const clientOutputPath = [generatedDirectory, "clients", "client.ts"].join(
path.sep,
)
const clientImportBuilder = new ImportBuilder({filename: clientOutputPath})
const clientImportBuilder = new ImportBuilder(
{filename: clientOutputPath},
importAlias,
)

const fetchClientBuilder = new TypescriptFetchClientBuilder(
clientOutputPath,
Expand Down

0 comments on commit 54335e8

Please sign in to comment.