From a44c06f40c6fb95440259f45479da8a112a1c5bd Mon Sep 17 00:00:00 2001 From: Jayan Ratna Date: Thu, 18 Jul 2024 15:47:37 +1200 Subject: [PATCH 1/7] feat: Add Agency API --- src/blutui.ts | 2 + .../agency/agencies/agencies.spec.ts | 0 src/resources/agency/agencies/agencies.ts | 51 +++++++++++++++++++ .../agencies/interfaces/agency.interface.ts | 37 ++++++++++++++ .../agency/agencies/interfaces/index.ts | 2 + .../update-agency-options.interface.ts | 19 +++++++ .../agencies/serializers/agency.serializer.ts | 30 +++++++++++ .../agency/agencies/serializers/index.ts | 2 + .../update-agency-options.serializer.ts | 16 ++++++ src/resources/agency/index.ts | 1 + src/resources/agency/projects/projects.ts | 9 ++-- .../serializers/project.serializer.ts | 2 +- 12 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 src/resources/agency/agencies/agencies.spec.ts create mode 100644 src/resources/agency/agencies/agencies.ts create mode 100644 src/resources/agency/agencies/interfaces/agency.interface.ts create mode 100644 src/resources/agency/agencies/interfaces/index.ts create mode 100644 src/resources/agency/agencies/interfaces/update-agency-options.interface.ts create mode 100644 src/resources/agency/agencies/serializers/agency.serializer.ts create mode 100644 src/resources/agency/agencies/serializers/index.ts create mode 100644 src/resources/agency/agencies/serializers/update-agency-options.serializer.ts diff --git a/src/blutui.ts b/src/blutui.ts index f3c910b..d395cc2 100644 --- a/src/blutui.ts +++ b/src/blutui.ts @@ -11,6 +11,7 @@ import { import { Client } from './utils/client' import { User } from './resources' +import { Agencies } from './resources/agency' import type { BlutuiOptions, @@ -30,6 +31,7 @@ export class Blutui { private readonly client: Client private readonly _agencies: Record = {} + readonly agencies = new Agencies(this) readonly user = new User(this) /** diff --git a/src/resources/agency/agencies/agencies.spec.ts b/src/resources/agency/agencies/agencies.spec.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/resources/agency/agencies/agencies.ts b/src/resources/agency/agencies/agencies.ts new file mode 100644 index 0000000..b3474a1 --- /dev/null +++ b/src/resources/agency/agencies/agencies.ts @@ -0,0 +1,51 @@ +import { Blutui } from '@/blutui' + +import { + Agency, + AgencyResponse, + SerializedUpdateAgencyOptions, + UpdateAgencyOptions, +} from './interfaces' +import { + deserializeAgency, + deserializeAgencyList, + serializeUpdateAgencyOptions, +} from './serializers' +import { List, ListResponse, PaginationOptions } from '@/types' + +export class Agencies { + constructor(private readonly blutui: Blutui) {} + + /** + * Retrieve a list of agencies you belong to. + */ + async list(options?: PaginationOptions): Promise> { + const { data } = await this.blutui.get>( + 'agencies', + { query: options } + ) + + return deserializeAgencyList(data) + } + + /** + * Get an agency you belong to, by ID. + */ + async get(id: string): Promise { + const { data } = await this.blutui.get(`agencies/${id}`) + + return deserializeAgency(data) + } + + /** + * Update an agency you belong to, by ID. + */ + async update(id: string, payload: UpdateAgencyOptions): Promise { + const { data } = await this.blutui.patch< + AgencyResponse, + SerializedUpdateAgencyOptions + >(`agencies/${id}`, serializeUpdateAgencyOptions(payload)) + + return deserializeAgency(data) + } +} diff --git a/src/resources/agency/agencies/interfaces/agency.interface.ts b/src/resources/agency/agencies/interfaces/agency.interface.ts new file mode 100644 index 0000000..d08d4ea --- /dev/null +++ b/src/resources/agency/agencies/interfaces/agency.interface.ts @@ -0,0 +1,37 @@ +export interface Agency { + id: string + object: 'agency' + name: string + email: string + slug: string + url: string | null + location: string + timezone: string + avatar: string | null + description: string | null + trialMode: boolean + isAgency: boolean + isAwsCustomer: boolean + createdAt: number + updatedAt: number + deletedAt?: number +} + +export interface AgencyResponse { + id: string + object: 'agency' + name: string + email: string + slug: string + url: string | null + location: string + timezone: string + avatar: string | null + description: string | null + trial_mode: boolean + is_agency: boolean + is_aws_customer: boolean + created_at: number + updated_at: number + deleted_at?: number +} diff --git a/src/resources/agency/agencies/interfaces/index.ts b/src/resources/agency/agencies/interfaces/index.ts new file mode 100644 index 0000000..885ea8d --- /dev/null +++ b/src/resources/agency/agencies/interfaces/index.ts @@ -0,0 +1,2 @@ +export * from './agency.interface' +export * from './update-agency-options.interface' diff --git a/src/resources/agency/agencies/interfaces/update-agency-options.interface.ts b/src/resources/agency/agencies/interfaces/update-agency-options.interface.ts new file mode 100644 index 0000000..2108bb6 --- /dev/null +++ b/src/resources/agency/agencies/interfaces/update-agency-options.interface.ts @@ -0,0 +1,19 @@ +export interface UpdateAgencyOptions { + name?: string + description?: string | null + email?: string + location?: string + url?: string | null + timezone?: string + avatar?: string | null +} + +export interface SerializedUpdateAgencyOptions { + name?: string + description?: string | null + email?: string + location?: string + url?: string | null + timezone?: string + avatar?: string | null +} diff --git a/src/resources/agency/agencies/serializers/agency.serializer.ts b/src/resources/agency/agencies/serializers/agency.serializer.ts new file mode 100644 index 0000000..0804fbd --- /dev/null +++ b/src/resources/agency/agencies/serializers/agency.serializer.ts @@ -0,0 +1,30 @@ +import { List, ListResponse } from '@/types' +import { Agency, AgencyResponse } from '../interfaces' +import { deserializePaginationMeta } from '@/utils/serializers' + +export const deserializeAgency = (agency: AgencyResponse): Agency => ({ + id: agency.id, + object: agency.object, + name: agency.name, + email: agency.email, + slug: agency.slug, + url: agency.url, + location: agency.location, + timezone: agency.timezone, + avatar: agency.avatar, + description: agency.description, + trialMode: agency.trial_mode, + isAgency: agency.is_agency, + isAwsCustomer: agency.is_aws_customer, + createdAt: agency.created_at, + updatedAt: agency.updated_at, + deletedAt: agency.deleted_at, +}) + +export const deserializeAgencyList = ( + agencies: ListResponse +): List => ({ + object: agencies.object, + data: agencies.data.map(deserializeAgency), + meta: deserializePaginationMeta(agencies.meta), +}) diff --git a/src/resources/agency/agencies/serializers/index.ts b/src/resources/agency/agencies/serializers/index.ts new file mode 100644 index 0000000..9a5b365 --- /dev/null +++ b/src/resources/agency/agencies/serializers/index.ts @@ -0,0 +1,2 @@ +export * from './agency.serializer' +export * from './update-agency-options.serializer' diff --git a/src/resources/agency/agencies/serializers/update-agency-options.serializer.ts b/src/resources/agency/agencies/serializers/update-agency-options.serializer.ts new file mode 100644 index 0000000..828559d --- /dev/null +++ b/src/resources/agency/agencies/serializers/update-agency-options.serializer.ts @@ -0,0 +1,16 @@ +import { + SerializedUpdateAgencyOptions, + UpdateAgencyOptions, +} from '../interfaces' + +export const serializeUpdateAgencyOptions = ( + options: UpdateAgencyOptions +): SerializedUpdateAgencyOptions => ({ + name: options.name, + description: options.description, + email: options.email, + location: options.location, + url: options.url, + timezone: options.timezone, + avatar: options.avatar, +}) diff --git a/src/resources/agency/index.ts b/src/resources/agency/index.ts index 8b83505..1b0fe8c 100644 --- a/src/resources/agency/index.ts +++ b/src/resources/agency/index.ts @@ -1,3 +1,4 @@ +export { Agencies } from './agencies/agencies' export { Brand } from './brand/brand' export { Domains } from './domains/domains' export { Projects } from './projects/projects' diff --git a/src/resources/agency/projects/projects.ts b/src/resources/agency/projects/projects.ts index c93cc70..9a8dd0d 100644 --- a/src/resources/agency/projects/projects.ts +++ b/src/resources/agency/projects/projects.ts @@ -33,9 +33,12 @@ export class Projects { async list( options?: PaginationOptions & Expandable<'primary_domain'> ): Promise> { - const { data } = await this.agency.get('projects', { - query: options, - }) + const { data } = await this.agency.get>( + 'projects', + { + query: options, + } + ) return deserializeProjectList(data) } diff --git a/src/resources/agency/projects/serializers/project.serializer.ts b/src/resources/agency/projects/serializers/project.serializer.ts index 689aa04..b570b0b 100644 --- a/src/resources/agency/projects/serializers/project.serializer.ts +++ b/src/resources/agency/projects/serializers/project.serializer.ts @@ -23,7 +23,7 @@ export const deserializeProject = (project: ProjectResponse): Project => ({ export const deserializeProjectList = ( projects: ListResponse ): List => ({ - object: 'list', + object: projects.object, data: projects.data.map(deserializeProject), meta: deserializePaginationMeta(projects.meta), }) From e135b19f750935e4ba109c46d883ed58a364f321 Mon Sep 17 00:00:00 2001 From: Jayan Ratna Date: Thu, 18 Jul 2024 15:50:53 +1200 Subject: [PATCH 2/7] add basic test file --- src/resources/agency/agencies/agencies.spec.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/resources/agency/agencies/agencies.spec.ts b/src/resources/agency/agencies/agencies.spec.ts index e69de29..f243344 100644 --- a/src/resources/agency/agencies/agencies.spec.ts +++ b/src/resources/agency/agencies/agencies.spec.ts @@ -0,0 +1,9 @@ +import fetch from 'jest-fetch-mock' + +describe('Agency', () => { + beforeEach(() => fetch.resetMocks()) + + describe('list', () => { + it('can retrieve a list of agencies', () => {}) + }) +}) From 5f9c86b0c1daa8e15b2f1c80dde2eaaabe77cad4 Mon Sep 17 00:00:00 2001 From: Jayan Ratna Date: Fri, 19 Jul 2024 10:40:35 +1200 Subject: [PATCH 3/7] add tests for agency resource --- src/blutui.ts | 3 +- src/resources/agencies/agencies.spec.ts | 60 +++++++++++++++++++ .../{agency => }/agencies/agencies.ts | 0 .../agencies/fixtures/agency-list.json | 31 ++++++++++ src/resources/agencies/fixtures/agency.json | 17 ++++++ .../agencies/interfaces/agency.interface.ts | 0 .../{agency => }/agencies/interfaces/index.ts | 0 .../update-agency-options.interface.ts | 0 .../agencies/serializers/agency.serializer.ts | 0 .../agencies/serializers/index.ts | 0 .../update-agency-options.serializer.ts | 0 .../agency/agencies/agencies.spec.ts | 9 --- src/resources/agency/index.ts | 1 - src/resources/index.ts | 1 + 14 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 src/resources/agencies/agencies.spec.ts rename src/resources/{agency => }/agencies/agencies.ts (100%) create mode 100644 src/resources/agencies/fixtures/agency-list.json create mode 100644 src/resources/agencies/fixtures/agency.json rename src/resources/{agency => }/agencies/interfaces/agency.interface.ts (100%) rename src/resources/{agency => }/agencies/interfaces/index.ts (100%) rename src/resources/{agency => }/agencies/interfaces/update-agency-options.interface.ts (100%) rename src/resources/{agency => }/agencies/serializers/agency.serializer.ts (100%) rename src/resources/{agency => }/agencies/serializers/index.ts (100%) rename src/resources/{agency => }/agencies/serializers/update-agency-options.serializer.ts (100%) delete mode 100644 src/resources/agency/agencies/agencies.spec.ts diff --git a/src/blutui.ts b/src/blutui.ts index d395cc2..edb8d5f 100644 --- a/src/blutui.ts +++ b/src/blutui.ts @@ -10,8 +10,7 @@ import { } from './exceptions' import { Client } from './utils/client' -import { User } from './resources' -import { Agencies } from './resources/agency' +import { Agencies, User } from './resources' import type { BlutuiOptions, diff --git a/src/resources/agencies/agencies.spec.ts b/src/resources/agencies/agencies.spec.ts new file mode 100644 index 0000000..e41d22a --- /dev/null +++ b/src/resources/agencies/agencies.spec.ts @@ -0,0 +1,60 @@ +import fetch from 'jest-fetch-mock' +import { Blutui } from '@/blutui' +import { fetchOnce, fetchURL } from '@/utils/testing' + +import agencyFixture from './fixtures/agency.json' +import agencyListFixture from './fixtures/agency-list.json' + +const accessToken = + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' +const blutui = new Blutui(accessToken) + +describe('Agency', () => { + beforeEach(() => fetch.resetMocks()) + + describe('list', () => { + it('can retrieve a list of agencies', async () => { + fetchOnce(agencyListFixture) + const agencies = await blutui.agencies.list() + + expect(fetchURL()).toBe(blutui.baseURL + `/v1/agencies`) + expect(agencies).toMatchObject({ + object: 'list', + }) + }) + }) + + describe('get', () => { + it('can retrieve an agency', async () => { + fetchOnce(agencyFixture) + const agency = await blutui.agencies.get(agencyFixture.id) + + expect(fetchURL()).toBe( + blutui.baseURL + `/v1/agencies/${agencyFixture.id}` + ) + expect(agency).toMatchObject({ + id: '9af3accc-1536-4336-8cc3-3b3b2a96c18a', + object: 'agency', + isAgency: false, + }) + }) + }) + + describe('update', () => { + it('can update an agency', async () => { + fetchOnce(agencyFixture) + const agency = await blutui.agencies.update(agencyFixture.id, { + name: 'Foo', + }) + + expect(fetchURL()).toBe( + blutui.baseURL + `/v1/agencies/${agencyFixture.id}` + ) + expect(agency).toMatchObject({ + id: '9af3accc-1536-4336-8cc3-3b3b2a96c18a', + object: 'agency', + isAwsCustomer: false, + }) + }) + }) +}) diff --git a/src/resources/agency/agencies/agencies.ts b/src/resources/agencies/agencies.ts similarity index 100% rename from src/resources/agency/agencies/agencies.ts rename to src/resources/agencies/agencies.ts diff --git a/src/resources/agencies/fixtures/agency-list.json b/src/resources/agencies/fixtures/agency-list.json new file mode 100644 index 0000000..ed6d12b --- /dev/null +++ b/src/resources/agencies/fixtures/agency-list.json @@ -0,0 +1,31 @@ +{ + "object": "list", + "data": [ + { + "id": "9af3accc-1536-4336-8cc3-3b3b2a96c18a", + "object": "agency", + "name": "Flume", + "email": "jayan@flume.agency", + "slug": "flume", + "url": "https://flume.agency", + "location": "NZ", + "timezone": "UTC", + "avatar": null, + "description": null, + "trial_mode": false, + "is_agency": false, + "is_aws_customer": false, + "created_at": 1703713667, + "updated_at": 1721087098 + } + ], + "meta": { + "hasMore": false, + "currentPage": 1, + "from": 1, + "to": 1, + "perPage": 10, + "total": 1, + "lastPage": 1 + } +} diff --git a/src/resources/agencies/fixtures/agency.json b/src/resources/agencies/fixtures/agency.json new file mode 100644 index 0000000..1921827 --- /dev/null +++ b/src/resources/agencies/fixtures/agency.json @@ -0,0 +1,17 @@ +{ + "id": "9af3accc-1536-4336-8cc3-3b3b2a96c18a", + "object": "agency", + "name": "Flume", + "email": "jayan@flume.agency", + "slug": "flume", + "url": "https://flume.agency", + "location": "NZ", + "timezone": "UTC", + "avatar": null, + "description": null, + "trial_mode": false, + "is_agency": false, + "is_aws_customer": false, + "created_at": 1703713667, + "updated_at": 1721087098 +} diff --git a/src/resources/agency/agencies/interfaces/agency.interface.ts b/src/resources/agencies/interfaces/agency.interface.ts similarity index 100% rename from src/resources/agency/agencies/interfaces/agency.interface.ts rename to src/resources/agencies/interfaces/agency.interface.ts diff --git a/src/resources/agency/agencies/interfaces/index.ts b/src/resources/agencies/interfaces/index.ts similarity index 100% rename from src/resources/agency/agencies/interfaces/index.ts rename to src/resources/agencies/interfaces/index.ts diff --git a/src/resources/agency/agencies/interfaces/update-agency-options.interface.ts b/src/resources/agencies/interfaces/update-agency-options.interface.ts similarity index 100% rename from src/resources/agency/agencies/interfaces/update-agency-options.interface.ts rename to src/resources/agencies/interfaces/update-agency-options.interface.ts diff --git a/src/resources/agency/agencies/serializers/agency.serializer.ts b/src/resources/agencies/serializers/agency.serializer.ts similarity index 100% rename from src/resources/agency/agencies/serializers/agency.serializer.ts rename to src/resources/agencies/serializers/agency.serializer.ts diff --git a/src/resources/agency/agencies/serializers/index.ts b/src/resources/agencies/serializers/index.ts similarity index 100% rename from src/resources/agency/agencies/serializers/index.ts rename to src/resources/agencies/serializers/index.ts diff --git a/src/resources/agency/agencies/serializers/update-agency-options.serializer.ts b/src/resources/agencies/serializers/update-agency-options.serializer.ts similarity index 100% rename from src/resources/agency/agencies/serializers/update-agency-options.serializer.ts rename to src/resources/agencies/serializers/update-agency-options.serializer.ts diff --git a/src/resources/agency/agencies/agencies.spec.ts b/src/resources/agency/agencies/agencies.spec.ts deleted file mode 100644 index f243344..0000000 --- a/src/resources/agency/agencies/agencies.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import fetch from 'jest-fetch-mock' - -describe('Agency', () => { - beforeEach(() => fetch.resetMocks()) - - describe('list', () => { - it('can retrieve a list of agencies', () => {}) - }) -}) diff --git a/src/resources/agency/index.ts b/src/resources/agency/index.ts index 1b0fe8c..8b83505 100644 --- a/src/resources/agency/index.ts +++ b/src/resources/agency/index.ts @@ -1,4 +1,3 @@ -export { Agencies } from './agencies/agencies' export { Brand } from './brand/brand' export { Domains } from './domains/domains' export { Projects } from './projects/projects' diff --git a/src/resources/index.ts b/src/resources/index.ts index 06a4a3b..aaa7f4c 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -1 +1,2 @@ +export { Agencies } from './agencies/agencies' export { User } from './user/user' From 81cf3da51f2aab2c91c04f28b28aa463c5c7a5f1 Mon Sep 17 00:00:00 2001 From: Jayan Ratna Date: Fri, 19 Jul 2024 17:03:23 +1200 Subject: [PATCH 4/7] fix errors --- src/resources/agencies/agencies.spec.ts | 6 +- src/resources/agencies/agencies.ts | 16 ++--- .../agencies/serializers/agency.serializer.ts | 5 +- .../update-agency-options.serializer.ts | 2 +- .../agency/projects/projects.spec.ts | 34 +++++------ src/resources/agency/projects/projects.ts | 59 ++++++++++--------- .../create-project-options.serializer.ts | 2 +- .../serializers/project.serializer.ts | 5 +- .../update-project-options.serializer.ts | 2 +- 9 files changed, 64 insertions(+), 67 deletions(-) diff --git a/src/resources/agencies/agencies.spec.ts b/src/resources/agencies/agencies.spec.ts index e41d22a..5402a95 100644 --- a/src/resources/agencies/agencies.spec.ts +++ b/src/resources/agencies/agencies.spec.ts @@ -17,7 +17,7 @@ describe('Agency', () => { fetchOnce(agencyListFixture) const agencies = await blutui.agencies.list() - expect(fetchURL()).toBe(blutui.baseURL + `/v1/agencies`) + expect(fetchURL()).toBe(`${blutui.baseURL}/v1/agencies`) expect(agencies).toMatchObject({ object: 'list', }) @@ -30,7 +30,7 @@ describe('Agency', () => { const agency = await blutui.agencies.get(agencyFixture.id) expect(fetchURL()).toBe( - blutui.baseURL + `/v1/agencies/${agencyFixture.id}` + `${blutui.baseURL}/v1/agencies/${agencyFixture.id}` ) expect(agency).toMatchObject({ id: '9af3accc-1536-4336-8cc3-3b3b2a96c18a', @@ -48,7 +48,7 @@ describe('Agency', () => { }) expect(fetchURL()).toBe( - blutui.baseURL + `/v1/agencies/${agencyFixture.id}` + `${blutui.baseURL}/v1/agencies/${agencyFixture.id}` ) expect(agency).toMatchObject({ id: '9af3accc-1536-4336-8cc3-3b3b2a96c18a', diff --git a/src/resources/agencies/agencies.ts b/src/resources/agencies/agencies.ts index b3474a1..74e7a96 100644 --- a/src/resources/agencies/agencies.ts +++ b/src/resources/agencies/agencies.ts @@ -1,17 +1,17 @@ -import { Blutui } from '@/blutui' - import { + deserializeAgency, + deserializeAgencyList, + serializeUpdateAgencyOptions, +} from './serializers' + +import type { Blutui } from '@/blutui' +import type { Agency, AgencyResponse, SerializedUpdateAgencyOptions, UpdateAgencyOptions, } from './interfaces' -import { - deserializeAgency, - deserializeAgencyList, - serializeUpdateAgencyOptions, -} from './serializers' -import { List, ListResponse, PaginationOptions } from '@/types' +import type { List, ListResponse, PaginationOptions } from '@/types' export class Agencies { constructor(private readonly blutui: Blutui) {} diff --git a/src/resources/agencies/serializers/agency.serializer.ts b/src/resources/agencies/serializers/agency.serializer.ts index 0804fbd..88abfbf 100644 --- a/src/resources/agencies/serializers/agency.serializer.ts +++ b/src/resources/agencies/serializers/agency.serializer.ts @@ -1,7 +1,8 @@ -import { List, ListResponse } from '@/types' -import { Agency, AgencyResponse } from '../interfaces' import { deserializePaginationMeta } from '@/utils/serializers' +import type { List, ListResponse } from '@/types' +import type { Agency, AgencyResponse } from '../interfaces' + export const deserializeAgency = (agency: AgencyResponse): Agency => ({ id: agency.id, object: agency.object, diff --git a/src/resources/agencies/serializers/update-agency-options.serializer.ts b/src/resources/agencies/serializers/update-agency-options.serializer.ts index 828559d..74cfe95 100644 --- a/src/resources/agencies/serializers/update-agency-options.serializer.ts +++ b/src/resources/agencies/serializers/update-agency-options.serializer.ts @@ -1,4 +1,4 @@ -import { +import type { SerializedUpdateAgencyOptions, UpdateAgencyOptions, } from '../interfaces' diff --git a/src/resources/agency/projects/projects.spec.ts b/src/resources/agency/projects/projects.spec.ts index 81979d1..5e95b57 100644 --- a/src/resources/agency/projects/projects.spec.ts +++ b/src/resources/agency/projects/projects.spec.ts @@ -18,7 +18,7 @@ describe('Project', () => { fetchOnce(projectListFixture) const projects = await blutui.agency('foo').projects.list() - expect(fetchURL()).toBe(blutui.baseURL + `/v1/agencies/foo/projects`) + expect(fetchURL()).toBe(`${blutui.baseURL}/v1/agencies/foo/projects`) expect(projects).toMatchObject({ object: 'list', }) @@ -32,7 +32,7 @@ describe('Project', () => { expect(fetchURL()).toBe( encodeURI( - blutui.baseURL + `/v1/agencies/foo/projects?expand[]=primary_domain` + `${blutui.baseURL}/v1/agencies/foo/projects?expand[]=primary_domain` ) ) expect(projects).toMatchObject({ @@ -47,7 +47,7 @@ describe('Project', () => { const project = await blutui.agency('foo').projects.get(projectFixture.id) expect(fetchURL()).toBe( - blutui.baseURL + `/v1/agencies/foo/projects/${projectFixture.id}` + `${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}` ) expect(project).toMatchObject({ id: '99bc147e-966c-4dd0-8def-de817c63cf41', @@ -63,8 +63,7 @@ describe('Project', () => { expect(fetchURL()).toBe( encodeURI( - blutui.baseURL + - `/v1/agencies/foo/projects/${projectFixture.id}?expand[]=primary_domain` + `${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}?expand[]=primary_domain` ) ) expect(project).toMatchObject({ @@ -81,7 +80,7 @@ describe('Project', () => { name: 'One', }) - expect(fetchURL()).toBe(blutui.baseURL + '/v1/agencies/foo/projects') + expect(fetchURL()).toBe(`${blutui.baseURL}/v1/agencies/foo/projects`) expect(project).toMatchObject({ object: 'project', name: 'One', @@ -99,7 +98,7 @@ describe('Project', () => { }) expect(fetchURL()).toBe( - blutui.baseURL + `/v1/agencies/foo/projects/${projectFixture.id}` + `${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}` ) expect(project).toMatchObject({ object: 'project', @@ -116,7 +115,7 @@ describe('Project', () => { .projects.remove(projectFixture.id) expect(fetchURL()).toBe( - blutui.baseURL + `/v1/agencies/foo/projects/${projectFixture.id}` + `${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}` ) expect(archivedProject).toMatchObject({ id: '99bc147e-966c-4dd0-8def-de817c63cf41', @@ -134,7 +133,7 @@ describe('Project', () => { .projects.archived({ limit: 2 }) expect(fetchURL()).toBe( - encodeURI(blutui.baseURL + `/v1/agencies/foo/projects/archived?limit=2`) + encodeURI(`${blutui.baseURL}/v1/agencies/foo/projects/archived?limit=2`) ) expect(projects).toMatchObject({ object: 'list', @@ -150,8 +149,7 @@ describe('Project', () => { .projects.restore(projectFixture.id) expect(fetchURL()).toBe( - blutui.baseURL + - `/v1/agencies/foo/projects/${projectFixture.id}/archived` + `${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}/archived` ) expect(project).toMatchObject({ object: 'project', @@ -168,8 +166,7 @@ describe('Project', () => { .projects.domains(projectFixture.id) expect(fetchURL()).toBe( - blutui.baseURL + - `/v1/agencies/foo/projects/${projectFixture.id}/domains` + `${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}/domains` ) expect(domains).toMatchObject({ object: 'list', @@ -185,7 +182,7 @@ describe('Project', () => { .projects.search({ name: 'One' }) expect(fetchURL()).toBe( - blutui.baseURL + `/v1/agencies/foo/projects/search` + `${blutui.baseURL}/v1/agencies/foo/projects/search` ) expect(projects).toMatchObject({ object: 'list', @@ -201,8 +198,7 @@ describe('Project', () => { .projects.publish(projectFixture.id) expect(fetchURL()).toBe( - blutui.baseURL + - `/v1/agencies/foo/projects/${projectFixture.id}/publish` + `${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}/publish` ) expect(project).toMatchObject({ id: '99bc147e-966c-4dd0-8def-de817c63cf41', @@ -219,8 +215,7 @@ describe('Project', () => { .projects.republish(projectFixture.id) expect(fetchURL()).toBe( - blutui.baseURL + - `/v1/agencies/foo/projects/${projectFixture.id}/republish` + `${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}/republish` ) expect(project).toMatchObject({ id: '99bc147e-966c-4dd0-8def-de817c63cf41', @@ -237,8 +232,7 @@ describe('Project', () => { .projects.unpublish(projectFixture.id) expect(fetchURL()).toBe( - blutui.baseURL + - `/v1/agencies/foo/projects/${projectFixture.id}/unpublish` + `${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}/unpublish` ) expect(project).toMatchObject({ id: '99bc147e-966c-4dd0-8def-de817c63cf41', diff --git a/src/resources/agency/projects/projects.ts b/src/resources/agency/projects/projects.ts index 9a8dd0d..e36a7a9 100644 --- a/src/resources/agency/projects/projects.ts +++ b/src/resources/agency/projects/projects.ts @@ -1,22 +1,24 @@ -import { Agency } from '@/agency' import { + deserializeProject, + deserializeProjectList, + serializeCreateProjectOptions, + serializeUpdateProjectOptions, +} from './serializers' +import { deserializeDomainList } from '../domains/serializers' + +import type { Agency } from '@/agency' +import type { CreateProjectOptions, Project, ProjectResponse, SearchProjectOptions, SerializedCreateProjectOptions, + SerializedSearchProjectOptions, SerializedUpdateProjectOptions, UpdateProjectOptions, } from './interfaces' -import { Domain, DomainResponse } from '../domains/interfaces' -import { - deserializeProject, - deserializeProjectList, - serializeCreateProjectOptions, - serializeUpdateProjectOptions, -} from './serializers' -import { deserializeDomainList } from '../domains/serializers' -import { +import type { Domain, DomainResponse } from '../domains/interfaces' +import type { DeletedResponse, Expandable, List, @@ -135,13 +137,12 @@ export class Projects { payload: SearchProjectOptions, options?: Expandable<'primary_domain'> ): Promise> { - const { data } = await this.agency.post>( - 'projects/search', - payload, - { - query: options, - } - ) + const { data } = await this.agency.post< + ListResponse, + SerializedSearchProjectOptions + >('projects/search', payload, { + query: options, + }) return deserializeProjectList(data) } @@ -152,10 +153,10 @@ export class Projects { * NOTE: An active Blutui subscription is required to perform this action. */ async publish(id: string): Promise { - const { data } = await this.agency.post( - `projects/${id}/publish`, - {} - ) + const { data } = await this.agency.post< + ProjectResponse, + Record + >(`projects/${id}/publish`, {}) return deserializeProject(data) } @@ -164,10 +165,10 @@ export class Projects { * Republish a project with the given ID. */ async republish(id: string): Promise { - const { data } = await this.agency.post( - `projects/${id}/republish`, - {} - ) + const { data } = await this.agency.post< + ProjectResponse, + Record + >(`projects/${id}/republish`, {}) return deserializeProject(data) } @@ -176,10 +177,10 @@ export class Projects { * Unpublish a project with the given ID. */ async unpublish(id: string): Promise { - const { data } = await this.agency.post( - `projects/${id}/unpublish`, - {} - ) + const { data } = await this.agency.post< + ProjectResponse, + Record + >(`projects/${id}/unpublish`, {}) return deserializeProject(data) } diff --git a/src/resources/agency/projects/serializers/create-project-options.serializer.ts b/src/resources/agency/projects/serializers/create-project-options.serializer.ts index 7568e17..e63565c 100644 --- a/src/resources/agency/projects/serializers/create-project-options.serializer.ts +++ b/src/resources/agency/projects/serializers/create-project-options.serializer.ts @@ -1,4 +1,4 @@ -import { +import type { CreateProjectOptions, SerializedCreateProjectOptions, } from '../interfaces' diff --git a/src/resources/agency/projects/serializers/project.serializer.ts b/src/resources/agency/projects/serializers/project.serializer.ts index b570b0b..2fbfb40 100644 --- a/src/resources/agency/projects/serializers/project.serializer.ts +++ b/src/resources/agency/projects/serializers/project.serializer.ts @@ -1,7 +1,8 @@ -import { List, ListResponse } from '@/types' -import { Project, ProjectResponse } from '../interfaces' import { deserializePaginationMeta } from '@/utils/serializers' +import type { List, ListResponse } from '@/types' +import type { Project, ProjectResponse } from '../interfaces' + export const deserializeProject = (project: ProjectResponse): Project => ({ id: project.id, object: project.object, diff --git a/src/resources/agency/projects/serializers/update-project-options.serializer.ts b/src/resources/agency/projects/serializers/update-project-options.serializer.ts index 8e9e5f7..ecaa641 100644 --- a/src/resources/agency/projects/serializers/update-project-options.serializer.ts +++ b/src/resources/agency/projects/serializers/update-project-options.serializer.ts @@ -1,4 +1,4 @@ -import { +import type { SerializedUpdateProjectOptions, UpdateProjectOptions, } from '../interfaces' From cc3db5d051145b6054086716f8c9a148b79e956e Mon Sep 17 00:00:00 2001 From: Jayan Ratna Date: Fri, 19 Jul 2024 17:11:20 +1200 Subject: [PATCH 5/7] fix errors --- src/types.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/types.ts b/src/types.ts index 53367da..76320ab 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,10 @@ +// Blutui Options + export interface BlutuiOptions { apiHostname?: string + request?: { + fetch?: typeof fetch + } } // List From b2c6703be35506ba107aeb5e96be6c11bbba122f Mon Sep 17 00:00:00 2001 From: Jayan Ratna Date: Fri, 19 Jul 2024 17:15:21 +1200 Subject: [PATCH 6/7] fix query strings --- src/utils/client.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/client.ts b/src/utils/client.ts index 8bdf41e..0f936f5 100644 --- a/src/utils/client.ts +++ b/src/utils/client.ts @@ -124,8 +124,9 @@ function getQueryString(queryObj?: Record) { if (element !== '' && element !== undefined) sanitizedQueryObj.push([`${param}[]`, element]) } - } else if (value && typeof value === 'string') { - sanitizedQueryObj.push([param, value]) + } else if (value) { + const newValue = String(value) + sanitizedQueryObj.push([param, newValue]) } } From fa216fcadc8c42e087ee292f2be43dcb3596f77e Mon Sep 17 00:00:00 2001 From: Jayan Ratna Date: Mon, 22 Jul 2024 14:40:56 +1200 Subject: [PATCH 7/7] merge fix --- .../agency/projects/serializers/project.serializer.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/resources/agency/projects/serializers/project.serializer.ts b/src/resources/agency/projects/serializers/project.serializer.ts index adbe085..236a2f6 100644 --- a/src/resources/agency/projects/serializers/project.serializer.ts +++ b/src/resources/agency/projects/serializers/project.serializer.ts @@ -4,9 +4,6 @@ import { deserializeDomain } from '../../domains/serializers' import type { Project, ProjectResponse } from '../interfaces' import type { List, ListResponse } from '@/types' -import type { List, ListResponse } from '@/types' -import type { Project, ProjectResponse } from '../interfaces' - export const deserializeProject = (project: ProjectResponse): Project => ({ id: project.id, object: project.object,