From d2b8a1eeac0f052958799771b6df2c0a350b9872 Mon Sep 17 00:00:00 2001 From: David Gamero Date: Tue, 17 Jun 2025 04:45:43 -0400 Subject: [PATCH] [typescript] add abort signal to requestcontext (#21323) * add abort signal to requestcontext * regenerate * rebuild and regenerate * abort signal import * refresh samples * clean csharp samples * csharp sample cleanup * add missing cs samples from master * abort testing --- .../resources/typescript/http/http.mustache | 11 + .../typescript/http/isomorphic-fetch.mustache | 1 + .../echo_api/typescript/build/http/http.ts | 11 + .../typescript/build/http/isomorphic-fetch.ts | 1 + .../builds/array-of-lists/http/http.ts | 10 + .../array-of-lists/http/isomorphic-fetch.ts | 1 + .../builds/enum-single-value/http/http.ts | 10 + .../http/isomorphic-fetch.ts | 1 + .../builds/null-types-simple/http/http.ts | 10 + .../http/isomorphic-fetch.ts | 1 + .../builds/with-unique-items/http/http.ts | 10 + .../http/isomorphic-fetch.ts | 1 + .../encode-decode/build/http/http.ts | 11 + .../build/http/isomorphic-fetch.ts | 1 + .../typescript/builds/browser/http/http.ts | 10 + .../builds/browser/http/isomorphic-fetch.ts | 1 + .../builds/composed-schemas/http/http.ts | 10 + .../composed-schemas/http/isomorphic-fetch.ts | 1 + .../typescript/builds/default/http/http.ts | 11 + .../builds/default/http/isomorphic-fetch.ts | 1 + .../typescript/builds/deno/http/http.ts | 10 + .../builds/deno/http/isomorphic-fetch.ts | 1 + .../builds/deno_object_params/http/http.ts | 10 + .../http/isomorphic-fetch.ts | 1 + .../builds/explode-query/http/http.ts | 11 + .../explode-query/http/isomorphic-fetch.ts | 1 + .../typescript/builds/inversify/http/http.ts | 11 + .../builds/inversify/http/isomorphic-fetch.ts | 1 + .../typescript/builds/jquery/http/http.ts | 10 + .../builds/nullable-enum/http/http.ts | 10 + .../nullable-enum/http/isomorphic-fetch.ts | 1 + .../builds/object_params/http/http.ts | 11 + .../object_params/http/isomorphic-fetch.ts | 1 + .../tests/default/test/api/PetApi.test.ts | 277 +++++++++++------- 34 files changed, 366 insertions(+), 104 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/typescript/http/http.mustache b/modules/openapi-generator/src/main/resources/typescript/http/http.mustache index 5b2ac5edec6..844882ab71e 100644 --- a/modules/openapi-generator/src/main/resources/typescript/http/http.mustache +++ b/modules/openapi-generator/src/main/resources/typescript/http/http.mustache @@ -5,6 +5,7 @@ import {{^supportsES6}}* as{{/supportsES6}} FormData from "form-data"; import { URL, URLSearchParams } from 'url'; import * as http from 'http'; import * as https from 'https'; +import { AbortSignal } from "node-fetch/externals"; {{/node}} {{/platforms}} import { Observable, from } from {{#useRxJS}}'rxjs'{{/useRxJS}}{{^useRxJS}}'../rxjsStub{{importFileExtension}}'{{/useRxJS}}; @@ -86,6 +87,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; {{#platforms}} {{#node}} private agent: http.Agent | https.Agent | undefined = undefined; @@ -167,6 +169,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + {{#platforms}} {{#node}} diff --git a/modules/openapi-generator/src/main/resources/typescript/http/isomorphic-fetch.mustache b/modules/openapi-generator/src/main/resources/typescript/http/isomorphic-fetch.mustache index 1ebbe5a3a9e..b822d4d9d3a 100644 --- a/modules/openapi-generator/src/main/resources/typescript/http/isomorphic-fetch.mustache +++ b/modules/openapi-generator/src/main/resources/typescript/http/isomorphic-fetch.mustache @@ -19,6 +19,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), {{#platforms}} {{#node}} agent: request.getAgent(), diff --git a/samples/client/echo_api/typescript/build/http/http.ts b/samples/client/echo_api/typescript/build/http/http.ts index 115d854c58b..71d0b857678 100644 --- a/samples/client/echo_api/typescript/build/http/http.ts +++ b/samples/client/echo_api/typescript/build/http/http.ts @@ -3,6 +3,7 @@ import * as FormData from "form-data"; import { URL, URLSearchParams } from 'url'; import * as http from 'http'; import * as https from 'https'; +import { AbortSignal } from "node-fetch/externals"; import { Observable, from } from '../rxjsStub'; export * from './isomorphic-fetch'; @@ -57,6 +58,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; private agent: http.Agent | https.Agent | undefined = undefined; /** @@ -135,6 +137,15 @@ export class RequestContext { this.headers[key] = value; } + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + + public setAgent(agent: http.Agent | https.Agent) { this.agent = agent; } diff --git a/samples/client/echo_api/typescript/build/http/isomorphic-fetch.ts b/samples/client/echo_api/typescript/build/http/isomorphic-fetch.ts index 26d267cfc06..d7ce46e4bee 100644 --- a/samples/client/echo_api/typescript/build/http/isomorphic-fetch.ts +++ b/samples/client/echo_api/typescript/build/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), agent: request.getAgent(), }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/client/others/typescript/builds/array-of-lists/http/http.ts b/samples/client/others/typescript/builds/array-of-lists/http/http.ts index fd40471a98f..d48cbd6b770 100644 --- a/samples/client/others/typescript/builds/array-of-lists/http/http.ts +++ b/samples/client/others/typescript/builds/array-of-lists/http/http.ts @@ -49,6 +49,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -125,6 +126,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/client/others/typescript/builds/array-of-lists/http/isomorphic-fetch.ts b/samples/client/others/typescript/builds/array-of-lists/http/isomorphic-fetch.ts index 3af85f3d902..20e2897b9f4 100644 --- a/samples/client/others/typescript/builds/array-of-lists/http/isomorphic-fetch.ts +++ b/samples/client/others/typescript/builds/array-of-lists/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), credentials: "same-origin" }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/client/others/typescript/builds/enum-single-value/http/http.ts b/samples/client/others/typescript/builds/enum-single-value/http/http.ts index fd40471a98f..d48cbd6b770 100644 --- a/samples/client/others/typescript/builds/enum-single-value/http/http.ts +++ b/samples/client/others/typescript/builds/enum-single-value/http/http.ts @@ -49,6 +49,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -125,6 +126,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/client/others/typescript/builds/enum-single-value/http/isomorphic-fetch.ts b/samples/client/others/typescript/builds/enum-single-value/http/isomorphic-fetch.ts index 3af85f3d902..20e2897b9f4 100644 --- a/samples/client/others/typescript/builds/enum-single-value/http/isomorphic-fetch.ts +++ b/samples/client/others/typescript/builds/enum-single-value/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), credentials: "same-origin" }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/client/others/typescript/builds/null-types-simple/http/http.ts b/samples/client/others/typescript/builds/null-types-simple/http/http.ts index fd40471a98f..d48cbd6b770 100644 --- a/samples/client/others/typescript/builds/null-types-simple/http/http.ts +++ b/samples/client/others/typescript/builds/null-types-simple/http/http.ts @@ -49,6 +49,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -125,6 +126,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/client/others/typescript/builds/null-types-simple/http/isomorphic-fetch.ts b/samples/client/others/typescript/builds/null-types-simple/http/isomorphic-fetch.ts index 3af85f3d902..20e2897b9f4 100644 --- a/samples/client/others/typescript/builds/null-types-simple/http/isomorphic-fetch.ts +++ b/samples/client/others/typescript/builds/null-types-simple/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), credentials: "same-origin" }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/client/others/typescript/builds/with-unique-items/http/http.ts b/samples/client/others/typescript/builds/with-unique-items/http/http.ts index fd40471a98f..d48cbd6b770 100644 --- a/samples/client/others/typescript/builds/with-unique-items/http/http.ts +++ b/samples/client/others/typescript/builds/with-unique-items/http/http.ts @@ -49,6 +49,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -125,6 +126,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/client/others/typescript/builds/with-unique-items/http/isomorphic-fetch.ts b/samples/client/others/typescript/builds/with-unique-items/http/isomorphic-fetch.ts index 3af85f3d902..20e2897b9f4 100644 --- a/samples/client/others/typescript/builds/with-unique-items/http/isomorphic-fetch.ts +++ b/samples/client/others/typescript/builds/with-unique-items/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), credentials: "same-origin" }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/client/others/typescript/encode-decode/build/http/http.ts b/samples/client/others/typescript/encode-decode/build/http/http.ts index 115d854c58b..71d0b857678 100644 --- a/samples/client/others/typescript/encode-decode/build/http/http.ts +++ b/samples/client/others/typescript/encode-decode/build/http/http.ts @@ -3,6 +3,7 @@ import * as FormData from "form-data"; import { URL, URLSearchParams } from 'url'; import * as http from 'http'; import * as https from 'https'; +import { AbortSignal } from "node-fetch/externals"; import { Observable, from } from '../rxjsStub'; export * from './isomorphic-fetch'; @@ -57,6 +58,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; private agent: http.Agent | https.Agent | undefined = undefined; /** @@ -135,6 +137,15 @@ export class RequestContext { this.headers[key] = value; } + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + + public setAgent(agent: http.Agent | https.Agent) { this.agent = agent; } diff --git a/samples/client/others/typescript/encode-decode/build/http/isomorphic-fetch.ts b/samples/client/others/typescript/encode-decode/build/http/isomorphic-fetch.ts index 26d267cfc06..d7ce46e4bee 100644 --- a/samples/client/others/typescript/encode-decode/build/http/isomorphic-fetch.ts +++ b/samples/client/others/typescript/encode-decode/build/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), agent: request.getAgent(), }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/openapi3/client/petstore/typescript/builds/browser/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/browser/http/http.ts index fd40471a98f..d48cbd6b770 100644 --- a/samples/openapi3/client/petstore/typescript/builds/browser/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/browser/http/http.ts @@ -49,6 +49,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -125,6 +126,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/openapi3/client/petstore/typescript/builds/browser/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/browser/http/isomorphic-fetch.ts index 3af85f3d902..20e2897b9f4 100644 --- a/samples/openapi3/client/petstore/typescript/builds/browser/http/isomorphic-fetch.ts +++ b/samples/openapi3/client/petstore/typescript/builds/browser/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), credentials: "same-origin" }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/http.ts index fd40471a98f..d48cbd6b770 100644 --- a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/http.ts @@ -49,6 +49,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -125,6 +126,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/isomorphic-fetch.ts index 3af85f3d902..20e2897b9f4 100644 --- a/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/isomorphic-fetch.ts +++ b/samples/openapi3/client/petstore/typescript/builds/composed-schemas/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), credentials: "same-origin" }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/openapi3/client/petstore/typescript/builds/default/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/default/http/http.ts index 115d854c58b..71d0b857678 100644 --- a/samples/openapi3/client/petstore/typescript/builds/default/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/default/http/http.ts @@ -3,6 +3,7 @@ import * as FormData from "form-data"; import { URL, URLSearchParams } from 'url'; import * as http from 'http'; import * as https from 'https'; +import { AbortSignal } from "node-fetch/externals"; import { Observable, from } from '../rxjsStub'; export * from './isomorphic-fetch'; @@ -57,6 +58,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; private agent: http.Agent | https.Agent | undefined = undefined; /** @@ -135,6 +137,15 @@ export class RequestContext { this.headers[key] = value; } + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + + public setAgent(agent: http.Agent | https.Agent) { this.agent = agent; } diff --git a/samples/openapi3/client/petstore/typescript/builds/default/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/default/http/isomorphic-fetch.ts index 26d267cfc06..d7ce46e4bee 100644 --- a/samples/openapi3/client/petstore/typescript/builds/default/http/isomorphic-fetch.ts +++ b/samples/openapi3/client/petstore/typescript/builds/default/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), agent: request.getAgent(), }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/openapi3/client/petstore/typescript/builds/deno/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/deno/http/http.ts index 922bfd778c1..0b57a8a07b1 100644 --- a/samples/openapi3/client/petstore/typescript/builds/deno/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/deno/http/http.ts @@ -48,6 +48,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -124,6 +125,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/openapi3/client/petstore/typescript/builds/deno/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/deno/http/isomorphic-fetch.ts index a7521351e06..af9057a5864 100644 --- a/samples/openapi3/client/petstore/typescript/builds/deno/http/isomorphic-fetch.ts +++ b/samples/openapi3/client/petstore/typescript/builds/deno/http/isomorphic-fetch.ts @@ -11,6 +11,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), }).then((resp: any) => { const headers: { [name: string]: string } = {}; resp.headers.forEach((value: string, name: string) => { diff --git a/samples/openapi3/client/petstore/typescript/builds/deno_object_params/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/deno_object_params/http/http.ts index 922bfd778c1..0b57a8a07b1 100644 --- a/samples/openapi3/client/petstore/typescript/builds/deno_object_params/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/deno_object_params/http/http.ts @@ -48,6 +48,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -124,6 +125,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/openapi3/client/petstore/typescript/builds/deno_object_params/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/deno_object_params/http/isomorphic-fetch.ts index a7521351e06..af9057a5864 100644 --- a/samples/openapi3/client/petstore/typescript/builds/deno_object_params/http/isomorphic-fetch.ts +++ b/samples/openapi3/client/petstore/typescript/builds/deno_object_params/http/isomorphic-fetch.ts @@ -11,6 +11,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), }).then((resp: any) => { const headers: { [name: string]: string } = {}; resp.headers.forEach((value: string, name: string) => { diff --git a/samples/openapi3/client/petstore/typescript/builds/explode-query/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/explode-query/http/http.ts index 115d854c58b..71d0b857678 100644 --- a/samples/openapi3/client/petstore/typescript/builds/explode-query/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/explode-query/http/http.ts @@ -3,6 +3,7 @@ import * as FormData from "form-data"; import { URL, URLSearchParams } from 'url'; import * as http from 'http'; import * as https from 'https'; +import { AbortSignal } from "node-fetch/externals"; import { Observable, from } from '../rxjsStub'; export * from './isomorphic-fetch'; @@ -57,6 +58,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; private agent: http.Agent | https.Agent | undefined = undefined; /** @@ -135,6 +137,15 @@ export class RequestContext { this.headers[key] = value; } + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + + public setAgent(agent: http.Agent | https.Agent) { this.agent = agent; } diff --git a/samples/openapi3/client/petstore/typescript/builds/explode-query/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/explode-query/http/isomorphic-fetch.ts index 26d267cfc06..d7ce46e4bee 100644 --- a/samples/openapi3/client/petstore/typescript/builds/explode-query/http/isomorphic-fetch.ts +++ b/samples/openapi3/client/petstore/typescript/builds/explode-query/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), agent: request.getAgent(), }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/openapi3/client/petstore/typescript/builds/inversify/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/inversify/http/http.ts index 15b563c38ea..743c114004a 100644 --- a/samples/openapi3/client/petstore/typescript/builds/inversify/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/inversify/http/http.ts @@ -3,6 +3,7 @@ import FormData from "form-data"; import { URL, URLSearchParams } from 'url'; import * as http from 'http'; import * as https from 'https'; +import { AbortSignal } from "node-fetch/externals"; import { Observable, from } from '../rxjsStub'; export * from './isomorphic-fetch'; @@ -57,6 +58,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; private agent: http.Agent | https.Agent | undefined = undefined; /** @@ -135,6 +137,15 @@ export class RequestContext { this.headers[key] = value; } + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + + public setAgent(agent: http.Agent | https.Agent) { this.agent = agent; } diff --git a/samples/openapi3/client/petstore/typescript/builds/inversify/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/inversify/http/isomorphic-fetch.ts index 26d267cfc06..d7ce46e4bee 100644 --- a/samples/openapi3/client/petstore/typescript/builds/inversify/http/isomorphic-fetch.ts +++ b/samples/openapi3/client/petstore/typescript/builds/inversify/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), agent: request.getAgent(), }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/openapi3/client/petstore/typescript/builds/jquery/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/jquery/http/http.ts index e65b0b18f33..0fb26e3bb3f 100644 --- a/samples/openapi3/client/petstore/typescript/builds/jquery/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/jquery/http/http.ts @@ -49,6 +49,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -125,6 +126,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/openapi3/client/petstore/typescript/builds/nullable-enum/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/nullable-enum/http/http.ts index fd40471a98f..d48cbd6b770 100644 --- a/samples/openapi3/client/petstore/typescript/builds/nullable-enum/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/nullable-enum/http/http.ts @@ -49,6 +49,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; /** * Creates the request context using a http method and request resource url @@ -125,6 +126,15 @@ export class RequestContext { public setHeaderParam(key: string, value: string): void { this.headers[key] = value; } + + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + } export interface ResponseBody { diff --git a/samples/openapi3/client/petstore/typescript/builds/nullable-enum/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/nullable-enum/http/isomorphic-fetch.ts index 3af85f3d902..20e2897b9f4 100644 --- a/samples/openapi3/client/petstore/typescript/builds/nullable-enum/http/isomorphic-fetch.ts +++ b/samples/openapi3/client/petstore/typescript/builds/nullable-enum/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), credentials: "same-origin" }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/openapi3/client/petstore/typescript/builds/object_params/http/http.ts b/samples/openapi3/client/petstore/typescript/builds/object_params/http/http.ts index 115d854c58b..71d0b857678 100644 --- a/samples/openapi3/client/petstore/typescript/builds/object_params/http/http.ts +++ b/samples/openapi3/client/petstore/typescript/builds/object_params/http/http.ts @@ -3,6 +3,7 @@ import * as FormData from "form-data"; import { URL, URLSearchParams } from 'url'; import * as http from 'http'; import * as https from 'https'; +import { AbortSignal } from "node-fetch/externals"; import { Observable, from } from '../rxjsStub'; export * from './isomorphic-fetch'; @@ -57,6 +58,7 @@ export class RequestContext { private headers: Headers = {}; private body: RequestBody = undefined; private url: URL; + private signal: AbortSignal | undefined = undefined; private agent: http.Agent | https.Agent | undefined = undefined; /** @@ -135,6 +137,15 @@ export class RequestContext { this.headers[key] = value; } + public setSignal(signal: AbortSignal): void { + this.signal = signal; + } + + public getSignal(): AbortSignal | undefined { + return this.signal; + } + + public setAgent(agent: http.Agent | https.Agent) { this.agent = agent; } diff --git a/samples/openapi3/client/petstore/typescript/builds/object_params/http/isomorphic-fetch.ts b/samples/openapi3/client/petstore/typescript/builds/object_params/http/isomorphic-fetch.ts index 26d267cfc06..d7ce46e4bee 100644 --- a/samples/openapi3/client/petstore/typescript/builds/object_params/http/isomorphic-fetch.ts +++ b/samples/openapi3/client/petstore/typescript/builds/object_params/http/isomorphic-fetch.ts @@ -12,6 +12,7 @@ export class IsomorphicFetchHttpLibrary implements HttpLibrary { method: method, body: body as any, headers: request.getHeaders(), + signal: request.getSignal(), agent: request.getAgent(), }).then((resp: any) => { const headers: { [name: string]: string } = {}; diff --git a/samples/openapi3/client/petstore/typescript/tests/default/test/api/PetApi.test.ts b/samples/openapi3/client/petstore/typescript/tests/default/test/api/PetApi.test.ts index c8137a5312e..ca3285d1b12 100644 --- a/samples/openapi3/client/petstore/typescript/tests/default/test/api/PetApi.test.ts +++ b/samples/openapi3/client/petstore/typescript/tests/default/test/api/PetApi.test.ts @@ -14,36 +14,66 @@ tag.id = Math.floor(Math.random() * 100000) let pet: petstore.Pet; function overridePetIDMiddleware(id: number): Middleware { return { - pre: (c: RequestContext) => { - return new Promise((resolve) => { - const segments = c.getUrl().split('/') - segments[segments.length - 1] = id.toString() - const newURL = segments.join('/') - c.setUrl(newURL) - resolve(c) - }) + pre: async (c: RequestContext) => { + const segments = c.getUrl().split('/') + segments[segments.length - 1] = id.toString() + const newURL = segments.join('/') + c.setUrl(newURL) + return c }, - post: (c: ResponseContext) => { - return new Promise((resolve) => { - resolve(c) - }) + post: async (c: ResponseContext) => { + return c }, } } -function NoopMiddleware(onPre: () => void, onPost: () => void): Middleware { +function noopMiddleware(onPre: () => void, onPost: () => void): Middleware { return { - pre: (c: RequestContext) => { - return new Promise((resolve) => { - onPre() - resolve(c) - }) + pre: async (c: RequestContext) => { + onPre() + return c }, - post: (c: ResponseContext) => { + post: async (c: ResponseContext) => { + onPost() + return c + }, + } +} + +/** + * Middleware that adds an abort signal to the request context. + * This can be used to abort requests using an AbortController. + * @param signal AbortSignal to use for the request + * @returns Middleware that sets the signal in the request context + */ +function abortSignalMiddleware(signal: AbortSignal): Middleware { + return { + pre: async (c: RequestContext) => { + c.setSignal(signal) + return c + }, + post: async (c: ResponseContext) => { + return c + }, + } +} + +/** + * Middleware that delays the request/response by a specified amount of time. + * @param delay in milliseconds + * @returns Middleware that delays the request/response + */ +function delayMiddleware(delay: number): Middleware { + return { + pre: async (c: RequestContext) => { + return new Promise((resolve) => { + setTimeout(() => resolve(c), delay); + }); + }, + post: async (c: ResponseContext) => { return new Promise((resolve) => { - onPost() - resolve(c) - }) + setTimeout(() => resolve(c), delay); + }); }, } } @@ -52,8 +82,8 @@ function MiddlewareCallTracker() { let CallOrder = [] as string[] return { CallOrder, - BaseMiddleware: NoopMiddleware(() => CallOrder.push('base-pre'), () => CallOrder.push('base-post')), - CalltimeMiddleware: NoopMiddleware(() => CallOrder.push('call-pre'), () => CallOrder.push('call-post')) + BaseMiddleware: noopMiddleware(() => CallOrder.push('base-pre'), () => CallOrder.push('base-post')), + CalltimeMiddleware: noopMiddleware(() => CallOrder.push('call-pre'), () => CallOrder.push('call-post')) } } @@ -74,88 +104,127 @@ describe("PetApi", () => { expect(createdPet).to.deep.equal(pet); }) - it("addPetViaMiddleware", async () => { - const wrongId = pet.id + 1 - const createdPet = await petApi.getPetById(wrongId, { middleware: [overridePetIDMiddleware(pet.id)] }) - expect(createdPet).to.deep.equal(pet); + describe("Middeware", () => { + + it("addPetViaMiddleware", async () => { + const wrongId = pet.id + 1 + const createdPet = await petApi.getPetById(wrongId, { middleware: [overridePetIDMiddleware(pet.id)] }) + expect(createdPet).to.deep.equal(pet); + }) + + it("appendMiddleware petid", async () => { + const wrongId = pet.id + 100 + const configuration = petstore.createConfiguration({ promiseMiddleware: [overridePetIDMiddleware(wrongId)] }) + const petApi = new petstore.PetApi(configuration) + try { + void await petApi.getPetById(pet.id) + } catch (err) { + expect(err.code).to.equal(404); + expect(err.message).to.include("Pet not found"); + } + const callTimeAppendedRightPet = await petApi.getPetById(wrongId, { middleware: [overridePetIDMiddleware(pet.id)], middlewareMergeStrategy: 'append' }) + expect(callTimeAppendedRightPet).to.deep.equal(pet); + }) + + it("should keep middleware when no options are given", async () => { + let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() + const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }); + const petApi = new petstore.PetApi(configuration); + const callTimeAppendedRightPet = await petApi.getPetById(pet.id); + expect(callTimeAppendedRightPet).to.deep.equal(pet); + expect(CallOrder).deep.equal(['base-pre', 'base-post']) + }) + + it("should keep middleware when options are given without middleware", async () => { + let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() + const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }); + const petApi = new petstore.PetApi(configuration); + const callTimeAppendedRightPet = await petApi.getPetById(pet.id, {}); + expect(callTimeAppendedRightPet).to.deep.equal(pet); + expect(CallOrder).deep.equal(['base-pre', 'base-post']) + }) + + it("should replace middleware when options contain an empty array of middlewares", async () => { + let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() + const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }); + const petApi = new petstore.PetApi(configuration); + const callTimeAppendedRightPet = await petApi.getPetById(pet.id, { middleware: [] }); + expect(callTimeAppendedRightPet).to.deep.equal(pet); + expect(CallOrder).deep.equal([]) + }) + + it("replace Middleware call order", async () => { + let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() + const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }) + const petApi = new petstore.PetApi(configuration) + const callTimeAppendedRightPet = await petApi.getPetById(pet.id, { middleware: [CalltimeMiddleware] }) + expect(callTimeAppendedRightPet).to.deep.equal(pet); + expect(CallOrder).deep.equal(['call-pre', 'call-post']) + }) + + it("prepend Middleware call order", async () => { + let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() + const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }) + const petApi = new petstore.PetApi(configuration) + const callTimeAppendedRightPet = await petApi.getPetById(pet.id, { middleware: [CalltimeMiddleware], middlewareMergeStrategy: 'prepend' }) + expect(callTimeAppendedRightPet).to.deep.equal(pet); + expect(CallOrder).deep.equal(['call-pre', 'base-pre', 'base-post', 'call-post']) + }) + + + it("append Middleware call order", async () => { + let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() + const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }) + const petApi = new petstore.PetApi(configuration) + const callTimeAppendedRightPet = await petApi.getPetById(pet.id, { middleware: [CalltimeMiddleware], middlewareMergeStrategy: 'append' }) + expect(callTimeAppendedRightPet).to.deep.equal(pet); + expect(CallOrder).deep.equal(['base-pre', 'call-pre', 'call-post', 'base-post']) + }) + + + it("prependMiddleware pet id", async () => { + const wrongId = pet.id + 100 + const configuration = petstore.createConfiguration({ promiseMiddleware: [overridePetIDMiddleware(pet.id)] }) + const petApi = new petstore.PetApi(configuration) + const callTimeAppendedRightPet = await petApi.getPetById(wrongId, { middleware: [overridePetIDMiddleware(wrongId)], middlewareMergeStrategy: 'prepend' }) + expect(callTimeAppendedRightPet).to.deep.equal(pet); + }) }) - it("appendMiddleware petid", async () => { - const wrongId = pet.id + 100 - const configuration = petstore.createConfiguration({ promiseMiddleware: [overridePetIDMiddleware(wrongId)] }) - const petApi = new petstore.PetApi(configuration) - try { - void await petApi.getPetById(pet.id) - } catch (err) { - expect(err.code).to.equal(404); - expect(err.message).to.include("Pet not found"); - } - const callTimeAppendedRightPet = await petApi.getPetById(wrongId, { middleware: [overridePetIDMiddleware(pet.id)], middlewareMergeStrategy: 'append' }) - expect(callTimeAppendedRightPet).to.deep.equal(pet); - }) - - it("should keep middleware when no options are given", async () => { - let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() - const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }); - const petApi = new petstore.PetApi(configuration); - const callTimeAppendedRightPet = await petApi.getPetById(pet.id); - expect(callTimeAppendedRightPet).to.deep.equal(pet); - expect(CallOrder).deep.equal(['base-pre', 'base-post']) - }) - - it("should keep middleware when options are given without middleware", async () => { - let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() - const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }); - const petApi = new petstore.PetApi(configuration); - const callTimeAppendedRightPet = await petApi.getPetById(pet.id, {}); - expect(callTimeAppendedRightPet).to.deep.equal(pet); - expect(CallOrder).deep.equal(['base-pre', 'base-post']) - }) - - it("should replace middleware when options contain an empty array of middlewares", async () => { - let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() - const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }); - const petApi = new petstore.PetApi(configuration); - const callTimeAppendedRightPet = await petApi.getPetById(pet.id, { middleware: [] }); - expect(callTimeAppendedRightPet).to.deep.equal(pet); - expect(CallOrder).deep.equal([]) - }) - - it("replace Middleware call order", async () => { - let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() - const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }) - const petApi = new petstore.PetApi(configuration) - const callTimeAppendedRightPet = await petApi.getPetById(pet.id, { middleware: [CalltimeMiddleware] }) - expect(callTimeAppendedRightPet).to.deep.equal(pet); - expect(CallOrder).deep.equal(['call-pre', 'call-post']) - }) - - it("prepend Middleware call order", async () => { - let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() - const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }) - const petApi = new petstore.PetApi(configuration) - const callTimeAppendedRightPet = await petApi.getPetById(pet.id, { middleware: [CalltimeMiddleware], middlewareMergeStrategy: 'prepend' }) - expect(callTimeAppendedRightPet).to.deep.equal(pet); - expect(CallOrder).deep.equal(['call-pre', 'base-pre', 'base-post','call-post']) - }) - - - it("append Middleware call order", async () => { - let { CallOrder, BaseMiddleware, CalltimeMiddleware } = MiddlewareCallTracker() - const configuration = petstore.createConfiguration({ promiseMiddleware: [BaseMiddleware] }) - const petApi = new petstore.PetApi(configuration) - const callTimeAppendedRightPet = await petApi.getPetById(pet.id, { middleware: [CalltimeMiddleware],middlewareMergeStrategy: 'append' }) - expect(callTimeAppendedRightPet).to.deep.equal(pet); - expect(CallOrder).deep.equal(['base-pre','call-pre','call-post','base-post']) - }) - - - it("prependMiddleware pet id", async () => { - const wrongId = pet.id + 100 - const configuration = petstore.createConfiguration({ promiseMiddleware: [overridePetIDMiddleware(pet.id)] }) - const petApi = new petstore.PetApi(configuration) - const callTimeAppendedRightPet = await petApi.getPetById(wrongId, { middleware: [overridePetIDMiddleware(wrongId)], middlewareMergeStrategy: 'prepend' }) - expect(callTimeAppendedRightPet).to.deep.equal(pet); + describe("AbortController", () => { + it("fails on invalid requests", async () => { + const controller = new AbortController(); + const abortMiddleware = abortSignalMiddleware(controller.signal); + const wrongId = pet.id + 1 + try { + await petApi.getPetById(wrongId, { middleware: [abortMiddleware] }) + } catch (err) { + expect(err.code).to.equal(404); + } + }) + it("succeeds on valid requests", async () => { + const controller = new AbortController(); + const abortMiddleware = abortSignalMiddleware(controller.signal); + const createdPet = await petApi.getPetById(pet.id, { middleware: [abortMiddleware] }) + expect(createdPet).to.deep.equal(pet); + }) + it("aborts request", async () => { + const signal = AbortSignal.timeout(10); // Set a timeout to ensure the request is aborted + const abortMiddleware = abortSignalMiddleware(signal); + try { + await petApi.getPetById(pet.id, { middleware: [abortMiddleware, delayMiddleware(20)] }) + } catch (err) { + expect(err.name).to.equal("AbortError"); + return; + } + throw new Error("Request was not aborted!"); + }) + it("ignores abort after response", async () => { + const signal = AbortSignal.timeout(20); // Set a timeout to ensure the request is aborted + const abortMiddleware = abortSignalMiddleware(signal); + const createdPet = await petApi.getPetById(pet.id, { middleware: [abortMiddleware, delayMiddleware(10)] }) + expect(createdPet).to.deep.equal(pet); + }) }) it("should override http api from option", async () => {