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
7 changes: 4 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"editor.defaultFormatter": "biomejs.biome",
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit"
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
Expand All @@ -7,9 +11,6 @@
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit"
},
"typescript.tsdk": "node_modules/typescript/lib",
"explorer.fileNesting.enabled": true
}
15 changes: 15 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,19 @@ import { Blutui } from './blutui'

export { Blutui }

// Blutui API

// Agency API
export * from './resources/agency/brand/interfaces'
export * from './resources/agency/cassettes/interfaces'
export * from './resources/agency/domains/interfaces'
export * from './resources/agency/invites/interfaces'
export * from './resources/agency/members/interfaces'
export * from './resources/agency/projects/interfaces'
export * from './resources/agency/roles/interfaces'

// Project Admin API

// Project API

export default Blutui
9 changes: 4 additions & 5 deletions src/resources/agency/brand/brand.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { deserializeBrand, serializeCreateBrandOptions } from './serializers'
import { serializeUpdateBrandOptions } from './serializers/update-brand-options.serializer'

import type { Agency } from '@/agency'
import type { DeletedResponse } from '@/types'
import type {
Brand as BrandI,
BrandResponse,
CreateBrandOptions,
SerializedCreateBrandOptions,
SerializedUpdateBrandOptions,
UpdateBrandOptions,
Brand as BrandI,
} from './interfaces'
import type { DeletedResponse } from '@/types'
import { deserializeBrand, serializeCreateBrandOptions } from './serializers'
import { serializeUpdateBrandOptions } from './serializers/update-brand-options.serializer'

