fork of hey-api/openapi-ts because I need some additional things

Merge pull request #2951 from hey-api/refactor/dsl-return-await

refactor: tighten up return and await methods

authored by

Lubos and committed by
GitHub
4948f350 cb869f74

+166 -108
+1 -1
.changeset/chilled-wolves-pump.md
··· 2 2 "@hey-api/openapi-ts": patch 3 3 --- 4 4 5 - parser: merge `default` keyword with `$ref` in OpenAPI 3.1 5 + **parser**: merge `default` keyword with `$ref` in OpenAPI 3.1
+6 -6
packages/openapi-ts/src/plugins/@hey-api/sdk/shared/class.ts
··· 392 392 g 393 393 .$if(!plugin.config.instance, (g) => g.public().static()) 394 394 .do( 395 - plugin.config.instance 396 - ? $.return( 397 - $.new(refChildClass.placeholder).args( 395 + $.return( 396 + plugin.config.instance 397 + ? $.new(refChildClass.placeholder).args( 398 398 $.object().prop('client', $('this').attr('client')), 399 - ), 400 - ) 401 - : $.return(refChildClass.placeholder), 399 + ) 400 + : refChildClass.placeholder, 401 + ), 402 402 ), 403 403 ); 404 404
+1 -1
packages/openapi-ts/src/plugins/@tanstack/query-core/v5/queryOptions.ts
··· 131 131 .param(optionsParamName, (p) => 132 132 p.optional(!isRequiredOptions).type(typeData), 133 133 ) 134 - .do($.return($(symbolQueryOptions.placeholder).call(queryOptionsObj))), 134 + .do($(symbolQueryOptions.placeholder).call(queryOptionsObj).return()), 135 135 ); 136 136 plugin.setSymbolValue(symbolQueryOptionsFn, statement); 137 137 };
+10 -12
packages/openapi-ts/src/plugins/arktype/v2/api.ts
··· 35 35 .async() 36 36 .param(dataParameterName) 37 37 .do( 38 - $.return( 39 - $(symbol.placeholder) 40 - .attr('parseAsync') 41 - .call($(dataParameterName)) 42 - .await(), 43 - ), 38 + $(symbol.placeholder) 39 + .attr('parseAsync') 40 + .call(dataParameterName) 41 + .await() 42 + .return(), 44 43 ); 45 44 }; 46 45 ··· 62 61 .async() 63 62 .param(dataParameterName) 64 63 .do( 65 - $.return( 66 - $(symbol.placeholder) 67 - .attr('parseAsync') 68 - .call($(dataParameterName)) 69 - .await(), 70 - ), 64 + $(symbol.placeholder) 65 + .attr('parseAsync') 66 + .call(dataParameterName) 67 + .await() 68 + .return(), 71 69 ); 72 70 };
+4 -4
packages/openapi-ts/src/plugins/swr/v2/useSwr.ts
··· 56 56 ) 57 57 .assign( 58 58 $.func().do( 59 - $.return( 60 - $(symbolUseSwr.placeholder).call( 59 + $(symbolUseSwr.placeholder) 60 + .call( 61 61 $.literal(operation.path), 62 62 $.func() 63 63 .async() 64 64 .do(...statements), 65 - ), 66 - ), 65 + ) 66 + .return(), 67 67 ), 68 68 ); 69 69 plugin.setSymbolValue(symbolUseQueryFn, statement);
+10 -12
packages/openapi-ts/src/plugins/valibot/v1/api.ts
··· 25 25 .async() 26 26 .param(dataParameterName) 27 27 .do( 28 - $.return( 29 - $(v.placeholder) 30 - .attr(identifiers.async.parseAsync) 31 - .call($(symbol.placeholder), $(dataParameterName)) 32 - .await(), 33 - ), 28 + $(v.placeholder) 29 + .attr(identifiers.async.parseAsync) 30 + .call(symbol.placeholder, dataParameterName) 31 + .await() 32 + .return(), 34 33 ); 35 34 }; 36 35 ··· 56 55 .async() 57 56 .param(dataParameterName) 58 57 .do( 59 - $.return( 60 - $(v.placeholder) 61 - .attr(identifiers.async.parseAsync) 62 - .call($(symbol.placeholder), $(dataParameterName)) 63 - .await(), 64 - ), 58 + $(v.placeholder) 59 + .attr(identifiers.async.parseAsync) 60 + .call(symbol.placeholder, dataParameterName) 61 + .await() 62 + .return(), 65 63 ); 66 64 };
+10 -12
packages/openapi-ts/src/plugins/zod/mini/api.ts
··· 22 22 .async() 23 23 .param(dataParameterName) 24 24 .do( 25 - $.return( 26 - $(symbol.placeholder) 27 - .attr(identifiers.parseAsync) 28 - .call($(dataParameterName)) 29 - .await(), 30 - ), 25 + $(symbol.placeholder) 26 + .attr(identifiers.parseAsync) 27 + .call(dataParameterName) 28 + .await() 29 + .return(), 31 30 ); 32 31 }; 33 32 ··· 49 48 .async() 50 49 .param(dataParameterName) 51 50 .do( 52 - $.return( 53 - $(symbol.placeholder) 54 - .attr(identifiers.parseAsync) 55 - .call($(dataParameterName)) 56 - .await(), 57 - ), 51 + $(symbol.placeholder) 52 + .attr(identifiers.parseAsync) 53 + .call(dataParameterName) 54 + .await() 55 + .return(), 58 56 ); 59 57 };
+10 -12
packages/openapi-ts/src/plugins/zod/v3/api.ts
··· 22 22 .async() 23 23 .param(dataParameterName) 24 24 .do( 25 - $.return( 26 - $(symbol.placeholder) 27 - .attr(identifiers.parseAsync) 28 - .call($(dataParameterName)) 29 - .await(), 30 - ), 25 + $(symbol.placeholder) 26 + .attr(identifiers.parseAsync) 27 + .call(dataParameterName) 28 + .await() 29 + .return(), 31 30 ); 32 31 }; 33 32 ··· 49 48 .async() 50 49 .param(dataParameterName) 51 50 .do( 52 - $.return( 53 - $(symbol.placeholder) 54 - .attr(identifiers.parseAsync) 55 - .call($(dataParameterName)) 56 - .await(), 57 - ), 51 + $(symbol.placeholder) 52 + .attr(identifiers.parseAsync) 53 + .call(dataParameterName) 54 + .await() 55 + .return(), 58 56 ); 59 57 };
+10 -12
packages/openapi-ts/src/plugins/zod/v4/api.ts
··· 22 22 .async() 23 23 .param(dataParameterName) 24 24 .do( 25 - $.return( 26 - $(symbol.placeholder) 27 - .attr(identifiers.parseAsync) 28 - .call(dataParameterName) 29 - .await(), 30 - ), 25 + $(symbol.placeholder) 26 + .attr(identifiers.parseAsync) 27 + .call(dataParameterName) 28 + .await() 29 + .return(), 31 30 ); 32 31 }; 33 32 ··· 49 48 .async() 50 49 .param(dataParameterName) 51 50 .do( 52 - $.return( 53 - $(symbol.placeholder) 54 - .attr(identifiers.parseAsync) 55 - .call(dataParameterName) 56 - .await(), 57 - ), 51 + $(symbol.placeholder) 52 + .attr(identifiers.parseAsync) 53 + .call(dataParameterName) 54 + .await() 55 + .return(), 58 56 ); 59 57 };
+3 -1
packages/openapi-ts/src/ts-dsl/attr.ts
··· 3 3 4 4 import type { MaybeTsDsl, WithString } from './base'; 5 5 import { TsDsl } from './base'; 6 - import { AccessMixin } from './mixins/access'; 6 + import { AccessMixin, registerLazyAccessAttrFactory } from './mixins/access'; 7 7 import { mixin } from './mixins/apply'; 8 8 import { AssignmentMixin } from './mixins/assignment'; 9 9 import { OperatorMixin } from './mixins/operator'; ··· 59 59 OperatorMixin, 60 60 OptionalMixin {} 61 61 mixin(AttrTsDsl, AccessMixin, AssignmentMixin, OperatorMixin, OptionalMixin); 62 + 63 + registerLazyAccessAttrFactory((expr, name) => new AttrTsDsl(expr, name));
+11 -4
packages/openapi-ts/src/ts-dsl/await.ts
··· 1 + /* eslint-disable @typescript-eslint/no-empty-object-type, @typescript-eslint/no-unsafe-declaration-merging */ 1 2 import ts from 'typescript'; 2 3 3 4 import type { MaybeTsDsl, WithString } from './base'; 4 5 import { TsDsl } from './base'; 6 + import { AccessMixin, registerLazyAccessAwaitFactory } from './mixins/access'; 7 + import { mixin } from './mixins/apply'; 5 8 6 9 export class AwaitTsDsl extends TsDsl<ts.AwaitExpression> { 7 - private exprNode: MaybeTsDsl<WithString>; 10 + private _awaitExpr: MaybeTsDsl<WithString>; 8 11 9 12 constructor(expr: MaybeTsDsl<WithString>) { 10 13 super(); 11 - this.exprNode = expr; 14 + this._awaitExpr = expr; 12 15 } 13 16 14 17 $render(): ts.AwaitExpression { 15 - const expr = this.$node(this.exprNode); 16 - return ts.factory.createAwaitExpression(expr); 18 + return ts.factory.createAwaitExpression(this.$node(this._awaitExpr)); 17 19 } 18 20 } 21 + 22 + export interface AwaitTsDsl extends AccessMixin {} 23 + mixin(AwaitTsDsl, AccessMixin); 24 + 25 + registerLazyAccessAwaitFactory((expr) => new AwaitTsDsl(expr));
+9 -12
packages/openapi-ts/src/ts-dsl/call.ts
··· 1 - /* eslint-disable @typescript-eslint/no-empty-object-type, @typescript-eslint/no-unsafe-declaration-merging */ 1 + /* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */ 2 2 import ts from 'typescript'; 3 3 4 - import { AwaitTsDsl } from './await'; 5 4 import type { MaybeTsDsl, WithString } from './base'; 6 5 import { TsDsl } from './base'; 6 + import { AccessMixin, registerLazyAccessCallFactory } from './mixins/access'; 7 7 import { mixin } from './mixins/apply'; 8 8 import { ArgsMixin } from './mixins/args'; 9 9 10 10 export class CallTsDsl extends TsDsl<ts.CallExpression> { 11 - private callee: MaybeTsDsl<WithString>; 11 + private _callee: MaybeTsDsl<WithString>; 12 12 13 13 constructor( 14 14 callee: MaybeTsDsl<WithString>, 15 15 ...args: ReadonlyArray<MaybeTsDsl<WithString>> 16 16 ) { 17 17 super(); 18 - this.callee = callee; 18 + this._callee = callee; 19 19 this.args(...args); 20 20 } 21 21 22 - /** Await the result of the call expression. */ 23 - await(): AwaitTsDsl { 24 - return new AwaitTsDsl(this); 25 - } 26 - 27 22 $render(): ts.CallExpression { 28 23 return ts.factory.createCallExpression( 29 - this.$node(this.callee), 24 + this.$node(this._callee), 30 25 undefined, 31 26 this.$args(), 32 27 ); 33 28 } 34 29 } 35 30 36 - export interface CallTsDsl extends ArgsMixin {} 37 - mixin(CallTsDsl, ArgsMixin); 31 + export interface CallTsDsl extends AccessMixin, ArgsMixin {} 32 + mixin(CallTsDsl, AccessMixin, ArgsMixin); 33 + 34 + registerLazyAccessCallFactory((expr, args) => new CallTsDsl(expr, ...args));
+3 -3
packages/openapi-ts/src/ts-dsl/expr.ts
··· 8 8 import { OperatorMixin } from './mixins/operator'; 9 9 10 10 export class ExprTsDsl extends TsDsl<ts.Expression> { 11 - private input: MaybeTsDsl<WithString>; 11 + private _exprInput: MaybeTsDsl<WithString>; 12 12 13 13 constructor(id: MaybeTsDsl<WithString>) { 14 14 super(); 15 - this.input = id; 15 + this._exprInput = id; 16 16 } 17 17 18 18 $render(): ts.Expression { 19 - return this.$node(this.input); 19 + return this.$node(this._exprInput); 20 20 } 21 21 } 22 22
+59 -5
packages/openapi-ts/src/ts-dsl/mixins/access.ts
··· 1 1 import type ts from 'typescript'; 2 2 3 - import { AttrTsDsl } from '../attr'; 3 + import type { AttrTsDsl } from '../attr'; 4 + import type { AwaitTsDsl } from '../await'; 4 5 import type { MaybeTsDsl, WithString } from '../base'; 5 - import { CallTsDsl } from '../call'; 6 + import type { CallTsDsl } from '../call'; 7 + import type { ReturnTsDsl } from '../return'; 8 + 9 + /** 10 + * Access helpers depend on other DSL classes that are initialized later in the 11 + * module graph. We store factory callbacks here and let each class lazily 12 + * register its own implementation once it has finished evaluation. This keeps 13 + * mixin application order predictable and avoids circular import crashes. 14 + */ 15 + 16 + type AttrFactory = ( 17 + expr: MaybeTsDsl<WithString>, 18 + name: WithString<ts.MemberName> | number, 19 + ) => AttrTsDsl; 20 + let attrFactory: AttrFactory | undefined; 21 + /** Registers the Attr DSL factory after its module has finished evaluating. */ 22 + export function registerLazyAccessAttrFactory(factory: AttrFactory): void { 23 + attrFactory = factory; 24 + } 25 + 26 + type AwaitFactory = (expr: MaybeTsDsl<WithString>) => AwaitTsDsl; 27 + let awaitFactory: AwaitFactory | undefined; 28 + /** Registers the Await DSL factory after its module has finished evaluating. */ 29 + export function registerLazyAccessAwaitFactory(factory: AwaitFactory): void { 30 + awaitFactory = factory; 31 + } 32 + 33 + type CallFactory = ( 34 + expr: MaybeTsDsl<WithString>, 35 + args: ReadonlyArray<MaybeTsDsl<WithString>>, 36 + ) => CallTsDsl; 37 + let callFactory: CallFactory | undefined; 38 + /** Registers the Call DSL factory after its module has finished evaluating. */ 39 + export function registerLazyAccessCallFactory(factory: CallFactory): void { 40 + callFactory = factory; 41 + } 42 + 43 + type ReturnFactory = (expr: MaybeTsDsl<WithString>) => ReturnTsDsl; 44 + let returnFactory: ReturnFactory | undefined; 45 + /** Registers the Return DSL factory after its module has finished evaluating. */ 46 + export function registerLazyAccessReturnFactory(factory: ReturnFactory): void { 47 + returnFactory = factory; 48 + } 6 49 7 50 export class AccessMixin { 8 51 /** Accesses a property on the current expression (e.g. `this.foo`). */ ··· 10 53 this: MaybeTsDsl<WithString>, 11 54 name: WithString<ts.MemberName> | number, 12 55 ): AttrTsDsl { 13 - return new AttrTsDsl(this, name); 56 + return attrFactory!(this, name); 14 57 } 15 - /** Calls the current expression as a function (e.g. `fn(arg1, arg2)`). */ 58 + 59 + /** Awaits the current expression (e.g. `await expr`). */ 60 + await(this: MaybeTsDsl<WithString>): AwaitTsDsl { 61 + return awaitFactory!(this); 62 + } 63 + 64 + /** Calls the current expression (e.g. `fn(arg1, arg2)`). */ 16 65 call( 17 66 this: MaybeTsDsl<WithString>, 18 67 ...args: ReadonlyArray<MaybeTsDsl<WithString>> 19 68 ): CallTsDsl { 20 - return new CallTsDsl(this, ...args); 69 + return callFactory!(this, args); 70 + } 71 + 72 + /** Produces a `return` statement returning the current expression. */ 73 + return(this: MaybeTsDsl<WithString>): ReturnTsDsl { 74 + return returnFactory!(this); 21 75 } 22 76 }
+2 -1
packages/openapi-ts/src/ts-dsl/mixins/value.ts
··· 1 1 import type ts from 'typescript'; 2 2 3 - import { type MaybeTsDsl, TsDsl, type WithString } from '../base'; 3 + import type { MaybeTsDsl, WithString } from '../base'; 4 + import { TsDsl } from '../base'; 4 5 5 6 export class ValueMixin extends TsDsl { 6 7 private value?: MaybeTsDsl<WithString>;
+3 -2
packages/openapi-ts/src/ts-dsl/new.ts
··· 3 3 4 4 import type { MaybeTsDsl, WithString } from './base'; 5 5 import { TsDsl } from './base'; 6 + import { AccessMixin } from './mixins/access'; 6 7 import { mixin } from './mixins/apply'; 7 8 import { ArgsMixin } from './mixins/args'; 8 9 import { GenericsMixin } from './mixins/generics'; ··· 31 32 } 32 33 } 33 34 34 - export interface NewTsDsl extends ArgsMixin, GenericsMixin {} 35 - mixin(NewTsDsl, ArgsMixin, GenericsMixin); 35 + export interface NewTsDsl extends AccessMixin, ArgsMixin, GenericsMixin {} 36 + mixin(NewTsDsl, AccessMixin, ArgsMixin, GenericsMixin);
+3 -4
packages/openapi-ts/src/ts-dsl/not.ts
··· 4 4 import { TsDsl } from './base'; 5 5 6 6 export class NotTsDsl extends TsDsl<ts.PrefixUnaryExpression> { 7 - private exprInput: MaybeTsDsl<WithString>; 7 + private _notExpr: MaybeTsDsl<WithString>; 8 8 9 9 constructor(expr: MaybeTsDsl<WithString>) { 10 10 super(); 11 - this.exprInput = expr; 11 + this._notExpr = expr; 12 12 } 13 13 14 14 $render(): ts.PrefixUnaryExpression { 15 - const expression = this.$node(this.exprInput); 16 15 return ts.factory.createPrefixUnaryExpression( 17 16 ts.SyntaxKind.ExclamationToken, 18 - expression, 17 + this.$node(this._notExpr), 19 18 ); 20 19 } 21 20 }
+11 -4
packages/openapi-ts/src/ts-dsl/return.ts
··· 1 + /* eslint-disable @typescript-eslint/no-empty-object-type, @typescript-eslint/no-unsafe-declaration-merging */ 1 2 import ts from 'typescript'; 2 3 3 4 import type { MaybeTsDsl, WithString } from './base'; 4 5 import { TsDsl } from './base'; 6 + import { AccessMixin, registerLazyAccessReturnFactory } from './mixins/access'; 7 + import { mixin } from './mixins/apply'; 5 8 6 9 export class ReturnTsDsl extends TsDsl<ts.ReturnStatement> { 7 - private expr?: MaybeTsDsl<WithString>; 10 + private _returnExpr?: MaybeTsDsl<WithString>; 8 11 9 12 constructor(expr?: MaybeTsDsl<WithString>) { 10 13 super(); 11 - this.expr = expr; 14 + this._returnExpr = expr; 12 15 } 13 16 14 17 $render(): ts.ReturnStatement { 15 - const exprNode = this.$node(this.expr); 16 - return ts.factory.createReturnStatement(exprNode); 18 + return ts.factory.createReturnStatement(this.$node(this._returnExpr)); 17 19 } 18 20 } 21 + 22 + export interface ReturnTsDsl extends AccessMixin {} 23 + mixin(ReturnTsDsl, AccessMixin); 24 + 25 + registerLazyAccessReturnFactory((expr) => new ReturnTsDsl(expr));