From 201d8b34f4696e70855c0bf88b0c7fa657bbb9a4 Mon Sep 17 00:00:00 2001 From: 2ynn Date: Mon, 5 Oct 2026 11:53:58 -0400 Subject: [PATCH] fix(typescript): export and deduplicate SSE params types in public exports In params-object mode, an operation-level x-speakeasy-exports entry on an SSE-overloaded operation with a union-of-objects request body only exported the base Params type. The Streaming/NonStreaming params and the per-variant Params{,NonStreaming,Streaming} types were not reachable from resources.ts, and the method declared no overload for the union-level Streaming/NonStreaming params, so a value of that type resolved to the catch-all overload and lost the narrowed stream return type. - Methods with union bodies now also declare the union-level NonStreaming/Streaming overloads, after the per-variant ones. - Every SSE operation export goes through one path: its Streaming and NonStreaming params are added after all explicit exports and skipped when the name is already taken, so explicit names keep their targets and duplicate members can no longer be emitted. Union-body operations also get each variant's full params, nested under the export's namespace only, so they never claim a flat alias. - The group-level and nested aliases share one intermediate declaration, and the export's namespace merges into an existing child of the same name instead of being renamed. For SSE operations without a request body, resources.ts no longer emits the duplicate X$2 intermediates (exported types are unchanged), and an explicit export that collides with a generated Streaming or NonStreaming name now keeps the flat name instead of the params type. --- .changesets/1791215442-c54f190b.yaml | 10 + .../namespaces/public_exports_test.go | 478 ++++++++++++++++++ .../typescriptv2/includes/method-signature.ts | 15 +- .../typescriptv2/includes/templating.ts | 113 +++-- .../templates/typescriptv2/method.ts.stmpl | 3 - 5 files changed, 576 insertions(+), 43 deletions(-) create mode 100644 .changesets/1791215442-c54f190b.yaml diff --git a/.changesets/1791215442-c54f190b.yaml b/.changesets/1791215442-c54f190b.yaml new file mode 100644 index 00000000..7c010765 --- /dev/null +++ b/.changesets/1791215442-c54f190b.yaml @@ -0,0 +1,10 @@ +id: 1791215442-c54f190b +features: + - publicExports +targets: + - typescriptv2 +type: fix +bump: patch +description: export streaming and per-variant params types for SSE operations with union request bodies, accept the union-level streaming params in method overloads, and deduplicate SSE params aliases (explicit exports now take precedence over generated SSE params aliases on name collisions) +author: 2ynn +date: "2026-10-05" diff --git a/pkg/generate/snapshots/namespaces/public_exports_test.go b/pkg/generate/snapshots/namespaces/public_exports_test.go index 64f75ca0..a8cae6a1 100644 --- a/pkg/generate/snapshots/namespaces/public_exports_test.go +++ b/pkg/generate/snapshots/namespaces/public_exports_test.go @@ -1088,3 +1088,481 @@ export * from "./exports.js"; Expected: expectedSnapshot, }) } + +const sseBodyVariantPublicExportsSpec = `openapi: 3.1.0 +info: + title: SSE Body Variant Public Exports + version: 1.0.0 +servers: + - url: https://api.example.com +paths: + /widgets: + post: + operationId: createWidget + x-speakeasy-group: widgets + x-speakeasy-sse-overload: true + x-speakeasy-exports: + - group: widgets + name: WidgetCreateParams + representation: input + description: >- + SSE overload with a union-of-objects body: the export's namespace + carries the union-level and per-variant params, including region. + parameters: + - name: region + in: query + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/CreateWidgetBody" + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Widget" + text/event-stream: + schema: + $ref: "#/components/schemas/WidgetEvent" + /{region}/widgets/{id}: + get: + operationId: getWidget + x-speakeasy-group: widgets + x-speakeasy-sse-overload: true + x-speakeasy-exports: + - group: widgets + name: WidgetGetParams + representation: input + description: >- + SSE overload without a body: no per-variant params are exported. + parameters: + - name: region + in: path + required: true + schema: + type: string + default: us + - name: id + in: path + required: true + schema: + type: string + - name: stream + in: query + schema: + type: boolean + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/Widget" + text/event-stream: + schema: + $ref: "#/components/schemas/WidgetEvent" +components: + schemas: + CreateWidgetBody: + oneOf: + - $ref: "#/components/schemas/CreateBasicWidget" + - $ref: "#/components/schemas/CreateCustomWidget" + CreateBasicWidget: + type: object + description: >- + Explicit exports named like per-variant params types keep targeting + this body model. + x-speakeasy-exports: + - group: widgets + name: CreateBasicWidgetParamsStreaming + representation: input + - group: widgets + name: CreateBasicWidgetParamsNonStreaming + representation: input + required: [color, label] + properties: + color: + type: string + label: + type: string + stream: + type: boolean + CreateCustomWidget: + type: object + required: [template, label] + properties: + template: + type: string + label: + type: string + stream: + type: boolean + Widget: + type: object + required: [id] + properties: + id: + type: string + WidgetEvent: + type: object + required: [data] + properties: + data: + type: object + required: [type] + properties: + type: + type: string` + +const sseBodyVariantParamsCheck = `import type { Widgets } from "./resources.js"; +import type * as MP from "./models/operations/method-params.js"; +import type { CreateBasicWidget } from "./models/create-basic-widget.js"; +import type { Widgets as WidgetsSDK } from "./sdk/widgets.js"; + +type Mutual = [A] extends [B] ? ([B] extends [A] ? true : false) : false; +type Idx = [A] extends [Record] ? 1 : 0; +type Same = + Mutual extends true + ? Mutual extends true + ? Mutual, Required> extends true + ? Mutual, Idx> + : false + : false + : false; +type IsStream = [Awaited] extends [AsyncIterable] ? true : false; + +export const unionStreaming: Same< + Widgets.WidgetCreateParamsStreaming, + MP.CreateWidgetParamsStreaming +> = true; +export const unionNonStreaming: Same< + Widgets.WidgetCreateParams.WidgetCreateParamsNonStreaming, + MP.CreateWidgetParamsNonStreaming +> = true; +export const variantStreaming: Same< + Widgets.WidgetCreateParams.CreateBasicWidgetParamsStreaming, + MP.CreateBasicWidgetParamsStreaming +> = true; +export const variantBase: Same< + Widgets.WidgetCreateParams.CreateCustomWidgetParams, + MP.CreateCustomWidgetParams +> = true; +export const bodyOnly: Same< + Widgets.CreateBasicWidgetParamsStreaming, + CreateBasicWidget +> = true; + +declare const sdk: WidgetsSDK; +declare const unionStreamingParams: Widgets.WidgetCreateParamsStreaming; +declare const unionNonStreamingParams: Widgets.WidgetCreateParamsNonStreaming; +declare const variantStreamingParams: Widgets.WidgetCreateParams.CreateCustomWidgetParamsStreaming; + +export function overloadChecks() { + const unionStream = sdk.createWidget(unionStreamingParams); + const unionJSON = sdk.createWidget(unionNonStreamingParams); + const variantStream = sdk.createWidget(variantStreamingParams); + const streams: IsStream = true; + const json: IsStream = false; + const variantStreams: IsStream = true; + return [streams, json, variantStreams]; +} +` + +func TestSnapTsPublicExportsSSEBodyVariants(t *testing.T) { + t.Parallel() + + genYaml := `typescript: + packageName: public-exports + methodSignature: params-object + flattenRequests: true + maxMethodParams: 999 +` + + expectedSnapshot := `--- src/models/operations/method-params.ts --- +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + * Generated under the AGPL-3.0-only license. + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import type { CreateBasicWidget } from "../create-basic-widget.js"; +import type { CreateCustomWidget } from "../create-custom-widget.js"; +import type { CreateWidgetRequest } from "./create-widget.js"; +import type { GetWidgetRequest } from "./get-widget.js"; + +export type CreateWidgetParams = + & Omit< + CreateWidgetRequest, + "body" + > + & CreateWidgetRequest["body"]; + +export type CreateWidgetParamsNonStreaming = CreateWidgetParams & { + stream?: false | undefined; +}; + +export type CreateWidgetParamsStreaming = CreateWidgetParams & { stream: true }; + +export type CreateBasicWidgetParams = + & Omit< + CreateWidgetRequest, + "body" + > + & CreateBasicWidget; + +export type CreateBasicWidgetParamsNonStreaming = CreateBasicWidgetParams & { + stream?: false | undefined; +}; + +export type CreateBasicWidgetParamsStreaming = CreateBasicWidgetParams & { + stream: true; +}; + +export type CreateCustomWidgetParams = + & Omit< + CreateWidgetRequest, + "body" + > + & CreateCustomWidget; + +export type CreateCustomWidgetParamsNonStreaming = CreateCustomWidgetParams & { + stream?: false | undefined; +}; + +export type CreateCustomWidgetParamsStreaming = CreateCustomWidgetParams & { + stream: true; +}; + +export type GetWidgetParams = Omit< + GetWidgetRequest, + "id" | "region" +>; + +export type GetWidgetParamsNonStreaming = GetWidgetParams & { + stream?: false | undefined; +}; + +export type GetWidgetParamsStreaming = GetWidgetParams & { stream: true }; + + +--- src/resources.ts --- +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + * Generated under the AGPL-3.0-only license. + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import type { CreateBasicWidget as CreateBasicWidget$Import } from "./models/create-basic-widget.js"; +import type { + CreateBasicWidgetParams as CreateBasicWidgetParams$Import, + CreateBasicWidgetParamsNonStreaming + as CreateBasicWidgetParamsNonStreaming$Import, + CreateBasicWidgetParamsStreaming as CreateBasicWidgetParamsStreaming$Import, + CreateCustomWidgetParams as CreateCustomWidgetParams$Import, + CreateCustomWidgetParamsNonStreaming + as CreateCustomWidgetParamsNonStreaming$Import, + CreateCustomWidgetParamsStreaming as CreateCustomWidgetParamsStreaming$Import, + CreateWidgetParams as CreateWidgetParams$Import, + CreateWidgetParamsNonStreaming as CreateWidgetParamsNonStreaming$Import, + CreateWidgetParamsStreaming as CreateWidgetParamsStreaming$Import, + GetWidgetParams as GetWidgetParams$Import, + GetWidgetParamsNonStreaming as GetWidgetParamsNonStreaming$Import, + GetWidgetParamsStreaming as GetWidgetParamsStreaming$Import, +} from "./models/operations/method-params.js"; +type CreateBasicWidgetParamsNonStreaming$ = CreateBasicWidget$Import; +type CreateBasicWidgetParamsStreaming$ = CreateBasicWidget$Import; +type WidgetCreateParams$ = CreateWidgetParams$Import; +type WidgetGetParams$ = GetWidgetParams$Import; +type WidgetCreateParamsNonStreaming$ = CreateWidgetParamsNonStreaming$Import; +type WidgetCreateParamsStreaming$ = CreateWidgetParamsStreaming$Import; +type CreateBasicWidgetParams$ = CreateBasicWidgetParams$Import; +type CreateBasicWidgetParamsNonStreaming$2 = + CreateBasicWidgetParamsNonStreaming$Import; +type CreateBasicWidgetParamsStreaming$2 = + CreateBasicWidgetParamsStreaming$Import; +type CreateCustomWidgetParams$ = CreateCustomWidgetParams$Import; +type CreateCustomWidgetParamsNonStreaming$ = + CreateCustomWidgetParamsNonStreaming$Import; +type CreateCustomWidgetParamsStreaming$ = + CreateCustomWidgetParamsStreaming$Import; +type WidgetGetParamsNonStreaming$ = GetWidgetParamsNonStreaming$Import; +type WidgetGetParamsStreaming$ = GetWidgetParamsStreaming$Import; +export type CreateBasicWidgetParamsNonStreaming = + CreateBasicWidgetParamsNonStreaming$; +export type CreateBasicWidgetParamsStreaming = + CreateBasicWidgetParamsStreaming$; +export type WidgetCreateParams = WidgetCreateParams$; +export type WidgetCreateParamsNonStreaming = WidgetCreateParamsNonStreaming$; +export type WidgetCreateParamsStreaming = WidgetCreateParamsStreaming$; +export type WidgetGetParams = WidgetGetParams$; +export type WidgetGetParamsNonStreaming = WidgetGetParamsNonStreaming$; +export type WidgetGetParamsStreaming = WidgetGetParamsStreaming$; +export declare namespace Widgets { + export type CreateBasicWidgetParamsNonStreaming = + CreateBasicWidgetParamsNonStreaming$; + export type CreateBasicWidgetParamsStreaming = + CreateBasicWidgetParamsStreaming$; + export type WidgetCreateParams = WidgetCreateParams$; + export type WidgetCreateParamsNonStreaming = WidgetCreateParamsNonStreaming$; + export type WidgetCreateParamsStreaming = WidgetCreateParamsStreaming$; + export type WidgetGetParams = WidgetGetParams$; + export type WidgetGetParamsNonStreaming = WidgetGetParamsNonStreaming$; + export type WidgetGetParamsStreaming = WidgetGetParamsStreaming$; + export namespace WidgetCreateParams { + export type CreateBasicWidgetParams = CreateBasicWidgetParams$; + export type CreateBasicWidgetParamsNonStreaming = + CreateBasicWidgetParamsNonStreaming$2; + export type CreateBasicWidgetParamsStreaming = + CreateBasicWidgetParamsStreaming$2; + export type CreateCustomWidgetParams = CreateCustomWidgetParams$; + export type CreateCustomWidgetParamsNonStreaming = + CreateCustomWidgetParamsNonStreaming$; + export type CreateCustomWidgetParamsStreaming = + CreateCustomWidgetParamsStreaming$; + export type WidgetCreateParamsNonStreaming = + WidgetCreateParamsNonStreaming$; + export type WidgetCreateParamsStreaming = WidgetCreateParamsStreaming$; + } + export namespace WidgetGetParams { + export type WidgetGetParamsNonStreaming = WidgetGetParamsNonStreaming$; + export type WidgetGetParamsStreaming = WidgetGetParamsStreaming$; + } +} + + +--- src/sdk/widgets.ts --- +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + * Generated under the AGPL-3.0-only license. + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { widgetsCreateWidget } from "../funcs/widgets-create-widget.js"; +import { widgetsGetWidget } from "../funcs/widgets-get-widget.js"; +import { EventStream } from "../lib/event-streams.js"; +import { ClientSDK, RequestOptions } from "../lib/sdks.js"; +import * as models from "../models/index.js"; +import * as operations from "../models/operations/index.js"; +import { + CreateBasicWidgetParamsNonStreaming, + CreateBasicWidgetParamsStreaming, + CreateCustomWidgetParamsNonStreaming, + CreateCustomWidgetParamsStreaming, + CreateWidgetParams, + CreateWidgetParamsNonStreaming, + CreateWidgetParamsStreaming, + GetWidgetParams, + GetWidgetParamsNonStreaming, + GetWidgetParamsStreaming, +} from "../models/operations/method-params.js"; +import { unwrapAsync } from "../types/fp.js"; + +export class Widgets extends ClientSDK { + /** + * SSE overload with a union-of-objects body: the export's namespace carries the union-level and per-variant params, including region. + */ + async createWidget( + params: CreateBasicWidgetParamsNonStreaming, + options?: RequestOptions, + ): Promise; + async createWidget( + params: CreateCustomWidgetParamsNonStreaming, + options?: RequestOptions, + ): Promise; + async createWidget( + params: CreateBasicWidgetParamsStreaming, + options?: RequestOptions, + ): Promise>; + async createWidget( + params: CreateCustomWidgetParamsStreaming, + options?: RequestOptions, + ): Promise>; + async createWidget( + params: CreateWidgetParamsNonStreaming, + options?: RequestOptions, + ): Promise; + async createWidget( + params: CreateWidgetParamsStreaming, + options?: RequestOptions, + ): Promise>; + async createWidget( + params: CreateWidgetParams, + options?: RequestOptions, + ): Promise; + async createWidget( + params: CreateWidgetParams, + options?: RequestOptions, + ): Promise { + const { region, ...body } = params; + return unwrapAsync(widgetsCreateWidget( + this, + body, + region, + options, + )); + } + + /** + * SSE overload without a body: no per-variant params are exported. + */ + async getWidget( + region: string | undefined, + id: string, + params?: GetWidgetParamsNonStreaming, + options?: RequestOptions, + ): Promise; + async getWidget( + region: string | undefined, + id: string, + params: GetWidgetParamsStreaming, + options?: RequestOptions, + ): Promise>; + async getWidget( + region: string | undefined, + id: string, + params?: GetWidgetParams, + options?: RequestOptions, + ): Promise; + async getWidget( + region: string | undefined, + id: string, + params?: GetWidgetParams, + options?: RequestOptions, + ): Promise { + return unwrapAsync(widgetsGetWidget( + this, + region, + id, + params?.stream, + options, + )); + } +} + + +` // end of snapshot + + snaptest.DoTestSnapshot(t, snaptest.Options{ + Spec: sseBodyVariantPublicExportsSpec, + GenYaml: genYaml, + IncludeGlobs: []string{ + "src/resources.ts", + "src/models/operations/method-params.ts", + "src/sdk/widgets.ts", + }, + Expected: expectedSnapshot, + AfterGenerate: func(t *testing.T, tempDir string) { + t.Helper() + require.NoError(t, os.WriteFile( + filepath.Join(tempDir, "src", "__params_check.ts"), + []byte(sseBodyVariantParamsCheck), + 0o644, + )) + }, + }) +} diff --git a/templates/templates/typescriptv2/includes/method-signature.ts b/templates/templates/typescriptv2/includes/method-signature.ts index bb77672b..c7c34ab8 100644 --- a/templates/templates/typescriptv2/includes/method-signature.ts +++ b/templates/templates/typescriptv2/includes/method-signature.ts @@ -416,16 +416,11 @@ function tsImportMethodParamsTypes( )}/method-params.js`; addImport(path, state.ParamsName, typeImport); if (state.SSE) { - // With per-variant overloads the union NonStreaming/Streaming aliases - // are not referenced by the method. - if (state.BodyVariants.length > 0) { - for (const variant of state.BodyVariants) { - addImport(path, `${variant.ParamsName}NonStreaming`, typeImport); - addImport(path, `${variant.ParamsName}Streaming`, typeImport); - } - } else { - addImport(path, `${state.ParamsName}NonStreaming`, typeImport); - addImport(path, `${state.ParamsName}Streaming`, typeImport); + addImport(path, `${state.ParamsName}NonStreaming`, typeImport); + addImport(path, `${state.ParamsName}Streaming`, typeImport); + for (const variant of state.BodyVariants) { + addImport(path, `${variant.ParamsName}NonStreaming`, typeImport); + addImport(path, `${variant.ParamsName}Streaming`, typeImport); } } return ""; diff --git a/templates/templates/typescriptv2/includes/templating.ts b/templates/templates/typescriptv2/includes/templating.ts index 99129e0b..3eface32 100644 --- a/templates/templates/typescriptv2/includes/templating.ts +++ b/templates/templates/typescriptv2/includes/templating.ts @@ -644,13 +644,16 @@ function buildTypeScriptPublicExportFile(): return node; }; - const addAlias = ( + const hasMember = ( members: TypeScriptPublicExportMember[], aliasName: string, + ): boolean => members.some((member) => member.Name === aliasName); + + const addIntermediate = ( + aliasName: string, path: string, sourceName: string, - canInterface = false, - ) => { + ): string => { const intermediate = uniquePublicExportAlias( `${aliasName}$`, usedIdentifiers, @@ -659,16 +662,50 @@ function buildTypeScriptPublicExportFile(): Name: intermediate, Target: importBinding(path, sourceName), }); + return intermediate; + }; + + const addMember = ( + members: TypeScriptPublicExportMember[], + aliasName: string, + intermediate: string, + canInterface: boolean, + registerFlat: boolean, + ) => { members.push({ Name: aliasName, Intermediate: intermediate, CanInterface: canInterface, }); - if (!flatByName.has(aliasName)) { + if (registerFlat && !flatByName.has(aliasName)) { flatByName.set(aliasName, intermediate); } }; + const addAlias = ( + members: TypeScriptPublicExportMember[], + aliasName: string, + path: string, + sourceName: string, + canInterface = false, + registerFlat = true, + ) => { + addMember( + members, + aliasName, + addIntermediate(aliasName, path, sourceName), + canInterface, + registerFlat, + ); + }; + + const deferredSSEExports: { + node: TypeScriptPublicExportNamespaceBuilder; + aliasName: string; + paramsPath: string; + paramsState: TSMethodParamsState; + }[] = []; + for (const { group, keys, parts } of groups) { const node = nodeForParts(keys, parts); @@ -692,32 +729,8 @@ function buildTypeScriptPublicExportFile(): if (paramsState) { const paramsPath = `${importPrefix}${getOperationsLocation()}/method-params.js`; addAlias(node.Members, aliasName, paramsPath, paramsState.ParamsName); - if (paramsState.SSE && paramsState.BodyVariants.length === 0) { - const variantNode = namespaceNode(node, aliasName, aliasName); - addAlias( - node.Members, - `${aliasName}NonStreaming`, - paramsPath, - `${paramsState.ParamsName}NonStreaming`, - ); - addAlias( - variantNode.Members, - `${aliasName}NonStreaming`, - paramsPath, - `${paramsState.ParamsName}NonStreaming`, - ); - addAlias( - node.Members, - `${aliasName}Streaming`, - paramsPath, - `${paramsState.ParamsName}Streaming`, - ); - addAlias( - variantNode.Members, - `${aliasName}Streaming`, - paramsPath, - `${paramsState.ParamsName}Streaming`, - ); + if (paramsState.SSE) { + deferredSSEExports.push({ node, aliasName, paramsPath, paramsState }); } continue; } @@ -734,6 +747,46 @@ function buildTypeScriptPublicExportFile(): } } + // Deferred so explicit exports keep their names; per-variant params stay + // nested-only so they never claim a flat alias. + const sseSuffixes = ["NonStreaming", "Streaming"]; + for (const { + node, + aliasName, + paramsPath, + paramsState, + } of deferredSSEExports) { + const variantNode = + node.ChildrenByKey.get(aliasName) ?? + node.Children.get(aliasName) ?? + namespaceNode(node, aliasName, aliasName); + for (const suffix of sseSuffixes) { + const name = `${aliasName}${suffix}`; + const targets = [node.Members, variantNode.Members].filter( + (members) => !hasMember(members, name), + ); + if (targets.length === 0) { + continue; + } + const intermediate = addIntermediate( + name, + paramsPath, + `${paramsState.ParamsName}${suffix}`, + ); + for (const members of targets) { + addMember(members, name, intermediate, false, members === node.Members); + } + } + for (const variant of paramsState.BodyVariants) { + for (const suffix of ["", ...sseSuffixes]) { + const name = `${variant.ParamsName}${suffix}`; + if (!hasMember(variantNode.Members, name)) { + addAlias(variantNode.Members, name, paramsPath, name, false, false); + } + } + } + } + const finalizeNamespace = ( node: TypeScriptPublicExportNamespaceBuilder, rootNamespace: boolean, diff --git a/templates/templates/typescriptv2/method.ts.stmpl b/templates/templates/typescriptv2/method.ts.stmpl index 9397749d..15f15e2e 100644 --- a/templates/templates/typescriptv2/method.ts.stmpl +++ b/templates/templates/typescriptv2/method.ts.stmpl @@ -20,7 +20,6 @@ {{- $paramsOpt := "" }}{{- if not $paramsState.ParamsRequired }}{{- $paramsOpt = "?" }}{{- end }} {{- if $sseTypes }} {{ $tsdoc }} -{{- if $paramsState.BodyVariants }} {{- range $variant := $paramsState.BodyVariants }} {{if not $useAPIPromise}}async {{end}}{{$methodName}}( {{- range $field := tsMethodPositionalFields $op }} @@ -61,7 +60,6 @@ options?: {{ $methodOptions }}, ): {{if $useAPIPromise}}API{{end}}Promise<{{$sseTypes.sseReturnType}}>; {{- end }} -{{- else }} {{if not $useAPIPromise}}async {{end}}{{$methodName}}( {{- range $field := tsMethodPositionalFields $op }} {{- $fieldType := resolveOutbound ( @@ -98,7 +96,6 @@ params: {{$paramsState.ParamsName}}Streaming, options?: {{ $methodOptions }}, ): {{if $useAPIPromise}}API{{end}}Promise<{{$sseTypes.sseReturnType}}>; -{{- end }} {{if not $useAPIPromise}}async {{end}}{{$methodName}}( {{- range $field := tsMethodPositionalFields $op }} {{sanitizeFieldName $field.Name}}: {{(resolveOutbound (