Security News
pnpm 10.0.0 Blocks Lifecycle Scripts by Default
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
@byjohann/utils
Advanced tools
A collection of utility functions that I use across my JavaScript and TypeScript projects.
Run the following command to add @byjohann/utils
to your project.
# npm
npm install -D @byjohann/utils
# pnpm
pnpm add -D @byjohann/utils
# yarn
yarn add -D @byjohann/utils
toArray
Converts MaybeArray<T>
to Array<T>
.
type MaybeArray<T> = T | T[]
declare function toArray<T>(array?: MaybeArray<T> | null | undefined): T[]
createCSV
Converts an array of objects to a comma-separated values (CSV) string that contains only the columns
specified.
declare function createCSV<T extends Record<string, unknown>>(
data: T[],
columns: (keyof T)[],
options?: {
/** @default ',' */
delimiter?: string
/** @default true */
includeHeaders?: boolean
/** @default false */
quoteAll?: boolean
}
): string
parseCSV
Parses a comma-separated values (CSV) string into an array of objects.
[!NOTE] The first row of the CSV string is used as the header row.
type CSVRow<T extends string = string> = Record<T, string>
declare function parseCSV<Header extends string>(csv: string): CSVRow<Header>[]
escapeCSVValue
Escapes a value for a CSV string.
[!NOTE] Returns an empty string if the value is
null
orundefined
.
declare function escapeCSVValue(value: unknown, { delimiter, quoteAll, }?: {
/** @default ',' */
delimiter?: string
/** @default false */
quoteAll?: boolean
}): string
tryParseJSON
Type-safe wrapper around JSON.stringify
falling back to the original value if it is not a string or an error is thrown.
declare function tryParseJSON<T = unknown>(value: unknown): T
cloneJSON
Clones the given JSON value.
[!NOTE] The value must not contain circular references as JSON does not support them. It also must contain JSON serializable values.
declare function cloneJSON<T>(value: T): T
A simple general purpose memoizer utility.
Useful for deferring initialization or expensive operations. Unlike a simple getter, there is no runtime overhead after the first invokation, since the getter itself is overwritten with the memoized value.
declare function lazy<T>(getter: () => T): { value: T }
Example:
const myValue = lazy(() => 'Hello, World!')
console.log(myValue.value) // Computes value, overwrites getter
console.log(myValue.value) // Returns cached value
console.log(myValue.value) // Returns cached value
interopDefault
Interop helper for default exports.
declare function interopDefault<T>(m: T | Promise<T>): Promise<T extends {
default: infer U
} ? U : T>
Example:
import { interopDefault } from '@byjohann/utils'
async function loadModule() {
const mod = await interopDefault(import('./module.js'))
}
objectKeys
Strictly typed Object.keys
.
declare function objectKeys<T extends Record<any, any>>(obj: T): Array<`${keyof T & (string | number | boolean | null | undefined)}`>
objectEntries
Strictly typed Object.entries
.
declare function objectEntries<T extends Record<any, any>>(obj: T): Array<[keyof T, T[keyof T]]>
deepApply
Deeply applies a callback to every key-value pair in the given object, as well as nested objects and arrays.
declare function deepApply<T extends Record<any, any>>(data: T, callback: (item: T, key: keyof T, value: T[keyof T]) => void): void
withoutLeadingSlash
Removes the leading slash from the given path if it has one.
declare function withoutLeadingSlash(path?: string): string
withLeadingSlash
Adds a leading slash to the given path if it does not already have one.
declare function withLeadingSlash(path?: string): string
withoutTrailingSlash
Removes the trailing slash from the given path if it has one.
declare function withoutTrailingSlash(path?: string): string
withTrailingSlash
Adds a trailing slash to the given path if it does not already have one.
declare function withTrailingSlash(path?: string): string
joinURL
Joins the given base URL and path, ensuring that there is only one slash between them.
declare function joinURL(base?: string, path?: string): string
withBase
Adds the base path to the input path, if it is not already present.
declare function withBase(input?: string, base?: string): string
withoutBase
Removes the base path from the input path, if it is present.
declare function withoutBase(input?: string, base?: string): string
getPathname
Returns the pathname of the given path, which is the path without the query string.
declare function getPathname(path?: string): string
withQuery
Returns the URL with the given query parameters. If a query parameter is undefined, it is omitted.
declare function withQuery(input: string, query?: QueryObject): string
Example:
import { withQuery } from '@byjohann/utils'
const url = withQuery('https://example.com', {
foo: 'bar',
// This key is omitted
baz: undefined,
// Object values are stringified
baz: { qux: 'quux' }
})
template
Simple template engine to replace variables in a string.
declare function template(str: string, variables: Record<string | number, any>, fallback?: string | ((key: string) => string)): string
Example:
import { template } from '@byjohann/utils'
const str = 'Hello, {name}!'
const variables = { name: 'world' }
console.log(template(str, variables)) // Hello, world!
generateRandomId
Generates a random string. The function is ported from nanoid
. You can specify the size of the string and the dictionary of characters to use.
declare function generateRandomId(size?: number, dict?: string): string
unindent
Removes common leading whitespace from a template string while also removing empty lines at the beginning and end.
declare function unindent(str: TemplateStringsArray | string): string
stripIndents
Removes common leading whitespace from a template string.
stripIndents`
Hello
World
` // => "Hello\nWorld"
stripIndents(' Hello\n World') // => "Hello\nWorld"
MIT License © 2024-PRESENT Johann Schopplich
FAQs
A collection of utilities for my projects
We found that @byjohann/utils demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.