@planet-a/affinity-node
Version:
API wrapper for the affinity.co API
153 lines (152 loc) • 5.34 kB
JavaScript
import * as dntShim from "../_dnt.shims.js";
import { assert } from '../deps/jsr.io/@std/assert/1.0.16/mod.js';
import { fileFrom } from 'fetch-blob/from.js';
import { defaultTransformers } from './axios_default_transformers.js';
import { createSearchIteratorFn } from './create_search_iterator_fn.js';
import { entityFilesUrl } from './urls.js';
/**
* Entity files are files uploaded to a relevant entity.
* Possible files, for example, would be a pitch deck for an opportunity or a physical mail correspondence for a person.
*/
export class EntityFiles {
/** @hidden */
constructor(axios) {
Object.defineProperty(this, "axios", {
enumerable: true,
configurable: true,
writable: true,
value: axios
});
/**
* Returns an async iterator that yields all entity files matching the given request
* Each yielded array contains up to the number specified in {@link AllEntityFileRequest.page_size} of entity files.
* Use this method if you want to process the entity files in a streaming fashion.
*
* *Please note:* the yielded entity files array may be empty on the last page.
*
* @example
* ```typescript
* let page = 0
* for await (const entries of affinity.entityFiles.pagedIterator({
* person_id: 123,
* page_size: 10
* })) {
* console.log(`Page ${++page} of entries:`, entries)
* }
* ```
*/
Object.defineProperty(this, "pagedIterator", {
enumerable: true,
configurable: true,
writable: true,
value: createSearchIteratorFn(this.all.bind(this), 'entity_files')
});
}
static transformEntityFile(file) {
return {
...file,
created_at: new Date(file.created_at),
};
}
/**
* Returns all entity files within your organization.
*/
async all(params) {
const response = await this.axios.get(entityFilesUrl(), {
params,
transformResponse: [
...defaultTransformers(),
(json) => {
return {
...json,
entity_files: json.entity_files.map(EntityFiles.transformEntityFile),
};
},
],
});
return response.data;
}
/**
* Fetches an entity with a specified `entity_file_id`.
*/
async get(entity_file_id) {
const response = await this.axios.get(entityFilesUrl(entity_file_id), {
transformResponse: [
...defaultTransformers(),
EntityFiles.transformEntityFile,
],
});
return response.data;
}
/**
* Downloads the entity file with the specified `entity_file_id`.
*
* @example
* ```typescript
* import { promises as fsPromises } from 'node:fs';
* const fileResponseStream = affinity.entityFiles.download(123);
* await fsPromises.writeFile(filePath, fileResponseStream);
* ```
*/
async download(entity_file_id) {
const response = await this.axios.get(entityFilesUrl(entity_file_id, true), {
responseType: 'stream',
// The download location of entity files is provided via a redirect from Affinity
maxRedirects: 5,
});
return response.data;
}
/**
* Uploads files attached to the entity with the given id.
*
* The file will display on the entity's profile, provided that the entity is not a person internal to the user's organization.
*
* @example
* ```typescript
* const entityFile = await affinity.entityFiles.upload({
* files: ['/path/to/example.pdf'],
* person_id: 123,
* });
* ```
*/
async upload(params) {
const formData = new dntShim.FormData();
const { files } = params;
assert(files.length, 'At least one file must be provided');
if (params.person_id) {
formData.append('person_id', params.person_id.toString());
}
else if (params.organization_id) {
formData.append('organization_id', params.organization_id.toString());
}
else if (params.opportunity_id) {
formData.append('opportunity_id', params.opportunity_id.toString());
}
else {
throw new Error('One of person_id, organization_id or opportunity_id must be provided');
}
await Promise.all(files.map((file) => appendToFormData(formData, file)));
const response = await this.axios.post(entityFilesUrl(), formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
return response.data.success === true;
}
}
function isFile(file) {
return file instanceof dntShim.File;
}
async function appendToFormData(formData, file) {
if (typeof file === 'string') {
const f = await fileFrom(file);
formData.append('files[]', f);
}
else if (isFile(file)) {
formData.append('files[]', file);
return null;
}
else {
throw new Error('Unsupported file type');
}
}