[typescript] Fix support for relative URLs (#15482)

* Add test for different url types

* Fix tests for typescript inversify framework

* Add workaround for relative URLs

* Regenerate samples
This commit is contained in:
Bodo Graumann 2023-07-06 17:30:19 +02:00 committed by GitHub
parent a16a315fee
commit ba1c600830
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 111 additions and 21 deletions

View File

@ -63,6 +63,20 @@ export class HttpException extends Error {
*/ */
export type RequestBody = undefined | string | FormData | URLSearchParams; export type RequestBody = undefined | string | FormData | URLSearchParams;
function ensureAbsoluteUrl(url: string) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
{{#platforms}}
{{#node}}
throw new Error("You need to define an absolute base url for the server.");
{{/node}}
{{^node}}
return window.location.origin + url;
{{/node}}
{{/platforms}}
}
/** /**
* Represents an HTTP request context * Represents an HTTP request context
*/ */
@ -83,7 +97,7 @@ export class RequestContext {
* @param httpMethod http method * @param httpMethod http method
*/ */
public constructor(url: string, private httpMethod: HttpMethod) { public constructor(url: string, private httpMethod: HttpMethod) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/* /*
@ -101,7 +115,7 @@ export class RequestContext {
* *
*/ */
public setUrl(url: string) { public setUrl(url: string) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/** /**

View File

@ -33,6 +33,13 @@ export class HttpException extends Error {
*/ */
export type RequestBody = undefined | string | FormData | URLSearchParams; export type RequestBody = undefined | string | FormData | URLSearchParams;
function ensureAbsoluteUrl(url: string) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
return window.location.origin + url;
}
/** /**
* Represents an HTTP request context * Represents an HTTP request context
*/ */
@ -48,7 +55,7 @@ export class RequestContext {
* @param httpMethod http method * @param httpMethod http method
*/ */
public constructor(url: string, private httpMethod: HttpMethod) { public constructor(url: string, private httpMethod: HttpMethod) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/* /*
@ -66,7 +73,7 @@ export class RequestContext {
* *
*/ */
public setUrl(url: string) { public setUrl(url: string) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/** /**

View File

@ -33,6 +33,13 @@ export class HttpException extends Error {
*/ */
export type RequestBody = undefined | string | FormData | URLSearchParams; export type RequestBody = undefined | string | FormData | URLSearchParams;
function ensureAbsoluteUrl(url: string) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
return window.location.origin + url;
}
/** /**
* Represents an HTTP request context * Represents an HTTP request context
*/ */
@ -48,7 +55,7 @@ export class RequestContext {
* @param httpMethod http method * @param httpMethod http method
*/ */
public constructor(url: string, private httpMethod: HttpMethod) { public constructor(url: string, private httpMethod: HttpMethod) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/* /*
@ -66,7 +73,7 @@ export class RequestContext {
* *
*/ */
public setUrl(url: string) { public setUrl(url: string) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/** /**

View File

@ -33,6 +33,13 @@ export class HttpException extends Error {
*/ */
export type RequestBody = undefined | string | FormData | URLSearchParams; export type RequestBody = undefined | string | FormData | URLSearchParams;
function ensureAbsoluteUrl(url: string) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
return window.location.origin + url;
}
/** /**
* Represents an HTTP request context * Represents an HTTP request context
*/ */
@ -48,7 +55,7 @@ export class RequestContext {
* @param httpMethod http method * @param httpMethod http method
*/ */
public constructor(url: string, private httpMethod: HttpMethod) { public constructor(url: string, private httpMethod: HttpMethod) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/* /*
@ -66,7 +73,7 @@ export class RequestContext {
* *
*/ */
public setUrl(url: string) { public setUrl(url: string) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/** /**

View File

@ -41,6 +41,13 @@ export class HttpException extends Error {
*/ */
export type RequestBody = undefined | string | FormData | URLSearchParams; export type RequestBody = undefined | string | FormData | URLSearchParams;
function ensureAbsoluteUrl(url: string) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
throw new Error("You need to define an absolute base url for the server.");
}
/** /**
* Represents an HTTP request context * Represents an HTTP request context
*/ */
@ -57,7 +64,7 @@ export class RequestContext {
* @param httpMethod http method * @param httpMethod http method
*/ */
public constructor(url: string, private httpMethod: HttpMethod) { public constructor(url: string, private httpMethod: HttpMethod) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/* /*
@ -75,7 +82,7 @@ export class RequestContext {
* *
*/ */
public setUrl(url: string) { public setUrl(url: string) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/** /**

View File

@ -32,6 +32,13 @@ export class HttpException extends Error {
*/ */
export type RequestBody = undefined | string | FormData | URLSearchParams; export type RequestBody = undefined | string | FormData | URLSearchParams;
function ensureAbsoluteUrl(url: string) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
return window.location.origin + url;
}
/** /**
* Represents an HTTP request context * Represents an HTTP request context
*/ */
@ -47,7 +54,7 @@ export class RequestContext {
* @param httpMethod http method * @param httpMethod http method
*/ */
public constructor(url: string, private httpMethod: HttpMethod) { public constructor(url: string, private httpMethod: HttpMethod) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/* /*
@ -65,7 +72,7 @@ export class RequestContext {
* *
*/ */
public setUrl(url: string) { public setUrl(url: string) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/** /**

View File

@ -41,6 +41,13 @@ export class HttpException extends Error {
*/ */
export type RequestBody = undefined | string | FormData | URLSearchParams; export type RequestBody = undefined | string | FormData | URLSearchParams;
function ensureAbsoluteUrl(url: string) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
throw new Error("You need to define an absolute base url for the server.");
}
/** /**
* Represents an HTTP request context * Represents an HTTP request context
*/ */
@ -57,7 +64,7 @@ export class RequestContext {
* @param httpMethod http method * @param httpMethod http method
*/ */
public constructor(url: string, private httpMethod: HttpMethod) { public constructor(url: string, private httpMethod: HttpMethod) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/* /*
@ -75,7 +82,7 @@ export class RequestContext {
* *
*/ */
public setUrl(url: string) { public setUrl(url: string) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/** /**

View File

@ -33,6 +33,13 @@ export class HttpException extends Error {
*/ */
export type RequestBody = undefined | string | FormData | URLSearchParams; export type RequestBody = undefined | string | FormData | URLSearchParams;
function ensureAbsoluteUrl(url: string) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
return window.location.origin + url;
}
/** /**
* Represents an HTTP request context * Represents an HTTP request context
*/ */
@ -48,7 +55,7 @@ export class RequestContext {
* @param httpMethod http method * @param httpMethod http method
*/ */
public constructor(url: string, private httpMethod: HttpMethod) { public constructor(url: string, private httpMethod: HttpMethod) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/* /*
@ -66,7 +73,7 @@ export class RequestContext {
* *
*/ */
public setUrl(url: string) { public setUrl(url: string) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/** /**

View File

@ -41,6 +41,13 @@ export class HttpException extends Error {
*/ */
export type RequestBody = undefined | string | FormData | URLSearchParams; export type RequestBody = undefined | string | FormData | URLSearchParams;
function ensureAbsoluteUrl(url: string) {
if (url.startsWith("http://") || url.startsWith("https://")) {
return url;
}
throw new Error("You need to define an absolute base url for the server.");
}
/** /**
* Represents an HTTP request context * Represents an HTTP request context
*/ */
@ -57,7 +64,7 @@ export class RequestContext {
* @param httpMethod http method * @param httpMethod http method
*/ */
public constructor(url: string, private httpMethod: HttpMethod) { public constructor(url: string, private httpMethod: HttpMethod) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/* /*
@ -75,7 +82,7 @@ export class RequestContext {
* *
*/ */
public setUrl(url: string) { public setUrl(url: string) {
this.url = new URL(url); this.url = new URL(ensureAbsoluteUrl(url));
} }
/** /**

View File

@ -0,0 +1,19 @@
import { expect } from '@esm-bundle/chai';
import { ServerConfiguration, HttpMethod } from 'ts-petstore-client'
describe("ServerConfiguration", () => {
it("supports absolute http URLs", async () => {
const config = new ServerConfiguration("http://localhost/v2", {});
expect(config.makeRequestContext("/resource", HttpMethod.PUT).getUrl()).to.equal("http://localhost/v2/resource");
})
it("supports absolute https URLs", async () => {
const config = new ServerConfiguration("https://localhost/v2", {});
expect(config.makeRequestContext("/resource", HttpMethod.PUT).getUrl()).to.equal("https://localhost/v2/resource");
})
it("supports relative URLs", async () => {
const config = new ServerConfiguration("/api", {});
expect(config.makeRequestContext("/resource", HttpMethod.PUT).getUrl()).to.equal("http://localhost:8080/api/resource");
})
})

View File

@ -4,6 +4,7 @@ export default {
files: "./dist/*.test.js", files: "./dist/*.test.js",
nodeResolve: true, nodeResolve: true,
manual: false, manual: false,
port: 8080,
browsers: [ browsers: [
puppeteerLauncher(), puppeteerLauncher(),
], ],

View File

@ -2,7 +2,7 @@ import "reflect-metadata";
import { Container } from "inversify"; import { Container } from "inversify";
import * as petstore from "ts-petstore-client"; import * as petstore from "ts-petstore-client";
import * as petstoreInternals from "ts-petstore-client/dist/apis/PetApi"; import * as petstoreInternals from "../../../builds/inversify/dist/apis/PetApi";
import { expect, assert } from "chai"; import { expect, assert } from "chai";
import * as fs from "fs"; import * as fs from "fs";
@ -20,7 +20,7 @@ describe("ApiServiceBinder", () => {
}); });
it("binds server config", async () => { it("binds server config", async () => {
const url = "foobar"; const url = "http://foobar";
let callCount = 0; let callCount = 0;
const mockServer = { const mockServer = {
makeRequestContext(endpoint: string, httpMethod: petstore.HttpMethod): petstore.RequestContext { makeRequestContext(endpoint: string, httpMethod: petstore.HttpMethod): petstore.RequestContext {
@ -45,7 +45,7 @@ describe("ApiServiceBinder", () => {
}); });
it("binds server config to url", async () => { it("binds server config to url", async () => {
const url = "foobar"; const url = "http://foobar";
const petId = 42; const petId = 42;
apiServiceBinder.bindServerConfigurationToURL(url); apiServiceBinder.bindServerConfigurationToURL(url);