Skip to content

Commit

Permalink
Respect config.url as source of truth for API calls (#138)
Browse files Browse the repository at this point in the history
* Use config.url as source of truth for base API URL, allowing for other protocols

Co-authored-by: David Graham <[email protected]>

* Add test for seeing if HTTP calls work.

Co-authored-by: David Graham <[email protected]>

---------

Co-authored-by: David Graham <[email protected]>
  • Loading branch information
iheanyi and dgraham authored Aug 21, 2023
1 parent 488e48b commit 0c3dea9
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
22 changes: 19 additions & 3 deletions __tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { cast, connect, format, hex, ExecutedQuery, DatabaseError } from '../dis
import { fetch, MockAgent, setGlobalDispatcher } from 'undici'
import packageJSON from '../package.json'

const mockHost = 'https://example.com'

const mockHosts = ['http://localhost:8080', 'https://example.com']
const CREATE_SESSION_PATH = '/psdb.v1alpha1.Database/CreateSession'
const EXECUTE_PATH = '/psdb.v1alpha1.Database/Execute'
const config = {
Expand All @@ -20,7 +19,7 @@ mockAgent.disableNetConnect()
setGlobalDispatcher(mockAgent)

// Provide the base url to the request
const mockPool = mockAgent.get(mockHost)
const mockPool = mockAgent.get((value) => mockHosts.includes(value))
const mockSession = 42

describe('config', () => {
Expand All @@ -40,6 +39,23 @@ describe('config', () => {
const got = await connection.execute('SELECT 1 from dual;')
expect(got).toBeDefined()
})

test('parses database URL when using HTTP', async () => {
const mockResponse = {
session: mockSession,
result: { fields: [], rows: [] }
}

mockPool.intercept({ path: EXECUTE_PATH, method: 'POST' }).reply(200, (opts) => {
expect(opts.headers['Authorization']).toEqual(`Basic ${btoa('someuser:password')}`)
expect(opts.headers['User-Agent']).toEqual(`database-js/${packageJSON.version}`)
return mockResponse
})

const connection = connect({ fetch, url: 'http://someuser:password@localhost:8080' })
const got = await connection.execute('SELECT 1 from dual;')
expect(got).toBeDefined()
})
})

describe('transaction', () => {
Expand Down
18 changes: 16 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,20 @@ class Tx {
}
}

function protocol(protocol: string): string {
return protocol === 'http:' ? protocol : 'https:'
}

function buildURL(url: URL): string {
const scheme = `${protocol(url.protocol)}//`

return new URL(url.pathname, `${scheme}${url.host}`).toString()
}

export class Connection {
private config: Config
private session: QuerySession | null
private url: string

constructor(config: Config) {
this.session = null
Expand All @@ -172,6 +183,9 @@ export class Connection {
this.config.username = url.username
this.config.password = url.password
this.config.host = url.hostname
this.url = buildURL(url)
} else {
this.url = new URL(`https://${this.config.host}`).toString()
}
}

Expand Down Expand Up @@ -200,7 +214,7 @@ export class Connection {
args: ExecuteArgs = null,
options: ExecuteOptions = defaultExecuteOptions
): Promise<ExecutedQuery> {
const url = new URL('/psdb.v1alpha1.Database/Execute', `https://${this.config.host}`)
const url = new URL('/psdb.v1alpha1.Database/Execute', this.url)

const formatter = this.config.format || format
const sql = args ? formatter(query, args) : query
Expand Down Expand Up @@ -251,7 +265,7 @@ export class Connection {
}

private async createSession(): Promise<QuerySession> {
const url = new URL('/psdb.v1alpha1.Database/CreateSession', `https://${this.config.host}`)
const url = new URL('/psdb.v1alpha1.Database/CreateSession', this.url)
const { session } = await postJSON<QueryExecuteResponse>(this.config, url)
this.session = session
return session
Expand Down

0 comments on commit 0c3dea9

Please sign in to comment.