Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"scripts": {
"build": "tsup src/index.ts --format esm,cjs --dts",
"dev": "npm run build -- --watch",
"test": "jest",
"format": "prettier \"src/**/*.{js,ts}\" --write",
"prepublishOnly": "npm run build"
Expand Down
3 changes: 2 additions & 1 deletion src/agency.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Blutui } from './blutui'

import { Brand } from './resources/agency'
import { Brand, Domains } from './resources/agency'
import type { GetOptions, PostOptions } from './types'

export class Agency {
readonly brand = new Brand(this)
readonly domains = new Domains(this)

constructor(
public username: string,
Expand Down
127 changes: 127 additions & 0 deletions src/resources/agency/domains/domains.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import fetch from 'jest-fetch-mock'
import { Blutui } from '@/blutui'
import { fetchOnce, fetchURL } from '@/utils/testing'
import domainFixture from './fixtures/domain.json'
import domainListFixture from './fixtures/domainList.json'

const accessToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
const blutui = new Blutui(accessToken)

describe('Domain', () => {
beforeEach(() => fetch.resetMocks())

describe('list', () => {
it('can retrieve a list of domains', async () => {
fetchOnce(domainListFixture)
const domains = await blutui.agency('foo').domains.list()

expect(fetchURL()).toBe(blutui.baseURL + `/v1/agencies/foo/domains`)
expect(domains).toMatchObject({
object: 'list',
})
})
})

describe('get', () => {
it('can retrieve a domain information', async () => {
fetchOnce(domainFixture)
const domain = await blutui.agency('foo').domains.get(domainFixture.id)

expect(fetchURL()).toBe(
blutui.baseURL + `/v1/agencies/foo/domains/${domainFixture.id}`
)
expect(domain).toMatchObject({
object: 'domain',
})
})

it('can retrieve a domain information with project', async () => {
fetchOnce(domainFixture)
const domain = await blutui.agency('foo').domains.get(domainFixture.id, {
expand: ['project'],
})
expect(fetchURL()).toContain(
encodeURI(
`/v1/agencies/foo/domains/${domainFixture.id}?expand[]=project`
)
)
expect(domain).toMatchObject({
object: 'domain',
})
})
})

describe('create', () => {
it('can create a new agency domain', async () => {
fetchOnce(domainFixture)
const domain = await blutui.agency('foo').domains.create({
name: 'example.com',
})

expect(fetchURL()).toBe(blutui.baseURL + '/v1/agencies/foo/domains')
expect(domain).toMatchObject({
object: 'domain',
name: 'example.com',
})
})
})

describe('update', () => {
it('can update an agency domain', async () => {
fetchOnce(domainFixture)
const domain = await blutui
.agency('foo')
.domains.update(domainFixture.id, { project: 'project-uuid' })

expect(fetchURL()).toBe(blutui.baseURL + `/v1/agencies/foo/domains/${domainFixture.id}`)
expect(domain).toMatchObject({
object: 'domain',
})
})
})

describe('remove', () => {
it('can remove an agency domain', async () => {
fetchOnce(domainFixture)
await blutui.agency('foo').domains.remove(domainFixture.id)

expect(fetchURL()).toBe(
blutui.baseURL + `/v1/agencies/foo/domains/${domainFixture.id}`
)
})
})

describe('refresh', () => {
it('can refresh domain token', async () => {
fetchOnce(domainFixture)
await blutui.agency('foo').domains.refresh(domainFixture.id)

expect(fetchURL()).toBe(
blutui.baseURL + `/v1/agencies/foo/domains/${domainFixture.id}/refresh`
)
})
})

describe('verify', () => {
it('can verify domain status', async () => {
fetchOnce(domainFixture)
await blutui.agency('foo').domains.verify(domainFixture.id)

expect(fetchURL()).toBe(
blutui.baseURL + `/v1/agencies/foo/domains/${domainFixture.id}/verify`
)
})
})

describe('search', () => {
it('Search for domains in your agency.', async () => {
fetchOnce(domainListFixture)
await blutui.agency('foo').domains.search({"name": "example.com"})

expect(fetchURL()).toBe(
blutui.baseURL + `/v1/agencies/foo/domains/search`
)
})
})
})
114 changes: 112 additions & 2 deletions src/resources/agency/domains/domains.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,115 @@
// import { Agency } from "@/agency";
import { Agency } from '@/agency'
import {
CreateDomainOptions,
DomainResponse,
DomainVerifyResponse,
SearchDomainOptions,
SerializedCreateDomainOptions,
SerializedUpdateDomainOptions,
UpdateDomainOptions,
type Domain,
} from './interfaces'
import {
deserializeDomain,
deserializeDomainList,
serializeCreateDomainOptions,
serializeUpdateDomainOptions,
} from './serializers'
import { DeletedResponse, List, ListResponse, PaginationOptions } from '@/types'

export class Domains {
// constructor(private readonly agency: Agency) {}
constructor(private readonly agency: Agency) {}

/**
* Get the domains list for the current agency.
*/
async list(paginationOptions?: PaginationOptions): Promise<List<Domain>> {
const { data } = await this.agency.get<ListResponse<DomainResponse>>(
'domains',
{ query: paginationOptions }
)
return deserializeDomainList(data)
}

/**
* Get a domain information by id.
*/
async get(id: string, options?: { expand: string[] }): Promise<Domain> {
const { data } = await this.agency.get<DomainResponse>(`domains/${id}`, {
query: options,
})

return deserializeDomain(data)
}

/**
* Add a domain to your agency.
*/
async create(payload: CreateDomainOptions): Promise<Domain> {
const { data } = await this.agency.post<
DomainResponse,
SerializedCreateDomainOptions
>('domains', serializeCreateDomainOptions(payload))

return deserializeDomain(data)
}

/**
* Update a domain for the current agency.
*
* @param payload - The values to update the brand
*/
async update(id: string, payload: UpdateDomainOptions): Promise<Domain> {
const { data } = await this.agency.patch<
DomainResponse,
SerializedUpdateDomainOptions
>(`domains/${id}`, serializeUpdateDomainOptions(payload))

return deserializeDomain(data)
}

/**
* Remove a domain for the current agency.
*/
async remove(id: string): Promise<DeletedResponse> {
const { data } = await this.agency.delete<DeletedResponse>(`domains/${id}`)

return data
}

/**
* Refresh the verification token for a domain from your agency.
*/
async refresh(id: string): Promise<Domain> {
const { data } = await this.agency.post<DomainResponse>(
`domains/${id}/refresh`,
{}
)

return deserializeDomain(data)
}

/**
* Check the verification status for a domain in your agency.
*/
async verify(id: string): Promise<DomainVerifyResponse> {
const { data } = await this.agency.post<DomainVerifyResponse>(
`domains/${id}/verify`,
{}
)
return data
}

/**
* Search for domains in your agency.
*/
async search(
searchDomainOptions: SearchDomainOptions
): Promise<List<Domain>> {
const { data } = await this.agency.post<ListResponse<DomainResponse>>(
'domains/search',
searchDomainOptions
)
return deserializeDomainList(data)
}
}
10 changes: 10 additions & 0 deletions src/resources/agency/domains/fixtures/domain.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": "9bfdb42b-1bf0-4510-978e-46aa329f8efa",
"object": "domain",
"name": "example.com",
"token": "08Q8wwsDMIuCwAsudZtXgf3ABkAwqbExgUPWUEPEuMBoWUIH0ie81R27h2elqjk1",
"project": "9bf15409-db06-4c2c-b1ee-3a64c0074092",
"verified_at": null,
"created_at": 1716170007,
"updated_at": 1716170007
}
24 changes: 24 additions & 0 deletions src/resources/agency/domains/fixtures/domainList.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"object": "list",
"data": [
{
"id": "9bfdb42b-1bf0-4510-978e-46aa329f8efa",
"object": "domain",
"name": "example.com",
"token": "08Q8wwsDMIuCwAsudZtXgf3ABkAwqbExgUPWUEPEuMBoWUIH0ie81R27h2elqjk1",
"project": "9bf15409-db06-4c2c-b1ee-3a64c0074092",
"verified_at": null,
"created_at": 1716170007,
"updated_at": 1716170007
}
],
"meta": {
"hasMore": false,
"currentPage": 1,
"from": 1,
"to": 1,
"perPage": 10,
"total": 1,
"lastPage": 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface CreateDomainOptions {
name: string
project?: string | null
}

export interface SerializedCreateDomainOptions {
name: string
project?: string | null
}
21 changes: 21 additions & 0 deletions src/resources/agency/domains/interfaces/domain.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export interface Domain {
id: string
object: 'domain'
name: string
token: string
project: string | Record<string, unknown>
verifiedAt: number
createdAt: number
updatedAt: number
}

export interface DomainResponse {
id: string
object: 'domain'
name: string
token: string
project: string | Record<string, unknown>
verified_at: number
created_at: number
updated_at: number
}
5 changes: 5 additions & 0 deletions src/resources/agency/domains/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './domain.interface'
export * from './create-domain-options.interface'
export * from './update-domain-options.interface'
export * from './search-domain-options.interface'
export * from './verify-domain-response.interface'
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface SearchDomainOptions {
name: string
}

export interface SerializedSearchDomainOptions {
name: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface UpdateDomainOptions {
project: string | null
}

export interface SerializedUpdateDomainOptions {
project: string | null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Domain Verify Response

export interface DomainVerifyResponse {
object: 'domain_state'
verified: boolean
message: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {
CreateDomainOptions,
SerializedCreateDomainOptions,
} from '../interfaces'

export const serializeCreateDomainOptions = (
options: CreateDomainOptions
): SerializedCreateDomainOptions => ({
name: options.name,
project: options.project,
})
22 changes: 22 additions & 0 deletions src/resources/agency/domains/serializers/domain.serializer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { List, ListResponse } from '@/types'
import { Domain, DomainResponse } from '../interfaces'
import { deserializePaginationMeta } from '@/utils/serializers'

export const deserializeDomain = (domain: DomainResponse): Domain => ({
id: domain.id,
object: domain.object,
name: domain.name,
token: domain.token,
project: domain.project,
verifiedAt: domain.verified_at,
createdAt: domain.created_at,
updatedAt: domain.updated_at,
})

export const deserializeDomainList = (
domains: ListResponse<DomainResponse>
): List<Domain> => ({
object: 'list',
data: domains.data.map(deserializeDomain),
meta: deserializePaginationMeta(domains.meta),
})
Loading