Skip to content

Commit 1a1f0bc

Browse files
committed
gh-87 Make scheme parameter optional
1 parent 655aa47 commit 1a1f0bc

File tree

5 files changed

+76
-24
lines changed

5 files changed

+76
-24
lines changed

src/connection/gqlClient.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ export interface GraphQLClient {
99
export const gqlClient = (config: ConnectionParams): GraphQLClient => {
1010
const defaultHeaders = config.headers;
1111
const version = '/v1/graphql';
12-
const baseUri = config.host.startsWith(`${config.scheme}://`)
13-
? `${config.host}${version}`
14-
: `${config.scheme}://${config.host}${version}`;
12+
const baseUri = `${config.host}${version}`;
1513

1614
return {
1715
// for backward compatibility with replaced graphql-client lib,

src/connection/httpClient.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ export interface HttpClient {
1515

1616
export const httpClient = (config: ConnectionParams): HttpClient => {
1717
const version = '/v1';
18-
const baseUri = config.host.startsWith(`${config.scheme}://`)
19-
? `${config.host}${version}`
20-
: `${config.scheme}://${config.host}${version}`;
18+
const baseUri = `${config.host}${version}`;
2119
const url = makeUrl(baseUri);
2220

2321
return {

src/connection/index.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ export default class Connection {
1010
private apiKey?: string;
1111
private authEnabled: boolean;
1212
private gql: GraphQLClient;
13+
public readonly host: string;
1314
public readonly http: HttpClient;
1415
public oidcAuth?: OidcAuthenticator;
1516

1617
constructor(params: ConnectionParams) {
1718
params = this.sanitizeParams(params);
19+
this.host = params.host;
1820
this.http = httpClient(params);
1921
this.gql = gqlClient(params);
2022
this.authEnabled = this.parseAuthParams(params);
@@ -36,10 +38,32 @@ export default class Connection {
3638
}
3739

3840
private sanitizeParams(params: ConnectionParams) {
41+
// Remove trailing slashes from the host
3942
while (params.host.endsWith('/')) {
4043
params.host = params.host.slice(0, -1);
4144
}
4245

46+
const protocolPattern = /^(https?:\/\/|ftp:\/\/|file:\/\/)/;
47+
const extractedSchemeMatch = params.host.match(protocolPattern);
48+
49+
// Check for the existence of scheme in params
50+
if (params.scheme) {
51+
// If the host contains a scheme different than provided scheme, replace it and throw a warning
52+
if (extractedSchemeMatch && extractedSchemeMatch[0] !== `${params.scheme}://`) {
53+
throw new Error(
54+
`The host contains a different protocol than specified in the scheme (scheme: ${params.scheme}:// != host: ${extractedSchemeMatch[0]})`
55+
);
56+
} else if (!extractedSchemeMatch) {
57+
// If no scheme in the host, simply prefix with the provided scheme
58+
params.host = `${params.scheme}://${params.host}`;
59+
}
60+
// If there's no scheme in params, ensure the host starts with a recognized protocol
61+
} else if (!extractedSchemeMatch) {
62+
throw new Error(
63+
'The host must start with a recognized protocol (e.g., http:// or https://) if no scheme is provided.'
64+
);
65+
}
66+
4367
return params;
4468
}
4569

src/connection/unit.test.ts

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -124,38 +124,73 @@ describe('mock server auth tests', () => {
124124
await conn.login().then((key) => expect(key).toEqual(apiKey));
125125
});
126126

127-
it('should construct the correct baseUri for conn.http when host contains scheme', async () => {
127+
it('should construct the correct url when host contains scheme', () => {
128128
const apiKey = 'abcd123';
129129

130130
const conn = new Connection({
131131
scheme: 'http',
132132
host: 'http://localhost:' + server.port,
133133
apiKey: new ApiKey(apiKey),
134134
});
135+
const expectedPath = 'http://localhost:' + server.port;
135136

136-
await conn.http.get('/testEndpoint');
137-
const lastRequestURL = server.lastRequest().path; // Get the path of the last request
138-
const expectedPath = '/v1/testEndpoint';
139-
expect(lastRequestURL).toEqual(expectedPath);
137+
expect(conn.host).toEqual(expectedPath);
140138
});
141139

142-
it('should construct the correct baseUri for conn.query when host contains scheme', async () => {
140+
it('should construct the correct url when scheme specified and host does not contain scheme', () => {
143141
const apiKey = 'abcd123';
144142

145143
const conn = new Connection({
146144
scheme: 'http',
145+
host: 'localhost:' + server.port,
146+
apiKey: new ApiKey(apiKey),
147+
});
148+
const expectedPath = 'http://localhost:' + server.port;
149+
150+
expect(conn.host).toEqual(expectedPath);
151+
});
152+
153+
it('should construct the correct url when no scheme is specified but host contains scheme', () => {
154+
const apiKey = 'abcd123';
155+
156+
const conn = new Connection({
147157
host: 'http://localhost:' + server.port,
148158
apiKey: new ApiKey(apiKey),
149159
});
160+
const expectedPath = 'http://localhost:' + server.port;
161+
162+
expect(conn.host).toEqual(expectedPath);
163+
});
164+
165+
it('should throw error when host contains different scheme than specified', () => {
166+
const apiKey = 'abcd123';
167+
168+
const createConnection = () => {
169+
return new Connection({
170+
scheme: 'https',
171+
host: 'http://localhost:' + server.port,
172+
apiKey: new ApiKey(apiKey),
173+
});
174+
};
175+
176+
expect(createConnection).toThrow(
177+
'The host contains a different protocol than specified in the scheme (scheme: https:// != host: http://)'
178+
);
179+
});
180+
181+
it('should throw error when scheme not specified and included in host', () => {
182+
const apiKey = 'abcd123';
183+
184+
const createConnection = () => {
185+
return new Connection({
186+
host: 'localhost:' + server.port,
187+
apiKey: new ApiKey(apiKey),
188+
});
189+
};
150190

151-
try {
152-
await conn.query('{ query { users } }');
153-
} catch (error) {
154-
// We just want to test the last request path
155-
}
156-
const lastRequestURL = server.lastRequest().path;
157-
const expectedPath = '/v1/graphql';
158-
expect(lastRequestURL).toEqual(expectedPath);
191+
expect(createConnection).toThrow(
192+
'The host must start with a recognized protocol (e.g., http:// or https://) if no scheme is provided.'
193+
);
159194
});
160195

161196
it('shuts down the server', () => {

src/index.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export interface ConnectionParams {
2222
authClientSecret?: AuthClientCredentials | AuthAccessTokenCredentials | AuthUserPasswordCredentials;
2323
apiKey?: ApiKey;
2424
host: string;
25-
scheme: string;
25+
scheme?: string;
2626
headers?: HeadersInit;
2727
}
2828

@@ -44,9 +44,6 @@ const app = {
4444
// check if the URL is set
4545
if (!params.host) throw new Error('Missing `host` parameter');
4646

47-
// check if the scheme is set
48-
if (!params.scheme) throw new Error('Missing `scheme` parameter');
49-
5047
// check if headers are set
5148
if (!params.headers) params.headers = {};
5249

0 commit comments

Comments
 (0)