@simplysf/simply-data-core
v0.3.7
Published
Content Version upload/download and CSV row counting logic — the library layer behind @simplysf/simply-data, published separately for direct consumption (e.g. editor tooling, CI scripts) without the CLI framework
Downloads
15,351
Readme
@simplysf/simply-data-core
Content Version upload/download, Content Note bulk upload, and CSV row counting logic. This is not a Salesforce CLI plugin — it's the library layer behind @simplysf/simply-data's file commands, published separately so it can be imported directly by anything that wants the same logic (an editor extension, a CI job, a script) without pulling in the CLI framework.
Install
npm install @simplysf/simply-data-coreRequires Node.js >=22 and either "type": "module" or a dynamic import() — this package ships ESM only.
API
Everything below is exported from the package root. Removing or renaming an export is a breaking change; see src/index.ts.
| Export | Description |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| uploadContentVersion(connection, filePath, title?, firstPublishLocationId?) | Uploads a local file as a new ContentVersion, re-queried to include ContentDocumentId. |
| downloadContentVersion(connection, contentVersionDownload, downloadDirectory) | Downloads a ContentVersion's file data to a local directory. |
| countCsvRows(filePath) | Counts the data rows in a CSV, excluding its header. |
| requestsForQuery(recordCount) | Estimates the API requests a record query costs, including its queryMore round trips. |
| REQUESTS_PER_UPLOAD | API requests consumed per file uploaded (2). |
| REQUESTS_PER_DOWNLOAD | API requests consumed per file downloaded (1). |
| QUERY_BATCH_SIZE | Records jsforce returns per query round trip. |
| createBoundary() | Generates a multipart boundary string. |
| escapeHeaderFilename(filename) | Escapes a filename for inclusion in a Content-Disposition header. |
| contentVersionMultipart(options) | Builds the multipart/form-data body for a ContentVersion create request. |
| createContentNote(connection, input, linkedEntityId) | Creates one ContentNote and links it to a record via ContentDocumentLink. |
| uploadContentNotes(connection, inputs, linkedEntityIdsByExternalId, options?) | Creates a stream of ContentNotes with bounded concurrency, resolving each one's parent record from a lookup map. |
| ContentVersion, ContentVersionCreateRequest, ContentVersionCreateResult, ContentVersionDownload, ContentVersionToUpload, ContentVersionMultipart | Types for the ContentVersion upload/download functions and the multipart body builder. |
| ContentNoteInput, ContentNoteResult, ContentNoteSuccessResult, ContentNoteErrorResult, UploadContentNotesOptions | Input, per-note result, and option types for createContentNote/uploadContentNotes. |
import { uploadContentVersion, downloadContentVersion } from '@simplysf/simply-data-core';
const contentVersion = await uploadContentVersion(connection, './report.pdf');
const filePath = await downloadContentVersion(connection, contentVersionDownload, './downloads');import { countCsvRows, requestsForQuery, REQUESTS_PER_UPLOAD } from '@simplysf/simply-data-core';
const rowCount = await countCsvRows('./records.csv');
const plannedRequests = requestsForQuery(rowCount) + rowCount * REQUESTS_PER_UPLOAD;import { queryRecords } from '@simplysf/simply-core';
import { uploadContentNotes, type ContentNoteInput } from '@simplysf/simply-data-core';
// Build the external-id -> record-id lookup notes will link against.
const lookup = new Map<string, string>();
for await (const record of queryRecords(connection, 'SELECT Id, Name FROM HRM_Request__c')) {
lookup.set(record.Name, record.Id);
}
const inputs: ContentNoteInput[] = [
{ content: 'Called the customer back.', title: 'Follow-up', linkedRecordExternalId: 'HRM-00042' },
];
for await (const result of uploadContentNotes(connection, inputs, lookup, { concurrency: 10 })) {
if (result.status === 'error') {
console.error(`${result.stage}: ${result.message}`);
}
}Issues
Please report any issues at https://github.com/SimplySF/simply-plugins-core/issues
Contributing
This package is part of the @simplysf/simply monorepo. See CONTRIBUTING.md for what's specific to this package, and the repo's root CONTRIBUTING.md for repo structure, setup, commit conventions, and how to submit a pull request. Please also read our Code of Conduct.
License
Licensed under the Apache-2.0 license.
