npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@simplysf/simply-core

v1.4.0

Published

Shared internal utilities for SimplySF Salesforce CLI plugins

Readme

@simplysf/simply-core

NPM Downloads/week License: Apache-2.0

Shared internal utilities for @simplysf Salesforce CLI plugins. This is not a Salesforce CLI plugin itself — it's a plain library consumed by the other packages in this monorepo.

It deliberately does not depend on @salesforce/sf-plugins-core. Anything needing the oclif flag or command layer belongs in @simplysf/simply-plugin-kit instead.

Install

npm install @simplysf/simply-core

API

Everything below is exported from the package root.

Authentication

| Export | Description | | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | authenticateClientCredentials(options) | Authenticates via the OAuth 2.0 Client Credentials grant — a flow the Salesforce CLI has no built-in support for (only web, JWT, and SFDX auth-url). Proxies @jsforce/jsforce-node's OAuth2 token exchange into @salesforce/core's AuthInfo, the same way the JWT flow hands off its own token internally, so the resulting org is persisted and alias-able like any other sf-authenticated org. | | ClientCredentialsAuthOptions, ClientCredentialsAuthResult | Option and result types. |

import { authenticateClientCredentials } from '@simplysf/simply-core';

const { username } = await authenticateClientCredentials({
  loginUrl: 'https://my-org.my.salesforce.com',
  consumerKey: 'consumer-key',
  consumerSecret: 'consumer-secret', // or consumerSecretFile: './consumer-secret.txt'
  alias: 'my-org',
  setDefault: true,
});
// -> persisted, usable as --target-org my-org anywhere in the sf/simply ecosystem

The Connected App's OAuth policy must include the api and id/openid scopes — AuthInfo resolves the username/org ID via services/oauth2/userinfo, which depends on them. Client Credentials tokens run as the single "run as" user configured on the Connected App in Setup, not a per-request user.

Querying

| Export | Description | | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | queryRecords(conn, soql, options?) | Async generator yielding flat, string-valued records. Picks its own transport: below bulkThreshold (default 2000) it uses Connection#autoFetchQuery; above it, streamBulkQuery, so memory stays flat at any result size. Not for Tooling API queries — Bulk API v2 doesn't support them. | | chunkedInQuery(conn, values, buildSoql, options) | Runs a query once per chunk of values, splicing each chunk into a quoted IN (...) clause, and returns every record from every chunk. Use when an IN list would otherwise exceed SOQL's length limit. | | escapeSoqlLiteral(value) | Escapes a value for use inside a single-quoted SOQL string literal. | | ChunkedInQueryOptions, QueryRecordsOptions | Option types for the two query helpers. |

Bulk API v2 streaming export

| Export | Description | | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | streamBulkQuery(conn, soql, opts?) | Runs a SOQL query through Bulk API v2 and returns the merged CSV results as one Readable. | | streamBulkQueryToFile(conn, soql, path, opts?) | The same, written straight to a file — the common case. | | SkipFirstLineTransform | Strips the duplicate header row from each result page after the first. | | StreamBulkQueryOptions, StreamBulkQueryResult, StreamBulkQueryToFileOptions, StreamBulkQueryToFileResult | Option and result types. |

Connection.bulk2.query() (jsforce's own convenience method) routes each result page through jsforce's legacy HTTP transport, which fully buffers each page into memory before your code can consume it — defeating streaming for large exports. These helpers avoid that by fetching result pages directly with undici, converting the response body straight to a Node stream, and piping it onward. jsforce is still used for job creation and polling; only the result-page fetch bypasses it.

import { streamBulkQueryToFile } from '@simplysf/simply-core';

const result = await streamBulkQueryToFile(connection, 'SELECT Id, Name FROM Account', './accounts.csv');
// { jobId: '750...', numberRecordsProcessed: 42 }

CSV output

| Export | Description | | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | createCsvFileWriter(outputPath, columns) | Opens a streaming CSV writer, for writing rows incrementally without holding them all in memory. | | writeRecordsToCsvFile(records, outputPath, columns) | Pipes an AsyncIterable of records — e.g. queryRecords() — straight to a CSV file. Resolves to { recordCount }. | | CsvFileWriter | The writer handle returned by createCsvFileWriter. |

sfdx-project.json

| Export | Description | | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | readSfdxProject(dir?) | Reads and parses the project file. | | getDefaultPackageDirectory(project) | Returns the entry flagged default: true. | | getPluginConfig(source, keyPath) | Walks a dot-delimited path (e.g. plugins.simply.dependencies.ignore) through any object, returning undefined if any segment is missing. | | SFDX_PROJECT_FILE_NAME | 'sfdx-project.json'. | | SfdxProject, SfdxPackageDirectory, SfdxPackageDirectoryDependency | Types for the parsed file. |

Package IDs

| Export | Description | | ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | | isPackage2Id, isPackage2VersionId, isSubscriberPackageId, isSubscriberPackageVersionId | Prefix predicates for the four package ID kinds. | | PACKAGE_PREFIX_PACKAGE2, PACKAGE_PREFIX_PACKAGE2_VERSION, PACKAGE_PREFIX_SUBSCRIBER_PACKAGE, PACKAGE_PREFIX_SUBSCRIBER_PACKAGE_VERSION | The prefixes those predicates check (0Ho, 05i, 033, 04t). |

Metadata package attribution

| Export | Description | | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | | resolvePackageNamesByApiName(conn, apiNames, options?) | Maps metadata API names to the installed package that owns them. | | resolvePackageNamesBySubjectId(conn, subjectIds, options?) | The same, keyed by subject ID. | | normalizePublisherName(publisherName, fallbackLabel) | Normalizes a publisher name for display, falling back to fallbackLabel when absent. | | LOCAL_PACKAGE_LABEL, LOCAL_PUBLISHER_NAME | Labels used for metadata that belongs to the org itself rather than an installed package. | | ResolvePackageNamesByApiNameOptions, ResolvePackageNamesOptions | Option types. |

Config files

| Export | Description | | ----------------------------------------------------- | ----------------------------------------------------------- | | loadJsonConfig(path, schema) / loadJsonConfigSync | Reads a JSON config file and validates it against a schema. | | parseJsonConfig(contents, schema) | The same, from an already-read string. | | ConfigSchema, JsonConfigResult | Schema and result types. |

Collections and paths

| Export | Description | | --------------------------------- | ---------------------------------------------------------------------------------------------- | | chunk(items, size) | Splits an array into fixed-size chunks. | | mapChunked(items, size, mapper) | Maps an async mapper over an array one chunk at a time, awaiting each chunk before the next. | | ensureDirectory(path) | Creates a directory (and parents) if it doesn't already exist. | | timestampForFileName(date?) | A filesystem-safe timestamp, for generated output file names. |

Issues

Please report any issues at https://github.com/SimplySF/simply-node/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.