diff --git a/frontend/lib/api/__test__/test-utils.ts b/frontend/lib/api/__test__/test-utils.ts index d766d76..a46f21a 100644 --- a/frontend/lib/api/__test__/test-utils.ts +++ b/frontend/lib/api/__test__/test-utils.ts @@ -1,18 +1,18 @@ import { beforeAll, expect } from 'vitest'; import { Requests } from '../../requests'; -import { OverrideParts } from '../base/urls'; +import { overrideParts } from '../base/urls'; import { PublicApi } from '../public'; import * as config from '../../../test/config'; import { UserApi } from '../user'; export function client() { - OverrideParts(config.BASE_URL, '/api/v1'); + overrideParts(config.BASE_URL, '/api/v1'); const requests = new Requests(''); return new PublicApi(requests); } export function userClient(token: string) { - OverrideParts(config.BASE_URL, '/api/v1'); + overrideParts(config.BASE_URL, '/api/v1'); const requests = new Requests('', token); return new UserApi(requests); } diff --git a/frontend/lib/api/base/index.test.ts b/frontend/lib/api/base/index.test.ts index 2f40e0c..87401f7 100644 --- a/frontend/lib/api/base/index.test.ts +++ b/frontend/lib/api/base/index.test.ts @@ -1,24 +1,24 @@ import { describe, expect, it } from 'vitest'; -import { UrlBuilder } from '.'; +import { route } from '.'; describe('UrlBuilder', () => { - it('basic query parameter', () => { - const result = UrlBuilder('/test', { a: 'b' }); - expect(result).toBe('/api/v1/test?a=b'); - }); + it('basic query parameter', () => { + const result = route('/test', { a: 'b' }); + expect(result).toBe('/api/v1/test?a=b'); + }); - it('multiple query parameters', () => { - const result = UrlBuilder('/test', { a: 'b', c: 'd' }); - expect(result).toBe('/api/v1/test?a=b&c=d'); - }); + it('multiple query parameters', () => { + const result = route('/test', { a: 'b', c: 'd' }); + expect(result).toBe('/api/v1/test?a=b&c=d'); + }); - it('no query parameters', () => { - const result = UrlBuilder('/test'); - expect(result).toBe('/api/v1/test'); - }); + it('no query parameters', () => { + const result = route('/test'); + expect(result).toBe('/api/v1/test'); + }); - it('list-like query parameters', () => { - const result = UrlBuilder('/test', { a: ['b', 'c'] }); - expect(result).toBe('/api/v1/test?a=b&a=c'); - }); + it('list-like query parameters', () => { + const result = route('/test', { a: ['b', 'c'] }); + expect(result).toBe('/api/v1/test?a=b&a=c'); + }); }); diff --git a/frontend/lib/api/base/index.ts b/frontend/lib/api/base/index.ts index 12f6df5..58ddbae 100644 --- a/frontend/lib/api/base/index.ts +++ b/frontend/lib/api/base/index.ts @@ -1,2 +1,2 @@ export { BaseAPI } from './base-api'; -export { UrlBuilder } from './urls'; +export { route } from './urls'; diff --git a/frontend/lib/api/base/urls.ts b/frontend/lib/api/base/urls.ts index bb40883..4185383 100644 --- a/frontend/lib/api/base/urls.ts +++ b/frontend/lib/api/base/urls.ts @@ -3,14 +3,23 @@ const parts = { prefix: '/api/v1', }; -export function OverrideParts(host: string, prefix: string) { +export function overrideParts(host: string, prefix: string) { parts.host = host; parts.prefix = prefix; } export type QueryValue = string | string[] | number | number[] | boolean | null | undefined; -export function UrlBuilder(rest: string, params: Record = {}): string { +/** + * route is a the main URL builder for the API. It will use a predefined host and prefix (global) + * in the urls.ts file and then append the passed in path parameter uring the `URL` class from the + * browser. It will also append any query parameters passed in as the second parameter. + * + * The default host `http://localhost.com` is removed from the path if it is present. This allows us + * to bootstrap the API with different hosts as needed (like for testing) but still allows us to use + * relative URLs in pruduction because the API and client bundle are served from the same server/host. + */ +export function route(rest: string, params: Record = {}): string { const url = new URL(parts.prefix + rest, parts.host); for (const [key, value] of Object.entries(params)) { @@ -23,6 +32,5 @@ export function UrlBuilder(rest: string, params: Record = {} } } - // we return the path only, without the base URL return url.toString().replace('http://localhost.com', ''); } diff --git a/frontend/lib/api/classes/items.ts b/frontend/lib/api/classes/items.ts index cba979e..b6398ec 100644 --- a/frontend/lib/api/classes/items.ts +++ b/frontend/lib/api/classes/items.ts @@ -1,4 +1,4 @@ -import { BaseAPI, UrlBuilder } from '../base'; +import { BaseAPI, route } from '../base'; import { Label } from './labels'; import { Location } from './locations'; import { Results } from './types'; @@ -33,22 +33,22 @@ export interface Item { export class ItemsApi extends BaseAPI { async getAll() { - return this.http.get>(UrlBuilder('/items')); + return this.http.get>(route('/items')); } async create(item: ItemCreate) { - return this.http.post(UrlBuilder('/items'), item); + return this.http.post(route('/items'), item); } async get(id: string) { - return this.http.get(UrlBuilder(`/items/${id}`)); + return this.http.get(route(`/items/${id}`)); } async delete(id: string) { - return this.http.delete(UrlBuilder(`/items/${id}`)); + return this.http.delete(route(`/items/${id}`)); } async update(id: string, item: ItemCreate) { - return this.http.put(UrlBuilder(`/items/${id}`), item); + return this.http.put(route(`/items/${id}`), item); } } diff --git a/frontend/lib/api/classes/labels.ts b/frontend/lib/api/classes/labels.ts index 82aa005..32ab306 100644 --- a/frontend/lib/api/classes/labels.ts +++ b/frontend/lib/api/classes/labels.ts @@ -1,4 +1,4 @@ -import { BaseAPI, UrlBuilder } from '../base'; +import { BaseAPI, route } from '../base'; import { Details, OutType, Results } from './types'; export type LabelCreate = Details & { @@ -14,22 +14,22 @@ export type Label = LabelCreate & export class LabelsApi extends BaseAPI { async getAll() { - return this.http.get>(UrlBuilder('/labels')); + return this.http.get>(route('/labels')); } async create(label: LabelCreate) { - return this.http.post(UrlBuilder('/labels'), label); + return this.http.post(route('/labels'), label); } async get(id: string) { - return this.http.get