knack-nest
Version:
A knack library for nestjs
225 lines (220 loc) • 8.6 kB
text/typescript
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';
()
export class KnackRepository<T> implements IGenericRepository {
private _knackConnection: KnackConnection;
private _objectKey: string;
constructor(
knackService: KnackService,
knackObject: T
){
(KNACK_OBJECT_CONNECTION)
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,
})
}
}