···11import type ts from 'typescript';
2233-import { AttrTsDsl } from '../attr';
33+import type { AttrTsDsl } from '../attr';
44+import type { AwaitTsDsl } from '../await';
45import type { MaybeTsDsl, WithString } from '../base';
55-import { CallTsDsl } from '../call';
66+import type { CallTsDsl } from '../call';
77+import type { ReturnTsDsl } from '../return';
88+99+/**
1010+ * Access helpers depend on other DSL classes that are initialized later in the
1111+ * module graph. We store factory callbacks here and let each class lazily
1212+ * register its own implementation once it has finished evaluation. This keeps
1313+ * mixin application order predictable and avoids circular import crashes.
1414+ */
1515+1616+type AttrFactory = (
1717+ expr: MaybeTsDsl<WithString>,
1818+ name: WithString<ts.MemberName> | number,
1919+) => AttrTsDsl;
2020+let attrFactory: AttrFactory | undefined;
2121+/** Registers the Attr DSL factory after its module has finished evaluating. */
2222+export function registerLazyAccessAttrFactory(factory: AttrFactory): void {
2323+ attrFactory = factory;
2424+}
2525+2626+type AwaitFactory = (expr: MaybeTsDsl<WithString>) => AwaitTsDsl;
2727+let awaitFactory: AwaitFactory | undefined;
2828+/** Registers the Await DSL factory after its module has finished evaluating. */
2929+export function registerLazyAccessAwaitFactory(factory: AwaitFactory): void {
3030+ awaitFactory = factory;
3131+}
3232+3333+type CallFactory = (
3434+ expr: MaybeTsDsl<WithString>,
3535+ args: ReadonlyArray<MaybeTsDsl<WithString>>,
3636+) => CallTsDsl;
3737+let callFactory: CallFactory | undefined;
3838+/** Registers the Call DSL factory after its module has finished evaluating. */
3939+export function registerLazyAccessCallFactory(factory: CallFactory): void {
4040+ callFactory = factory;
4141+}
4242+4343+type ReturnFactory = (expr: MaybeTsDsl<WithString>) => ReturnTsDsl;
4444+let returnFactory: ReturnFactory | undefined;
4545+/** Registers the Return DSL factory after its module has finished evaluating. */
4646+export function registerLazyAccessReturnFactory(factory: ReturnFactory): void {
4747+ returnFactory = factory;
4848+}
649750export class AccessMixin {
851 /** Accesses a property on the current expression (e.g. `this.foo`). */
···1053 this: MaybeTsDsl<WithString>,
1154 name: WithString<ts.MemberName> | number,
1255 ): AttrTsDsl {
1313- return new AttrTsDsl(this, name);
5656+ return attrFactory!(this, name);
1457 }
1515- /** Calls the current expression as a function (e.g. `fn(arg1, arg2)`). */
5858+5959+ /** Awaits the current expression (e.g. `await expr`). */
6060+ await(this: MaybeTsDsl<WithString>): AwaitTsDsl {
6161+ return awaitFactory!(this);
6262+ }
6363+6464+ /** Calls the current expression (e.g. `fn(arg1, arg2)`). */
1665 call(
1766 this: MaybeTsDsl<WithString>,
1867 ...args: ReadonlyArray<MaybeTsDsl<WithString>>
1968 ): CallTsDsl {
2020- return new CallTsDsl(this, ...args);
6969+ return callFactory!(this, args);
7070+ }
7171+7272+ /** Produces a `return` statement returning the current expression. */
7373+ return(this: MaybeTsDsl<WithString>): ReturnTsDsl {
7474+ return returnFactory!(this);
2175 }
2276}
+2-1
packages/openapi-ts/src/ts-dsl/mixins/value.ts
···11import type ts from 'typescript';
2233-import { type MaybeTsDsl, TsDsl, type WithString } from '../base';
33+import type { MaybeTsDsl, WithString } from '../base';
44+import { TsDsl } from '../base';
4556export class ValueMixin extends TsDsl {
67 private value?: MaybeTsDsl<WithString>;
+3-2
packages/openapi-ts/src/ts-dsl/new.ts
···3344import type { MaybeTsDsl, WithString } from './base';
55import { TsDsl } from './base';
66+import { AccessMixin } from './mixins/access';
67import { mixin } from './mixins/apply';
78import { ArgsMixin } from './mixins/args';
89import { GenericsMixin } from './mixins/generics';
···3132 }
3233}
33343434-export interface NewTsDsl extends ArgsMixin, GenericsMixin {}
3535-mixin(NewTsDsl, ArgsMixin, GenericsMixin);
3535+export interface NewTsDsl extends AccessMixin, ArgsMixin, GenericsMixin {}
3636+mixin(NewTsDsl, AccessMixin, ArgsMixin, GenericsMixin);