diff --git a/packages/clients/src/api/index.ts b/packages/clients/src/api/index.ts index aac4475e9..c14930473 100644 --- a/packages/clients/src/api/index.ts +++ b/packages/clients/src/api/index.ts @@ -16,5 +16,6 @@ export * as RDB from './rdb' export * as Redis from './redis' export * as Registry from './registry' export * as Test from './test' +export * as TransactionalEmail from './transactional_email' export * as VPC from './vpc' export * as VPCGW from './vpcgw' diff --git a/packages/clients/src/api/transactional_email/index.ts b/packages/clients/src/api/transactional_email/index.ts new file mode 100644 index 000000000..e6671523d --- /dev/null +++ b/packages/clients/src/api/transactional_email/index.ts @@ -0,0 +1 @@ +export * as v1alpha1 from './v1alpha1' diff --git a/packages/clients/src/api/transactional_email/v1alpha1/api.gen.ts b/packages/clients/src/api/transactional_email/v1alpha1/api.gen.ts new file mode 100644 index 000000000..99ebe614d --- /dev/null +++ b/packages/clients/src/api/transactional_email/v1alpha1/api.gen.ts @@ -0,0 +1,304 @@ +// This file was automatically generated. DO NOT EDIT. +// If you have any remark or suggestion do not hesitate to open an issue. +import { + API, + enrichForPagination, + unmarshalServiceInfo, + urlParams, + validatePathParam, +} from '../../../bridge' +import type { Region, ServiceInfo } from '../../../bridge' +import { + marshalCreateDomainRequest, + marshalCreateEmailRequest, + unmarshalCreateEmailResponse, + unmarshalDomain, + unmarshalEmail, + unmarshalListDomainsResponse, + unmarshalListEmailsResponse, + unmarshalStatistics, +} from './marshalling.gen' +import type { + CancelEmailRequest, + CheckDomainRequest, + CreateDomainRequest, + CreateEmailRequest, + CreateEmailResponse, + Domain, + Email, + GetDomainRequest, + GetEmailRequest, + GetServiceInfoRequest, + GetStatisticsRequest, + ListDomainsRequest, + ListDomainsResponse, + ListEmailsRequest, + ListEmailsResponse, + RevokeDomainRequest, + Statistics, +} from './types.gen' + +const jsonContentHeaders = { + 'Content-Type': 'application/json; charset=utf-8', +} + +/** + * Transactional_email. + * + * Tem. + */ +export class TransactionalEmailV1Alpha1GenAPI extends API { + /** Lists the available regions of the API. */ + public static readonly LOCALITIES: Region[] = ['fr-par'] + + getServiceInfo = (request: Readonly = {}) => + this.client.fetch( + { + method: 'GET', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}`, + }, + unmarshalServiceInfo, + ) + + /** + * Send an email + * + * @param request - The request {@link CreateEmailRequest} + * @returns A Promise of CreateEmailResponse + */ + createEmail = (request: Readonly) => + this.client.fetch( + { + body: JSON.stringify( + marshalCreateEmailRequest(request, this.client.settings), + ), + headers: jsonContentHeaders, + method: 'POST', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/emails`, + }, + unmarshalCreateEmailResponse, + ) + + /** + * Get information about an email + * + * @param request - The request {@link GetEmailRequest} + * @returns A Promise of Email + */ + getEmail = (request: Readonly) => + this.client.fetch( + { + method: 'GET', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/emails/${validatePathParam('emailId', request.emailId)}`, + }, + unmarshalEmail, + ) + + protected pageOfListEmails = (request: Readonly = {}) => + this.client.fetch( + { + method: 'GET', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/emails`, + urlParams: urlParams( + ['domain_id', request.domainId], + ['mail_from', request.mailFrom], + ['mail_to', request.mailTo], + ['page', request.page], + [ + 'page_size', + request.pageSize ?? this.client.settings.defaultPageSize, + ], + [ + 'project_id', + request.projectId ?? this.client.settings.defaultProjectId, + ], + ['since', request.since], + ['statuses', request.statuses], + ['until', request.until], + ), + }, + unmarshalListEmailsResponse, + ) + + /** + * List emails sent from a domain and/or for a project and/or for an organization + * + * @param request - The request {@link ListEmailsRequest} + * @returns A Promise of ListEmailsResponse + */ + listEmails = (request: Readonly = {}) => + enrichForPagination('emails', this.pageOfListEmails, request) + + /** + * Get statistics on the email statuses + * + * @param request - The request {@link GetStatisticsRequest} + * @returns A Promise of Statistics + */ + getStatistics = (request: Readonly = {}) => + this.client.fetch( + { + method: 'GET', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/statistics`, + urlParams: urlParams( + ['domain_id', request.domainId], + ['mail_from', request.mailFrom], + [ + 'project_id', + request.projectId ?? this.client.settings.defaultProjectId, + ], + ['since', request.since], + ['until', request.until], + ), + }, + unmarshalStatistics, + ) + + /** + * Try to cancel an email if it has not yet been sent + * + * @param request - The request {@link CancelEmailRequest} + * @returns A Promise of Email + */ + cancelEmail = (request: Readonly) => + this.client.fetch( + { + body: '{}', + headers: jsonContentHeaders, + method: 'POST', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/emails/${validatePathParam('emailId', request.emailId)}/cancel`, + }, + unmarshalEmail, + ) + + /** + * Register a domain in a project + * + * @param request - The request {@link CreateDomainRequest} + * @returns A Promise of Domain + */ + createDomain = (request: Readonly) => + this.client.fetch( + { + body: JSON.stringify( + marshalCreateDomainRequest(request, this.client.settings), + ), + headers: jsonContentHeaders, + method: 'POST', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/domains`, + }, + unmarshalDomain, + ) + + /** + * Get information about a domain + * + * @param request - The request {@link GetDomainRequest} + * @returns A Promise of Domain + */ + getDomain = (request: Readonly) => + this.client.fetch( + { + method: 'GET', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/domains/${validatePathParam('domainId', request.domainId)}`, + }, + unmarshalDomain, + ) + + protected pageOfListDomains = (request: Readonly = {}) => + this.client.fetch( + { + method: 'GET', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/domains`, + urlParams: urlParams( + ['page', request.page], + [ + 'page_size', + request.pageSize ?? this.client.settings.defaultPageSize, + ], + [ + 'project_id', + request.projectId ?? this.client.settings.defaultProjectId, + ], + ['status', request.status], + ), + }, + unmarshalListDomainsResponse, + ) + + /** + * List domains in a project and/or in an organization + * + * @param request - The request {@link ListDomainsRequest} + * @returns A Promise of ListDomainsResponse + */ + listDomains = (request: Readonly = {}) => + enrichForPagination('domains', this.pageOfListDomains, request) + + /** + * Revoke a domain + * + * @param request - The request {@link RevokeDomainRequest} + * @returns A Promise of Domain + */ + revokeDomain = (request: Readonly) => + this.client.fetch( + { + body: '{}', + headers: jsonContentHeaders, + method: 'POST', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/domains/${validatePathParam('domainId', request.domainId)}/revoke`, + }, + unmarshalDomain, + ) + + /** + * Ask for an immediate check of a domain (DNS check) + * + * @param request - The request {@link CheckDomainRequest} + * @returns A Promise of Domain + */ + checkDomain = (request: Readonly) => + this.client.fetch( + { + body: '{}', + headers: jsonContentHeaders, + method: 'POST', + path: `/transactional-email/v1alpha1/regions/${validatePathParam( + 'region', + request.region ?? this.client.settings.defaultRegion, + )}/domains/${validatePathParam('domainId', request.domainId)}/check`, + }, + unmarshalDomain, + ) +} diff --git a/packages/clients/src/api/transactional_email/v1alpha1/index.ts b/packages/clients/src/api/transactional_email/v1alpha1/index.ts new file mode 100644 index 000000000..d664080a1 --- /dev/null +++ b/packages/clients/src/api/transactional_email/v1alpha1/index.ts @@ -0,0 +1,2 @@ +export { TransactionalEmailV1Alpha1GenAPI as API } from './api.gen' +export * from './types.gen' diff --git a/packages/clients/src/api/transactional_email/v1alpha1/marshalling.gen.ts b/packages/clients/src/api/transactional_email/v1alpha1/marshalling.gen.ts new file mode 100644 index 000000000..cb50dbd90 --- /dev/null +++ b/packages/clients/src/api/transactional_email/v1alpha1/marshalling.gen.ts @@ -0,0 +1,194 @@ +// This file was automatically generated. DO NOT EDIT. +// If you have any remark or suggestion do not hesitate to open an issue. +import { + isJSONObject, + unmarshalArrayOfObject, + unmarshalDate, +} from '../../../bridge' +import type { DefaultValues } from '../../../bridge' +import type { + CreateDomainRequest, + CreateEmailRequest, + CreateEmailRequestAddress, + CreateEmailRequestAttachment, + CreateEmailResponse, + Domain, + Email, + EmailTry, + ListDomainsResponse, + ListEmailsResponse, + Statistics, +} from './types.gen' + +const unmarshalEmailTry = (data: unknown) => { + if (!isJSONObject(data)) { + throw new TypeError( + `Unmarshalling the type 'EmailTry' failed as data isn't a dictionary.`, + ) + } + + return { + code: data.code, + message: data.message, + rank: data.rank, + triedAt: unmarshalDate(data.tried_at), + } as EmailTry +} + +export const unmarshalStatistics = (data: unknown) => { + if (!isJSONObject(data)) { + throw new TypeError( + `Unmarshalling the type 'Statistics' failed as data isn't a dictionary.`, + ) + } + + return { + canceledCount: data.canceled_count, + failedCount: data.failed_count, + newCount: data.new_count, + sendingCount: data.sending_count, + sentCount: data.sent_count, + totalCount: data.total_count, + } as Statistics +} + +export const unmarshalDomain = (data: unknown) => { + if (!isJSONObject(data)) { + throw new TypeError( + `Unmarshalling the type 'Domain' failed as data isn't a dictionary.`, + ) + } + + return { + createdAt: unmarshalDate(data.created_at), + dkimConfig: data.dkim_config, + id: data.id, + lastError: data.last_error, + lastValidAt: unmarshalDate(data.last_valid_at), + name: data.name, + nextCheckAt: unmarshalDate(data.next_check_at), + organizationId: data.organization_id, + projectId: data.project_id, + region: data.region, + revokedAt: unmarshalDate(data.revoked_at), + spfConfig: data.spf_config, + statistics: data.statistics + ? unmarshalStatistics(data.statistics) + : undefined, + status: data.status, + } as Domain +} + +export const unmarshalEmail = (data: unknown) => { + if (!isJSONObject(data)) { + throw new TypeError( + `Unmarshalling the type 'Email' failed as data isn't a dictionary.`, + ) + } + + return { + createdAt: unmarshalDate(data.created_at), + id: data.id, + lastTries: unmarshalArrayOfObject(data.last_tries, unmarshalEmailTry), + mailFrom: data.mail_from, + messageId: data.message_id, + projectId: data.project_id, + rcptTo: data.rcpt_to, + rcptType: data.rcpt_type, + status: data.status, + statusDetails: data.status_details, + tryCount: data.try_count, + updatedAt: unmarshalDate(data.updated_at), + } as Email +} + +export const unmarshalCreateEmailResponse = (data: unknown) => { + if (!isJSONObject(data)) { + throw new TypeError( + `Unmarshalling the type 'CreateEmailResponse' failed as data isn't a dictionary.`, + ) + } + + return { + emails: unmarshalArrayOfObject(data.emails, unmarshalEmail), + } as CreateEmailResponse +} + +export const unmarshalListDomainsResponse = (data: unknown) => { + if (!isJSONObject(data)) { + throw new TypeError( + `Unmarshalling the type 'ListDomainsResponse' failed as data isn't a dictionary.`, + ) + } + + return { + domains: unmarshalArrayOfObject(data.domains, unmarshalDomain), + totalCount: data.total_count, + } as ListDomainsResponse +} + +export const unmarshalListEmailsResponse = (data: unknown) => { + if (!isJSONObject(data)) { + throw new TypeError( + `Unmarshalling the type 'ListEmailsResponse' failed as data isn't a dictionary.`, + ) + } + + return { + emails: unmarshalArrayOfObject(data.emails, unmarshalEmail), + totalCount: data.total_count, + } as ListEmailsResponse +} + +const marshalCreateEmailRequestAddress = ( + request: CreateEmailRequestAddress, + defaults: DefaultValues, +): Record => ({ + email: request.email, + name: request.name, +}) + +const marshalCreateEmailRequestAttachment = ( + request: CreateEmailRequestAttachment, + defaults: DefaultValues, +): Record => ({ + content: request.content, + name: request.name, + type: request.type, +}) + +export const marshalCreateDomainRequest = ( + request: CreateDomainRequest, + defaults: DefaultValues, +): Record => ({ + domain_name: request.domainName, + project_id: request.projectId ?? defaults.defaultProjectId, +}) + +export const marshalCreateEmailRequest = ( + request: CreateEmailRequest, + defaults: DefaultValues, +): Record => ({ + attachments: request.attachments + ? request.attachments.map(elt => + marshalCreateEmailRequestAttachment(elt, defaults), + ) + : undefined, + bcc: request.bcc + ? request.bcc.map(elt => marshalCreateEmailRequestAddress(elt, defaults)) + : undefined, + cc: request.cc + ? request.cc.map(elt => marshalCreateEmailRequestAddress(elt, defaults)) + : undefined, + from: request.from + ? marshalCreateEmailRequestAddress(request.from, defaults) + : undefined, + html: request.html, + project_id: request.projectId ?? defaults.defaultProjectId, + send_before: request.sendBefore, + subject: request.subject, + text: request.text, + to: request.to + ? request.to.map(elt => marshalCreateEmailRequestAddress(elt, defaults)) + : undefined, +}) diff --git a/packages/clients/src/api/transactional_email/v1alpha1/types.gen.ts b/packages/clients/src/api/transactional_email/v1alpha1/types.gen.ts new file mode 100644 index 000000000..4509da079 --- /dev/null +++ b/packages/clients/src/api/transactional_email/v1alpha1/types.gen.ts @@ -0,0 +1,288 @@ +// This file was automatically generated. DO NOT EDIT. +// If you have any remark or suggestion do not hesitate to open an issue. +import type { Region } from '../../../bridge' + +export type DomainStatus = + | 'unknown' + | 'checked' + | 'unchecked' + | 'invalid' + | 'locked' + | 'revoked' + | 'pending' + +export type EmailRcptType = 'unknown_rcpt_type' | 'to' | 'cc' | 'bcc' + +export type EmailStatus = + | 'unknown' + | 'new' + | 'sending' + | 'sent' + | 'failed' + | 'canceled' + +/** Create email request. address */ +export interface CreateEmailRequestAddress { + /** Email address */ + email: string + /** Optional display name */ + name?: string +} + +/** Create email request. attachment */ +export interface CreateEmailRequestAttachment { + /** Filename of the attachment */ + name: string + /** MIME type of the attachment (Currently only allow, text files, pdf and html files) */ + type: string + /** Content of the attachment, encoded in base64 */ + content: Array +} + +/** Create email response */ +export interface CreateEmailResponse { + /** Single page of emails matching the requested criteria */ + emails: Array +} + +/** Domain */ +export interface Domain { + /** ID of the domain */ + id: string + /** ID of the organization to which the domain belongs */ + organizationId: string + /** ID of the project */ + projectId: string + /** Domain name (example.com) */ + name: string + /** Status of the domain */ + status: DomainStatus + /** Date and time of domain's creation */ + createdAt?: Date + /** Date and time of the next scheduled check */ + nextCheckAt?: Date + /** Date and time the domain was last found to be valid */ + lastValidAt?: Date + /** Date and time of the revocation of the domain */ + revokedAt?: Date + /** Error message if the last check failed */ + lastError?: string + /** Snippet of the SPF record that should be registered in the DNS zone */ + spfConfig: string + /** DKIM public key, as should be recorded in the DNS zone */ + dkimConfig: string + /** Domain's statistics */ + statistics?: Statistics + region: Region +} + +/** Email */ +export interface Email { + /** Technical ID of the email */ + id: string + /** MessageID of the email */ + messageId: string + /** ID of the project to which the email belongs */ + projectId: string + /** Email address of the sender */ + mailFrom: string + /** Email address of the recipient */ + rcptTo: string + /** Type of the recipient */ + rcptType: EmailRcptType + /** Creation date of the email object */ + createdAt?: Date + /** Last update time of the email object */ + updatedAt?: Date + /** Status of the email */ + status: EmailStatus + /** Additional information on the status */ + statusDetails?: string + /** Total number of attempts to send the email */ + tryCount: number + /** Informations about the latest three attempts to send the email */ + lastTries: Array +} + +/** Email. try */ +export interface EmailTry { + /** Rank number of this attempt to send the email */ + rank: number + /** Date of the attempt */ + triedAt?: Date + /** + * The SMTP status code received after the attempt. 0 if the attempt did not + * reach an SMTP server. + */ + code: number + /** + * The SMTP message received, if any. If the attempt did not reach an SMTP + * server, the message says why. + */ + message: string +} + +/** List domains response */ +export interface ListDomainsResponse { + /** Total number of domains matching the request (without pagination) */ + totalCount: number + domains: Array +} + +/** List emails response */ +export interface ListEmailsResponse { + /** Count of all emails matching the requested criteria */ + totalCount: number + /** Single page of emails matching the requested criteria */ + emails: Array +} + +/** Statistics */ +export interface Statistics { + /** Total number of emails matching the request criteria */ + totalCount: number + /** + * Number of emails still in the `new` transient state (received from the API, + * not yet processed) + */ + newCount: number + /** + * Number of emails still in the `sending` transient state (received from the + * API, not yet in their final status) + */ + sendingCount: number + /** + * Number of emails in the final `sent` state (have been delivered to the + * target mail system) + */ + sentCount: number + /** + * Number of emails in the final `failed` state (refused by the target mail + * system with a final error status) + */ + failedCount: number + /** Number of emails in the final `canceled` state (canceled by customer's request) */ + canceledCount: number +} + +export type GetServiceInfoRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region +} + +export type CreateEmailRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + /** Sender information (must be from a checked domain declared in the project) */ + from?: CreateEmailRequestAddress + /** Array of recipient information (limited to 1 recipient) */ + to?: Array + /** Array of recipient information (unimplemented) */ + cc?: Array + /** Array of recipient information (unimplemented) */ + bcc?: Array + /** Message subject */ + subject: string + /** Text content */ + text: string + /** HTML content */ + html: string + /** ID of the project in which to create the email */ + projectId?: string + /** Array of attachments */ + attachments?: Array + /** Maximum date to deliver mail */ + sendBefore?: Date +} + +export type GetEmailRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + /** ID of the email to retrieve */ + emailId: string +} + +export type ListEmailsRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + page?: number + pageSize?: number + /** Optional ID of the project in which to list the emails */ + projectId?: string + /** Optional ID of the domain for which to list the emails */ + domainId?: string + /** Optional, list emails created after this date */ + since?: Date + /** Optional, list emails created before this date */ + until?: Date + /** Optional, list emails sent with this `mail_from` sender's address */ + mailFrom?: string + /** Optional, list emails sent with this `mail_to` recipient's address */ + mailTo?: string + /** Optional, list emails having any of this status */ + statuses?: Array +} + +export type GetStatisticsRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + /** Optional, count emails for this project */ + projectId?: string + /** + * Optional, count emails send from this domain (must be coherent with the + * `project_id` and the `organization_id`) + */ + domainId?: string + /** Optional, count emails created after this date */ + since?: Date + /** Optional, count emails created before this date */ + until?: Date + /** Optional, count emails sent with this `mail_from` sender's address */ + mailFrom?: string +} + +export type CancelEmailRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + /** ID of the email to cancel */ + emailId: string +} + +export type CreateDomainRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + projectId?: string + domainName: string +} + +export type GetDomainRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + /** ID of the domain */ + domainId: string +} + +export type ListDomainsRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + /** Page number (1 for the first page) */ + page?: number + /** Page size */ + pageSize?: number + projectId?: string + status?: Array +} + +export type RevokeDomainRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + /** ID of the domain to revoke */ + domainId: string +} + +export type CheckDomainRequest = { + /** Region to target. If none is passed will use default region from the config */ + region?: Region + /** ID of the domain to check */ + domainId: string +}