export class Brand {
constructor(private readonly agency: Agency) {}
Expand Down
23 changes: 11 additions & 12 deletions src/resources/agency/cassettes/cassettes.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import {
deserializeCassette,
serializeCreateCassetteOptions,
serializeDuplicateCassetteOptions,
serializeUpdateCassetteOptions,
} from './serializers'

import type { Agency } from '@/agency'
import type { DeletedResponse, Expandable } from '@/types'
import type {
CassetteResponse,
Cassette,
CassetteResponse,
CreateCassetteOptions,
SerializedCreateCassetteOptions,
UpdateCassetteOptions,
SerializedUpdateCassetteOptions,
DuplicateCassetteOptions,
SerializedCreateCassetteOptions,
SerializedDuplicateCassetteOptions,
SerializedUpdateCassetteOptions,
UpdateCassetteOptions,
} from './interfaces'
import type { DeletedResponse, Expandable } from '@/types'
import {
deserializeCassette,
serializeCreateCassetteOptions,
serializeDuplicateCassetteOptions,
serializeUpdateCassetteOptions,
} from './serializers'

export class Cassettes {
constructor(private readonly agency: Agency) {}
Expand Down
2 changes: 1 addition & 1 deletion src/resources/agency/domains/domains.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { Blutui } from '@/blutui'
import { fetchOnce, fetchURL } from '@/utils/testing'

import domainFixture from './fixtures/domain.json'
import domainWithProjectFixture from './fixtures/domain-with-project.json'
import domainListFixture from './fixtures/domain-list.json'
import domainWithProjectFixture from './fixtures/domain-with-project.json'

const accessToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
Expand Down
29 changes: 14 additions & 15 deletions src/resources/agency/domains/domains.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
import {
deserializeDomain,
deserializeDomainList,
serializeCreateDomainOptions,
serializeUpdateDomainOptions,
} from './serializers'

import type { Agency } from '@/agency'
import type {
DeletedResponse,
Expandable,
List,
ListResponse,
PaginationOptions,
} from '@/types'
import type {
CreateDomainOptions,
Domain,
DomainResponse,
DomainVerifyResponse,
SearchDomainOptions,
SerializedCreateDomainOptions,
SerializedSearchDomainOptions,
SerializedUpdateDomainOptions,
UpdateDomainOptions,
Domain,
} from './interfaces'
import type {
DeletedResponse,
Expandable,
List,
ListResponse,
PaginationOptions,
} from '@/types'
import {
deserializeDomain,
deserializeDomainList,
serializeCreateDomainOptions,
serializeUpdateDomainOptions,
} from './serializers'

export class Domains {
constructor(private readonly agency: Agency) {}
Expand Down
23 changes: 11 additions & 12 deletions src/resources/agency/invites/invites.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import {
deserializeInvite,
deserializeInviteList,
serializeUpdateInviteOptions,
} from './serializers'

import type { Agency } from '@/agency'
import type {
Invite,
InviteResponse,
SerializedUpdateInviteOptions,
UpdateInviteOptions,
} from './interfaces'
import type {
DeletedResponse,
Expandable,
List,
ListResponse,
PaginationOptions,
} from '@/types'
import type {
Invite,
InviteResponse,
SerializedUpdateInviteOptions,
UpdateInviteOptions,
} from './interfaces'
import {
deserializeInvite,
deserializeInviteList,
serializeUpdateInviteOptions,
} from './serializers'

export class Invites {
constructor(private readonly agency: Agency) {}
Expand Down
3 changes: 1 addition & 2 deletions src/resources/agency/members/members.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import fetch from 'jest-fetch-mock'
import { Blutui } from '@/blutui'
import { ValidationException } from '@/exceptions'
import { fetchOnce, fetchURL } from '@/utils/testing'

import memberFixture from './fixtures/member.json'
import memberListFixture from './fixtures/member-list.json'
import { ValidationException } from '@/exceptions'

const accessToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
Expand Down
23 changes: 11 additions & 12 deletions src/resources/agency/members/members.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import {
deserializeMember,
deserializeMemberList,
serializeUpdateMemberOptions,
} from './serializers'

import type { Agency } from '@/agency'
import type {
Member,
MemberResponse,
SerializedUpdateMemberOptions,
UpdateMemberOptions,
} from './interfaces'
import type {
DeletedResponse,
List,
ListResponse,
PaginationOptions,
} from '@/types'
import type {
Member,
MemberResponse,
SerializedUpdateMemberOptions,
UpdateMemberOptions,
} from './interfaces'
import {
deserializeMember,
deserializeMemberList,
serializeUpdateMemberOptions,
} from './serializers'

export class Members {
constructor(private readonly agency: Agency) {}
Expand Down
10 changes: 10 additions & 0 deletions src/resources/agency/projects/fixtures/project-brand.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": 1,
"object": "project_brand",
"default_logo": "https://cdn.blutui.com/uploads/assets/logo/brand.svg",
"square_logo": "https://cdn.blutui.com/uploads/assets/logo/brand-square.svg",
"primary_color": "#ff2f0a",
"secondary_color": "#fff2ed",
"created_at": "2025-03-31T01:09:30+00:00",
"updated_at": "2025-04-01T01:26:12+00:00"
}
2 changes: 2 additions & 0 deletions src/resources/agency/projects/fixtures/project-list.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"timezone": "UTC",
"subdomain": "one",
"primary_domain": "9bfdb42b-1bf0-4510-978e-46aa329f8efa",
"cassette": "9d4b361e-4c00-4ac8-be51-fa76a5040c2a",
"brand": 1,
"published": true,
"processed": true,
"created_at": 1720758022,
Expand Down
1 change: 1 addition & 0 deletions src/resources/agency/projects/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './create-project-options.interface'
export * from './project.interface'
export * from './project-brand.interface'
export * from './search-project-options.interface'
export * from './update-project-options.interface'
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export interface ProjectBrand {
id: number
object: 'project_brand'
defaultLogo: string | null
squareLogo: string | null
primaryColor: string | null
secondaryColor: string | null
createdAt: string
updatedAt: string
}

export interface ProjectBrandResponse {
id: number
object: 'project_brand'
default_logo: string | null
square_logo: string | null
primary_color: string | null
secondary_color: string | null
created_at: string
updated_at: string
}
24 changes: 15 additions & 9 deletions src/resources/agency/projects/interfaces/project.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import type { Brand, BrandResponse } from '../../brand/interfaces'
import type { Cassette, CassetteResponse } from '../../cassettes/interfaces'
import type { Domain, DomainResponse } from '../../domains/interfaces'
import type {
ProjectBrand,
ProjectBrandResponse,
} from './project-brand.interface'

export interface Project {
id: string
Expand All @@ -12,12 +16,13 @@ export interface Project {
timezone: string
subdomain: string
primaryDomain: string | null | Domain
brand: string | null | Brand
cassette: string | null | Cassette
brand: string | null | ProjectBrand
published: boolean
processed: boolean
createdAt: number
updatedAt: number
deletedAt?: number
createdAt: string
updatedAt: string
deletedAt?: string
}

export interface ProjectResponse {
Expand All @@ -31,10 +36,11 @@ export interface ProjectResponse {
timezone: string
subdomain: string
primary_domain: string | null | DomainResponse
brand: string | null | BrandResponse
cassette: string | null | CassetteResponse
brand: string | null | ProjectBrandResponse
published: boolean
processed: boolean
created_at: number
updated_at: number
deleted_at?: number
created_at: string
updated_at: string
deleted_at?: string
}
41 changes: 28 additions & 13 deletions src/resources/agency/projects/projects.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import fetch from 'jest-fetch-mock'
import { Blutui } from '@/blutui'
import { fetchOnce, fetchSearchParams, fetchURL } from '@/utils/testing'

import cassetteListFixture from '../cassettes/fixtures/cassette-list.json'
import domainListFixture from '../domains/fixtures/domain-list.json'
import projectFixture from './fixtures/project.json'
import projectWithPrimaryDomainFixture from './fixtures/project-with-primary-domain.json'
import projectBrandFixture from './fixtures/project-brand.json'
import projectListFixture from './fixtures/project-list.json'
import domainListFixture from '../domains/fixtures/domain-list.json'
import cassetteListFixture from '../cassettes/fixtures/cassette-list.json'
import projectWithPrimaryDomainFixture from './fixtures/project-with-primary-domain.json'

const accessToken =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
Expand Down Expand Up @@ -181,18 +181,17 @@ describe('Project', () => {
})
})

describe('domains', () => {
it('can retrieve a list of domains for a project', async () => {
fetchOnce(domainListFixture)
const domains = await blutui
.agency('foo')
.projects.domains(projectFixture.id)
describe('brand', () => {
it('can retrieve a brand for a project', async () => {
fetchOnce(projectBrandFixture)
const brand = await blutui.agency('foo').projects.brand(projectFixture.id)

expect(fetchURL()).toBe(
`${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}/domains`
`${blutui.baseURL}/v1/agencies/foo/projects/${projectFixture.id}/brand`
)
expect(domains).toMatchObject({
object: 'list',
expect(brand).toMatchObject({
object: 'project_brand',
primaryColor: '#ff2f0a',
})
})
})
Expand All @@ -213,6 +212,22 @@ describe('Project', () => {
})
})

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

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

describe('search', () => {
it('can search for projects', async () => {
fetchOnce(projectListFixture)
Expand Down
Loading