bam-ticketing-sdk
Version:
SDK for B.A.M Ticketing API
693 lines (601 loc) • 16.1 kB
text/typescript
import { AxiosInstance } from 'axios'
import queryString from 'query-string'
import {
User,
Roles,
Wallet,
NewUser,
Organizer,
UserInvite,
UserUpdate,
OrganizerId,
NewOrganizer,
EnrollmentId,
SeatsWorkspace,
PublicUserData,
UserPermissions,
UserPermissionChange,
Email,
MarketRuleset,
Fee,
FeeUpdate,
FeeCreate,
MarketRulesetCreate,
MarketRulesetUpdate,
MarketRulesetListQuery,
GetOrganizerRequest,
UserQuery,
KYCLevel,
ListQuery,
Currency,
ListUserQuery,
OnboardStripePayload,
OnboardStripeResponse,
OnboardStripeStatus,
OrganizerDomain,
OrganizerDomainCreate,
OrganizerDomainUpdate,
OrganizerDomainQuery,
NewsletterUpdate,
Newsletter,
NewsletterCreate,
} from './types'
import {
HealthStatus,
IdParam,
QRCodePayload,
StatusResponse,
StringIdParam,
} from '../common/types'
import { getStringifiedQuery } from '../common/query'
/**
* Service class for account API calls.
*/
export class AccountService {
constructor(readonly client: AxiosInstance, readonly version: string) {}
/**
* Returns true if the service is reachable
*
* @returns Services' online status
*/
async health(): Promise<HealthStatus> {
try {
const res = await this.client.get(`account/health`)
if (res.data.status === 'ok') {
return { online: true }
}
} catch (e) {
// Do nothing
}
return { online: false }
}
/**
* Returns the organizer with the given name or id.
* Currently an organizer only has one workspace.
*
* @param req name of the organizer
* @returns Seats workspaces for the organizer
* @throws `NotFoundError`
*/
async getSeatsWorkspacesForOrganizer(
req: OrganizerId
): Promise<SeatsWorkspace[]> {
const query = queryString.stringify(
{
organizer_name: req.id,
},
{ arrayFormat: 'comma' }
)
const res = await this.client.get(
`account/${this.version}/seats-workspace?${query}`
)
return res.data.data
}
/**
* List all organizers
*
* @returns array of Organizer objects
*/
async listOrganizers(query: ListQuery = {}): Promise<Organizer[]> {
const queryString = getStringifiedQuery(query)
const res = await this.client.get(
`account/${this.version}/organizer?${queryString}`
)
return res.data.data
}
/**
* Returns the organizer with the given name or id.
*
* @param req id or name of the organizer
* @returns Organizer object
* @throws `NotFoundError`
*/
async getOrganizer(req: GetOrganizerRequest): Promise<Organizer> {
const query = queryString.stringify(
{
fields: req.fields,
},
{ arrayFormat: 'comma' }
)
const res = await this.client.get(
`account/${this.version}/organizer/${req.id}?${query}`
)
return res.data.data
}
/**
* Create an organizer
*
* @param org New organizer data
* @returns Organizer object
* @throws `BadRequestError`
*/
async createOrganizer(org: NewOrganizer): Promise<Organizer> {
const res = await this.client.post(`account/${this.version}/organizer`, org)
return res.data.data
}
/**
* Updates an organizer
*
* @param id.id name or id of the organizer
* @param org updated organizer data
* @returns Organizer object
*/
async updateOrganizer(
id: OrganizerId,
org: Partial<Organizer>
): Promise<Organizer> {
const res = await this.client.patch(
`account/${this.version}/organizer/${id.id}`,
org
)
return res.data.data
}
/**
* Returns the user with the given id.
*
* @param req id of the user
* @returns User object
* @throws `NotFoundError`
*/
async getUser(req: IdParam): Promise<User> {
const res = await this.client.get(`account/${this.version}/user/${req.id}`)
return res.data.data
}
/**
* Returns the user with the given email.
*
* @param email email of the user
* @returns User object
* @throws `NotFoundError`
*/
async getUserByEmail(email: Email): Promise<PublicUserData> {
const res = await this.client.get(
`account/${this.version}/user/email/${email.email}`
)
return res.data.data
}
/**
* Creates a new user
*
* @param user User data
* @returns User object
* @throws `BadRequestError`
*/
async createUser(user: NewUser): Promise<User> {
const res = await this.client.post(`account/${this.version}/user`, user)
return res.data.data
}
/**
* Creates and adds an user to an organizer
*
* @param user User data and permissions
* @returns User object
* @throws `BadRequestError`
*/
async inviteUser(user: UserInvite): Promise<User> {
if (user.grantedPermissions != null) {
user.role = Roles.Custom
}
const res = await this.client.post(
`account/${this.version}/user/invite`,
user
)
return res.data.data
}
/**
* Update a user
* If a new email is sent, it needs to be confirmed
*
* @param user User data
* @returns User object
* @throws `BadRequestError`, `NotFoundError`
*/
async updateUser(id: IdParam, user: UserUpdate): Promise<User> {
const res = await this.client.patch(
`account/${this.version}/user/${id.id}`,
user
)
return res.data.data
}
/**
* Initiate password reset process for a given email (i.e. user)
*
* @param email E-Mail of user which wants to reset the password
*/
async resetUserPassword(email: Email): Promise<StatusResponse> {
const res = await this.client.post(
`account/${this.version}/user/password/reset`,
{ email: email.email }
)
return res.data.data
}
/**
* Resend the verification link to an unverified user.
*
* @param email Email of the user for which the verification link should be resent.
* @throws BadRequestError if the user is already verified.
*/
async resendUserVerification(email: Email): Promise<void> {
await this.client.post(`account/${this.version}/user/verify/resend`, {
email: email.email,
})
}
/**
* Deletes a user
*
* @param id ID of the user to delete
* @throws `NotFoundError`
*/
async deleteUser(id: IdParam): Promise<void> {
await this.client.delete(`account/${this.version}/user/${id.id}`)
}
/**
* List users belonging to a specific organizer.
*
* @param id.id Id or name of the organizer
* @param query Additional fields that should be fetched with the users.
*/
async listUsersInOrganization(
id: OrganizerId,
query: UserQuery = {}
): Promise<User[]> {
const queryString = getStringifiedQuery(query)
const res = await this.client.get(
`account/${this.version}/organizer/${id.id}/users?${queryString}`
)
return res.data.data
}
/**
* Use this method to list the users.
* @param query.email Query the users by the email
*/
async listUsers(query: ListUserQuery = {}): Promise<User[]> {
const queryString = getStringifiedQuery(query)
const res = await this.client.get(
`account/${this.version}/user?${queryString}`
)
return res.data.data
}
/**
* Gets public info for a user with the enrollment id
*
* @param id enrollment ID of the user
* @throws `NotFoundError`
*/
async checkEnrollment(id: EnrollmentId): Promise<PublicUserData> {
const res = await this.client.get(
`account/${this.version}/user/enrollment/${id.enrollmentId}`
)
return res.data.data
}
/**
* Set a user's permissions.
* The caller need to have the `*.change_permission` permission for each class of permissions which are granted.
*
* @param id Id of the user
* @param perms Set of new permissions for the user
* @returns User object
* @throws `BadRequestError`, `NotFoundError`, `ForbiddenError`
*/
async setPermissions(
id: IdParam,
perms: UserPermissions
): Promise<UserPermissionChange> {
// Granted permissions object won't be used otherwise
if (perms.grantedPermissions != null) {
perms.role = Roles.Custom
}
const res = await this.client.patch(
`account/${this.version}/user/${id.id}/permission`,
perms
)
return res.data.data
}
/**
* Creates a new certificate and private key for a user.
* If there is no authorization, a new user and their wallet will be created.
*
* @returns User IDs, certificate and private key
*/
async createWallet(): Promise<Wallet> {
const res = await this.client.post(
`account/${this.version}/certificate/enroll`,
{}
)
return res.data.data
}
/**
* Renews the certificate and private key for a user.
*
* @returns User IDs, certificate and private key
*/
async renewWallet(): Promise<Wallet> {
const res = await this.client.post(
`account/${this.version}/certificate/renew`,
{}
)
return res.data.data
}
/**
* Return the market rules for the given ruleset
* @param marketRulesetId
* @returns
*/
async getMarketControlSettings(
marketRulesetId: StringIdParam
): Promise<MarketRuleset> {
const res = await this.client.get(
`account/${this.version}/market-control/${marketRulesetId.id}`
)
return res.data.data
}
/**
* Create a secondary market ruleset for an organizer
* @param marketRuleset Ruleset data
*/
async createMarketControlSettings(
marketRuleset: MarketRulesetCreate
): Promise<MarketRuleset> {
const res = await this.client.post(
`account/${this.version}/market-control`,
marketRuleset
)
return res.data.data
}
/**
* Update a secondary market ruleset
* @param id Id of the ruleset
* @param marketRuleset Updated ruleset data
*/
async updateMarketControlSettings(
id: StringIdParam,
marketRuleset: MarketRulesetUpdate
): Promise<MarketRuleset> {
const res = await this.client.patch(
`account/${this.version}/market-control/${id.id}`,
marketRuleset
)
return res.data.data
}
/**
* Delete a secondary market ruleset
* @param id Id of the ruleset
*/
async deleteMarketControlSettings(id: StringIdParam): Promise<void> {
await this.client.delete(`account/${this.version}/market-control/${id.id}`)
}
/**
* Fetch QR code data for publishing the ruleset on the chain
* @param id Id of the ruleset
*/
async getMarketControlSettingsQRCodePayload(
id: StringIdParam
): Promise<QRCodePayload> {
const res = await this.client.get(
`account/${this.version}/market-control/${id.id}/qr-payload`
)
return res.data.data
}
/**
* List the secondary market rulesets
*/
async listMarketControlSettings(
query: MarketRulesetListQuery = {}
): Promise<MarketRuleset[]> {
const queryString = getStringifiedQuery(query)
const res = await this.client.get(
`account/${this.version}/market-control?${queryString}`
)
return res.data.data
}
/**
* Get fee by id
* @param id Id of the fee
*/
async getFee(id: IdParam): Promise<Fee> {
const res = await this.client.get(`account/${this.version}/fee/${id.id}`)
return res.data.data
}
/**
* Create a fee for the organizer. Requires administrative rights.
* @param fee Fee data
*/
async createFee(fee: FeeCreate): Promise<Fee> {
const res = await this.client.post(`account/${this.version}/fee`, fee)
return res.data.data
}
/**
* Update fee data. Requires administrative rights.
* @param id Id of the fee
* @param fee Updated fee data
*/
async updateFee(id: IdParam, fee: FeeUpdate): Promise<Fee> {
const res = await this.client.patch(
`account/${this.version}/fee/${id.id}`,
fee
)
return res.data.data
}
/**
* List all registered KYC levels
*/
async listKycLevels(query: ListQuery = {}): Promise<KYCLevel[]> {
const queryString = getStringifiedQuery(query)
const res = await this.client.get(
`account/${this.version}/kyc?${queryString}`
)
return res.data.data
}
/**
* List all registered currencies
*/
async listCurrencies(query: ListQuery = {}): Promise<Currency[]> {
const queryString = getStringifiedQuery(query)
const res = await this.client.get(
`account/${this.version}/currency?${queryString}`
)
return res.data.data
}
/**
* Starts the onboarding process for the payment provider
*
* @param id.id name or id of the organizer
* @param onboardPayload return and refresh urls
* @returns redirect url
*/
async onboardStripeConnect(
id: OrganizerId,
onboardPayload: OnboardStripePayload
): Promise<OnboardStripeResponse> {
const res = await this.client.post(
`account/${this.version}/organizer/${id.id}/onboard/stripe`,
onboardPayload
)
return res.data.data
}
/**
* Gets the onboarding status for the payment provider
*
* @param id.id name or id of the organizer
* @returns data about the completeness of the onboarding process
*/
async getStripeConnectStatus(id: OrganizerId): Promise<OnboardStripeStatus> {
const res = await this.client.get(
`account/${this.version}/organizer/${id.id}/onboard/stripe`
)
return res.data.data
}
/**
* Get a domain by its ID
* @param id Id of the domain
*/
async getDomain(id: IdParam): Promise<OrganizerDomain> {
const res = await this.client.get(`account/${this.version}/domain/${id.id}`)
return res.data.data
}
/**
* Lists or searches for domains. Returns associated organizers for each domain.
*/
async listDomains(
queryReq: OrganizerDomainQuery
): Promise<OrganizerDomain[]> {
const query = queryString.stringify(queryReq)
const res = await this.client.get(`account/${this.version}/domain?${query}`)
return res.data.data
}
/**
* Create a domain for the organizer. Requires permissions for that organizer.
* @param domain Domain name and either the organizer ID or the organizer name
*/
async createDomain(domain: OrganizerDomainCreate): Promise<OrganizerDomain> {
const res = await this.client.post(`account/${this.version}/domain`, domain)
return res.data.data
}
/**
* Update domain data. Requires permissions for that organizer.
* @param id Id of the domain
* @param domain Updated domain name
*/
async updateDomain(
id: IdParam,
domain: OrganizerDomainUpdate
): Promise<OrganizerDomain> {
const res = await this.client.patch(
`account/${this.version}/domain/${id.id}`,
domain
)
return res.data.data
}
/**
* Delete a domain. Requires permissions for that organizer.
* @param id Id of the domain
*/
async deleteDomain(id: IdParam): Promise<void> {
await this.client.delete(`account/${this.version}/domain/${id.id}`)
}
/**
* Get a newsletter by its ID
*/
async getNewsletter(id: IdParam): Promise<Newsletter> {
const res = await this.client.get(
`account/${this.version}/newsletter/${id.id}`
)
return res.data.data
}
/**
* Lists all newsletters
*/
async listNewsletters(queryReq: OrganizerDomainQuery): Promise<Newsletter[]> {
const query = queryString.stringify(queryReq)
const res = await this.client.get(
`account/${this.version}/newsletter?${query}`
)
return res.data.data
}
/**
* Create a newsletter. Requires permissions for the main organizer.
* @param newsletter Subject and content. It will be put in the `info` email template.
*/
async createNewsletter(newsletter: NewsletterCreate): Promise<Newsletter> {
const res = await this.client.post(
`account/${this.version}/newsletter`,
newsletter
)
return res.data.data
}
/**
* Update newsletter content. Requires permissions for the main organizer.
* @param id ID of the newsletter
* @param newsletter Updated content
*/
async updateNewsletter(
id: IdParam,
newsletter: NewsletterUpdate
): Promise<Newsletter> {
const res = await this.client.patch(
`account/${this.version}/newsletter/${id.id}`,
newsletter
)
return res.data.data
}
/**
* Delete a newsletter. Requires permissions for the main organizer.
*/
async deleteNewsletter(id: IdParam): Promise<void> {
await this.client.delete(`account/${this.version}/newsletter/${id.id}`)
}
/**
* Sends out the emails containing the newsletter content.
* Requires permissions for the main organizer.
* The newsletter will be marked as sent, but it can still be updated and resent.
*
* @param id ID of the newsletter to send
*/
async sendNewsletter(id: IdParam): Promise<Newsletter> {
const res = await this.client.post(
`account/${this.version}/newsletter/${id.id}/send`,
{}
)
return res.data.data
}
}