UNPKG

knack-nest

Version:
225 lines (220 loc) 8.6 kB
import Knack from 'knack-sdk'; import { IGenericRepository } from "./GenericRepository"; import { KnackConnection } from './knackConnection'; import { AuthenticateArgs, AuthenticateTokenArgs, CreateRecordArgs, CreateViewRecordArgs, DeletePayload, DeleteRecordArgs, DeleteViewRecordArgs, GetRecordArgs, GetRecordsArgs, GetRecordsPayload, KnackSession, ObjectPayload, UpdateRecordArgs, UpdateViewRecordArgs, UploadFileArgs, UploadPayload, ViewRecordPayload } from 'knack-sdk/dist/types'; import FormData from 'form-data'; import { Inject, Injectable } from '@nestjs/common'; import { KNACK_OBJECT_CONNECTION, KNACK_OBJECT_OPTIONS } from '../constant'; import { KnackService } from '../knack.service'; @Injectable() export class KnackRepository<T> implements IGenericRepository { private _knackConnection: KnackConnection; private _objectKey: string; constructor( @Inject(KNACK_OBJECT_CONNECTION) knackService: KnackService, knackObject: T ){ this._knackConnection = knackService.knackConnection; //@ts-ignore this._objectKey = knackObject.getInstance().objectKey; } /** * Authenticate a user via their email and password * @param args - AuthenticateArgs * @param args.email - User's email * @param args.password - User's password * @returns Promise<void> */ async authenticate(args: AuthenticateArgs) { const {request, apiToken} = this._knackConnection; const { session: { user: { token } } } = await request<KnackSession>(`applications/${apiToken}/session`, { method: 'POST', json: args }) this._knackConnection.apiToken = token return token } /** * Authenticate tokens by getting a clean view * @param args - AuthenticateTokenArgs * @param args.sceneKey - The scene key * @param args.viewKey - The view key * @param args.token - The token to be validated * @returns Promise<ViewRecordPayload> */ async authenticateToken(args: AuthenticateTokenArgs) { const { sceneKey, viewKey, token } = args this._knackConnection.apiToken = token; return this._knackConnection.request<ViewRecordPayload>( `pages/${sceneKey}/views/${viewKey}/records`, { method: 'GET' } ) } /** * Creates a record in the Object of your choice * @param args - CreateRecordArgs * @param args.objectKey - The desired Object where this record will live * @param args.data - JSON pojo of field keys with corresponding data * @returns Promise<ObjectPayload> */ createRecord(args: Partial<CreateRecordArgs>) { const { data: json } = args return this._knackConnection.request<ObjectPayload>(`objects/${this._objectKey}/records`, { method: 'POST', json }) } /** * Creates a record in the Object of your choice, limited to a User's view * @param args - CreateViewRecordArgs * @param args.sceneKey - The scene key * @param args.viewKey - The view key * @param args.data - JSON pojo of field keys with corresponding data * @returns Promise<ViewRecordPayload> */ createViewRecord(args: CreateViewRecordArgs) { const { sceneKey, viewKey, data: json } = args return this._knackConnection.request<ViewRecordPayload>( `pages/${sceneKey}/views/${viewKey}/records`, { method: 'POST', json } ) } /** * Deletes a record by object key and record id * @param args - DeleteRecordArgs * @param args.objectKey - The Object where this record lives * @param args.recordId - The Record's ID that it to be deleted * @returns Promise<DeletePayload> */ deleteRecord(args: Partial<DeleteRecordArgs>) { const { recordId } = args return this._knackConnection.request<DeletePayload>(`objects/${this._objectKey}/records/${recordId}`, { method: 'DELETE' }) } /** * Deletes a record based on a users' allowed actions * @param args - DeleteViewRecordArgs * @param args.sceneKey - The scene key * @param args.viewKey - The view key * @param args.recordId - The Record's ID that it to be deleted * @returns Promise<DeletePayload> */ deleteViewRecord(args: DeleteViewRecordArgs) { const { sceneKey, viewKey, recordId } = args return this._knackConnection.request<DeletePayload>( `pages/${sceneKey}/views/${viewKey}/records/${recordId}`, { method: 'DELETE' } ) } /** * Gets a record by object key and record id * @param args - GetRecordArgs * @param args.objectKey - The Object where this record lives * @param args.recordId - The Record's ID that it to be deleted * @returns Promise<ObjectPayload> */ getRecord(args: Partial<GetRecordArgs>) { const { recordId } = args return this._knackConnection.request<ObjectPayload>( `objects/${this._objectKey}/records/${recordId}` ) } /** * Gets record by object key and filters. Supports pagination and sorting * @param args - GetRecordsArgs * @param args.objectKey - The Object where this record lives * @param [args.format] - Format of the response `raw`, `html`, or `both` * @param [args.filters] - Filter rules for narrowing your results * @param [args.page] - Page you're requesting * @param [args.rowsPerPage] - Number of rows per page * @param [args.sortField] - Field to sort results on * @param [args.sortOrder] - Ascending (`asc`) or Descending (`desc`) * @returns Promise<GetRecordsPayload> */ getRecords(args: Partial<GetRecordsArgs>) { const { filters, format, page, rowsPerPage, sortField, sortOrder } = args const searchParams = { ...(filters && { filters: JSON.stringify(filters) }), ...(format && { format }), ...(page && { page }), ...(rowsPerPage && { rows_per_page: rowsPerPage }), ...(sortField && { sort_field: sortField }), ...(sortOrder && { sort_order: sortOrder }) } return this._knackConnection.request<GetRecordsPayload>( `objects/${this._objectKey}/records`, { method: 'GET', searchParams } ) } /** * Updates a record for a type of Object * @param args - UpdateRecordArgs * @param args.objectKey - The desired Object where this record is * @param args.recordId - The Record's ID that it to be updated * @param args.data - JSON pojo of field keys with corresponding data * @returns Promise<ObjectPayload> */ updateRecord(args: Partial<UpdateRecordArgs>) { const { data: json, recordId } = args return this._knackConnection.request<ObjectPayload>(`objects/${this._objectKey}/records/${recordId}`, { method: 'PUT', json }) } /** * Updates a record of a type of Object, limited to a User's view * @param args - UpdateViewRecordArgs * @param args.sceneKey - The scene key * @param args.viewKey - The view key * @param args.data - JSON pojo of field keys with corresponding data * @returns Promise<ViewRecordPayload> */ updateViewRecord(args: UpdateViewRecordArgs) { const { sceneKey, viewKey, data: json, recordId } = args return this._knackConnection.request<ViewRecordPayload>( `pages/${sceneKey}/views/${viewKey}/records/${recordId}`, { method: 'PUT', json } ) } /** * Uploads a file or image to knack and return the public url. * @param args - UploadFileArgs * @param args.file - Readable Stream of the file you wish to upload * @returns Promise<ObjectPayload> */ async uploadFileToRecord(args: Partial<UploadFileArgs>) { const { fieldKey, file } = args const form = new FormData() form.append('files', file) const { id } = await this._knackConnection.request<UploadPayload>(`applications/${this._knackConnection.appid}/assets/file/upload`, { body: form, method: 'POST' }) return this.createRecord({ objectKey: this._objectKey, data: { [fieldKey]: id } }) } /** * Uploads a file or image to a record in a designated field * @param args - UploadFileArgs * @param args.objectKey - The desired Object where this record will live * @param args.fieldKey - The desired Field where this file will be added * @param args.file - Readable Stream of the file you wish to upload * @param args.timeout - timeout to prevent hanging requests * @returns Promise<ObjectPayload> */ async uploadFile(args: UploadFileArgs) { const { file } = args const form = new FormData() form.append('files', file) return this._knackConnection.request<UploadPayload>(`applications/${this._knackConnection.appid}/assets/file/upload`, { body: form, method: 'POST', timeoutSeconds: args.timeout, }) } }